Refactoring control point and critical path detection code.
[charm.git] / src / ck-cp / pathHistory.h
1
2 /**     @defgroup CriticalPathFramework Critical Path Detection
3
4         Usable for determining the critical paths in Charm++, Charisma, and SDAG programs. 
5 */
6
7 /** 
8     A system for exposing application and runtime "control points" 
9     to the dynamic optimization framework.
10
11     @addtogroup CriticalPathFramework
12     @{
13
14 */
15 #ifndef __PATH_HISTORY_H__
16 #define __PATH_HISTORY_H__
17
18 #include <vector>
19 #include <map>
20 #include <cmath>
21 #include "ControlPoints.decl.h"
22 #include "envelope.h"
23
24 #include<pup_stl.h>
25
26 #define DEBUG 0
27
28
29
30 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
31
32
33 /**
34    Augments the PathHistory in the envelope with the other necessary information
35    from the envelope. These should be derived from an incoming message.
36
37    These objects can then be used for storing of information about a path 
38    outside of the incoming message's header. 
39
40    These are used for:
41       1) information about the currently executing message
42       2) combining the maximum paths along a reduction
43       3) combining multiple paths in Charisma and SDAG programs
44
45    This can be constructed from an envelope.
46 */
47
48 void initializeCriticalPath(void);
49
50
51 //#warning "Usinge MergeablePathHistory in pathHistory.h"
52 class MergeablePathHistory {
53  public:
54   double timeEntryMethodStarted;
55
56   double preceding_path_time;
57
58   int sender_pe;  // for traversing back over the PAG
59   int sender_history_table_idx; // for traversing back over the PAG
60   
61   int local_ep;  // The locally executing EP
62   int local_arr; // The locally executing array
63
64  MergeablePathHistory(const envelope *env) 
65    : sender_pe(env->getSrcPe()), 
66     sender_history_table_idx(env->pathHistory.get_sender_history_table_idx()), 
67     local_ep(env->getEpIdx()),
68     local_arr(env->getArrayMgrIdx()),
69     preceding_path_time(env->pathHistory.getTime()),
70     timeEntryMethodStarted(0.0)
71       {
72         // No body
73       }
74
75
76   MergeablePathHistory() {
77     reset();
78   }
79   
80   void reset(){
81     sender_pe = -1; 
82     sender_history_table_idx = -1; 
83     local_ep = -1;
84     preceding_path_time = 0.0;
85     timeEntryMethodStarted = 0.0;
86   }
87   
88   void sanity_check(){
89     if(sender_history_table_idx > -1){ 
90       CkAssert(sender_pe < CkNumPes()); 
91       CkAssert(sender_pe >= -1);
92     }
93 /*     CkAssert(sender_history_table_idx < 100000); */
94 /*     CkAssert(sender_history_table_idx >= 0); */
95    
96 /*     CkAssert(local_ep < 500); */
97 /*     CkAssert(local_ep >= 0); */
98
99   }
100
101   void updateMax(const MergeablePathHistory& other){
102     if(preceding_path_time < other.preceding_path_time)
103       *this = other;
104   }
105
106
107   void updateMax(const envelope* env){
108     updateMax(MergeablePathHistory(env));
109   }
110   
111   double getTotalTime() const{
112     return preceding_path_time;
113   }
114
115   /// Write a description of the path into the beginning of the provided buffer. The buffer ought to be large enough.
116   void printHTMLToString(char* buf) const{
117     buf[0] = '\0';
118     sprintf(buf+strlen(buf), "MergeablePathHistory time=%lf send pe=%d idx=%d timeEntryStarted=%lf", (double)preceding_path_time, (int)sender_pe, (int)sender_history_table_idx, (double)timeEntryMethodStarted);
119   }
120
121   void setDebug100(){
122     preceding_path_time = 100.0;
123     CkPrintf("Setting path length to 100\n");
124   }
125
126
127 };
128
129
130
131
132 /** 
133     Stores information about the critical path in the table on each PE. 
134     The PAG can be constructed by merging these together.
135
136     These can be constructed from a MergeablePathHistory, and are assumed to refer to the local PE.
137 */
138
139 class PathHistoryTableEntry {
140   
141  public:
142   int sender_pe;
143   int sender_history_table_idx;
144   int local_ep;
145   int local_arr;
146   int local_pe;
147
148  private:
149   double start_time;
150   double local_path_time;
151   double preceding_path_time;
152
153  public:
154   
155  PathHistoryTableEntry() 
156    : sender_pe(-1), 
157     sender_history_table_idx(-1), 
158     start_time(0.0),
159     local_path_time(0.0), 
160     preceding_path_time(0.0),     
161     local_ep(-1),
162     local_arr(-1),
163     local_pe(CkMyPe())
164       {
165         // No body
166       }
167   
168
169   /// Construct an entry for the table assuming the start time in input path is correct
170  PathHistoryTableEntry(const MergeablePathHistory& p, double localContribution = 0.0)
171     : sender_pe(p.sender_pe), 
172     sender_history_table_idx(p.sender_history_table_idx), 
173     local_path_time(localContribution), 
174     preceding_path_time(p.preceding_path_time),
175     start_time(p.timeEntryMethodStarted),
176     local_ep(p.local_ep),
177     local_arr(p.local_arr),
178     local_pe(CkMyPe())
179       {
180         // No body
181       }
182
183   /// Construct an entry with the actual start and end times for it.
184   PathHistoryTableEntry(const MergeablePathHistory& p, double start, double finish)
185     : sender_pe(p.sender_pe), 
186     sender_history_table_idx(p.sender_history_table_idx), 
187     local_path_time(finish-start), 
188     preceding_path_time(p.preceding_path_time),
189     start_time(start),
190     local_ep(p.local_ep),
191     local_arr(p.local_arr),
192     local_pe(CkMyPe())
193       {
194         // No body
195       }
196
197   void printInfo(char *prefix = ""){
198     CkPrintf("%s [sender pe=%d table idx=%d] [local path contribution=%lf ep=%d] [Time= %lf + %lf]\n", prefix,  
199              sender_pe, sender_history_table_idx, local_path_time, local_ep, preceding_path_time, local_path_time);  
200   }
201
202
203   /// Add an entry for this path history into the table, and write the corresponding information into the provided header
204   int addToTableAndEnvelope(envelope *env);
205   
206   /// Add an entry for this path history into the table. Returns the new index in the table.
207   int addToTable();
208   
209   /// Return the length of the path up to and including this entry
210   double getTotalTime(){
211     return local_path_time + preceding_path_time;
212   }
213
214   double get_start_time() const {return start_time;}
215   double get_local_path_time() const {return local_path_time;}
216   double get_preceding_path_time() const {return preceding_path_time;}
217
218 };
219
220
221 /// A debugging routine that outputs critical path info as Projections user events.
222 void  saveCurrentPathAsUserEvent(char* prefix="");
223
224 /// A debugging helper routine that sets the values in the currently executing message's path to 100
225 void setCurrentlyExecutingPathTo100(void);
226
227 /// A debugging routine that outputs critical path info as Projections user events.
228 void  printPathInMsg(void* msg);
229
230 /// A debugging routine that outputs critical path info as Projections user events.
231 void  printEPInfo();
232
233
234 /// A routine for printing out information along the critical path.
235 void traceCriticalPathBack(CkCallback cb);
236
237
238
239 /// A message containing information about a path of entry method invocations. This contains an array of PathHistoryTableEntry objects
240 class pathInformationMsg : public CMessage_pathInformationMsg {
241  public:
242   PathHistoryTableEntry *history;
243   int historySize;
244   CkCallback cb;
245   int table_idx;
246
247   void printme(){
248     CkPrintf("Path contains %d entries\n", historySize);
249     for(int i=historySize-1;i>=0;i--){
250       CkPrintf("\tPath Step %d: local_path_time=%lf arr=%d ep=%d starttime=%lf preceding path time=%lf pe=%d\n",i, history[i].get_local_path_time(),  history[i].local_arr, history[i].local_ep, history[i].get_start_time(), history[i].get_preceding_path_time(), history[i].local_pe);
251     }
252     
253   }
254   
255 };
256 #endif
257
258 CkpvExtern(MergeablePathHistory, currentlyExecutingPath);
259 CkpvExtern(double, timeEntryMethodStarted);
260
261 // Reset the counts for the currently executing message. Cut the incoming path
262 extern void resetThisEntryPath();
263
264 extern void criticalPath_start(envelope * env); 
265 extern void criticalPath_send(envelope * sendingEnv);
266 extern void criticalPath_end();
267 extern void criticalPath_split(); 
268
269
270
271
272 /// Wrappers for Charm++ programs to use to annotate their program dependencies
273
274 /// Declare a MergeablePathHistory variable, whose name is mangled with the supplied parameter
275 #define MERGE_PATH_DECLARE(x) MergeablePathHistory merge_path_##x
276
277 /// Reset the merge_path variable
278 #define MERGE_PATH_RESET(x) merge_path_##x.reset()
279
280 /// Take the maximal path from the stored merge_path variable and the currently executing path. Put the result in currently executing path.
281 #define MERGE_PATH_MAX(x) merge_path_##x.updateMax(CkpvAccess(currentlyExecutingPath)); CkpvAccess(currentlyExecutingPath) = merge_path_##x; 
282
283
284
285 /// Declare a dynamic MergeablePathHistory variable. Each object can have many merge points stored in this single DECLARE.
286 #define MERGE_PATH_DECLARE_D(x) std::map<int,MergeablePathHistory> merge_path_D_##x
287
288 /// Reset the merge_path variable
289 #define MERGE_PATH_RESET_D(x,n) merge_path_D_##x[n].reset()
290
291 /// Delete the merge_path variable
292 #define MERGE_PATH_DELETE_D(x,n) merge_path_D_##x.erase(n)
293
294 /// Delete all entries in the merge_path variable
295 #define MERGE_PATH_DELETE_ALL_D(x) merge_path_D_##x.clear()
296
297 /// Take the maximal path from the stored merge_path variable and the currently executing path. Put the result in currently executing path.
298 #define MERGE_PATH_MAX_D(x,n) merge_path_D_##x[n].updateMax(CkpvAccess(currentlyExecutingPath)); CkpvAccess(currentlyExecutingPath) = merge_path_D_##x[n]; 
299
300
301 /** @} */
302 #endif