Merge branch 'charm' of charmgit:charm into xiang/optChkp
[charm.git] / src / ck-perf / trace-counter.h
1 /**
2  * \addtogroup CkPerf
3 */
4 /*@{*/
5
6 #ifndef __trace_counter_h__
7 #define __trace_counter_h__
8
9 #include <stdio.h>
10 #include <errno.h>
11 #include "trace.h"
12 #include "trace-common.h"
13 #include "conv-config.h"
14
15 #define MAX_ENTRIES 500
16
17 //*******************************************************
18 //* TIME IS ALWAYS IN SECONDS UNTIL IT IS PRINTED OUT,  *
19 //* IN WHICH CASE IT IS CONVERTED TO (us)               *
20 //*******************************************************
21
22 //! track statistics for all entry points
23 class StatTable {
24   public:
25     StatTable();
26     ~StatTable();
27     void init(int argc);
28     //! one entry is called for 'time' seconds, value is counter reading 
29     void setEp(int epidx, int stat, long long value, double time);
30     //! write three lines for each stat:
31     //!   1. number of calls for each entry
32     //!   2. average count for each entry
33     //!   3. total time in us spent for each entry
34     void write(FILE* fp);
35     void clear();
36     int numStats() { return numStats_; }
37     //! do a reduction across processors to calculate the total count for
38     //! each count, and if the count has flops, etc, then calc the 
39     //! the flops/s, etc...
40     void doReduction(int phase, double idleTime);
41
42   private:
43     //! struct to maintain statistics
44     struct Statistics {
45       char*  name;                    // name of stat being tracked
46       char*  desc;                    // description of stat being tracked
47       unsigned int numCalled  [MAX_ENTRIES];  // total number times called
48       double       avgCount   [MAX_ENTRIES];  // track average of value
49       double       stdDevCount[MAX_ENTRIES];  // track stddev of value
50       double       totTime    [MAX_ENTRIES];  // total time assoc with counter
51       long long    maxCount   [MAX_ENTRIES];  // maximum count among all times
52       long long    minCount   [MAX_ENTRIES];  // minimum count among all times
53
54       Statistics(): name(NULL) { }
55     };
56
57     Statistics* stats_;             // track stats for each entry point
58     int         numStats_;          // size of statistics being tracked
59 };
60
61 //! counter log pool this implements functions for TraceCounter but
62 //! that needed to be performed on a node-level
63 class CountLogPool {
64   public:
65     CountLogPool();
66     ~CountLogPool() { }
67     // if phase is -1 and always has been, write normal filename
68     // if phase not -1, but has been higher before, write filename + "phaseX"
69     void write(int phase=-1) ;
70     // if phase is -1 and always has been, write normal filename
71     // if phase not -1, but has been higher before, write filename + "phaseX"
72     void writeSts(int phase=-1);
73     FILE* openFile(int phase=-1);
74     void setEp(int epidx, 
75                int index1, long long count1, 
76                int index2, long long count2, 
77                double time);
78     void clearEps() { stats_.clear(); }
79     void init(int argc) { stats_.init(argc); }
80     void doReduction(int phase, double idleTime) { 
81       stats_.doReduction(phase, idleTime); 
82     }
83
84   private:
85     StatTable stats_;       // store stats per counter
86     int       lastPhase_;   // keep track of last phase for closing behavior
87 };
88
89 //! For each processor, TraceCounter calculates mean, stdev, etc of 
90 //! CPU performance counters for each entry point.
91 class TraceCounter : public Trace {
92   public:
93     TraceCounter();
94     ~TraceCounter();
95     //! process command line arguments!
96     void traceInit(char **argv);
97     //! turn trace on/off, note that charm will automatically call traceBegin()
98     //! at the beginning of every run unless the command line option "+traceoff"
99     //! is specified
100     void traceBegin();
101     void traceEnd();
102     //! registers user event trace module returns int identifier 
103     int traceRegisterUserEvent(const char* userEvent) { 
104       // CmiPrintf("%d/%d traceRegisterUserEvent(%s)\n", 
105       // CkMyPe(), CkNumPes(), userEvent);
106       return 0;
107     }
108     //! a user event has just occured
109     void userEvent(int e) { 
110       // CmiPrintf("%d/%d userEvent %d\n", CkMyPe(), CkNumPes(), e); 
111     }
112     //! creation of message(s)
113     void creation(envelope *e, int epIdx, int num=1) { }
114     //! ???
115     void messageRecv(char *env, int pe) { }
116     //! begin/end execution of a Charm++ entry point
117     //! NOTE: begin/endPack and begin/endUnpack can be called in between
118     //!       a beginExecute and its corresponding endExecute.
119     void beginExecute(envelope *e);
120     void beginExecute(
121       int event,   //! event type defined in trace-common.h
122       int msgType, //! message type
123       int ep,      //! Charm++ entry point (will correspond to sts file) 
124       int srcPe,   //! Which PE originated the call
125       int ml=0,   //! message size
126       CmiObjId *idx=0);   //! array idx
127     void endExecute();
128     //! begin/end idle time for this pe
129     void beginIdle(double curWallTime);
130     void endIdle(double curWallTime);
131     //! begin/end the process of packing a message (to send)
132     void beginPack();
133     void endPack();
134     //! begin/end the process of unpacking a message (can occur before calling
135     //! a entry point or during an entry point when 
136     void beginUnpack();
137     void endUnpack();
138     //! ???
139     void enqueue(envelope *e) { }
140     void dequeue(envelope *e) { }
141     //! begin/end of execution
142     void beginComputation();
143     void endComputation();
144     //! clear all data collected for entry points
145     void traceClearEps();
146     //! write the summary sts file for this trace
147     void traceWriteSts();
148     //! do any clean-up necessary for tracing
149     void traceClose();
150
151     //! CounterArg is a linked list of strings that allows
152     //! processing of command line args
153     struct CounterArg {
154       int         code;
155       char*       arg;
156       char*       desc;
157       CounterArg* next;
158       int         index;  // index into statTable
159
160       CounterArg(): code(-1), arg(NULL), desc(NULL), next(NULL), index(-1) { }
161       CounterArg(int c, char* a, char* d):
162         code(c), arg(a), desc(d), next(NULL), index(-1) { }
163       void setValues(int _code, char* _arg, char* _desc) {
164         code = _code;  arg = _arg;  desc = _desc;
165       }
166     };
167
168   private:
169     enum TC_Status { IDLE, WORKING };
170     int cancel_beginIdle, cancel_endIdle;
171     
172     // command line processing
173     CounterArg* firstArg_;      // pointer to start of linked list of args
174     CounterArg* lastArg_;       // pointer to end of linked list of args
175     int         argStrSize_;    // size of max arg string (formatted output)
176     CounterArg* commandLine_;   // list of command line args
177     int         commandLineSz_; // size of commande line args array
178     CounterArg* counter1_;      // point to current counter, circle linked list
179     CounterArg* counter2_;      // point to current counter, circle linked list
180     int         counter1Sz_;    // size of cycle
181     int         counter2Sz_;    // size of cycle
182     
183     // result of different command line opts
184     bool        overview_;      // if true, just measure between phases
185     bool        switchRandom_;  // if true, switch counters randomly
186     bool        switchByPhase_; // if true, switch counters only at phases
187     bool        noLog_;         // if true, don't write a log file
188     bool        writeByPhase_;  // if true, write out a log file every phase
189
190     // store between start/stop of counter read
191     int         execEP_;        // id currently executing entry point
192     double      startEP_;       // start time of currently executing ep
193     double      startIdle_;     // start time of currently executing idle
194     int         genStart_;      // track value of start_counters
195
196     // store state
197     double      idleTime_;        // total idle time
198     int         phase_;           // current phase
199     int         reductionPhase_;  // for reduction output
200     bool        traceOn_;         // true if trace is turned on
201     TC_Status   status_;          // to prevent errors
202     bool        dirty_;           // true if endExecute called 
203
204     //! start/stop the overall counting ov eps (don't write to logCount, 
205     //! just print to screen
206     void beginOverview();
207     void endOverview();
208     //! switch counters by whatever switching strategy 
209     void switchCounters();
210     //! add the argument parameters to the linked list of args choices
211     void registerArg(CounterArg* arg);
212     //! see if the arg (str or code) matches any in the linked list of choices
213     //! and sets arg->code to the SGI code
214     //! return true if arg matches, false otherwise
215     bool matchArg(CounterArg* arg);
216     //! print out usage argument
217     void usage();
218     //! print out all arguments in the linked-list of choices
219     void printHelp();
220 };
221
222 #endif  // __trace_counter_h__
223
224 /*@}*/
225
226