Matlab: Print progress from parfor loop

醉酒当歌 提交于 2019-11-28 18:54:46

Simple Progress Bar

Something like a progress bar could be done similar to this...

Before the parfor loop :

fprintf('Progress:\n');
fprintf(['\n' repmat('.',1,m) '\n\n']);

And during the loop:

fprintf('\b|\n');

Here we have m is the total number of iterations, the . shows the total number of iterations and | shows the number of iterations completed. The \n makes sure the characters are printed in the parfor loop.

Progress Bar and Percentage Completion

Otherwise you could try this: http://www.mathworks.com/matlabcentral/fileexchange/32101-progress-monitor--progress-bar--that-works-with-parfor

It will display a progress bar and percentage completion but can be easily modified to just include the percentage completion or progress bar.

This function amends a character to a file on every iteration and then reads the number of characters written to that file which indicates the number of iterations completed. This file accessing method is allowed in parfor's.

Assuming you correctly add the above to your MATLAB path somehow, you can then use the following:

arglist = [arg1, arg2, arg3, arg4];
parfor_progress(size(arglist, 2)); % Set the total number of iterations

parfor ii = 1:size(arglist, 2)
    myfun(arglist(ii));
    parfor_progress; % Increment the progress counter
end
parfor_progress(0); % Reset the progress counter

Time to Completion and Percentage Completion

There is also a function called showTimeToCompletion() which is available from: https://www.soundzones.com/software/sound-zone-tools/

and works alongside parfor_progress. This function allows you to print a detailed summary of the progress of a parfor loop (or any loop for that matter) which contains the start time, length of time running, estimated finish time and percentage completion. It makes smart use of the \b (backspace) character so that the command window isn't flooded with text. Although not strictly a progress 'bar' it is perhaps more informative.

The third example in the header of the function file,

fprintf('\t Completion: ');
showTimeToCompletion; startTime=tic;
len=1e2;
p = parfor_progress( len );
parfor i = 1:len
    pause(1);
    p = parfor_progress;
    showTimeToCompletion( p/100, [], [], startTime );
end

outputs the following to the command window:

     Completion: 31.00%
      Remaining: 00:00:23
          Total: 00:00:33
Expected Finish: 3:30:07PM  14-Nov-2017

Useful for estimating the completion of a running simulation, especially one that may take hours or days.

Starting in R2013b, you can use PARFEVAL to evaluate your function asynchronously and have the client display progress updates. (Obviously this approach is not quite as simple as adding stuff to your PARFOR loop). There's an example here.

The Diary property of the Future returned by PARFEVAL is updated continuously while processing, so that might also be useful if you have a small number of large tasks.

Starting in R2017a, you can use parallel.pool.DataQueue and afterEach to implement a waitbar for parfor, like so:

if isempty(gcp('nocreate'))
    parpool('local', 3);
end
dq = parallel.pool.DataQueue;
N = 10;
wb = waitbar(0, 'Please wait...');
% Use the waitbar's UserData to track progress
wb.UserData = [0 N];
afterEach(dq, @(varargin) iIncrementWaitbar(wb));
afterEach(dq, @(idx) fprintf('Completed iteration: %d\n', idx));
parfor idx = 1:N
    pause(rand());
    send(dq, idx);
end
close(wb);

function iIncrementWaitbar(wb)
ud = wb.UserData;
ud(1) = ud(1) + 1;
waitbar(ud(1) / ud(2), wb);
wb.UserData = ud;
end

after exploring @Edric answer I found that there is an example in the Matlab documentation that exactly implements a waitbar for a pareval loop. Check help FetchNext

N = 100;
for idx = N:-1:1
    % Compute the rank of N magic squares
    F(idx) = parfeval(@rank, 1, magic(idx));
end
% Build a waitbar to track progress
h = waitbar(0, 'Waiting for FevalFutures to complete...');
results = zeros(1, N);
for idx = 1:N
    [completedIdx, thisResult] = fetchNext(F);
    % store the result
    results(completedIdx) = thisResult;
    % update waitbar
    waitbar(idx/N, h, sprintf('Latest result: %d', thisResult));
end
% Clean up
delete(h)
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!