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