0
$\begingroup$

Here is a compiled, non-parallel function that works.

allInhibitions=Compile[{{idArray,_Integer,2},{sizeArray,_Real,2},{constantA,_Real},{inhibitionRuleArrays,_Real,3}},Module[{rows,cols,rowLabels,colLabels,inhibitionArray},
(* Initialize the inhibition array with zeroes *)
inhibitionArray=sizeArray*0.;
(* Loop over the locations *)
Do[
(* Add the inhibition from each plant to the inhibition array *)
inhibitionArray+=inhibitionIJC[i,j,idArray,sizeArray,constantA,inhibitionRuleArrays],
{i,1,Length[sizeArray]},{j,1,Length[sizeArray[[1]]]}];
inhibitionArray
]];

The function inhibitionIJC[] is also compiled, the 2D arrays are 50 by 100, and the 3D is 4 by 50 by 100.

I would like to make the Do loop run in parallel, using ParallelDo, but of course simply changing it to ParallelDo doesn't work. At first I thought the extra step of SetSharedVariable was the missing piece, because the Help shows this:

SetSharedVariable[j]; j = 0;
ParallelDo[j++, {5}]; j

so I tried this:

allInhibitions=Compile[{{idArray,_Integer,2},{sizeArray,_Real,2},{constantA,_Real},{inhibitionRuleArrays,_Real,3}},Module[{rows,cols,rowLabels,colLabels,inhibitionArray},
(* Initialize the inhibition array with zeroes *)
SetSharedVariable[inhibitionArray];
inhibitionArray=sizeArray*0.;
(* Loop over the locations *)
ParallelDo[
(* Add the inhibition from each plant to the inhibition array *)
inhibitionArray+=inhibitionIJC[i,j,idArray,sizeArray,constantA,inhibitionRuleArrays],
{i,1,Length[sizeArray]},{j,1,Length[sizeArray[[1]]]}];
inhibitionArray
]];

But it returns all zeroes, i.e., the initialized array. Any advice would be appreciated. Is it because I'm inside a Module? I've tried various options, such as making inhibitionArray a global variable and distributing it first, as in the Help example. But that evaluates endlessly, and when I try to abort says

Kernels: Subkernel connected though KernelObject[1,local] appears dead

which suggests a larger issue.

$\endgroup$
  • 1
    $\begingroup$ ParallelDo simply cannot be used in Compile. $\endgroup$ – Szabolcs Nov 20 '18 at 16:54
  • $\begingroup$ It seems you are just looping over the elements of an array, computing somewthing for each, then adding up the results. The first step to effective parallelization is to make sure that the subseqeunt steps in your loop do not depend on each other. E.g., compute each number you want to add first, then add them up at the end. With this approach, you might be able to use things sucha s Listable compiled functions (see Compile doc page), which are parallelizable in a different way. $\endgroup$ – Szabolcs Nov 20 '18 at 16:57
  • $\begingroup$ Thanks. If ParallelDo can't compile, fair enough, but I would have expected either an error message on compilation or on execution! It runs without any complaint, but just doesn't return the right results. $\endgroup$ – Gareth Russell Nov 20 '18 at 19:50
  • $\begingroup$ I can think of a bunch of different ways to parallelize it 'by hand' as it were — I was just hoping for some of that ol' Mathematica magic where adding "Parallel" just works. Your suggestion about calculating all the numbers first is not as easy at it seems because each {i,j} step returns a complete array, so it would be 5000 5000-element arrays. I was trying to avoid that with the +=. I'll figure out way. Since the internal function inhibitionIJC[] is compiled, perhaps I won't bother compiling the loop! $\endgroup$ – Gareth Russell Nov 20 '18 at 19:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.