How can I fix the warning and the error in parfor?
7 次查看(过去 30 天)
显示 更早的评论
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
How can I fix the warning about a(k) and the error about c(k)?
5 个评论
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
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
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)
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)
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Parallel for-Loops (parfor) 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!