Cell array use, indexing and slicing in parallelization
11 次查看(过去 30 天)
显示 更早的评论
I have a problem with the parfor loop below. Essentially I get the following error: "Error: Unable to classify the variable 'inter_cnt' in the body of the parfor-loop."
I have tried to include enough information so that other variables make sense, while not distracting from the point.
I think it might be a problem with "slicing", because I know that you need to slice your variables properly when using a parfor.
If I comment out the "inter_cnt(...)" line (see code for relevant comment at the end of the while loop), then the code runs.
Please let me know if anymore information is necessary
% initializing first page of cell array
inter_cnt={'energy',enr(1);'coherent', 0;'compton', 0;'photoelectric', 0;'pair-triplet', 0;};
% re setting interaction counter for all other energies (pages)
for i= 2:length(enr)
inter_cnt_intermediate = {'energy',enr(i);'coherent', 0;'compton', 0;'photoelectric', 0;'pair-triplet', 0;};
inter_cnt=cat(3,inter_cnt,inter_cnt_intermediate);
end
N_particles = 0;
parfor j = 1:length(enr)
particle_num = 0;
while particle_num <= N_particles % a while loop that loops for each step the particle takes
% select the interaction
intr_gen = rand; % generate a random number
inter_type = interaction_selector(enr(j),intr_gen,M,mu_t); % call the interaction selector function
index_for_cell_interaction = find(strcmp([inter_cnt(:,1,1)], inter_type)); % finds the right index in the cell array containing the counts of each interaction
index_for_cell_energy = find([inter_cnt{1,2,:}] == enr(j)); % finds the right index in the cell array containing the counts of each interaction
inter_cnt{index_for_cell_interaction,2,index_for_cell_energy} = inter_cnt{index_for_cell_interaction,2,index_for_cell_energy} + 1; % increases the count for the interaction type that was chosen by interaction selector
% commenting out the above ^ line, the code runs without error
particle_num = particle_num+1;
end
end
0 个评论
采纳的回答
Walter Roberson
2022-4-2
Inside the parfor loop, you can write to local variables all you want, but sometimes parfor will require you to clearly initialize the local variable inside the parfor loop in order for it to be certain that you mean the variable to be local.
Inside the parfor loop, you can write to non-local variables using indices that involve the parfor loop index variable only once, in form that must be equivalent to constant*variable+constant, and all other indices for the variables must be constant or : . And you cannot write to two different locations inside the same non-local variable inside the loop.
inter_cnt{j, 1} = 3; %okay in itself
inter_cnt{j, 2} = 4; %fail, can only write to one part of the variable in the same loop
Your index_for_cell_energy is calculated independent of your loop variable j, and also could refer to several different rows (parfor has no way of knowing that your strings are unique). Your index_for_cell_energy is calculated independent of your loop variable j, and also could refer to several different columns (no inherent reason why find([inter_cnt{1,2,:}] == enr(j)) would be scalar.) You are literally writing to one or more random locations in the array.
There is no this can be made to work with parfor in the form given.
What can be done, is instead of doing the increment of inter_cnt inside the parfor loop, just keep track of the index_for_cell_interaction and index_for_cell_energy (and make sure they are scalar.) Like
index_for_cell_interaction(j) = find(strcmp([inter_cnt(:,1,1)], inter_type)); % finds the right index in the cell array containing the counts of each interaction
index_for_cell_energy(j) = find([inter_cnt{1,2,:}] == enr(j)); % finds the right index in the cell array containing the counts of each interaction
then after the loop, use sparse() or accumarray() to total the counts.
4 个评论
Walter Roberson
2022-4-3
Create a per-slice output, and assign to it at the end of the loop. For example, initialize inter_cnt just inside the start of the parfor and then at the end
all_inter_cnt(j) = inter_cnt;
then outside the parfor, do whatever is appropriate to bring the results all together, such as
cat(4, all_inter_cnt{:})
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Matrix Indexing 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!