6b5d9e9565c9749f904759bd6acfca0079cf4ff7
[charm.git] / src / langs / bluegene / bigsim_record.h
1 #ifndef BIGSIM_RECORD_H
2 #define BIGSIM_RECORD_H
3
4 /// Message watcher: for record/replay support
5 class BgMessageWatcher {
6 protected:
7         int nodelevel;
8 public:
9         virtual ~BgMessageWatcher() {}
10         /**
11          * This message is about to be processed by Charm.
12          * If this function returns false, the message will not be processed.
13          */
14         virtual CmiBool record(char *msg) { return CmiFalse; }
15         virtual int replay() { return 0; }
16         virtual void rewind() {}
17 };
18
19 class BgMessageRecorder : public BgMessageWatcher {
20         FILE *f;
21         long pos;
22 public:
23         BgMessageRecorder(FILE * f_, int node);
24         ~BgMessageRecorder() { fclose(f); }
25
26         virtual CmiBool record(char *msg) {
27 //                if (BgGetGlobalWorkerThreadID()==0) printf("srcpe: %d size: %d handle: %d\n",CmiBgMsgSrcPe(msg),CmiBgMsgLength(msg),CmiBgMsgHandle(msg));
28                 int d = CmiBgMsgSrcPe(msg);
29                 pos = ftell(f);
30                 fwrite(&d, sizeof(int), 1, f);
31 //CmiAssert(CmiBgMsgThreadID(msg) != -1);
32                 if ( (nodelevel == 0 && d == BgGetGlobalWorkerThreadID()) ||
33                      (nodelevel == 1 && d/BgGetNumWorkThread() == BgGetGlobalWorkerThreadID()/BgGetNumWorkThread()) ) {
34                     //CmiPrintf("[%d] local message.\n", BgGetGlobalWorkerThreadID());
35                     return CmiTrue; // don't record local msg
36                 }
37                 d = CmiBgMsgLength(msg);
38                 fwrite(&d, sizeof(int), 1, f);
39 /*
40 if (BgGetGlobalWorkerThreadID()==1 && CmiBgMsgHandle(msg) == 21) {
41 int *m = (int *) ((char *)msg+CmiReservedHeaderSize);
42 printf("replay: %d %d\n", m[0], m[1]);
43 }
44 */
45                 fwrite(msg, sizeof(char), d, f);
46                 //CmiPrintf("[%d] BgMessageRecord>  PE: %d size: %d msg: %p\n", BgGetGlobalWorkerThreadID(), CmiBgMsgSrcPe(msg),CmiBgMsgLength(msg), msg);
47                 return CmiTrue;
48         }
49         virtual int replay() { return 0; }
50         virtual void rewind() {
51 //if (BgGetGlobalWorkerThreadID()==0) printf("rewind to %ld\n", pos);
52                 fseek(f, pos, SEEK_SET);
53         }
54         void write_nodeinfo();
55 };
56
57 class BgMessageReplay : public BgMessageWatcher {
58         FILE * f;
59         int lcount, rcount;
60         /// Read the next message we need from the file:
61 private:
62         void done() {
63                 int mype = BgGetGlobalWorkerThreadID();
64                 printf("[%d] BgMessageReplay> Emulation replay finished at %f seconds due to end of log.\n", mype, CmiWallTimer());
65                 printf("[%d] BgMessageReplay> Replayed %d local records and %d remote records, total of %lld bytes of data replayed.\n", mype, lcount, rcount, ftell(f));
66        }
67 public:
68         BgMessageReplay(FILE * f_, int node);
69         ~BgMessageReplay() {
70                 done();
71                 fclose(f);
72         }
73         CmiBool record(char *msg) { return CmiFalse; }
74         int replay(void) {
75                 int nextPE;
76                 int ret =  fread(&nextPE, sizeof(int), 1, f);
77                 if (-1 == ret || ret == 0) {
78                         done();
79                         ConverseExit();
80                         return 0;
81                 }
82                 int mype = BgGetGlobalWorkerThreadID();
83                 if ( (nodelevel == 0 && nextPE == mype) ||
84                      (nodelevel == 1 && nextPE/BgGetNumWorkThread() == mype/BgGetNumWorkThread()) ) {
85 //printf("BgMessageReplay> local message\n");
86                   lcount ++;
87                   return 0;
88                 }
89                 int nextSize;
90                 ret = fread(&nextSize, sizeof(int), 1, f);
91                 CmiAssert(ret ==1);
92                 CmiAssert(nextSize > 0);
93                 char *msg = (char*)CmiAlloc(nextSize);
94                 ret = fread(msg, sizeof(char), nextSize, f);
95                 if (ret != nextSize) {
96                   CmiPrintf("Bigsim replay> fread returns only %d when asked %d bytes!\n", ret, nextSize);
97                 CmiAssert(ret == nextSize);
98                 }
99                 CmiAssert(CmiBgMsgLength(msg) == nextSize);
100                 // CmiPrintf("BgMessageReplay>  pe:%d size: %d handle: %d msg: %p\n", nextPE, nextSize, CmiBgMsgHandle(msg), msg);
101                 BgSendLocalPacket(mype%BgGetNumWorkThread(), CmiBgMsgHandle(msg), LARGE_WORK, nextSize, msg);
102                 rcount ++;
103                 return 1;
104         }
105 };
106
107
108 extern void BgRead_nodeinfo(int node, int &startpe, int &endpe);
109
110 #endif