Nesting and Flow in parfor-Loops

Nested Functions

The body of a parfor-loop cannot make reference to a nested function. However, it can call a nested function by means of a function handle.

Nested Loops

The body of a parfor-loop cannot contain another parfor-loop. But it can call a function that contains another parfor-loop.

However, because a worker cannot open a parallel pool, a worker cannot run the inner nested parfor-loop in parallel. This means that only one level of nested parfor-loops can run in parallel. If the outer loop runs in parallel on a parallel pool, the inner loop runs serially on each worker. If the outer loop runs serially in the client (e.g., parfor specifying zero workers), the function that contains the inner loop can run the inner loop in parallel on workers in a pool.

The body of a parfor-loop can contain for-loops. You can use the inner loop variable for indexing the sliced array, but only if you use the variable in plain form, not part of an expression. For example:

A = zeros(4,5);
parfor j = 1:4
    for k = 1:5
        A(j,k) = j + k;
    end
end
A

Further nesting of for-loops with a parfor is also allowed.

Limitations of Nested for-Loops

For proper variable classification, the range of a for-loop nested in a parfor must be defined by constant numbers or variables. In the following example, the code on the left does not work because the for-loop upper limit is defined by a function call. The code on the right works around this by defining a broadcast or constant variable outside the parfor first:

InvalidValid
A = zeros(100, 200);
parfor i = 1:size(A, 1)
   for j = 1:size(A, 2)
      A(i, j) = plus(i, j);
   end
end
A = zeros(100, 200);
n = size(A, 2);
parfor i = 1:size(A,1)
   for j = 1:n
      A(i, j) = plus(i, j);
   end
end

The index variable for the nested for-loop must never be explicitly assigned other than in its for statement. When using the nested for-loop variable for indexing the sliced array, you must use the variable in plain form, not as part of an expression. For example, the following code on the left does not work, but the code on the right does:

InvalidValid
A = zeros(4, 11);
parfor i = 1:4
   for j = 1:10
      A(i, j + 1) = i + j;
   end
end
A = zeros(4, 11);
parfor i = 1:4
   for j = 2:11
      A(i, j) = i + j - 1;
   end
end

If you use a nested for-loop to index into a sliced array, you cannot use that array elsewhere in the parfor-loop. In the following example, the code on the left does not work because A is sliced and indexed inside the nested for-loop; the code on the right works because v is assigned to A outside the nested loop:

InvalidValid
A = zeros(4, 10);
parfor i = 1:4
    for j = 1:10
        A(i, j) = i + j;
    end
    disp(A(i, 1))
end
A = zeros(4, 10);
parfor i = 1:4
    v = zeros(1, 10);
    for j = 1:10
        v(j) = i + j;
    end
    disp(v(1))
    A(i, :) = v;
end

Inside a parfor, if you use multiple for-loops (not nested inside each other) to index into a single sliced array, they must loop over the same range of values. Furthermore, a sliced output variable can be used in only one nested for-loop. In the following example, the code on the left does not work because j and k loop over different values; the code on the right works to index different portions of the sliced array A:

InvalidValid
A = zeros(4, 10);
parfor i = 1:4
   for j = 1:5
      A(i, j) = i + j;
   end
   for k = 6:10
      A(i, k) = pi;
   end
end
A = zeros(4, 10);
parfor i = 1:4
   for j = 1:10
      if j < 6
         A(i, j) = i + j;
      else
         A(i, j) = pi;
      end
   end
end

Nested spmd Statements

The body of a parfor-loop cannot contain an spmd statement, and an spmd statement cannot contain a parfor-loop.

Break and Return Statements

The body of a parfor-loop cannot contain break or return statements.

Consider instead using parfeval or parfevalOnAll.

P-Code Scripts

You can call P-code script files from within a parfor-loop, but P-code script cannot contain a parfor-loop.

More About

Was this topic helpful?