МАТЛАБ: Что происходит с глобальной переменной при работе в параллельном режиме? - PullRequest
5 голосов
/ 16 июля 2011

Что происходит с глобальной переменной при работе в параллельном режиме?

У меня есть глобальная переменная "to_be_optimized_parameterIndexSet", которая является вектором индексов, которые должны быть оптимизированы с помощью gamultiobj, и я установил ее значение только в основном скрипте (больше нигде).

Мой код работает правильно в последовательном режиме, но когда я переключаюсь в параллельный режим (используя «matlabpool open» и устанавливая правильные значения для «gaoptimset»), упомянутая глобальная переменная становится пустой (= []) в фитнес-функции и вызывает ошибка:

??? 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.

Я проверил весь код, чтобы убедиться, что я не менял эту глобальную переменную где-либо еще.

У меня есть четырехъядерный процессор.

Где ошибка? Любое предложение?

РЕДАКТИРОВАТЬ 1 : код MATLAB в основном скрипте:

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...

MATLAB-код фитнес-функции "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

Ответы [ 2 ]

6 голосов
/ 18 июля 2011

Глобальные переменные не передаются от клиента MATLAB работникам, выполняющим тело цикла PARFOR.Единственные данные, которые отправляются в тело цикла, это переменные, которые встречаются в тексте программы. Эта запись в блоге может помочь.

2 голосов
/ 17 июля 2011

это действительно зависит от типа переменной, которую вы вводите. Мне нужно увидеть больше вашего кода, чтобы указать на недостаток, но в целом рекомендуется избегать того, чтобы сложные переменные передавались каждому работнику. Другими словами, может потребоваться повторная инициализация чего-либо большего, чем примитив, в параллельной подпрограмме или могут потребоваться специальные вызовы функций (например, использование feval для дескрипторов функций).

Мой совет: RTM

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...