How can I fix the warning and the error in parfor?

5 ビュー (過去 30 日間)
Jingtao
Jingtao 2024 年 3 月 26 日
コメント済み: Jingtao 2024 年 3 月 27 日
a = linspace(1,100,100);
parfor i=1:10
for j=1:10
k = (i-1)*10+j;
b = a(k)+5; %// warning
c(k) = b; %// error
end
end
Error: Unable to classify the variable 'c' in the body of the parfor-loop. For more information, see Parallel for Loops in MATLAB, "Solve Variable Classification Issues in parfor-Loops".
How can I fix the warning about a(k) and the error about c(k)?
  5 件のコメント
VBBV
VBBV 2024 年 3 月 26 日
a = linspace(1,100,100);
k = 1;
parfor i=1:10
for j=1:10
c(i,j) = a((i-1)*10+j)+5; %// error
end
end
c = reshape(c,1,[]) % do reshape after the loop computation
c = 1x100
6 16 26 36 46 56 66 76 86 96 7 17 27 37 47 57 67 77 87 97 8 18 28 38 48 58 68 78 88 98
Dyuman Joshi
Dyuman Joshi 2024 年 3 月 26 日
編集済み: Dyuman Joshi 2024 年 3 月 26 日
"This is a simplified code for demonstration. Actually number of the loops is huge."
In that case, please share your original code and specify what the objective is.

サインインしてコメントする。

採用された回答

Damian Pietrus
Damian Pietrus 2024 年 3 月 26 日
The warning about a(k) just means that a is being sent as a broadcast variable. This means that it is sent in its entirety to each worker compared to a sliced input variable, where only the portion of the array needed for calculations is sent to each worker. This is not always a bad thing, so I'm going to skip over this warning.
As for the error with c, this occurs because of the way that MATLAB classifies variables in a parfor loop. To get results out of the loop, you either need to use a reduction variable or a sliced output variable. A sliced output variable is one, that among other things, is indexed into using the parfor loop variable. This means that you'll have to use that loop variable.
I've created two options below that can hopefully help. The first version removes your nested loop entirely, and uses the loop variable to index into c.
% Original code converted to a for-loop
a = linspace(1,100,100);
orig_c = nan(size(a));
for i=1:10
for j=1:10
orig_k = (i-1)*10+j;
orig_b = a(orig_k)+5; %// warning
orig_c(orig_k) = orig_b; %// error
end
end
% Modified parfor loop
a = linspace(1,100,100);
c = nan(size(a));
parfor i=1:100
b = a(i)+5;
c(i) = b;
end
% Check to see if the results are equal
isequal(orig_c, c)
ans = logical
1
If you need the nested loops in your code, you may have to do some refactoring to use the loop index. Here, we are using a some temporary variables and cell arrays to store portions of the output that we can extract from the parfor loop. Later, we combine the results outside of our parfor loop using the temporary results. I haven't timed this, so I'm not sure if this will result in an overall speedup.
% Original code converted to a for-loop
a = linspace(1,100,100);
orig_c = nan(size(a));
for i=1:10
for j=1:10
orig_k = (i-1)*10+j;
orig_b = a(orig_k)+5; %// warning
orig_c(orig_k) = orig_b; %// error
end
end
% Modified parfor loop
a = linspace(1,100,100);
c = nan(size(a));
% Use a temporary cell array to store the results from each iteration
tempResults = cell(1, 10);
% Each iteration writes to its own cell, completely independent of others
parfor i=1:10
% Temporary array for the results in this iteration
tempC = zeros(1, 10);
for j=1:10
b = a((i-1)*10+j)+5;
% Fill the temporary array
tempC(j) = b;
end
% Assign the temporary array to the cell
tempResults{i} = tempC;
end
% After the parfor loop, combine the results from each cell into the output array c
for i=1:10
c((i-1)*10+1:i*10) = tempResults{i};
end
% Check to see if the results are equal
isequal(orig_c, c)
ans = logical
1
  1 件のコメント
Jingtao
Jingtao 2024 年 3 月 27 日
Thanks a lot, Damian.

サインインしてコメントする。

その他の回答 (0 件)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by