parfor
-Loopsparfor
-Loop Variables Are Consecutive Increasing IntegersLoop variables in a parfor
-loop must be consecutive
increasing integers. For this reason, the following examples return
errors:
parfor i = 0:0.2:1 % not integers parfor j = 1:2:11 % not consecutive parfor k = 12:-1:1 % not increasing
iValues = 0:0.2:1; parfor idx = 1:numel(iValues) i = iValues(idx); ... end
parfor
-LoopsWhen MATLAB® recognizes a name in a parfor
-loop
as a variable, the variable is classified in one of several categories,
shown in the following table. Make sure that your variables are uniquely
classified and meet the category requirements. parfor
-loops
that violate the requirement return an error.
Classification | Description |
---|---|
Loop Variables | Loop indices |
Sliced Variables | Arrays whose segments are operated on by different iterations of the loop |
Broadcast Variables | Variables defined before the loop whose value is required inside the loop, but never assigned inside the loop |
Reduction Variables | Variables that accumulates a value across iterations of the loop, regardless of iteration order |
Temporary Variables | Variables created inside the loop, and not accessed outside the loop |
To find out which variables you have, examine the code fragment. All variable classifications in the table are represented in this code:
If you run into variable classification problems, consider these
approaches before you resort to the more difficult method of converting
the body of a parfor
-loop into a function.
If you use a nested for
-loop
to index into a sliced array, you cannot use that array elsewhere
in the parfor
-loop. 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. You can compute an entire row, and then perform a
single assignment into the sliced output.
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 |
The code on the left does not work because the variable x
in parfor
cannot
be classified. This variable cannot be classified because there are
multiple assignments to different parts of x
.
Therefore parfor
cannot determine whether there
is a dependency between iterations of the loop. The code on the right
works because you completely overwrite the value of x
. parfor
can
now determine unambiguously that x
is a temporary
variable.
Invalid | Valid |
---|---|
parfor idx = 1:10 x(1) = 7; x(2) = 8; out(idx) = sum(x); end | parfor idx = 1:10 x = [7, 8]; out(idx) = sum(x); end |
This example shows how to slice the field of a structured
array. See struct
for details.
The code on the left does not work because the variable a
in parfor
cannot
be classified. This variable cannot be classified because the form
of indexing is not valid for a sliced variable. The first level of
indexing is not the sliced indexing operation, even though the field x
of a
appears
to be sliced correctly. The code on the right works because you extract
the field of the struct
into a separate variable tmpx
. parfor
can
now determine correctly that this variable is sliced. In general,
you cannot use fields of struct
s or properties
of objects as sliced input or output variables in parfor
.
Invalid | Valid |
---|---|
a.x = []; parfor idx = 1:10 a.x(idx) = 7; end | tmpx = []; parfor idx = 1:10 tmpx(idx) = 7; end a.x = tmpx; |
You cannot create a structure in a parfor
-loop
using dot notation assignment. In the code on the left, both lines
inside the loop generate a classification error. In the code on the
right, as a workaround you can use the struct
function
to create the structure in the loop or in the first field.
Invalid | Valid |
---|---|
parfor i = 1:4 temp.myfield1 = rand(); temp.myfield2 = i; end | parfor i = 1:4 temp = struct(); temp.myfield1 = rand(); temp.myfield2 = i; end parfor i = 1:4 temp = struct('myfield1',rand(),'myfield2',i); end |
You cannot use structure fields as sliced input or
output arrays in a parfor
-loop. In
other words, you cannot use the loop variable to index the elements
of a structure field. In the code on the left, both lines in the loop
generate a classification error because of the indexing. In the code
on the right, as a workaround for sliced output, you employ separate
sliced arrays in the loop. Then you assign the structure fields after
the loop is complete.
Invalid | Valid |
---|---|
parfor i = 1:4 outputData.outArray1(i) = 1/i; outputData.outArray2(i) = i^2; end | parfor i = 1:4 outArray1(i) = 1/i; outArray2(i) = i^2; end outputData = struct('outArray1',outArray1,'outArray2',outArray2); |
The workaround for sliced input is to assign the structure field to a separate array before the loop. You can use that new array for the sliced input.
inArray1 = inputData.inArray1; inArray2 = inputData.inArray2; parfor i = 1:4 temp1 = inArray1(i); temp2 = inArray2(i); end
parfor
-Loop into a FunctionIf all else fails, you can usually solve variable classification
problems in parfor
-loops by converting the body
of the parfor
-loop into a function. In the code
on the left, Code Analyzer flags a problem with variable y,
but cannot resolve it. In the code on the right, you solve this problem
by converting the body of the parfor
-loop into
a function.
Invalid | Valid |
---|---|
function parfor_loop_body_bad data = rand(5,5); means = zeros(1,5); parfor X = 1:5 % Code Analyzer flags problem % with variable y below y.mean = mean(data(:,X)); means(X) = y.mean; end disp(means); | function parfor_loop_body_good data = rand(5,5); means = zeros(1,5); parfor X = 1:5 % Call a function instead means(X) = computeMeans(data(:,X); end disp(means); % This function now contains the body % of the parfor-loop function meansX = computeMeans(dataX) y.mean = mean(dataX); meansX = y.mean; Starting parallel pool (parpool) using the 'local' profile ... connected to 4 workers. 0.6786 0.5691 0.6742 0.6462 0.6307 |
If you use a name that MATLAB cannot unambiguously distinguish
as a variable inside a parfor
-loop, at parse time
MATLAB assumes you are referencing a function. Then at run-time, if
the function cannot be found, MATLAB generates an error. See Variable Names (MATLAB).
For example, in the following code f(5)
could refer
either to the fifth element of an array named f
,
or to a function named f
with an argument of 5
.
If f
is not clearly defined as a variable in the
code, MATLAB looks for the function f
on the path
when the code runs.
parfor i = 1:n ... a = f(5); ... end
parfor
-loopsThe body of a parfor
-loop must be transparent:
all references to variables must be “visible” in the
text of the code. For more details about transparency, see Ensure Transparency in parfor-Loops.
The body of a parfor
-loop cannot contain global
or persistent
variable
declarations.