13c26f6c1b3266822d5161ecbb2983e7d873b253
[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         CBase_Bench::pup(p);
186         p | pass ;
187         p | mcount ;
188         p | time;
189         p | startTime;
190         p | firstEntryFlag ;
191         p | sendFinishedFlag ;
192         p | sproxy ;
193         p | myinst;
194     }
195   
196     Bench(ComlibInstanceHandle cinst)
197     {   
198         pass = 0;
199         mcount = 0;
200         time = 0.0;
201         
202         firstEntryFlag = 0;
203         sendFinishedFlag = 0;
204
205         CkArrayIndex *elem_array = new CkArrayIndex[nElements];
206         for(int count = 0; count < nElements; count ++) 
207             elem_array[count] = CkArrayIndex1D(count);
208         
209         //Create the section proxy on all array elements
210         //Later subset test should be added to this benchmark 
211         sproxy = CProxySection_Bench::ckNew
212             (thisProxy.ckGetArrayID(), elem_array, nElements); 
213         ComlibResetSectionProxy(&sproxy);
214         ComlibDelegateProxy(&sproxy);
215
216         usesAtSync = CmiTrue;
217         setMigratable(true);
218         myinst = cinst;
219     }
220     
221     Bench(CkMigrateMessage *m) {
222         //CkPrintf(" Migrated to %d\n", CkMyPe());
223     }
224
225     //Send messages through the section proxy
226     void sendMessage()
227     {
228         if(thisIndex >= nElements) {
229             finishPass();
230             return;
231         }
232         
233         int count = 0;
234         int size = MESSAGESIZE;
235         
236 #ifdef USELIB
237         BenchMessage *bmsg = new(&size, 0) BenchMessage;
238         bmsg->src = thisIndex;
239         sproxy.receiveMessage(bmsg);
240 #else
241         arr[count].receiveMessage(new (&size, 0) BenchMessage);
242 #endif
243         sendFinishedFlag = 1;   
244     }
245     
246     void receiveMessage(BenchMessage *bmsg){
247         
248         //CkPrintf("[%d][%d] In Receive Message \n", CkMyPe(), thisIndex);
249         
250         CkAssert (bmsg->src >= 0 && bmsg->src < nElements);
251
252         if(!firstEntryFlag) {
253             startTime = CkWallTimer();
254             firstEntryFlag = 1;
255         }
256         
257         delete bmsg;
258         
259         mcount ++;
260
261         if(mcount == nElements){
262             finishPass();
263         }
264     }
265
266     //All messages received, loadbalance or start next phase
267     void start(int messagesize){
268         //CkPrintf("In Start\n");
269         MESSAGESIZE = messagesize;
270         
271         if(firstEntryFlag) {
272             //            CkPrintf("Calling AtSync\n");
273             AtSync();
274         }
275         else
276             sendMessage();
277     }
278
279     void ResumeFromSync() {
280         ComlibResetSectionProxy(&sproxy);
281         //myinst.setSourcePe();
282         sendMessage();
283     }
284
285     void finishPass(){
286         mcount = 0;            
287         pass ++;        
288         time += CkWallTimer() - startTime;
289
290         CProxy_Main mainProxy(mid);
291         if(pass == MAXPASS){
292             pass = 0;
293             mainProxy.done();
294         }
295         else {
296             sendMessage();
297             int x = 0;
298         }
299         
300         sendFinishedFlag = 0;
301     }
302 };
303
304 #include "bench.def.h"