Clear Filters
Clear Filters

Assigning values to a vector out of order in parallel (parfor)

11 views (last 30 days)
I have a code where I'm trying to assign chunks of values to a vector out of order in a parfor loop, where the placement is determined by where I have a 1 in my logicG array, which is filled with only logical values, whose total sum is equal to Samples*D. My function myFunc takes in a vector Xi of length N and outputs a vector of length D. The way this assigning works is that every entry in myVec will be assigned a value exactly once. The error I get when I try to run this is
Error: Unable to classify the variable 'newQoI' in the body of the parfor-loop. For more information, see Parallel for Loops in MATLAB, "Solve Variable Classification Issues in parfor-Loops".
However, I believe that MATLAB thinks I might be trying to assign multiple values in parallel to a single entry in myVec, however this is not the case. In case when hovering my cursor over "parfor" in my code I'm told that: The PARFOR loop cannot run due to the way variable 'myVec' is used
Here is my code. I'm hoping there is an easy way around this.
[H,D] = size(logicG); %
myVec = zeros(Samples*D,1);
N = 5;
parfor i=1:H
Xi = XIUnion(i,:);
logicCols = nonzeros((1:D).*logicG(i,:));
linLocs = sub2ind([H,N],i*ones(length(logicCols),1),logicCols);
funcOut = myFunc(Xi);
myVec(linLocs) = nonzeros(funcOut.*logicG(i,:).');
end

Accepted Answer

Edric Ellis
Edric Ellis on 28 Feb 2023
One of the constraints of parfor is that indexed outputs like myVec must be "sliced" - that means that you must assign only elements in slices defined by the loop variable. In this case, you can work around the limitation by storing up the values to assign and the locations to assign them to, and then apply that later. A bit like this (untested, hope it's about right):
[H,D] = size(logicG); %
myVec = zeros(Samples*D,1);
N = 5;
% Use tmpOut to store the results
tmpOut = cell(H, 2);
parfor i=1:H
Xi = XIUnion(i,:);
logicCols = nonzeros((1:D).*logicG(i,:));
linLocs = sub2ind([H,N],i*ones(length(logicCols),1),logicCols);
funcOut = myFunc(Xi);
% Simply store the locations and values
tmpOut(i,:) = {linLocs, nonzeros(funcOut.*logicG(i,:).')};
end
% Back at the client, apply
for i = 1:H
[linLocs, values] = deal(tmpOut{i,:});
myVec(linLocs) = values;
end

More Answers (0)

Categories

Find more on Parallel for-Loops (parfor) in Help Center and File Exchange

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!