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!
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
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?