Skip to content
This repository has been archived by the owner on Mar 3, 2020. It is now read-only.

PackUnpack

Stefan Vigerske edited this page Mar 3, 2020 · 1 revision

PFunc requires that all function pointers that need to be parallelized be of the type be of the type void ()(void). This forces pr ogrammers to pack all arguments to their parallel functions into either a single structure or buffer. Although this is relatively easy to do for functions that accept small number of arguments, currying arguments back and forth is tedious for most functions. To alleviate these troubles, PFunc provides two function calls: pfunc_pack and pfunc_unpack, that help in packing arguments. These two functions are similar in vein to stdlib's printf function in that they both take in a format specifier that allows us to pack arguments using varargs. In this section, we will rewrite relevant sections from the Fibonacci example from the previous section using pfunc_pack and pfunc_unpack to demonstrate its use. Consider rewritten version of the function parallel_fib given below:

void parallel_fib (void* arg) {
  int n;
  int* fib_n;

  /* unpack the arguments */
  pfunc_unpack (arg, "int, int*", &n, &fib_n);

  if (0 == n || 1 == n) *fib_n = n;
  else {
    int x, y;
    pfunc_cilk_task_t fib_task;
    char* fib_arg_1;
    char* fib_arg_2;

    /* Pack the arguments to the function call */
    pfunc_pack (&fib_arg_1, "int, int*", n-1, &x);
    pfunc_pack (&fib_arg_2, "int, int*", n-2, &y);

    pfunc_cilk_task_init (&fib_task);

    pfunc_cilk_spawn_c_gbl (fib_task, NULL, NULL, parallel_fib, fib_arg_1);
    parallel_fib (fib_arg_2);

    pfunc_cilk_wait_gbl (fib_task);
    pfunc_cilk_task_clear (&fib_task);

    *fib_n = x + y;
  }
}

In this example, we first use pfunc_unpack to get the arguments to the current invocation of parallel_fib. Later, for non-base cases, we utilize pfunc_pack to prepare the arguments for the recursive invocation of parallel_fib. Notice that no memory was allocated for the buffers during pfunc_pack or that no memory was freed following the call to pfunc_unpack. This is because PFunc internally allocates and deallocates memory required for the packing and unpacking of the function parameters.

Caveats

As both pfunc_pack and pfunc_unpack utilize varargs to parse their inputs. As a result, char, unsigned char and float cannot be used as parameters. Instead, use int, unsigned int and double.

User-defined types

As both pfunc_pack and pfunc_unpack utilize varargs to parse their inputs, user-defined types cannot be specified as the parameter types. Instead, user-defined types should be passed by reference as void*. The valid values inside the format string of pfunc_pack and pfunc_unpack are: int, unsigned int, long int, int*, unsigned int*, long int*, int**, unsigned int**, long int**, char*, unsigned char*, char**, unsigned char**, float*, float**, double, double*, double** and void*.