I have written a simple chemical simulation which calculates the properties of a large number of grid-boxes in parallel. Accordingly, I index the Y-dimension using a parallel loop:
function[outputArray] = stackTest()
numX = 10;
numY = 10;
numZ = 10;
outputArray = zeros(numX,numY,numZ);
for iX = 1:numX
parfor iY = 1:numY
coreArray = outputArray(iX,iY,:);
for iZ = 1:numZ
tempNum = iX*iY*iZ;
coreArray(1,1,iZ) = tempNum;
end
outputArray(iX,iY,:) = coreArray;
end
end
end
This works fine. However, I am using booleans to control whether or not certain actions are performed, as shown in the following code. This works fine when using a simple for
loop on Y, but when using parfor
, the code fails with a claim that optionalArg
is not defined:
function[outputArray] = stackTest(controlArg)
numX = 10;
numY = 10;
numZ = 10;
outputArray = zeros(numX,numY,numZ);
if (controlArg)
optionalArg = 10;
end
for iX = 1:numX
parfor iY = 1:numY
coreArray = outputArray(iX,iY,:);
for iZ = 1:numZ
tempNum = iX*iY*iZ;
if controlArg
tempNum = tempNum * optionalArg;
end
coreArray(1,1,iZ) = tempNum;
end
outputArray(iX,iY,:) = coreArray;
end
end
end
stackTest
now works fine if controlArg = true
, but not if controlArg = false
; the only way around it I have found is to define optionalArg
independent of controlArg
. Needless to say this is a simplified version of the problem, but I would be grateful to anyone that can explain this to me; I suspect it's a subset of the problems that parfor
loops have with globals, but since I am defining no globals I'm a little confused.
Regards,
Skipsh
When controlArg
is false, optionalArg
is undefined. I guess MATLAB does not trust you that controlArg
will always be false (and by that, I mean it has no mechanism to deduce it, although for the code above, a human may think it is obvious). Thus, it cannot guarantee that no parfor
iteration needs to know optionalArg
at this point of your code:
if controlArg
tempNum = tempNum * optionalArg;
end
For a quick fix, define optionalArg
without the surrounding if clause -- you check controlArg
again before you use it anyway. Alternatively, try replacing optionalArg
by 10*controlArg
(or all three lines by some mathematical expression that maps 0
(false) to 1 and 1
(true) to your desired value of optionalArg
, e.g. tempNum = tempNum * (controlArg*9+1);
).
btw: Maybe you can tell a bit more about the actual problem (not necessarily in this question). The output array above can be produced by one line of code or two, and I guess one of the advantages of MATLAB, vectorised calculation of many similar operations at once (without explicit parallelisation) can be applied to your problem as well (i.e. you might not need three levels of for
loops.