parfor
Этот пример показывает, как выполнить сдвиг параметра параллельно и построить график прогресса во время параллельных расчетов. Можно использовать DataQueue
для мониторинга результатов во время расчетов в параллельном пуле. Можно также использовать DataQueue
с параллельными функциями языка, такими как parfor
, parfeval
и spmd
.
Пример показывает, как выполнить свип параметра в классической системе, осцилляторе Ван дер Поля. Эта система может быть выражена как набор ОДУ, зависимых от двух параметров осциллятора Ван дер Поля, и :
Можно выполнить параллельный сдвиг параметра над параметрами и использование parfor
цикл, чтобы узнать средний период при их варьировании. Следующая анимация показывает выполнение этого примера в локальном кластере.
Задайте область значений значений для параметров, которые будут исследованы. Создайте сетку для расчета различных комбинаций параметров.
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
отправлять промежуточные результаты от работников клиенту. Используйте 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
, и откройте новый, используя профиль для вашего большого кластера. В коде ниже показан профиль кластера с именем '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