5
$\begingroup$

I want to evaluate a table of functions with ParallelTable. Here is the serial code:

f[i_] := f[i] =
  Quiet@
   NIntegrate[
     Sin[Sin[Sin[x^(i + 3)]]], {x, 0, 3},
     MaxRecursion -> 50, PrecisionGoal -> 40
   ]

Table[f[i], {i, 1, 3}]
{0.288687, 0.24239, 0.204309}

When I do this, I can then access the memoized values of f[i] immediately without recalculation:

f[3] // Timing
{0., 0.204309}

Now here is the parallel version:

ParallelTable[f[i], {i, 1, 3}]
{0.288687, 0.24239, 0.204309}

In this case, however, I don't have access to the memoized values of f[i]; the values have to be recalculated, as evidenced by the longer time it takes to return them:

f[3] // Timing
{2.23, 0.204309}

What is the problem with the shared data?

$\endgroup$
2
  • 5
    $\begingroup$ The memoized values generated in the parallel evaluation are stored on the subkernels on which they were generated and not on the main kernel. When you try to access them from the main kernel (i.e. by executing f[3] in the front end), the main kernel has no record of that value and has to recalculate it. The same problem was discussed in this question, where you may also find a possible solution: Parallel evaluation of function with memorization. $\endgroup$
    – MarcoB
    Mar 11, 2016 at 13:53
  • 3
    $\begingroup$ If you just need the memoized values on the main kernel, I like the method of this answer to the question linked by Marco. It keeps the interprocess communication down to just when you fetch the memoized values, so it won't be so bad as things like SetSharedFunction[]. $\endgroup$
    – Michael E2
    Mar 11, 2016 at 14:20

1 Answer 1

1
$\begingroup$

The memoization is performed at the kernel assigned to the tasks, it is only the results of the computation that is transferred. If you do

ParallelTable[AbsoluteTiming@f[i], {i, 1, 19}]

multiple times, you will see that the response time is improved on subsequent calls.

If you declare the function to be shared among the kernels, using

SetSharedFunction[f] 

prior to the definition of f you will see that the cached values are shared, or rather "downvalues are synchronised among all parallel kernels" as it says in the documentation.

$\endgroup$
1
  • 3
    $\begingroup$ Careful with SetSharedFunction! As Szabolcz mentioned in his answer to the older q, "The problem with SetSharedFunction is that it forces f to be evaluated on the main kernel: this means that you will lose parallelization and that there is extra communication overhead." This is also mentioned as a possible Issue in the documentation to SetSharedFunction: "A shared function is inefficient for mere code distribution and leads to sequential evaluation". $\endgroup$
    – MarcoB
    Mar 11, 2016 at 14:46

Not the answer you're looking for? Browse other questions tagged or ask your own question.