PManjunatha
PManjunatha

Reputation: 79

MATLAB parfor index exceeds the number of array elements

Why MATLAB throws an error even if it shouldn't go to the first case of the switch statement? Below is the minimal example:

mycase = 2;
non_crack_bytes = 1:6000;
syn_crack_bytes = 1:10000;
imgCount = 10000;
parfor j = 1 : imgCount
    switch mycase
        case 1
            if ~(non_crack_bytes(j) == 0)
                % Do something
            else
                continue;
            end
        case 2
            if ~(syn_crack_bytes(j) == 0)
                % Do something
            else
                continue;
            end
    end        
end

The error I am getting is:

Error using ScratchPaperFile>(parfor supply)
Index exceeds the number of array elements (6000).
Error in ScratchPaperFile (line 10)
parfor j = 1 : imgCount

Upvotes: 3

Views: 1533

Answers (2)

Edric
Edric

Reputation: 25140

@David's answer shows a valid workaround, but the reason it works is not quite all that it seems.

To run a parfor loop, MATLAB analyses each variable used within the loop and classifies them. In the original code, non_crack_bytes is classified as a "sliced input" variable - in other words, MATLAB considers that each iteration of the loop needs a single value from non_crack_bytes corresponding to the loop index j. The error occurs long before the worker tries to read from non_crack_bytes - the error occurs on the client trying to send the elements of non_crack_bytes that it thinks the worker will need. (This is why the error mentions "parfor supply", a bit of internal jargon relating to sending sliced loop inputs).

@David's fix introduces an additional access of non_crack_bytes inside the loop which changes it from a "sliced input" variable to a "broadcast" variable. That means that the client sends the whole of non_crack_bytes to each worker. This is why the error doesn't occur, not the careful indexing. In fact, you can just as well fix the loop like this:

parfor j = 1:imgCount
    size(non_crack_bytes); % access whole of non_crack_bytes
    switch mycase
        case 1
            if non_crack_bytes(j) ~= 0
        ... % etc.

It's the access of the whole of non_crack_bytes that forces the analysis to consider it to be a "broadcast" variable, and it's that that prevents the error.

Upvotes: 7

David
David

Reputation: 8459

@Jay-Pi identified the issue in their comment. Matlab is careful with parfor loops, so here you need to make it more explicit that nothing bad can happen.

mycase = 2;
non_crack_bytes = 1:6000;
syn_crack_bytes = 1:10000;
imgCount = 10000;
parfor j = 1 : imgCount
    switch mycase
        case 1
            if j<=numel(non_crack_bytes) & ~(non_crack_bytes(j) == 0)
                % Do something
            else
                continue;
            end
        case 2
            if ~(syn_crack_bytes(j) == 0)
                % Do something
            else
                continue;
            end
    end
end

Upvotes: 3

Related Questions