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.
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.
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:
| Invalid | Valid |
|---|---|
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:
| Invalid | Valid |
|---|---|
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:
| Invalid | Valid |
|---|---|
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:
| Invalid | Valid |
|---|---|
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 |
The body of a parfor-loop cannot contain
an spmd statement, and an spmd statement
cannot contain a parfor-loop.
The body of a parfor-loop cannot contain break or return statements.
Consider instead using parfeval or parfevalOnAll.
You can call P-code script files from within a parfor-loop,
but P-code script cannot contain a parfor-loop.