|On this page…|
All workers executing a parfor-loop must have the same MATLAB® search path as the client, so that they can execute any functions called in the body of the loop. Therefore, whenever you use cd, addpath, or rmpath on the client, it also executes on all the workers, if possible. For more information, see the parpool reference page. When the workers are running on a different platform than the client, use the function pctRunOnAll to properly set the MATLAB search path on all workers.
Functions files that contain parfor-loops must be available on the search path of the workers in the pool running the parfor, or made available to the workers by the AttachedFiles or AdditionalPaths setting of the parallel pool.
When an error occurs during the execution of a parfor-loop, all iterations that are in progress are terminated, new ones are not initiated, and the loop terminates.
Errors and warnings produced on workers are annotated with the worker ID and displayed in the client's Command Window in the order in which they are received by the client MATLAB.
The behavior of lastwarn is unspecified at the end of the parfor if used within the loop body.
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 in the MATLAB documentation.) 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
The body of a parfor-loop must be transparent, meaning that all references to variables must be "visible" (i.e., they occur in the text of the program).
In the following example, because X is not visible as an input variable in the parfor body (only the string 'X' is passed to eval), it does not get transferred to the workers. As a result, MATLAB issues an error at run time:
X = 5; parfor ii = 1:4 eval('X'); end
Similarly, you cannot clear variables from a worker's workspace by executing clear inside a parfor statement:
parfor ii= 1:4 <statements...> clear('X') % cannot clear: transparency violation <statements...> end
As a workaround, you can free up most of the memory used by a variable by setting its value to empty, presumably when it is no longer needed in your parfor statement:
parfor ii= 1:4 <statements...> X = ; <statements...> end
Examples of some other functions that violate transparency are evalc, evalin, and assignin with the workspace argument specified as 'caller'; save and load, unless the output of load is assigned to a variable. Running a script from within a parfor-loop can cause a transparency violation if the script attempts to access (read or write) variables of the parent workspace; to avoid this issue, convert the script to a function and call it with the necessary variables as input or output arguments.
Because of the way sliced input variables are segmented and distributed to the workers in the parallel pool, you cannot use a sliced input variable to reference a function handle. If you need to call a function handle with the parfor index variable as an argument, use feval.
For example, suppose you had a for-loop that performs:
B = @sin; for ii = 1:100 A(ii) = B(ii); end
A corresponding parfor-loop does not allow B to reference a function handle. So you can work around the problem with feval:
B = @sin; parfor ii = 1:100 A(ii) = feval(B, ii); end
If you use a function that is not strictly computational in nature (e.g., input, plot, keyboard) in a parfor-loop or in any function called by a parfor-loop, the behavior of that function occurs on the worker. The results might include hanging the worker process or having no visible effect at all.
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.
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:
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
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:
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. For example, 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:
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. 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:
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.
Changes made to handle classes on the workers during loop iterations are not automatically propagated to the client.
You can call P-code script files from within a parfor-loop, but P-code script cannot contain a parfor-loop.
Creating Structures as Temporaries. You cannot create a structure in a parfor-loop by using dot-notation assignment. For example, in the following code both lines inside the loop generate a classification error.
parfor i = 1:4 temp.myfield1 = rand(); temp.myfield2 = i; end
The workaround is to use the struct function to create the structure in the loop, or at least to create the first field. The following code shows two such solutions.
parfor i = 1:4 temp = struct(); temp.myfield1 = rand(); temp.myfield2 = i; end
parfor i = 1:4 temp = struct('myfield1',rand(),'myfield2',i); end
Slicing Structure Fields. You cannot use structure fields as sliced input or output arrays in a parfor-loop; that is, you cannot use the loop variable to index the elements of a structure field. For example, in the following code both lines in the loop generate a classification error because of the indexing:
parfor i = 1:4 outputData.outArray1(i) = 1/i; outputData.outArray2(i) = i^2; end
The workaround for sliced output is to employ separate sliced arrays in the loop, and assign the structure fields after the loop is complete, as shown in the following code.
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, and 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
If you are passing objects into or out of a parfor-loop, the objects must properly facilitate being saved and loaded. For more information, see Understanding the Save and Load Process.
If a variable is initialized before a parfor-loop, then used inside the parfor-loop, it has to be passed to each MATLAB worker evaluating the loop iterations. Only those variables used inside the loop are passed from the client workspace. However, if all occurrences of the variable are indexed by the loop variable, each worker receives only the part of the array it needs. For more information, see Where to Create Arrays.
Running your code on local workers might offer the convenience of testing your application without requiring the use of cluster resources. However, there are certain drawbacks or limitations with using local workers. Because the transfer of data does not occur over the network, transfer behavior on local workers might not be indicative of how it will typically occur over a network. For more details, see Optimizing on Local vs. Cluster Workers.
In versions of MATLAB prior to 7.5 (R2007b), the keyword parfor designated a more limited style of parfor-loop than what is available in MATLAB 7.5 and later. This old style was intended for use with codistributed arrays (such as inside an spmd statement or a parallel job), and has been replaced by a for-loop that uses drange to define its range; see Looping Over a Distributed Range (for-drange).
The past and current functionality of the parfor keyword is outlined in the following table:
|Functionality||Syntax Prior to MATLAB 7.5||Current Syntax|
|Parallel loop for codistributed arrays|
parfor i = range loop body . . end
for i = drange(range) loop body . . end
|Parallel loop for implicit distribution of work||Not Implemented|
parfor i = range loop body . . end