¿Qué ocurre con una variable global cuando se ejecuta en modo paralelo?MATLAB: ¿Qué ocurre con una variable global cuando se ejecuta en el modo paralelo?
Tengo una variable global, "to_be_optimized_parameterIndexSet", que es un vector de índices que deben optimizarse usando gamultiobj y he establecido su valor solo en el script principal (en ningún otro lugar).
Mi código funciona correctamente en modo serie pero cuando cambio al modo paralelo (usando "matlabpool abierto" y estableciendo valores adecuados para 'gaoptimset') la variable global mencionada se vacía (= []) en la función de adecuación y causa este 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.
He comprobado todo el código para asegurarme de que no he cambiado esta variable global en todos lados.
Tengo un procesador de cuatro núcleos.
¿Dónde está el error? ¿cualquier sugerencia?
EDIT 1: El código de MATLAB en el script principal:
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...
El código MATLAB de la función de aptitud, "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
Dice: "Además, no puede definir variables globales o variables persistentes dentro del cuerpo del ciclo parfor. También sugiero tener cuidado con el uso de globales ya que los cambios en los valores globales en los trabajadores no se reflejan automáticamente en los valores globales locales. " Sin embargo, no estoy "definiendo variables globales" en los ciclos par-for y no he cambiado el valor de las variables globales en los trabajadores. Definí las variables globales en el cliente y las usé en los trabajadores. –
Por cierto, después de modificar las variables globales para que se pasen explícitamente, el problema se resolvió pero aún no está escrito en la ayuda de MATLAB que no se puede enviar información a través de variables globales a los trabajadores. –
¿Cómo es que modificas tu código para pasarlos explícitamente? Tengo una configuración global (ya sea para obtener datos, ya sea para escribir archivos en el sistema de archivos) almacenada en una estructura global, que solo quiero leer sobre los trabajadores, por eso estoy preguntando. – Ronny