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