-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparfor_wait.m
111 lines (107 loc) · 4.37 KB
/
parfor_wait.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
classdef parfor_wait < handle
%This class creates a waitbar or message when using for or parfor.
%Required Input:
%TotalMessage: N in "i = 1: N".
%Optional Inputs:
%'Waitbar': true of false (default). If true, this class creates a
% waitbar.
%'FileName': 'screen' or a char array. If 'screen', print the message
% on screen; otherwise, save the message in the file
% named 'FileName'.
%'ReportInterval': 1x1. Report at every i is costly. This number
% defines the interval for reporting.
%%To use this class, one needs to call the class right before the loop:
%N = 1000;
%WaitMessage = parfor_wait(N);
%%Call "Send" method in the loop.
%for i = 1: N
% WaitMessage.Send;
% pause(0.5);
%end
%%Delete the obj after the loop.
%WaitMessage.Destroy;
%Copyright (c) 2019, Yun Pu
properties (SetAccess = private)
NumMessage; %Number of messages received from the workers.
TotalMessage; %Number of total messages.
Waitbar; %If waitbar is true, create a waitbar; otherwise, save the message in a file.
FileName; %If FileName = 'screen', the current message does not save in a file.
StartTime
UsedTime_1; %Time at last step.
WaitbarHandle;
Message = '';
ReportInterval;
FileID;
DataQueueHandle;
end
methods
function Obj = parfor_wait(TotalMessage, message,varargin)
Obj.DataQueueHandle = parallel.pool.DataQueue;
Obj.StartTime = tic;
Obj.NumMessage = 0;
Obj.UsedTime_1 = Obj.StartTime;
Obj.TotalMessage = TotalMessage;
Obj.Message = message;
InParser = inputParser;
addParameter(InParser,'Waitbar',false,@islogical);
addParameter(InParser,'FileName', 'screen', @ischar);
addParameter(InParser,'ReportInterval', ceil(TotalMessage/100), @isnumeric);
parse(InParser, varargin{:})
Obj.Waitbar = InParser.Results.Waitbar;
Obj.FileName = InParser.Results.FileName;
Obj.ReportInterval = InParser.Results.ReportInterval;
if Obj.Waitbar
Obj.WaitbarHandle = waitbar(0, [Obj.Message,num2str(0), '%'], 'Resize', true);
end
switch Obj.FileName
case 'screen'
otherwise
Obj.FileID = fopen(Obj.FileName, 'w');
end
afterEach(Obj.DataQueueHandle, @Obj.Update);
end
function Send(Obj)
send(Obj.DataQueueHandle, 0);
end
function Destroy(Obj)
if Obj.Waitbar
delete(Obj.WaitbarHandle);
end
delete(Obj.DataQueueHandle);
delete(Obj);
end
end
methods (Access = private)
function Obj = Update(Obj, ~)
Obj.AddOne;
if mod(Obj.NumMessage, Obj.ReportInterval)
return
end
if Obj.Waitbar
Obj.WaitbarUpdate;
else
Obj.FileUpdate;
end
end
function WaitbarUpdate(Obj)
UsedTime_now = toc(Obj.StartTime);
EstimatedTimeNeeded = (UsedTime_now-Obj.UsedTime_1)/Obj.ReportInterval*(Obj.TotalMessage-Obj.NumMessage);
waitbar(Obj.NumMessage/Obj.TotalMessage, Obj.WaitbarHandle, [Obj.Message, num2str(Obj.NumMessage/Obj.TotalMessage*100, '%.2f'), '%']);
Obj.UsedTime_1 = UsedTime_now;
end
function FileUpdate(Obj)
UsedTime_now = toc(Obj.StartTime);
EstimatedTimeNeeded = (UsedTime_now-Obj.UsedTime_1)/Obj.ReportInterval*(Obj.TotalMessage-Obj.NumMessage);
switch Obj.FileName
case 'screen'
fprintf('%.2f%%; %.2fs used and %.2fs needed...\n', Obj.NumMessage/Obj.TotalMessage*100, UsedTime_now, EstimatedTimeNeeded);
otherwise
fprintf(Obj.FileID, '%.2f%%; %.2fs used and %.2fs needed...\n', Obj.NumMessage/Obj.TotalMessage*100, UsedTime_now, EstimatedTimeNeeded);
end
Obj.UsedTime_1 = UsedTime_now;
end
function AddOne(Obj)
Obj.NumMessage = Obj.NumMessage + 1;
end
end
end