Fixing some bugs in the new node aware multicast strategy.
[charm.git] / src / ck-com / ComlibStats.h
1 #ifndef COMLIB_STATS_H
2 #define COMLIB_STATS_H
3
4 /**
5    @addtogroup CharmComlib
6    @{
7    @file
8    
9    @brief Classes for storing simple statistics about messages send and received.
10 */
11
12 #include "charm++.h"
13 #include "convcomlibmanager.h"
14
15 class ComlibLocalStats;
16 class ComlibComRec {
17     int nmessages_sent;
18     int totalbytes_sent;
19     int nmessages_received;
20     int totalbytes_received;
21     
22     unsigned char *procMap; // Map of which processors have communicated
23     int npes;               // Total number of processors participating 
24                             // in the communication operation
25     int degree;             // Number of processors messages are sent 
26                             // to or received from
27     CmiBool recorded;
28
29     friend class ComlibLocalStats;
30  public:
31     ComlibComRec() {
32         npes = CkNumPes();
33         procMap = 0;
34         totalbytes_sent = 0;
35         totalbytes_received = 0;
36         nmessages_sent = 0;
37         nmessages_received = 0;
38         degree = 0;
39         recorded = CmiFalse;
40     }
41
42     ComlibComRec(int _npes) {
43         npes = _npes;
44         procMap = 0;
45         totalbytes_sent = 0;
46         totalbytes_received = 0;
47         nmessages_sent = 0;
48         nmessages_received = 0;
49         degree = 0;
50         recorded = CmiFalse;
51     }
52
53     ~ComlibComRec() {
54         if(recorded && procMap)
55             CmiFree(procMap);
56
57         procMap = 0;
58     }
59
60     void setNpes(int _npes) {npes = _npes;}
61     CmiBool isRecorded() { return recorded;}
62
63     int getTotalBytes() { return  totalbytes_sent + totalbytes_received; }
64     int getTotalMessages() { return nmessages_sent + nmessages_received;}
65     int getDegree() { return degree;}
66
67     inline void recordSend(int size, int dest) {
68         if(!recorded) {
69             recorded = CmiTrue;
70             int mapsize = (npes / (sizeof(char)*8) + 1) * sizeof(char); 
71             procMap = (unsigned char*) CmiAlloc(mapsize);
72             memset(procMap, 0, mapsize);
73         }
74
75         nmessages_sent ++;
76         totalbytes_sent += size;
77         int pos = dest / (sizeof(char)*8);
78         int off = dest % (sizeof(char)*8);
79
80         if((procMap[pos] & (1 << off)) == 0) {
81             degree ++;
82             procMap[pos] |= 1 << off;    //mark a processor as being sent to
83         }
84     }
85
86     inline void recordSendM(int size, int *dest_m, int ndest) {
87         
88         if(!recorded) {
89             recorded = CmiTrue;
90             int mapsize = (npes / (sizeof(char)*8) + 1) * sizeof(char); 
91             procMap = (unsigned char*) CmiAlloc(mapsize);
92             memset(procMap, 0, mapsize);
93         }
94         
95         nmessages_sent += ndest;
96         totalbytes_sent += size * ndest;
97         
98         for(int count = 0; count < ndest; count ++) {
99             int pos = dest_m[count] / (sizeof(char)*8);
100             int off = dest_m[count] % (sizeof(char)*8);
101             
102             if((procMap[pos] & (1 << off)) == 0) {
103                 degree ++;
104                 //mark a processor as being sent to
105                 procMap[pos] |= 1 << off;    
106             }
107         }
108     }
109
110     inline void recordRecv(int size, int src) {
111         if(!recorded) {
112             recorded = CmiTrue;
113             int mapsize = (npes / (sizeof(char)*8) + 1) * sizeof(char); 
114             procMap = (unsigned char*) CmiAlloc(mapsize);
115             memset(procMap, 0, mapsize);
116         }
117
118         nmessages_received ++;
119         totalbytes_received += size;
120         int pos = src / (sizeof(char) * 8);
121         int off = src % (sizeof(char) * 8);
122
123         if((procMap[pos] & (1 << off)) == 0) {
124             degree ++;
125             procMap[pos] |= 1 << off;    //mark a processor as being sent to
126         }
127     }
128     
129     inline void recordRecvM(int size, int *src_m, int nsrc) {
130         if(!recorded) {
131             recorded = CmiTrue;
132             int mapsize = (npes / (sizeof(char)*8) + 1) * sizeof(char); 
133             procMap = (unsigned char*) CmiAlloc(mapsize);
134             memset(procMap, 0, mapsize);
135         }
136
137         nmessages_received += nsrc;
138         totalbytes_received += size * nsrc;
139
140         for(int count = 0; count < nsrc; count++) {
141             int pos = src_m[count] / (sizeof(char) * 8);
142             int off = src_m[count] % (sizeof(char) * 8);
143             
144             if((procMap[pos] & (1 << off)) == 0) {
145                 degree ++;
146                 //mark a processor as being sent to
147                 procMap[pos] |= 1 << off;    
148             }
149         }
150     }
151     
152     void reset () {
153         if(procMap)
154             CmiFree(procMap);
155         procMap = 0;
156         totalbytes_sent = 0;
157         totalbytes_received = 0;
158         nmessages_sent = 0;
159         nmessages_received = 0;
160         degree = 0;
161         recorded = CmiFalse;
162     }
163
164     void pup(PUP::er &p) {
165         p | nmessages_sent;
166         p | totalbytes_sent;
167         p | nmessages_received;
168         p | totalbytes_received;
169         p | npes;
170         p | degree;
171         p | recorded;
172
173
174         int mapsize = (npes / (sizeof(char)*8) + 1) * sizeof(char); 
175         if(p.isUnpacking()) {
176             if(recorded) 
177                 procMap = (unsigned char*) CmiAlloc(mapsize);
178         }
179         
180         if(recorded)
181             p(procMap, mapsize);
182     }
183 };
184
185 class ComlibLocalStats {
186  public:
187     CkVec<ComlibComRec> cdata;
188     int nstrats;
189
190     ComlibLocalStats(int _strats) : cdata(_strats) {
191       nstrats = _strats;
192     }
193     
194     ComlibLocalStats() : cdata(1) {
195       nstrats = 1;
196     }
197
198     void setNstrats(int nst) {
199         nstrats = nst;
200         cdata.resize(nstrats);
201     }
202
203     inline void recordSend(int sid, int size, int dest) {
204       if(sid >= nstrats) {
205         nstrats = sid + 1;
206         cdata.resize(nstrats);
207       }
208
209       cdata[sid].recordSend(size, dest);
210
211     }
212
213     inline void recordRecv(int sid, int size, int src) {
214       if(sid >= nstrats) {
215         nstrats = sid + 1;
216         cdata.resize(nstrats);
217       }
218
219       cdata[sid].recordRecv(size, src);
220     }
221
222     inline void recordSendM(int sid, int size, int *dest_m, int ndest) {
223       if(sid >= nstrats) {
224         nstrats = sid + 1;
225         cdata.resize(nstrats);
226       }
227
228       cdata[sid].recordSendM(size, dest_m, ndest);
229     }
230
231     inline void recordRecvM(int sid, int size, int *src_m, int nsrc) {
232       if(sid >= nstrats) {
233         nstrats = sid + 1;
234         cdata.resize(nstrats);
235       }
236
237       cdata[sid].recordRecvM(size, src_m, nsrc);
238     }
239     
240     inline void reset() {
241       for(int count = 0; count < nstrats; count++)
242         cdata[count].reset();
243     }
244
245     void pup(PUP::er &p) {
246       p | nstrats;
247       p | cdata;
248     }
249
250     ComlibLocalStats & operator=(ComlibLocalStats &in) {
251       nstrats = in.nstrats;
252
253       cdata.resize(in.cdata.size());
254       for(int count = 0; count < in.nstrats; count++) {
255         if(in.cdata[count].isRecorded()) {
256           memcpy(&cdata[count],&in.cdata[count], sizeof(ComlibComRec));
257           
258           int npes = in.cdata[count].npes;
259           int mapsize = (npes / (sizeof(char)*8) + 1) * sizeof(char); 
260           cdata[count].procMap = (unsigned char*) CmiAlloc(mapsize);
261           memcpy(cdata[count].procMap, in.cdata[count].procMap, mapsize);
262         }
263         else
264           cdata[count].reset();
265       }
266       
267       return *this;
268     }
269 };
270
271 class ComlibGlobalStats {
272  
273   ComlibLocalStats *statsArr;
274   
275  public:
276   
277   ComlibGlobalStats();
278   ~ComlibGlobalStats() {}
279   
280   void updateStats(ComlibLocalStats &stats, int pe); 
281   
282   //The average amount of data communicated
283   void getAverageStats(int sid, double &, double &, double &, double &);
284 };
285
286 /*@}*/
287 #endif