fixed a debug statement
[charm.git] / src / conv-perf / traceCore.C
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include <string.h>
6 #include <assert.h>
7
8 #include "converse.h"
9 #include "traceCore.h"
10 #include "traceCoreCommon.h"
11
12 #include "converseEvents.h"     //TODO: remove this hack for REGISTER_CONVESE
13 #include "charmEvents.h"        //TODO: remove this hack for REGISTER_CHARM
14 #include "machineEvents.h"      // for machine events
15 //#include "ampiEvents.h"       /* for ampi events */
16
17 CpvExtern(double, _traceCoreInitTime);
18 CpvExtern(char*, _traceCoreRoot);
19 CpvExtern(int, _traceCoreBufferSize);
20 CpvExtern(TraceCore*, _traceCore);
21 //CpvStaticDeclare(int ,staticNumEntries);
22
23 /* Trace Timer */
24 #define  TRACE_CORE_TIMER   CmiWallTimer
25 inline double TraceCoreTimer() { return TRACE_CORE_TIMER() - CpvAccess(_traceCoreInitTime); }
26 inline double TraceCoreTimer(double t) { return t - CpvAccess(_traceCoreInitTime); }
27
28 /***************** Class TraceCore Definition *****************/
29 TraceCore::TraceCore(char** argv)
30 {
31         int binary = CmiGetArgFlag(argv,"+binary-trace");
32         
33
34         if(CpvAccess(_traceCoreOn) == 0){
35                 traceCoreOn=0;
36                 return;
37         }
38         traceCoreOn=1;
39         traceLogger = new TraceLogger(CpvAccess(_traceCoreRoot), binary);
40         //CmiPrintf("[%d]In TraceCore Constructor\n",CmiMyPe());
41         startPtc();
42         REGISTER_CONVERSE
43         REGISTER_CHARM
44         REGISTER_MACHINE
45         //REGISTER_AMPI
46         //closePtc();
47 }
48
49 TraceCore::~TraceCore()
50 {
51         closePtc();
52         if(traceLogger) delete traceLogger; 
53 }
54
55 void TraceCore::RegisterLanguage(int lID, char* ln)
56 {
57         //CmiPrintf("Register Language called for %s at %d \n",ln,lID);
58   if(traceCoreOn == 0){
59                 return;
60   }
61   traceLogger->RegisterLanguage(lID, ln);
62
63   // code for ptc file generation
64   if(maxlID < lID){
65         maxlID = lID;
66   }
67   lIDList[numLangs] = lID;
68   lNames[numLangs] = new char[strlen(ln)+1];
69   sprintf(lNames[numLangs],"%s",ln);
70   numLangs++;
71
72  }
73
74 struct TraceCoreEvent *insert_TraceCoreEvent(struct TraceCoreEvent *root,int eID){
75         struct TraceCoreEvent *p;
76         
77         if(root == NULL){
78                 p = (struct TraceCoreEvent *)malloc(sizeof(struct TraceCoreEvent));
79                 p->next = NULL;
80                 p->eID = eID;
81                 return p;
82         }
83         p = root;
84         while(p->next != NULL)
85                 p = p->next;
86         p->next = (struct TraceCoreEvent *)malloc(sizeof(struct TraceCoreEvent));
87         p->next->next = NULL;
88         p->next->eID = eID;
89         return root;
90 }
91
92
93 void print_TraceCoreEvent(FILE *fpPtc,struct TraceCoreEvent *root,char *lang){
94         struct TraceCoreEvent *p;
95         
96         p = root;
97         while(p!=NULL){
98                 fprintf(fpPtc,"%d %s%d ",p->eID,lang,p->eID);
99                 p = p->next;
100
101         }
102 }
103
104 //TODO: currently these are dummy definitions
105 void TraceCore::RegisterEvent(int lID, int eID)
106 {
107         //CmiPrintf("registering event (%d, %d)\n", lID, eID);
108         if(traceCoreOn == 0){
109                 return;
110         }
111         // code for ptc file generation
112         for(int i=0;i<numLangs;i++){
113                 if(lIDList[i] == lID){
114                         if(maxeID[i] < eID){
115                                 maxeID[i] = eID;
116                         }
117                         numEvents[i]++;
118                         eventLists[i] = insert_TraceCoreEvent(eventLists[i],eID);
119                         break;
120                 }
121         }
122 }
123
124 void TraceCore::startPtc(){
125         if(traceCoreOn ==0){
126                 return;
127         }
128         char *str = new char[strlen(CpvAccess(_traceCoreRoot))+strlen(".ptc")+1];
129         sprintf(str,"%s.ptc",CpvAccess(_traceCoreRoot));
130         fpPtc = fopen(str,"w");
131         if(fpPtc == NULL){
132                 CmiAbort("Can't generate Ptc file");
133         }
134         fprintf(fpPtc,"%d\n",CmiNumPes());
135         for(int i=0;i<MAX_NUM_LANGUAGES;i++){
136                 eventLists[i] = NULL;
137                 maxeID[i] = 0;
138                 numEvents[i] = 0;
139         }
140         maxlID = 0;
141         numLangs = 0;
142 }
143
144
145 void TraceCore::closePtc(){
146         int i;
147         if(traceCoreOn ==0){
148                 return;
149         }
150         fprintf(fpPtc,"%d %d ",maxlID,numLangs);
151         for(i=0;i<numLangs;i++){
152                 fprintf(fpPtc,"%d %s ",lIDList[i],lNames[i]);
153         }
154         fprintf(fpPtc,"\n");
155         for(i=0;i<numLangs;i++){
156                 fprintf(fpPtc,"%d %d %d ",lIDList[i],maxeID[i],numEvents[i]);
157                 print_TraceCoreEvent(fpPtc,eventLists[i],lNames[i]);
158                 fprintf(fpPtc,"\n");
159         }
160         fclose(fpPtc);
161 }
162
163
164
165
166 //TODO: only for compatibility with incomplete converse instrumentation
167 void TraceCore::LogEvent(int lID, int eID)
168
169         if(traceCoreOn == 0){
170                 return;
171         }
172         LogEvent(lID, eID, 0, NULL, 0, NULL); 
173 }
174
175 void TraceCore::LogEvent(int lID, int eID, int iLen, const int* iData)
176
177         if(traceCoreOn == 0){
178                 return;
179         }
180         LogEvent(lID, eID, iLen, iData, 0, NULL); 
181 }
182
183 void TraceCore::LogEvent(int lID, int eID, int iLen, const int* iData,double t){
184         if(traceCoreOn == 0){
185                 return;
186         }
187         CmiPrintf("TraceCore LogEvent called \n");
188 #ifndef CMK_OPTIMIZE    
189         int *iDataalloc;
190         if(iLen != 0){
191                 iDataalloc = (int *)malloc(iLen*sizeof(int));
192                 for(int i=0;i<iLen;i++){
193                         iDataalloc[i] = iData[i];
194                 }
195         }else{
196                 iDataalloc = NULL;
197         }
198         traceLogger->add(lID,eID,TraceCoreTimer(t),iLen,iDataalloc,0,NULL);
199 #endif
200 }
201
202
203 void TraceCore::LogEvent(int lID, int eID, int sLen, const char* sData)
204
205         if(traceCoreOn == 0){
206                 return;
207         }
208         LogEvent(lID, eID, 0, NULL, sLen, sData); 
209 }
210
211 void TraceCore::LogEvent(int lID, int eID, int iLen, const int* iData, int sLen,const char* sData)
212 {
213         //CmiPrintf("lID: %d, eID: %d", lID, eID);
214         if(traceCoreOn == 0){
215                 return;
216         }
217                 
218
219 #ifndef CMK_OPTIMIZE
220         int *iDataalloc;
221         char *sDataalloc;
222         if(iLen != 0){
223                 iDataalloc = (int *)malloc(iLen*sizeof(int));
224                 for(int i=0;i<iLen;i++){
225                         iDataalloc[i] = iData[i];
226                 }
227         }else{
228                 iDataalloc = NULL;
229         }
230         if(sLen != 0){
231                 sDataalloc = (char *)malloc(sLen*sizeof(char));
232                 for(int i=0;i<sLen;i++){
233                         sDataalloc[i] = sData[i];
234                 }
235         }else{
236                 sDataalloc = NULL;
237         }
238
239         traceLogger->add(lID, eID, TraceCoreTimer(), iLen, iDataalloc, sLen, sDataalloc);
240 #endif
241 }
242
243 /***************** Class TraceEntry Definition *****************/
244 TraceEntry::TraceEntry(TraceEntry& te)
245 {
246         languageID = te.languageID;
247         eventID    = te.eventID;
248         timestamp  = te.timestamp;
249         eLen       = te.eLen;
250         entity     = te.entity;
251         iLen       = te.iLen;
252         iData      = te.iData;
253         sLen       = te.sLen;
254         sData      = te.sData;
255 }
256
257 TraceEntry::~TraceEntry()
258 {
259         if(entity) free(entity);
260         if(iData)  free(iData);
261         if(sData)  free(sData);
262 }
263
264 void TraceEntry::write(FILE* fp, int prevLID, int prevSeek, int nextLID, int nextSeek)
265 {
266         //NOTE: no need to write languageID to file
267         if(prevLID == 0 && nextLID ==0)
268                 fprintf(fp, "%d %f %d %d ", eventID, timestamp, 0, 0);
269         else if(prevLID == 0 && nextLID !=0)
270                 fprintf(fp, "%d %f %d %d %d", eventID, timestamp, 0, nextLID, nextSeek);
271         else if(prevLID != 0 && nextLID ==0)
272                 fprintf(fp, "%d %f %d %d %d", eventID, timestamp, prevLID, prevSeek, 0);
273         else // if(prevLID != 0 && nextLID !=0)
274                 fprintf(fp, "%d %f %d %d %d %d", eventID, timestamp, prevLID, prevSeek, nextLID, nextSeek);
275
276         fprintf(fp, " %d", eLen);
277         if(eLen != 0) {
278           for(int i=0; i<eLen; i++) fprintf(fp, " %d", entity[i]);
279         }
280
281         fprintf(fp, " %d", iLen);
282         if(iLen != 0) {
283           for(int i=0; i<iLen; i++) fprintf(fp, " %d", iData[i]);
284         }
285
286         if(sLen !=0) fprintf(fp, " %s\n", sData);
287         else fprintf(fp, "\n");
288
289         // free memory
290         if(entity){
291                 free(entity);
292         }
293         entity = NULL;
294         if(iData){
295                 free(iData);
296         }
297         iData = NULL;
298         if(sData){
299                 free(sData);
300         }
301         sData=NULL;
302 }
303
304 /***************** Class TraceLogger Definition *****************/
305 TraceLogger::TraceLogger(char* program, int b):
306         numLangs(1), numEntries(0), lastWriteFlag(0), prevLID(0), prevSeek(0)
307 {
308   binary = b;
309
310   
311
312   poolSize = 10000; // CkpvAccess(CtrLogBufSize);
313   pool = new TraceEntry[poolSize+5];
314 //  CmiPrintf("CtrLogBufSize %d \n",CkpvAccess(CtrLogBufSize));
315  // CmiPrintf("PoolSize = %d \n",poolSize);
316   for (int lID=0;lID<MAX_NUM_LANGUAGES;lID++) {
317     lName[lID]=NULL;
318     fName[lID]=NULL;
319   }
320
321   pgm = new char[strlen(program)+1];
322   sprintf(pgm, "%s", program);
323   numEntries = 0;
324   isWriting = 0;
325   buffer = NULL;
326
327   //CmiPrintf("In TraceLogger Constructor %s %d",pgm,strlen(program)+1);
328   //initlogfiles();
329
330 }
331
332  void TraceLogger::initlogfiles(){
333         openLogFiles();
334         closeLogFiles();
335 }
336
337
338 TraceLogger::~TraceLogger()
339 {
340   if(binary)
341   { lastWriteFlag = 1; writeBinary(); }
342   else
343   { lastWriteFlag = 1; write(); }
344   for (int lID=0;lID<MAX_NUM_LANGUAGES;lID++) {
345     delete[] lName[lID];
346     delete[] fName[lID];
347   }
348 }
349
350 void TraceLogger::RegisterLanguage(int lID, char* ln)
351 {
352         numLangs++;
353
354         lName[lID] = new char[strlen(ln)+1];
355         sprintf(lName[lID], "%s", ln);
356
357         char pestr[10]; sprintf(pestr, "%d\0", CmiMyPe());
358         fName[lID] = new char[strlen(pgm)+1+strlen(pestr)+1+strlen(ln)+strlen(".log")+10];
359         sprintf(fName[lID], "%s.%s.%s.log", pgm, pestr, ln);
360
361         // my debug code - schak
362         //CmiPrintf("%s at %d in %d \n",fName[lID],lID,fName[lID]);
363         if(CpvAccess(_traceCoreOn) == 0){
364                 CmiPrintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1_traceCoreOn = 0 in RegisterLanguage \n");
365                 return;
366         }
367         FILE* fp = NULL;
368         do
369         {
370         fp = fopen(fName[lID], "w");
371         } while (!fp && (errno == EINTR || errno == EMFILE));
372         if(!fp) {
373         CmiAbort("Cannot open Projector Trace File for writing ... \n");
374         }
375         if(!binary) {
376         fprintf(fp, "PROJECTOR-RECORD: %s.%s\n", pestr, lName[lID]);
377         }
378         //fclose(fp);
379         fptrs[lID] = fp;
380 }
381
382 void TraceLogger::verifyFptrs(){
383         
384   for(int i=1; i<numLangs; i++){
385                 if(!fptrs[i]){
386                         CmiPrintf("Null File Pointer Found after Open\n");
387                 }
388   }
389 }
390
391 void TraceLogger::write(void)
392 {
393         if(CpvAccess(_traceCoreOn) == 0){
394                 return;
395         }
396         //openLogFiles();
397         verifyFptrs();
398         int currLID=0, nextLID=0;
399         int pLID=0, nLID=0;
400         int currSeek=0, nextSeek=0;
401         int i;
402         for(i=0; i<numEntries-1; i++) {
403                 currLID  = pool[i].languageID;
404                 FILE* fp = fptrs[currLID];
405                 if(fp ==  NULL)
406                         return;
407                 currSeek = ftell(fp);
408                 nextLID  = pool[i+1].languageID;
409                 nextSeek = ftell(fptrs[nextLID]);
410
411                 pLID = ((prevLID==currLID)?0:prevLID);
412                 nLID = ((nextLID==currLID)?0:nextLID);
413                 pool[i].write(fp, pLID, prevSeek, nLID, nextSeek);
414
415                 prevSeek = currSeek; prevLID = currLID;
416                 flushLogFiles();
417         }
418         if(lastWriteFlag==1) {
419                 currLID  = pool[i].languageID;
420                 FILE* fp = fptrs[currLID];
421                 if(fp == NULL)
422                         return;
423                 currSeek = ftell(fp);
424                 nextLID  = nextSeek = 0;
425
426                 pLID = ((prevLID==currLID)?0:prevLID);
427                 nLID = ((nextLID==currLID)?0:nextLID);
428                 pool[i].write(fp, pLID, prevSeek, nLID, nextSeek);
429                 closeLogFiles();
430         }
431
432         
433 }
434
435 //TODO
436 void TraceLogger::writeBinary(void) {};
437 //TODO
438 void TraceLogger::writeSts(void) {};
439
440 void TraceLogger::add(int lID, int eID, double timestamp, int iLen, int* iData, int sLen, char* sData)
441 {
442         
443   if(isWriting){
444         //  CmiPrintf("Printing in buffer \n");
445           buffer = new TraceEntry(lID, eID, timestamp, iLen, iData, sLen, sData);
446   }else{
447   new (&pool[numEntries]) TraceEntry(lID, eID, timestamp, iLen, iData, sLen, sData);
448   numEntries = numEntries+1;
449 if(numEntries>= poolSize) {
450     double writeTime = TraceCoreTimer();
451     isWriting = 1;
452     if(binary) writeBinary();
453         else       write();
454
455
456     new (&pool[0]) TraceEntry(pool[numEntries-1]);
457     //numEntries = 1;
458     numEntries=1;
459     if(buffer != NULL){
460             new (&pool[1]) TraceEntry(*buffer);
461             numEntries=2;
462             delete buffer;
463             buffer = NULL;
464     }
465         isWriting = 0;
466         //TODO
467     //new (&pool[numEntries++]) TraceEntry(0, BEGIN_INTERRUPT, writeTime);
468     //new (&pool[numEntries++]) TraceEntry(0, END_INTERRUPT, TraceCoreTimer());
469   }
470  }
471 }
472
473 void TraceLogger::openLogFiles()
474 {
475   CmiPrintf("[%d]Entering openLogFile \n",CmiMyPe());
476   for(int i=1; i<numLangs; i++) {
477
478         FILE* fp = NULL;
479         do
480         {
481
482                         fp = fopen(fName[i], "a");
483
484         } while (!fp && (errno == EINTR || errno == EMFILE));
485         if(!fp) {
486         //      CmiPrintf("FILE NAME %s at %d \n",fName[i],i);
487                 CmiAbort("Cannot open Projector Trace File for writing ... \n");
488         }
489         CmiPrintf("[%d]Iteration %d : fp %d \n",CmiMyPe(),i,fp);
490         fptrs[i] = fp;
491
492         if(i == 1)
493                 assert(fptrs[1]);
494         else if(i == 2)
495         {
496                 assert(fptrs[1]);
497                 assert(fptrs[2]);
498         }
499         else if(i>= 3)
500         {
501                 assert(fptrs[1]);
502                 assert(fptrs[2]);
503                 assert(fptrs[3]);
504         }
505   }
506   CmiAssert(fptrs[1]);
507     CmiAssert(fptrs[2]);
508       CmiAssert(fptrs[3]);
509   CmiPrintf("[%d]In Open log files ........\n",CmiMyPe());
510   verifyFptrs();
511   CmiPrintf("[%d].....................\n",CmiMyPe());
512 }
513
514 void TraceLogger::closeLogFiles()
515 {
516
517   for(int i=1; i<numLangs; i++){
518                 if(fptrs[i])
519                         fclose(fptrs[i]);
520                 fptrs[i]=NULL;
521                 
522   }
523 }
524
525 void TraceLogger::flushLogFiles(){
526         for(int i=1;i<numLangs;i++){
527                 fflush(fptrs[i]);
528         }
529 }
530