9
$\begingroup$

I'm trying to use Parallesubmit to run some calculations in parallel, but it looks like all the calculations are evaluated at one kernel. Consider this example:

LaunchKernels[]
(* {"KernelObject"[1, "local"], "KernelObject"[2, "local"], 
 "KernelObject"[3, "local"], "KernelObject"[4, "local"]} *)

f[a_, b_, {min_, max_}] := Pause[1]

ls = {0, 1};

DistributeDefinitions[f]
(* {f} *)

evl = Table[ParallelSubmit[{n}, {f[1, 0, ls], $KernelID}], {n, 1, 8}]

WaitAll[evl] // AbsoluteTiming
(* {8.0152, {{Null, 4}, {Null, 3}, {Null, 2}, {Null, 1}, {Null, 
   4}, {Null, 3}, {Null, 2}, {Null, 1}}} *)

We can see that $KernelID reported that the work are distributed among four kernels, but the timing shows they are evaluated at one kernel.

For comparison, ParallelTable works as expected

ParallelTable[{f[1, 0, ls], $KernelID}, {n, 1, 
   8}] // AbsoluteTiming
(* {2.00714, {{Null, 4}, {Null, 4}, {Null, 3}, {Null, 3}, {Null,
    2}, {Null, 2}, {Null, 1}, {Null, 1}}} *)

It appears that the problem may relate to the distribution of definition for ls, but why is there the inconsistency between $KernelID and AbsoluteTiming?

If ParallelSubmit doesn't know the definition of ls, I expect it to just complain, like in this example

t = 1;
evl = Table[ParallelSubmit[{n}, {Pause[t], $KernelID}], {n, 1, 4}];
WaitAll[evl]
(kernel 4) Pause::numnm :  Non-negative machine-sized number expected at position 1 in Pause[t].
(kernel 3) Pause::numnm :  Non-negative machine-sized number expected at position 1 in Pause[t].
(kernel 2) Pause::numnm :  Non-negative machine-sized number expected at position 1 in Pause[t].
(kernel 1) Pause::numnm :  Non-negative machine-sized number expected at position 1 in Pause[t].
(* {{Null, 4}, {Null, 3}, {Null, 2}, {Null, 1}} *)

Shall we consider this behavor as a bug?

$\endgroup$

1 Answer 1

5
$\begingroup$

This is not a bug, and as you said the problem lies in the subkernels not knowing about ls. Monitoring the communication between the main and subkernels with LinkSnooper you can see packets being exchanged like

Master ---> Sub: EvaluatePacket[{Global`f[1, 0, Global`ls], $KernelID}]
Master <--- Sub: ReturnPacket[{Global`f[1, 0, Global`ls], 1}]

While $KernelID does get evaluated in the subkernels, f just returns as is, since the third argument has to be a list with two elements, and the subkernel does not have a definition for ls. The ReturnPacket then gets processed in the main kernel, and as ls is now defined, Pause[1] is evaluated.

In your second example it is not ParallelSubmit or WaitAll that are complaining (how could they be aware that they should know about ls?), but Pause was not called with a numeric argument.

So there are three solutions:

  1. Distribute the definition of ls to the subkernels

    DistributeDefinitions[ls];
    evl = Table[ParallelSubmit[{n}, {f[1, 0, ls], $KernelID}], {n, 1, 4}];
    WaitAll[evl] // AbsoluteTiming
    
{2.04807, {{Null, 2}, {Null, 1}, {Null, 2}, {Null, 1}}}
  1. Tell ParallelSubmit to substitute ls before sending everything off to the subkernels (as you did for n)

     evl = Table[ParallelSubmit[{n,ls}, {f[1, 0, ls], $KernelID}], {n, 1, 4}];
     WaitAll[evl] // AbsoluteTiming
    
{2.02098, {{Null, 2}, {Null, 1}, {Null, 2}, {Null, 1}}}
  1. Make f complain when not evaluated with proper arguments

    f::badArgs = "f called with impropper arguments";
    f[a_, b_, {min_, max_}] := Pause[1]
    f[___] := (Message[f::badArgs]; $Failed);
    
    DistributeDefinitions[f]
    
     evl = Table[ParallelSubmit[{n}, {f[1, 0, ls], $KernelID}], {n, 1, 4}];
     WaitAll[evl] // AbsoluteTiming
    
f::badArgs :  f called with impropper arguments  
f::badArgs :  f called with impropper arguments  
f::badArgs :  f called with impropper arguments  
f::badArgs :  f called with impropper arguments  
{1.22837, {{$Failed, 4}, {$Failed, 3}, {$Failed, 2}, {$Failed, 1}}}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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