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