parfeval
В этом примере показано, как выполнить сдвиг параллельного параметра с parfeval
и отправьте результаты назад во время расчетов с DataQueue
объект. parfeval
не блокирует MATLAB, поэтому можно продолжать работу во время выполнения расчетов.
Пример выполняет свип параметра на системе Лоренца обыкновенных дифференциальных уравнений, на параметрах и , и показывает хаотичность этой системы.
Задайте область значений параметров, которые вы хотите исследовать в сдвиге параметра.
gridSize = 40; sigma = linspace(5, 45, gridSize); rho = linspace(50, 100, gridSize); beta = 8/3;
Создайте 2-D сетку параметров при помощи meshgrid
функция.
[rho,sigma] = meshgrid(rho,sigma);
Создайте объект рисунка и установите 'Visible'
на true
чтобы он открылся в новом окне, вне live скрипта. Чтобы визуализировать результаты сдвига параметра, создайте объемную поверхностную диаграмму. Обратите внимание, что инициализация Z
компонент поверхности с NaN
создает пустой график.
figure('Visible',true); surface = surf(rho,sigma,NaN(size(sigma))); xlabel('\rho','Interpreter','Tex') ylabel('\sigma','Interpreter','Tex')
Создайте пул параллельных рабочих мест с помощью parpool
функция.
parpool;
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 6).
Чтобы отправить данные от работников, создайте DataQueue
объект. Настройте функцию, которая обновляет объемную поверхностную диаграмму каждый раз, когда рабочий отправляет данные при помощи afterEach
функция. The updatePlot
функция является вспомогательной функцией, заданной в конце примера.
Q = parallel.pool.DataQueue; afterEach(Q,@(data) updatePlot(surface,data));
После определения параметров можно выполнить сдвиг параллельного параметра.
parfeval
работает более эффективно, когда вы распределяете рабочую нагрузку. Чтобы распределить рабочую нагрузку, сгруппируйте параметры для исследования в разделы. В данном примере разделите на равномерные разделы размера step
при помощи оператора двоеточия (:
). Получившийся массив partitions
содержит контуры разделов. Обратите внимание, что необходимо добавить конечную точку последнего раздела.
step = 100; partitions = [1:step:numel(sigma), numel(sigma)+1]
partitions = 1×17
1 101 201 301 401 501 601 701 801 901 1001 1101 1201 1301 1401 1501 1601
Для оптимальной эффективности попробуйте разделить на разделы:
Достаточно большой, чтобы время расчета было большим по сравнению с накладными расходами на планирование раздела.
Достаточно маленькие, чтобы было достаточно разделов, чтобы все рабочие были заняты.
Чтобы представлять выполнение функций на параллельных работниках и сохранить их результаты, используйте будущие объекты.
f(1:numel(partitions)-1) = parallel.FevalFuture;
Выгрузка расчетов параллельным рабочим с помощью parfeval
функция. parameterSweep
является вспомогательной функцией, заданной в конце этого скрипта, которая решает систему Лоренца на разделе параметров, которые нужно исследовать. У него есть один выходной аргумент, поэтому вы должны задать 1
как количество выходов в parfeval
.
for ii = 1:numel(partitions)-1 f(ii) = parfeval(@parameterSweep,1,partitions(ii),partitions(ii+1),sigma,rho,beta,Q); end
parfeval
не блокирует MATLAB, поэтому можно продолжать работу во время выполнения расчетов. Рабочие вычисляют параллельно и отправляют промежуточные результаты через DataQueue
как только они станут доступными.
Если вы хотите заблокировать MATLAB до parfeval
завершает, используйте wait
функция на будущих объектах. Использование wait
функция полезна, когда последующий код зависит от завершения parfeval
.
wait(f);
После parfeval
завершает расчеты, wait
завершает, и вы можете выполнить больше кода. Для примера постройте график контура полученной поверхности. Используйте fetchOutputs
функция для извлечения результатов, сохраненных в будущих объектах.
results = reshape(fetchOutputs(f),gridSize,[]); contourf(rho,sigma,results) xlabel('\rho','Interpreter','Tex') ylabel('\sigma','Interpreter','Tex')
Если вашему параметру sweep нужно больше вычислительных ресурсов и у вас есть доступ к кластеру, можно масштабировать parfeval
расчеты. Дополнительные сведения см. в разделе Шкале с рабочего стола на кластер.
Задайте вспомогательную функцию, которая решает систему Лоренца на разбиении параметров, которые нужно исследовать. Отправка промежуточных результатов клиенту MATLAB при помощи send
функция на DataQueue
объект.
function results = parameterSweep(first,last,sigma,rho,beta,Q) results = zeros(last-first,1); for ii = first:last-1 lorenzSystem = @(t,a) [sigma(ii)*(a(2) - a(1)); a(1)*(rho(ii) - a(3)) - a(2); a(1)*a(2) - beta*a(3)]; [t,a] = ode45(lorenzSystem,[0 100],[1 1 1]); result = a(end,3); send(Q,[ii,result]); results(ii-first+1) = result; end end
Задайте другую вспомогательную функцию, которая обновляет объемную поверхностную диаграмму при поступлении новых данных.
function updatePlot(surface,data) surface.ZData(data(1)) = data(2); drawnow('limitrate'); end
afterEach
| parallel.pool.DataQueue
| parfeval
| parpool