Revert "Drop requirement for user code to call CBase_foo::pup(p)"
[charm.git] / tests / charm++ / commtest / comlib / bench.C
1
2 /***********************
3         This benchmark tests all to all personalized communication
4    in Charm++ using the communication library.
5
6          To Run
7              bench <message_size> <array_elements>
8
9          Defaults
10            message size = 128b
11            array elements = CkNumPes
12
13          Performance tips
14             - Use a maxiter of 1000
15             - Use +LBOff to remove loadbalancing overheads
16
17 Sameer Kumar 10/28/04      
18 ***********************/
19
20 #include <stdio.h>
21 #include <string.h>
22
23 #include <sys/time.h>
24 #include <sys/resource.h>
25 #include <unistd.h>
26
27 #include "charm++.h"
28 #include "ComlibManager.h"
29 #include "EachToManyMulticastStrategy.h"
30 #include "StreamingStrategy.h"
31 #include "DummyStrategy.h"
32 #include "bench.decl.h"
33
34 #define USELIB  1           // Use comlib or default charm++
35 #define MAXITER 10          // Number of iterations to run For
36                             // benchmark runs this should be atleast a
37                             // 1000
38
39 #define NUMPASS 1           // Number of all-to-all phases with the
40                             // same message size. After NUMPASS phases
41                             // the message size will be
42                             // increased. Useful while using the
43                             // learning framework.
44
45 /*readonly*/ CkChareID mid;
46 /*readonly*/ CProxy_Bench arr;
47 /*readonly*/ int nElements;
48
49 //Old way of creating messages in Charm++
50 class BenchMessage : public CMessage_BenchMessage {
51 public:
52     char *data;
53
54     static void *alloc(int mnum, size_t size, int *sizes, int priobits){
55         int total_size = size + CK_ALIGN(sizeof(char) * sizes[0], 8);
56         BenchMessage *dmsg = (BenchMessage *)CkAllocMsg(mnum, total_size, 
57                                                         priobits);
58         dmsg->data = (char *)dmsg + sizeof(BenchMessage);
59         return (void *)dmsg;    
60     }
61     
62     static void *pack(BenchMessage *msg){
63         return (void *)msg;
64     }
65     
66     static BenchMessage *unpack(void *buf){
67         BenchMessage *bmsg = (BenchMessage *)buf;
68         bmsg->data = (char *)bmsg + sizeof(BenchMessage);
69         return bmsg;
70     }
71 };
72
73 /*mainchare*/
74 class Main : public CBase_Main
75 {
76     int pass, superpass;
77     double curTime;
78     int mcount;
79     int size;
80
81 public:
82     Main(CkArgMsg* m)
83     {
84         int stratID = 0;
85         //Process command-line arguments
86         pass = 0;
87         superpass = 0;
88         nElements = CkNumPes();
89
90         mcount = 0;
91
92         size = 128;
93         if(m->argc > 1 ) size = atoi(m->argv[1]);
94         if(m->argc > 2 ) 
95             nElements = atoi(m->argv[2]);
96         delete m;
97         
98         //Start the computation
99         CkPrintf("Running Bench on %d processors for %d elements with %d byte messages\n", CkNumPes(), nElements, size);
100         
101         mid = thishandle;        
102         //ComlibInstanceHandle tmpInstance = CkGetComlibInstance();
103         ComlibInstanceHandle cinst = CkGetComlibInstance();
104         
105         arr = CProxy_Bench::ckNew();
106         
107         int count = 0;
108         CkArrayIndex *elem_array = new CkArrayIndex[nElements];
109         for(count = 0; count < nElements; count ++) {
110             elem_array[count] = CkArrayIndex1D(count);
111         }
112
113         //Create strategy
114         EachToManyMulticastStrategy *strat = new 
115             EachToManyMulticastStrategy(USE_MESH, arr.ckGetArrayID(), 
116                                         arr.ckGetArrayID(), 
117                                         nElements, elem_array, 
118                                         nElements, elem_array);
119         
120 //        strat->enableLearning();
121         cinst.setStrategy(strat);                
122
123         for(count =0; count < nElements; count++)
124           arr[count].insert(cinst);
125
126         arr.doneInserting();
127
128         curTime = CkWallTimer();
129
130         //for(count = 0; count < nElements; count++)            
131         //  arr[count].start(size);
132
133         arr.start(size);
134     };
135     
136     void send(void) {
137         
138       mcount ++;
139       
140       if (mcount == nElements){
141         
142         pass ++;
143         mcount = 0;
144         
145         CkPrintf("%d %5.4lf\n", size, (CmiWallTimer() - curTime)*1000/
146                  MAXITER);
147         curTime = CkWallTimer();
148         
149         if(pass == NUMPASS)
150           done();
151         else {
152             //for(int count = 0; count < nElements; count++)            
153             //  arr[count].start(size);
154             arr.start(size);
155         }
156       }
157     }
158     
159     void done()
160     {   
161       superpass ++;
162       mcount = 0;
163       pass = 0;
164       
165       if(superpass == 10)
166           CkExit();
167       else {
168           if(superpass < 20)
169               size += 50;
170           else if(superpass < 30)
171               size += 100;
172           else if(superpass < 40)
173               size += 200;
174           else if(superpass < 50)
175               size += 500;
176           
177           //for(int count = 0; count < nElements; count++)            
178           //  arr[count].start(size);
179           arr.start(size);
180       }
181     }
182 };
183
184 /******** The all to all benchmar array *************/
185 /*array [1D]*/
186 class Bench : public CBase_Bench
187 {
188     int pass;
189     int mcount;
190     int ite;
191     int msize;
192     double startTime;
193     ComlibInstanceHandle myInst;
194     CProxy_Bench arrd;      
195
196 public:
197   
198     Bench(ComlibInstanceHandle cinst)
199     {   
200         pass = 0;
201         mcount = 0;
202         ite = 0;
203         msize = 0;
204
205         myInst = cinst;
206
207         myInst.setSourcePe();
208
209         usesAtSync = CmiTrue;
210         setMigratable(true);
211
212         arrd = arr;
213         ComlibDelegateProxy(&arrd);
214     }
215     
216     Bench(CkMigrateMessage *m) {
217         //CkPrintf("Migrated to %d\n", CkMyPe());
218         //myInst = cinst;
219     }
220     
221     //Send all to all messages
222     //proxy arr is the charm++ proxy
223     //proxy arrd is the comlib delegated proxy
224     void sendMessage()
225     {
226 #ifdef USELIB
227         myInst.beginIteration();
228 #endif        
229         for(int count = 0; count < nElements; count ++){
230             
231             ComlibPrintf("[%d] Sending Message from %d to %d\n", CkMyPe(), thisIndex, count);
232
233 #ifdef USELIB
234             arrd[count].receiveMessage(new (&msize, 0) BenchMessage); 
235 #else
236             arr[count].receiveMessage(new (&msize, 0) BenchMessage);
237 #endif
238         }
239
240 #ifdef USELIB
241         myInst.endIteration();
242 #endif        
243     }
244
245     //receive the all to all messages Once I have everyones message I
246     //initiate the next iteration, or call loadbalancing.
247     void receiveMessage(BenchMessage *bmsg){
248         
249         delete bmsg;
250         mcount ++;
251         
252         ComlibPrintf("In Receive Message %d %d %d\n", thisIndex, CkMyPe(), 
253                      pass);
254
255         if(mcount == nElements){
256             mcount = 0;            
257             pass ++;            
258             CProxy_Main mainProxy(mid);
259
260             //If I have finished all iterations for this message size,
261             //Go back to main and start with a larger message size.
262             if(pass == MAXITER){
263                 pass = 0;                
264                 mainProxy.send();
265             }
266             else
267                 sendMessage();
268         }
269     }
270     
271     void start(int messagesize){
272         msize = messagesize;
273
274         //Initiate loadbalance at the phases 1 and NUMPASS/2
275         //So if NUMPASS = 1, loadbalancing will not be called 
276         if(ite % NUMPASS == NUMPASS/2 || ite % NUMPASS == 1) {
277             //Call atsync in the middle and in the end
278             ComlibPrintf("[%d] Calling Atsync\n", CkMyPe());
279             AtSync();
280         }
281         else
282             sendMessage();
283         
284         //CkPrintf("In Start\n");
285         ite ++;
286     }
287
288     //Finished loadbalancing
289     void ResumeFromSync() {
290         //        CkPrintf("%d: resuming\n", CkMyPe());
291         myInst.setSourcePe();
292         sendMessage();
293     }
294
295     //Pack the data for migration
296     void pup(PUP::er &p) {
297         //if(p.isPacking())
298         //  CkPrintf("Migrating from %d\n", CkMyPe());
299
300         CBase_Bench::pup(p);
301         p | pass ;
302         p | mcount ;
303         p | ite ;
304         p | startTime;
305         p | arrd;
306         p | myInst;
307         p | msize;
308     }
309 };
310
311
312 #include "bench.def.h"
313