added +sumonly which will combine summary bin data from all pes to pe0 and write...
[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 // time in seconds
23 #define  BIN_SIZE       0.001
24
25 #define  MAX_ENTRIES      500
26
27 #define  MAX_MARKS       256
28
29 #define  MAX_PHASES       10
30
31 /// Bin entry record CPU time in an interval
32 class BinEntry {
33   public:
34     void *operator new(size_t s) {void*ret=malloc(s);_MEMCHECK(ret);return ret;}
35     void *operator new(size_t, void *ptr) { return ptr; }
36     void operator delete(void *ptr) { free(ptr); }
37 #ifdef WIN32
38     void operator delete(void *, void *) { }
39 #endif
40     BinEntry(): time(0.) {}
41     BinEntry(double t): time(t) {}
42     inline double getTime() { return time; }
43     void setTime(double t) { time = t; }
44     double &Time() { return time; }
45     void write(FILE *fp);
46     void writeU(FILE *fp, int u);
47     int  getU();
48   private:
49     double time;
50 };
51
52 /// a phase entry for trace summary
53 class PhaseEntry {
54   private:
55     int count[MAX_ENTRIES];
56     double times[MAX_ENTRIES];
57     double maxtimes[MAX_ENTRIES];
58   public:
59     PhaseEntry();
60     /// one entry is called for 'time' seconds.
61     void setEp(int epidx, double time) {
62         if (epidx>=MAX_ENTRIES) 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         for (i=0; i<_numEntries; i++) 
76             fprintf(fp, "%d ", count[i]);
77         fprintf(fp, "\n");
78
79         fprintf(fp, "[%d] ", seq);
80         for (i=0; i<_numEntries; i++) 
81             fprintf(fp, "%ld ", (long)(times[i]*1.0e6) );
82         fprintf(fp, "\n");
83
84         fprintf(fp, "[%d] ", seq);
85         for (i=0; i<_numEntries; i++) 
86             fprintf(fp, "%ld ", (long)(maxtimes[i]*1.0e6) );
87         fprintf(fp, "\n");
88     }
89 };
90
91 /// table of PhaseEntry
92 class PhaseTable {
93   private:
94     PhaseEntry **phases;
95     int numPhase;         /**< phase table size */
96     int cur_phase;        /**< current phase */
97     int phaseCalled;      /**< total number of phases */
98   public:
99     PhaseTable(int n): numPhase(n) {
100         phases = new PhaseEntry*[n];
101         _MEMCHECK(phases);
102         for (int i=0; i<n; i++) phases[i] = NULL;
103         cur_phase = -1;
104         phaseCalled = 0;
105     }
106     ~PhaseTable() {
107         for (int i=0; i<numPhase; i++) delete phases[i];
108         delete [] phases;
109     }
110     inline int numPhasesCalled() { return phaseCalled; };
111     /**
112       start a phase. If new, create a new PhaseEntry
113     */
114     void startPhase(int p) { 
115         if (p<0 && p>=numPhase) CmiAbort("Invalid Phase number. \n");
116         cur_phase = p; 
117         if (phases[cur_phase] == NULL) {
118             phases[cur_phase] = new PhaseEntry;
119             _MEMCHECK(phases[cur_phase]);
120             phaseCalled ++;
121         }
122     }
123     void setEp(int epidx, double time) {
124         if (cur_phase == -1) return;
125         if (phases[cur_phase] == NULL) CmiAbort("No current phase!\n");
126         phases[cur_phase]->setEp(epidx, time);
127     }
128     void write(FILE *fp) {
129         for (int i=0; i<numPhase; i++ )
130             if (phases[i]) { 
131                 phases[i]->write(fp, i);
132             }
133     }
134 };
135
136 double epThreshold;
137 double epInterval;
138
139 /// info for each entry
140 class SumEntryInfo {
141 public:
142   double epTime;
143   double epMaxTime;
144   int epCount;
145   enum {HIST_SIZE = 10};
146   int hist[HIST_SIZE];
147 public:
148   SumEntryInfo(): epTime(0.), epMaxTime(0.), epCount(0) {}
149   void clear() {
150     epTime = epMaxTime = 0.;
151     epCount = 0;
152     for (int i=0; i<HIST_SIZE; i++) hist[i]=0;
153   }
154   void setTime(double t) {
155     epTime += t;
156     epCount ++;
157     if (epMaxTime < t) epMaxTime = t;
158     for (int i=HIST_SIZE-1; i>=0; i--) {
159       if (t>epThreshold+i*epInterval) {
160         hist[i]++; break;
161       }
162     }
163   }
164 };
165
166 /// summary log pool
167 class SumLogPool {
168   private:
169     UInt poolSize;
170     UInt numEntries;
171     BinEntry *pool;     /**< bins */
172     FILE *fp, *stsfp ;
173
174     SumEntryInfo  *epInfo;
175     int epSize;
176
177     /// a mark entry for trace summary
178     typedef struct {
179       double time;
180     } MarkEntry;
181     CkVec<MarkEntry *> events[MAX_MARKS];
182     int markcount;
183
184     /// for phases
185     PhaseTable phaseTab;
186   public:
187     SumLogPool(char *pgm);
188     ~SumLogPool();
189     void write(void) ;
190     void writeSts(void);
191     void add(double time, int pe);
192     void setEp(int epidx, double time);
193     void clearEps() {
194       for(int i=0; i < epSize; i++) {
195         epInfo[i].clear();
196       }
197     }
198     void shrink(void) ;
199     void addEventType(int eventType, double time);
200     void startPhase(int phase) { phaseTab.startPhase(phase); }
201     BinEntry *bins() { return pool; }
202     int getNumEntries() { return numEntries; }
203 };
204
205 /// class for recording trace summary events 
206 /**
207   TraceSummary calculate CPU utilizations in bins, and will record
208   number of calls and total wall time for each entry. 
209 */
210 class TraceSummary : public Trace {
211     SumLogPool*  _logPool;
212     int curevent;
213     int execEvent;
214     int execEp;
215     int execPe;
216
217     double binStart;
218     double start, packstart, unpackstart;
219     double bin;
220     int msgNum;
221   public:
222     TraceSummary(char **argv);
223     void beginExecute(envelope *e);
224     void beginExecute(int event,int msgType,int ep,int srcPe, int mlen=0);
225     void endExecute(void);
226     void beginPack(void);
227     void endPack(void);
228     void beginUnpack(void);
229     void endUnpack(void);
230     void beginComputation(void);
231     void endComputation(void);
232
233     void traceClearEps();
234     void traceWriteSts();
235     void traceClose();
236
237     /**
238        for trace summary event mark
239     */
240     void addEventType(int eventType);
241     /** 
242        for starting a new phase
243     */
244     void startPhase(int phase);
245
246     /**
247        query utilities
248     */
249     SumLogPool *pool() { return _logPool; }
250 };
251
252 #endif
253
254 /*@}*/