afterAll

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

Синтаксис

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

Описание

пример

outputFuture = afterAll(futures,funtocall,nout) автоматически оценивает funtocall на выходных аргументах всех фьючерсов в futures, когда они все завершены, и возвращает outputFuture, чтобы содержать результат. afterAll оценивает funtocall на вертикальной конкатенации выходных аргументов всех фьючерсов. Если количество выходных аргументов элементов во фьючерсах отличается, afterAll использует минимум и игнорирует конечные выходные аргументы. afterAll вызывает выходные аргументы funtocall with nout.

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

пример

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

Примеры

свернуть все

Можно использовать afterAll, чтобы автоматически вызвать функции на все объединенные выходные параметры вычислений parfeval.

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

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

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

afterAll(f, @(r) disp(max(r)), 0);
    0.9998

Можно объединить 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);

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

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

errorFuture = parfeval( @(n) randn(n), 0, 0.5);
Starting parallel pool (parpool) using the 'Local' profile ...
connected to 4 workers.
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]

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

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

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

afterAll(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 не вызывается, и outputFuture завершается с ошибкой. Чтобы видеть, завершается ли будущее с ошибкой, можно проверять свойство Error outputFuture. Если вы отменяете элемент futures, это приводит к тому же поведению, как будто элемент столкнулся с ошибкой.

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

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

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

Пример: funtocall = @max

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

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

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

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

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

Можно использовать этот подход, если вы хотите обработать какие-либо ошибки. Установите passFuture на true так, чтобы afterAll вызвал funtocall на выходные параметры futures, даже если они столкнулись с ошибками. Необходимо вызвать fetchOutputs на входном параметре к funtocall, чтобы извлечь результаты. Если будущие результаты по ошибке, fetchOutputs выдает ошибку, которую можно зафиксировать и обработать.

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

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

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

свернуть все

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

Чтобы извлечь результаты, вызовите fetchOutputs на outputFuture:

outputFutures = afterAll(futures,funtocall,nout);
[out1,out2,...,outM] = fetchOutputs(outputFutures);
Обратите внимание на то, что это эквивалентно вызову funtocall после выборки выходных параметров в futures, за исключением того, что afterAll вызывает автоматически funtocall, когда все элементы в futures завершаются:
[tmp1,tmp2,...,tmpN] = fetchOutputs(futures);
[out1,out2,...,outM] = funtocall(tmp1,tmp2,...tmpN)
N является количеством выходных параметров от futures, и M является количеством выходных параметров, заданных в afterAll с входным параметром nout.

Советы

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

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

Смотрите также

| |

Введенный в R2018a