2011-07-16 22 views
5

¿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 

Respuesta

6

Las variables globales no son pasados ​​desde el cliente MATLAB para los trabajadores que ejecutan el cuerpo del bucle parfor. Los únicos datos que se envían al cuerpo del bucle son variables que ocurren en el texto del programa. This blog entry podría ayudar.

+0

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

+0

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

+0

¿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

2

que realmente depende del tipo de variable que está ingresando. Necesito ver más de su código para señalar el error, pero en general es una buena práctica evitar asumir que se le pasarán variables complicadas a cada trabajador. En otras palabras, cualquier cosa más que una primitiva puede necesitar ser reinicializada dentro de una rutina paralela o puede necesitar tener llamadas a funciones específicas (como usar feval para los identificadores de funciones).

Mi consejo: RTM

+0

Gracias. He agregado el código. –

+1

Voy a restressar lo que dije originalmente ... aunque no estoy 100% seguro, entiendo que los loops parfor viven en su propio mundo y que los valores mundiales simplemente no se pasan (creo que recuerdo que se trata de este hecho hace muchas lunas) y, por lo tanto, los valores son simplemente nulos ... Por lo tanto, debe volver a escribir su función para pasar explícitamente estos parámetros. – Rasman

+1

Gracias por la respuesta y el comentario, pero me gustaría que no hubiera usado la palabra "RTFM". –

Cuestiones relacionadas