- Required (static): If you use a nested for-loop to index into a sliced array, you cannot use that array elsewhere in the parfor-loop.
Variable in parfor cannot be classified, error not shown in editor
    4 views (last 30 days)
  
       Show older comments
    
    Bob photonics
      
 on 28 Jul 2020
  
    
    
    
    
    Commented: Bob photonics
      
 on 6 Aug 2020
            Hey everyone I've been looking at parfor and going through some previously given answers and documentation but I'm having a hard time to figure out what my mistake is.
Error: The variable CFxL_Norm in a parfor cannot be classified.
I do assume that CFxLconst_Norm will give the same error. In my script I first assign 2 empty cell-matrix of size (XX,10) and each cell will contain a matrix (501x401x401), except in the last column the cells will contain 1 simple number.
normalisePerc=[0.2, 0.5, 0.8, 1, 0.01, 0.05, 0.1, 0.3, 0.4, 0.6, 0.7, 0.9]; %values can be changed later on
Lnlp=length(normalisePerc); %Length of the normalise percentage array
CFxL_Norm=cell(Lnlp,8+2); % CFxLight400nm + normaliseperc
CFxLconst_Norm=cell(Lnlp,8+2); % CFxLight400nm + normaliseperc
some other code and then this
A=Ef_Norm{9}; %%% assign variable as temporary for parfor, throwaway afterwards
%Lnlp=length(normalisePerc);  %Same, to not use length but a fixed constant
parfor kk=1:Lnlp
    fprintf('number %i of %i cycles for normalising \n', kk, Lnlp);
    NLP=normalisePerc(kk); %get value from array
    NLPinv=1/NLP; %allows to use multiplication in a few places for an increase in speed
    D=A.*NLPinv;
    D(D > 1) = 2./(1+1./D(D > 1));
    for tt=1:8
        fprintf('number %i of %i steps for normalising \n', tt+(kk-1)*8, Lnlp*8);
        tic
        B=Ef_Norm{tt}.*NLPinv;  %Gives a warning about overhead but not causing problems
        B(B > 1) = 2./(1+1./B(B > 1));
        for qq=1:lyq2 %Would have prefered to use parfor for this loop, lyq2=401. Matlab recommends outer loops only
            CFs=Cafluo_Norm{tt}(:,:,qq)'; %Gives a warning about overhead but not causing problems
            CFxL_Norm{kk,tt}(:,:,qq)=CFs.*B(:,:,qq);
            CFxLconst_Norm{kk,tt}(:,:,qq)=CFs.*D(:,:,qq);
        end
        fprintf('Time needed for this step was: \n');
        toc
    end
    tt=9;
    for qq=1:lyq2 %Also would have prefered to use parfor for this loop but Matlab recommends outer loops only.
        tmp1=Cafluo_Norm{tt}(:,:,qq)'.*D(:,:,qq);
        CFxL_Norm{kk,tt}(:,:,qq)=tmp1;
        CFxLconst_Norm{kk,tt}(:,:,qq)=tmp1;
    end
end
tt=10;
tmpnlp=num2cell(normalisePerc');
CFxL_Norm(:,10)=tmpnlp;
CFxLconst_Norm(:,tt)=tmpnlp;
clear tt kk NLP A B D NLPinv qq CFs tmp1 tmpnlp
fprintf('\n \n \n');
I don't see any of the problems regarding things, like addressing the same cell at the same time or even multiple times. I am also pretty sure the variables are independent of each other. Thus I don't really understand why I'm still getting this error and what I'm doing wrong.
0 Comments
Accepted Answer
  Edric Ellis
    
      
 on 29 Jul 2020
        The code you've shown there isn't complete enough for us to attempt to run and see the error you're encountering. It would be helpful if you could simplify the code to the point where we can try and run it as a for loop before trying a parfor loop.
That said, I think you're hitting one of the restrictions of assigning into sliced variables with nested for loops inside parfor. This doc page has the details. I think the relevant restriction is:
In your code, you've got multiple cases where you're assigning into the sliced outputs. I would recommend trying to change things so that you have only a single assignment statement into your sliced outputs.
4 Comments
  Walter Roberson
      
      
 on 29 Jul 2020
				In the below, I have made the relevant changes only for CFxL_Norm, without looking at the other variables. You probably need to make similar changes for CFxLconst_Norm .
The key here is to use temporary variables to accumulate all partial results, and then have a single assignment statement at the end that changes everything having to do with the variable indexed by the parfor index.
A=Ef_Norm{9}; %%% assign variable as temporary for parfor, throwaway afterwards
parfor kk=1:Lnlp
    fprintf('number %i of %i cycles for normalising \n', kk, Lnlp);
    NLP=normalisePerc(kk); %get value from array
    NLPinv=1/NLP; %allows to use multiplication in a few places for an increase in speed
    D=A.*NLPinv;
    D(D > 1) = 2./(1+1./D(D > 1));
    AAAt = cell(1,9);
    for tt=1:8
        fprintf('number %i of %i steps for normalising \n', tt+(kk-1)*8, Lnlp*8);
        tic
        B=Ef_Norm{tt}.*NLPinv;  %Gives a warning about overhead
        B(B > 1) = 2./(1+1./B(B > 1));
        AAA=zeros(lzq2,lxq2,lyq2); %CHANGE TO ADD THIS, temporary variable
        AAA2=zeros(lzq2,lxq2,lyq2); %CHANGE TO ADD THIS, temporary variable
        for qq=1:lyq2
            CFs=Cafluo_Norm{tt}(:,:,qq)'; %Gives a warning about overhead
            AAA(:,:,qq)=CFs.*B(:,:,qq); %Introduced to remove slicing and indexing issues
            AAA2(:,:,qq)=CFs.*D(:,:,qq); %Introduced to remove slicing and indexing issues
        end
        AAAt{tt}=AAA; %Assign here to actual variable
        CFxLconst_Norm{kk,tt}=AAA2; %Assign here to actual variable
        fprintf('Time needed for this step was: \n');
        toc
    end
    tt=9;
    AAA3=zeros(lzq2,lxq2,lyq2); %Same changes repeated as before
    AAA4=zeros(lzq2,lxq2,lyq2); %same change
    for qq=1:lyq2
        tmp1=Cafluo_Norm{tt}(:,:,qq)'.*D(:,:,qq);
        AAA3(:,:,qq)=tmp1; %same change as before
        AAA4(:,:,qq)=tmp1; %same change
    end
    AAAt{tt}=AAA3; %same change
    CFxLconst_Norm{kk,tt}=AA4; %Same change
    CFxL_Norm(kk,:) = AAAt;
end
tt=10;
tmpnlp=num2cell(normalisePerc');
CFxl_Norm(:,tt)=tmpnlp;
CFxLconst_Norm(:,tt)=tmpnlp;
More Answers (0)
See Also
Categories
				Find more on Loops and Conditional Statements in Help Center and File Exchange
			
	Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

