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

5 visualizaciones (últimos 30 días)
Jingtao
Jingtao el 26 de Mzo. de 2024
Comentada: Jingtao el 27 de Mzo. de 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 comentarios
VBBV
VBBV el 26 de Mzo. de 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 el 26 de Mzo. de 2024
Editada: Dyuman Joshi el 26 de Mzo. de 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.

Iniciar sesión para comentar.

Respuesta aceptada

Damian Pietrus
Damian Pietrus el 26 de Mzo. de 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

Más respuestas (0)

Community Treasure Hunt

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

Start Hunting!

Translated by