00001
00007 #include "graphrouter.h"
00008 #include "hypercubetopology.h"
00009
00010 #define PERSISTENT_BUFSIZE 65536
00011
00012 #define gmap(pe) {if (gpes) pe=gpes[pe];}
00013
00014 GraphRouter::GraphRouter(int n, int me, Strategy *parent) : Router(parent) {
00015 init(n, me, new HypercubeTopology(n, me));
00016 }
00017
00018 void GraphRouter::init(int n, int me, TopologyDescriptor *tp)
00019 {
00020 NumPes=n;
00021 MyPe=me;
00022 gpes=NULL;
00023 this->tp = tp;
00024
00025 PeGraph = new PeTable(NumPes);
00026 pesToSend = new int[NumPes];
00027 nstages = tp->getNumStages() + 1;
00028 currentIteration = 0;
00029
00030 stageComplete = new int[nstages];
00031 recvExpected = new int[nstages];
00032 recvCount = new int[nstages];
00033
00034 memset(stageComplete, 0, nstages * sizeof(int));
00035 memset(recvCount, 0, nstages * sizeof(int));
00036
00037 for(int count = 1; count < nstages; count++)
00038 recvExpected[count] = tp->getNumMessagesExpected(count);
00039
00040 curStage = 0;
00041 ComlibPrintf("me=%d NUMPES=%d nstages=%d\n", MyPe, n, nstages);
00042 }
00043
00044 GraphRouter::~GraphRouter()
00045 {
00046 delete PeGraph;
00047 delete pesToSend;
00048 delete tp;
00049 delete [] stageComplete;
00050 delete [] recvExpected;
00051 delete [] recvCount;
00052 delete [] neighborPeList;
00053 }
00054
00055 void GraphRouter::NumDeposits(comID, int num)
00056 {
00057 }
00058
00059 void GraphRouter::EachToAllMulticast(comID id, int size, void *msg, int more)
00060 {
00061 int npe=NumPes;
00062 int * destpes=(int *)CmiAlloc(sizeof(int)*npe);
00063 for (int i=0;i<npe;i++) destpes[i]=i;
00064 EachToManyMulticast(id, size, msg, npe, destpes, more);
00065 }
00066
00067 void GraphRouter::sendMessages(comID id, int cur_stage){
00068 int nsteps = tp->getNumSteps(cur_stage);
00069 int nextpe = 0, npestosend = 0;
00070
00071 for(int stepcount = 0; stepcount < nsteps; stepcount ++){
00072 tp->getPesToSend(stepcount, cur_stage, npestosend, pesToSend, nextpe);
00073
00074 gmap(nextpe);
00075 ComlibPrintf("%d:sending to %d for %d pes in stage %d\n", MyPe, nextpe, npestosend, cur_stage);
00076
00077 int len;
00078 #if CMK_COMLIB_USE_VECTORIZE
00079 PTvectorlist newmsg;
00080 newmsg=PeGraph->ExtractAndVectorize(id, cur_stage + 1, npestosend,
00081 pesToSend);
00082 #else
00083 char *newmsg;
00084 newmsg=PeGraph->ExtractAndPack(id, cur_stage + 1, npestosend,
00085 pesToSend, &len);
00086 #endif
00087 #if CMK_PERSISTENT_COM
00088 if(len < PERSISTENT_BUFSIZE)
00089 if(currentIteration % 2)
00090 CmiUsePersistentHandle(&handlerArrayOdd[cur_stage], 1);
00091 else
00092 CmiUsePersistentHandle(&handlerArrayEven[cur_stage], 1);
00093 #endif
00094
00095 if (newmsg) {
00096 if(cur_stage < nstages - 2)
00097 CmiSetHandler(newmsg, CkpvAccess(RouterRecvHandle));
00098 else
00099 CmiSetHandler(newmsg, CkpvAccess(RouterProcHandle));
00100 #if CMK_COMLIB_USE_VECTORIZE
00101 CmiSyncVectorSendAndFree(nextpe, -newmsg->count, newmsg->sizes, newmsg->msgs);
00102 #else
00103 CmiSyncSendAndFree(nextpe, len, newmsg);
00104 #endif
00105 }
00106 else {
00107 SendDummyMsg(id, nextpe, cur_stage + 1);
00108 }
00109
00110 #if CMK_PERSISTENT_COM
00111 if(len < PERSISTENT_BUFSIZE)
00112 CmiUsePersistentHandle(NULL, 0);
00113 #endif
00114 }
00115 }
00116
00117 void GraphRouter::EachToManyMulticast(comID id, int size, void *msg,
00118 int numpes, int *destpes, int more)
00119 {
00120 PeGraph->InsertMsgs(numpes, destpes, size, msg);
00121 if (more) return;
00122
00123 ComlibPrintf("All messages received %d\n", MyPe);
00124 sendMessages(id, 0);
00125
00126 curStage = 1;
00127
00128 int stage_itr;
00129 for(stage_itr = curStage; stage_itr < nstages - 1; stage_itr ++){
00130 if(stageComplete[stage_itr]){
00131 sendMessages(id, stage_itr);
00132 stageComplete[stage_itr] = 0;
00133 }
00134 else break;
00135 }
00136 curStage = stage_itr;
00137 if(curStage == nstages - 1)
00138 ProcManyMsg(id, NULL);
00139 else
00140 PeGraph->ExtractAndDeliverLocalMsgs(MyPe, container);
00141 }
00142
00143 void GraphRouter::RecvManyMsg(comID id, char *msg)
00144 {
00145 int stage = 0;
00146 stage = PeGraph->UnpackAndInsert(msg);
00147
00148 recvCount[stage] ++;
00149 if (recvCount[stage] == recvExpected[stage]) {
00150 ComlibPrintf("%d recvcount=%d recvexpected = %d stage=%d\n", MyPe, recvCount[stage], recvExpected[stage], stage);
00151
00152 recvCount[stage] = 0;
00153 stageComplete[stage] = 1;
00154 }
00155
00156 int stage_itr;
00157 for(stage_itr = curStage; stage_itr < nstages - 1; stage_itr ++){
00158 if(stageComplete[stage_itr]){
00159 sendMessages(id, stage_itr);
00160 stageComplete[stage_itr] = 0;
00161 }
00162 else break;
00163 }
00164 curStage = stage_itr;
00165 if(curStage == nstages - 1)
00166 ProcManyMsg(id, NULL);
00167 else
00168 PeGraph->ExtractAndDeliverLocalMsgs(MyPe, container);
00169 }
00170
00171 void GraphRouter::DummyEP(comID id, int stage)
00172 {
00173 if(stage < nstages - 1) {
00174 recvCount[stage] ++;
00175 if (recvCount[stage] == recvExpected[stage]) {
00176 ComlibPrintf("%d DUMMY recvcount=%d recvexpected = %d\n", MyPe, recvCount[stage], recvExpected[stage]);
00177 recvCount[stage] = 0;
00178 stageComplete[stage] = 1;
00179 }
00180
00181 int stage_itr;
00182 for(stage_itr = curStage; stage_itr < nstages - 1; stage_itr ++){
00183 if(stageComplete[stage_itr]){
00184 sendMessages(id, stage_itr);
00185 stageComplete[stage] = 0;
00186 }
00187 else break;
00188 }
00189 curStage = stage_itr;
00190 if(curStage == nstages - 1)
00191 ProcManyMsg(id, NULL);
00192 else
00193 PeGraph->ExtractAndDeliverLocalMsgs(MyPe, container);
00194 }
00195 else
00196 ProcManyMsg(id, NULL);
00197 }
00198
00199 void GraphRouter:: ProcManyMsg(comID id, char *m)
00200 {
00201 int stage = nstages - 1;
00202 if(m) {
00203 PeGraph->UnpackAndInsert(m);
00204 recvCount[stage] ++;
00205 }
00206
00207 if(recvCount[stage] == recvExpected[stage]) {
00208 ComlibPrintf("%d proc many msg %d\n", MyPe, stage);
00209 stageComplete[stage] = 1;
00210 }
00211 else
00212 return;
00213
00214 if(curStage != nstages -1)
00215 return;
00216
00217 currentIteration ++;
00218 recvCount[stage] = 0;
00219 PeGraph->ExtractAndDeliverLocalMsgs(MyPe, container);
00220
00221 PeGraph->Purge();
00222 curStage = 0;
00223 Done(id);
00224 }
00225
00226 Router * newgraphobject(int n, int me, Strategy *strat)
00227 {
00228 ComlibPrintf("In create graph router \n");
00229 Router *obj = new GraphRouter(n, me, strat);
00230 return(obj);
00231 }
00232
00233 void GraphRouter :: SetMap(int *pes)
00234 {
00235 gpes=pes;
00236
00237 #if CMK_PERSISTENT_COM
00238 numNeighbors=0;
00239 neighborPeList = new int[NumPes];
00240
00241 tp->getNeighbors(numNeighbors, neighborPeList);
00242 handlerArrayOdd = new PersistentHandle[numNeighbors];
00243 handlerArrayEven = new PersistentHandle[numNeighbors];
00244
00245
00246 int pcount = 0;
00247 for (pcount = 0; pcount < numNeighbors; pcount++) {
00248 int dest = neighborPeList[pcount];
00249 gmap(dest);
00250 ComlibPrintf("%d:Creating Persistent Buffer of size %d at %d\n", MyPe,
00251 PERSISTENT_BUFSIZE, dest);
00252 handlerArrayOdd[pcount] = CmiCreatePersistent(dest,
00253 PERSISTENT_BUFSIZE);
00254 ComlibPrintf("%d:Creating Even Persistent Buffer of size %d at %d\n",
00255 MyPe, PERSISTENT_BUFSIZE, dest);
00256 handlerArrayEven[pcount] = CmiCreatePersistent(dest,
00257 PERSISTENT_BUFSIZE);
00258 }
00259 #endif
00260 }
00261