Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MATLAB parfor slicing issue?

Tags:

matlab

parfor

I have a section of code that finds Harris corners in a sequence of images. I need to do this for 92 images, but it's rather slow. As such, I'd like to run the code in parallel. The code I have below has an error related to the variable "corners"

%% Harris corners
    max_pts = 900;
    corners = zeros(max_pts,2,size(images,3));
    parfor i = 1:size(images,3)
        I = images(:,:,i);
        [y x] = get_corners(I,max_pts);
        corners(1:length(y),:,i) = [y x];
    end

Which says:

MATLAB runs loops in parfor functions by dividing the loop iterations into groups, and then sending them to MATLAB workers where they run in parallel. For MATLAB to do this in a repeatable, reliable manner, it must be able to classify all the variables used in the loop. The code uses the indicated variable in a way that is incompatible with classification. Suggested Action Fix the usage of the indicated variable. For more information about variable classification and other restrictions on parfor loop iterations, see “Classification of Variables” in the Parallel Computing Toolbox documentation.

Any ideas how to fix this?

Thanks!

like image 484
Bradley Powers Avatar asked Mar 06 '11 00:03

Bradley Powers


2 Answers

As mentioned by @Chris, the line

corners(1:length(y),:,i) = [y x];

is the problem. An easy way to make sure corners is sliceable is to use a cell array

max_pts = 900;
cornerCell = cell(size(images,3),1);
parfor i = 1:size(images,3)
    I = images(:,:,i);
    [y x] = get_corners(I,max_pts);
    cornerCell{i} = [y x];
end

If you don't want corners to be a cell array (note that to plot corners for the ith image, you can call imshow(images(:,:,i),[]),hold on, plot(cornerCell{i}(:,1),cornerCell{i}(:,2),'o')), you can always convert back to your original 900-by-2-by-nImages array in a loop that won't cost you any noticeable time:

corners = zeros(max_pts,2,size(images,3));
for i=1:size(images,3)
   corners(1:size(cornerCell{i},1),:,i) = cornerCell{i};
end
like image 117
Jonas Avatar answered Oct 30 '22 17:10

Jonas


First off:

  corners(1:length(y),:,i) = [y x];

That is the problem line.

Did you read the documentation?

http://www.mathworks.com/help/toolbox/distcomp/brdqtjj-1.html#bq_tcng-1

Shape of Array — In assigning to a sliced variable, the right-hand side of the assignment is not [] or '' (these operators indicate deletion of elements).

Shape of Array. A sliced variable must maintain a constant shape. The variable A shown here on either line is not sliced:

A(i,:) = []; A(end + 1) = i;

The reason A is not sliced in either case is because changing the shape of a sliced array would violate assumptions governing communication between the client and workers.

I don't have a good feel for what x and y are, but it should now be clear what the problem is. Can you rewrite this so that you aren't assigning [] to the slice?

like image 23
Chris Avatar answered Oct 30 '22 15:10

Chris