Adding no-op versions of the critical path methods.
[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
27 void initializeCriticalPath(void);
28
29
30 /**
31    Augments the PathHistory in the envelope with the other necessary information
32    from the envelope. These should be derived from an incoming message.
33
34    These objects can then be used for storing of information about a path 
35    outside of the incoming message's header. 
36
37    These are used for:
38       1) information about the currently executing message
39       2) combining the maximum paths along a reduction
40       3) combining multiple paths in Charisma and SDAG programs
41
42    This can be constructed from an envelope.
43 */
44
45 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
46
47 //#warning "Usinge MergeablePathHistory in pathHistory.h"
48 class MergeablePathHistory {
49  public:
50   double timeEntryMethodStarted;
51
52   double preceding_path_time;
53
54   int sender_pe;  // for traversing back over the PAG
55   int sender_history_table_idx; // for traversing back over the PAG
56   
57   int local_ep;  // The locally executing EP
58   int local_arr; // The locally executing array
59
60  MergeablePathHistory(const envelope *env) 
61    : sender_pe(env->getSrcPe()), 
62     sender_history_table_idx(env->pathHistory.get_sender_history_table_idx()), 
63     local_ep(env->getEpIdx()),
64     local_arr(env->getArrayMgrIdx()),
65     preceding_path_time(env->pathHistory.getTime()),
66     timeEntryMethodStarted(0.0)
67       {
68         // No body
69       }
70
71
72   MergeablePathHistory() {
73     reset();
74   }
75   
76   void reset(){
77     sender_pe = -1; 
78     sender_history_table_idx = -1; 
79     local_ep = -1;
80     preceding_path_time = 0.0;
81     timeEntryMethodStarted = 0.0;
82   }
83   
84   void sanity_check(){
85     if(sender_history_table_idx > -1){ 
86       CkAssert(sender_pe < CkNumPes()); 
87       CkAssert(sender_pe >= -1);
88     }
89 /*     CkAssert(sender_history_table_idx < 100000); */
90 /*     CkAssert(sender_history_table_idx >= 0); */
91    
92 /*     CkAssert(local_ep < 500); */
93 /*     CkAssert(local_ep >= 0); */
94
95   }
96
97   void updateMax(const MergeablePathHistory& other){
98     if(preceding_path_time < other.preceding_path_time)
99       *this = other;
100   }
101
102
103   void updateMax(const envelope* env){
104     updateMax(MergeablePathHistory(env));
105   }
106   
107   double getTotalTime() const{
108     return preceding_path_time;
109   }
110
111   /// Write a description of the path into the beginning of the provided buffer. The buffer ought to be large enough.
112   void printHTMLToString(char* buf) const{
113     buf[0] = '\0';
114     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);
115   }
116
117   void setDebug100(){
118     preceding_path_time = 100.0;
119     CkPrintf("Setting path length to 100\n");
120   }
121
122
123 };
124
125 #endif
126
127
128 /** 
129     Stores information about the critical path in the table on each PE. 
130     The PAG can be constructed by merging these together.
131
132     These can be constructed from a MergeablePathHistory, and are assumed to refer to the local PE.
133 */
134 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
135 class PathHistoryTableEntry {
136   
137  public:
138   int sender_pe;
139   int sender_history_table_idx;
140   int local_ep;
141   int local_arr;
142   int local_pe;
143
144  private:
145   double start_time;
146   double local_path_time;
147   double preceding_path_time;
148
149  public:
150   
151  PathHistoryTableEntry() 
152    : sender_pe(-1), 
153     sender_history_table_idx(-1), 
154     start_time(0.0),
155     local_path_time(0.0), 
156     preceding_path_time(0.0),     
157     local_ep(-1),
158     local_arr(-1),
159     local_pe(CkMyPe())
160       {
161         // No body
162       }
163   
164
165   /// Construct an entry for the table assuming the start time in input path is correct
166  PathHistoryTableEntry(const MergeablePathHistory& p, double localContribution = 0.0)
167     : sender_pe(p.sender_pe), 
168     sender_history_table_idx(p.sender_history_table_idx), 
169     local_path_time(localContribution), 
170     preceding_path_time(p.preceding_path_time),
171     start_time(p.timeEntryMethodStarted),
172     local_ep(p.local_ep),
173     local_arr(p.local_arr),
174     local_pe(CkMyPe())
175       {
176         // No body
177       }
178
179   /// Construct an entry with the actual start and end times for it.
180   PathHistoryTableEntry(const MergeablePathHistory& p, double start, double finish)
181     : sender_pe(p.sender_pe), 
182     sender_history_table_idx(p.sender_history_table_idx), 
183     local_path_time(finish-start), 
184     preceding_path_time(p.preceding_path_time),
185     start_time(start),
186     local_ep(p.local_ep),
187     local_arr(p.local_arr),
188     local_pe(CkMyPe())
189       {
190         // No body
191       }
192
193   void printInfo(char *prefix = ""){
194     CkPrintf("%s [sender pe=%d table idx=%d] [local path contribution=%lf ep=%d] [Time= %lf + %lf]\n", prefix,  
195              sender_pe, sender_history_table_idx, local_path_time, local_ep, preceding_path_time, local_path_time);  
196   }
197
198
199   /// Add an entry for this path history into the table, and write the corresponding information into the provided header
200   int addToTableAndEnvelope(envelope *env);
201   
202   /// Add an entry for this path history into the table. Returns the new index in the table.
203   int addToTable();
204   
205   /// Return the length of the path up to and including this entry
206   double getTotalTime(){
207     return local_path_time + preceding_path_time;
208   }
209
210   double get_start_time() const {return start_time;}
211   double get_local_path_time() const {return local_path_time;}
212   double get_preceding_path_time() const {return preceding_path_time;}
213
214 };
215 #else 
216 class PathHistoryTableEntry{
217 };
218 #endif
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 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
249     CkPrintf("Path contains %d entries\n", historySize);
250     for(int i=historySize-1;i>=0;i--){
251       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);
252     }
253 #endif    
254   }
255   
256 };
257
258
259 #ifdef USE_CRITICAL_PATH_HEADER_ARRAY
260 CkpvExtern(MergeablePathHistory, currentlyExecutingPath);
261 CkpvExtern(double, timeEntryMethodStarted);
262
263 // Reset the counts for the currently executing message. Cut the incoming path
264 extern void resetThisEntryPath();
265
266 extern void criticalPath_start(envelope * env); 
267 extern void criticalPath_send(envelope * sendingEnv);
268 extern void criticalPath_end();
269 extern void criticalPath_split(); 
270
271
272
273
274 /// Wrappers for Charm++ programs to use to annotate their program dependencies
275
276 /// Declare a MergeablePathHistory variable, whose name is mangled with the supplied parameter
277 #define MERGE_PATH_DECLARE(x) MergeablePathHistory merge_path_##x
278
279 /// Reset the merge_path variable
280 #define MERGE_PATH_RESET(x) merge_path_##x.reset()
281
282 /// Take the maximal path from the stored merge_path variable and the currently executing path. Put the result in currently executing path.
283 #define MERGE_PATH_MAX(x) merge_path_##x.updateMax(CkpvAccess(currentlyExecutingPath)); CkpvAccess(currentlyExecutingPath) = merge_path_##x; 
284
285
286
287 /// Declare a dynamic MergeablePathHistory variable. Each object can have many merge points stored in this single DECLARE.
288 #define MERGE_PATH_DECLARE_D(x) std::map<int,MergeablePathHistory> merge_path_D_##x
289
290 /// Reset the merge_path variable
291 #define MERGE_PATH_RESET_D(x,n) merge_path_D_##x[n].reset()
292
293 /// Delete the merge_path variable
294 #define MERGE_PATH_DELETE_D(x,n) merge_path_D_##x.erase(n)
295
296 /// Delete all entries in the merge_path variable
297 #define MERGE_PATH_DELETE_ALL_D(x) merge_path_D_##x.clear()
298
299 /// Take the maximal path from the stored merge_path variable and the currently executing path. Put the result in currently executing path.
300 #define MERGE_PATH_MAX_D(x,n) merge_path_D_##x[n].updateMax(CkpvAccess(currentlyExecutingPath)); CkpvAccess(currentlyExecutingPath) = merge_path_D_##x[n]; 
301
302
303
304 #else
305
306
307 /// Empty no-op version for when critical path history is not compiled in
308 class MergeablePathHistory{
309 }
310
311 #define MERGE_PATH_DECLARE(x) ;
312 #define MERGE_PATH_RESET(x) ;
313 #define MERGE_PATH_MAX(x) ;
314 #define MERGE_PATH_DECLARE_D(x) ;
315 #define MERGE_PATH_RESET_D(x,n) ;
316 #define MERGE_PATH_DELETE_D(x,n) ;
317 #define MERGE_PATH_DELETE_ALL_D(x) ;
318 #define MERGE_PATH_MAX_D(x,n) ;
319
320
321 #endif
322
323
324 /** @} */
325 #endif