a little utility to record start/end events.
[charm.git] / src / langs / bluegene / bigsim_record.C
1
2 #include <stdio.h>
3
4 #include "blue.h"
5 #include "bigsim_record.h"
6 #include "blue_impl.h"
7 #include "charm++.h"
8 #include "envelope.h"
9
10 int converseheader = 0;
11
12 int _heter = 1;
13
14 BgMessageRecorder::BgMessageRecorder(FILE * f_, int node) :f(f_) {
15   nodelevel = node;
16   fwrite(&nodelevel, sizeof(int),1,f);
17
18   converseheader = CmiReservedHeaderSize;
19   fwrite(&converseheader, sizeof(int),1,f);
20
21   // write processor data
22   int d = BgGetGlobalWorkerThreadID();
23   int mype = d;
24   fwrite(&d, sizeof(int),1,f);
25
26   nodeInfo *myNode = cta(threadinfo)->myNode;
27   d = myNode->x;
28   fwrite(&d, sizeof(int), 1, f);
29   d = myNode->y;
30   fwrite(&d, sizeof(int), 1, f);
31   d = myNode->z;
32   fwrite(&d, sizeof(int), 1, f);
33
34   d = BgGetThreadID();
35   fwrite(&d, sizeof(int), 1, f);
36
37   d = BgNumNodes();
38   fwrite(&d, sizeof(int), 1, f);
39
40   d = BgNumNodes()*BgGetNumWorkThread();
41   fwrite(&d, sizeof(int), 1, f);
42  
43   d = cva(bgMach).x;
44   fwrite(&d, sizeof(int), 1, f);
45   d = cva(bgMach).y;
46   fwrite(&d, sizeof(int), 1, f);
47   d = cva(bgMach).z;
48   fwrite(&d, sizeof(int), 1, f);
49  
50   if (nodelevel == 1 && mype % BgGetNumWorkThread() == 0) {
51     write_nodeinfo();
52   }
53 }
54
55 void BgMessageRecorder::write_nodeinfo()
56 {
57   int mype = BgGetGlobalWorkerThreadID();
58   int mynode = mype / BgGetNumWorkThread();
59   char fName[128];
60   sprintf(fName,"bgnode_%06d.log",mynode);
61   FILE *fp = fopen(fName, "w");
62   fprintf(fp, "%d %d\n", mype, mype + BgGetNumWorkThread()-1);
63   fclose(fp);
64 }
65
66 CmiBool BgMessageRecorder::record(char *msg) {
67                 CmiAssert(msg != NULL);
68 //                if (BgGetGlobalWorkerThreadID()==0) printf("srcpe: %d size: %d handle: %d\n",CmiBgMsgSrcPe(msg),CmiBgMsgLength(msg),CmiBgMsgHandle(msg));
69                 int d = CmiBgMsgSrcPe(msg);
70                 pos = ftell(f);
71                 fwrite(&d, sizeof(int), 1, f);
72 //CmiAssert(CmiBgMsgThreadID(msg) != -1);
73                 if ( (nodelevel == 0 && d == BgGetGlobalWorkerThreadID()) ||
74                      (nodelevel == 1 && d/BgGetNumWorkThread() == BgGetGlobalWorkerThreadID()/BgGetNumWorkThread()) ) {
75                     //CmiPrintf("[%d] local message.\n", BgGetGlobalWorkerThreadID());
76                     return CmiTrue; // don't record local msg
77                 }
78 /*
79 if (BgGetGlobalWorkerThreadID()==1 && CmiBgMsgHandle(msg) == 21) {
80 int *m = (int *) ((char *)msg+CmiReservedHeaderSize);
81 printf("replay: %d %d\n", m[0], m[1]);
82 }
83 */
84                 if (_heter) {                     // heter
85                 int isCharm = (CmiGetHandler(msg)==_charmHandlerIdx) || (CmiGetXHandler(msg)==_charmHandlerIdx);
86                 fwrite(&isCharm, sizeof(int), 1, f);
87                 if (isCharm) {
88                 PUP::toDisk p(f);
89                 envelope *env = (envelope*)msg;
90                 char *m = (char *)EnvToUsr(env);
91                 CkPupMessage(p, (void **)&m, 2);
92                 }
93                 else {    // converse
94                 d = CmiBgMsgLength(msg) - CmiReservedHeaderSize;
95                 fwrite(&d, sizeof(int), 1, f);
96                 fwrite(msg+CmiReservedHeaderSize, sizeof(char), d, f);
97                 }
98                 d = CmiGetHandler(msg);
99                 fwrite(&d, sizeof(int), 1, f);
100                 d = CmiGetXHandler(msg);
101                 fwrite(&d, sizeof(int), 1, f);
102                 d = CmiGetInfo(msg);
103                 fwrite(&d, sizeof(int), 1, f);
104                   // bigsim header
105                 d = CmiBgMsgType(msg);
106                 fwrite(&d, sizeof(int), 1, f);
107                 d = CmiBgMsgLength(msg) - sizeof(envelope);
108                 fwrite(&d, sizeof(int), 1, f);
109                 d = CmiBgMsgNodeID(msg);
110                 fwrite(&d, sizeof(int), 1, f);
111                 d = CmiBgMsgThreadID(msg);
112                 fwrite(&d, sizeof(int), 1, f);
113                 d = CmiBgMsgHandle(msg);
114                 fwrite(&d, sizeof(int), 1, f);
115                 d = CmiBgMsgID(msg);
116                 fwrite(&d, sizeof(int), 1, f);
117                 d = CmiBgMsgSrcPe(msg);
118                 fwrite(&d, sizeof(int), 1, f);
119                 d = CmiBgMsgFlag(msg);
120                 fwrite(&d, sizeof(int), 1, f);
121                 d = CmiBgMsgRefCount(msg);
122                 fwrite(&d, sizeof(int), 1, f);
123                 }
124                 else {      // store by bytes
125                 d = CmiBgMsgLength(msg);
126                 fwrite(&d, sizeof(int), 1, f);
127                 fwrite(msg, sizeof(char), d, f);
128                 }
129                 //CmiPrintf("[%d] BgMessageRecord>  PE: %d size: %d msg: %p\n", BgGetGlobalWorkerThreadID(), CmiBgMsgSrcPe(msg),CmiBgMsgLength(msg), msg);
130                 return CmiTrue;
131 }
132
133 BgMessageReplay::BgMessageReplay(FILE * f_, int node) :f(f_) {
134   nodelevel = node;
135   lcount = rcount = 0;
136
137   int d;
138   fread(&d, sizeof(int), 1, f);
139   if (nodelevel != d) {
140     CmiPrintf("BgReplay> Fatal error: can not replay %s logs.\n", d?"node level":"processor level");
141     CmiAbort("BgReplay error");
142   }
143
144   fread(&converseheader, sizeof(int),1,f);
145
146   fread(&d, sizeof(int), 1, f);
147   BgSetGlobalWorkerThreadID(d);
148
149   nodeInfo *myNode = cta(threadinfo)->myNode;
150   fread(&d, sizeof(int), 1, f);
151   myNode->x = d;
152   fread(&d, sizeof(int), 1, f);
153   myNode->y = d;
154   fread(&d, sizeof(int), 1, f);
155   myNode->z = d;
156
157   fread(&d, sizeof(int), 1, f);
158   BgSetThreadID(d);
159   if (nodelevel == 0 && d != 0)
160     CmiAbort("BgReplay> Fatal error: can not replay processor level log of rank other than 0.");
161   fread(&d, sizeof(int), 1, f);
162   BgSetNumNodes(d);
163   fread(&d, sizeof(int), 1, f);
164   if (nodelevel == 1 && d/BgNumNodes() != BgGetNumWorkThread())
165     CmiAbort("BgReplay> Fatal error: the number of worker threads is not the same as in the logs.\n");
166   BgSetNumWorkThread(d/BgNumNodes());
167
168   fread(&d, sizeof(int), 1, f);
169   cva(bgMach).x = d;
170   fread(&d, sizeof(int), 1, f);
171   cva(bgMach).y = d;
172   fread(&d, sizeof(int), 1, f);
173   cva(bgMach).z = d;
174
175   //myNode->id = nodeInfo::XYZ2Local(myNode->x,myNode->y,myNode->z);
176
177   CmiPrintf("BgMessageReplay: PE => %d NumPes => %d wth:%d\n", BgGetGlobalWorkerThreadID(), BgNumNodes()*BgGetNumWorkThread(), BgGetNumWorkThread());
178
179   replay();
180 }
181
182 void BgRead_nodeinfo(int node, int &startpe, int &endpe)
183 {
184     char fName[128];
185     sprintf(fName,"bgnode_%06d.log",node);
186     FILE *fp = fopen(fName, "r");
187     if (fp==NULL) {
188       CmiPrintf("BgReplayNode> metadata file for node %d does not exist!\n", node);
189       CmiAbort("BgRead_nodeinfo");
190     }
191     fscanf(fp, "%d %d\n", &startpe, &endpe);
192     fclose(fp);
193 }
194
195 int BgMessageReplay::replay(void) {
196                 int nextPE;
197                 int ret =  fread(&nextPE, sizeof(int), 1, f);
198                 if (-1 == ret || ret == 0) {
199 //                      done();
200                         callAllUserTracingFunction();   // flush logs
201                         ConverseExit();
202                         return 0;
203                 }
204                 int mype = BgGetGlobalWorkerThreadID();
205                 if ( (nodelevel == 0 && nextPE == mype) ||
206                      (nodelevel == 1 && nextPE/BgGetNumWorkThread() == mype/BgGetNumWorkThread()) ) {
207 //printf("BgMessageReplay> local message\n");
208                   lcount ++;
209                   return 0;
210                 }
211
212                 char *msg;
213                 int nextSize;
214                 if (_heter) {                     // heter
215                 int isCharm;
216                 int d;
217                 fread(&isCharm, sizeof(int), 1, f);
218                 if (isCharm) {
219 printf("Charm msg\n");
220                 PUP::fromDisk p(f);
221                 char *m;
222                 CkPupMessage(p, (void **)&m, 2);
223                 msg = (char*)UsrToEnv(m);
224                 }
225                 else {   // Converse
226                   fread(&d, sizeof(int), 1, f);
227                   int len = d + CmiReservedHeaderSize;
228 printf("Converse msg: %d\n", len);
229                   msg = (char*)CmiAlloc(len);
230                   fread(msg+CmiReservedHeaderSize, sizeof(char), d, f);
231                 }
232                 fread(&d, sizeof(int), 1, f);
233                 CmiSetHandler(msg, d);
234                 fread(&d, sizeof(int), 1, f);
235                 CmiSetXHandler(msg, d);
236                 fread(&d, sizeof(int), 1, f);
237                 CmiSetInfo(msg, d);
238                   // bigsim header
239                 fread(&d, sizeof(int), 1, f);
240                 CmiBgMsgType(msg) = d;
241                 fread(&d, sizeof(int), 1, f);
242                 CmiBgMsgLength(msg) = d + sizeof(envelope);
243                 nextSize = CmiBgMsgLength(msg);
244                 fread(&d, sizeof(int), 1, f);
245                 CmiBgMsgNodeID(msg) = d;
246                 fread(&d, sizeof(int), 1, f);
247                 CmiBgMsgThreadID(msg) = d;
248                 fread(&d, sizeof(int), 1, f);
249                 CmiBgMsgHandle(msg) = d;
250                 if(d<0 || d>1000) CmiPrintf("Suspicious BigSim handler %d\n", d);
251                 fread(&d, sizeof(int), 1, f);
252                 CmiBgMsgID(msg) = d;
253                 fread(&d, sizeof(int), 1, f);
254                 CmiBgMsgSrcPe(msg) = d;
255                 fread(&d, sizeof(int), 1, f);
256                 CmiBgMsgFlag(msg) = d;
257                 fread(&d, sizeof(int), 1, f);
258                 CmiBgMsgRefCount(msg) = d;
259                 }
260                 else {      // read by bytes
261                 ret = fread(&nextSize, sizeof(int), 1, f);
262                 CmiAssert(ret ==1);
263                 CmiAssert(nextSize > 0);
264                 msg = (char*)CmiAlloc(nextSize);
265                 ret = fread(msg, sizeof(char), nextSize, f);
266                 if (ret != nextSize) {
267                   CmiPrintf("Bigsim replay> fread returns only %d when asked %d bytes!\n", ret, nextSize);
268                 CmiAssert(ret == nextSize);
269                 }
270                 }
271                 CmiAssert(CmiBgMsgLength(msg) == nextSize);
272                 // CmiPrintf("BgMessageReplay>  pe:%d size: %d handle: %d msg: %p\n", nextPE, nextSize, CmiBgMsgHandle(msg), msg);
273                 BgSendLocalPacket(mype%BgGetNumWorkThread(), CmiBgMsgHandle(msg), LARGE_WORK, nextSize, msg);
274                 rcount ++;
275                 return 1;
276 }