add definition for CmiInt16
[charm.git] / src / ck-perf / trace-summary.h
1 /**
2  * \addtogroup CkPerf
3 */
4 /*@{*/
5
6 #ifndef _SUMMARY_H
7 #define _SUMMARY_H
8
9 #include <stdio.h>
10 #include <errno.h>
11
12 #include "trace.h"
13 #include "envelope.h"
14 #include "register.h"
15 #include "trace-common.h"
16
17 // initial bin size, time in seconds
18 #define  BIN_SIZE       0.001
19
20 #define  MAX_MARKS       256
21
22 #define  MAX_PHASES       100
23
24 /// Bin entry record CPU time in an interval
25 class BinEntry {
26   public:
27     void *operator new(size_t s) {void*ret=malloc(s);_MEMCHECK(ret);return ret;}
28     void *operator new(size_t, void *ptr) { return ptr; }
29     void operator delete(void *ptr) { free(ptr); }
30 #if defined(WIN32) || CMK_MULTIPLE_DELETE
31     void operator delete(void *, void *) { }
32 #endif
33     BinEntry(): _time(0.), _idleTime(0.) {}
34     BinEntry(double t, double idleT): _time(t), _idleTime(idleT) {}
35     double &time() { return _time; }
36     double &getIdleTime() { return _idleTime; }
37     void write(FILE *fp);
38     int  getU();
39     int getUIdle();
40   private:
41     double _time;
42     double _idleTime;
43 };
44
45 /// a phase entry for trace summary
46 class PhaseEntry {
47   private:
48     int nEPs;
49     int *count;
50     double *times;
51     double *maxtimes;
52   public:
53     PhaseEntry();
54     ~PhaseEntry() { delete [] count; delete [] times; delete [] maxtimes; }
55     /// one entry is called for 'time' seconds.
56     void setEp(int epidx, double time) {
57         if (epidx>=nEPs) CmiAbort("Too many entry functions!\n");
58         count[epidx]++;
59         times[epidx] += time;
60         if (maxtimes[epidx] < time) maxtimes[epidx] = time;
61     }
62     /**
63         write two lines for each phase:
64         1. number of calls for each entry;
65         2. time in us spent for each entry.
66     */
67     void write(FILE *fp, int seq) {
68         int i;
69         fprintf(fp, "[%d] ", seq);
70         int _numEntries=_entryTable.size();
71         for (i=0; i<_numEntries; i++) 
72             fprintf(fp, "%d ", count[i]);
73         fprintf(fp, "\n");
74
75         fprintf(fp, "[%d] ", seq);
76         for (i=0; i<_numEntries; i++) 
77             fprintf(fp, "%ld ", (long)(times[i]*1.0e6) );
78         fprintf(fp, "\n");
79
80         fprintf(fp, "[%d] ", seq);
81         for (i=0; i<_numEntries; i++) 
82             fprintf(fp, "%ld ", (long)(maxtimes[i]*1.0e6) );
83         fprintf(fp, "\n");
84     }
85 };
86
87 /// table of PhaseEntry
88 class PhaseTable {
89   private:
90     PhaseEntry **phases;
91     int numPhase;         /**< phase table size */
92     int cur_phase;        /**< current phase */
93     int phaseCalled;      /**< total number of phases */
94   public:
95     PhaseTable(int n): numPhase(n) {
96         phases = new PhaseEntry*[n];
97         _MEMCHECK(phases);
98         for (int i=0; i<n; i++) phases[i] = NULL;
99         cur_phase = -1;
100         phaseCalled = 0;
101     }
102     ~PhaseTable() {
103         for (int i=0; i<numPhase; i++) delete phases[i];
104         delete [] phases;
105     }
106     inline int numPhasesCalled() { return phaseCalled; };
107     /**
108       start a phase. If new, create a new PhaseEntry
109     */
110     void startPhase(int p) { 
111         if (p<0 && p>=numPhase) CmiAbort("Invalid Phase number. \n");
112         cur_phase = p; 
113         if (phases[cur_phase] == NULL) {
114             phases[cur_phase] = new PhaseEntry;
115             _MEMCHECK(phases[cur_phase]);
116             phaseCalled ++;
117         }
118     }
119     void setEp(int epidx, double time) {
120         if (cur_phase == -1) return;
121         if (phases[cur_phase] == NULL) CmiAbort("No current phase!\n");
122         phases[cur_phase]->setEp(epidx, time);
123     }
124     void write(FILE *fp) {
125         for (int i=0; i<numPhase; i++ )
126             if (phases[i]) { 
127                 phases[i]->write(fp, i);
128             }
129     }
130 };
131
132 double epThreshold;
133 double epInterval;
134
135 /// info for each entry
136 class SumEntryInfo {
137 public:
138   double epTime;
139   double epMaxTime;
140   int epCount;
141   enum {HIST_SIZE = 10};
142   int hist[HIST_SIZE];
143 public:
144   SumEntryInfo(): epTime(0.), epMaxTime(0.), epCount(0) {}
145   void clear() {
146     epTime = epMaxTime = 0.;
147     epCount = 0;
148     for (int i=0; i<HIST_SIZE; i++) hist[i]=0;
149   }
150   void setTime(double t) {
151     epTime += t;
152     epCount ++;
153     if (epMaxTime < t) epMaxTime = t;
154     for (int i=HIST_SIZE-1; i>=0; i--) {
155       if (t>epThreshold+i*epInterval) {
156         hist[i]++; break;
157       }
158     }
159   }
160 };
161
162 /// summary log pool
163 class SumLogPool {
164   private:
165     UInt poolSize;
166     UInt numBins;
167     BinEntry *pool;     /**< bins */
168     FILE *fp, *stsfp, *sdfp ;
169     char *pgm;
170
171     SumEntryInfo  *epInfo;
172     UInt epInfoSize;
173
174     /// a mark entry for trace summary
175     typedef struct {
176       double time;
177     } MarkEntry;
178     CkVec<MarkEntry *> events[MAX_MARKS];
179     int markcount;
180
181     /// for phases
182     PhaseTable phaseTab;
183
184     /// for Summary-Detail
185     double *cpuTime;    //[MAX_INTERVALS * MAX_ENTRIES];
186     int *numExecutions; //[MAX_INTERVALS * MAX_ENTRIES];
187
188   public:
189     SumLogPool(char *pgm);
190     ~SumLogPool();
191     double *getCpuTime() {return cpuTime;}
192     void initMem();
193     void write(void) ;
194     void writeSts(void);
195     void add(double time, double idleTime, int pe);
196     void setEp(int epidx, double time);
197     void clearEps() {
198       for(int i=0; i < epInfoSize; i++) {
199         epInfo[i].clear();
200       }
201     }
202     void shrink(void);
203     void shrink(double max);
204     void addEventType(int eventType, double time);
205     void startPhase(int phase) { phaseTab.startPhase(phase); }
206     BinEntry *bins() { return pool; }
207     UInt getNumEntries() { return numBins; }
208     UInt getEpInfoSize() {return epInfoSize;} 
209     UInt getPoolSize() {return poolSize;}
210     // accessors to normal summary data
211     inline double getTime(unsigned int interval) {
212       return pool[interval].time();
213     }
214
215
216     inline double getCPUtime(unsigned int interval, unsigned int ep){
217       if(cpuTime != NULL)
218         return cpuTime[interval*epInfoSize+ep]; 
219       else 
220         return 0.0;
221     }
222     
223     inline void setCPUtime(unsigned int interval, unsigned int ep, double val){
224         cpuTime[interval*epInfoSize+ep] = val; }
225     inline double addToCPUtime(unsigned int interval, unsigned int ep, double val){
226         cpuTime[interval*epInfoSize+ep] += val;
227         return cpuTime[interval*epInfoSize+ep]; }
228     inline int getNumExecutions(unsigned int interval, unsigned int ep){
229         return numExecutions[interval*epInfoSize+ep]; }
230     inline void setNumExecutions(unsigned int interval, unsigned int ep, unsigned int val){
231         numExecutions[interval*epInfoSize+ep] = val; }
232     inline int incNumExecutions(unsigned int interval, unsigned int ep){
233         ++numExecutions[interval*epInfoSize+ep];
234         return numExecutions[interval*epInfoSize+ep]; }
235     inline int getUtilization(int interval, int ep);
236
237
238     void updateSummaryDetail(int epIdx, double startTime, double endTime);
239
240
241 };
242
243 /// class for recording trace summary events 
244 /**
245   TraceSummary calculate CPU utilizations in bins, and will record
246   number of calls and total wall time for each entry. 
247 */
248 class TraceSummary : public Trace {
249     SumLogPool*  _logPool;
250     int execEvent;
251     int execEp;
252     int execPe;
253
254     /* per-log metadata maintained to derive cross-event information */
255     double binStart; /* time of last filled bin? */
256     double start, packstart, unpackstart, idleStart;
257     double binTime, binIdle;
258     int msgNum; /* used to handle multiple endComputation calls?? */
259     int inIdle;
260     int inExec;
261     int depth;
262   public:
263     TraceSummary(char **argv);
264     void creation(envelope *e, int epIdx, int num=1) {}
265
266     void beginExecute(envelope *e);
267     void beginExecute(char *msg);
268     void beginExecute(CmiObjId  *tid);
269     void beginExecute(int event,int msgType,int ep,int srcPe, int mlen=0, CmiObjId *idx=NULL);
270     void endExecute(void);
271     void endExecute(char *msg);
272     void beginIdle(double currT);
273     void endIdle(double currT);
274     void traceBegin(void);
275     void traceEnd(void);
276     void beginPack(void);
277     void endPack(void);
278     void beginUnpack(void);
279     void endUnpack(void);
280     void beginComputation(void);
281     void endComputation(void);
282
283     void traceClearEps();
284     void traceWriteSts();
285     void traceClose();
286
287     /**
288        for trace summary event mark
289     */
290     void addEventType(int eventType);
291     /** 
292        for starting a new phase
293     */
294     void startPhase(int phase);
295
296     /**
297        query utilities
298     */
299     SumLogPool *pool() { return _logPool; }
300
301     /**
302      *  Supporting methods for CCS queries
303      */
304     void traceEnableCCS();
305     void fillData(double *buffer, double reqStartTime, 
306                   double reqBinSize, int reqNumBins);
307 };
308
309 #endif
310
311 /*@}*/