Reputation: 79
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
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
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