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