2 @addtogroup ConvComlibRouter
5 @brief Grid (3d grid) based router
13 #include "3dgridrouter.h"
16 #define gmap(pe) {if (gpes) pe=gpes[pe];}
18 /**The only communication op used. Modify this to use
20 #if CMK_COMLIB_USE_VECTORIZE
21 #define GRIDSENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe) \
24 newmsg=PeGrid->ExtractAndVectorize(kid, u1, knpe, kpelist);\
26 CmiSetHandler(newmsg->msgs[0], khndl);\
27 CmiSyncVectorSendAndFree(knextpe, -newmsg->count, newmsg->sizes, newmsg->msgs);\
30 SendDummyMsg(kid, knextpe, u2);\
34 #define GRIDSENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe) \
37 newmsg=PeGrid->ExtractAndPack(kid, u1, knpe, kpelist, &len);\
39 CmiSetHandler(newmsg, khndl);\
40 CmiSyncSendAndFree(knextpe, len, (char *)newmsg);\
43 SendDummyMsg(kid, knextpe, u2);\
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++;
61 inline int Expect1(int gpe, int gnpes)
63 int i, len=ColLen3D(gnpes);
64 int pe = gpe % (len * len);
67 if((gnpes - 1)/(len * len) == gpe / (len * len))
68 npes = ((gnpes - 1) % (len*len)) + 1;
70 for (i=len-1;i>=0;i--) {
73 int offset=pe-myrow*len;
74 if ((toprep+offset) <= (npes-1)) return(i+1);
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);
85 if(myplane < lastplane)
88 int pe = gpe % (len * len);
90 int lastrow = ((gnpes - 1) % (len * len)) / len;
95 int ret = ((gnpes - 1) % (len * len)) - myrow * len + 1;
102 inline int LPMsgExpect(int gpe, int gnpes)
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);
112 if ((toprep + (gpe % (row * col))) <= (gnpes-1)) return(i+1);
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);
128 COLLEN=ColLen3D(NumPes);
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;
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);
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);
152 if(MyPe + ROWLEN * COLLEN >= NumPes)
153 recvExpected[1] += Expect2(MyPe + ROWLEN*COLLEN, NumPes);
154 ComlibPrintf("%d: here\n");
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);
163 PeGrid = new PeTable(/*CkNumPes()*/NumPes);
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];
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;
178 oneplane[count][idx++] = dest;
185 zline = new int[nplanes];
188 ComlibPrintf("%d:%d:COLLEN=%d, ROWLEN=%d, recvexpected=%d,%d\n", CkMyPe(), MyPe, COLLEN, ROWLEN, recvExpected[0], recvExpected[1]);
191 D3GridRouter::~D3GridRouter()
195 for(int count = 0; count < COLLEN; count ++)
196 delete[] oneplane[count];
201 void D3GridRouter :: InitVars()
209 void D3GridRouter::NumDeposits(comID, int num)
213 void D3GridRouter::EachToAllMulticast(comID id, int size, void *msg, int more)
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)
227 PeGrid->InsertMsgs(numpes, destpes, size, msg);
233 ComlibPrintf("All messages received %d %d\n", CkMyPe(), COLLEN);
236 int firstproc = MyPe - (MyPe % (ROWLEN * COLLEN));
237 for (i=0;i<COLLEN;i++) {
239 ComlibPrintf("ROWLEN = %d, COLLEN =%d first proc = %d\n",
240 ROWLEN, COLLEN, firstproc);
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;
247 if (nummappedpes <= 0) { // looks for nextpe in the previous plane
248 nextpe -= ROWLEN * COLLEN;
253 if (nextpe >= NumPes) {
254 int mm=(nextpe-NumPes) % nummappedpes;
255 nextpe=nextrowrep+mm;
258 if (nextpe == MyPe) {
259 ComlibPrintf("%d calling recv directly\n", MyPe);
261 RecvManyMsg(id, NULL);
265 //ComlibPrintf("nummappedpes = %d, NumPes = %d, nextrowrep = %d, nextpe = %d, mype = %d\n", nummappedpes, NumPes, nextrowrep, nextpe, MyPe);
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);
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]);
278 stage = PeGrid->UnpackAndInsert(msg);
282 if ((recvCount[0] == recvExpected[0]) && (routerStage == 0)){
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;
289 //if (nextpe >= NumPes || nextpe==MyPe) continue;
293 RecvManyMsg(id, NULL);
297 if(nextpe >= NumPes) {
298 nextpe -= ROWLEN * COLLEN;
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);
315 //ComlibPrintf(")\n");
317 ComlibPrintf("Before gmap %d\n", nextpe);
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);
327 if((recvCount[1] == recvExpected[1]) && (routerStage == 1)){
329 for (int k=0; k < nplanes; k++) {
330 int nextpe = (MyPe % (ROWLEN * COLLEN)) + k * ROWLEN * COLLEN;
332 if (nextpe >= NumPes || nextpe==MyPe) continue;
334 int gnextpe = nextpe;
335 int *pelist = &gnextpe;
337 ComlibPrintf("Before gmap %d\n", nextpe);
341 //ComlibPrintf("After gmap %d\n", nextpe);
343 ComlibPrintf("%d:sending proc message %d %d\n", MyPe, nextpe, nplanes);
344 GRIDSENDFN(id, 2, 2, 1, pelist, CkpvAccess(RouterProcHandle), nextpe);
350 void D3GridRouter::DummyEP(comID id, int stage)
353 ComlibPrintf("%d dummy calling lp\n", MyPe);
358 ComlibPrintf("%d dummy calling recv\n", MyPe);
359 RecvManyMsg(id, NULL);
363 void D3GridRouter:: ProcManyMsg(comID id, char *m)
365 PeGrid->UnpackAndInsert(m);
366 ComlibPrintf("%d proc calling lp\n", MyPe);
370 void D3GridRouter:: LocalProcMsg(comID id)
372 ComlibPrintf("%d local procmsg called\n", MyPe);
375 PeGrid->ExtractAndDeliverLocalMsgs(MyPe, container);
377 if (LPMsgCount==LPMsgExpected) {
381 ComlibPrintf("%d:Round Done\n", CkMyPe());
386 void D3GridRouter :: SetMap(int *pes)