exponenta event banner

Печать во время сдвига параметра с помощью parfeval

В этом примере показано, как выполнить параллельный сдвиг параметров с помощью parfeval и отправить результаты обратно во время вычислений с помощью DataQueue объект. parfeval не блокирует MATLAB, поэтому можно продолжить работу во время выполнения вычислений.

Пример выполняет зачистку параметров в системе Лоренца обыкновенных дифференциальных уравнений, в отношении параметров, и показывает хаотичность этой системы.

ddtx = λ (y-z) ddty = x (start-z) -yddtz = xy-βx

Создать сетку параметров

Определите диапазон параметров, которые требуется исследовать при протягивании параметров.

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 чтобы она открылась в новом окне, за пределами живого сценария. Для визуализации результатов сдвига параметров создайте график поверхности. Обратите внимание, что инициализация 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 функция. 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')

Если для сдвига параметров требуется больше вычислительных ресурсов и у вас есть доступ к кластеру, вы можете увеличить 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

См. также

| | |

Связанные темы