projector trace files
[charm.git] / src / conv-perf / traceCore.C
1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <errno.h>
5
6 #include "converse.h"
7 #include "traceCore.h"
8 #include "traceCoreCommon.h"
9
10 #include "converseEvents.h"     //TODO: remove this hack for REGISTER_CONVESE
11 #include "charmEvents.h"        //TODO: remove this hack for REGISTER_CHARM
12
13 CpvExtern(int, _traceCoreOn);
14 CpvExtern(double, _traceCoreInitTime);
15 CpvExtern(char*, _traceCoreRoot);
16 CpvExtern(int, _traceCoreBufferSize);
17 CpvExtern(TraceCore*, _traceCore);
18
19 /* Trace Timer */
20 #define  TRACE_CORE_TIMER   CmiWallTimer
21 inline double TraceCoreTimer() { return TRACE_CORE_TIMER() - CpvAccess(_traceCoreInitTime); }
22
23 /***************** Class TraceCore Definition *****************/
24 TraceCore::TraceCore(char** argv)
25 {
26         int binary = CmiGetArgFlag(argv,"+binary-trace");
27         traceLogger = new TraceLogger(CpvAccess(_traceCoreRoot), binary);
28
29         REGISTER_CONVERSE
30         REGISTER_CHARM
31 }
32
33 TraceCore::~TraceCore()
34 { if(traceLogger) delete traceLogger; }
35
36 void TraceCore::RegisterLanguage(int lID, char* ln)
37 { traceLogger->RegisterLanguage(lID, ln); }     
38
39 //TODO: currently these are dummy definitions
40 void TraceCore::RegisterEvent(int lID, int eID)
41 { CmiPrintf("registering event (%d, %d)\n", lID, eID); }        
42
43 //TODO: only for compatibility with incomplete converse instrumentation
44 void TraceCore::LogEvent(int lID, int eID)
45 { LogEvent(lID, eID, 0, NULL, 0, NULL); }
46
47 void TraceCore::LogEvent(int lID, int eID, int iLen, int* iData)
48 { LogEvent(lID, eID, iLen, iData, 0, NULL); }
49
50 void TraceCore::LogEvent(int lID, int eID, int sLen, char* sData)
51 { LogEvent(lID, eID, 0, NULL, sLen, sData); }
52
53 void TraceCore::LogEvent(int lID, int eID, int iLen, int* iData, int sLen, char* sData)
54 {
55         CmiPrintf("lID: %d, eID: %d", lID, eID);
56         if(iData != NULL) {
57                 CmiPrintf(" iData: ");
58                 for(int i=0; i<iLen; i++) { CmiPrintf("%d ", iData[i]); }
59         }
60         if(sData != NULL) {
61                 CmiPrintf("sData: %s", sData);
62         }
63         CmiPrintf("\n");
64
65
66         traceLogger->add(lID, eID, TraceCoreTimer(), iLen, iData, sLen, sData); 
67 }
68
69 /***************** Class TraceEntry Definition *****************/
70 TraceEntry::TraceEntry(TraceEntry& te)
71 {
72         languageID = te.languageID;
73         eventID    = te.eventID;
74         timestamp  = te.timestamp;
75         eLen       = te.eLen;
76         entity     = te.entity;
77         iLen       = te.iLen;
78         iData      = te.iData;
79         sLen       = te.sLen;
80         sData      = te.sData;
81 }
82
83 TraceEntry::~TraceEntry()
84 {
85         if(entity) delete [] entity;
86         if(iData)  delete [] iData;
87         if(sData)  delete [] sData;
88 }
89
90 void TraceEntry::write(FILE* fp, int prevLID, int prevSeek, int nextLID, int nextSeek)
91 {
92         //NOTE: no need to write languageID to file
93         if(prevLID == 0 && nextLID ==0)
94                 fprintf(fp, "%d %f %d %d", eventID, timestamp, 0, 0); 
95         else if(prevLID == 0 && nextLID !=0)
96                 fprintf(fp, "%d %f %d %d %d", eventID, timestamp, 0, nextLID, nextSeek); 
97         else if(prevLID != 0 && nextLID ==0)
98                 fprintf(fp, "%d %f %d %d %d", eventID, timestamp, prevLID, prevSeek, 0); 
99         else // if(prevLID != 0 && nextLID !=0)
100                 fprintf(fp, "%d %f %d %d %d %d", eventID, timestamp, prevLID, prevSeek, nextLID, nextSeek);
101
102         fprintf(fp, " %d", eLen);
103         if(eLen != 0) {
104           for(int i=0; i<eLen; i++) fprintf(fp, " %d", entity[i]);  
105         }
106
107         fprintf(fp, " %d", iLen);
108         if(iLen != 0) {
109           for(int i=0; i<iLen; i++) fprintf(fp, " %d", iData[i]);  
110         }
111
112         if(sLen !=0) fprintf(fp, " %s\n", sData);
113         else fprintf(fp, "\n");
114
115         // free memory 
116         if(entity) delete [] entity;
117         if(iData)  delete [] iData;
118         if(sData)  delete [] sData;
119 }
120
121 /***************** Class TraceLogger Definition *****************/
122 TraceLogger::TraceLogger(char* program, int b): 
123         numLangs(1), numEntries(0), lastWriteFlag(0), prevLID(0), prevSeek(0) 
124 {
125   binary = b;
126   pool = new TraceEntry[CpvAccess(_traceCoreBufferSize)];
127   poolSize = CpvAccess(_traceCoreBufferSize);
128
129   pgm = new char[strlen(program)];
130   sprintf(pgm, "%s", program);
131   openLogFiles();
132   closeLogFiles();
133 }
134
135 TraceLogger::~TraceLogger() 
136 {
137   if(binary)
138   { lastWriteFlag = 1; writeBinary(); }
139   else
140   { lastWriteFlag = 1; write(); }
141   delete [] pool;
142   delete [] fName;
143 }
144
145 void TraceLogger::RegisterLanguage(int lID, char* ln)
146 {
147         numLangs++;
148
149         lName[lID] = new char[strlen(ln)];
150         sprintf(lName[lID], "%s", ln);
151
152         char pestr[10]; sprintf(pestr, "%d", CmiMyPe());
153         fName[lID] = new char[strlen(pgm)+1+strlen(pestr)+1+strlen(ln)+strlen(".log")];
154         sprintf(fName[lID], "%s.%s.%s.log", pgm, pestr, ln);
155
156         FILE* fp = NULL;
157         do
158         {
159         fp = fopen(fName[lID], "w");
160         } while (!fp && (errno == EINTR || errno == EMFILE));
161         if(!fp) {
162         CmiAbort("Cannot open Projector Trace File for writing ... \n");
163         }
164         if(!binary) {
165         fprintf(fp, "PROJECTOR-RECORD: %s.%s\n", pestr, lName[lID]);
166         }
167         fclose(fp);
168 }
169
170 void TraceLogger::write(void)
171 {
172         openLogFiles();
173
174         int currLID=0, nextLID=0;
175         int pLID=0, nLID=0;
176         int currSeek=0, nextSeek=0;
177         int i;
178         for(i=0; i<numEntries-1; i++) {
179                 currLID  = pool[i].languageID;
180                 FILE* fp = fptrs[currLID];
181                 currSeek = ftell(fp); 
182                 nextLID  = pool[i+1].languageID;
183                 nextSeek = ftell(fptrs[nextLID]);
184
185                 pLID = ((prevLID==currLID)?0:prevLID);
186                 nLID = ((nextLID==currLID)?0:nextLID);
187                 pool[i].write(fp, pLID, prevSeek, nLID, nextSeek);
188
189                 prevSeek = currSeek; prevLID = currLID; 
190         }
191         if(lastWriteFlag==1) {
192                 currLID  = pool[i].languageID;
193                 FILE* fp = fptrs[currLID];
194                 currSeek = ftell(fp); 
195                 nextLID  = nextSeek = 0;
196
197                 pLID = ((prevLID==currLID)?0:prevLID);
198                 nLID = ((nextLID==currLID)?0:nextLID);
199                 pool[i].write(fp, pLID, prevSeek, nLID, nextSeek);
200         }
201
202         closeLogFiles();
203 }
204
205 //TODO
206 void TraceLogger::writeBinary(void) {};
207 //TODO
208 void TraceLogger::writeSts(void) {};
209
210 void TraceLogger::add(int lID, int eID, double timestamp, int iLen, int* iData, int sLen, char* sData)
211 {
212   new (&pool[numEntries++]) TraceEntry(lID, eID, timestamp, iLen, iData, sLen, sData); 
213   if(poolSize==numEntries) {
214     double writeTime = TraceCoreTimer();
215
216     if(binary) writeBinary(); 
217         else       write();
218
219         // move the last entry of pool to first position
220     new (&pool[0]) TraceEntry(pool[numEntries-1]); 
221     numEntries = 1;
222         //TODO
223     //new (&pool[numEntries++]) TraceEntry(0, BEGIN_INTERRUPT, writeTime);
224     //new (&pool[numEntries++]) TraceEntry(0, END_INTERRUPT, TraceCoreTimer());
225   }
226 }
227
228 void TraceLogger::openLogFiles()
229 {
230   for(int i=1; i<numLangs; i++) {
231         FILE* fp = NULL;
232         do
233         {
234         fp = fopen(fName[i], "a");
235         } while (!fp && (errno == EINTR || errno == EMFILE));
236         if(!fp) {
237         CmiAbort("Cannot open Projector Trace File for writing ... \n");
238         }
239         fptrs[i] = fp;
240   }
241 }
242
243 void TraceLogger::closeLogFiles()
244 {
245   for(int i=1; i<numLangs; i++)
246         fclose(fptrs[i]);
247 }
248