Fix parallel build of examples/charm++/user-driven-interop
[charm.git] / src / conv-perf / traceCore.C
blob34723a648d566f2816b1be628ac6e17d14c0da27
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include <string.h>
6 #include <assert.h>
8 #include "converse.h"
9 #include "traceCore.h"
10 #include "traceCoreCommon.h"
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
16 CpvExtern(double, _traceCoreInitTime);
17 CpvExtern(char*, _traceCoreRoot);
18 CpvExtern(int, _traceCoreBufferSize);
19 CpvExtern(TraceCore*, _traceCore);
20 //CpvStaticDeclare(int ,staticNumEntries);
22 /* Trace Timer */
23 #define  TRACE_CORE_TIMER   CmiWallTimer
24 inline double TraceCoreTimer() { return TRACE_CORE_TIMER() - CpvAccess(_traceCoreInitTime); }
25 inline double TraceCoreTimer(double t) { return t - CpvAccess(_traceCoreInitTime); }
27 /***************** Class TraceCore Definition *****************/
28 TraceCore::TraceCore(char** argv)
30         int binary = CmiGetArgFlag(argv,"+binary-trace");
31         
33         if(CpvAccess(_traceCoreOn) == 0){
34                 traceCoreOn=0;
35                 return;
36         }
37         traceCoreOn=1;
38         traceLogger = new TraceLogger(CpvAccess(_traceCoreRoot), binary);
39         //CmiPrintf("[%d]In TraceCore Constructor\n",CmiMyPe());
40         startPtc();
41         REGISTER_CONVERSE
42         REGISTER_CHARM
43         REGISTER_MACHINE
44         //REGISTER_AMPI
45         //closePtc();
48 TraceCore::~TraceCore()
50         closePtc();
51         if(traceLogger) delete traceLogger; 
54 void TraceCore::RegisterLanguage(int lID, const char* ln)
56         //CmiPrintf("Register Language called for %s at %d \n",ln,lID);
57   if(traceCoreOn == 0){
58                 return;
59   }
60   traceLogger->RegisterLanguage(lID, ln);
62   // code for ptc file generation
63   if(maxlID < lID){
64         maxlID = lID;
65   }
66   lIDList[numLangs] = lID;
67   lNames[numLangs] = new char[strlen(ln)+1];
68   sprintf(lNames[numLangs],"%s",ln);
69   numLangs++;
71  }
73 struct TraceCoreEvent *insert_TraceCoreEvent(struct TraceCoreEvent *root,int eID){
74         struct TraceCoreEvent *p;
75         
76         if(root == NULL){
77                 p = (struct TraceCoreEvent *)malloc(sizeof(struct TraceCoreEvent));
78                 p->next = NULL;
79                 p->eID = eID;
80                 return p;
81         }
82         p = root;
83         while(p->next != NULL)
84                 p = p->next;
85         p->next = (struct TraceCoreEvent *)malloc(sizeof(struct TraceCoreEvent));
86         p->next->next = NULL;
87         p->next->eID = eID;
88         //cppcheck-suppress memleak
89         return root;
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;
101         }
104 //TODO: currently these are dummy definitions
105 void TraceCore::RegisterEvent(int lID, int eID)
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         }
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     delete [] str;
146 void TraceCore::closePtc(){
147         int i;
148         if(traceCoreOn ==0){
149                 return;
150         }
151         fprintf(fpPtc,"%d %d ",maxlID,numLangs);
152         for(i=0;i<numLangs;i++){
153                 fprintf(fpPtc,"%d %s ",lIDList[i],lNames[i]);
154         }
155         fprintf(fpPtc,"\n");
156         for(i=0;i<numLangs;i++){
157                 fprintf(fpPtc,"%d %d %d ",lIDList[i],maxeID[i],numEvents[i]);
158                 print_TraceCoreEvent(fpPtc,eventLists[i],lNames[i]);
159                 fprintf(fpPtc,"\n");
160         }
161         fclose(fpPtc);
167 //TODO: only for compatibility with incomplete converse instrumentation
168 void TraceCore::LogEvent(int lID, int eID)
170         if(traceCoreOn == 0){
171                 return;
172         }
173         LogEvent(lID, eID, 0, NULL, 0, NULL); 
176 void TraceCore::LogEvent(int lID, int eID, int iLen, const int* iData)
178         if(traceCoreOn == 0){
179                 return;
180         }
181         LogEvent(lID, eID, iLen, iData, 0, NULL); 
184 void TraceCore::LogEvent(int lID, int eID, int iLen, const int* iData,double t){
185         if(traceCoreOn == 0){
186                 return;
187         }
188         CmiPrintf("TraceCore LogEvent called \n");
189 #if CMK_TRACE_ENABLED   
190         int *iDataalloc;
191         if(iLen != 0){
192                 iDataalloc = (int *)malloc(iLen*sizeof(int));
193                 for(int i=0;i<iLen;i++){
194                         iDataalloc[i] = iData[i];
195                 }
196         }else{
197                 iDataalloc = NULL;
198         }
199         traceLogger->add(lID,eID,TraceCoreTimer(t),iLen,iDataalloc,0,NULL);
200 #endif
204 void TraceCore::LogEvent(int lID, int eID, int sLen, const char* sData)
206         if(traceCoreOn == 0){
207                 return;
208         }
209         LogEvent(lID, eID, 0, NULL, sLen, sData); 
212 void TraceCore::LogEvent(int lID, int eID, int iLen, const int* iData, int sLen,const char* sData)
214         //CmiPrintf("lID: %d, eID: %d", lID, eID);
215         if(traceCoreOn == 0){
216                 return;
217         }
218                 
220 #if CMK_TRACE_ENABLED
221         int *iDataalloc;
222         char *sDataalloc;
223         if(iLen != 0){
224                 iDataalloc = (int *)malloc(iLen*sizeof(int));
225                 for(int i=0;i<iLen;i++){
226                         iDataalloc[i] = iData[i];
227                 }
228         }else{
229                 iDataalloc = NULL;
230         }
231         if(sLen != 0){
232                 sDataalloc = (char *)malloc(sLen*sizeof(char));
233                 for(int i=0;i<sLen;i++){
234                         sDataalloc[i] = sData[i];
235                 }
236         }else{
237                 sDataalloc = NULL;
238         }
240         traceLogger->add(lID, eID, TraceCoreTimer(), iLen, iDataalloc, sLen, sDataalloc);
241 #endif
244 /***************** Class TraceEntry Definition *****************/
245 TraceEntry::TraceEntry(TraceEntry& te)
247         languageID = te.languageID;
248         eventID    = te.eventID;
249         timestamp  = te.timestamp;
250         eLen       = te.eLen;
251         entity     = te.entity;
252         iLen       = te.iLen;
253         iData      = te.iData;
254         sLen       = te.sLen;
255         sData      = te.sData;
258 TraceEntry::~TraceEntry()
260         if(entity) free(entity);
261         if(iData)  free(iData);
262         if(sData)  free(sData);
265 void TraceEntry::write(FILE* fp, int prevLID, int prevSeek, int nextLID, int nextSeek)
267         //NOTE: no need to write languageID to file
268         if(prevLID == 0 && nextLID ==0)
269                 fprintf(fp, "%d %f %d %d ", eventID, timestamp, 0, 0);
270         else if(prevLID == 0 && nextLID !=0)
271                 fprintf(fp, "%d %f %d %d %d", eventID, timestamp, 0, nextLID, nextSeek);
272         else if(prevLID != 0 && nextLID ==0)
273                 fprintf(fp, "%d %f %d %d %d", eventID, timestamp, prevLID, prevSeek, 0);
274         else // if(prevLID != 0 && nextLID !=0)
275                 fprintf(fp, "%d %f %d %d %d %d", eventID, timestamp, prevLID, prevSeek, nextLID, nextSeek);
277         fprintf(fp, " %d", eLen);
278         if(eLen != 0) {
279           for(int i=0; i<eLen; i++) fprintf(fp, " %d", entity[i]);
280         }
282         fprintf(fp, " %d", iLen);
283         if(iLen != 0) {
284           for(int i=0; i<iLen; i++) fprintf(fp, " %d", iData[i]);
285         }
287         if(sLen !=0) fprintf(fp, " %s\n", sData);
288         else fprintf(fp, "\n");
290         // free memory
291         if(entity){
292                 free(entity);
293         }
294         entity = NULL;
295         if(iData){
296                 free(iData);
297         }
298         iData = NULL;
299         if(sData){
300                 free(sData);
301         }
302         sData=NULL;
305 /***************** Class TraceLogger Definition *****************/
306 TraceLogger::TraceLogger(char* program, int b):
307         numEntries(0), numLangs(1), lastWriteFlag(false), prevLID(0), prevSeek(0)
309   binary = b;
311   
313   poolSize = 10000; // CkpvAccess(CtrLogBufSize);
314   pool = new TraceEntry[poolSize+5];
315 //  CmiPrintf("CtrLogBufSize %d \n",CkpvAccess(CtrLogBufSize));
316  // CmiPrintf("PoolSize = %d \n",poolSize);
317   for (int lID=0;lID<MAX_NUM_LANGUAGES;lID++) {
318     lName[lID]=NULL;
319     fName[lID]=NULL;
320   }
322   pgm = new char[strlen(program)+1];
323   sprintf(pgm, "%s", program);
324   numEntries = 0;
325   isWriting = false;
326   buffer = NULL;
328   //CmiPrintf("In TraceLogger Constructor %s %d",pgm,strlen(program)+1);
329   //initlogfiles();
333  void TraceLogger::initlogfiles(){
334         openLogFiles();
335         closeLogFiles();
339 TraceLogger::~TraceLogger()
341   if(binary)
342   { lastWriteFlag = true; writeBinary(); }
343   else
344   { lastWriteFlag = true; write(); }
345   for (int lID=0;lID<MAX_NUM_LANGUAGES;lID++) {
346     delete[] lName[lID];
347     delete[] fName[lID];
348   }
351 void TraceLogger::RegisterLanguage(int lID, const char* ln)
353         numLangs++;
355         lName[lID] = new char[strlen(ln)+1];
356         sprintf(lName[lID], "%s", ln);
358         char pestr[10]; sprintf(pestr, "%d", CmiMyPe());
359         fName[lID] = new char[strlen(pgm)+1+strlen(pestr)+1+strlen(ln)+strlen(".log")+10];
360         sprintf(fName[lID], "%s.%s.%s.log", pgm, pestr, ln);
362         // my debug code - schak
363         //CmiPrintf("%s at %d in %d \n",fName[lID],lID,fName[lID]);
364         if(CpvAccess(_traceCoreOn) == 0){
365                 CmiPrintf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1_traceCoreOn = 0 in RegisterLanguage \n");
366                 return;
367         }
368         FILE* fp = NULL;
369         do
370         {
371         fp = fopen(fName[lID], "w");
372         } while (!fp && (errno == EINTR || errno == EMFILE));
373         if(!fp) {
374         CmiAbort("Cannot open Projector Trace File for writing ... \n");
375         }
376         if(!binary) {
377         fprintf(fp, "PROJECTOR-RECORD: %s.%s\n", pestr, lName[lID]);
378         }
379         //fclose(fp);
380         fptrs[lID] = fp;
383 void TraceLogger::verifyFptrs(){
384         
385   for(int i=1; i<numLangs; i++){
386                 if(!fptrs[i]){
387                         CmiPrintf("Null File Pointer Found after Open\n");
388                 }
389   }
392 void TraceLogger::write(void)
394         if(CpvAccess(_traceCoreOn) == 0){
395                 return;
396         }
397         //openLogFiles();
398         verifyFptrs();
399         int currLID=0, nextLID=0;
400         int pLID=0, nLID=0;
401         int currSeek=0, nextSeek=0;
402         int i;
403         for(i=0; i<numEntries-1; i++) {
404                 currLID  = pool[i].languageID;
405                 FILE* fp = fptrs[currLID];
406                 if(fp ==  NULL)
407                         return;
408                 currSeek = ftell(fp);
409                 nextLID  = pool[i+1].languageID;
410                 nextSeek = ftell(fptrs[nextLID]);
412                 pLID = ((prevLID==currLID)?0:prevLID);
413                 nLID = ((nextLID==currLID)?0:nextLID);
414                 pool[i].write(fp, pLID, prevSeek, nLID, nextSeek);
416                 prevSeek = currSeek; prevLID = currLID;
417                 flushLogFiles();
418         }
419         if(lastWriteFlag) {
420                 currLID  = pool[i].languageID;
421                 FILE* fp = fptrs[currLID];
422                 if(fp == NULL)
423                         return;
424                 currSeek = ftell(fp);
425                 nextLID  = nextSeek = 0;
427                 pLID = ((prevLID==currLID)?0:prevLID);
428                 nLID = ((nextLID==currLID)?0:nextLID);
429                 pool[i].write(fp, pLID, prevSeek, nLID, nextSeek);
430                 closeLogFiles();
431         }
433         
436 //TODO
437 void TraceLogger::writeBinary(void) {}
438 //TODO
439 void TraceLogger::writeSts(void) {}
441 void TraceLogger::add(int lID, int eID, double timestamp, int iLen, int* iData, int sLen, char* sData)
443         
444   if(isWriting){
445         //  CmiPrintf("Printing in buffer \n");
446           buffer = new TraceEntry(lID, eID, timestamp, iLen, iData, sLen, sData);
447   }else{
448   new (&pool[numEntries]) TraceEntry(lID, eID, timestamp, iLen, iData, sLen, sData);
449   numEntries = numEntries+1;
450 if(numEntries>= poolSize) {
451     double writeTime = TraceCoreTimer();
452     isWriting = true;
453     if(binary) writeBinary();
454         else       write();
457     new (&pool[0]) TraceEntry(pool[numEntries-1]);
458     //numEntries = 1;
459     numEntries=1;
460     if(buffer != NULL){
461             new (&pool[1]) TraceEntry(*buffer);
462             numEntries=2;
463             delete buffer;
464             buffer = NULL;
465     }
466         isWriting = false;
467         //TODO
468     //new (&pool[numEntries++]) TraceEntry(0, BEGIN_INTERRUPT, writeTime);
469     //new (&pool[numEntries++]) TraceEntry(0, END_INTERRUPT, TraceCoreTimer());
470   }
474 void TraceLogger::openLogFiles()
476   CmiPrintf("[%d]Entering openLogFile \n",CmiMyPe());
477   for(int i=1; i<numLangs; i++) {
479         FILE* fp = NULL;
480         do
481         {
483                         fp = fopen(fName[i], "a");
485         } while (!fp && (errno == EINTR || errno == EMFILE));
486         if(!fp) {
487         //      CmiPrintf("FILE NAME %s at %d \n",fName[i],i);
488                 CmiAbort("Cannot open Projector Trace File for writing ... \n");
489         }
490         CmiPrintf("[%d]Iteration %d : fp %d \n",CmiMyPe(),i,fp);
491         fptrs[i] = fp;
493         if(i == 1)
494                 assert(fptrs[1]);
495         else if(i == 2)
496         {
497                 assert(fptrs[1]);
498                 assert(fptrs[2]);
499         }
500         else if(i>= 3)
501         {
502                 assert(fptrs[1]);
503                 assert(fptrs[2]);
504                 assert(fptrs[3]);
505         }
506   }
507   CmiAssert(fptrs[1]);
508     CmiAssert(fptrs[2]);
509       CmiAssert(fptrs[3]);
510   CmiPrintf("[%d]In Open log files ........\n",CmiMyPe());
511   verifyFptrs();
512   CmiPrintf("[%d].....................\n",CmiMyPe());
515 void TraceLogger::closeLogFiles()
518   for(int i=1; i<numLangs; i++){
519                 if(fptrs[i])
520                         fclose(fptrs[i]);
521                 fptrs[i]=NULL;
522                 
523   }
526 void TraceLogger::flushLogFiles(){
527         for(int i=1;i<numLangs;i++){
528                 fflush(fptrs[i]);
529         }