1
$\begingroup$

In a parallelised computation, I would like each kernel separately to break out of ParallelDo when it has finished going through the loop once. For a single kernel this works with Break[]. For example

Do[Print[i]; Break[], {i, 1, 100}]

Gives output

1

But if I try the same thing on ParallelDo (I have two kernels),

ParallelDo[Print[i]; Break[], {i, 1, 100}]

I get the strange output

1 (Kernel 2)

14 (Kernel 1)

27 (Kernel 2)

40 (Kernel 1)

53 (Kernel 2)

65 (Kernel 1)

77 (Kernel 2)

89 (Kernel 1)

while I would have expected just two outputs. It's essential that the two kernels break out separately, because my actual computation involves a random element such that running through the loop different times can take way more or less time. Thank you

$\endgroup$
0

1 Answer 1

2
$\begingroup$

Using

ParallelDo[Print[i]; Break[], {i, 1, 100}, Method -> "CoarsestGrained"]

or

ParallelDo[Print[i]; Break[], {i, 1, 100}, Method -> "EvaluationsPerKernel" -> 1]

should give you the desired behavior.
These options are explained and illustrated in the Options ▶ Method section of Parallelize.

Mathematica breaks the computation within ParallelDo into subunits. The default tries to balance evaluation size and number of evaluations. In your example these are 8 subunits, each starting individually not knowing that there occurred a Break[] for a smaller i before.


For the example given in your comment below

Module[{counter = 0},
 ParallelTry[
  While[! 0.5 <= RandomReal[] <= 0.50000001, counter++]; 
  Print["Gonna break at trial " <> ToString[counter]], 
  Range[$ProcessorCount]]]

or

Module[{counter = 0},
 ParallelDo[
  While[! 0.5 <= RandomReal[] <= 0.50000001, counter++]; 
  Print["Gonna break at trial " <> 
ToString[counter]], {$ProcessorCount}]]

might be more suitable.

$\endgroup$
3
  • 1
    $\begingroup$ Thank you, the "CoarsestGrained" option did the job in my case. I didn't specify my question enough: actually, I only wanted to break out of the loop when a certain condition was satisfied. If it's not satisfied, the kernel should try again. So a better example of code (with solution) is ParallelDo[ If[0.5 <= RandomReal[] <= 0.50000001, Print["Gonna break at trial " <> ToString[i]]; Break[]], {i, 1, 10^10}, Method -> "CoarsestGrained"] $\endgroup$
    – Latrace
    Commented Mar 7, 2015 at 16:24
  • 1
    $\begingroup$ @Latrace You should be aware that only the first kernel starts counting at 1. Your second kernel will start counting at 5000000001. See my update for two other possible implementations. You should use ParallelTry, if only one solution is needed. $\endgroup$
    – Karsten7
    Commented Mar 7, 2015 at 17:23
  • $\begingroup$ Thank you again, that is indeed more precise! $\endgroup$
    – Latrace
    Commented Mar 7, 2015 at 17:46

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.