0454a303c8297927692be8dae474877829fe6349
[charm.git] / tests / charm++ / commtest / comlib / benchsectionmulti.C
1
2 /*******************************************
3         This benchmark tests section multicast feature of the
4         Communication library with a many to many multicast benchmark.
5         Section multicasts are traditionally used for one-to-many
6         multicast operations, but this benchmark tests them in an
7         many-to-many fashion.
8
9          To Run
10              benchsectionmulti <message_size> <array_elements>
11
12          Defaults
13            message size = 128b
14            array elements = CkNumPes
15
16          Performance tips
17             - Use a maxpass of 1000
18             - Use +LBOff to remove loadbalancing statistics 
19               collection overheads
20
21 Sameer Kumar 03/17/05      
22 **************************************************/
23
24 #include <stdio.h>
25 #include <string.h>
26
27 #include <sys/time.h>
28 #include <sys/resource.h>
29 #include <unistd.h>
30
31 #include "ComlibManager.h"
32 #include "RingMulticastStrategy.h"
33 #include "DirectMulticastStrategy.h"
34 #include "bench.decl.h"
35
36 #define USELIB
37 #define MAXPASS 10
38
39 int MESSAGESIZE=128;
40 /*readonly*/ CkChareID mid;
41 /*readonly*/ CProxy_Bench arr;
42 /*readonly*/ int nElements;
43
44 class BenchMessage : public CkMcastBaseMsg, public CMessage_BenchMessage {
45 public:
46     int size;
47     char *data;
48     int src;
49     
50     static void *alloc(int mnum, size_t size, int *sizes, int priobits){
51         int total_size = size + sizeof(char) * sizes[0];
52         BenchMessage *dmsg = (BenchMessage *)CkAllocMsg(mnum, total_size, 
53                                                         priobits);
54         dmsg->size = sizes[0];        
55         return (void *)dmsg;
56     }
57     
58     static void *pack(BenchMessage *msg){
59         return (void *)msg;
60     }
61     
62     static BenchMessage *unpack(void *buf){
63         BenchMessage *bmsg = (BenchMessage *)buf;
64         return bmsg;
65     }
66 };
67
68 /*mainchare*/
69 class Main : public CBase_Main
70 {
71     int pass, superpass;
72     double curTime;
73 public:
74     Main(CkArgMsg* m)
75     {
76         //Process command-line arguments
77         pass = 0;
78         superpass = 0;
79         nElements= CkNumPes();
80
81         if(m->argc > 1 ) MESSAGESIZE=atoi(m->argv[1]);
82
83         if(m->argc > 2 ) nElements=atoi(m->argv[2]);
84
85         delete m;
86         
87         CkPrintf("Running Bench on %d processors for %d elements with %d byte messages\n", CkNumPes(), nElements, MESSAGESIZE);
88         
89         mid = thishandle;        
90
91         arr = CProxy_Bench::ckNew();
92                 
93         int count = 0;
94         CkArrayIndex *elem_array = new CkArrayIndex[nElements];
95         for(count = 0; count < nElements; count ++) {
96             elem_array[count] = CkArrayIndex1D(count);
97         }
98
99         //Different section multicast strategies
100         DirectMulticastStrategy *dstrat = new DirectMulticastStrategy
101             (arr.ckGetArrayID());
102
103         RingMulticastStrategy *rstrat = new RingMulticastStrategy(arr.ckGetArrayID());
104
105         //        CkPrintf("After creating array\n");
106         CkArrayID aid = arr.ckGetArrayID();
107
108         ComlibInstanceHandle cinst = CkGetComlibInstance();        
109         cinst.setStrategy(dstrat);
110         ComlibPrintf("After register strategy\n");
111
112         for(count = 0; count < nElements; count++)
113             arr[count].insert(cinst);
114         arr.doneInserting();
115         
116         curTime = CkWallTimer();
117         arr.sendMessage();
118         //        CkPrintf("After Main\n");
119     };
120     
121     void send(void) {
122         
123         static int count = 0;
124         count ++;
125
126         if (count == nElements){
127             pass ++;
128             count = 0;
129             arr.sendMessage();
130         }
131     }
132     
133     //Phase done, initiate next phase with larger message sizes
134     void done()
135     {
136         static int count = 0;
137         
138         count ++;
139         
140         if(count == nElements) {
141             CkPrintf("%d %5.4lf\n", MESSAGESIZE, (CmiWallTimer() - curTime)*1000/MAXPASS);
142
143             curTime = CkWallTimer();
144             superpass ++;
145             pass = 0;
146             count = 0;
147
148             if(superpass == 10)
149                 CkExit();
150             else {
151               if(superpass < 20)
152                   MESSAGESIZE += 50;
153               else if(superpass < 30)
154                   MESSAGESIZE += 100;
155               else if(superpass < 40)
156                   MESSAGESIZE += 200;
157               else if(superpass < 50)
158                   MESSAGESIZE += 500;
159               
160               arr.start(MESSAGESIZE);
161             }
162         }
163     }
164 };
165
166 /*array [1D]*/
167 class Bench : public CBase_Bench
168 {
169     int pass;
170     int mcount;
171     double time, startTime;
172     int firstEntryFlag, sendFinishedFlag;
173
174     CProxySection_Bench sproxy;  //Section proxy, which decides who
175                                  //all this array element is sending
176                                  //to
177     ComlibInstanceHandle myinst;
178
179 public:
180
181     void pup(PUP::er &p) {
182         //if(p.isPacking())
183         //            CkPrintf("Migrating from %d\n", CkMyPe());
184
185         p | pass ;
186         p | mcount ;
187         p | time;
188         p | startTime;
189         p | firstEntryFlag ;
190         p | sendFinishedFlag ;
191         p | sproxy ;
192         p | myinst;
193     }
194   
195     Bench(ComlibInstanceHandle cinst)
196     {   
197         pass = 0;
198         mcount = 0;
199         time = 0.0;
200         
201         firstEntryFlag = 0;
202         sendFinishedFlag = 0;
203
204         CkArrayIndex *elem_array = new CkArrayIndex[nElements];
205         for(int count = 0; count < nElements; count ++) 
206             elem_array[count] = CkArrayIndex1D(count);
207         
208         //Create the section proxy on all array elements
209         //Later subset test should be added to this benchmark 
210         sproxy = CProxySection_Bench::ckNew
211             (thisProxy.ckGetArrayID(), elem_array, nElements); 
212         ComlibResetSectionProxy(&sproxy);
213         ComlibDelegateProxy(&sproxy);
214
215         usesAtSync = CmiTrue;
216         setMigratable(true);
217         myinst = cinst;
218     }
219     
220     Bench(CkMigrateMessage *m) {
221         //CkPrintf(" Migrated to %d\n", CkMyPe());
222     }
223
224     //Send messages through the section proxy
225     void sendMessage()
226     {
227         if(thisIndex >= nElements) {
228             finishPass();
229             return;
230         }
231         
232         int count = 0;
233         int size = MESSAGESIZE;
234         
235 #ifdef USELIB
236         BenchMessage *bmsg = new(&size, 0) BenchMessage;
237         bmsg->src = thisIndex;
238         sproxy.receiveMessage(bmsg);
239 #else
240         arr[count].receiveMessage(new (&size, 0) BenchMessage);
241 #endif
242         sendFinishedFlag = 1;   
243     }
244     
245     void receiveMessage(BenchMessage *bmsg){
246         
247         //CkPrintf("[%d][%d] In Receive Message \n", CkMyPe(), thisIndex);
248         
249         CkAssert (bmsg->src >= 0 && bmsg->src < nElements);
250
251         if(!firstEntryFlag) {
252             startTime = CkWallTimer();
253             firstEntryFlag = 1;
254         }
255         
256         delete bmsg;
257         
258         mcount ++;
259
260         if(mcount == nElements){
261             finishPass();
262         }
263     }
264
265     //All messages received, loadbalance or start next phase
266     void start(int messagesize){
267         //CkPrintf("In Start\n");
268         MESSAGESIZE = messagesize;
269         
270         if(firstEntryFlag) {
271             //            CkPrintf("Calling AtSync\n");
272             AtSync();
273         }
274         else
275             sendMessage();
276     }
277
278     void ResumeFromSync() {
279         ComlibResetSectionProxy(&sproxy);
280         //myinst.setSourcePe();
281         sendMessage();
282     }
283
284     void finishPass(){
285         mcount = 0;            
286         pass ++;        
287         time += CkWallTimer() - startTime;
288
289         CProxy_Main mainProxy(mid);
290         if(pass == MAXPASS){
291             pass = 0;
292             mainProxy.done();
293         }
294         else {
295             sendMessage();
296             int x = 0;
297         }
298         
299         sendFinishedFlag = 0;
300     }
301 };
302
303 #include "bench.def.h"