MATLAB: What happens for a global variable when running in the parallel mode?

眉间皱痕 提交于 2019-12-12 11:13:26

问题


What happens for a global variable when running in the parallel mode?

I have a global variable, "to_be_optimized_parameterIndexSet", which is a vector of indexes that should be optimized using gamultiobj and I have set its value only in the main script(nowhere else).

My code works properly in serial mode but when I switch to parallel mode (using "matlabpool open" and setting proper values for 'gaoptimset' ) the mentioned global variable becomes empty (=[]) in the fitness function and causes this error:

??? Error using ==> parallel_function at 598
Error in ==> PF_gaMultiFitness at 15 [THIS LINE: constants(to_be_optimized_parameterIndexSet) = individual;]
 In an assignment  A(I) = B, the number of elements in B and
 I must be the same.

Error in ==> fcnvectorizer at 17
        parfor (i = 1:popSize)

Error in ==> gamultiobjMakeState at 52
        Score =
        fcnvectorizer(state.Population(initScoreProvided+1:end,:),FitnessFcn,numObj,options.SerialUserFcn);

Error in ==> gamultiobjsolve at 11
state = gamultiobjMakeState(GenomeLength,FitnessFcn,output.problemtype,options);

E    rror in ==> gamultiobj at 238
[x,fval,exitFlag,output,population,scores] = gamultiobjsolve(FitnessFcn,nvars, ...

Error in ==> PF_GA_mainScript at 136
[x, fval, exitflag, output] = gamultiobj(@(individual)PF_gaMultiFitness(individual, initialConstants), ...

Caused by:
    Failure in user-supplied fitness function evaluation. GA cannot continue.

I have checked all the code to make sure I've not changed this global variable everywhere else.

I have a quad-core processor.

Where is the bug? any suggestion?

EDIT 1: The MATLAB code in the main script:

clc
clear
close all

format short g
global simulation_duration % PF_gaMultiFitness will use this variable
global to_be_optimized_parameterIndexSet % PF_gaMultiFitness will use this variable
global IC  stimulusMoment % PF_gaMultiFitness will use these variables

[initialConstants IC] = oldCICR_Constants; %initialize state
to_be_optimized_parameterIndexSet = [21    22    23    24    25    26    27    28    17    20];
LB = [ 0.97667      0.38185      0.63529     0.046564      0.23207      0.87484      0.46014    0.0030636   0.46494      0.82407 ];
UB = [1.8486      0.68292      0.87129      0.87814      0.66982       1.3819      0.64562      0.15456   1.3717       1.8168];
PopulationSize = input('Population size? ') ;
GaTimeLimit = input('GA time limit? (second)  ');
matlabpool open
nGenerations = inf;
options = gaoptimset('PopulationSize', PopulationSize, 'TimeLimit',GaTimeLimit, 'Generations', nGenerations, ...
    'Vectorized','off', 'UseParallel','always');

[x, fval, exitflag, output] = gamultiobj(@(individual)PF_gaMultiFitness(individual, initialConstants), ...
    length(to_be_optimized_parameterIndexSet),[],[],[],[],LB,UB,options);

matlabpool close

some other piece of code to show the results...

The MATLAB code of the fitness function, "PF_gaMultiFitness":

function objectives =PF_gaMultiFitness(individual, constants)
global simulation_duration IC stimulusMoment to_be_optimized_parameterIndexSet
%THIS FUNCTION RETURNS MULTI OBJECTIVES AND PUTS EACH OBJECTIVE IN A COLUMN

constants(to_be_optimized_parameterIndexSet) = individual;
[smcState , ~, Time]= oldCICR_CompCore(constants, IC, simulation_duration,2);
targetValue = 1; % [uM]desired [Ca]i peak concentration
afterStimulus = smcState(Time>stimulusMoment,14); % values of [Ca]i after stimulus
peak_Ca_value = max(afterStimulus); % smcState(:,14) is [Ca]i

if peak_Ca_value < 0.8 * targetValue
    objectives(1,1) = inf;

else
    objectives(1, 1) =  abs(peak_Ca_value - targetValue);
end

pkIDX = peakFinder(afterStimulus);
nPeaks = sum(pkIDX);
if nPeaks > 1
    peakIndexes = find(pkIDX);
    period = Time(peakIndexes(2)) - Time(peakIndexes(1));
    objectives(1,2)  = 1e5* 1/period;

elseif nPeaks ==   1 && peak_Ca_value > 0.8 * targetValue
    objectives(1,2) = 0;
else 
    objectives(1,2) = inf;

end


end

回答1:


Global variables do not get passed from the MATLAB client to the workers executing the body of the PARFOR loop. The only data that does get sent into the loop body are variables that occur in the text of the program. This blog entry might help.




回答2:


it really depends on the type of variable you're putting in. i need to see more of your code to point out the flaw, but in general it is good practice to avoid assuming complicated variables will be passed to each worker. In other words anything more then a primitive may need to be reinitialized inside a parallel routine or may need have specific function calls (like using feval for function handles).

My advice: RTM



来源:https://stackoverflow.com/questions/6715263/matlab-what-happens-for-a-global-variable-when-running-in-the-parallel-mode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!