afterEach

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

Синтаксис

outputFuture = afterEach(futures,funtocall,nout)
outputFuture = afterEach(futures,funtocall,nout,'PassFuture',passFuture)

Описание

пример

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, и оставить пользовательский интерфейс быстро реагирующим. Используйте afterEach, чтобы обновить пользовательский интерфейс, когда промежуточные вычисления будут готовы. Используйте afterAll, чтобы обновить пользовательский интерфейс, когда все вычисления будут готовы.

Создайте простой пользовательский интерфейс с помощью waitbar.

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

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

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

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

maxFuture = afterEach(f, @max, 1);
updateWaitbarFuture = afterEach(f, @(~) waitbar(sum(strcmp('finished', {f.State}))/numel(f), h), 1);

Закройте waitbar, когда все вычисления будут сделаны. Используйте afterAll на updateWaitbarFuture, чтобы продолжиться автоматически операцией закрытия. afterAll получает указатель фигуры из updateWaitbarFuture и выполняет его функцию на нем.

closeWaitbarFuture = afterAll(updateWaitbarFuture, @(h) delete(h), 0);

Покажите гистограмму после того, как все максимальные значения будут вычислены. Используйте afterAll на maxFuture, чтобы продолжить операцию автоматически. afterAll получает максимальные значения из maxFuture и вызывает histogram на них.

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. Ячейка содержит ошибку, если соответствующий элемент 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