parfor: unable to classify

6 views (last 30 days)
alpedhuez
alpedhuez on 3 Aug 2020
Commented: alpedhuez on 4 Aug 2020
I got the following error message for parfor. Please advise.
Error: Unable to classify the variable 'x' in the body of the parfor-loop. For more information, see Parallel for Loops in MATLAB, "Solve Variable Classification Issues in parfor-Loops".
  3 Comments
alpedhuez
alpedhuez on 3 Aug 2020
Can I send you mix file?
Rik
Rik on 3 Aug 2020
You can post your code here. Then other people can answer your question as well.

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 4 Aug 2020
The majority of "Unable to classify" errors that can be solved without a large rewrite, can be solved by steps similar to these:
  1. Find all input variables that are indexed by the parfor index variable. If the indexing expression that uses the parfor index variable is not just the variable name by itself, or the variable name plus a simple literal constant, then you probably have problems with your indexing. There is a bit more freedom than just "index variable" or "index variable plus simple constant", so sometimes something more is permitted. If you have the same input variable being indexed by two different expressions involving the parfor variable, you probably have indexing problems.
  2. For all of those input variables, extract the entire row or column indexed by that expression, into a separate variable. When you extract, you can use constant indices for anything that is always constant in the code. For example if the code always refers to x(7,k,something) then use x7k = squeeze(x(7,k,:))
  3. For all output variables that are indexed by the parfor index variable, prepare a local variable of the correct size and type matching what is indexed. For example if all the assignments were to x(8,k,something) and you do not read from x(8,k,something), then prepare x8k = zeros(1,size(x,3)) ahead of time.
  4. If there are any variables where you assign to part of a row or column but not the whole thing, and do not read from the rest of the row or column, then treat the row or column as an input variable and read the whole thing, even the parts you are not going to examine or write to in your code. For example if you assign to x(k,1:5) but not to x(k,6:8) then even if you do not read from x before assigning to it, you should xk = x(k,:) near the top of your parfor loop.
  5. Any variable you both read from and write to, treat like the input variables -- make a copy of the entire row or column that is indexed by the parfor variable.
  6. Now, inside your parfor loop, everywhere where you would have read from the input variable, read instead from the temporary copy you made of the row or column, without using the loop index. For example instead of x(k,4) then if you did xk = x(k,:); then read from xk(4) or xk(1,4)
  7. Likewise, inside the parfor loop, everywhere where you would have written to an output variable, instead write to the local variable.
  8. Just before the end of your parfor loop, write copy the output variables to the entire row or column of the appropriate variable, indexed by the appropriate parfor index expression (preferably just the plain index variable name.) For example if before you assigned to x(k,1:5) but not x(k,6:8) then following the above instructions at the top of the loop you would have done xk = x(k,:), and inside the loop you would have written to xk(1:5). And just before the end of the parfor, you would do x(k,:) = xk; to write the entire row back -- including the elements you know you would not have changed. Do not try to be "smart" about which portions you output: just assign the entire temporary variable back to the appropriate place. This is simple and parfor can understand it easily. The more logic you add to only write to part of the row or column, the less likely parfor is to be willing to process the operations.
  9. If you have variables or sections of variable that are only written to conditionally, perhaps only updated under uncommon circumstances, it is still cleaner to create the temporary output variable (possibly copying the entire row or column into it if you only update part of the row or column), as-if you were almost certain to be making the changes. Then at the end, go ahead and blindly write the values back whether you changed them or not. Again, this is simple and parfor can understand it easily. However, if the amount of data that you would be writing back is "large", then you could set a temporary value to false, and then set the value to true if it turns out you do change the data, and then at the end of the loop write back the entire temporary variable only if the temporary flag variable is true.
  10. Only have one place in the parfor loop that reads from a given input variable or writes to the output variable. You can read or write the temporary variables all you want, but grab the entire chunk that you might want to look at in the loop, and write the entire chunk of the variable. For example, no kx1 = x(k,1:2); xk3 = x(k,3:4): instead xk = x(k,:) xk1 = xk(1:2); xk3 = xk(3:4);
The above steps are good enough to clear up a lot of different problems in variable classification, by simplifying the accesses: parfor can see clearly which section of the variables are being read from or written to and can arrange to send only that part between processes. Do not make parfor try to do dynamic analysis to figure out whether the reading and writing is permitted: make it so simple that parfor can just static analysis.
There are some computation sequences that the above steps cannot solve. In particular, if your for loop updated a variable and later iterations use the updated variable, then you cannot do the calculation with parfor (not unless you can rewrite it in terms of "reduction" variables.) For example, if you had x(k+1) = x(k) + 0.01; then parfor cannot handle that, and you would have to rewrite it to something like xmin = x(1); %before the parfor; xk = k * 0.01 + xmin; %this can be evaluated no matter what order you execute the loops in.

More Answers (0)

Categories

Find more on Parallel for-Loops (parfor) in Help Center and File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!