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

7 vues (au cours des 30 derniers jours)
Jingtao
Jingtao le 26 Mar 2024
Commenté : Jingtao le 27 Mar 2024
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 commentaires
VBBV
VBBV le 26 Mar 2024
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 le 26 Mar 2024
Modifié(e) : Dyuman Joshi le 26 Mar 2024
"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.

Connectez-vous pour commenter.

Réponse acceptée

Damian Pietrus
Damian Pietrus le 26 Mar 2024
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

Plus de réponses (0)

Catégories

En savoir plus sur Parallel for-Loops (parfor) dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by