How to solve "parfor cannot be classified" issue?
    6 views (last 30 days)
  
       Show older comments
    
    Xin Shen
 on 4 Oct 2019
  
    
    
    
    
    Commented: Walter Roberson
      
      
 on 1 Nov 2019
            Greetings,
I tried to convert my program with nested for-loops to parfor loop and got error "The variable z in a parfor cannot be classified". I read documents about "Troubleshoot Variables in parfor-Loops". But I don't totally understand it and even I tried different ways, the program still does not work.
Which rule I violate ( the slicing or nested for-loops )? And how to solve it, pack it as a function?
function xhat = eGram(Func,ParaVector,X0,scaling,flag) 
Tol = 1E-7;
% gramian parameters
n = ParaVector(1);
k = ParaVector(2);
% initialization for T for observability
T(:,:,1) = eye(n,n);
Cm = logspace(log10(0.01),log10(1),5) .';
e = eye(n,n);
s = length(Cm);
r = size(T,3);
xhat = zeros(n,n,r*s);
Ts = 0.1;
nu = 600;
[~,~,Y0] = Func(X0);
if scaling
    Y0_ = scale(Y0,Y0,Tol);
else
    Y0_ = Y0;
end
for l=1:r
    for m=1:s
        z = zeros(n,nu*k);
        parfor i=1:n    % !!! Here said variable z does not use
            % apply perturbed initial condition
            initvalue = X0 + Cm(m)*T(:,:,l)*e(:,i);
            [t,X,Y] = Func(initvalue);
            if scaling
                Y_ = scale(Y,Y0,Tol);
            else
                Y_ = Y;
            end
            if flag==0
                for iii = 1:k
                    z(i,nu*(iii-1)+1:nu*iii) = (Y_(:,iii) - Y0_(1,iii))';
                end
            else
                 for iii = 1:k
                    z(i,nu*(iii-1)+1:nu*iii) = (Y_(:,iii) - Y0_(:,iii))';
                end
            end
        end                
        chsi = z*z';
        xhat(:,:,(l-1)*s+m) = 1/(r*s*Cm(m)^2)*Ts*T(:,:,l)*chsi*T(:,:,l)';
        if any(isnan(xhat))
            disp(['l is ' num2str(l)]);
            disp(['m is ' num2str(m)]);
            disp(['i is ' num2str(i)]);
        end
    end
end
end
0 Comments
Accepted Answer
  Walter Roberson
      
      
 on 4 Oct 2019
                         zt = zeros(1, nu*k);
                 for iii = 1:k
                    zt(1,nu*(iii-1)+1:nu*iii) = (Y_(:,iii) - Y0_(1,iii))';
                 end
                 z(ii, :) = zt;
You can probably vectorize. It looks like it would be something like
                 zt = Y_ - Y0_(1,:);
                 z(ii,:) = zt(:);
4 Comments
  Walter Roberson
      
      
 on 1 Nov 2019
				I recomend keeping it simple:
- Try making the parfor index the last index into any variable. In particular, avoid making it the first index, as first index will give you the least efficient memory transfer.
- For each variable that you are reading from, or which you are doing a read/modify/write for, extract all of the variable indexed by the parfor value into a temporary variable, so what you get in the temporary variable is just the parts that have to do with the parfor index
- For each variable that you are writing into but not as a read/modify/write cycle, initialize a temporary variable that is the size of the data related to the slice indexed by the parfor index.
- Manipulate the temporary variables as needed, including writing to them
- For each read/modify/write variable, assign the temporary variable back over the slice indexed by the parfor index; for each variable writing into but not read/modify/write, assign the temporary variable into the output variable indexed by the parfor index.
If you have some very large variables you might need to modify this sequence. If you have particular need for distributed variables instead of sliced variables, then you might need to modify this sequence.
More Answers (0)
See Also
Categories
				Find more on Loops and Conditional Statements in Help Center and File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
