【问题标题】:MATLAB: What happens for a global variable when running in the parallel mode?MATLAB:在并行模式下运行时,全局变量会发生什么?
【发布时间】:2011-07-16 04:11:05
【问题描述】:

在并行模式下运行时全局变量会发生什么?

我有一个全局变量“to_be_optimized_pa​​rameterIndexSet”,它是一个索引向量,应该使用 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.

我检查了所有代码以确保我没有在其他任何地方更改此全局变量。

我有一个四核处理器。

错误在哪里?有什么建议吗?

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

适应度函数“PF_gaMultiFitness”的MATLAB代码:

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

【问题讨论】:

    标签: global-variables parallel-processing matlab


    【解决方案1】:

    全局变量不会从 MATLAB 客户端传递给执行 PARFOR 循环体的工作人员。唯一发送到循环体的数据是程序文本中出现的变量。 This blog entry 可能会有所帮助。

    【讨论】:

    • 它说,“此外,您不能在 parfor 循环的主体内定义全局变量或持久变量。我还建议小心使用全局变量,因为工人全局值的变化不是自动反映在本地全局值中。”但是,我没有在 par-for 循环中“定义全局变量”,也没有更改 worker 中全局变量的值。我在客户端上定义了全局变量,只是在 worker 中使用它们。
    • 顺便说一句,在修改了全局变量以使它们显式传递之后,问题已解决,但在 MATLAB 帮助中没有写到您无法通过全局变量向工作人员发送信息。
    • 你是如何修改代码以显式传递它们的?我有一个存储在全局结构中的全局配置(是否生成数字,是否将文件写入文件系统),我只想在工作人员身上读取,这就是我问的原因。
    【解决方案2】:

    这实际上取决于您输入的变量类型。我需要查看更多代码以指出缺陷,但一般来说,避免假设复杂的变量将传递给每个工作人员是一个好习惯。换句话说,除了原语之外的任何东西都可能需要在并行例程中重新初始化,或者可能需要进行特定的函数调用(例如使用 feval 函数句柄)。

    我的建议:RTM

    【讨论】:

    • 我要再次强调我最初所说的话......虽然我不是 100% 确定,但我理解的方式是 parfor 循环存在于它们自己的小世界中,而全局值根本不存在t 被传递(我想我记得很多个月前处理过这个事实),所以这些值只是 null ......因此,您需要重写您的函数以显式传递这些参数。
    • 感谢您的回答和评论,但我希望您没有使用“RTFM”这个词。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-16
    • 1970-01-01
    • 2022-10-14
    • 2015-09-14
    • 2014-03-22
    • 1970-01-01
    相关资源
    最近更新 更多