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