2011-07-16 9 views
5

パラレルモードで実行中のグローバル変数はどうなりますか?MATLAB:パラレルモードで実行しているときにグローバル変数はどうなりますか?

私はグローバル変数 "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 

答えて

6

グローバル変数はのparforループの本体を実行する労働者にMATLABクライアントから渡されません。ループ本体に送信される唯一のデータは、プログラムのテキスト内で発生する変数です。 This blog entryが役に立ちます。

+0

"また、グローバル変数や永続変数をparforループの本体に定義することはできません。ワーカーのグローバル値の変更はローカルグローバル値に自動的に反映されないため、グローバルの使用には注意が必要です。 "しかし、私はpar-forループで "グローバル変数を定義する"ではなく、ワーカーでグローバル変数の値を変更していません。クライアントでグローバル変数を定義し、ワーカーで使用しました。 –

+0

ところで、グローバル変数が明示的に渡されるようにグローバル変数を変更した後、問題は解決しましたが、グローバル変数を介してワーカーに情報を送信できないというMATLABヘルプには書かれていません。 –

+0

コードを明示的に渡すようにコードを修正する方法は?グローバルな構造(ファイルをファイルシステムに書き込むかどうかを決定する)は、グローバル構造に格納されているので、私は労働者を読みたいと思うので、私はそれを求めています。 – Ronny

2

それは本当にの種類によって異なりますあなたが入れている変数です。私は欠陥を指摘するためにあなたのコードをもっと見る必要がありますが、一般的に、複雑な変数が各作業者に渡されると仮定するのは避けてください。言い換えれば、プリミティブは並列ルーチン内で再初期化する必要があるかもしれませんし、特定の関数呼び出しを必要とするかもしれません(関数ハンドルにfevalを使うなど)。

私のアドバイス:RTM

+0

ありがとうございました。私はコードを追加しました。 –

+1

私は元々言ったことを元に戻すつもりです...私は100%確信していませんが、私が理解しているのは、parforループが自分の小さな世界に住み、グローバルな価値が単に渡されないということですこの事実を多くの月前に処理したことを思い出してください)、値はただnullです...したがって、これらのパラメータを明示的に渡すように関数を書き直す必要があります。 – Rasman

+1

回答とコメントをありがとうが、あなたは「RTFM」という言葉を使わなかったことを祈っています。 –

関連する問題