00001
00009 #include "OneTimeMulticastStrategy.h"
00010 #include "TopoManager.h"
00011 #include <string>
00012 #include <set>
00013 #include <vector>
00014 #include <list>
00015 #include <map>
00016
00017
00018
00019 using std::list;
00020 using std::set;
00021 using std::vector;
00022 using std::map;
00023
00025 #define SYNCLISTSENDANDFREE 1
00026
00027
00028 CkpvExtern(CkGroupID, cmgrID);
00029
00030 OneTimeMulticastStrategy::OneTimeMulticastStrategy()
00031 : Strategy(), CharmStrategy() {
00032
00033 setType(ARRAY_STRATEGY);
00034 }
00035
00036 OneTimeMulticastStrategy::~OneTimeMulticastStrategy() {
00037 }
00038
00039 void OneTimeMulticastStrategy::pup(PUP::er &p){
00040 Strategy::pup(p);
00041 CharmStrategy::pup(p);
00042 }
00043
00044
00046 void OneTimeMulticastStrategy::insertMessage(CharmMessageHolder *cmsg){
00047 #if DEBUG
00048 CkPrintf("[%d] OneTimeMulticastStrategy::insertMessage\n", CkMyPe());
00049 fflush(stdout);
00050 #endif
00051
00052 if(cmsg->dest_proc != IS_SECTION_MULTICAST && cmsg->sec_id == NULL) {
00053 CkAbort("OneTimeMulticastStrategy can only be used with an array section proxy");
00054 }
00055
00056
00057 envelope *env = UsrToEnv(cmsg->getCharmMessage());
00058 int npes = 1;
00059 int pes[1] = {0};
00060 _TRACE_CREATION_MULTICAST(env, npes, pes);
00061
00062 #if DEBUG
00063 CkPrintf("[%d] after TRACE_CREATION_MULTICAST menv->event=%d\n", CkMyPe(), (int)env->getEvent());
00064 #endif
00065
00066
00067 ComlibMulticastMsg * multMsg = sinfo.getNewMulticastMessage(cmsg, 0, getInstance());
00068
00069
00070 #if DEBUG
00071 CkPrintf("[%d] after TRACE_CREATION_MULTICAST multMsg->event=%d\n", CkMyPe(), (int)( UsrToEnv(multMsg)->getEvent() ) );
00072 #endif
00073
00074
00075 remoteMulticast(multMsg, true);
00076
00077
00078 localMulticast(cmsg);
00079
00080 delete cmsg;
00081 }
00082
00083
00084
00086 void OneTimeMulticastStrategy::localMulticast(CharmMessageHolder *cmsg) {
00087 double start = CmiWallTimer();
00088 CkSectionID *sec_id = cmsg->sec_id;
00089 CkVec< CkArrayIndex > localIndices;
00090 CkArrayID aid(sec_id->_cookie.get_aid());
00091 sinfo.getLocalIndices(sec_id->_nElems, sec_id->_elems, aid, localIndices);
00092 deliverToIndices(cmsg->getCharmMessage(), localIndices );
00093 traceUserBracketEvent(10000, start, CmiWallTimer());
00094 }
00095
00096
00097
00098
00099
00104 void OneTimeMulticastStrategy::remoteMulticast(ComlibMulticastMsg * multMsg, bool rootPE) {
00105 double start = CmiWallTimer();
00106
00107 envelope *env = UsrToEnv(multMsg);
00108
00109
00111 int myIndex = -10000;
00112 const int totalDestPEs = multMsg->nPes;
00113 const int myPe = CkMyPe();
00114
00115
00116 if(rootPE){
00117 CkAssert(CkMyPe() == multMsg->_cookie.get_pe());
00118 myIndex = -1;
00119 } else {
00120 for (int i=0; i<totalDestPEs; ++i) {
00121 if(multMsg->indicesCount[i].pe == myPe){
00122 myIndex = i;
00123 break;
00124 }
00125 }
00126 }
00127
00128 if(myIndex == -10000)
00129 CkAbort("My PE was not found in the list of destination PEs in the ComlibMulticastMsg");
00130
00131 int npes;
00132 int *pelist = NULL;
00133
00134 if(totalDestPEs > 0) {
00135
00136 determineNextHopPEs(totalDestPEs, multMsg->indicesCount, myIndex, multMsg->_cookie.get_pe(), pelist, npes );
00137 } else {
00138 npes = 0;
00139 }
00140
00141 if(npes == 0) {
00142 #if DEBUG
00143 CkPrintf("[%d] OneTimeMulticastStrategy::remoteMulticast is not forwarding to any other PEs\n", CkMyPe());
00144 #endif
00145 traceUserBracketEvent(10001, start, CmiWallTimer());
00146 CmiFree(env);
00147 return;
00148 }
00149
00150
00151 RECORD_SENDM_STATS(getInstance(), env->getTotalsize(), pelist, npes);
00152
00153
00154 CmiSetHandler(env, CkpvAccess(comlib_handler));
00155 ((CmiMsgHeaderExt *) env)->stratid = getInstance();
00156 CkPackMessage(&env);
00157
00158 double middle = CmiWallTimer();
00159
00160
00161
00162
00163 #if SYNCLISTSENDANDFREE
00164 CmiSyncListSendAndFree(npes, pelist, env->getTotalsize(), (char*)env);
00165 #else
00166
00167 CkAssert(npes > 0);
00168 CmiSyncListSend(npes, pelist, env->getTotalsize(), (char*)env);
00169
00170 delete[] pelist;
00171 #endif
00172
00173 double end = CmiWallTimer();
00174 traceUserBracketEvent(10001, start, middle);
00175 traceUserBracketEvent(10002, middle, end);
00176
00177 }
00178
00179
00180
00185 void OneTimeMulticastStrategy::handleMessage(void *msg){
00186 #if DEBUG
00187
00188 #endif
00189 envelope *env = (envelope *)msg;
00190 CkUnpackMessage(&env);
00191 ComlibMulticastMsg* multMsg = (ComlibMulticastMsg*)EnvToUsr(env);
00192
00193
00194
00195 RECORD_RECV_STATS(getInstance(), env->getTotalsize(), env->getSrcPe());
00196
00197
00198 int localElems;
00199 envelope *newenv;
00200 CkArrayIndex *local_idx_list;
00201 sinfo.unpack(env, localElems, local_idx_list, newenv);
00202 ComlibMulticastMsg *newmsg = (ComlibMulticastMsg *)EnvToUsr(newenv);
00203
00204
00205
00206
00207 #if SYNCLISTSENDANDFREE
00208
00209
00210 deliverToIndices(newmsg, localElems, local_idx_list );
00211
00212
00213 remoteMulticast(multMsg, false);
00214
00215 #else
00216
00217
00218 remoteMulticast(multMsg, false);
00219
00220
00221 deliverToIndices(newmsg, localElems, local_idx_list );
00222
00223
00224 CmiFree(multMsg);
00225
00226 #endif
00227
00228 }
00229
00230
00231
00232
00233 void OneTimeMulticastStrategy::determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, const int rootPE, int * &pelist, int &npes) {
00234 if(myIndex==-1){
00235
00236
00237 npes = totalDestPEs;
00238
00239 pelist = new int[npes];
00240 for (int i=0; i<npes; ++i) {
00241 pelist[i] = destPEs[i].pe;
00242 }
00243 } else {
00244
00245 npes = 0;
00246 }
00247
00248 }
00249
00250
00251 void OneTimeRingMulticastStrategy::determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, const int rootPE, int * &pelist, int &npes) {
00252 const int myPe = CkMyPe();
00253
00254 if(myIndex == totalDestPEs-1){
00255
00256 npes = 0;
00257 return;
00258 } else {
00259
00260 npes = 1;
00261 pelist = new int[1];
00262 pelist[0] = destPEs[myIndex+1].pe;
00263 }
00264
00265 }
00266
00267
00268 void OneTimeTreeMulticastStrategy::determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, const int rootPE, int * &pelist, int &npes){
00269 const int myPe = CkMyPe();
00270
00271
00272
00273 int sendLogicalIndexStart = degree*(myIndex+1) + 1;
00274 int sendLogicalIndexEnd = sendLogicalIndexStart + degree - 1;
00275
00276 if(sendLogicalIndexEnd-1 >= totalDestPEs){
00277 sendLogicalIndexEnd = totalDestPEs;
00278 }
00279
00280 int numSend = sendLogicalIndexEnd - sendLogicalIndexStart + 1;
00281 if(numSend <= 0){
00282 npes = 0;
00283 return;
00284 }
00285
00286 #if DEBUG
00287 if(numSend > 0)
00288 CkPrintf("Tree logical index %d sending to logical %d to %d (totalDestPEs excluding root=%d) numSend=%d\n",
00289 myIndex+1, sendLogicalIndexStart, sendLogicalIndexEnd, totalDestPEs, numSend);
00290 #endif
00291
00292 npes = numSend;
00293 pelist = new int[npes];
00294
00295 for(int i=0;i<numSend;i++){
00296 CkAssert(sendLogicalIndexStart-1+i < totalDestPEs);
00297 pelist[i] = destPEs[sendLogicalIndexStart-1+i].pe;
00298 #if DEBUG
00299 CkPrintf("Tree logical index %d sending to PE %d\n", myIndex+1, pelist[i]);
00300 #endif
00301 CkAssert(pelist[i] < CkNumPes());
00302 }
00303
00304 }
00305
00306
00308 int getFirstPeOnPhysicalNodeFromList(int pe, const int totalDestPEs, const ComlibMulticastIndexCount* destPEs){
00309 int num;
00310 int *nodePeList;
00311 CmiGetPesOnPhysicalNode(CmiPhysicalNodeID(pe), &nodePeList, &num);
00312
00313 for(int i=0;i<num;i++){
00314
00315 int p = nodePeList[i];
00316
00317 for(int j=0;j<totalDestPEs;j++){
00318 if(p == destPEs[j].pe){
00319
00320 return p;
00321 }
00322 }
00323 }
00324
00325 CkAbort("ERROR: Could not find an entry for pe in destPEs list.\n");
00326 return -1;
00327 }
00328
00329
00331 int getNthPeOnPhysicalNodeFromList(int n, int pe, const int totalDestPEs, const ComlibMulticastIndexCount* destPEs){
00332 int num;
00333 int *nodePeList;
00334 CmiGetPesOnPhysicalNode(CmiPhysicalNodeID(pe), &nodePeList, &num);
00335
00336 int count = 0;
00337 int lastFound = -1;
00338
00339
00340 for(int i=0;i<num;i++){
00341 int p = nodePeList[i];
00342
00343
00344 for(int j=0;j<totalDestPEs;j++){
00345 if(p == destPEs[j].pe){
00346 lastFound = p;
00347 if(count==n)
00348 return p;
00349 count++;
00350 }
00351 }
00352 }
00353
00354 if(lastFound != -1)
00355 return lastFound;
00356
00357 CkAbort("ERROR: Could not find an entry for pe in destPEs list.\n");
00358 return -1;
00359 }
00360
00361
00363 vector<int> getPesOnPhysicalNodeFromList(int pe, const int totalDestPEs, const ComlibMulticastIndexCount* destPEs){
00364
00365 vector<int> result;
00366
00367 int num;
00368 int *nodePeList;
00369 CmiGetPesOnPhysicalNode(CmiPhysicalNodeID(pe), &nodePeList, &num);
00370
00371 for(int i=0;i<num;i++){
00372
00373 int p = nodePeList[i];
00374 for(int j=0;j<totalDestPEs;j++){
00375 if(p == destPEs[j].pe){
00376
00377
00378 result.push_back(p);
00379 break;
00380 }
00381 }
00382 }
00383
00384 return result;
00385 }
00386
00387
00388
00390 vector<int> getOtherPesOnPhysicalNodeFromList(int pe, const int totalDestPEs, const ComlibMulticastIndexCount* destPEs){
00391
00392 vector<int> result;
00393
00394 int num;
00395 int *nodePeList;
00396 CmiGetPesOnPhysicalNode(CmiPhysicalNodeID(pe), &nodePeList, &num);
00397
00398 for(int i=0;i<num;i++){
00399
00400 int p = nodePeList[i];
00401 if(p != pe){
00402 for(int j=0;j<totalDestPEs;j++){
00403 if(p == destPEs[j].pe){
00404
00405 result.push_back(p);
00406 break;
00407 }
00408 }
00409 }
00410 }
00411
00412 return result;
00413 }
00414
00415
00416 void OneTimeNodeTreeMulticastStrategy::determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, const int rootPE, int * &pelist, int &npes){
00417 const int myPe = CkMyPe();
00418
00419 set<int> nodePERepresentatives;
00420
00421
00422 for(int i=0; i<totalDestPEs; i++){
00423 int pe = destPEs[i].pe;
00424 int representative = getFirstPeOnPhysicalNodeFromList(pe, totalDestPEs, destPEs);
00425 nodePERepresentatives.insert(representative);
00426 }
00427
00428
00429
00430 set<int>::iterator splitter = nodePERepresentatives.upper_bound(rootPE);
00431 vector<int> nodePERepresentativesOrdered;
00432 for(set<int>::iterator iter = splitter; iter!=nodePERepresentatives.end(); ++iter){
00433 nodePERepresentativesOrdered.push_back(*iter);
00434 }
00435 for(set<int>::iterator iter = nodePERepresentatives.begin(); iter!=splitter; ++iter){
00436 nodePERepresentativesOrdered.push_back(*iter);
00437 }
00438
00439 CkAssert(nodePERepresentativesOrdered.size() == nodePERepresentatives.size());
00440
00441 int numRepresentativePEs = nodePERepresentatives.size();
00442
00443 int repForMyPe=-1;
00444 if(myIndex != -1)
00445 repForMyPe = getFirstPeOnPhysicalNodeFromList(CkMyPe(), totalDestPEs, destPEs);
00446
00447 #if DEBUG
00448 CkPrintf("[%d] Multicasting to %d PEs on %d physical nodes repForMyPe=%d\n", CkMyPe(), totalDestPEs, numRepresentativePEs, repForMyPe);
00449 fflush(stdout);
00450 #endif
00451
00452
00453 if(CkMyPe() == repForMyPe || myIndex == -1){
00454
00455
00456
00457 int *repPeList = new int[numRepresentativePEs];
00458 int myRepIndex = -1;
00459 int p=0;
00460 for(vector<int>::iterator iter=nodePERepresentativesOrdered.begin(); iter != nodePERepresentativesOrdered.end(); iter++){
00461 repPeList[p] = *iter;
00462 if(*iter == repForMyPe)
00463 myRepIndex = p;
00464 p++;
00465 }
00466 CkAssert(myRepIndex >=0 || myIndex==-1);
00467
00468
00469 int sendLogicalIndexStart = degree*(myRepIndex+1) + 1;
00470 int sendLogicalIndexEnd = sendLogicalIndexStart + degree - 1;
00471
00472 if(sendLogicalIndexEnd-1 >= numRepresentativePEs){
00473 sendLogicalIndexEnd = numRepresentativePEs;
00474 }
00475
00476 int numSendTree = sendLogicalIndexEnd - sendLogicalIndexStart + 1;
00477 if(numSendTree < 0)
00478 numSendTree = 0;
00479
00480 vector<int> otherLocalPes = getOtherPesOnPhysicalNodeFromList(CkMyPe(), totalDestPEs, destPEs);
00481 int numSendLocal;
00482 if(myIndex == -1)
00483 numSendLocal = 0;
00484 else
00485 numSendLocal = otherLocalPes.size();
00486
00487
00488
00489 #if DEBUG
00490 CkPrintf("[%d] numSendTree=%d numSendLocal=%d sendLogicalIndexStart=%d sendLogicalIndexEnd=%d\n", CkMyPe(), numSendTree, numSendLocal, sendLogicalIndexStart, sendLogicalIndexEnd);
00491 fflush(stdout);
00492 #endif
00493
00494 int numSend = numSendTree + numSendLocal;
00495 if(numSend <= 0){
00496 npes = 0;
00497 return;
00498 }
00499
00500 npes = numSend;
00501 pelist = new int[npes];
00502
00503 for(int i=0;i<numSendTree;i++){
00504 CkAssert(sendLogicalIndexStart-1+i < numRepresentativePEs);
00505 pelist[i] = repPeList[sendLogicalIndexStart-1+i];
00506 CkAssert(pelist[i] < CkNumPes() && pelist[i] >= 0);
00507 }
00508
00509 delete[] repPeList;
00510 repPeList = NULL;
00511
00512 for(int i=0;i<numSendLocal;i++){
00513 pelist[i+numSendTree] = otherLocalPes[i];
00514 CkAssert(pelist[i] < CkNumPes() && pelist[i] >= 0);
00515 }
00516
00517
00518 #if DEBUG
00519 char buf[1024];
00520 sprintf(buf, "PE %d is sending to Remote Node PEs: ", CkMyPe() );
00521 for(int i=0;i<numSend;i++){
00522 if(i==numSendTree)
00523 sprintf(buf+strlen(buf), " and Local To Node PEs: ", pelist[i]);
00524
00525 sprintf(buf+strlen(buf), "%d ", pelist[i]);
00526 }
00527 CkPrintf("%s\n", buf);
00528 fflush(stdout);
00529 #endif
00530
00531 } else {
00532
00533 npes = 0;
00534 return;
00535 }
00536
00537
00538
00539 }
00540
00541
00542 void OneTimeNodeTreeRingMulticastStrategy::determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, const int rootPE, int * &pelist, int &npes){
00543 const int myPe = CkMyPe();
00544
00545 set<int> nodePERepresentatives;
00546
00547
00548 for(int i=0; i<totalDestPEs; i++){
00549 int pe = destPEs[i].pe;
00550 int representative = getFirstPeOnPhysicalNodeFromList(pe, totalDestPEs, destPEs);
00551 nodePERepresentatives.insert(representative);
00552 }
00553
00554
00555
00556 set<int>::iterator splitter = nodePERepresentatives.upper_bound(rootPE);
00557 vector<int> nodePERepresentativesOrdered;
00558 for(set<int>::iterator iter = splitter; iter!=nodePERepresentatives.end(); ++iter){
00559 nodePERepresentativesOrdered.push_back(*iter);
00560 }
00561 for(set<int>::iterator iter = nodePERepresentatives.begin(); iter!=splitter; ++iter){
00562 nodePERepresentativesOrdered.push_back(*iter);
00563 }
00564
00565 CkAssert(nodePERepresentativesOrdered.size() == nodePERepresentatives.size());
00566 int numRepresentativePEs = nodePERepresentatives.size();
00567
00568 int repForMyPe=-1;
00569 if(myIndex != -1)
00570 repForMyPe = getFirstPeOnPhysicalNodeFromList(CkMyPe(), totalDestPEs, destPEs);
00571
00572 #if DEBUG
00573 CkPrintf("[%d] Multicasting to %d PEs on %d physical nodes repForMyPe=%d\n", CkMyPe(), totalDestPEs, numRepresentativePEs, repForMyPe);
00574 fflush(stdout);
00575 #endif
00576
00577
00578 if(CkMyPe() == repForMyPe || myIndex == -1){
00579
00580
00581
00582 int *repPeList = new int[numRepresentativePEs];
00583 int myRepIndex = -1;
00584 int p=0;
00585 for(vector<int>::iterator iter=nodePERepresentativesOrdered.begin(); iter != nodePERepresentativesOrdered.end(); iter++){
00586 repPeList[p] = *iter;
00587 if(*iter == repForMyPe)
00588 myRepIndex = p;
00589 p++;
00590 }
00591 CkAssert(myRepIndex >=0 || myIndex==-1);
00592
00593
00594 int sendLogicalIndexStart = degree*(myRepIndex+1) + 1;
00595 int sendLogicalIndexEnd = sendLogicalIndexStart + degree - 1;
00596
00597 if(sendLogicalIndexEnd-1 >= numRepresentativePEs){
00598 sendLogicalIndexEnd = numRepresentativePEs;
00599 }
00600
00601 int numSendTree = sendLogicalIndexEnd - sendLogicalIndexStart + 1;
00602 if(numSendTree < 0)
00603 numSendTree = 0;
00604
00605
00606
00607 vector<int> otherLocalPes = getOtherPesOnPhysicalNodeFromList(CkMyPe(), totalDestPEs, destPEs);
00608 int numSendLocal = 0;
00609 if(myIndex == -1)
00610 numSendLocal = 0;
00611 else {
00612 if(otherLocalPes.size() > 0)
00613 numSendLocal = 1;
00614 else
00615 numSendLocal = 0;
00616 }
00617
00618
00619 #if DEBUG
00620 CkPrintf("[%d] numSendTree=%d numSendLocal=%d sendLogicalIndexStart=%d sendLogicalIndexEnd=%d\n", CkMyPe(), numSendTree, numSendLocal, sendLogicalIndexStart, sendLogicalIndexEnd);
00621 fflush(stdout);
00622 #endif
00623
00624 int numSend = numSendTree + numSendLocal;
00625 if(numSend <= 0){
00626 npes = 0;
00627 return;
00628 }
00629
00630 npes = numSend;
00631 pelist = new int[npes];
00632
00633 for(int i=0;i<numSendTree;i++){
00634 CkAssert(sendLogicalIndexStart-1+i < numRepresentativePEs);
00635 pelist[i] = repPeList[sendLogicalIndexStart-1+i];
00636 CkAssert(pelist[i] < CkNumPes() && pelist[i] >= 0);
00637 }
00638
00639 delete[] repPeList;
00640 repPeList = NULL;
00641
00642 for(int i=0;i<numSendLocal;i++){
00643 pelist[i+numSendTree] = otherLocalPes[i];
00644 CkAssert(pelist[i] < CkNumPes() && pelist[i] >= 0);
00645 }
00646
00647
00648 #if DEBUG
00649 char buf[1024];
00650 sprintf(buf, "PE %d is sending to Remote Node PEs: ", CkMyPe() );
00651 for(int i=0;i<numSend;i++){
00652 if(i==numSendTree)
00653 sprintf(buf+strlen(buf), " and Local To Node PEs: ", pelist[i]);
00654
00655 sprintf(buf+strlen(buf), "%d ", pelist[i]);
00656 }
00657 CkPrintf("%s\n", buf);
00658 fflush(stdout);
00659 #endif
00660
00661 } else {
00662
00663 const vector<int> otherLocalPes = getPesOnPhysicalNodeFromList(CkMyPe(), totalDestPEs, destPEs);
00664
00665 npes = 0;
00666 pelist = new int[1];
00667
00668
00669 const int numOthers = otherLocalPes.size() ;
00670
00671 for(int i=0;i<numOthers;i++){
00672 if(otherLocalPes[i] == CkMyPe()){
00673
00674 if(i+1<otherLocalPes.size()){
00675
00676 pelist[0] = otherLocalPes[i+1];
00677 npes = 1;
00678 }
00679 }
00680 }
00681
00682
00683 #if DEBUG
00684 if(npes==0)
00685 CkPrintf("[%d] At end of ring\n", CkMyPe() );
00686 else
00687 CkPrintf("[%d] sending along ring to %d\n", CkMyPe(), pelist[0] );
00688
00689 fflush(stdout);
00690 #endif
00691
00692
00693 }
00694
00695
00696
00697 }
00698
00699
00700
00701 int OneTimeDimensionOrderedMulticastStrategy::findMinMaxArray(int min, int len, int *array, bool* notincluded, int value) {
00702 int k = value;
00703 int a = -1;
00704 for (int j = 0; j < len; j++) {
00705 if (notincluded[j]) continue;
00706 if (min && array[j] < k) {
00707 k = array[j];
00708 a = j;
00709 } else if (!min && array[j] > k) {
00710 k = array[j];
00711 a = j;
00712 }
00713 }
00714 return a;
00715 }
00716
00717 void OneTimeDimensionOrderedMulticastStrategy::determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, const int rootPe, int * &pelist, int &npes) {
00718 const int myPe = CkMyPe();
00719
00720 set<int> nodePEReps;
00721
00722
00723 for(int i=0; i<totalDestPEs; i++){
00724 int pe = destPEs[i].pe;
00725 CkAssert(pe != rootPe);
00726 if (myPe == 0)
00727 CkPrintf("destPE = %d\n", pe);
00728 int rep = getFirstPeOnPhysicalNodeFromList(pe, totalDestPEs, destPEs);
00729 nodePEReps.insert(rep);
00730 }
00731
00732 int numRepPEs = nodePEReps.size();
00733
00734 int repForMyPe = -1;
00735 if(myIndex != -1)
00736 repForMyPe = getFirstPeOnPhysicalNodeFromList(CkMyPe(), totalDestPEs, destPEs);
00737
00738 map<int, set<int> > spanTree;
00739
00740 TopoManager tmgr;
00741
00742 int myX, myY, myZ, myT;
00743 tmgr.rankToCoordinates(rootPe, myX, myY, myZ, myT);
00744
00745 map<int, int> peRef;
00746 int *repPeRef = new int[numRepPEs+1];
00747 int *repPeX = new int[numRepPEs+1];
00748 int *repPeY = new int[numRepPEs+1];
00749 int *repPeZ = new int[numRepPEs+1];
00750
00751 int i = 0, myRepIndex;
00752
00753 for (set<int>::iterator iter = nodePEReps.begin(); iter != nodePEReps.end(); ++iter) {
00754 int pe = *iter;
00755 repPeRef[i] = pe;
00756 peRef[pe] = i;
00757 int t;
00758 tmgr.rankToCoordinates(pe, repPeX[i], repPeY[i], repPeZ[i], t);
00759 if (*iter == repForMyPe)
00760 myRepIndex = i;
00761 i++;
00762 }
00763
00764 int t;
00765 repPeRef[i] = rootPe;
00766 peRef[rootPe] = i;
00767 tmgr.rankToCoordinates(rootPe, repPeX[i], repPeY[i], repPeZ[i], t);
00768
00769 CkAssert(myRepIndex >= 0 || myIndex == -1);
00770
00771 bool *destAdded = new bool[numRepPEs];
00772
00773 for (int i = 0; i < numRepPEs; i++)
00774 destAdded[i] = false;
00775
00776 int mode = 0;
00777
00778 spanTree[rootPe].insert(rootPe);
00779
00780
00781
00782 while (spanTree.size() < numRepPEs+1) {
00783 int k = 0;
00784 for (int i = 0; i < numRepPEs; i++) {
00785 if (destAdded[i])
00786 k++;
00787 }
00788
00789
00790
00791 for(map<int, set<int> >::iterator iter = spanTree.begin(); iter != spanTree.end(); ++iter) {
00792 int pe = iter->first;
00793 int iPe = peRef[pe];
00794 if (mode % 4 == 0) {
00795
00796 int i1 = findMinMaxArray(1, numRepPEs, repPeX, destAdded, repPeX[iPe]);
00797
00798 if (i1 != -1) {
00799 destAdded[i1] = true;
00800 spanTree[pe].insert(repPeRef[i1]);
00801 spanTree[repPeRef[i1]].insert(repPeRef[i1]);
00802
00803 }
00804
00805
00806 int i2 = findMinMaxArray(0, numRepPEs, repPeX, destAdded, repPeX[iPe]);
00807
00808 if (i2 != -1) {
00809 destAdded[i2] = true;
00810 spanTree[pe].insert(repPeRef[i2]);
00811 spanTree[repPeRef[i2]].insert(repPeRef[i2]);
00812
00813 }
00814 } else if (mode % 4 == 1) {
00815 bool* notEqX = new bool[numRepPEs];
00816 for (int i = 0; i < numRepPEs; i++) {
00817 notEqX[i] = destAdded[i];
00818 if (!destAdded[i] && repPeX[iPe] != repPeX[i])
00819 notEqX[i] = true;
00820 }
00821
00822
00823 int i1 = findMinMaxArray(1, numRepPEs, repPeY, notEqX, repPeY[iPe]);
00824
00825 if (i1 != -1) {
00826 destAdded[i1] = true;
00827 spanTree[pe].insert(repPeRef[i1]);
00828 spanTree[repPeRef[i1]].insert(repPeRef[i1]);
00829
00830 }
00831
00832
00833 int i2 = findMinMaxArray(0, numRepPEs, repPeY, notEqX, repPeY[iPe]);
00834
00835 if (i2 != -1) {
00836 destAdded[i2] = true;
00837 spanTree[pe].insert(repPeRef[i2]);
00838 spanTree[repPeRef[i2]].insert(repPeRef[i2]);
00839
00840 }
00841
00842 delete[] notEqX;
00843 } else if (mode % 4 == 2) {
00844 bool* notEqXY = new bool[numRepPEs];
00845 for (int i = 0; i < numRepPEs; i++) {
00846 notEqXY[i] = destAdded[i];
00847 if (!destAdded[i] && (repPeX[iPe] != repPeX[i] || repPeY[iPe] != repPeY[i]))
00848 notEqXY[i] = true;
00849 }
00850
00851
00852 int i1 = findMinMaxArray(1, numRepPEs, repPeZ, notEqXY, repPeZ[iPe]);
00853
00854 if (i1 != -1) {
00855 destAdded[i1] = true;
00856 spanTree[pe].insert(repPeRef[i1]);
00857 spanTree[repPeRef[i1]].insert(repPeRef[i1]);
00858
00859 }
00860
00861
00862 int i2 = findMinMaxArray(0, numRepPEs, repPeZ, notEqXY, repPeZ[iPe]);
00863
00864 if (i2 != -1) {
00865 destAdded[i2] = true;
00866 spanTree[pe].insert(repPeRef[i2]);
00867 spanTree[repPeRef[i2]].insert(repPeRef[i2]);
00868
00869 }
00870
00871 delete[] notEqXY;
00872 }
00873 }
00874 mode++;
00875 }
00876
00877
00878
00879 static bool firstTime = true;
00880
00881 if (myPe == 0 && firstTime) {
00882 firstTime = false;
00883 for(map<int, set<int> >::iterator iter = spanTree.begin(); iter != spanTree.end(); ++iter) {
00884 CkPrintf("Map %d to: ", iter->first);
00885 for(set<int>::iterator iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2) {
00886 CkPrintf("%d, ", *iter2);
00887 }
00888 CkPrintf("\n");
00889 }
00890 }
00891
00892
00893 vector<int> otherLocalPes = getOtherPesOnPhysicalNodeFromList(CkMyPe(), totalDestPEs, destPEs);
00894 int numSendLocal = otherLocalPes.size();
00895
00896 int numSend = spanTree[myPe].size() > 0 ? spanTree[myPe].size()-1 + numSendLocal : numSendLocal;
00897
00898 if(numSend <= 0) {
00899 npes = 0;
00900 return;
00901 }
00902
00903
00904
00905 npes = numSend;
00906 pelist = new int[npes];
00907
00908 i = 0;
00909
00910 for (set<int>::iterator iter = spanTree[myPe].begin(); iter != spanTree[myPe].end(); ++iter) {
00911 if (*iter != myPe) {
00912 pelist[i] = *iter;
00913 i++;
00914 }
00915 }
00916
00917 for(int j = 0; j < numSendLocal; j++){
00918 pelist[i] = otherLocalPes[j];
00919 i++;
00920 }
00921 }
00922
00923 #include "spanningTreeStrategy.h"
00924
00925 using namespace topo;
00926
00927 void OneTimeTopoTreeMulticastStrategy::determineNextHopPEs(const int totalDestPEs, const ComlibMulticastIndexCount* destPEs, const int myIndex, const int rootPE, int * &pelist, int &npes)
00928 {
00930 npes = 0;
00931 int myPE = (myIndex<0)? rootPE : destPEs[myIndex].pe;
00932
00934 std::vector<topo::SpanningTreeVertex> tree;
00935 tree.push_back( topo::SpanningTreeVertex(rootPE) );
00936 for (int i=0; i< totalDestPEs; i++)
00937 tree.push_back( topo::SpanningTreeVertex(destPEs[i].pe) );
00938
00940 topo::buildSpanningTree(tree.begin(),tree.end(),degree);
00941
00943 int peIdx = -1;
00944 bool noMatchFound = true;
00945 while ( (++peIdx < tree.size()) && noMatchFound)
00946 {
00947 if (myPE == tree[peIdx].id)
00948 {
00950 npes = tree[peIdx].childIndex.size();
00951 pelist = new int[npes];
00952 for (int i=0; i< npes; i++)
00953 pelist[i] = tree[ peIdx + tree[peIdx].childIndex[i] ].id;
00954 noMatchFound = false;
00955 }
00956 }
00957 }
00958