Main Content

parfor를 사용하여 파라미터 스윕 중에 플로팅하기

이 예제에서는 파라미터 스윕을 병렬로 수행하고 병렬 계산 중에 진행 내용을 플로팅하는 방법을 보여줍니다. DataQueue를 사용하여 병렬 풀에서 계산하는 동안 결과를 모니터링할 수 있습니다. 또한 DataQueueparfor, parfeval, spmd 같은 병렬 언어 기능과 함께 사용할 수도 있습니다.

이 예제에서는 고전적 시스템인 반데르폴 발진기에서 파라미터 스윕을 수행하는 방법을 보여줍니다. 이 시스템은 두 개의 반데르폴 발진기 파라미터인 μν에 종속된 ODE 세트로 표현할 수 있습니다.

x˙=νy

y˙=μ(1-x2)y-x

parfor 루프를 사용하여 파라미터 μν에 대해 병렬 파라미터 스윕을 수행하면 파라미터 값을 변화시키면서 y의 평균 주기를 구할 수 있습니다. 다음 애니메이션은 로컬 클러스터에서 이 예제를 실행하는 것을 보여줍니다.

파라미터 스윕 값 설정하기

탐색할 파라미터 값의 범위를 정의합니다. 여러 다양한 파라미터 조합을 나타내는 메시그리드를 만듭니다.

gridSize = 6;
mu = linspace(100, 150, gridSize);
nu = linspace(0.5, 2, gridSize);
[M,N] = meshgrid(mu,nu);

결과를 시각화할 곡면 플롯 준비하기

스윕 결과를 저장할 변수를 선언합니다. 초기 곡면이 플로팅되는 것을 방지하기 위해 사전할당에 nan을 사용합니다. 각 파라미터 조합에 대한 스윕의 결과를 시각화하기 위해 곡면 플롯을 만듭니다. 제목, 레이블 및 제한과 같은 설정을 준비합니다.

Z = nan(size(N));
c = surf(M, N, Z);
xlabel('\mu Values','Interpreter','Tex')
ylabel('\nu Values','Interpreter','Tex')
zlabel('Mean Period of  y')
view(137, 30)
axis([100 150 0.5 2 0 500]);

파라미터 스윕 중에 결과를 가져올 수 있도록 DataQueue 설정하기

DataQueue를 만들어 워커에서 클라이언트로 중간 결과를 보냅니다. afterEach 함수를 사용하여 워커가 현재 결과를 보낼 때마다 곡면을 업데이트하는 콜백을 클라이언트에서 정의합니다.

D = parallel.pool.DataQueue;
D.afterEach(@(x) updateSurface(c, x));

파라미터 스윕을 수행하고 결과 플로팅하기

parfor를 사용하여 병렬 파라미터 스윕을 수행합니다. 메시그리드의 각 파라미터 조합에 대해 시스템을 풀고 평균 주기를 계산하도록 워커에 지시합니다. 워커가 계산을 완료하면 즉시 각 반복의 결과를 클라이언트로 다시 보냅니다.

parfor ii = 1:numel(N)
    [t, y] = solveVdp(M(ii), N(ii));
    l = islocalmax(y(:, 2));
    send(D, [ii mean(diff(t(l)))]);
end
Starting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 6).

클러스터로 확장하기

클러스터에 액세스할 수 있는 경우 계산을 확장할 수 있습니다. 이렇게 하려면 이전 parpool을 삭제하고 더 큰 클러스터를 위한 프로파일을 사용하여 새 parpool을 여십시오. 아래 코드에서는 클러스터 프로파일 이름이 'MyClusterInTheCloud'로 표시되어 있습니다. 이 코드를 직접 실행하려면 'MyClusterInTheCloud'를 사용자의 클러스터 프로파일 이름으로 바꿔야 합니다. 워커 개수를 조정합니다. 이 예제에서는 워커가 4개로 표시되어 있습니다. 그리드 크기를 늘려 전체 계산 크기를 늘립니다.

gridSize = 25;
delete(gcp('nocreate'));
parpool('MyClusterInTheCloud',4);
Starting parallel pool (parpool) using the 'MyClusterInTheCloud' profile ...
Connected to the parallel pool (number of workers: 4).

클러스터 프로파일을 설정한 후 파라미터 스윕 코드를 다시 실행하면, 클러스터의 워커가 계산을 수행한 다음 결과가 나오면 이를 MATLAB 클라이언트로 보냅니다. 다음 애니메이션은 클러스터에서 이 예제를 실행하는 것을 보여줍니다.

헬퍼 함수

헬퍼 함수를 만들어 연립방정식을 정의하고 이 연립방정식에 솔버를 적용합니다.

function [t, y] = solveVdp(mu, nu)
f = @(~,y) [nu*y(2); mu*(1-y(1)^2)*y(2)-y(1)];
[t,y] = ode23s(f,[0 20*mu],[2; 0]);
end

DataQueue에 대한 함수를 선언하여 워커에서 가져온 결과로 그래프를 업데이트합니다.

function updateSurface(s, d)
s.ZData(d(1)) = d(2);
drawnow('limitrate');
end

참고 항목