Franck Dernoncourt
Franck Dernoncourt

Reputation: 83317

Is there any usual way to imitate a break in a parfor?

The body of a parfor-loop cannot contain a break statement.:

The parfor statement works by breaking up iterations of a loop and running these iterations on multiple MATLAB workers. Using break and return statements implies that later iterations of the loop should not run after either of these two statements execute. Therefore, the loop iterations must run in sequence. However, for the parfor loop to be valid, the result of running the successive loop iterations must not depend on the order in which they run.

E.g. the following won't work:

if matlabpool('size') == 0 % checking to see if my pool is already open
    matlabpool(2)
end

parfor i=1:10
    inv(rand(1000))
    break
end

Is there any usual way to imitate a break in a parfor?

Upvotes: 1

Views: 2763

Answers (3)

rpina61
rpina61

Reputation: 31

There IS a way to break out of a parfor by executing the parfor within a try/catch and using Matlab's "throw" or "throwAsCaller" error exception handling. It allows the break condition to be detected and conditional code to be executed, as well as allowing any code after breaking out of the parfor loop to be executed. First, start your parallel pool with whatever number of workers. In the code below, I generate a "fault" condition in my parfor loop by choosing a random number between 0 and 1. If the number is less than 0.9, the parfor loop continues. If it is greater, the code breaks out of the parfor loop, executes some conditional code in the catch statement, and then continues execution of the follow-on code. I display the ME exception in the catch only to show you can detect which value of the loop variable "i" resulted in the break condition. BTW, I tested this on R2019a.

 function parfor_break_test
  disp('Do something outside parfor ...')
  disp('Now execute the parfor inside a try/catch ...')
  try
    parfor i=1:10
      fprintf('Do something inside parfor w/ i=%d ...\n',i)
      if rand > 0.9
        ME = MException('parfor:break',sprintf('Breaking out of parfor @ i=%d ...',i));
        throw(ME)
      end
      disp('No fault, so do something else inside the parfor ...')
      pause(0.1)
    end
  catch ME
    fprintf('\n\nOops ... parfor break ... do something here ...\n\n')
    disp(ME)
  end
  disp('Do something outside the parfor whether or not break occurred ...')
end

Upvotes: 3

K.K.McDonald
K.K.McDonald

Reputation: 121

There is no way to break, but if you define a logical condition, you can use it to skip parfor counter and still use the advantages of parfor processing in exchange for a mild expense of skipping some counter numbers. for example

parfor i=1:10
    if (i>= 5)
       continue;
    end
    inv(rand(1000))
end

Also if possible, use simple for loop, it is better for small programs, I usually use parfor for heavy duty Monte Carlo simulation with multi-layer for loops and huge processing.

You can also operate parfor on little chunks and put it inside a while or another parfor loop. For example assume you want to run a program with "mounte_num = 10000" iterations. define "monte_temp = mounte_num / 100" and go like this

temp = 0
while (temp <= 100)
     parfor i=1:monte_temp 
           WHATEVER;
     end
     temp = temp + 1;
end

Upvotes: 1

Benoit_11
Benoit_11

Reputation: 13945

I'm afraid you can't get out of a parfor loop with something like a break statement since the order in which the loop is executed is totally arbitrary.

Would it be possible for you to use spmd blocks instead? With them you can let each worker know whether some condition is met/violated for example and thus better control the flow of the program. That might be more of a comment than an answer sorry; I though it was too long for a comment though.

Upvotes: 3

Related Questions