A very ressource efficient Matlab class for progress monitoring during a parfor
loop displaying the remaining time and optional progress of each worker.
It supports distributed worker pools (i.e. doesn't only work on local pools).
Matlabs download page: ParforProgressbar
% 'numIterations' is an integer with the total number of iterations in the loop.
% Feel free to increase this even higher and see other progress monitors fail.
numIterations = 100000;
% Then construct a ParforProgressbar object:
ppm = ParforProgressbar(numIterations);
parfor i = 1:numIterations
% do some parallel computation
pause(100/numIterations);
% increment counter to track progress
ppm.increment();
end
% Delete the progress handle when the parfor loop is done (otherwise the timer that keeps updating the progress might not stop).
delete(ppm);
ppm = ParforProgressbar(numIterations) constructs a ParforProgressbar object.
'numIterations' is an integer with the total number of
iterations in the parfor loop.
ppm = ParforProgressbar(___, 'showWorkerProgress', true) will display
the progress of all workers (default: false).
ppm = ParforProgressbar(___, 'progressBarUpdatePeriod', 1.5) will
update the progressbar every 1.5 second (default: 1.0 seconds).
ppm = ParforProgressbar(___, 'title', 'my fancy title') will
show 'my fancy title' on the progressbar.
ppm = ParforProgressbar(___, 'parpool', 'local') will
start the parallel pool (parpool) using the 'local' profile.
ppm = ParforProgressbar(___, 'parpool', {profilename, poolsize, Name, Value})
will start the parallel pool (parpool) using the profilename profile with
poolsize workers and any Name Value pair supported by function parpool.
Let's say you have a list of files that need to be processed at specific lines. So you open each file and process the specific line
file_line = {{'fileA.txt',3},{'fileA.txt',5},{'fileB.txt',2}}; % probably much bigger
sz = length(file_line);
result = cell(sz, 1);
ppm = ParforProgressbar(sz);
parfor i = 1 : sz
filename = file_line{i}{1};
data = my_open_file_slow(filename);
result{i} = my_process_line_fast(data, file_line{i}{2});
end
delete(ppm)
However, 'fileA' does appear several times and my_open_file_slow is very expensive in contrast to my_process_line_fast. But maybe this worker has already opened this exact file the loop cycle before. But filename and data are not accessable in the next loop cycle! ParforProgressbar provides a simple technique to save some temporary user data that might speed up your parfor loop significantly:
file_line = {{'fileA.txt',3},{'fileA.txt',5},{'fileB.txt',2}}; % probably much bigger
sz = length(file_line);
result = cell(sz, 1);
ppm = ParforProgressbar(sz);
parfor i = 1 : sz
filename = file_line{i}{1};
userData = ppm.getUserData();
if(isempty(userData) || ~strcmp(userData{1}, filename))
data = my_open_file_slow(filename);
ppm.setUserData({filename, data});
else
data = userData{2};
end
result{i} = my_process_line_fast(data, file_line{i}{2});
end
delete(ppm)
Matlab's parfor loop schedules each worker on demand. I.e. if a worker finishes one loop cycle, another loop iteration is assigned to this worker. Because each loop cycle can vary in complexity, some workers can iterate much more cycles than others in the same time. ParforProgressbar doesn't get informed about this assignments and estimates the worker progress by evenly dividing the total iterations by the number of workers. This might lead to estimated individual worker progress higher than 100%.
delete(ppm)
If the ppm object isn't reachable anymore, you can delete all timer objects:
delete(timerfindall)