MATLAB: How to convert a for-Loop Into parfor-Loops

for loopparallel computingparfor

Im trying to use parfor-Loop to speed up the computation. Here is the code (a kind of customized pdist function):
for i = 1:size1-1
for j = i+1:size1
index = index + 1;
Y(index) = distance(dataSet(:,:,i),dataSet(:,:,j));
end
end
I'm using parfor for the outer loop, but I got an error message on parfor:
  • "The PARFOR cannot run due the way variable index is used"
  • "The PARFOR cannot run due the way variable Y is used"
and, in the inner loop:
  • "Valid indices for Y are restricted in PARFOR loops"
Both the errors occurred because of the use of the indexes in the inner loop, I can't figure out how to change the code for avoiding this problem. I've read the documentation, but i can't figured out how to convert into a parfor loop. How should I use parfor in this context?

Best Answer

The outputs from parfor loops need to be "sliced" - i.e. one of the subscripts must be the parfor loop index, and the others must be a fixed list of constant subscripts.
In your case, this is a bit tricky because of the structure of your nested loops. Here's one way - I'm converting the doubly-nested loop into a single loop by flattening out the indexing operations, and then using ind2sub to convert back from the flattened index to the co-ordinates.
% linIdxs starts out as a matrix of linear indices
linIdxs = reshape(1:(size1*size1), size1, size1);
% We need the lower triangle of these, and we need the transposed version
% to match the original code's ordering of subscripts
linIdxs = tril(linIdxs', -1);
% Discard the indices that were set to 0 by TRIL
linIdxs(linIdxs == 0) = [];
parfor idx = 1:numel(linIdxs)
% Convert back from a linear index to [i,j] co-ordinate pair
[i,j] = ind2sub([size1, size1], linIdxs(idx));
Y(idx) = distance(dataSet(:,:,i),dataSet(:,:,j));
end