MATLAB Answers

Giorgia
0

Error: The variable in a parfor cannot be classified

Asked by Giorgia
on 20 Jun 2017
Latest activity Commented on by Eric
on 21 Jun 2017
I've been getting the common "Error: The variable ph_samples_volume in a parfor cannot be classified." and I cannot understand how to fix it. I have been reading the answers to similar questions but I haven't figured out how to apply it for my case. I think it has to do with the way I am slicing my variable but I am not sure how to improve the current slicing. Thank you in advance for your help, Giorgia
x_dim=96;
y_dim=112;
z_dim=96;
nsamples=50;
for i = 1:max_fib
eval(strcat('ph_samples_volume(:,:,:,:,i) = zeros(dimension(1),dimension(2),dimension(3),nsamples);'));
eval(strcat('th_samples_volume(:,:,:,:,i) = zeros(dimension(1),dimension(2),dimension(3),nsamples);'));
end
parfor z=1:z_dim
for x=1:x_dim
for y=1:y_dim
if odf_full(x,y,z) ~= 0 && mask(x,y,z)~=0
%get odf at x,y,z
odf = odfs(:,odf_full(x,y,z)); %odf at [x y z] location
p_idx=index(x,y,z,:)+1;
[ph, th] = find_samples( odf, nsamples, odf_vertices, odf_faces, p_idx); %in deg
curr_fibers=length(p_idx(p_idx~=0)); %number between 1 and 3
for i=1:curr_fibers
peak_number=strcat('peak',num2str(i));
ph_samples=[ph.(peak_number)];
th_samples=[th.(peak_number)];
ph_samples_volume(x,y,z,:,i) = ph_samples; %in deg
th_samples_volume(x,y,z,:,i) = th_samples; %in deg
end
end
end
end
end

  2 Comments

There are some strange details:
1. Why do you use eval without any need here? The strcat inside the eval is applied to one string only, so there is nothing to concatenate. The "for i = 1:max_fib" loop is not useful at all. Use either Eric's suggestion or:
ph_samples_volume = zeros([dimension(1:3), nsamples, max_fib]);
th_samples_volume = zeros(size(ph_samples_volume));
Note: Avoid eval in general. See Answers: No EVAL
2. What is the prupose of the square brackets in:
ph_samples = [ph.(peak_number)];
  1. You are right, The eval was used initially because I was creating structs based on the value of i, but then I changed and forgot to remove the for loop. Now I replaced it with Eric suggestion and I still get the same classification error.
  2. Also residual for past edits, thank you for pointing that out. The current code is now shown below, and I still get the classification error.
x_dim=dimension(1);
y_dim=dimension(2);
z_dim=dimension(3);
nsamples=50;
[ph_samples_volume, th_samples_volume] = deal(zeros(dimension(1),dimension(2),dimension(3),nsamples,max_fib));
parfor z=1:z_dim
for x=1:x_dim
for y=1:y_dim
if odf_full(x,y,z) ~= 0 && mask(x,y,z)~=0
odf = odfs(:,odf_full(x,y,z));
p_idx=index(x,y,z,:)+1;
[ph, th] = find_samples( odf, nsamples, odf_vertices, odf_faces, p_idx);
curr_fibers=length(p_idx(p_idx~=0));
for i=1:curr_fibers
peak_number=strcat('peak',num2str(i));
ph_samples=ph.(peak_number);
th_samples=th.(peak_number);
ph_samples_volume(x,y,z,:,i) = ph_samples;
th_samples_volume(x,y,z,:,i) = th_samples;
end
end
end
end
end

Sign in to comment.

1 Answer

Answer by Eric
on 20 Jun 2017

Try replacing the for loop with the eval() statements with
[ph_samples_volume, th_samples_volume] = deal(zeros(dimension(1),dimension(2),dimension(3),nsamples,max_fib));

  2 Comments

Hello Eric,
Thank you for you suggestion but I still get the same error even with your correction. Any other ideas?
Giorgia
It's hard to debug this without the code, but here are a few thoughts:
1. Can you re-write find_samples() such that it is compatible with parfeval? It seems you would have to pass it x, y, z, odf_full, and mask in addition to the existing inputs. It could then create odf and p_idx itself. It would also need to do the checking of the if statement and return zeros when that case fails.
2. The outer three for loops could be replaced by a single for loop. You could calculate z, x, and y from that single index. My guess is that won't help, though.
3. Is there a way to re-write find_samples such that it returns a matrix rather than a structure? It would allow considerably simpler indexing. I wonder if the anonymous indexing into a structure is causing Matlab grief in classifying variables.
4. Before parallelizing, it's usually worthwhile figuring out where the bottleneck is in the first place. Presumably the bottleneck is the find_samples() function. Is there anything in that code that could be improved? Often times people come to me for help parallelizing code or running it on a cluster when they haven't used the profiler. Once we see what's causing the slowdown, we can often find a solution to the problem that makes parallelizing the code unnecessary. If you haven't profiled your code, I would recommend giving it a try. You can start the profiler by running
profile viewer
at the command prompt.

Sign in to comment.