How do I implement Parfor loop with nested for loops?

조회 수: 14 (최근 30일)
Amir Patel
Amir Patel 2013년 5월 22일
Hi
I'm doing a Brute Force search by varying 5 parameters, running a Simulink model and then calculating a cost function.
I have a Matlab script which contains the following:
simTime = 2; %2 seconds simulation time
N = 5; % number of time step
brakeRange = 0:1/(10-1):1; % Vector of possible brake value (percent)
timeVec = 0:simTime/(N-1):simTime;
leng = length(brakeRange);
data = zeros(leng^N,N+1);
a =1;
tic
for i = 1: leng
s = sprintf('\n Percentage complete = %s % ',num2str((a/leng^N)*100));
disp(s);
for j = 1: leng
for k = 1: leng
for l = 1: leng
for m = 1: leng
% Index input vector
inVec = [brakeRange(i) brakeRange(j) brakeRange(k) brakeRange(l) brakeRange(m)];
% run simulation
simOut = sim(mdl,'SimulationMode','Accelerator','ReturnWorkspaceOutputs', 'on');
% Get cost from simulation
tempJ = simOut.get('cost');
%packing data struct
data(a,:) = horzcat(tempJ(end), inVec);
% increment counter
a = a +1;
end
end
end
end
end
Unfortunately, the code is very slow, so I decided to purchase the Parallel Computing Toolbox. I tried to use Parfor, but I get the error message "the PARFOR loop cannot runt due to the way data is used." I get the same message for the variable 'a'.
I think the problem has to do with sliced variables (?) but I'm not sure as I'm new to Parallel Computing. How does one implement parfor loops with nested for loops?

채택된 답변

Edric Ellis
Edric Ellis 2013년 5월 23일
While you and I can clearly see that each simulation and access into 'data' is independent, unfortunately PARFOR doesn't understand the way you've written things. In general, output variables in PARFOR must be indexed using the loop variable and constant terms only. I would suggest that you should be able to flatten your multiply-nest loop, and then it will be simple to get PARFOR to understand.
The key to flattening in this case is to use MATLAB's IND2SUB which can be used to convert a single counter into a series of subscripts. So, you need something like this
% simSpace is the size of the space you're exploring
simSpace = [leng, leng, leng, leng, leng];
% calculate the total number of simulations
numSims = prod(simSpace);
% pre-allocate data
data = zeros(numSims,N+1);
parfor idx = 1:numSims
% convert scalar index into subscripts
[i, j, k, l, m] = ind2sub(simSpace, idx);
% Index input vector (you should be able to use a single vector
% subscript here, as shown)
inVec = brakeRange([i, j, k, l, m]);
simOut = ...;
data(idx, :) = ...;
end
  댓글 수: 3
Amir Patel
Amir Patel 2013년 5월 23일
Hi Edric
I've accepted this answer because M-Lint isn't complaining anymore.
However, when I try and run the simulation, I get the following message: Error using parallel_function (line 589)
Error evaluating expression 'simTime' for 'StopTime' specified in the
Configuration Parameters dialog for block diagram
'bruteForceModel_NOTAIL': Undefined function or variable 'simTime'.
Error stack:
(No remote error stack)
Error in bruteForce_withoutTail_parfor (line 42)
parfor idx = 1:numSims
'simTime' is declared before the parfor loop, which is why I think it's complaining. How do I pass this value so that all workers have it? Normally, I just declare it at the top of the script.
Thanks in advance,
Amir
Edric Ellis
Edric Ellis 2013년 5월 24일
This page http://www.mathworks.co.uk/help/simulink/ug/running-parallel-simulations.html has details about how to resolve workspace access problems when running Simulink models inside PARFOR.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by