LRTS Comm Thread Tracing in message recieve
[charm.git] / src / conv-com / 3dgridrouter.C
blob88107c79f924437dd7dd780bdeaca58bc82c36fc
1 /**
2    @addtogroup ConvComlibRouter
3    @{
4    @file 
5    @brief Grid (3d grid) based router
6    @Author Sameer Kumar
7 */
13 #include "3dgridrouter.h"
14 //#define NULL 0
16 #define gmap(pe) {if (gpes) pe=gpes[pe];}
18 /**The only communication op used. Modify this to use
19  ** vector send */
20 #if CMK_COMLIB_USE_VECTORIZE
21 #define GRIDSENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe)  \
22         {int len;\
23         PTvectorlist newmsg;\
24         newmsg=PeGrid->ExtractAndVectorize(kid, u1, knpe, kpelist);\
25         if (newmsg) {\
26           CmiSetHandler(newmsg->msgs[0], khndl);\
27           CmiSyncVectorSendAndFree(knextpe, -newmsg->count, newmsg->sizes, newmsg->msgs);\
28         }\
29         else {\
30           SendDummyMsg(kid, knextpe, u2);\
31         }\
33 #else
34 #define GRIDSENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe)  \
35         {int len;\
36         char * newmsg;\
37         newmsg=PeGrid->ExtractAndPack(kid, u1, knpe, kpelist, &len);\
38         if (newmsg) {\
39           CmiSetHandler(newmsg, khndl);\
40           CmiSyncSendAndFree(knextpe, len, (char *)newmsg);\
41         }\
42         else {\
43           SendDummyMsg(kid, knextpe, u2);\
44         }\
46 #endif
48 #define ROWLEN COLLEN
50 #define RowLen(pe) ColLen3D(pe)
51 #define PELISTSIZE ((ROWLEN-1)/sizeof(int)+1)
53 inline int ColLen3D(int npes)
55     int len= (int)cubeRoot((double)npes);
56     //    ComlibPrintf("%d:collen len = %d\n", CkMyPe(), len);
57     if (npes > (len * len * len)) len++;
58     return(len);
61 inline int Expect1(int gpe, int gnpes)
63     int i, len=ColLen3D(gnpes);
64     int pe = gpe % (len * len);
65     
66     int npes = len * len;
67     if((gnpes - 1)/(len * len) == gpe / (len * len))
68         npes = ((gnpes - 1) % (len*len)) + 1;
69     
70     for (i=len-1;i>=0;i--) {
71         int myrow=pe/len;
72         int toprep=i*len;
73         int offset=pe-myrow*len;
74         if ((toprep+offset) <= (npes-1)) return(i+1);
75     }
76     return 0;
77     //return(len);
80 inline int Expect2(int gpe, int gnpes) {
81     int len=RowLen(gnpes);
82     int myplane = gpe / (len * len);
83     int lastplane = (gnpes - 1)/(len * len);
84     
85     if(myplane < lastplane)
86         return len;
88     int pe = gpe % (len * len);
89     int myrow = pe / len;
90     int lastrow = ((gnpes - 1) % (len * len)) / len;
91     
92     if (myrow < lastrow)
93         return len;
94     
95     int ret = ((gnpes - 1) % (len * len)) - myrow * len + 1;
96     if(ret < 0)
97         ret = 0;
98     return ret;
100     
102 inline int LPMsgExpect(int gpe, int gnpes)
104     int i;
105     int row = RowLen(gnpes);
106     int col = ColLen3D(gnpes);
107     int len = (int)ceil(((double)gnpes) / (row * col));
109     for (i=len-1;i>=0;i--) {
110         int toprep=i*(row * col);
111         
112         if ((toprep + (gpe % (row * col))) <= (gnpes-1)) return(i+1);
113     }
114     return(len);
117 /****************************************************
118  * Preallocated memory=P ints + MAXNUMMSGS msgstructs
119  *****************************************************/
120 D3GridRouter::D3GridRouter(int n, int me, Strategy *parent) : Router(parent)
122     ComlibPrintf("PE=%d me=%d NUMPES=%d\n", CkMyPe(), me, n);
123     
124     NumPes=n;
125     MyPe=me;
126     gpes=NULL;
128     COLLEN=ColLen3D(NumPes);
130     recvExpected[0] = 0;
131     recvExpected[1] = 0;
132     routerStage = 0;
133     
134     int myrow = (MyPe % (ROWLEN * COLLEN)) / COLLEN;
135     int myrep = myrow * COLLEN + MyPe - (MyPe % (ROWLEN * COLLEN));
136     int numunmappedpes=myrep+ROWLEN-NumPes;
137     int nummappedpes=ROWLEN;
138     
139     if (numunmappedpes >0) {
140         nummappedpes=NumPes-myrep;
141         int i=NumPes+MyPe-myrep;
142         while (i<myrep+ROWLEN) {
143             recvExpected[0] += Expect1(i, NumPes);
144             i+=nummappedpes;
145         }
146     }
147     
148     if((NumPes % (COLLEN * ROWLEN) != 0) && ((NumPes - 1)/(ROWLEN*COLLEN) - MyPe/(ROWLEN*COLLEN) == 1)){
149         if(myrep + ROWLEN * COLLEN >= NumPes) 
150             recvExpected[0] += Expect1(MyPe + ROWLEN*COLLEN, NumPes);
151         
152         if(MyPe + ROWLEN * COLLEN >= NumPes) 
153             recvExpected[1] += Expect2(MyPe + ROWLEN*COLLEN, NumPes);
154         ComlibPrintf("%d: here\n");
155     }
157     recvExpected[0] += Expect1(MyPe, NumPes);
158     recvExpected[1] += Expect2(MyPe, NumPes);
160     LPMsgExpected = LPMsgExpect(MyPe, NumPes);
161     //ComlibPrintf("%d LPMsgExpected=%d\n", MyPe, LPMsgExpected);
162     
163     PeGrid = new PeTable(/*CkNumPes()*/NumPes);
164     
165     nplanes = (int)ceil(((double)NumPes) / (ROWLEN * COLLEN));
167     oneplane = new int*[COLLEN];
168     psize = new int[COLLEN];
169     for(int count = 0; count < COLLEN; count ++) {
170         oneplane[count] = new int[nplanes * ROWLEN];
172         int idx = 0;
173         
174         for (int j=0;j< ROWLEN;j++) 
175             for(int k = 0; k < nplanes; k++) {
176                 int dest = count * ROWLEN + j + ROWLEN * COLLEN * k;
177                 if(dest < NumPes) {
178                     oneplane[count][idx++] = dest;
179                 }
180                 else break;
181             }
182         psize[count] = idx;
183     }
185     zline = new int[nplanes];
186     
187     InitVars();
188     ComlibPrintf("%d:%d:COLLEN=%d, ROWLEN=%d, recvexpected=%d,%d\n", CkMyPe(), MyPe, COLLEN, ROWLEN, recvExpected[0], recvExpected[1]);
191 D3GridRouter::~D3GridRouter()
193     delete PeGrid;
194     delete[] zline;
195     for(int count = 0; count < COLLEN; count ++)
196         delete[] oneplane[count];
197     
198     delete[] oneplane;
201 void D3GridRouter :: InitVars()
203     recvCount[0]=0;
204     recvCount[1]=0;
205     
206     LPMsgCount=0;
209 void D3GridRouter::NumDeposits(comID, int num)
213 void D3GridRouter::EachToAllMulticast(comID id, int size, void *msg, int more)
215     int npe=NumPes;
216     int * destpes=(int *)CmiAlloc(sizeof(int)*npe);
217     for (int i=0;i<npe;i++) destpes[i]=i;
218     EachToManyMulticast(id, size, msg, npe, destpes, more);
221 void D3GridRouter::EachToManyMulticast(comID id, int size, void *msg, int numpes, int *destpes, int more)
223     int i;
224     
225     //Buffer the message
226     if (size) {
227         PeGrid->InsertMsgs(numpes, destpes, size, msg);
228     }
229     
230     if (more) return;
232     routerStage = 0;
233     ComlibPrintf("All messages received %d %d\n", CkMyPe(), COLLEN);
234     
235     //Send the messages
236     int firstproc = MyPe - (MyPe % (ROWLEN * COLLEN));
237     for (i=0;i<COLLEN;i++) {
238         
239         ComlibPrintf("ROWLEN = %d, COLLEN =%d first proc = %d\n", 
240                      ROWLEN, COLLEN, firstproc);
241         
242         //int MYROW = (MyPe % (ROWLEN * COLLEN))/ROWLEN;
243         int nextrowrep = firstproc + i*ROWLEN;
244         int nextpe = (MyPe % (ROWLEN * COLLEN)) % ROWLEN + nextrowrep;
245         int nummappedpes=NumPes-nextrowrep;
246         
247         if (nummappedpes <= 0) { // looks for nextpe in the previous plane
248             nextpe -= ROWLEN * COLLEN;
249             if(nextpe < 0)
250                 continue;
251         }
253         if (nextpe >= NumPes) {
254             int mm=(nextpe-NumPes) % nummappedpes;
255             nextpe=nextrowrep+mm;
256         }
257         
258         if (nextpe == MyPe) {
259             ComlibPrintf("%d calling recv directly\n", MyPe);
260             recvCount[0]++;
261             RecvManyMsg(id, NULL);
262             continue;
263         }
264         
265         //ComlibPrintf("nummappedpes = %d, NumPes = %d, nextrowrep = %d, nextpe = %d, mype = %d\n", nummappedpes, NumPes, nextrowrep,  nextpe, MyPe);
266         
267         gmap(nextpe);
268         ComlibPrintf("sending to column %d and dest %d in %d\n", i, nextpe, CkMyPe());
269         GRIDSENDFN(id, 0, 0, psize[i], oneplane[i],CkpvAccess(RouterRecvHandle), nextpe); 
270     }
273 void D3GridRouter::RecvManyMsg(comID id, char *msg)
275     ComlibPrintf("%d recvcount=%d,%d recvexpected = %d,%d\n", MyPe, recvCount[0],  recvCount[1], recvExpected[0],recvExpected[1]);
276     int stage = 0;
277     if (msg) {
278         stage = PeGrid->UnpackAndInsert(msg);
279         recvCount[stage]++;
280     }
281     
282     if ((recvCount[0] == recvExpected[0]) && (routerStage == 0)){
283         routerStage = 1;
284         int myrow = (MyPe % (ROWLEN * COLLEN)) / COLLEN;
285         int myrep = myrow*ROWLEN + MyPe - (MyPe % (ROWLEN * COLLEN));
286         for (int i=0;i<ROWLEN;i++) {
287             int nextpe = myrep + i;
288             
289             //if (nextpe >= NumPes || nextpe==MyPe) continue;
290             
291             if(nextpe == MyPe) {
292                 recvCount[1]++;
293                 RecvManyMsg(id, NULL);
294                 continue;
295             }
296             
297             if(nextpe >= NumPes) {
298                 nextpe -= ROWLEN * COLLEN;
299                 if(nextpe < 0)
300                     continue;
301             }
303             int *pelist = zline;
304             int k = 0;
305             
306             //ComlibPrintf("recv:myrow = %d, nplanes = %d\n", myrow, nplanes);
307             //ComlibPrintf("recv:%d->%d:", MyPe, nextpe);
308             for(k = 0; k < nplanes; k++) {
309                 int dest = myrow * ROWLEN + i + ROWLEN * COLLEN * k;
310                 //ComlibPrintf("%d,", dest);
311                 if(dest >= NumPes)
312                     break;
313                 zline[k] = dest;
314             }
315             //ComlibPrintf(")\n");
317             ComlibPrintf("Before gmap %d\n", nextpe);
318             
319             gmap(nextpe);
320             
321             //ComlibPrintf("After gmap %d\n", nextpe);
322             ComlibPrintf("%d:sending recv message %d %d\n", MyPe, nextpe, myrep);
323             GRIDSENDFN(id, 1, 1, k, pelist, CkpvAccess(RouterRecvHandle), nextpe);
324         }
325     }
326     
327     if((recvCount[1] == recvExpected[1]) && (routerStage == 1)){
328         routerStage = 2;
329         for (int k=0; k < nplanes; k++) {
330             int nextpe = (MyPe % (ROWLEN * COLLEN)) + k * ROWLEN * COLLEN;
332             if (nextpe >= NumPes || nextpe==MyPe) continue;
333             
334             int gnextpe = nextpe;
335             int *pelist = &gnextpe;
336             
337             ComlibPrintf("Before gmap %d\n", nextpe);
338             
339             gmap(nextpe);
340             
341             //ComlibPrintf("After gmap %d\n", nextpe);
342             
343             ComlibPrintf("%d:sending proc message %d %d\n", MyPe, nextpe, nplanes);
344             GRIDSENDFN(id, 2, 2, 1, pelist, CkpvAccess(RouterProcHandle), nextpe);
345         }
346         LocalProcMsg(id);
347     }
350 void D3GridRouter::DummyEP(comID id, int stage)
352     if (stage == 2) {
353         ComlibPrintf("%d dummy calling lp\n", MyPe);
354         LocalProcMsg(id);
355     }
356     else {
357         recvCount[stage]++;
358         ComlibPrintf("%d dummy calling recv\n", MyPe);
359         RecvManyMsg(id, NULL);
360     }
363 void D3GridRouter:: ProcManyMsg(comID id, char *m)
365     PeGrid->UnpackAndInsert(m);
366     ComlibPrintf("%d proc calling lp\n", MyPe);
367     LocalProcMsg(id);
370 void D3GridRouter:: LocalProcMsg(comID id)
372     ComlibPrintf("%d local procmsg called\n", MyPe);
373     
374     LPMsgCount++;
375     PeGrid->ExtractAndDeliverLocalMsgs(MyPe, container);
376     
377     if (LPMsgCount==LPMsgExpected) {
378         PeGrid->Purge();
379         InitVars();
380         routerStage = 0;
381         ComlibPrintf("%d:Round Done\n", CkMyPe());
382         Done(id);
383     }
386 void D3GridRouter :: SetMap(int *pes)
388     gpes=pes;
391 /*@}*/