afterEach

Задайте функцию, которая будет вызываться после каждой параллели. Будущее завершается

Описание

пример

outputFuture = afterEach(futures,funtocall,nout) автоматически оценивает funtocall от выходных аргументов каждого из элементов в futures как только они станут готовы. afterEach вызывает funtocall с nout выводит аргументы и создает outputFuture для удержания выходов.

Полезное приложение для afterEach является обновлением пользовательских интерфейсов, таких как графики и приложения во время параллельных расчетов с помощью parfeval. Для примера можно отправить несколько расчеты работникам, используя parfeval и обновляйте свой пользовательский интерфейс, когда каждый из них заканчивает использовать afterEach.

пример

outputFuture = afterEach(futures,funtocall,nout,'PassFuture',passFuture) ведет себя так же, если passFuture является false. Если passFuture является true, afterEach вызывает funtocall на каждом элементе в futures, а не на их выходных аргументах. Это происходит, даже если элементы futures обнаружены ошибки.

Примеры

свернуть все

Можно использовать afterEach для автоматического вызова функций на каждом из результатов parfeval расчеты.

Использование parfeval для вычисления случайных векторов в рабочих. С настройками по умолчанию parfeval создает parpool автоматически, если он уже не создан.

for idx = 1:10
    f(idx) = parfeval(@rand, 1, 1000, 1);
end

Отображение максимального элемента в каждом из этих векторов после их создания. afterEach выполняет указатель на функцию на выходе каждого будущего, когда они станут готовы.

afterEach(f, @(r) disp(max(r)), 0);
    0.9975

    0.9990

    0.9982

    0.9991

    0.9982

    0.9998

    0.9999

    0.9986

    0.9996

    0.9990

Можно комбинировать afterEach и afterAll для автоматического вызова дополнительных функций по результатам фьючерсов. Оба afterEach и afterAll сгенерировать будущие переменные, которые могут быть снова использованы в afterEach и afterAll.

Использование parfeval для вычисления случайных векторов в рабочих. С настройками по умолчанию parfeval создает parpool автоматически, если он уже не создан.

for idx= 1:10
    f(idx) = parfeval(@rand, 1, 1000, 1);
end
Starting parallel pool (parpool) using the 'local' profile ...
connected to 8 workers.

Вычислите самый большой элемент в каждом из этих векторов, когда они станут готовы. afterEach выполняет указатель на функцию на выходе каждого будущего, когда они станут готовы, и создает другое будущее для удержания результатов.

maxFuture = afterEach(f, @(r) max(r), 1);

Чтобы вычислить минимальное значение среди них, вызовите afterAll на этом новом будущем. afterAll выполняет функцию на комбинированных выходных аргументах всех фьючерсов после их завершения. В этом случае afterAll выполняет функцию min на выходах maxFuture после завершения и создает другое будущее для удержания результата.

minFuture = afterAll(maxFuture, @(r) min(r), 1);

Получить результат можно используя fetchOutputs. fetchOutput ждет, пока будущее не завершится, чтобы собрать результаты.

fetchOutputs(minFuture)
ans = 0.9973

Можно проверить результат afterEach по вызову fetchOutputs о его будущей переменной.

fetchOutputs(maxFuture)
ans = 10×1

    0.9996
    0.9989
    0.9994
    0.9973
    1.0000
    1.0000
    0.9989
    0.9994
    0.9998
    0.9999

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

  • Использование afterEach обновлять пользовательский интерфейс после завершения каждого расчета.

  • Использование afterAll обновить пользовательский интерфейс после завершения расчетов.

Использование waitbar чтобы создать указатель на рисунок, h. Когда вы используете afterEach или afterAll, а waitbar функция обновляет указатель на рисунок. Для получения дополнительной информации об указателе объектов смотрите Указатель Объекта Behavior.

h = waitbar(0,'Waiting...');

Использование parfeval вычислить вещественную часть собственных значений случайных матриц. С настройками по умолчанию parfeval автоматически создает параллельный пул, если он еще не создан.

for idx = 1:100
    f(idx) = parfeval(@(n) real(eig(randn(n))),1,5e2); 
end

Можно использовать afterEach для автоматического вызова функций на каждом из результатов parfeval расчеты. Использование afterEach вычислять самое большое значение в каждом из выходных массивов после завершения каждого будущего.

maxFuture = afterEach(f,@max,1);

Можно использовать State свойство для получения статуса фьючерса. Создайте логический массив, где State свойство фьючерсов в f является "finished". Использование mean вычислить долю готовых фьючерсов. Затем создайте анонимную функцию updateWaitbar. Функция изменяет дробную длину полосы ожидания h к части готовых фьючерсов.

updateWaitbar = @(~) waitbar(mean({f.State} == "finished"),h);

Использование afterEach и updateWaitbar чтобы обновить дробную длину полосы ожидания после каждого будущего в maxFuture завершает. Использование afterAll и delete чтобы закрыть панель ожидания после завершения всех расчетов.

updateWaitbarFutures = afterEach(f,updateWaitbar,0);
afterAll(updateWaitbarFutures,@(~) delete(h),0);

Использование afterAll и histogram чтобы показать гистограмму результатов в maxFuture после завершения всех фьючерсов.

showsHistogramFuture = afterAll(maxFuture,@histogram,0);

Когда расчеты для будущих переменных приводят к ошибке, по умолчанию afterEach не вычисляет свою функцию для элементов, которые не смогли выполнить. Если вы хотите обработать любые ошибки, например, у вас есть пользовательский интерфейс, который вы хотите обновить, можно использовать пару "имя-значение" PassFuture. Когда установлено значение trueбудущая переменная передается в функцию обратного вызова. Можно вызвать fetchOutputs на нем обрабатывайте выходы и обрабатывайте любые возможные ошибки.

Отправляйте расчеты рабочим, использующим parfeval. С настройками по умолчанию parfeval создает parpool автоматически, если он уже не создан. Если ваш parfeval расчеты приводят к ошибке, будущим ошибкам переменных и их Error свойство отражает его.

errorFuture = parfeval(@(n) randn(n), 0, 0.5);
wait(errorFuture);
errorFuture.Error
ans = 
  ParallelException with properties:

     identifier: 'MATLAB:NonIntegerInput'
        message: 'Size inputs must be integers.'
          cause: {}
    remotecause: {[1×1 MException]}
          stack: [1×1 struct]

Если вы используете afterEach в этом будущем функция обратного вызова не оценивается на тех элементах в будущем, которые ошибались. В коде ниже, msgbox не выполняется, поскольку будущие ошибки.

afterEach(errorFuture, @() msgbox('Operation completed'), 0);

Чтобы обработать фьючерсы, которые приводят к ошибкам, используйте пару "имя-значение" PassFuture при вызове afterEach. Будущая переменная передается в функцию обратного вызова вместо ее выходов. Функции fetchOutputs о будущей переменной и обрабатывать ее выходы. Если будущее приводит к ошибке, fetchOutputs выдает ошибку, которую можно поймать и обработать. Следующий код показывает диалоговое окно ошибки.

afterEach(errorFuture, @handleError, 0, 'PassFuture', true);

function handleError(f)
    try
        output = fetchOutputs(f);
        % Do something with the output
    catch
        errordlg('Operation failed');
    end
end

Входные параметры

свернуть все

Фьючерсы, заданные как массив parallel.Future. funtocall вызывается на каждом из его элементов, когда они становятся готовы. Вы можете использовать parfeval создать будущее.

Если элемент futures встречается с ошибкой, funtocall не оценивается для этого элемента futuresоднако он оценивается для других элементов futures которые не сталкиваются с ошибками. Чтобы увидеть, есть ли фьючерсы с ошибками, можно проверить Error свойство outputFuture. Это свойство является пустым массивом ячеек, если нет ошибок. Если есть ошибки, это массив ячеек, который содержит столько камеры, сколько фьючерсов в futures. A камеры содержит ошибку, если соответствующий элемент futures обнаружена ошибка, и в противном случае она пуста. Если вы отменяете элемент futuresэто приводит к тому же поведению, как если бы элемент столкнулся с ошибкой.

Пример: future = parfeval(@rand,1,1000,1); afterEach(future,@max,1);

Типы данных: parallel.Future

Функция для выполнения, заданная как функция для вызова выходных аргументов каждого из фьючерсов в futures когда они станут готовы. funtocall оценивается на MATLAB® клиент, а не работники параллельного пула.

Пример: funtocall = @max

Типы данных: function handle

Количество выходов, заданное в виде целого числа, ожидаемое от funtocall.

Пример: afterEach(futures,@max,1)

Типы данных: scalar

Индикатор, заданный как логический скаляр, который определяет тип входных параметров к funtocall. Если установлено значение true, каждое будущее в futures передается в funtocall. В противном случае выходные аргументы каждого будущего в futures передаются в funtocall. Этот аргумент является необязательным и false по умолчанию.

Вы можете использовать этот подход, если хотите обработать любые ошибки. Задайте passFuture на true так что afterEach вызывает funtocall на каждом элементе в futures, даже если они столкнулись с ошибками. Вы должны позвонить fetchOutputs от входного параметра к funtocall для извлечения результатов. Если есть фьючерсы с ошибками, fetchOutputs выдает ошибку, которую можно поймать и обработать.

Пример: afterEach(futures,@(f) disp(fetchOutputs(f)),0,'PassFuture',true)

Типы данных: logical scalar

Выходные аргументы

свернуть все

Будущее, вернувшееся как parallel.Future проведение результатов оценки funtocall на каждом из фьючерсов в futures когда они станут готовы. Чтобы извлечь результаты, вызовите fetchOutputs на outputFuture.

Совет

  • Использовать afterEach на любом из фьючерсов, возвращенных из parfeval, parfevalOnAll, afterAll, afterEach, или массив, содержащий их комбинацию. Для примера используйте afterEach для автоматического вызова большего количества функций в результатах другого afterAll или afterEach. Вы можете вызвать afterEach на фьючерсах до и после их окончания.

  • Использовать cancel о будущем, возвращенном из afterEach для отмены его выполнения. Если вы вызываете afterEach на отмененном будущем, afterEach ведет себя так же, как если бы в будущем произошла ошибка.

См. также

| |

Введенный в R2018a