In MATLAB, it is really easy to do parallel processing of trivially parallelizable problems with a
parfor loop. I do it all the time. It’s great. A problem with this is that, if you need to parallelize something in the first place, it’s typically something that takes a really long time to run. Some type of progress monitor is normally easier to make, but because
parfor does not iterate in order and the workers cannot communicate with one another, it’s a little tricky to do in the parallel case.
So I made a very hacky solution to this problem. Basically, I start with a blank file (parfor_progress.txt) and add a line to it each time an iteration of the loop finishes. At that time, I also count the number of lines in parfor_progress.txt and display that as a percentage of the total number of iterations.
function percent = parfor_progress(N) %PARFOR_PROGRESS Progress monitor (progress bar) that works with parfor. % PARFOR_PROGRESS works by creating a file called parfor_progress.txt in % your working directory, and then keeping track of the parfor loop's % progress within that file. This workaround is necessary because parfor % workers cannot communicate with one another so there is no simple way % to know which iterations have finished and which haven't. % % PARFOR_PROGRESS(N) initializes the progress monitor for a set of N % upcoming calculations. % % PARFOR_PROGRESS updates the progress inside your parfor loop and % displays an updated progress bar. % % PARFOR_PROGRESS(0) deletes parfor_progress.txt and finalizes progress % bar. % % To suppress output from any of these functions, just ask for a return % variable from the function calls, like PERCENT = PARFOR_PROGRESS which % returns the percentage of completion. % % Example: % % N = 100; % parfor_progress(N); % parfor i=1:N % pause(rand); % Replace with real code % parfor_progress; % end % parfor_progress(0); % % See also PARFOR. % By Jeremy Scheff - firstname.lastname@example.org - http://www.jeremyscheff.com/ error(nargchk(0, 1, nargin, 'struct')); if nargin < 1 N = -1; end percent = 0; w = 50; % Width of progress bar if N > 0 f = fopen('parfor_progress.txt', 'w'); if f<0 error('Do you have write permissions for %s?', pwd); end fprintf(f, '%d\n', N); % Save N at the top of progress.txt fclose(f); if nargout == 0 disp([' 0%[>', repmat(' ', 1, w), ']']); end elseif N == 0 delete('parfor_progress.txt'); percent = 100; if nargout == 0 disp([repmat(char(8), 1, (w+9)), char(10), '100%[', repmat('=', 1, w+1), ']']); end else if ~exist('parfor_progress.txt', 'file') error('parfor_progress.txt not found. Run PARFOR_PROGRESS(N) before PARFOR_PROGRESS to initialize parfor_progress.txt.'); end f = fopen('parfor_progress.txt', 'a'); fprintf(f, '1\n'); fclose(f); f = fopen('parfor_progress.txt', 'r'); progress = fscanf(f, '%d'); fclose(f); percent = (length(progress)-1)/progress(1)*100; if nargout == 0 perc = sprintf('%3.0f%%', percent); % 4 characters wide, percentage disp([repmat(char(8), 1, (w+9)), char(10), perc, '[', repmat('=', 1, round(percent*w/100)), '>', repmat(' ', 1, w - round(percent*w/100)), ']']); end end
Then, to get a progress bar for a
parfor loop, all you have to do is something like this:
N = 100; parfor_progress(N); parfor i=1:N pause(rand); % Replace with real code parfor_progress; end parfor_progress(0);
You should thank commenter Ben Aernouts for helping me make the progress bar pretty.
Please leave a comment if you know of a better way to do this!