00001
00005
00006 #include <math.h>
00007
00008
00009 #include <vector>
00010 #include "converse.h"
00011 #include "topology.h"
00012
00013 extern char *_lbtopo;
00014
00015 int LBTopology::get_hop_count(int src,int dest)
00016 {
00017 int npe;
00018 int *visited_srcs;
00019
00020 if(src==dest)
00021 return 0;
00022
00023 npe = max_neighbors();
00024 visited_srcs = new int[npes];
00025
00026 int count = rec_hop_count(src,dest,npe,1,visited_srcs,999999);
00027 delete [] visited_srcs;
00028
00029 return count;
00030 }
00031
00032 int LBTopology::rec_hop_count(int src,int dest,int max_neigh,int count,int *visited_srcs,int min_hop_cnt)
00033 {
00034 int *pes = new int[max_neigh];
00035
00036 int ret_val=0;
00037 int skip_neigh=0;
00038 int neigh_cnt=0;
00039 int i;
00040
00041 neighbors(src,pes,neigh_cnt);
00042
00043 visited_srcs[count-1]=src;
00044
00045 for(i=0;i<neigh_cnt;i++)
00046 {
00047 if(pes[i]==dest)
00048 return count;
00049 }
00050 for(i=0;i<neigh_cnt;i++)
00051 {
00052 for(int j=0;j<count;j++)
00053 if(visited_srcs[j]==pes[i])
00054 {
00055 skip_neigh=1;
00056 break;
00057 }
00058 if(!skip_neigh)
00059 {
00060 if(min_hop_cnt > count+1){
00061 ret_val=rec_hop_count(pes[i],dest,max_neigh,count+1,visited_srcs,min_hop_cnt);
00062 if(ret_val < min_hop_cnt)
00063 min_hop_cnt = ret_val;
00064 }
00065 }
00066 else
00067 skip_neigh=0;
00068 }
00069 delete [] pes;
00070 return min_hop_cnt;
00071 }
00072
00073 double LBTopology::per_hop_delay(int last_hop)
00074 {
00075 if(!last_hop)
00076 return (HOP_LINK_DELAY + HOP_PROC_DELAY);
00077 else
00078 return HOP_LINK_DELAY;
00079 }
00080
00081 void LBTopology::get_pairwise_hop_count(double **distance)
00082 {
00083 struct queueNode
00084 {
00085 int index;
00086 int dist;
00087 queueNode *next;
00088 queueNode(int i,int d): index(i), dist(d), next(NULL) {}
00089 };
00090
00091 bool *visited=new bool[npes];
00092 int *neigh=new int[max_neighbors()];
00093 int num_neighbors;
00094
00095 for(int i=0;i<npes;i++)
00096 {
00097
00098 for(int j=0;j<npes;j++)
00099 visited[j]=false;
00100
00101 queueNode *q=new queueNode(i,0);
00102 queueNode *last=q;
00103 distance[i][i]=0;
00104 visited[i]=true;
00105
00106
00107 while(q)
00108 {
00109 neighbors(q->index,neigh,num_neighbors);
00110 for(int j=0;j<num_neighbors;j++)
00111 {
00112 if(!visited[neigh[j]])
00113 {
00114 visited[neigh[j]]=true;
00115 distance[i][neigh[j]]=q->dist+1;
00116 queueNode *qnew=new queueNode(neigh[j],q->dist+1);
00117 last->next=qnew;
00118 last=last->next;
00119 }
00120 }
00121 queueNode *qtemp=q;
00122 q=q->next;
00123 delete qtemp;
00124 }
00125 }
00126 delete[] visited;
00127 delete[] neigh;
00128 }
00129
00130
00131
00132 template <int ppn>
00133 class LBTopo_smp_n: public LBTopology {
00134 public:
00135 LBTopo_smp_n(int p): LBTopology(p) {}
00136 virtual int max_neighbors() { return npes - 1; }
00137
00138 virtual void neighbors(int mype, int* _n, int &nb){
00139 nb = 0;
00140 for(int i=1; i<=ppn; i++)
00141 {
00142 _n[nb++] = (mype+i)%npes;
00143 }
00144 }
00145
00146 int get_hop_count(int src,int dest){
00147
00148
00149 int a = src/ppn;
00150 int b = dest/ppn;
00151
00152 if(a!=b){
00153
00154 return 2;
00155 }
00156 else{
00157
00158 return 1;
00159 }
00160 }
00161 };
00162
00163 typedef LBTopo_smp_n<1> LBTopo_smp_n_1;
00164 typedef LBTopo_smp_n<2> LBTopo_smp_n_2;
00165 typedef LBTopo_smp_n<3> LBTopo_smp_n_3;
00166 typedef LBTopo_smp_n<4> LBTopo_smp_n_4;
00167 typedef LBTopo_smp_n<5> LBTopo_smp_n_5;
00168 typedef LBTopo_smp_n<6> LBTopo_smp_n_6;
00169 typedef LBTopo_smp_n<7> LBTopo_smp_n_7;
00170 typedef LBTopo_smp_n<8> LBTopo_smp_n_8;
00171 typedef LBTopo_smp_n<9> LBTopo_smp_n_9;
00172 typedef LBTopo_smp_n<10> LBTopo_smp_n_10;
00173
00174 LBTOPO_MACRO(LBTopo_smp_n_1)
00175 LBTOPO_MACRO(LBTopo_smp_n_2)
00176 LBTOPO_MACRO(LBTopo_smp_n_3)
00177 LBTOPO_MACRO(LBTopo_smp_n_4)
00178 LBTOPO_MACRO(LBTopo_smp_n_5)
00179 LBTOPO_MACRO(LBTopo_smp_n_6)
00180 LBTOPO_MACRO(LBTopo_smp_n_7)
00181 LBTOPO_MACRO(LBTopo_smp_n_8)
00182 LBTOPO_MACRO(LBTopo_smp_n_9)
00183 LBTOPO_MACRO(LBTopo_smp_n_10)
00184
00185
00186
00187
00188 LBTOPO_MACRO(LBTopo_ring)
00189
00190 int LBTopo_ring::max_neighbors()
00191 {
00192 if (npes > 2) return 2;
00193 else return (npes-1);
00194 }
00195
00196 void LBTopo_ring::neighbors(int mype, int* _n, int &nb)
00197 {
00198 nb = 0;
00199 if (npes>1) _n[nb++] = (mype + npes -1) % npes;
00200 if (npes>2) _n[nb++] = (mype + 1) % npes;
00201 }
00202
00203 int LBTopo_ring::get_hop_count(int src,int dest){
00204
00205 int dist=src-dest;
00206 if(dist<0) dist=-dist;
00207
00208 if((npes-dist) < dist)
00209 return (npes-dist);
00210 else
00211 return dist;
00212 }
00213
00214
00215
00216 LBTOPO_MACRO(LBTopo_torus2d)
00217
00218 LBTopo_torus2d::LBTopo_torus2d(int p): LBTopology(p)
00219 {
00220 width = (int)sqrt(p*1.0);
00221 if (width * width < npes) width++;
00222 }
00223
00224 int LBTopo_torus2d::max_neighbors()
00225 {
00226 return 4;
00227 }
00228
00229 int LBTopo_torus2d::goodcoor(int x, int y)
00230 {
00231 if (x<0 || x>=width) return -1;
00232 if (y<0 || y>=width) return -1;
00233 int next = x*width + y;
00234 if (next<npes && next>=0) return next;
00235 return -1;
00236 }
00237
00238 static int checkuniq(int *arr, int nb, int val) {
00239 for (int i=0;i<nb;i++) if (arr[i]==val) return 0;
00240 return 1;
00241 }
00242
00243 void LBTopo_torus2d::neighbors(int mype, int* _n, int &nb)
00244 {
00245 int next;
00246 int x = mype/width;
00247 int y = mype%width;
00248 nb=0;
00249 for (int i=-1; i<=1; i+=2) {
00250 int x1 = x+i;
00251 if (x1 == -1) {
00252 x1 = width-1;
00253 while (goodcoor(x1, y)==-1) x1--;
00254 }
00255 else if (goodcoor(x1, y) == -1) x1=0;
00256 next = goodcoor(x1, y);
00257 CmiAssert(next != -1);
00258 if (next != mype && checkuniq(_n, nb, next)) _n[nb++] = next;
00259
00260 int y1 = y+i;
00261 if (y1 == -1) {
00262 y1 = width-1;
00263 while (goodcoor(x, y1)==-1) y1--;
00264 }
00265 else if (goodcoor(x, y1) == -1) y1=0;
00266 next = goodcoor(x, y1);
00267 CmiAssert(next != -1);
00268 if (next != mype && checkuniq(_n, nb, next)) _n[nb++] = next;
00269 }
00270 }
00271
00272 int LBTopo_torus2d::get_hop_count(int src,int dest){
00273 int xpos_src,xpos_dest;
00274 int ypos_src,ypos_dest;
00275 int xdist=0;
00276 int ydist=0;
00277
00278 int xchange;
00279 if(src > dest){
00280 xchange = src;
00281 src = dest;
00282 dest = xchange;
00283 }
00284
00285 xpos_src=src%width;
00286 ypos_src=src/width;
00287
00288 xpos_dest=dest%width;
00289 ypos_dest=dest/width;
00290
00291 xdist = xpos_dest-xpos_src;
00292 if(xdist<0) xdist=-xdist;
00293 if((width-xdist) < xdist)
00294 xdist = width-xdist;
00295
00296 ydist = ypos_dest-ypos_src;
00297 if(ydist<0) ydist=-ydist;
00298
00299 int lastpos=(npes-1)%width;
00300 int otherylen=0;
00301
00302 if(xpos_src<=lastpos && xpos_dest<=lastpos)
00303 otherylen=((npes-1)/width)+1-ydist;
00304 else{
00305 if(ypos_dest==((npes-1)/width))
00306 otherylen=((npes-1)/width)+1-ydist;
00307 else
00308 otherylen=((npes-1)/width)-ydist;
00309 }
00310
00311 if(otherylen < ydist)
00312 ydist=otherylen;
00313
00314
00315 int sdist=0,adist=0,bdist=0,cdist=0,ddist=0;
00316
00317 if(xpos_src>lastpos && xpos_dest>lastpos){
00318 sdist = xpos_src;
00319 if((width-sdist) < sdist)
00320 sdist = width-sdist;
00321
00322 adist = ((npes-1)/width)-ypos_src;
00323 if(adist<0) adist=-adist;
00324 if(ypos_src+1 < adist)
00325 adist = ypos_src+1;
00326
00327 bdist = 1;
00328
00329 cdist = ((npes-1)/width)-ypos_dest;
00330 if(cdist<0) cdist=-cdist;
00331 if(ypos_dest+1 < cdist)
00332 cdist = ypos_dest+1;
00333
00334 ddist = xpos_dest-lastpos;
00335 if(ddist<0) ddist=-ddist;
00336 if((width-ddist) < ddist)
00337 ddist = width-ddist;
00338 }
00339 else{
00340 if(xpos_src>lastpos){
00341 xchange = src;
00342 src = dest;
00343 dest = xchange;
00344 xpos_src=src%width;
00345 ypos_src=src/width;
00346 xpos_dest=dest%width;
00347 ypos_dest=dest/width;
00348 }
00349 adist = ((npes-1)/width)-ypos_src;
00350 if(adist<0) adist=-adist;
00351 if(ypos_src+1 < adist)
00352 adist = ypos_src+1;
00353
00354 if(xpos_dest<=lastpos){
00355 bdist = xpos_dest-xpos_src;
00356 if(bdist<0) bdist=-bdist;
00357 if((lastpos+1-bdist) < bdist)
00358 bdist = lastpos+1-bdist;
00359
00360 cdist = ((npes-1)/width)-ypos_dest;
00361 if(cdist<0) cdist=-cdist;
00362 if(ypos_dest+1 < cdist)
00363 cdist = ypos_dest+1;
00364
00365 ddist=0;
00366 }
00367 else{
00368 bdist = lastpos-xpos_src;
00369 if(bdist<0) bdist=-bdist;
00370 if((xpos_src+1) < bdist)
00371 bdist = xpos_src+1;
00372
00373 cdist = ((npes-1)/width)-ypos_dest;
00374 if(cdist<0) cdist=-cdist;
00375 if(ypos_dest+1 < cdist)
00376 cdist = ypos_dest+1;
00377
00378 ddist = xpos_dest-lastpos;
00379 if(ddist<0) ddist=-ddist;
00380 if((width-ddist) < ddist)
00381 ddist = width-ddist;
00382 }
00383 }
00384
00385 if((sdist+adist+bdist+cdist+ddist) < (xdist+ydist))
00386 return (sdist+adist+bdist+cdist+ddist);
00387 else
00388 return (xdist+ydist);
00389
00390 }
00391
00392
00393
00394 LBTOPO_MACRO(LBTopo_torus3d)
00395
00396 LBTopo_torus3d::LBTopo_torus3d(int p): LBTopology(p)
00397 {
00398 width = 1;
00399 while ( (width+1) * (width+1) * (width+1) <= npes) width++;
00400 if (width * width * width < npes) width++;
00401 }
00402
00403 int LBTopo_torus3d::max_neighbors()
00404 {
00405 return 6;
00406 }
00407
00408 int LBTopo_torus3d::goodcoor(int x, int y, int z)
00409 {
00410 if (x<0 || x>=width) return -1;
00411 if (y<0 || y>=width) return -1;
00412 if (z<0 || z>=width) return -1;
00413 int next = x*width*width + y*width + z;
00414 if (next<npes && next>=0) return next;
00415 return -1;
00416 }
00417
00418 void LBTopo_torus3d::neighbors(int mype, int* _n, int &nb)
00419 {
00420
00421 int x = mype/(width*width);
00422 int k = mype%(width*width);
00423 int y = k/width;
00424 int z = k%width;
00425 int next;
00426 nb=0;
00427 for (int i=-1; i<=1; i+=2) {
00428 int x1 = x+i;
00429 if (x1 == -1) {
00430 x1 = width-1;
00431 while (goodcoor(x1, y, z)==-1) x1--;
00432 }
00433 else if (goodcoor(x1, y, z) == -1) x1=0;
00434 next = goodcoor(x1, y, z);
00435 CmiAssert(next != -1);
00436 if (next != mype && checkuniq(_n, nb, next)) _n[nb++] = next;
00437
00438 int y1 = y+i;
00439 if (y1 == -1) {
00440 y1 = width-1;
00441 while (goodcoor(x, y1, z)==-1) y1--;
00442 }
00443 else if (goodcoor(x, y1, z) == -1) y1=0;
00444 next = goodcoor(x, y1, z);
00445 CmiAssert(next != -1);
00446 if (next != mype && checkuniq(_n, nb, next)) _n[nb++] = next;
00447
00448 int z1 = z+i;
00449 if (z1 == -1) {
00450 z1 = width-1;
00451 while (goodcoor(x, y, z1)==-1) z1--;
00452 }
00453 else if (goodcoor(x, y, z1) == -1) z1=0;
00454 next = goodcoor(x, y, z1);
00455 CmiAssert(next != -1);
00456 if (next != mype && checkuniq(_n, nb, next)) _n[nb++] = next;
00457 }
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 LBTOPO_MACRO(LBTopo_mesh3d)
00499
00500 LBTopo_mesh3d::LBTopo_mesh3d(int p): LBTopology(p)
00501 {
00502 width = 1;
00503 while ( (width+1) * (width+1) * (width+1) <= npes) width++;
00504 if (width * width * width < npes) width++;
00505 }
00506
00507 int LBTopo_mesh3d::max_neighbors()
00508 {
00509 return 6;
00510 }
00511
00512 int LBTopo_mesh3d::goodcoor(int x, int y, int z)
00513 {
00514 if (x<0 || x>=width) return -1;
00515 if (y<0 || y>=width) return -1;
00516 if (z<0 || z>=width) return -1;
00517 int next = z*width*width + y*width + x;
00518 if (next<npes && next>=0) return next;
00519 return -1;
00520 }
00521
00522 void LBTopo_mesh3d::neighbors(int mype, int* _n, int &nb)
00523 {
00524
00525 int z = mype/(width*width);
00526 int k = mype%(width*width);
00527 int y = k/width;
00528 int x = k%width;
00529 int next;
00530 int isNeigh=1;
00531 nb=0;
00532 for (int i=-1; i<=1; i+=2) {
00533 isNeigh=1;
00534 int x1 = x+i;
00535 if (x1 == -1) {
00536
00537 x1=x;
00538
00539 isNeigh=0;
00540 }
00541 else if (goodcoor(x1, y, z) == -1) { x1=0; isNeigh=0; }
00542 next = goodcoor(x1, y, z);
00543 CmiAssert(next != -1);
00544 if (next != mype && isNeigh && checkuniq(_n, nb, next)) _n[nb++] = next;
00545
00546 isNeigh=1;
00547 int y1 = y+i;
00548 if (y1 == -1) {
00549
00550
00551 y1=y;
00552 isNeigh=0;
00553 }
00554 else if (goodcoor(x, y1, z) == -1) { y1=0; isNeigh=0; }
00555 next = goodcoor(x, y1, z);
00556 CmiAssert(next != -1);
00557 if (next != mype && isNeigh && checkuniq(_n, nb, next)) _n[nb++] = next;
00558
00559 isNeigh=1;
00560 int z1 = z+i;
00561 if (z1 == -1) {
00562
00563
00564 z1=z;
00565 isNeigh=0;
00566 }
00567 else if (goodcoor(x, y, z1) == -1) { z1=0; isNeigh=0; }
00568 next = goodcoor(x, y, z1);
00569 CmiAssert(next != -1);
00570 if (next != mype && isNeigh && checkuniq(_n, nb, next)) _n[nb++] = next;
00571 }
00572 }
00573
00574
00575
00576
00577 template <int dimension>
00578 class LBTopo_torus_nd: public LBTopology {
00579 private:
00580
00581 int* Cardinality;
00582 int VirtualProcessorCount;
00583 int* TempCo;
00584 private:
00585 int GetNeighborID(int ProcessorID, int number) {
00586 CmiAssert(number>=0 && number<max_neighbors());
00587 CmiAssert(ProcessorID>=0 && ProcessorID<npes);
00588 get_processor_coordinates(ProcessorID, TempCo);
00589
00590 int index = number/2;
00591 int displacement = (number%2)? -1: 1;
00592 do{
00593 TempCo[index] = (TempCo[index] + displacement + Cardinality[index]) % Cardinality[index];
00594 get_processor_id(TempCo, &ProcessorID);
00595 } while (ProcessorID >= npes);
00596 return ProcessorID;
00597 }
00598 public:
00599 LBTopo_torus_nd(int p): LBTopology(p) {
00600 int i;
00601 CmiAssert(dimension>=1 && dimension<=16);
00602 CmiAssert(p>=1);
00603
00604 Cardinality = new int[dimension];
00605 TempCo = new int[dimension];
00606 double pp = p;
00607 for(i=0;i<dimension;i++) {
00608 Cardinality[i] = (int)ceil(pow(pp,1.0/(dimension-i))-1e-5);
00609 pp = pp / Cardinality[i];
00610 }
00611 VirtualProcessorCount = 1;
00612 for(i=0;i<dimension;i++) {
00613 VirtualProcessorCount *= Cardinality[i];
00614 }
00615 }
00616 ~LBTopo_torus_nd() {
00617 delete[] Cardinality;
00618 delete[] TempCo;
00619 }
00620 virtual int max_neighbors() {
00621 return dimension*2;
00622 }
00623 virtual void neighbors(int mype, int* _n, int &nb) {
00624 nb = 0;
00625 for(int i=0;i<dimension*2;i++) {
00626 _n[nb] = GetNeighborID(mype, i);
00627 if (_n[nb]!=mype && (nb==0 || _n[nb-1]!=_n[nb]) ) nb++;
00628 }
00629 }
00630 virtual int get_dimension() {
00631 return dimension;
00632 }
00633 virtual bool get_processor_coordinates(int processor_id, int* processor_coordinates) {
00634 CmiAssert(processor_id>=0 && processor_id<VirtualProcessorCount);
00635 CmiAssert( processor_coordinates != NULL );
00636 for(int i=0;i<dimension;i++) {
00637 processor_coordinates[i] = processor_id % Cardinality[i];
00638 processor_id = processor_id / Cardinality[i];
00639 }
00640 return true;
00641 }
00642 virtual bool get_processor_id(const int* processor_coordinates, int* processor_id) {
00643 int i;
00644 CmiAssert( processor_coordinates != NULL );
00645 CmiAssert( processor_id != NULL );
00646 for(i=dimension-1;i>=0;i--)
00647 CmiAssert( 0<=processor_coordinates[i] && processor_coordinates[i]<Cardinality[i]);
00648 (*processor_id) = 0;
00649 for(i=dimension-1;i>=0;i--) {
00650 (*processor_id) = (*processor_id)* Cardinality[i] + processor_coordinates[i];
00651 }
00652 return true;
00653 }
00654
00655 virtual bool coordinate_difference(const int* my_coordinates, const int* target_coordinates, int* difference) {
00656
00657 CmiAssert( my_coordinates != NULL);
00658 CmiAssert( target_coordinates != NULL);
00659 CmiAssert( difference != NULL);
00660
00661 for(int i=0;i<dimension;i++) {
00662
00663 difference[i] = target_coordinates[i] - my_coordinates[i];
00664 if (abs(difference[i])*2 > Cardinality[i]) {
00665 difference[i] += (difference[i]>0) ? -Cardinality[i] : Cardinality[i];
00666 } else if (abs(difference[i])*2 == Cardinality[i]) {
00667 difference[i] = 0;
00668 }
00669 }
00670
00671 return true;
00672 }
00673
00674 virtual bool coordinate_difference(int my_processor_id, int target_processor_id, int* difference) {
00675 CmiAssert( difference != NULL);
00676 int my_coordinates[dimension];
00677 int target_coordinates[dimension];
00678 get_processor_coordinates(my_processor_id, my_coordinates);
00679 get_processor_coordinates(target_processor_id, target_coordinates);
00680 coordinate_difference(my_coordinates, target_coordinates, difference);
00681 return true;
00682 }
00683 };
00684
00685 typedef LBTopo_torus_nd<1> LBTopo_torus_nd_1;
00686 typedef LBTopo_torus_nd<2> LBTopo_torus_nd_2;
00687 typedef LBTopo_torus_nd<3> LBTopo_torus_nd_3;
00688 typedef LBTopo_torus_nd<4> LBTopo_torus_nd_4;
00689 typedef LBTopo_torus_nd<5> LBTopo_torus_nd_5;
00690 typedef LBTopo_torus_nd<6> LBTopo_torus_nd_6;
00691 typedef LBTopo_torus_nd<7> LBTopo_torus_nd_7;
00692 typedef LBTopo_torus_nd<8> LBTopo_torus_nd_8;
00693 typedef LBTopo_torus_nd<9> LBTopo_torus_nd_9;
00694 typedef LBTopo_torus_nd<10> LBTopo_torus_nd_10;
00695
00696 LBTOPO_MACRO(LBTopo_torus_nd_1)
00697 LBTOPO_MACRO(LBTopo_torus_nd_2)
00698 LBTOPO_MACRO(LBTopo_torus_nd_3)
00699 LBTOPO_MACRO(LBTopo_torus_nd_4)
00700 LBTOPO_MACRO(LBTopo_torus_nd_5)
00701 LBTOPO_MACRO(LBTopo_torus_nd_6)
00702 LBTOPO_MACRO(LBTopo_torus_nd_7)
00703 LBTOPO_MACRO(LBTopo_torus_nd_8)
00704 LBTOPO_MACRO(LBTopo_torus_nd_9)
00705 LBTOPO_MACRO(LBTopo_torus_nd_10)
00706
00707
00708
00709
00710
00711
00712 template <int dimension>
00713 class LBTopo_torus_nd_smp: public LBTopology {
00714 private:
00715
00716 int* Cardinality;
00717 int VirtualNodeCount;
00718 int* TempCo;
00719 int ppn;
00720 int NumOfNodes;
00721 private:
00722 int GetNeighborID(int ProcessorID, int number) {
00723 CmiAssert(number>=0 && number<max_neighbors());
00724 CmiAssert(ProcessorID>=0 && ProcessorID<npes);
00725 int neighborId;
00726 int nodeId = CmiPhysicalNodeID(ProcessorID);
00727
00728 get_node_coordinates(nodeId, TempCo);
00729
00730 int index = number/2;
00731 int displacement = (number%2)? -1: 1;
00732 do{
00733 TempCo[index] = (TempCo[index] + displacement + Cardinality[index]) % Cardinality[index];
00734 get_node_id(TempCo, &nodeId);
00735 } while (nodeId >= NumOfNodes);
00736 neighborId = CmiGetFirstPeOnPhysicalNode(nodeId);
00737 return neighborId;
00738 }
00739 public:
00740 LBTopo_torus_nd_smp(int p): LBTopology(p) {
00741 int i;
00742 CmiAssert(dimension>=1 && dimension<=32);
00743 CmiAssert(p>=1);
00744
00745 ppn = CmiNumPesOnPhysicalNode(0);
00746 NumOfNodes = CmiNumPhysicalNodes();
00747
00748 Cardinality = new int[dimension];
00749 TempCo = new int[dimension];
00750 double pp = NumOfNodes;
00751 for(i=0;i<dimension;i++) {
00752 Cardinality[i] = (int)ceil(pow(pp,1.0/(dimension-i))-1e-5);
00753 pp = pp / Cardinality[i];
00754 }
00755 VirtualNodeCount = 1;
00756 for(i=0;i<dimension;i++) {
00757 VirtualNodeCount *= Cardinality[i];
00758 }
00759 #ifdef YHDEBUG
00760 CmiPrintf(" ppn=%d, NumOfNodes=%d\n", ppn, NumOfNodes);
00761 #endif
00762 }
00763 ~LBTopo_torus_nd_smp() {
00764 delete[] Cardinality;
00765 delete[] TempCo;
00766 }
00767 virtual int max_neighbors() {
00768 return (dimension+ppn)*2;
00769 }
00770 virtual void neighbors(int mype, int* _n, int &nb) {
00771 nb = 0;
00772 int *nodePeList;
00773 int numpes;
00774 int rank = CmiPhysicalRank(mype);
00775 int node = CmiPhysicalNodeID(mype);
00776 int _ppn_ = CmiNumPesOnPhysicalNode(node);
00777 CmiGetPesOnPhysicalNode(node, &nodePeList, &numpes);
00778 #ifdef YHDEBUG
00779 CmiPrintf(" PE[%d] ppn=%d, NumOfNodes=%d, rank=%d, node=%d, numpes=%d\n", mype, _ppn_, NumOfNodes, rank, node, numpes);
00780 #endif
00781 for(int i=0; i<numpes; i++)
00782 {
00783 int _pid = nodePeList[i];
00784 if(_pid != mype)
00785 {
00786 _n[nb] = _pid;
00787 nb++;
00788 }
00789 }
00790
00791
00792 if(mype == CmiGetFirstPeOnPhysicalNode(node))
00793 {
00794 for(int j=0; j<dimension*2; j++)
00795 {
00796
00797 _n[nb] = GetNeighborID(mype, j);
00798
00799 if (_n[nb]!=mype && (nb==0 || _n[nb-1]!=_n[nb]) ) nb++;
00800 }
00801 }
00802
00803 #ifdef YHDEBUG
00804 CmiPrintf(" [%d] neighbor = %d ppn=%d, NumOfNodes=%d, rank=%d, node=%d, numpes=%d\n", mype, nb, _ppn_, NumOfNodes, rank, node, numpes);
00805 #endif
00806 }
00807 virtual int get_dimension() {
00808 return dimension;
00809 }
00810 virtual bool get_node_coordinates(int node_id, int* node_coordinates) {
00811 CmiAssert(node_id>=0 && node_id<VirtualNodeCount);
00812 CmiAssert( node_coordinates != NULL );
00813 for(int i=0;i<dimension;i++) {
00814 node_coordinates[i] = node_id % Cardinality[i];
00815 node_id = node_id / Cardinality[i];
00816 }
00817 return true;
00818 }
00819 virtual bool get_node_id(const int* node_coordinates, int* node_id) {
00820 int i;
00821 CmiAssert( node_coordinates != NULL );
00822 CmiAssert( node_id != NULL );
00823 for(i=dimension-1;i>=0;i--)
00824 CmiAssert( 0<=node_coordinates[i] && node_coordinates[i]<Cardinality[i]);
00825 (*node_id) = 0;
00826 for(i=dimension-1;i>=0;i--) {
00827 (*node_id) = (*node_id)* Cardinality[i] + node_coordinates[i];
00828 }
00829 return true;
00830 }
00831
00832 virtual bool coordinate_difference(const int* my_coordinates, const int* target_coordinates, int* difference) {
00833 CmiAssert( my_coordinates != NULL);
00834 CmiAssert( target_coordinates != NULL);
00835 CmiAssert( difference != NULL);
00836 for(int i=0;i<dimension;i++) {
00837 difference[i] = target_coordinates[i] - my_coordinates[i];
00838 if (abs(difference[i])*2 > Cardinality[i]) {
00839 difference[i] += (difference[i]>0) ? -Cardinality[i] : Cardinality[i];
00840 } else if (abs(difference[i])*2 == Cardinality[i]) {
00841 difference[i] = 0;
00842 }
00843 }
00844 return true;
00845 }
00846
00847 virtual bool coordinate_difference(int my_processor_id, int target_processor_id, int* difference) {
00848 CmiAssert( difference != NULL);
00849 int my_coordinates[dimension];
00850 int target_coordinates[dimension];
00851 get_processor_coordinates(my_processor_id, my_coordinates);
00852 get_processor_coordinates(target_processor_id, target_coordinates);
00853 coordinate_difference(my_coordinates, target_coordinates, difference);
00854 return true;
00855 }
00856 };
00857
00858
00859 typedef LBTopo_torus_nd_smp<1> LBTopo_torus_nd_smp_1;
00860 typedef LBTopo_torus_nd_smp<2> LBTopo_torus_nd_smp_2;
00861 typedef LBTopo_torus_nd_smp<3> LBTopo_torus_nd_smp_3;
00862 typedef LBTopo_torus_nd_smp<4> LBTopo_torus_nd_smp_4;
00863 typedef LBTopo_torus_nd_smp<5> LBTopo_torus_nd_smp_5;
00864 typedef LBTopo_torus_nd_smp<6> LBTopo_torus_nd_smp_6;
00865 typedef LBTopo_torus_nd_smp<7> LBTopo_torus_nd_smp_7;
00866 typedef LBTopo_torus_nd_smp<8> LBTopo_torus_nd_smp_8;
00867 typedef LBTopo_torus_nd_smp<9> LBTopo_torus_nd_smp_9;
00868 typedef LBTopo_torus_nd_smp<10> LBTopo_torus_nd_smp_10;
00869
00870 LBTOPO_MACRO(LBTopo_torus_nd_smp_1)
00871 LBTOPO_MACRO(LBTopo_torus_nd_smp_2)
00872 LBTOPO_MACRO(LBTopo_torus_nd_smp_3)
00873 LBTOPO_MACRO(LBTopo_torus_nd_smp_4)
00874 LBTOPO_MACRO(LBTopo_torus_nd_smp_5)
00875 LBTOPO_MACRO(LBTopo_torus_nd_smp_6)
00876 LBTOPO_MACRO(LBTopo_torus_nd_smp_7)
00877 LBTOPO_MACRO(LBTopo_torus_nd_smp_8)
00878 LBTOPO_MACRO(LBTopo_torus_nd_smp_9)
00879 LBTOPO_MACRO(LBTopo_torus_nd_smp_10)
00880
00881
00882
00883
00884 template <int dimension>
00885 class LBTopo_itorus_nd: public LBTopology {
00886 private:
00887 int *dim;
00888 int *tempCoor;
00889
00890 public:
00891 LBTopo_itorus_nd(int p): LBTopology(p) {
00892 CmiPrintf("Irregular torus created\n");
00893 dim = new int[dimension];
00894 tempCoor = new int[dimension];
00895
00896 int i=0;
00897 char *lbcopy = strdup(_lbtopo);
00898 char *ptr = strchr(lbcopy, ':');
00899 if (ptr==NULL) {
00900 free(lbcopy);
00901 return;
00902 }
00903 ptr = strtok(ptr+1, ",");
00904 while (ptr) {
00905 dim[i]=atoi(ptr);
00906 i++;
00907 ptr = strtok(NULL, ",");
00908 }
00909 CmiAssert(dimension==i);
00910
00911 int procs=1;
00912 for(i=0;i<dimension;i++)
00913 procs*=dim[i];
00914 CmiAssert(dimension>=1 && dimension<=16);
00915 CmiAssert(p>=1);
00916 CmiAssert(procs==p);
00917 free(lbcopy);
00918 }
00919
00920 ~LBTopo_itorus_nd() {
00921 delete[] dim;
00922 delete[] tempCoor;
00923 }
00924
00925 virtual int max_neighbors() {
00926 return dimension*2;
00927 }
00928
00929 virtual void neighbors(int mype, int* _n, int &nb) {
00930 nb = 0;
00931 for(int i=0;i<dimension*2;i++) {
00932 _n[nb] = GetNeighborID(mype, i);
00933 if (_n[nb]!=mype && (nb==0 || _n[nb-1]!=_n[nb]) ) nb++;
00934 }
00935 }
00936
00937 int GetNeighborID(int ProcessorID, int number) {
00938 CmiAssert(number>=0 && number<max_neighbors());
00939 CmiAssert(ProcessorID>=0 && ProcessorID<npes);
00940 get_processor_coordinates(ProcessorID, tempCoor);
00941
00942 int index = number/2;
00943 int displacement = (number%2)? -1: 1;
00944
00945 tempCoor[index] = (tempCoor[index] + displacement + dim[index]) % dim[index];
00946 get_processor_id(tempCoor, &ProcessorID);
00947
00948 return ProcessorID;
00949 }
00950
00951 virtual bool get_processor_coordinates(int processor_id, int* processor_coordinates) {
00952 CmiAssert(processor_id>=0 && processor_id<npes);
00953 CmiAssert(processor_coordinates != NULL );
00954 for(int i=0;i<dimension;i++) {
00955 processor_coordinates[i] = processor_id % dim[i];
00956 processor_id = processor_id / dim[i];
00957 }
00958 return true;
00959 }
00960
00961 virtual bool get_processor_id(const int* processor_coordinates, int* processor_id) {
00962 int i;
00963 CmiAssert( processor_coordinates != NULL );
00964 CmiAssert( processor_id != NULL );
00965 for(i=dimension-1;i>=0;i--)
00966 CmiAssert( 0<=processor_coordinates[i] && processor_coordinates[i]<dim[i]);
00967 (*processor_id) = 0;
00968 for(i=dimension-1;i>=0;i--) {
00969 (*processor_id) = (*processor_id)* dim[i] + processor_coordinates[i];
00970 }
00971 return true;
00972 }
00973 };
00974
00975
00976 typedef LBTopo_itorus_nd<1> LBTopo_itorus_nd_1;
00977 typedef LBTopo_itorus_nd<2> LBTopo_itorus_nd_2;
00978 typedef LBTopo_itorus_nd<3> LBTopo_itorus_nd_3;
00979 typedef LBTopo_itorus_nd<4> LBTopo_itorus_nd_4;
00980 typedef LBTopo_itorus_nd<5> LBTopo_itorus_nd_5;
00981 typedef LBTopo_itorus_nd<6> LBTopo_itorus_nd_6;
00982 typedef LBTopo_itorus_nd<7> LBTopo_itorus_nd_7;
00983
00984 LBTOPO_MACRO(LBTopo_itorus_nd_1)
00985 LBTOPO_MACRO(LBTopo_itorus_nd_2)
00986 LBTOPO_MACRO(LBTopo_itorus_nd_3)
00987 LBTOPO_MACRO(LBTopo_itorus_nd_4)
00988 LBTOPO_MACRO(LBTopo_itorus_nd_5)
00989 LBTOPO_MACRO(LBTopo_itorus_nd_6)
00990 LBTOPO_MACRO(LBTopo_itorus_nd_7)
00991
00992
00993
00994
00995
00996 template <int dimension>
00997 class LBTopo_imesh_nd: public LBTopology {
00998 private:
00999 int *dim;
01000 int *tempCoor;
01001
01002 public:
01003 LBTopo_imesh_nd(int p): LBTopology(p) {
01004 CmiPrintf("Irregular mesh created\n");
01005 dim = new int[dimension];
01006 tempCoor = new int[dimension];
01007
01008 int i=0;
01009 char *lbcopy = strdup(_lbtopo);
01010 char *ptr = strchr(lbcopy, ':');
01011 if (ptr==NULL)
01012 {
01013 delete [] dim;
01014 delete [] tempCoor;
01015 free(lbcopy);
01016 return;
01017 }
01018 ptr = strtok(ptr+1, ",");
01019 while (ptr) {
01020 dim[i]=atoi(ptr);
01021 i++;
01022 ptr = strtok(NULL, ",");
01023 }
01024 CmiAssert(dimension==i);
01025
01026
01027
01028 int procs=1;
01029 for(i=0;i<dimension;i++)
01030 procs*=dim[i];
01031 CmiAssert(dimension>=1 && dimension<=16);
01032 CmiAssert(p>=1);
01033 CmiAssert(procs==p);
01034 free(lbcopy);
01035 }
01036
01037 ~LBTopo_imesh_nd() {
01038 delete[] dim;
01039 delete[] tempCoor;
01040 }
01041
01042 virtual int max_neighbors() {
01043 return dimension*2;
01044 }
01045
01046 virtual void neighbors(int mype, int* _n, int &nb) {
01047 nb = 0;
01048 for(int i=0;i<dimension*2;i++) {
01049 _n[nb] = GetNeighborID(mype, i);
01050 if (_n[nb]!=mype && (nb==0 || _n[nb-1]!=_n[nb]) ) nb++;
01051 }
01052
01053
01054
01055
01056 }
01057
01058 int GetNeighborID(int ProcessorID, int number) {
01059 CmiAssert(number>=0 && number<max_neighbors());
01060 CmiAssert(ProcessorID>=0 && ProcessorID<npes);
01061 get_processor_coordinates(ProcessorID, tempCoor);
01062
01063 int index = number/2;
01064 int displacement = (number%2)? -1: 1;
01065
01066 if((tempCoor[index]==0 && displacement==-1) || (tempCoor[index]==dim[index]-1 && displacement==1)){
01067 }
01068 else{
01069 tempCoor[index] = (tempCoor[index] + displacement + dim[index]) % dim[index];
01070 get_processor_id(tempCoor, &ProcessorID);
01071 }
01072
01073 return ProcessorID;
01074 }
01075
01076 virtual bool get_processor_coordinates(int processor_id, int* processor_coordinates) {
01077 CmiAssert(processor_id>=0 && processor_id<npes);
01078 CmiAssert(processor_coordinates != NULL );
01079 for(int i=0;i<dimension;i++) {
01080 processor_coordinates[i] = processor_id % dim[i];
01081 processor_id = processor_id / dim[i];
01082 }
01083 return true;
01084 }
01085
01086 virtual bool get_processor_id(const int* processor_coordinates, int* processor_id) {
01087 int i;
01088 CmiAssert( processor_coordinates != NULL );
01089 CmiAssert( processor_id != NULL );
01090 for(i=dimension-1;i>=0;i--)
01091 CmiAssert( 0<=processor_coordinates[i] && processor_coordinates[i]<dim[i]);
01092 (*processor_id) = 0;
01093 for(i=dimension-1;i>=0;i--) {
01094 (*processor_id) = (*processor_id)* dim[i] + processor_coordinates[i];
01095 }
01096 return true;
01097 }
01098 };
01099
01100
01101 typedef LBTopo_imesh_nd<1> LBTopo_imesh_nd_1;
01102 typedef LBTopo_imesh_nd<2> LBTopo_imesh_nd_2;
01103 typedef LBTopo_imesh_nd<3> LBTopo_imesh_nd_3;
01104 typedef LBTopo_imesh_nd<4> LBTopo_imesh_nd_4;
01105 typedef LBTopo_imesh_nd<5> LBTopo_imesh_nd_5;
01106 typedef LBTopo_imesh_nd<6> LBTopo_imesh_nd_6;
01107 typedef LBTopo_imesh_nd<7> LBTopo_imesh_nd_7;
01108
01109 LBTOPO_MACRO(LBTopo_imesh_nd_1)
01110 LBTOPO_MACRO(LBTopo_imesh_nd_2)
01111 LBTOPO_MACRO(LBTopo_imesh_nd_3)
01112 LBTOPO_MACRO(LBTopo_imesh_nd_4)
01113 LBTOPO_MACRO(LBTopo_imesh_nd_5)
01114 LBTOPO_MACRO(LBTopo_imesh_nd_6)
01115 LBTOPO_MACRO(LBTopo_imesh_nd_7)
01116
01117
01118
01119
01120 LBTOPO_MACRO(LBTopo_graph)
01121
01122 int LBTopo_graph::max_neighbors()
01123 {
01124 return (int)(sqrt(1.0*CmiNumPes())+0.5);
01125 }
01126
01127 extern "C" void gengraph(int, int, int, int *, int *, int);
01128
01129 void LBTopo_graph::neighbors(int mype, int* na, int &nb)
01130 {
01131 gengraph(CmiNumPes(), (int)(sqrt(1.0*CmiNumPes())+0.5), 234, na, &nb, 0);
01132 }
01133
01134
01135 template <int dimension>
01136 class LBTopo_graph_nc: public LBTopology {
01137
01138 public:
01139 LBTopo_graph_nc(int p): LBTopology(p) {}
01140 int max_neighbors()
01141 {
01142 return dimension + 1;
01143 }
01144
01145 void neighbors(int mype, int* na, int &nb)
01146 {
01147 #if CMK_NODE_QUEUE_AVAILABLE
01148 gengraph(CmiNumNodes(), dimension, 234, na, &nb, 0);
01149 #else
01150 gengraph(CmiNumPes(), dimension, 234, na, &nb, 0);
01151 #endif
01152 }
01153
01154 };
01155 typedef LBTopo_graph_nc<2> LBTopo_graph_nc_2;
01156 typedef LBTopo_graph_nc<3> LBTopo_graph_nc_3;
01157 typedef LBTopo_graph_nc<4> LBTopo_graph_nc_4;
01158 typedef LBTopo_graph_nc<5> LBTopo_graph_nc_5;
01159 typedef LBTopo_graph_nc<6> LBTopo_graph_nc_6;
01160 typedef LBTopo_graph_nc<7> LBTopo_graph_nc_7;
01161 typedef LBTopo_graph_nc<8> LBTopo_graph_nc_8;
01162 typedef LBTopo_graph_nc<9> LBTopo_graph_nc_9;
01163 typedef LBTopo_graph_nc<10> LBTopo_graph_nc_10;
01164 typedef LBTopo_graph_nc<20> LBTopo_graph_nc_20;
01165
01166 LBTOPO_MACRO(LBTopo_graph_nc_2)
01167 LBTOPO_MACRO(LBTopo_graph_nc_3)
01168 LBTOPO_MACRO(LBTopo_graph_nc_4)
01169 LBTOPO_MACRO(LBTopo_graph_nc_5)
01170 LBTOPO_MACRO(LBTopo_graph_nc_6)
01171 LBTOPO_MACRO(LBTopo_graph_nc_7)
01172 LBTOPO_MACRO(LBTopo_graph_nc_8)
01173 LBTOPO_MACRO(LBTopo_graph_nc_9)
01174 LBTOPO_MACRO(LBTopo_graph_nc_10)
01175 LBTOPO_MACRO(LBTopo_graph_nc_20)
01176
01177
01178
01179
01180
01181
01182
01183
01184 class LBTopo_complete: public LBTopology {
01185 public:
01186 LBTopo_complete(int p): LBTopology(p) {}
01187 int max_neighbors() {
01188 return npes - 1;
01189 }
01190 void neighbors(int mype, int* _n, int &nb) {
01191 nb = 0;
01192 for (int i=0; i<npes; i++) if (mype != i) _n[nb++] = i;
01193 }
01194 };
01195
01196 LBTOPO_MACRO(LBTopo_complete)
01197
01198
01199
01200 template <int k>
01201 class LBTopo_karytree: public LBTopology {
01202 public:
01203 LBTopo_karytree(int p): LBTopology(p) {}
01204 virtual int max_neighbors() {
01205 return k+1;
01206 }
01207 virtual void neighbors(int mype, int* _n, int &nb) {
01208 nb = 0;
01209 if (mype!=0) _n[nb++] = (mype-1)/k;
01210 int firstchild = mype*k+1;
01211 for (int i=0; i<k; i++)
01212 if (firstchild+i < npes) _n[nb++] = firstchild+i;
01213 }
01214 };
01215
01216 typedef LBTopo_karytree<2> LBTopo_2_arytree;
01217 typedef LBTopo_karytree<3> LBTopo_3_arytree;
01218 typedef LBTopo_karytree<4> LBTopo_4_arytree;
01219 typedef LBTopo_karytree<128> LBTopo_128_arytree;
01220 typedef LBTopo_karytree<512> LBTopo_512_arytree;
01221
01222 LBTOPO_MACRO(LBTopo_2_arytree)
01223 LBTOPO_MACRO(LBTopo_3_arytree)
01224 LBTOPO_MACRO(LBTopo_4_arytree)
01225 LBTOPO_MACRO(LBTopo_128_arytree)
01226 LBTOPO_MACRO(LBTopo_512_arytree)
01227
01228
01229
01230 class LBTopoMap {
01231 public:
01232 const char *name;
01233 LBtopoFn fn;
01234 LBTopoMap(const char *s, LBtopoFn f): name(s), fn(f) {}
01235 LBTopoMap(const LBTopoMap &p);
01236 void operator=(const LBTopoMap &p);
01237 };
01238
01239 class LBTopoVec {
01240 std::vector<LBTopoMap *> lbTopos;
01241 public:
01242 LBTopoVec() {
01243
01244 lbTopos.reserve(64);
01245 lbTopos.push_back(new LBTopoMap("ring", createLBTopo_ring));
01246 lbTopos.push_back(new LBTopoMap("torus2d", createLBTopo_torus2d));
01247 lbTopos.push_back(new LBTopoMap("torus3d", createLBTopo_torus3d));
01248 lbTopos.push_back(new LBTopoMap("mesh3d", createLBTopo_mesh3d));
01249 lbTopos.push_back(new LBTopoMap("torus_nd_1", createLBTopo_torus_nd_1));
01250 lbTopos.push_back(new LBTopoMap("torus_nd_2", createLBTopo_torus_nd_2));
01251 lbTopos.push_back(new LBTopoMap("torus_nd_3", createLBTopo_torus_nd_3));
01252 lbTopos.push_back(new LBTopoMap("torus_nd_4", createLBTopo_torus_nd_4));
01253 lbTopos.push_back(new LBTopoMap("torus_nd_5", createLBTopo_torus_nd_5));
01254 lbTopos.push_back(new LBTopoMap("torus_nd_6", createLBTopo_torus_nd_6));
01255 lbTopos.push_back(new LBTopoMap("torus_nd_7", createLBTopo_torus_nd_7));
01256 lbTopos.push_back(new LBTopoMap("torus_nd_8", createLBTopo_torus_nd_8));
01257 lbTopos.push_back(new LBTopoMap("torus_nd_9", createLBTopo_torus_nd_9));
01258 lbTopos.push_back(new LBTopoMap("torus_nd_10", createLBTopo_torus_nd_10));
01259 lbTopos.push_back(new LBTopoMap("torus_nd_smp_1", createLBTopo_torus_nd_smp_1));
01260 lbTopos.push_back(new LBTopoMap("torus_nd_smp_2", createLBTopo_torus_nd_smp_2));
01261 lbTopos.push_back(new LBTopoMap("torus_nd_smp_3", createLBTopo_torus_nd_smp_3));
01262 lbTopos.push_back(new LBTopoMap("torus_nd_smp_4", createLBTopo_torus_nd_smp_4));
01263 lbTopos.push_back(new LBTopoMap("torus_nd_smp_5", createLBTopo_torus_nd_smp_5));
01264 lbTopos.push_back(new LBTopoMap("torus_nd_smp_6", createLBTopo_torus_nd_smp_6));
01265 lbTopos.push_back(new LBTopoMap("torus_nd_smp_7", createLBTopo_torus_nd_smp_7));
01266 lbTopos.push_back(new LBTopoMap("torus_nd_smp_8", createLBTopo_torus_nd_smp_8));
01267 lbTopos.push_back(new LBTopoMap("torus_nd_smp_9", createLBTopo_torus_nd_smp_9));
01268 lbTopos.push_back(new LBTopoMap("torus_nd_smp_10", createLBTopo_torus_nd_smp_10));
01269 lbTopos.push_back(new LBTopoMap("itorus_nd_1", createLBTopo_itorus_nd_1));
01270 lbTopos.push_back(new LBTopoMap("itorus_nd_2", createLBTopo_itorus_nd_2));
01271 lbTopos.push_back(new LBTopoMap("itorus_nd_3", createLBTopo_itorus_nd_3));
01272 lbTopos.push_back(new LBTopoMap("itorus_nd_4", createLBTopo_itorus_nd_4));
01273 lbTopos.push_back(new LBTopoMap("itorus_nd_5", createLBTopo_itorus_nd_5));
01274 lbTopos.push_back(new LBTopoMap("itorus_nd_6", createLBTopo_itorus_nd_6));
01275 lbTopos.push_back(new LBTopoMap("itorus_nd_7", createLBTopo_itorus_nd_7));
01276 lbTopos.push_back(new LBTopoMap("imesh_nd_1", createLBTopo_imesh_nd_1));
01277 lbTopos.push_back(new LBTopoMap("imesh_nd_2", createLBTopo_imesh_nd_2));
01278 lbTopos.push_back(new LBTopoMap("imesh_nd_3", createLBTopo_imesh_nd_3));
01279 lbTopos.push_back(new LBTopoMap("imesh_nd_4", createLBTopo_imesh_nd_4));
01280 lbTopos.push_back(new LBTopoMap("imesh_nd_5", createLBTopo_imesh_nd_5));
01281 lbTopos.push_back(new LBTopoMap("imesh_nd_6", createLBTopo_imesh_nd_6));
01282 lbTopos.push_back(new LBTopoMap("imesh_nd_7", createLBTopo_imesh_nd_7));
01283 lbTopos.push_back(new LBTopoMap("graph", createLBTopo_graph));
01284 lbTopos.push_back(new LBTopoMap("graph_nc_2", createLBTopo_graph_nc_2));
01285 lbTopos.push_back(new LBTopoMap("graph_nc_3", createLBTopo_graph_nc_3));
01286 lbTopos.push_back(new LBTopoMap("graph_nc_4", createLBTopo_graph_nc_4));
01287 lbTopos.push_back(new LBTopoMap("graph_nc_5", createLBTopo_graph_nc_5));
01288 lbTopos.push_back(new LBTopoMap("graph_nc_6", createLBTopo_graph_nc_6));
01289 lbTopos.push_back(new LBTopoMap("graph_nc_7", createLBTopo_graph_nc_7));
01290 lbTopos.push_back(new LBTopoMap("graph_nc_8", createLBTopo_graph_nc_8));
01291 lbTopos.push_back(new LBTopoMap("graph_nc_9", createLBTopo_graph_nc_9));
01292 lbTopos.push_back(new LBTopoMap("graph_nc_10", createLBTopo_graph_nc_10));
01293 lbTopos.push_back(new LBTopoMap("graph_nc_20", createLBTopo_graph_nc_20));
01294 lbTopos.push_back(new LBTopoMap("complete", createLBTopo_complete));
01295 lbTopos.push_back(new LBTopoMap("2_arytree", createLBTopo_2_arytree));
01296 lbTopos.push_back(new LBTopoMap("3_arytree", createLBTopo_3_arytree));
01297 lbTopos.push_back(new LBTopoMap("4_arytree", createLBTopo_4_arytree));
01298 lbTopos.push_back(new LBTopoMap("128_arytree", createLBTopo_128_arytree));
01299 lbTopos.push_back(new LBTopoMap("512_arytree", createLBTopo_512_arytree));
01300 lbTopos.push_back(new LBTopoMap("smp_n_1", createLBTopo_smp_n_1));
01301 lbTopos.push_back(new LBTopoMap("smp_n_2", createLBTopo_smp_n_2));
01302 lbTopos.push_back(new LBTopoMap("smp_n_3", createLBTopo_smp_n_3));
01303 lbTopos.push_back(new LBTopoMap("smp_n_4", createLBTopo_smp_n_4));
01304 lbTopos.push_back(new LBTopoMap("smp_n_5", createLBTopo_smp_n_5));
01305 lbTopos.push_back(new LBTopoMap("smp_n_6", createLBTopo_smp_n_6));
01306 lbTopos.push_back(new LBTopoMap("smp_n_7", createLBTopo_smp_n_7));
01307 lbTopos.push_back(new LBTopoMap("smp_n_8", createLBTopo_smp_n_8));
01308 lbTopos.push_back(new LBTopoMap("smp_n_9", createLBTopo_smp_n_9));
01309 lbTopos.push_back(new LBTopoMap("smp_n_10", createLBTopo_smp_n_10));
01310 }
01311 ~LBTopoVec() {
01312 for (auto i : lbTopos)
01313 delete i;
01314 }
01315 void push_back(LBTopoMap *map) { lbTopos.push_back(map); }
01316 int length() { return lbTopos.size(); }
01317 LBTopoMap * operator[](size_t n) { return lbTopos[n]; }
01318 void print() {
01319 for (auto i : lbTopos) {
01320 CmiPrintf(" %s\n", i->name);
01321 }
01322 }
01323 };
01324
01325 static LBTopoVec* lbTopoMap;
01326 static CmiNodeLock lbTopoMapInitLock;
01327 static bool lbTopoInitialized = false;
01328
01329 void LBTopoInit() {
01330 CmiAssert(!lbTopoInitialized);
01331 lbTopoMapInitLock = CmiCreateLock();
01332 lbTopoInitialized = true;
01333 }
01334
01335 extern "C"
01336 LBtopoFn LBTopoLookup(const char *name)
01337 {
01338
01339
01340 CmiLock(lbTopoMapInitLock);
01341 if (!lbTopoMap)
01342 lbTopoMap = new LBTopoVec();
01343 CmiUnlock(lbTopoMapInitLock);
01344
01345 for (int i=0; i<lbTopoMap->length(); i++) {
01346 if (strcmp(name, (*lbTopoMap)[i]->name)==0) return (*lbTopoMap)[i]->fn;
01347 }
01348 return NULL;
01349 }
01350
01351
01352 extern "C" void getTopoNeighbors(void *topo, int myid, int* narray, int *n)
01353 {
01354 ((LBTopology*)topo)->neighbors(myid, narray, *n);
01355 }
01356
01357 extern "C" int getTopoMaxNeighbors(void *topo)
01358 {
01359 return ((LBTopology*)topo)->max_neighbors();
01360 }
01361
01362 extern "C" void printoutTopo()
01363 {
01364 lbTopoMap->print();
01365 }
01366