Revert "Drop requirement for user code to call CBase_foo::pup(p)"
[charm.git] / tests / charm++ / commtest / eachtomany-test-2 / eachtomany.C
1 #include "eachtomany.decl.h"
2
3 #include <comlib.h>
4 #include <cassert>
5 #include <iostream>
6
7 /*
8  * Test of EachToMany Strategy 
9  */
10
11 CProxy_Main mainProxy;
12 CProxy_EachToManyArray eachToManyArrayProxy;
13
14 int nElements;
15
16 #define DEBUG 0
17 #define COMDEBUG 0 
18
19 ComlibInstanceHandle stratEachToManyArray;
20
21 class eachToManyMessage : public CMessage_eachToManyMessage{
22 public:
23   int length;
24   char* msg;
25 };
26
27 // mainchare
28
29 class Main : public CBase_Main
30 {
31 private:
32   int nDone;
33   int totalIterations;
34   int iter;
35   
36   /// The number of array elements that have reported their successful setup so far
37   int nArrElemSetup;
38   
39 public:
40
41   Main(CkArgMsg *m) {    
42     nDone = 0;
43     totalIterations = 50;
44     iter = 0;
45     nArrElemSetup = 0;
46     
47     com_debug = COMDEBUG; // also below
48      
49     nElements=CkNumPes()*2;
50     if(m->argc >1 ) nElements=atoi(m->argv[1]);
51     if(m->argc >2 ) totalIterations=atoi(m->argv[2]);
52     delete m;
53
54     mainProxy = thishandle;
55         
56     // Create the array
57     eachToManyArrayProxy = CProxy_EachToManyArray::ckNew(nElements);
58
59     // Create a strategy
60     CkArrayIndex *allElts = new CkArrayIndex[nElements];
61     for (int i = 0; i<nElements; i++) {
62         CkArrayIndex1D index = i;
63         allElts[i] = index;
64     }
65     Strategy *strategy2 = new EachToManyMulticastStrategy(USE_DIRECT, eachToManyArrayProxy, eachToManyArrayProxy, nElements,allElts,nElements,allElts);
66     stratEachToManyArray = ComlibRegister(strategy2);
67
68     eachToManyArrayProxy.setup();
69     
70     delete [] allElts;
71     
72   } 
73
74   void arraySetupDone(){
75            nArrElemSetup ++;
76            if(nArrElemSetup == nElements){
77 #if DEBUG
78                    CkPrintf("[MainChare] Array setup completed. Starting test.\n");
79 #endif
80                    eachToManyArrayProxy.TestEachToMany(iter);   
81            }
82   }
83   
84   void doNext(){
85           nDone++;
86           // Becase each array element sends a message to all array elements,
87           // there are a total of nElements^2 messages received
88           // We do one comlib all to all and two other non-delegated ones as well. 
89          
90 #if DEBUG
91           CkPrintf("[MainChare] doNext() nDone=%d\n",nDone);
92 #endif
93           
94           const int nTotal = nElements*nElements;
95           if (nDone == nTotal){
96                   int printIteration = 10;
97                   int maxprints = 5;
98                   while( (totalIterations / printIteration) > maxprints)
99                           printIteration *= 2;
100                   if(iter % printIteration == 0)
101                           CkPrintf("[MainChare] Completed iteration %d\n",iter);
102                   
103                   
104                   iter ++;
105                   nDone = 0;
106                   if(iter == totalIterations){
107                           CkPrintf("[MainChare] Successful Completion of %d iterations\n", iter);
108                           CkPrintf("Test Completed Successfully\n");
109                           CkExit();
110                   }
111           
112                   // Do another iteration
113                   int arrElt = 2;
114                   int numPes = CkNumPes();
115                   int destPe = iter%numPes;
116                     
117                   if( iter>4 && arrElt<nElements && destPe < CkNumPes() ){
118 #if DEBUG
119                           CkPrintf("[%d] Decided to migrate elt %d to %d iter=%d numpes=%d\n", CkMyPe(), arrElt, destPe, iter, numPes);
120 #endif
121                           eachToManyArrayProxy[arrElt].migrateMeTo(destPe);
122                   }
123                   
124                   eachToManyArrayProxy.TestEachToMany(iter); 
125           
126           }
127  
128             
129   }
130   
131 };
132
133 class EachToManyArray : public CBase_EachToManyArray {
134 private:
135   CProxy_EachToManyArray localProxy;
136   
137 public:
138
139   EachToManyArray() {
140           com_debug = COMDEBUG; // also above
141   }
142
143   
144   void setup(){
145           // We cannot put this in the constructor because the strategy may not yet have been created. Our references to it would therefore be invald.
146           localProxy = thisProxy;
147           ComlibAssociateProxy(stratEachToManyArray, localProxy); 
148           mainProxy.arraySetupDone();
149   }
150   
151   void pup(PUP::er &p){
152           
153           // Call PUP Routine for superclass
154           CBase_EachToManyArray::pup(p);
155           
156           if(p.isUnpacking()){
157                   localProxy = thisProxy;
158                   ComlibAssociateProxy(stratEachToManyArray, localProxy);
159 #if DEBUG
160                   CkPrintf("pup() associating proxy with comlib strategy instance\n");
161 #endif
162           }
163   }
164   
165   
166   EachToManyArray(CkMigrateMessage *m) {
167 #if DEBUG
168           CkPrintf("Object %d has migrated to %d\n", thisIndex, CkMyPe());
169 #endif
170           localProxy = thisProxy;
171           ComlibAssociateProxy(stratEachToManyArray, localProxy); 
172   }
173   
174   void migrateMeTo(int toPe){
175 #if DEBUG
176           CkPrintf("==========================================\n\n[%d] object is calling migrateMe(toPe=%d)\n", CkMyPe(),toPe);
177 #endif 
178           migrateMe (toPe);
179   }
180   
181     
182   void TestEachToMany(int iter) {
183
184           // Build a message
185           char *msg = (char*)malloc(256);
186           sprintf(msg, "%d", thisIndex);
187           eachToManyMessage* b = new(strlen(msg)+1,0) eachToManyMessage;
188           memcpy(b->msg, msg, strlen(msg)+1);
189           b->length = strlen(msg);
190
191           // Broadcast the message to the whole array
192 //        CkPrintf("[%d] Application: array elt=%d about to call ComlibBegin()\n", CkMyPe(), thisIndex);
193           ComlibBegin(localProxy, iter);
194 //        CkPrintf("[%d] Application: array elt=%d broadcasting msg=%s\n", CkMyPe(), thisIndex, msg);
195           localProxy.receive(b);
196           ComlibEnd(localProxy, iter);
197           
198           free(msg);
199   }
200
201   void receive(eachToManyMessage* m) {
202  
203 #if DEBUG
204   //    CkPrintf("[%d] Application: received message %s\n", CkMyPe(), m->msg);
205     int src;
206     sscanf(m->msg,"%d",&src);
207     CkPrintf("Application Received: %d to %d  [%d] \n", src, thisIndex, CkMyPe());
208 #endif           
209     delete m;
210     mainProxy.doNext();
211   }
212   
213 };
214
215 #include "eachtomany.def.h"