Error during parallel processing in Matlab

2020-05-03 11:51发布

问题:

I have this (quite long) Matlab code with nested loops where I want to parallelize the main time-consuming iteration. The only variable that (apparently) gives me problems is DMax, where I get the error:

Error: The variable DMax in a `parfor` cannot be classified.
See Parallel for Loops in MATLAB, "Overview".

This is a draft of my code:

t0=matrix (Maxiter,1); % This is a big matrix whose dimensions are reported in brachets
Maxiter = 1E6;
DMax = zeros(Maxiter,40);
% Other Stuff
for j=1:269 
     % Do more stuff
     for soil=1:4
        parfor i =1:Maxiter        
            k(i,soil) = a %k is a real number
            a(i,soil) = b %similar to k
            % Do a lot of stuff
            for t= (floor(t0(i,soil))+1):40
                DMax(i,t) = k(i,soil)*((t-t0(i,soil))^a(i,soil));
                % Do some more stuff
            end
        end
    end
end
for time=1:40
   % Do the final stuff
end

I guess the problem is in the way I defined DMax, but I do not know what it could be more precisely. I already looked on the web but with not very satisfying results.

回答1:

It is very clearly described in the documentation that each variable inside parfor must be classified into one of several types. Your DMax variable should be a sliced variable (arrays whose segments are operated on by different iterations of the loop), but in order to be classified as such, all the following conditions must hold:

  • Type of First-Level Indexing — The first level of indexing is either parentheses, (), or braces, {}.
  • Fixed Index Listing — Within the first-level parenthesis or braces, the list of indices is the same for all occurrences of a given variable.
  • Form of Indexing — Within the list of indices for the variable, exactly one index involves the loop variable.
  • Shape of Array — The array maintains a constant shape. In assigning to a sliced variable, the right-hand side of the assignment cannot be [] or '', because these operators attempt to
    delete elements.

Clearly, Fixed Index Listing property does not hold since you reference it as DMax(i,t) where t changes its values. There's an identical example described in the documentation, please pay attention. So one workaround would be to use a temporary variable inside the inner loop, and then assign the whole row back to DMax.

Also note that variable a cannot be classified into any category either. That's not to mention that it's not defined in your example at all. Please read the guide carefully and make sure it can be classified into one of the categories. Rewrite the code if needed, e.g. introducing new temporary variables.

Here's the code where DMax usage is corrected:

Maxiter = 1E6;
t0 = randn(Maxiter,1); % This is a big matrix whose dimensions are reported in brachets
DMax = zeros(Maxiter,40);
% Other Stuff
for j = 1:269 
     % Do more stuff
     for soil = 1:4
        parfor i = 1:Maxiter        
            k(i,soil) = a %k is a real number
            a(i,soil) = b %similar to k
            % Do a lot of stuff
            tmp = zeros(1,40);
            for t = (floor(t0(i,soil))+1):40
                tmp(t) = k(i,soil)*((t-t0(i,soil))^a(i,soil));
                % Do some more stuff
            end
            DMax(i,:) = tmp;
        end
    end
end
for time = 1:40
   % Do the final stuff
end