serial to parallel Harmony Search

1 回表示 (過去 30 日間)
khaled
khaled 2013 年 6 月 22 日
HI, i need to convert the following code into parallel by making the for loop (1:N) into parfor but i keep getting errors because the HM, can anyone help me, thank you.
timer=0;
timer2=0;
Dim=500;
ub=100;
lb=-100;
HMS=500;
% HARMONY basic Harmony Search minimization for continuous variables
% Unpack the parameter vector
for f=1:30
tic;
MaxImp = 100000;
HMCR = 0.9;
PAR = 0.3;
% Dimension arrays
N = Dim; % Number of decision variables
HM = zeros(2*HMS,N);
F = zeros(2*HMS,1);
%xnew = zeros(HMS,N);
% Randomly initialize HM, taking care to keep each variable within bounds.
% Evaluate the corresponding objective function values.
HM(1:HMS,:) = lb + (ub-lb).*rand(HMS,N);
F(1:HMS) = sum(HM(1:HMS,:)'.^2);
Convergence = [];
Diversity = [];
[fbest,idxbest] = min(F);
% Loop through MaxImp improvisations
for j = 1 : HMS : MaxImp
% Improvise a new harmony: loop though each variable
b = std(HM(1:HMS,:));
for h = 1 : HMS
for i = 1:N
% Randomly perform one of the three HS operations
if rand < HMCR
% Memory considering: randomly select a note stored in HM
%xnew(h,i) = HM(ceil(rand*HMS),i);
HM(HMS+h,i) = HM(ceil(rand*HMS),i);
if rand < PAR
% Pitch adjusting: randomly adjust the pitch slightly
% within +/- b(i), and ensure bounds are satisfied
%xnew(h,i) = xnew(h,i) + (2*rand-1)*b(i);
HM(HMS+h,i) = HM(HMS+h,i) + (2*rand-1)*b(i);
HM(HMS+h,i) = min(max(HM(HMS+h,i),lb),ub);
end
else
% Random playing: randomly select any pitch within bounds
%xnew(h,i) = lb + rand*(ub-lb);
HM(HMS+h,i) = lb + rand*(ub-lb);
end
end % Finished improvising a new harmony
end
% HM update: check whether the new harmony is better than the worst
% harmony currently in HM
%fnew = f(xnew,function_number) + bias;
F(HMS+1:2*HMS) = sum(HM(HMS+1:2*HMS,:)'.^2);
[F,Index] = sort(F);
HM = HM(Index,:);
[fbest,idxbest] = min(F);
Convergence = [Convergence,fbest];
end % Maximum number of improvisations reached
Convergence = [Convergence,fbest];
timer2=toc;
timer=timer+timer2;
end
timer=timer/30;
disp(timer);

回答 (1 件)

Walter Roberson
Walter Roberson 2013 年 6 月 23 日
You will not be able to use parfor() on that code as-is. You have the line
HM(HMS+h,i) = HM(ceil(rand*HMS),i);
Logically we know that ceil(rand*HMS) is at greatest ceil(1*HMS) and so HMS, and logically we know that for positive "h", HMS+h > HMS and so HMS+h > ceil(rand*HMS) . We can thus see that for any one serial iteration, there is no access conflict, only backwards references. However, for parfor() to be able to analyze the code, the indices of any one array must have fixed offsets to each other (e.g., HMS+h and HMS+h+17 would be fine) or else the indices must be fixed (e.g., HM(3) and HM(HMS+h+17) ).
At the moment, an appropriate code adjustment is not coming to my mind. I suspect it might involve something like reordering the h vs i loops and doing the parfor on the outer one; or perhaps it will involve extracting a row (or column) of HMS into a vector before an inner parfor loop, and then writing it back after the parfor loop. I would need to work out the logic; I am not sure it can be done.
  2 件のコメント
khaled
khaled 2013 年 6 月 23 日
What if we changed the for loops into while loops and just use "matlabpool" will this works?
Walter Roberson
Walter Roberson 2013 年 6 月 23 日
matlabpool() typically has no useful effect unless you call upon a specific parallelizing directive such as parfor or spmd .

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeParallel for-Loops (parfor) についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by