Search code examples
matlabparfor

Unable to write to matrix lines with parfor


How can I write into my result matrix lines using parfor?

Code sample:

xCount = 10;
yCount = 20;
area = xCount*yCount;
PP = nan(area,3);

parfor x = 1:10
    for y = 1:20
        id = y + (x-1)*yCount; % global PP line id.
        z = x^2+y*10; % my stuff to get Z.
        PP(id,:) = [x y z]; % write to PP line
    end
end

The PARFOR loop cannot run due to the way variable 'PP' is used.


Solution

  • I actually says "Valid indices are restricted within PARFOR loops". The reason it says that it that MATLAB iterates through a parfor loop non-consecutive, meaning it can do iterations in semi-random order like 5 2 4 1 3, as opposed to 1 2 3 4 5. This means that in order to know where in PP MATLAB has to store your result, it wants to know before entering the parallel environment that no lines get called by different iterations, as to avoid conflicts when getting results back from the workers.

    The solution will be to structure PP in such a way that it's known beforehand where the indices are stores, e.g. by creating a 2D array to use before the loop to store stuff in:

    xCount = 10;
    yCount = 20;
    area = xCount*yCount;
    PP(xCount,yCount) = 0;
    y=1:yCount;
    
    parfor x = 1:xCount
        z = x^2+y.*10; % my stuff to get Z.
        PP(x,:) = z; % write to PP line
    end
    %// Go to the [x y z] format
    PP = [repmat((1:yCount).',xCount,1),repmat((1:xCount).',yCount,1), PP(:)];
    

    I'd personally not do the last line in this case, since it stores three doubles for each useful value (z), whilst in the 2D matrix that comes out of the loop it only stores 1 double which can be indexed by simply reading PP(x,y). Thus it costs you 3 times the memory to store the same amount of useful data.