Wei Shi
Wei Shi

Reputation: 5055

Using parfor on submatrix in matlab

I have a piece of code that divides a image matrix img into small piece and work on them parallel. But Matlab says parfor loop cannot be used, because the way outC{i,j} is indexed. How do I fix this?

The sub matrices are of different size. If img=[4x7], then

C=[3x3 3x3 3x1;
   1x3 1x3 1x1]

On a side note, I'm not sure if using cell array is a good idea here. If not, feel free to give suggestion on how to divide up the img as well.

C=mat2cell(img, rowSplit, colSplit);
[rowc,colc]=size(C);
outC=cell(rowc,colc);
parfor i=1:rowc
    for j=1:colc
       outC{i,j}=doWork(C{i,j}); 
    end
end

Upvotes: 1

Views: 1032

Answers (3)

Sam Roberts
Sam Roberts

Reputation: 24127

Although there are many answers here that will help in using a parfor block to do what you need, I would think that an even better solution might be to use an spmd block instead.

Rather than splitting your image up into smaller portions within a cell array, consider instead converting it into a distributed array, perhaps distributing in the same portions as you're currently doing. Within the spmd block, you can execute your doWork function, and it will be applied to whatever portion of the (co-)distributed array is present on that worker. Finally you can assemble the results and gather them back to the client.

I find spmd more complex to grasp than parfor, but it's very powerful once you've got the idea of it; and I would think this example might be very conveniently expressed in that form.

Upvotes: 1

Ramashalanka
Ramashalanka

Reputation: 8864

You can use linear indexing for both the input and output.

First I make a pretend input of your shape, and a simple doWork function:

>> C= {rand(3) rand(3) rand(3,1); rand(1,3) rand(1,3) rand(1)};
>> C
C = 
    [3x3 double]    [3x3 double]    [3x1 double]
    [1x3 double]    [1x3 double]    [    0.3922]
>> doWork = @(x)2*x;

Then use linear indexing:

>> outC=cell(size(C));
>> parfor ci=1:numel(C)
     outC{ci} = doWork(C{ci});
   end

A quick check that it's worked:

>> outC{2,1}./C{2,1}
ans =
     2     2     2

Upvotes: 4

Ben Voigt
Ben Voigt

Reputation: 283684

Just build a vector of outputs, and use reshape afterwards to make it into a matrix.

Upvotes: 0

Related Questions