add in log summary the meaning of the thread_resume_ep, so that loadlog can tell...
[charm.git] / src / langs / bluegene / bigsim_logs.h
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 //Contains the structures for bg logs and timelines
9 #ifndef BLUE_LOGS_H
10 #define BLUE_LOGS_H
11
12 #include <string.h>
13
14 #include "blue.h"
15 #include "blue_defs.h"
16 #include "cklists.h"
17
18 #define BG_CURRENT_VERSION      5
19
20 extern int bglog_version;
21
22 extern int bgcorroff;
23
24 // identifier for a message which records the source node that generate
25 // this message and a message sequence number (_msgID)
26 class BgMsgID
27 {
28 private:
29   int _node;            // node number where the message is created
30   int _msgID;           // local index number on pe
31
32 public:
33   BgMsgID(): _node(-1), _msgID(-1) {}
34   BgMsgID(int p, int m): _node(p), _msgID(m) {}
35   void pup(PUP::er &p) {
36     p|_node; p|_msgID;
37   }
38   inline int operator == (const BgMsgID &m) {
39     return _node == m._node && _msgID == m._msgID;
40   }
41   int node() { return _node; }
42   int msgID() { return _msgID; }
43 };
44
45 /**
46   a message sent event in timeline
47 */
48 class BgMsgEntry {
49   friend class BgTimeLog;
50 public:
51   int msgID;
52   int dstPe;          // dest bg node in global sequence
53   double sendTime;      // msg sending offset in the event
54   double recvTime;      // predicted recv time with delay
55 #if DELAY_SEND
56   char *sendMsg;        // real msg
57 #endif
58   CmiInt2 tID;          // destination worker thread ID
59   int msgsize;          // message size
60   int group;            // number of messages in this group
61 private:
62   BgMsgEntry() {}
63 public:
64   BgMsgEntry(int seqno, int _msgSize, double _sendTime, double _recvTime, int dstNode, int destrank);
65   BgMsgEntry(char *msg, int node, int tid, int local, int g=1);
66   inline void print() {
67     CmiPrintf("msgID:%d sent:%f recvtime:%f dstPe:%d group:%d\n", msgID, sendTime, recvTime, dstPe, group);
68   }
69   void write(FILE *fp) {
70     if(dstPe >= 0)
71       fprintf(fp, "msgID:%d sent:%f recvtime:%f dstPe:%d size:%d group:%d\n", msgID, sendTime, recvTime, dstPe, msgsize, group);
72     if(dstPe == -1)
73       fprintf(fp, "msgID:%d sent:%f recvtime:%f dstPe:BG_BROADCASTALL size:%d group:%d\n", msgID, sendTime, recvTime, msgsize, group);
74     if(dstPe <= -100)
75       fprintf(fp, "msgID:%d sent:%f recvtime:%f dstPe:BG_BROADCASTALL except %d size:%d group:%d\n", msgID, sendTime, recvTime, -100-dstPe, msgsize, group);
76     
77   }
78 #if DELAY_SEND
79 //  void send();
80 #endif
81   void pup(PUP::er &p) {
82     p|msgID; p|dstPe; p|sendTime; p|recvTime; p|tID; p|msgsize; 
83     if (p.isUnpacking()) group = 1;    // default value
84     if (bglog_version>0) p|group;
85   }
86 };
87
88 /**
89   event for higher level of tracing like trace projections
90 */
91 class bgEvents {
92 private:
93   bgEventCallBackFn  callbackFn;
94   void* usrPtr;
95 public:
96   void*   data;         // e.g. can be pointer to trace projection log entry
97   int     index;                // index of the event to its original log pool.
98   double  rTime;        // relative time from the start entry
99   char   eType;
100   bgEvents(): index(-1) {}
101   bgEvents(void *d, int idx, double t, bgEventCallBackFn fn, void *ptr, char e):
102         data(d), index(idx), rTime(t), callbackFn(fn), usrPtr(ptr), eType(e) {}
103   inline void update(double startT, double recvT, int e) {
104         if (eType==e) callbackFn(data, startT+rTime, recvT, usrPtr);
105   }
106   void print();
107   void write(FILE *fp);
108   void pup(PUP::er &p);
109 };
110
111 #define BG_STARTSIM     0x1
112 #define BG_QD           0x2
113
114 extern void BgDelaySend(BgMsgEntry *msgEntry);
115
116 class BgTimeLineRec;
117 /**
118   one time log for an handler function;
119   it records a list of message sent events in an execution of handler
120 */
121 class BgTimeLog {
122 public:
123   int ep;
124   int seqno;
125   BgMsgID  msgId;       // incoming message that generates this log
126   short charm_ep;
127
128   CmiObjId objId;
129
130   double recvTime;      //Time at which the message was received in 'inbuffer'
131   double startTime, endTime;
132   double oldStartTime, execTime;
133   double effRecvTime;
134
135 //  int threadNum;      // by guna, for seq load balancing  ???
136
137   CkVec< BgMsgEntry * > msgs;
138   CkVec< bgEvents * > evts;
139   CkVec< BgTimeLog* > backwardDeps;
140   CkVec< BgTimeLog* > forwardDeps;
141   char doCorrect;
142   char flag;
143   char name[20];
144
145   friend class BgTimeLineRec;
146 public:
147   BgTimeLog(BgTimeLog *);
148   BgTimeLog(const BgMsgID &msgID);
149   BgTimeLog(char *msg, char *str=NULL);
150   BgTimeLog(): ep(-1), charm_ep(-1), recvTime(.0), startTime(.0), endTime(.0), execTime(.0), 
151                effRecvTime(INVALIDTIME), seqno(0), doCorrect(1), flag(0) 
152     {strcpy(name,"dummyname");}
153   BgTimeLog(int epc, char* name, double sTime, double eTime);
154   BgTimeLog(int epc, char* name, double sTime);
155   ~BgTimeLog();
156
157   inline void setName(char *_name) { strncpy(name, _name, 20); }
158   inline void setEP(int _ep) { ep = _ep; }
159   inline void setCharmEP(short _ep) { charm_ep = _ep; }
160   inline void setTime(double stime, double etime) {
161          startTime = stime;
162          endTime = etime;
163          setExecTime();
164   }
165   inline void setExecTime() {
166            execTime = endTime - startTime;
167            if(execTime < BG_EPSILON && execTime > -BG_EPSILON)
168              execTime = 0.0;
169            CmiAssert(execTime >= 0.0);
170          }
171   inline void addMsg(BgMsgEntry *mentry) {
172            msgs.push_back(mentry);
173          }
174   inline void addMsg(char *msg, int node, int tid, int local, int group=1) { 
175            msgs.push_back(new BgMsgEntry(msg, node, tid, local, group)); 
176          }
177   inline void setObjId(CmiObjId *idx) {
178            memcpy(&objId, idx, sizeof(CmiObjId));
179          }
180   void closeLog();
181   void print(int node, int th);
182   void write(FILE *fp);
183
184   inline void setStartEvent() { flag |= BG_STARTSIM; }
185   inline int isStartEvent() { return (flag & BG_STARTSIM); }
186   inline int isQDEvent() { return (flag & BG_QD); }
187
188   // add backward dep of the log corresponent to msg
189   void addMsgBackwardDep(BgTimeLineRec &tlinerec, void* msg);
190   void addBackwardDep(BgTimeLog* log);
191   //takes a list of Logs on which this log is dependent (backwardDeps) 
192   void addBackwardDeps(CkVec<BgTimeLog*> logs);
193   void addBackwardDeps(CkVec<void*> logs);
194   int bDepExists(BgTimeLog* log);                       // by guna
195   //Returns earliest time by which all backward dependents ended  
196   // return the last eff recv time
197   double getEndOfBackwardDeps() {
198     double maxEndTime =0.0;
199     for(int i=0;i<backwardDeps.length();i++)
200 //    maxEndTime = max(maxEndTime,backwardDeps[i]->endTime);
201       maxEndTime = BG_MAX(maxEndTime,backwardDeps[i]->effRecvTime);
202       
203     return maxEndTime;
204   }
205
206   inline void addEvent(void *data,int idx,double absT,bgEventCallBackFn fn,void *p,int e) { 
207     evts.push_back(new bgEvents(data, idx, absT-startTime, fn, p, e)); 
208   }
209   inline void updateEvents(int e) {
210     for (int i=0; i<evts.length(); i++)
211       evts[i]->update(startTime ,recvTime, e);
212   }
213   inline double key() { return effRecvTime; }
214   inline int compareKey(BgTimeLog* otherLog){
215     if(((isZero(effRecvTime-otherLog->effRecvTime))&&(seqno < otherLog->seqno))
216        ||(isLess(effRecvTime,otherLog->effRecvTime)))
217       return -1;
218     return 1;
219   }
220   inline int isEqual(BgTimeLog* otherLog){
221     return (otherLog==this);
222   }
223   void pup(PUP::er &p);
224
225 #if DELAY_SEND
226   void send() {
227     for (int i=0; i<msgs.length(); i++)
228       BgDelaySend(msgs[i]);
229   }
230 #endif
231 };
232
233
234 /**
235   Timeline for a VP
236 */
237 typedef CkQ< BgTimeLog *> BgTimeLine;
238
239 /**
240   A wrapper for CkQ of BgTimeLine
241 */
242 class BgTimeLineRec {
243 public:
244   BgTimeLine  timeline;
245   int         commit;
246   int         startIdx;
247   int         startCorrFlag;
248   int         correctSendIdx;
249   int         counter;
250   double      minCorrection;
251   BgTimeLog  *bgCurLog;         /* current unfinished log */
252   BgTimeLog  *bgPrevLog;        /* previous log that should make dependency */
253 #if DELAY_SEND
254   CkQ<BgTimeLog *>   sendingLogs;       // send buffered
255 #endif
256 public:
257   BgTimeLineRec(): timeline(1024), commit(0), counter(1), correctSendIdx(0), 
258                    startIdx(0), bgCurLog(NULL), bgPrevLog(NULL) {
259       if (bgcorroff) startCorrFlag=0; else startCorrFlag=1;
260       minCorrection = INVALIDTIME;
261     }
262   ~BgTimeLineRec() {
263       for (int i=0; i<timeline.length(); i++)  delete timeline[i];
264     }
265   BgTimeLog * operator[](size_t n) {
266         CmiAssert(n!=(size_t)-1);
267         return timeline[n];
268     }
269   int length() { return timeline.length(); }
270   // special enq which will assign seqno
271   void enq(BgTimeLog *log, int isnew) {
272         log->seqno = counter++;
273         timeline.enq(log);
274 #if DELAY_SEND
275         if (isnew) sendingLogs.enq(log);
276 #endif
277   }
278   void setStartIdx(){
279     startIdx = timeline.length();
280   }
281   double computeUtil(int *numRealMsgs){
282     //From startIdx to the end of the timeline
283     double total=0.0;
284     int tlineLen = length();
285     for(int i=0;i<tlineLen;i++) {
286       BgTimeLog *log = timeline[i];
287       total += log->execTime;
288       *numRealMsgs += log->msgs.length();
289     }
290     return total;
291   }
292   inline void clearSendingLogs() {
293 #if DELAY_SEND
294     while (!sendingLogs.isEmpty()) {
295       BgTimeLog *log = sendingLogs.deq();
296       log->send();
297     }
298 #endif
299   }
300   void logEntryStart(char *m);
301 //  void logEntryCommit();
302   void logEntryInsert(BgTimeLog* log);
303   void logEntryStart(BgTimeLog* log);
304   void logEntryClose();
305   void logEntrySplit(const char *name = "split-broadcast");
306   BgTimeLog *getTimeLogOnThread(const BgMsgID &msgId, int *index);
307
308   void pup(PUP::er &p);
309 };
310
311 // BigSim log function API
312 int BgIsInALog(BgTimeLineRec &tlinerec);
313 BgTimeLog *BgLastLog(BgTimeLineRec &tlinerec);
314 void BgAddBackwardDep(BgTimeLog *curlog, BgTimeLog* deplog);
315 BgTimeLog *BgStartLogByName(BgTimeLineRec &tlinerec, int ep, char *name, double starttime, BgTimeLog *prevLog);
316 void BgEndLastLog(BgTimeLineRec &tlinerec);
317
318 int BgLogGetThreadEP();
319 int BgLoadTraceSummary(const char *fname, int &totalProcs, int &numX, int &numY, int &numZ, int &numCth, int &numWth, int &numPes);
320 int BgReadProc(int procNum, int numWth, int numPes, int totalProcs, int* allNodeOffsets, BgTimeLineRec& tlinerec);
321 int* BgLoadOffsets(int totalProcs, int numPes);
322 void BgWriteThreadTimeLine(char *fname, int x, int y, int z, int th, BgTimeLine &tline);
323 void BgWriteTraceSummary(int numPes, int x, int y=1, int z=1, int numWth=1, int numCth=1, char *traceroot=NULL);
324 void BgWriteTimelines(int seqno, BgTimeLineRec **tlinerecs, int nlocalNodes, char *traceroot=NULL);
325 void BgWriteTimelines(int seqno, BgTimeLineRec *tlinerecs, int nlocalNodes, char *traceroot=NULL);
326 extern "C" void BgGenerateLogs();
327
328 #endif