How do I convert a for-Loop Into parfor-Loops?

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?

 Accepted 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

3 Comments

Thank you! This seem to really solve my problem but the parfor statement throw this error:
Error using parseDistAzInputs (line 46)
Incorrect latitude and longitude data matrices
What does it mean? and how could i avoiding the warning:
The entire array or struct 'dataSet' is a broadcast variable. This might result in unnecessary communication overhead.
Sorry! No error message, my fault. Thank you again!
This is simply an information message telling you that dataSet is a parfor broadcast variable. This means that the whole contents of dataSet are sent to each worker, and that is potentially damaging to performance. I think this is inevitable because of the way your loop is structured (sometimes it is possible to avoid "accidentally" broadcasting data, but this is not one of those cases).

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

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

Start Hunting!