Pergunta

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

Foi útil?

Solução

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top