Effacer les filtres
Effacer les filtres

Parallelizing For Loops - Issue

6 vues (au cours des 30 derniers jours)
Aimee Kessell
Aimee Kessell le 12 Sep 2023
Hi there, I'm attempting to parallelize a nested for loop as seen below that is running linear programs via a Gurobi solver.
for ir = 1:n-1
Aeq = AugS; beq = zeros(m,1);
newRow = zeros(1,n);
newRow(ir) = 1;
AeqNew = [Aeq; newRow];
beqNew = [beq; 1];
Aeqlb = [modelUpd.lb; -1];
Aeqlb(idxCSource) = CsourceLB;
Aeqlb(idxObj) = BiomassLB;
Aequb = modelUpd.ub;
Aineq = [diag(diag(ones(length(modelUpd.rxns)))) -Aequb(1:end);
-diag(diag(ones(length(modelUpd.rxns)))) Aeqlb(1:end-1);
zeros(1,length(modelUpd.rxns)) Aeqlb(end)];
bineq = zeros(size(Aineq,1),1);
for jr = 1:1:n-1
%Build Gurobi model;
modelG.A = sparse([Aineq; AeqNew]);
modelG.rhs = [bineq; beqNew];
modelG.lb = -1000*ones(n,1);
modelG.ub = 1000*ones(n,1);
modelG.sense = [repmat('<',1,size(Aineq,1)) repmat('=',1,size(AeqNew,1))];
%To find the minimum flux values.
f = zeros(1,n);
f(jr) = 1;
modelG.modelsense = 'min';
modelG.obj = f;
params.outputflag = 0;
result = gurobi(modelG,params);
if strcmp(result.status, 'OPTIMAL')
fluxMin1(ir,jr) = result.objval;
else
fluxMin1(ir,jr) = "N/A";
end
%To find the maximum flux values.
f(jr) = 1;
modelG.modelsense = 'max';
modelG.obj = f;
params.outputflag = 0;
result = gurobi(modelG,params);
if strcmp(result.status, 'OPTIMAL')
fluxMax1(ir,jr) = result.objval;
else
fluxMax1(ir,jr) = "N/A";
end
f(jr) = 0;
end
end
Unfortunately, I keep getting the error: 'The PARFOR look cannot run due to the way variable 'modelG' is used.'
However, I cannot fix this variable as I'd seen similarly done as the modelG variable is a structure containing sparse matrices, modelsense options, etc.
Any help with somehow parallelizing this code would be great as it's currently running 8.4 million linear programs which is taking 0.5 secs each -- so I'm looking at a code that is running 3.5 days. :'D
Thanks!

Réponses (3)

Matt J
Matt J le 12 Sep 2023
Modifié(e) : Matt J le 12 Sep 2023
I would use parfor just to run the n gurobi optimizations. After you've collected all the results in a struct array Results(jr), you can post-process them.
modelG.A = sparse([Aineq; AeqNew]);
modelG.rhs = [bineq; beqNew];
modelG.lb = -1000*ones(n,1);
modelG.ub = 1000*ones(n,1);
modelG.sense = [repmat('<',1,size(Aineq,1)) repmat('=',1,size(AeqNew,1))];
modelG.modelsense = 'min';
modelG.obj=zeros(1,n);
params.outputflag = 0;
parfor jr=1:n
mdl=modelG;
mdl.obj(jr) = 1;
s = gurobi(mdl,params);
Results(jr).status=s.status;
Results(jr).optval=s.optval;
end
  1 commentaire
Walter Roberson
Walter Roberson le 13 Sep 2023
Structuring it this way to avoid re-assigning all of those fields is a good idea.

Connectez-vous pour commenter.


Walter Roberson
Walter Roberson le 12 Sep 2023
It looks like it is not treating modelG as a local variable. That implies that there is a reference to modelG either before the parfor or else after the parfor.
I suggest that at the beginning of the for j loop (which is what I presume you are turning into parfor) that you add
modelG = struct();
That will force parfor j to treat modelG as local to the parfor iteration.

Sam Marshalik
Sam Marshalik le 13 Sep 2023
You may be able to put the contents of the parfor-loop into a separate function and calling that function from that parfor-loop. It resolves the error message, but I have not had a chance to run it.

Catégories

En savoir plus sur Parallel for-Loops (parfor) dans Help Center et File Exchange

Produits


Version

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by