In the following parfor loop, Matlab says the variable 'sf' cannot be classified. However, the way it is defined inside the innermost loop doesn't seem to affect parfor. Could you tell me the issue and show me how this code snippet should be modified?
parfor ii=1:1:10000
for jj=1:200
for kk=1:80
sf{kk}=fit([kk*dKy;(kk+1)*dKy],[result{kk}(ii);result{kk+1}(ii)],'exp1','lower',[kk*dKy,result{kk}(ii)]);
fun=#(t) sf{kk}(t).*cos(Ky(kk).*t);
result2{ii}(jj)=0;
result2{ii}(jj)=result2{ii}(jj)+integral(fun,Ky(kk),Ky(kk+1),'ArrayValued',true)/(2*pi);
end
end
end
Related
I am trying to use a for loop inside of a parfor loop in Matlab.
The for loop is equivalent to the ballode example in here.
Inside the for loop a function ballBouncing is called which is a system of 6 differential equations.
So, what I am trying to do is to use 500 different sets of parameter values for the ODE system and run it, but for each parameter set, a sudden impulse is added, which is handled through the code in 'for' loop.
However, I don't understand how to implement this using a parfor and a for loop as below.
I could run this code by using two for loops but when the outer loop is made to be a parfor it gives the errors,
the PARFOR loop cannot run due to the way variable results is used,
the PARFOR loop cannot run due to the way variable y0 is used and
Valid indices for results are restricted in PARFOR loops
results=NaN(500,100);
x=rand(500,10);
parfor j=1:500
bouncingTimes=[10,50];%at time 10 a sudden impulse is added
refine=2;
tout=0;
yout=y0;%initial conditions of ODE system
paras=x(j,:);%parameter values for the ODE
for i=1:2
tfinal=bouncingTimes(i);
[t,y]=ode45(#(t,y)ballBouncing(t,y,paras),tstart:1:tfinal,y0,options);
nt=length(t);
tout=[tout;t(2:nt)];
yout=[yout;y(2:nt,:)];
y0(1:5)=y(nt,1:5);%updating initial conditions with the impulse
y0(6)=y(nt,6)+paras(j,10);
options = odeset(options,'InitialStep',t(nt)-t(nt-refine),...
'MaxStep',t(nt)-t(1));
tstart =t(nt);
end
numRows=length(yout(:,1));
results(1:numRows,j)=yout(:,1);
end
results;
Can someone help me to implement this using a parfor outer loop.
Fixing the assignment into results is relatively straightforward - what you need to do is ensure you always assign a whole column. Here's how I would do that:
% We will always need the full size of results in dimension 1
numRows = size(results, 1);
parfor j = ...
yout = ...; % variable size
yout(end:numRows, :) = NaN; % Expand if necessary
results(:, j) = yout(1:numRows, 1); % Shrink 'yout' if necessary
end
However, y0 is harder to deal with - the iterations of your parfor loop are not order-independent because of the way you're passing information from one iteration to the next. parfor can only handle loops where the iterations are order-independent.
The following code shows this error
Error: The variable out in a parfor cannot be classified.
N=5;
ini = 3;
l=ini:(N+ini-1);
out=cell(1,N);
parfor i=l
out{i+(1-ini)} = func(i);
end
The problem occurs when a variable like ini is an index of any variable inside a parfor loop.
Can ini be introduced in such way that the code works without changing the structure?
MATLAB version R2017a.
I would like to run a Simulink model in a parfor loop on many cores with different data. However, I could not get the sim results when I use parfor whereas I can obtain them while using only for loop.
It simply get [t,u] from workspace1, consider a transfer function n{1}/d{1} and then calculates the EqFracInt to workspace2.
The problematic part of my code is
...
parfor ieq=1:1
assignin('base','t',t);
assignin('base','u',u);
assignin('base','n',n);
assignin('base','d',d);
assignin('base','T_end',T_end);
[simout] = sim('RespSpecFrac', [0 T_end], simset('ReturnWorkspaceOutputs','on'));
PGRs = simout.get('EqFracInt');
end
I could not get the PGRs values. Could you please explain the error to me and how to solve it?
The cause you can't get PGRs values is that is a temporary variable. Since in a parfor loop each iteration is independent, any variable assigned directly inside the loop without indexing is used only in that specific iteration and destroyed.
In order to get the desired values, you need to transform PGRs in either a sliced variable (by indexing it) or in a reduction variable (by, for example, concatenating it). Try to modify the last line of your loop following one of these examples:
PGRs(ieq, :) = simout.get('EqFracInt'); % sliced variable
or
PGRs = [PGRs; simout.get('EqFracInt')]; % reduction variable
The specific implementation will depend on the shape of the expected outputs EqFracInt, of course. You can see more about types of variables inside a parfor loop in the documentation.
This question already has an answer here:
parfor in matlab. sliced variable and nested loop
(1 answer)
Closed 7 years ago.
Consider the following code in MATLAB:
function parallelProblem
N = 10;
A = rand(N);
parfor i=1:N
for k=2:N
A(i,k) = f(A(i,k-1));
end
end
end
function y=f(x)
y = x;
end
This is a summary of the problematic code I'm working on. Basically the idea is the following: I have to variables iand kand I can perform my computation with no communication between different i, but communication between different values of kis required.
Therefore I want to parallelize the loop over i. However, for the code above I get the error
parallelProblem
Error: File: parallelProblem.m Line: 6 Column: 9
The variable A in a parfor cannot be classified.
See Parallel for Loops in MATLAB, "Overview".
Hovering over the word parfor (which is underlined) gives
The PARFOR loop can not run due to the way the variable 'A' is used.
and hovering over f(A(i,k-1)) gives
Valid indices for 'A' are restricted in PARFOR loops
and
In PARFOR loop, variable 'A' is indexed in different ways, potentially causing dependencies between iterations.
From an intuitive point of view, I see no reason why the code should be working in parallel. Is there any way, I can modify my code to get the desired result?
The problem is that you are overwriting A. Loops in a parfor are not executed in order and MATLAB sees that you are overwriting the values of A, and then using them. You can easily fix this using an auxiliary variable:
function parallelProblem
N = 5;
A = magic(N);
Aresult=[];
parfor i=1:N,N
b=[];
for k=2:N
b(k) = f(A(i,k-1));
end
Aresult(i,:)=b;
end
end
The following code:
matlabpool('open','local',2)
parfor i=1:5
proc = System.Diagnostics.Process;
end
results in an error:
Error: MATLAB cannot determine whether "System" refers to a function or variable.
However, when I execute the parfor loop again (after the error), it runs through! I found a couple of similar questions, but I wasn't able to implement the suggested solutions.
MATLAB parfor - cannot determine whether "ModelUtil" refers to a function or variable?
MATLAB using parfor (parallel computing toolbox) and custom packages with +
I can't wrap my mind around why the loop runs the second time. If I then call
matlabpool close
and execute the whole script again, the error appears once again. So it only happens the first time after the pool was initiated. Any ideas?
This is because any variable or function you use in a parfor loop must be defined explicitly in the code at parsing time. If there is any ambiguity, Matlab opt to throw an error rather than messing up by assuming.
Just define an anonymous function that create the object you want before the parfor loop, then you can use it as will within the parfor loop.
This run fine on my machine (Matlab R2013a):
getSystemProcess = #() System.Diagnostics.Process ;
parfor i=1:5
proc = getSystemProcess();
end
Read this Matlab chapter for more informations on how the variable/function names are interpreted in a parfor loop: Unambiguous Variable Names