Main Content

afterAll

Run function after all functions finish running in the background

    Description

    B = afterAll(A,fcn,n) returns a Future object B and runs the function fcn automatically after all elements in the Future array A finish.

    MATLAB® runs the function fcn using the concatenated outputs from each element in A. The outputs Y1,...,Ym from each Future object are concatenated vertically, in linear index order. For example, if A is a two-element Future vector with outputs y1 and y2 from the first and second Future objects respectively, MATLAB runs fcn([y1; y2]) after all elements in A finish.

    If the Future array A has M elements, MATLAB runs the function only once. When the scheduled function fcn finishes, the Future object B finishes.

    You create a Future object when:

    • You run a function in the background using backgroundPool.

    • You run a function on a parallel pool when you have Parallel Computing Toolbox™.

      For more information about using afterAll on a parallel pool, see Use afterEach and afterAll to Run Callback Functions (Parallel Computing Toolbox).

    If any of the elements in A encounters an error, afterAll finishes with an error.

    example

    B = afterAll(A,fcn,n,PassFuture=true) runs fcn using A instead of using the concatenated outputs of each element in A.

    example

    Examples

    collapse all

    This example shows how to automatically invoke functions on all of the combined outputs of your parfeval computations.

    Preallocate an array of Future objects, then use parfeval to compute random vectors and retrieve one output. Specify backgroundPool as the first argument to run the function in the background. Repeat 10 times to schedule 10 parfeval computations.

    f(1:10) = parallel.FevalFuture;
    for idx = 1:10
        f(idx) = parfeval(backgroundPool,@rand,1,1000,1);
    end
    wait(f)

    After all the Future objects finish, display the maximum element among all of those vectors.

    The input argument to max is the concatenated output of all the Future objects. Specify the third argument to the afterAll function as 0 to return no outputs from the callback.

    afterAll(f,@(r) fprintf("Maximum element is %1.4f\n",max(r)),0);

    This example shows how to use afterAll to handle errors from functions that run in the background.

    When you call afterAll on Future objects that result in errors, by default, afterAll also errors. If you want to handle any errors in the preceding futures, for example, when you have a user interface that you want to update, you can use the PassFuture argument. When you set PassFuture to true, MATLAB passes the array of Future objects to the callback function. You can interact with the individual elements of the Future array, process the outputs, and handle any possible errors.

    Send computations to the background using parfeval. Some of these computations deliberately result in errors.

    N = 10;
    F(1:N) = parallel.FevalFuture;
    for idx = 1:2:N
        F(idx) = parfeval(backgroundPool,@rand,1,1);
    end
    
    for idx = 2:2:N
        F(idx) = parfeval(backgroundPool,@rand,1,0.1);
    end

    If any of the elements in the preceding futures encounters an error, afterAll finishes with an error. In the code below, afterAll errors. Use the Error property of the afterAll future a to view the error.

    a  = afterAll(F,@mean,1);
    wait(a)
    a.Error
    ans = 
      MException with properties:
    
        identifier: 'MATLAB:parallel:future:PrecedingExecutionErrors'
           message: 'The preceding futures with IDs: 90,91,92,93,94 resulted in an error.'
             cause: {5×1 cell}
             stack: [0×1 struct]
        Correction: []
    
    

    To handle the elements in the preceding futures that have errors, write a callback function that takes in the future array as an input argument. The displayRunSummary helper function determine which futures completed successfully using the Error property and fetches their outputs. It then calculates the mean of the completed runs and displays this information in a user interface, including a table showing the completion status of each computation.

    a2 = afterAll(F,@displayRunSummary,0,PassFuture=true);

    function displayRunSummary(F)
    N = numel(F);
    output = zeros(N,1);
    for idx = 1:N
        f = F(idx);
        field = strcat("Run_",num2str(idx));
        results.(field) = isempty(f.Error);
        if isempty(f.Error)
            output(idx) = fetchOutputs(f);
        end
    end
    meanAll = mean(output,"omitmissing");
    
    fig = uifigure('Position',[100 100 900 250]);
    
    runText = strcat("Number of completed runs = ", ...
        num2str(nnz(output)),"/",num2str(numel(output)));
    uilabel(fig,Text=runText,FontWeight="bold",Position=[25 125 700 100]);
    
    meanText = strcat("Mean of all completed runs = ",num2str(meanAll));
    uilabel(fig,Text=meanText,FontWeight="bold",Position=[25 150 700 100]);
    
    t = struct2table(results);
    t.Properties.RowNames = "Completed";
    uitable(fig,Position=[25 50 850 100],Data=t);
    end

    This example shows how to use afterEach to update a wait bar with the progress of functions running in the background.

    Create a wait bar, w.

    w = waitbar(0,'Please wait ...');

    Set the number of iterations for your for-loop, N. Store the current number of completed iterations, 0, and the total number of iterations, N, in the UserData property of the wait bar.

    N = 20;
    w.UserData = [0 N];

    Run a for-loop with N iterations. In each iteration, use parfeval and backgroundPool to run pause in the background for a random number of seconds. Store each Future object in an array.

    for i = 1:N
        delay = rand;
        f(i) = parfeval(backgroundPool,@pause,0,delay);
    end

    Use the helper function updateWaitbar to update the waitbar after each Future finishes.

    afterEach(f,@(~)updateWaitbar(w),0);

    Use delete to close the wait bar after all the Future objects finish.

    afterAll(f,@(~)delete(w),0);

    Define Helper Function

    Define the helper function updateWaitbar. The function increments the first element of the UserData property, then uses the vector to calculate the progress.

    function updateWaitbar(w)
        % Update a waitbar using the UserData property.
    
        % Check if the waitbar is a reference to a deleted object
        if isvalid(w)
            % Increment the number of completed iterations 
            w.UserData(1) = w.UserData(1) + 1;
    
            % Calculate the progress
            progress = w.UserData(1) / w.UserData(2);
    
            % Update the waitbar
            waitbar(progress,w);
        end
    end

    Input Arguments

    collapse all

    Input Future object, specified as a parallel.Future scalar or array.

    MATLAB runs the function fcn after all elements in A finish.

    • By default, PassFuture is false, and MATLAB runs the callback function using the concatenated outputs Y1,...,Ym from each Future element in A. The outputs Y1,...,Ym from each Future object are concatenated vertically, in linear index order. For example, if A is a two-element Future vector with outputs y1 and y2 from the first and second Future objects respectively, MATLAB runs fcn([y1; y2]) after all elements in A finish.

      If any of the elements in A encounters an error, afterAll finishes with an error.

    • If you specify PassFuture as true, MATLAB runs the callback function as fcn(A).

      If any of the elements in A encounters an error, afterAll does not finish with an error.

    If the Future array has M elements, MATLAB runs the function M times. When the scheduled function fcn finishes, the Future object B finishes.

    Example: A = parfeval(backgroundPool,@magic,1,3);

    Callback function to run, specified as a function handle.

    Example: fcn = @magic

    Number of output arguments, specified as a nonnegative integer scalar.

    • If you specify PassFuture as true, n is the number of output arguments expected from running fcn(A) using the Future array A.

    • Otherwise, n is the number of output arguments expected from running fcn(Y1,...,Ym) using the vertically concatenated outputs Y1,...,Ym from each element Aj in the Future array A.

    Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

    Pass the Future array A to callback function, specified as true or false.

    • By default PassFuture is false and MATLAB runs the function fcn using the concatenated outputs from each element in A. The outputs Y1,...,Ym from each Future object are concatenated vertically, in linear index order. For example, if A is a two-element Future vector with outputs y1 and y2 from the first and second Future objects respectively, MATLAB runs fcn([y1; y2]) after all elements in A finish.

      If any of the elements in A encounters an error, afterAll finishes with an error.

    • If you specify PassFuture as true, MATLAB runs fcn(A) after all Future elements in A finishes, instead of concatenating the outputs of the Future elements in A.

      If any of the elements in A encounters an error, afterAll does not finish with an error.

    Data Types: logical

    Output Arguments

    collapse all

    Output Future object, returned as a parallel.Future object.

    • Use fetchOutputs to retrieve results from B.

    • Use afterEach or afterAll to run a function when B completes.

    When you set PassFuture, you change the Error property of B if afterAll does not result in an error:

    • By default, PassFuture is false, and if any of the elements in A encounters an error, afterAll finishes with an error. The Error property of B is an MException object.

      To find the cause of the error, use the cause property of B.Error.

    • If PassFuture is true, and any of the elements in A encounters an error, afterAll does not finish with an error. The Error property of B is an empty MException object.

    If afterAll results in an error, the Error property of B is an MException object.

    Version History

    Introduced in R2018a