00001
00009 #include "gridrouter.h"
00010
00011 #define gmap(pe) {if (gpes) pe=gpes[pe];}
00012
00015 #if CMK_COMLIB_USE_VECTORIZE
00016 #define GRIDSENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe) \
00017 {int len;\
00018 PTvectorlist newmsg;\
00019 ComlibPrintf("Entering Gridsendfn\n");\
00020 newmsg=PeMesh->ExtractAndVectorize(kid, u1, knpe, kpelist);\
00021 if (newmsg) {\
00022 CmiSetHandler(newmsg->msgs[0], khndl);\
00023 ComlibPrintf("Sending in Gridsendfn to %d\n",knextpe);\
00024 CmiSyncVectorSendAndFree(knextpe, -newmsg->count, newmsg->sizes, newmsg->msgs);\
00025 }\
00026 else {\
00027 SendDummyMsg(kid, knextpe, u2);\
00028 }\
00029 }
00030 #else
00031 #define GRIDSENDFN(kid, u1, u2, knpe, kpelist, khndl, knextpe) \
00032 {int len;\
00033 char *newmsg;\
00034 newmsg=PeMesh->ExtractAndPack(kid, u1, knpe, kpelist, &len);\
00035 if (newmsg) {\
00036 CmiSetHandler(newmsg, khndl);\
00037 CmiSyncSendAndFree(knextpe, len, newmsg);\
00038 }\
00039 else {\
00040 SendDummyMsg(kid, knextpe, u2);\
00041 }\
00042 }
00043 #endif
00044
00045
00046
00047
00048 GridRouter::GridRouter(int n, int me, Strategy *parent) : Router(parent)
00049 {
00050
00051
00052 NumPes=n;
00053 MyPe=me;
00054 gpes=NULL;
00055 COLLEN=ColLen(NumPes);
00056 LPMsgExpected = Expect(MyPe, NumPes);
00057 recvExpected = 0;
00058
00059 myrow=MyPe/COLLEN;
00060 mycol=MyPe%COLLEN;
00061 int lastrow = (NumPes - 1)/COLLEN;
00062
00063 if(myrow < lastrow)
00064 recvExpected = ROWLEN;
00065 else
00066 recvExpected = (NumPes - 1)%ROWLEN + 1;
00067
00068 if(lastrow * COLLEN + mycol > NumPes - 1) {
00069
00070 if(lastrow * COLLEN + myrow <= NumPes - 1)
00071
00072 recvExpected ++;
00073
00074 if((myrow == 0) && (NumPes == ROWLEN*(COLLEN-1) - 1))
00075
00076 recvExpected ++;
00077 }
00078
00079 ComlibPrintf("%d LPMsgExpected=%d\n", MyPe, LPMsgExpected);
00080
00081 PeMesh = new PeTable(NumPes);
00082 PeMesh1 = new PeTable(NumPes);
00083 PeMesh2 = new PeTable(NumPes);
00084
00085 onerow=(int *)CmiAlloc(ROWLEN*sizeof(int));
00086
00087 rowVector = (int *)CmiAlloc(ROWLEN*sizeof(int));
00088 colVector = (int *)CmiAlloc(COLLEN*sizeof(int));
00089
00090 int myrep=myrow*COLLEN;
00091 int count = 0;
00092 int pos = 0;
00093
00094 for(count = mycol; count < ROWLEN+mycol; count ++){
00095 int nextpe= myrep + count%ROWLEN;
00096
00097 if (nextpe >= NumPes) {
00098 int new_row = mycol % (myrow+1);
00099
00100 if(new_row >= myrow)
00101 new_row = 0;
00102
00103 nextpe = COLLEN * new_row + count%ROWLEN;
00104 }
00105
00106 if(nextpe == MyPe)
00107 continue;
00108
00109 ComlibPrintf("Row[%d] = %d\n", MyPe, nextpe);
00110
00111 rowVector[pos ++] = nextpe;
00112 }
00113 rvecSize = pos;
00114
00115 pos = 0;
00116 for(count = myrow; count < COLLEN+myrow; count ++){
00117 int nextrowrep = (count % COLLEN) *COLLEN;
00118 int nextpe = nextrowrep+mycol;
00119
00120 if(nextpe < NumPes && nextpe != MyPe)
00121 colVector[pos ++] = nextpe;
00122 }
00123
00124 cvecSize = pos;
00125
00126 growVector = new int[rvecSize];
00127 gcolVector = new int[cvecSize];
00128
00129 for(count = 0; count < rvecSize; count ++)
00130 growVector[count] = rowVector[count];
00131
00132 for(count = 0; count < cvecSize; count ++)
00133 gcolVector[count] = colVector[count];
00134
00135
00136 InitVars();
00137 ComlibPrintf("%d:COLLEN=%d, ROWLEN=%d, recvexpected=%d\n", MyPe, COLLEN, ROWLEN, recvExpected);
00138 }
00139
00140 GridRouter::~GridRouter()
00141 {
00142 delete PeMesh;
00143 delete PeMesh1;
00144 delete PeMesh2;
00145
00146 delete [] growVector;
00147 delete [] gcolVector;
00148
00149 CmiFree(onerow);
00150 CmiFree(rowVector);
00151 CmiFree(colVector);
00152 }
00153
00154 void GridRouter :: InitVars()
00155 {
00156 recvCount=0;
00157 LPMsgCount=0;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166 void GridRouter::EachToAllMulticast(comID id, int size, void *msg, int more)
00167 {
00168 int npe=NumPes;
00169 int * destpes=(int *)CmiAlloc(sizeof(int)*npe);
00170 for (int i=0;i<npe;i++) destpes[i]=i;
00171 EachToManyMulticast(id, size, msg, npe, destpes, more);
00172 }
00173
00174 extern void CmiReference(void *blk);
00175
00176 void GridRouter::EachToManyMulticast(comID id, int size, void *msg, int numpes, int *destpes, int more)
00177 {
00178 if(id.isAllToAll)
00179 PeMesh->InsertMsgs(1, &MyPe, size, msg);
00180 else
00181 PeMesh->InsertMsgs(numpes, destpes, size, msg);
00182
00183 if (more) return;
00184
00185 ComlibPrintf("All messages received %d %d %d\n", MyPe, COLLEN,id.isAllToAll);
00186 sendRow(id);
00187 }
00188
00189 void GridRouter::EachToManyMulticastQ(comID id, CkQ<MessageHolder *> &msgq) {
00190
00191 ComlibPrintf("Grid Router :: EachToManyQ\n");
00192
00193 int count = 0;
00194 int length = msgq.length();
00195 if(id.isAllToAll) {
00196 for(count = 0; count < length; count ++) {
00197 MessageHolder *mhdl = msgq.deq();
00198 PeMesh->InsertMsgs(1, &MyPe, mhdl->size, mhdl->getMessage());
00199 delete mhdl;
00200 }
00201 }
00202 else {
00203 for(count = 0; count < length; count ++) {
00204 MessageHolder *mhdl = msgq.deq();
00205 PeMesh->InsertMsgs(mhdl->npes, mhdl->pelist, mhdl->size,
00206 mhdl->getMessage());
00207 delete mhdl;
00208 }
00209 }
00210
00211 sendRow(id);
00212 }
00213
00214
00215 void GridRouter::sendRow(comID id) {
00216
00217 int i=0;
00218 char *a2amsg = NULL;
00219 int a2a_len;
00220 if(id.isAllToAll) {
00221 ComlibPrintf("ALL to ALL flag set\n");
00222
00223 a2amsg = PeMesh->ExtractAndPackAll(id, 0, &a2a_len);
00224 CmiSetHandler(a2amsg, CkpvAccess(RouterRecvHandle));
00225 CmiReference(a2amsg);
00226 CmiSyncListSendAndFree(rvecSize, growVector, a2a_len, a2amsg);
00227 RecvManyMsg(id, a2amsg);
00228 return;
00229 }
00230
00231
00232
00233
00234 int myrep= myrow*COLLEN;
00235 int maxlength = (NumPes - 1)/COLLEN + 1;
00236
00237 for (int colcount = 0; colcount < rvecSize; ++colcount) {
00238 int nextpe = rowVector[colcount];
00239 i = nextpe % COLLEN;
00240
00241 int length = maxlength;
00242 if((length - 1)* COLLEN + i >= NumPes)
00243 length --;
00244
00245 for (int j = 0; j < length; j++) {
00246 onerow[j]=j * COLLEN + i;
00247 }
00248
00249 ComlibPrintf("%d: before gmap sending to %d of column %d for %d procs, %d,%d,%d,%d\n",
00250 MyPe, nextpe, i, length, onerow[0], onerow[1], onerow[2], onerow[3]);
00251
00252 gmap(nextpe);
00253
00254 GRIDSENDFN(id, 0, 0,length, onerow, CkpvAccess(RouterRecvHandle), nextpe);
00255 ComlibPrintf("%d:sending to %d of column %d\n", MyPe, nextpe, i);
00256 }
00257 RecvManyMsg(id, NULL);
00258 }
00259
00260 void GridRouter::RecvManyMsg(comID id, char *msg)
00261 {
00262 if (msg) {
00263 if(id.isAllToAll)
00264 PeMesh1->UnpackAndInsertAll(msg, 1, &MyPe);
00265 else
00266 PeMesh->UnpackAndInsert(msg);
00267 }
00268
00269 recvCount++;
00270
00271 ComlibPrintf("%d recvcount=%d recvexpected = %d\n", MyPe, recvCount, recvExpected);
00272
00273 if (recvCount == recvExpected) {
00274
00275 char *a2amsg;
00276 int a2a_len;
00277 if(id.isAllToAll) {
00278 a2amsg = PeMesh1->ExtractAndPackAll(id, 1, &a2a_len);
00279 CmiSetHandler(a2amsg, CkpvAccess(RouterProcHandle));
00280 CmiReference(a2amsg);
00281 CmiSyncListSendAndFree(cvecSize, gcolVector, a2a_len, a2amsg);
00282 ProcManyMsg(id, a2amsg);
00283 return;
00284 }
00285
00286 for (int rowcount=0; rowcount < cvecSize; rowcount++) {
00287 int nextpe = colVector[rowcount];
00288
00289 int gnextpe = nextpe;
00290 int *pelist=&gnextpe;
00291
00292 ComlibPrintf("Before gmap %d\n", nextpe);
00293
00294 gmap(nextpe);
00295
00296 ComlibPrintf("After gmap %d\n", nextpe);
00297
00298 ComlibPrintf("%d:sending message to %d of row %d\n", MyPe, nextpe,
00299 rowcount);
00300
00301 GRIDSENDFN(id, 0, 1, 1, pelist, CkpvAccess(RouterProcHandle), nextpe);
00302 }
00303
00304 LocalProcMsg(id);
00305 }
00306 }
00307
00308 void GridRouter::DummyEP(comID id, int magic)
00309 {
00310 if (magic == 1) {
00311
00312 LocalProcMsg(id);
00313 }
00314 else {
00315
00316 RecvManyMsg(id, NULL);
00317 }
00318 }
00319
00320 void GridRouter:: ProcManyMsg(comID id, char *m)
00321 {
00322 ComlibPrintf("%d: ProcManyMsg\n", MyPe);
00323
00324 if(id.isAllToAll)
00325 PeMesh2->UnpackAndInsertAll(m, 1, &MyPe);
00326 else
00327 PeMesh->UnpackAndInsert(m);
00328
00329
00330 LocalProcMsg(id);
00331 }
00332
00333 void GridRouter:: LocalProcMsg(comID id)
00334 {
00335 LPMsgCount++;
00336 PeMesh->ExtractAndDeliverLocalMsgs(MyPe, container);
00337 if(id.isAllToAll)
00338 PeMesh2->ExtractAndDeliverLocalMsgs(MyPe, container);
00339
00340 ComlibPrintf("%d local procmsg called, %d, %d\n", MyPe,
00341 LPMsgCount, LPMsgExpected);
00342 if (LPMsgCount==LPMsgExpected) {
00343 PeMesh->Purge();
00344 if(id.isAllToAll)
00345 PeMesh2->Purge();
00346
00347 InitVars();
00348 Done(id);
00349 }
00350 }
00351
00352 Router * newgridobject(int n, int me, Strategy *strat)
00353 {
00354 Router *obj=new GridRouter(n, me, strat);
00355 return(obj);
00356 }
00357
00358 void GridRouter :: SetMap(int *pes)
00359 {
00360
00361 gpes=pes;
00362
00363 if(!gpes)
00364 return;
00365
00366 int count = 0;
00367
00368 for(count = 0; count < rvecSize; count ++)
00369 growVector[count] = gpes[rowVector[count]];
00370
00371 for(count = 0; count < cvecSize; count ++)
00372 gcolVector[count] = gpes[colVector[count]];
00373 }