remove unused variables and other cleanup to get a clean compilation.
[charm.git] / src / conv-com / gridrouter.C
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7
8 /**
9    @addtogroup ConvComlibRouter
10    @{
11    @file
12    @brief Grid (mesh) based router 
13 */
14
15
16 #include "gridrouter.h"
17
18 #define gmap(pe) {if (gpes) pe=gpes[pe];}
19
20 /**The only communication op used. Modify this to use
21  ** vector send */
22 #if CMK_COMLIB_USE_VECTORIZE
23 #define GRIDSENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe)  \
24         {int len;\
25         PTvectorlist newmsg;\
26         ComlibPrintf("Entering Gridsendfn\n");\
27         newmsg=PeMesh->ExtractAndVectorize(kid, u1, knpe, kpelist);\
28         if (newmsg) {\
29           CmiSetHandler(newmsg->msgs[0], khndl);\
30           ComlibPrintf("Sending in Gridsendfn to %d\n",knextpe);\
31           CmiSyncVectorSendAndFree(knextpe, -newmsg->count, newmsg->sizes, newmsg->msgs);\
32         }\
33         else {\
34           SendDummyMsg(kid, knextpe, u2);\
35         }\
36 }
37 #else
38 #define GRIDSENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe)  \
39         {int len;\
40         char *newmsg;\
41         newmsg=PeMesh->ExtractAndPack(kid, u1, knpe, kpelist, &len);\
42         if (newmsg) {\
43           CmiSetHandler(newmsg, khndl);\
44           CmiSyncSendAndFree(knextpe, len, newmsg);\
45         }\
46         else {\
47           SendDummyMsg(kid, knextpe, u2);\
48         }\
49 }
50 #endif
51
52 /****************************************************
53  * Preallocated memory=P ints + MAXNUMMSGS msgstructs
54  *****************************************************/
55 GridRouter::GridRouter(int n, int me, Strategy *parent) : Router(parent)
56 {
57   //CmiPrintf("PE=%d me=%d NUMPES=%d\n", MyPe, me, n);
58   
59   NumPes=n;
60   MyPe=me;
61   gpes=NULL;
62   COLLEN=ColLen(NumPes);
63   LPMsgExpected = Expect(MyPe, NumPes);
64   recvExpected = 0;
65
66   myrow=MyPe/COLLEN;
67   mycol=MyPe%COLLEN;  
68   int lastrow = (NumPes - 1)/COLLEN;
69   
70   if(myrow < lastrow) 
71       recvExpected = ROWLEN;
72   else
73       recvExpected = (NumPes - 1)%ROWLEN + 1;
74
75   if(lastrow * COLLEN + mycol > NumPes - 1) {
76       //We have a hole in the lastrow
77       if(lastrow * COLLEN + myrow <= NumPes - 1) 
78           //We have a processor which wants to send data to that hole
79           recvExpected ++;
80       
81       if((myrow == 0) && (NumPes == ROWLEN*(COLLEN-1) - 1))
82           //Special case with one hole only
83           recvExpected ++;      
84   }
85   
86   ComlibPrintf("%d LPMsgExpected=%d\n", MyPe, LPMsgExpected);
87
88   PeMesh = new PeTable(NumPes);
89   PeMesh1 = new PeTable(NumPes);
90   PeMesh2 = new PeTable(NumPes);
91
92   onerow=(int *)CmiAlloc(ROWLEN*sizeof(int));
93
94   rowVector = (int *)CmiAlloc(ROWLEN*sizeof(int));
95   colVector = (int *)CmiAlloc(COLLEN*sizeof(int));
96
97   int myrep=myrow*COLLEN;
98   int count = 0;
99   int pos = 0;
100
101   for(count = mycol; count < ROWLEN+mycol; count ++){
102       int nextpe= myrep + count%ROWLEN;
103       
104       if (nextpe >= NumPes) {
105           int new_row = mycol % (myrow+1);
106           
107           if(new_row >= myrow)
108               new_row = 0;
109           
110           nextpe = COLLEN * new_row + count%ROWLEN;
111       }
112       
113       if(nextpe == MyPe)
114           continue;
115
116       ComlibPrintf("Row[%d] = %d\n", MyPe, nextpe);
117
118       rowVector[pos ++] = nextpe;
119   }
120   rvecSize = pos;
121
122   pos = 0;
123   for(count = myrow; count < COLLEN+myrow; count ++){
124       int nextrowrep = (count % COLLEN) *COLLEN;
125       int nextpe = nextrowrep+mycol;
126       
127       if(nextpe < NumPes && nextpe != MyPe)
128           colVector[pos ++] = nextpe;
129   }
130   
131   cvecSize = pos;
132
133   growVector = new int[rvecSize];
134   gcolVector = new int[cvecSize];
135
136   for(count = 0; count < rvecSize; count ++)
137       growVector[count] = rowVector[count];
138   
139   for(count = 0; count < cvecSize; count ++)
140       gcolVector[count] = colVector[count];
141   
142
143   InitVars();
144   ComlibPrintf("%d:COLLEN=%d, ROWLEN=%d, recvexpected=%d\n", MyPe, COLLEN, ROWLEN, recvExpected);
145 }
146
147 GridRouter::~GridRouter()
148 {
149   delete PeMesh;
150   delete PeMesh1;
151   delete PeMesh2;
152     
153   delete [] growVector;
154   delete [] gcolVector;
155
156   CmiFree(onerow);
157   CmiFree(rowVector);
158   CmiFree(colVector);
159 }
160
161 void GridRouter :: InitVars()
162 {
163   recvCount=0;
164   LPMsgCount=0;
165 }
166
167 /*
168 void GridRouter::NumDeposits(comID, int num)
169 {
170 }
171 */
172
173 void GridRouter::EachToAllMulticast(comID id, int size, void *msg, int more)
174 {
175   int npe=NumPes;
176   int * destpes=(int *)CmiAlloc(sizeof(int)*npe);
177   for (int i=0;i<npe;i++) destpes[i]=i;
178   EachToManyMulticast(id, size, msg, npe, destpes, more);
179 }
180
181 extern void CmiReference(void *blk);
182
183 void GridRouter::EachToManyMulticast(comID id, int size, void *msg, int numpes, int *destpes, int more)
184 {
185   if(id.isAllToAll)
186       PeMesh->InsertMsgs(1, &MyPe, size, msg);
187   else
188       PeMesh->InsertMsgs(numpes, destpes, size, msg);
189   
190   if (more) return;
191
192   ComlibPrintf("All messages received %d %d %d\n", MyPe, COLLEN,id.isAllToAll);
193   sendRow(id);
194 }
195
196 void GridRouter::EachToManyMulticastQ(comID id, CkQ<MessageHolder *> &msgq) {
197    
198     ComlibPrintf("Grid Router :: EachToManyQ\n");
199  
200     int count = 0;
201     int length = msgq.length();
202     if(id.isAllToAll) {
203         for(count = 0; count < length; count ++) {
204             MessageHolder *mhdl = msgq.deq();
205             PeMesh->InsertMsgs(1, &MyPe, mhdl->size, mhdl->getMessage());
206             delete mhdl;
207         }
208     }
209     else {
210         for(count = 0; count < length; count ++) {
211             MessageHolder *mhdl = msgq.deq();
212             PeMesh->InsertMsgs(mhdl->npes, mhdl->pelist, mhdl->size, 
213                                mhdl->getMessage());
214             delete mhdl;
215         }
216     }
217     
218     sendRow(id);
219 }
220
221
222 void GridRouter::sendRow(comID id) {
223
224     int i=0;
225     char *a2amsg = NULL;
226     int a2a_len;
227     if(id.isAllToAll) {
228         ComlibPrintf("ALL to ALL flag set\n");
229         
230         a2amsg = PeMesh->ExtractAndPackAll(id, 0, &a2a_len);
231         CmiSetHandler(a2amsg, CkpvAccess(RouterRecvHandle));
232         CmiReference(a2amsg);
233         CmiSyncListSendAndFree(rvecSize, growVector, a2a_len, a2amsg);      
234         RecvManyMsg(id, a2amsg);
235         return;
236     }
237     
238     //Send the messages
239     //int MYROW  =MyPe/COLLEN;
240     //int MYCOL = MyPe%COLLEN;
241     int myrep= myrow*COLLEN; 
242     int maxlength = (NumPes - 1)/COLLEN + 1;
243     
244     for (int colcount = 0; colcount < rvecSize; ++colcount) {
245         int nextpe = rowVector[colcount];
246         i = nextpe % COLLEN;
247         
248         int length = maxlength;
249         if((length - 1)* COLLEN + i >= NumPes)
250             length --;
251         
252         for (int j = 0; j < length; j++) {
253             onerow[j]=j * COLLEN + i;
254         }
255         
256         ComlibPrintf("%d: before gmap sending to %d of column %d for %d procs,  %d,%d,%d,%d\n",
257                      MyPe, nextpe, i, length, onerow[0], onerow[1], onerow[2], onerow[3]);
258         
259         gmap(nextpe);
260         
261         GRIDSENDFN(id, 0, 0,length, onerow, CkpvAccess(RouterRecvHandle), nextpe); 
262         ComlibPrintf("%d:sending to %d of column %d\n", MyPe, nextpe, i);
263     }
264     RecvManyMsg(id, NULL);
265 }
266
267 void GridRouter::RecvManyMsg(comID id, char *msg)
268 {
269   if (msg) {  
270       if(id.isAllToAll)
271           PeMesh1->UnpackAndInsertAll(msg, 1, &MyPe);
272       else
273           PeMesh->UnpackAndInsert(msg);
274   }
275
276   recvCount++;
277
278   ComlibPrintf("%d recvcount=%d recvexpected = %d\n", MyPe, recvCount, recvExpected);
279
280   if (recvCount == recvExpected) {
281       
282       char *a2amsg;
283       int a2a_len;
284       if(id.isAllToAll) {
285           a2amsg = PeMesh1->ExtractAndPackAll(id, 1, &a2a_len);
286           CmiSetHandler(a2amsg, CkpvAccess(RouterProcHandle));
287           CmiReference(a2amsg);
288           CmiSyncListSendAndFree(cvecSize, gcolVector, a2a_len, a2amsg);   
289           ProcManyMsg(id, a2amsg);
290           return;
291       }
292
293       for (int rowcount=0; rowcount < cvecSize; rowcount++) {
294           int nextpe = colVector[rowcount];
295                     
296           int gnextpe = nextpe;
297           int *pelist=&gnextpe;
298           
299           ComlibPrintf("Before gmap %d\n", nextpe);
300           
301           gmap(nextpe);
302
303           ComlibPrintf("After gmap %d\n", nextpe);
304           
305           ComlibPrintf("%d:sending message to %d of row %d\n", MyPe, nextpe, 
306                        rowcount);
307           
308           GRIDSENDFN(id, 0, 1, 1, pelist, CkpvAccess(RouterProcHandle), nextpe);
309       }
310       
311       LocalProcMsg(id);
312   }
313 }
314
315 void GridRouter::DummyEP(comID id, int magic)
316 {
317   if (magic == 1) {
318         //ComlibPrintf("%d dummy calling lp\n", MyPe);
319         LocalProcMsg(id);
320   }
321   else {
322         //ComlibPrintf("%d dummy calling recv\n", MyPe);
323         RecvManyMsg(id, NULL);
324   }
325 }
326
327 void GridRouter:: ProcManyMsg(comID id, char *m)
328 {
329     ComlibPrintf("%d: ProcManyMsg\n", MyPe);
330     
331     if(id.isAllToAll)
332         PeMesh2->UnpackAndInsertAll(m, 1, &MyPe);
333     else
334         PeMesh->UnpackAndInsert(m);
335     //ComlibPrintf("%d proc calling lp\n");
336     
337     LocalProcMsg(id);
338 }
339
340 void GridRouter:: LocalProcMsg(comID id)
341 {
342     LPMsgCount++;
343     PeMesh->ExtractAndDeliverLocalMsgs(MyPe, container);
344     if(id.isAllToAll)
345         PeMesh2->ExtractAndDeliverLocalMsgs(MyPe, container);
346     
347     ComlibPrintf("%d local procmsg called, %d, %d\n", MyPe, 
348                  LPMsgCount, LPMsgExpected);
349     if (LPMsgCount==LPMsgExpected) {
350         PeMesh->Purge();
351         if(id.isAllToAll)
352             PeMesh2->Purge();
353         
354         InitVars();
355         Done(id);
356     }
357 }
358
359 Router * newgridobject(int n, int me, Strategy *strat)
360 {
361   Router *obj=new GridRouter(n, me, strat);
362   return(obj);
363 }
364
365 void GridRouter :: SetMap(int *pes)
366 {
367     
368   gpes=pes;
369   
370   if(!gpes)
371       return;
372
373   int count = 0;
374
375   for(count = 0; count < rvecSize; count ++)
376       growVector[count] = gpes[rowVector[count]];
377   
378   for(count = 0; count < cvecSize; count ++)
379       gcolVector[count] = gpes[colVector[count]];
380 }
381 /*@}*/