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