afterAll

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

Описание

пример

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