AMROC Main     Blockstructured Adaptive Mesh Refinement in object-oriented C++


Main Page   Class Hierarchy   Compound List   File List  

DAGHDistribution.C

Go to the documentation of this file.
00001 
00006 #include "DAGHDistribution.h"
00007 
00008 #ifdef DEBUG_PRINT
00009 #include "CommServer.h"
00010 #endif
00011 
00012 /*************************************************************************/
00013 /* Partitioning functions based on Paul Walker's implementation          */
00014 /*************************************************************************/
00015 void partition_one(const BBox& wholebbox, BBox* boxes, const int np, 
00016                    const int dim);
00017 void partition_two(const BBox& wholebbox, BBox* boxes, const int np, 
00018                    const int dim1, const int dim2);
00019 void partition_all(const BBox& wholebbox, BBox* boxes, const int np);
00020 void pwalker_partition(const BBox& wholebbox, BBox* boxes, const int np);
00021 /*************************************************************************/
00022 
00023 DAGHDistribution::DAGHDistribution(const int disttype, BBoxList& bbl)
00024         : type(disttype), boxes(0), wfunc(0)
00025   {
00026     boxes = new BBox[bbl.number()];
00027     register BBox* bb = 0;
00028     register int cnt = 0;
00029     for (bb=bbl.first();bb;bb=bbl.next()) {
00030       boxes[cnt++] = *bb; 
00031     }
00032   }
00033 
00034 void DAGHDistribution::set_dist(const int disttype, BBoxList& bbl)
00035   {
00036     type = disttype;
00037     if (boxes) delete [] boxes;
00038     boxes = new BBox[bbl.number()];
00039     register BBox* bb = 0;
00040     register int cnt = 0;
00041     for (bb=bbl.first();bb;bb=bbl.next()) {
00042       boxes[cnt++] = *bb; 
00043     }
00044   }
00045 
00046 unsigned long DAGHDistribution::get_load(GridUnitList& ggul, 
00047                                          const short* olap)
00048   {
00049     if (wfunc) { 
00050       unsigned long load = 0, n = 0;
00051       int levels = ggul.levels();
00052       for (int l=0;l<levels;l++) 
00053         load += (*wfunc)(&(n=ggul.numelems(l,olap)),&l);
00054       return load;
00055     } 
00056     else return( ggul.load(olap) );
00057   }
00058 
00059 void DAGHDistribution::partition(GridUnitList*& ggul,
00060                                  GridUnitList*& lgul,
00061                                  const int np, const int me, 
00062                                  const int minw, const short* olap)
00063   {
00064     if (type == DAGHCompositeDistribution) 
00065       partitionComposite(ggul, lgul, np, me, minw, olap);
00066 
00067     else if (type == DAGHBlockXDistribution) 
00068       partitionBlockOne(DAGH_X, ggul, lgul, np, me, minw, olap);
00069     else if (type == DAGHBlockYDistribution) 
00070       partitionBlockOne(DAGH_Y, ggul, lgul, np, me, minw, olap);
00071     else if (type == DAGHBlockZDistribution) 
00072       partitionBlockOne(DAGH_Z, ggul, lgul, np, me, minw, olap);
00073 
00074     else if (type == DAGHBlockXYDistribution) 
00075       partitionBlockTwo(DAGH_X, DAGH_Y, ggul, lgul, np, me, minw, olap);
00076     else if (type == DAGHBlockYZDistribution) 
00077       partitionBlockTwo(DAGH_Y, DAGH_Z, ggul, lgul, np, me, minw, olap);
00078     else if (type == DAGHBlockXZDistribution) 
00079       partitionBlockTwo(DAGH_X, DAGH_Z, ggul, lgul, np, me, minw, olap);
00080 
00081     else if (type == DAGHBlockAllDistribution) 
00082       partitionBlockAll(ggul, lgul, np, me, minw, olap);
00083 
00084     else if (type == DAGHUserDefDistribution) 
00085       partitionUserDef(ggul, lgul, np, me, minw, olap);
00086 
00087     else
00088       assert(0);
00089   }
00090 
00091 void DAGHDistribution::partition(const BBox& wbbox,
00092                                  BBox& mybbox,
00093                                  const int np, 
00094                                  const int me)
00095   {
00096     if (type == DAGHCompositeDistribution)
00097         type = DAGHBlockXDistribution;
00098 
00099     if (me >= np) {
00100         mybbox = BBox::_empty_bbox;
00101         return;
00102     }
00103 
00104     if (type != DAGHUserDefDistribution) {
00105       if (boxes) delete [] boxes;
00106       boxes = new BBox[np];
00107 
00108       if (type == DAGHBlockXDistribution) 
00109         partition_one(wbbox, boxes, np, DAGH_X);
00110       else if (type == DAGHBlockYDistribution) 
00111         partition_one(wbbox, boxes, np, DAGH_Y);
00112       else if (type == DAGHBlockZDistribution) 
00113         partition_one(wbbox, boxes, np, DAGH_Z);
00114       
00115       else if (type == DAGHBlockXYDistribution) 
00116         partition_two(wbbox, boxes, np, DAGH_X, DAGH_Y);
00117       else if (type == DAGHBlockYZDistribution) 
00118         partition_two(wbbox, boxes, np, DAGH_Y, DAGH_Z);
00119       else if (type == DAGHBlockXZDistribution) 
00120         partition_two(wbbox, boxes, np, DAGH_X, DAGH_Z);
00121 
00122       else if (type == DAGHBlockAllDistribution) 
00123         partition_all(wbbox, boxes, np);
00124 
00125       else
00126         assert(0);
00127     }
00128     mybbox = boxes[me];
00129   }
00130 
00131 /* This function is slightly modified. Perhaps, segmentation faults are created
00132   by the complex GridUnit-modifications. No errors have been observed after 
00133   lgul->add() and operator= have been introduced. RD */
00134 
00135 void DAGHDistribution::partitionComposite(GridUnitList*& ggul,
00136                                           GridUnitList*& lgul,
00137                                           const int np, const int me, 
00138                                           const int minw, const short* olap)
00139   {
00140 #ifdef DEBUG_PRINT
00141     /* Cannot partition an empty list */
00142     assert(ggul->number() > 0);
00143   
00144     /* Zero procs... ? */
00145     assert(np > 0);
00146 #endif
00147 
00148     //if (!localspans.isempty()) localspans.empty();
00149 
00150     if (me < np) {
00151       if (lgul) lgul->empty();
00152       else {
00153         lgul = new GridUnitList;
00154       }
00155     }
00156 
00157 //     dMapIndex *lmin = 0;
00158 //     dMapIndex lmax;
00159 
00160     unsigned long work = get_load(*ggul,olap);
00161 
00162     unsigned long thresh = (unsigned long) (1.0*(work/np)+0.5);
00163     register unsigned long curthresh = thresh;
00164 
00165     int p = 0, pcnt = 0;
00166     unsigned long tmpw = 0, w = 0;
00167 
00168     register GridUnit *tmpgu = ggul->first();
00169 
00170 #ifdef DEBUG_PRINT_DIST
00171     ( comm_service::log() << "\n{ Composite Distribution: "
00172       << np << " " << work << " " << thresh
00173       << "} \n"
00174       ).flush();
00175 #endif
00176  
00177     for (int cnt=0;tmpgu;cnt++,tmpgu=ggul->next()) {
00178         w += (tmpw = tmpgu->guWork(olap));
00179 
00180         if (p>=np) {
00181             tmpgu->guSetOwner(np-1);
00182             if (np-1 == me) {
00183                 GridUnit* newgu = lgul->add();
00184                 *newgu = *tmpgu;
00185             }
00186             continue;
00187         }
00188  
00189 #ifdef DEBUG_PRINT_DIST
00190         ( comm_service::log() << "\n{ Partitioning: "
00191           << cnt << " " << p << " "
00192           << curthresh << " " << w << " " << tmpw << " "
00193           << tmpgu->guBaseIndex()  << " "
00194           << *ggul->currec()
00195           << "} \n"
00196 
00197           ).flush();
00198 #endif
00199         
00200         if (w <= curthresh) {
00201             
00202 #ifdef DEBUG_PRINT_DIST
00203             if (p>=np)
00204                 ( comm_service::log() << "\n************* Current Composite List *************\n"
00205                   << *ggul
00206                   << "\n************* ***************** *************\n"
00207                   << "\n************* Current Bucket *************\n"
00208                   << *((SimpleBucketVoid *) ggul)
00209                   << "\n************* ***************** *************\n"
00210                   ).flush();
00211 #endif
00212 #ifdef DEBUG_PRINT
00213             assert (p<np);
00214 #endif
00215             tmpgu->guSetOwner(p); pcnt++;
00216             if (p == me)  {
00217               GridUnit* newgu = lgul->add();
00218               *newgu = *tmpgu;
00219             }
00220             continue;
00221 //          if (!lmin) lmin = new dMapIndex(tmpgu->guBaseIndex());
00222 //          lmax = tmpgu->guBaseIndex();
00223         }
00224         else 
00225             if (w-curthresh < tmpw/4) {
00226                 
00227 #ifdef DEBUG_PRINT_DIST
00228                 if (p>=np)
00229                     ( comm_service::log() << "\n************* Current Composite List *************\n"
00230                       << *ggul
00231                       << "\n************* ***************** *************\n"
00232                       << "\n************* Current Bucket *************\n"
00233                       << *((SimpleBucketVoid *) ggul)
00234                       << "\n************* ***************** *************\n"
00235                       ).flush();
00236 #endif
00237 #ifdef DEBUG_PRINT
00238                 assert(p<np);
00239 #endif
00240                 tmpgu->guSetOwner(p); pcnt++;
00241                 if (p == me) {
00242                   GridUnit* newgu = lgul->add();
00243                   *newgu = *tmpgu;
00244                 }
00245 //              lmax = tmpgu->guBaseIndex();
00246                 p++; pcnt = 0; 
00247                 if (p<np)
00248                   curthresh = w + (unsigned long) (1.0*((work>w ? work-w : 0)/(np-p))+0.5);
00249                 continue;
00250             }  
00251             else 
00252                 if (w >= curthresh && tmpgu->guExtent(tmpgu->guCrsLev()) > minw) {
00253                     w -= tmpw;
00254                     cnt--;
00255                     unsigned long oldwork = work;
00256                     ggul->decompose();
00257                     work = get_load(*ggul,olap);
00258 
00259                     //              if (work == oldwork) assert(0);
00260                   
00261 #ifdef DEBUG_PRINT_DIST
00262                     ( comm_service::log() << "\n************* After Decompose *************\n"
00263                       << "Cur Proc:" << p << " "
00264                       << *ggul->current() << "\n"
00265                       << "Cur GU:" << ggul->current() << "\n"
00266                       << "\n************* ***************** *************\n"
00267                       ).flush();
00268 #endif
00269                     thresh = (unsigned long) (1.0*(work/np)+0.5);
00270                     curthresh = curthresh+(unsigned long)(1.0*((work>oldwork ? 
00271                                   work-oldwork : 0)/(np-p))+0.5);
00272                     continue;
00273                 }
00274                 else 
00275                     if (pcnt == 0) {
00276                         
00277 #ifdef DEBUG_PRINT_DIST
00278                         if (p>=np)
00279                             ( comm_service::log() << "\n************* Current Composite List *************\n"
00280                               << *ggul
00281                               << "\n************* ***************** *************\n"
00282                               << "\n************* Current Bucket *************\n"
00283                               << *((SimpleBucketVoid *) ggul)
00284                               << "\n************* ***************** *************\n"
00285                               ).flush();
00286 #endif
00287 #ifdef DEBUG_PRINT 
00288                         assert(p<np);
00289 #endif
00290                         tmpgu->guSetOwner(p); pcnt++;
00291                         if (p == me) {  
00292                           GridUnit* newgu = lgul->add();
00293                           *newgu = *tmpgu;
00294                         }
00295 //                      lmax = tmpgu->guBaseIndex();
00296                         p++; pcnt = 0;
00297                         if (p<np)
00298                             curthresh = w + (unsigned long) (1.0*((work>w ? 
00299                                           work-w : 0)/(np-p))+0.5);
00300                         continue;
00301                     }
00302                     else  {
00303                         p++; pcnt = 0;
00304                         
00305 #ifdef DEBUG_PRINT_DIST
00306                         if (p>=np)
00307                             ( comm_service::log() << "\n************* Current Composite List *************\n"
00308                               << *ggul
00309                               << "\n************* ***************** *************\n"
00310                               << "\n************* Current Bucket *************\n"
00311                               << *((SimpleBucketVoid *) ggul)
00312                               << "\n************* ***************** *************\n"
00313                               ).flush();
00314 #endif
00315 #ifdef DEBUG_PRINT
00316                         assert(p<np);
00317 #endif
00318                         if (p>=np) continue;
00319 
00320                         tmpgu->guSetOwner(p);
00321                         if (p == me) {  
00322                           GridUnit* newgu = lgul->add();
00323                           *newgu = *tmpgu;
00324                         }
00325 //                      if (!lmin) lmin = new dMapIndex(tmpgu->guBaseIndex());
00326 //                      lmax = tmpgu->guBaseIndex();
00327                         curthresh = (w-tmpw) + (unsigned long) (1.0*((work+tmpw>w ? 
00328                                         work+tmpw-w : 0)/(np-p))+0.5);
00329                         if (w >= curthresh) {
00330                             p++; pcnt = 0;
00331                             if (p<np) 
00332                                 curthresh = w + (unsigned long) (1.0*((work>w ? 
00333                                               work-w : 0)/(np-p))+0.5);
00334                         }
00335                         continue;
00336                     }
00337     }
00338     if (p<me && me<np) {
00339       cerr << "Cannot distribute anything to processor " << me 
00340            << ". Refine base grid!\n";
00341     }
00342   }
00343 
00344 void DAGHDistribution::partitionBlockOne(const int axis,
00345                                          GridUnitList*& ggul,
00346                                          GridUnitList*& lgul,
00347                                          const int np, const int me, 
00348                                          const int minw, const short* olap)
00349   {
00350 #ifdef DEBUG_PRINT
00351     /* Cannot partition an empty list */
00352     assert(ggul->number() > 0);
00353   
00354     /* Zero procs... ? */
00355     assert(np > 0);
00356 #endif
00357 
00358     if (boxes) delete [] boxes;
00359     boxes = new BBox[np];
00360 
00361     const int flev = (ggul->first())->guFineLev();
00362     BBoxList tmpbbl;
00363     ggul->bboxlist(tmpbbl, flev, 0, 0);
00364     BBox wbbox = tmpbbl.reduce();
00365     partition_one(wbbox, boxes, np, axis);
00366 
00367     GridUnitList tmpgul;
00368     for (register int p=0;p<np;p++) {
00369       ggul->intersect(boxes[p], flev, tmpgul, 0);
00370       GridUnitList tmpgul(*ggul);
00371       tmpgul *= boxes[p];
00372       ggul->setowner(tmpgul,p);
00373       if (p == me) {
00374         if (lgul) {
00375           lgul->empty();
00376           *lgul = tmpgul;
00377         }
00378         else {
00379           lgul = new GridUnitList(tmpgul);
00380         }
00381         lgul->setowner(me);
00382       } 
00383     }
00384   }
00385 
00386 void DAGHDistribution::partitionBlockTwo(const int axis1, const int axis2,
00387                                          GridUnitList*& ggul,
00388                                          GridUnitList*& lgul,
00389                                          const int np, const int me, 
00390                                          const int minw, const short* olap)
00391   {
00392 #ifdef DEBUG_PRINT
00393     /* Cannot partition an empty list */
00394     assert(ggul->number() > 0);
00395   
00396     /* Zero procs... ? */
00397     assert(np > 0);
00398 #endif
00399 
00400     if (boxes) delete [] boxes;
00401     boxes = new BBox[np];
00402 
00403     const int flev = ggul->first()->guFineLev();
00404     BBoxList tmpbbl;
00405 
00406     ggul->bboxlist(tmpbbl, flev, 0, 0);
00407     BBox wbbox = tmpbbl.reduce();
00408     partition_two(wbbox, boxes, np, axis1, axis2);
00409     GridUnitList tmpgul;
00410     for (register int p=0;p<np;p++) {
00411       ggul->intersect(boxes[p], flev, tmpgul, 0);
00412       GridUnitList tmpgul(*ggul);
00413       tmpgul *= boxes[p];
00414       ggul->setowner(tmpgul,p);
00415       if (p == me) {
00416         if (lgul) {
00417           lgul->empty();
00418           *lgul = tmpgul;
00419         }
00420         else {
00421           lgul = new GridUnitList(tmpgul);
00422         }
00423         lgul->setowner(me);
00424       } 
00425     }
00426   }
00427 
00428 void DAGHDistribution::partitionBlockAll(GridUnitList*& ggul,
00429                                          GridUnitList*& lgul,
00430                                          const int np, const int me, 
00431                                          const int minw, const short* olap)
00432   {
00433 #ifdef DEBUG_PRINT
00434     /* Cannot partition an empty list */
00435     assert(ggul->number() > 0);
00436   
00437     /* Zero procs... ? */
00438     assert(np > 0);
00439 #endif
00440 
00441     if (boxes) delete [] boxes;
00442     boxes = new BBox[np];
00443 
00444     const int flev = (ggul->first())->guFineLev();
00445     BBoxList tmpbbl;
00446     ggul->bboxlist(tmpbbl, flev, 0, 0);
00447     BBox wbbox = tmpbbl.reduce();
00448     partition_all(wbbox, boxes, np);
00449 
00450     GridUnitList tmpgul;
00451     for (register int p=0;p<np;p++) {
00452       ggul->intersect(boxes[p], flev, tmpgul, 0);
00453       GridUnitList tmpgul(*ggul);
00454       tmpgul *= boxes[p];
00455       ggul->setowner(tmpgul,p);
00456       if (p == me) {
00457         if (lgul) {
00458           lgul->empty();
00459           *lgul = tmpgul;
00460         }
00461         else {
00462           lgul = new GridUnitList(tmpgul);
00463         }
00464         lgul->setowner(me);
00465       } 
00466     }
00467   }
00468 
00469 void DAGHDistribution::partitionUserDef(GridUnitList*& ggul,
00470                                         GridUnitList*& lgul,
00471                                         const int np, const int me, 
00472                                         const int minw, const short* olap)
00473   {
00474 #ifdef DEBUG_PRINT
00475     /* The list boxes has to be defined */
00476     assert(boxes); 
00477 
00478     /* Cannot partition an empty list */
00479     assert(ggul->number() > 0);
00480   
00481     /* Zero procs... ? */
00482     assert(np > 0);
00483 #endif
00484 
00485     const int flev = (ggul->first())->guFineLev();
00486     BBoxList tmpbbl;
00487     ggul->bboxlist(tmpbbl, flev, 0, 0);
00488     BBox wbbox = tmpbbl.reduce();
00489     partition_all(wbbox, boxes, np);
00490 
00491     GridUnitList tmpgul;
00492     for (register int p=0;p<np;p++) {
00493       ggul->intersect(boxes[p], flev, tmpgul, 0);
00494       GridUnitList tmpgul(*ggul);
00495       tmpgul *= boxes[p];
00496       ggul->setowner(tmpgul,p);
00497       if (p == me) {
00498         if (lgul) {
00499           lgul->empty();
00500           *lgul = tmpgul;
00501         }
00502         else {
00503           lgul = new GridUnitList(tmpgul);
00504         }
00505         lgul->setowner(me);
00506       } 
00507     }
00508   }
00509 
00510 /*$int DAGHDistribution::islocal(dMapIndex const &idx)
00511   {
00512     DAGHSpan *span = 0;
00513 
00514     DAGHListLoop(localspans,span,DAGHSpan) 
00515         if (span->contains(idx)) return 1;
00516     DAGHEndLoop
00517     
00518     return 0;
00519   }$*/
00520 
00521 void partition_one(const BBox& wholebbox, BBox* boxes, const int np, 
00522                    const int dim)
00523   {
00524 
00525     const int extent = wholebbox.extents(dim);
00526 
00527 #ifdef DEBUG_PRINT
00528     assert (extent >= np); // I should have atleast extent points. */
00529 #endif
00530 
00531     const int dx = extent/np;
00532     int Xtra = extent-(dx*np);
00533 
00534     for (register int p=0;p<np;p++) {
00535       const int dlower = p*dx + Min(Xtra,p);
00536       const int dupper = (np-p-1)*dx + Max((Xtra-p-1),0);
00537       boxes[p] = wholebbox;
00538       boxes[p].growlower(dim,dlower);
00539       boxes[p].growupper(dim,-dupper);
00540     }
00541   }
00542 
00543 /* A modification of pwalker_partition by Paul Walker */
00544 void partition_two(const BBox& wholebbox, BBox* boxes, const int np, 
00545                    const int dim1, const int dim2)
00546   {
00547     /* Great now figure out the decomposition in n1,n2 */
00548     int n1,n2;
00549     
00550     /* Initizialize */
00551     n1 = np;
00552     n2 = 1;
00553     if (n1 % 2 == 0) {
00554       while (n1 % 2 == 0 && n1 > n2
00555              && (abs(n1-n2) >= abs(n1/2-n2*2))) {
00556         n1 /= 2;
00557         n2 *= 2;
00558       }
00559     } else {
00560       while (n1 % 3 == 0 && n1 > n2
00561              && (abs(n1-n2) >= abs(n1/3-n2*3))) {
00562         n1 /= 3;
00563         n2 *= 3;
00564       }
00565     }
00566 
00567     const int rank = wholebbox.rank;
00568     const Coords& glb(wholebbox.lower());
00569     const Coords& gub(wholebbox.upper());
00570     const Coords& step(wholebbox.stepsize());
00571 
00572     /* Set up deltas */
00573     Coords delt(rank,0); 
00574     delt(dim1) =  (gub(dim1)-glb(dim1)+step(dim1))/n1;
00575     delt(dim2) =  (gub(dim2)-glb(dim2)+step(dim2))/n2;
00576 
00577     /* Set up correction vector */
00578     Coords cor(rank,0);
00579     cor(0) =  (gub(0)-glb(0)+step(0))%n1;
00580     cor(1) =  (gub(1)-glb(1)+step(1))%n2;
00581 
00582     /* Initialize the bboxes */
00583     for (register int p=0;p<np;p++) boxes[p] = wholebbox;
00584 
00585     for (int ii=0;ii<n1;ii++) {
00586       for (int jj=0;jj<n2;jj++) {
00587         /* We may care about topology here later... */
00588         int whichp = ii + jj*n1;
00589 
00590         Coords c1(rank,0), c2 (rank,0);
00591 
00592         c1(0) = (cor(0) > ii) ? 1 : 0;
00593         c1(1) = (cor(1) > jj) ? 1 : 0;
00594         
00595         /*$c2(0) = n1 - (cor(0) - ii) - 1;
00596         c2(1) = n2 - (cor(1) - jj) - 1;$*/
00597 
00598         c2(0) = Min(cor(0),ii);
00599         c2(1) = Min(cor(1),jj);
00600         
00601         Coords& lb(boxes[whichp].lower());
00602         Coords& ub(boxes[whichp].upper());
00603 
00604         lb(0) = glb(0) + (ii * (delt(0)) + c2(0));
00605         lb(1) = glb(1) + (jj * (delt(1)) + c2(1));
00606         
00607         ub(0) = lb(0) + delt(0) + c1(0) - 1;
00608         ub(1) = lb(1) + delt(1) + c1(1) - 1;
00609       }
00610     }
00611   }
00612 
00613 /* A modification of pwalker_partition by Paul Walker */
00614 void partition_all(const BBox& wholebbox, BBox* boxes, const int np)
00615   {
00616     /* Great now figure out the decomposition in n1,n2,n3 */
00617     int n1,n2,n3;
00618     
00619     /* Initizialize */
00620     n1 = np;
00621     n2 = 1;
00622     n3 = 1;
00623     for (register int i=0;i<2;i++) {
00624       int twof = 0;
00625       if (n1 % 2 == 0) twof = 1;
00626       if (twof) {
00627         while (n1 % 2 == 0 && n1 > n2
00628                && (abs(n1-n2) >= abs(n1/2-n2*2))) {
00629           n1 /= 2;
00630           n2 *= 2;
00631         }
00632       } else {
00633         while (n1 % 3 == 0 && n1 > n2
00634                && (abs(n1-n2) >= abs(n1/3-n2*3))) {
00635           n1 /= 3;
00636           n2 *= 3;
00637         }
00638       }
00639       twof = 0;
00640       if (n2 % 2 == 0) twof = 1;
00641       if (twof) {
00642         while (n2 % 2 == 0 && n2 > n3
00643                && (abs(n2-n3) >= abs(n2/2-n3*2))) {
00644           n2 /= 2;
00645           n3 *= 2;
00646         }
00647       } else {
00648         while (n2 % 3 == 0 && n2 > n3
00649                && (abs(n2-n3) >= abs(n2/3-n3*3))) {
00650           n2 /= 3;
00651           n3 *= 3;
00652         }
00653       }
00654     }
00655     /* Sort based on global box (later)... */ 
00656     
00657     const int rank = wholebbox.rank;
00658     const Coords& glb(wholebbox.lower());
00659     const Coords& gub(wholebbox.upper());
00660     const Coords& step(wholebbox.stepsize());
00661 
00662     /* Set up deltas */
00663     Coords delt(rank,0);
00664     delt(0) =  (gub(0)-glb(0)+step(0))/n1;
00665     delt(1) =  (gub(1)-glb(1)+step(1))/n2;
00666     delt(2) =  (gub(2)-glb(2)+step(2))/n3;
00667 
00668     /* Set up correction vector */
00669     Coords cor(rank,0);
00670     cor(0) =  (gub(0)-glb(0)+step(0))%n1;
00671     cor(1) =  (gub(1)-glb(1)+step(1))%n2;
00672     cor(2) =  (gub(2)-glb(2)+step(2))%n3;
00673     
00674     /*$comm_service::log() << "glb " << glb << endl;
00675     comm_service::log() << "gub " << gub << endl;
00676     comm_service::log() << "deltas " << delt << endl;
00677     comm_service::log() << "correction " << cor << endl;$*/
00678 
00679     /* Initialize the bboxes */
00680     for (register int p=0;p<np;p++) boxes[p] = wholebbox;
00681 
00682     for (int ii=0;ii<n1;ii++) {
00683       for (int jj=0;jj<n2;jj++) {
00684         for (int kk=0;kk<n3;kk++) {
00685           /* We may care about topology here later... */
00686           int whichp = ii + jj*n1 + kk*n1*n2;
00687           
00688           /*$comm_service::log() << whichp << " "
00689                               << ii << " "
00690                               << jj << " "
00691                               << kk << endl;$*/
00692 
00693           Coords c1(rank,0), c2 (rank,0);
00694 
00695           c1(0) = (cor(0) > ii) ? 1 : 0;
00696           c1(1) = (cor(1) > jj) ? 1 : 0;
00697           c1(2) = (cor(2) > kk) ? 1 : 0;
00698 
00699           /*$c2(0) = n1 - (cor(0) - ii) - 1;
00700           c2(1) = n2 - (cor(1) - jj) - 1;
00701           c2(2) = n3 - (cor(2) - kk) - 1;$*/
00702 
00703           c2(0) = Min(cor(0),ii);
00704           c2(1) = Min(cor(1),jj);
00705           c2(2) = Min(cor(2),kk);
00706 
00707           Coords& lb(boxes[whichp].lower());
00708           Coords& ub(boxes[whichp].upper());
00709 
00710           lb(0) = glb(0) + (ii * (delt(0)) + c2(0));
00711           lb(1) = glb(1) + (jj * (delt(1)) + c2(1));
00712           lb(2) = glb(2) + (kk * (delt(2)) + c2(2));
00713 
00714           ub(0) = lb(0) + delt(0) + c1(0) - 1;
00715           ub(1) = lb(1) + delt(1) + c1(1) - 1;
00716           ub(2) = lb(2) + delt(2) + c1(2) - 1;
00717 
00718           /*$comm_service::log() << "lb " << lb << endl;
00719           comm_service::log() << "ub " << ub << endl;$*/
00720 
00721         }
00722       }
00723     }
00724   }
00725 
00726 void pwalker_partition(const BBox& wholebbox, BBox* boxes, const int np)
00727   {
00728     Coords glb(wholebbox.lower());
00729     Coords gub(wholebbox.upper());
00730     /* Great now figure out the decomposition in nx,ny,nz */
00731     int nx,ny,nz;
00732     
00733     /* Initizialize */
00734     nx = np;
00735     ny = 1;
00736     nz = 1;
00737     for (int i=0;i<2;i++) {
00738       int twof = 0;
00739       if (nx % 2 == 0) twof = 1;
00740       if (twof) {
00741         while (nx % 2 == 0 && nx > ny
00742                && (abs(nx-ny) >= abs(nx/2-ny*2))) {
00743           nx /= 2;
00744           ny *= 2;
00745         }
00746       } else {
00747         while (nx % 3 == 0 && nx > ny
00748                && (abs(nx-ny) >= abs(nx/3-ny*3))) {
00749           nx /= 3;
00750           ny *= 3;
00751         }
00752       }
00753       twof = 0;
00754       if (ny % 2 == 0) twof = 1;
00755       if (twof) {
00756         while (ny % 2 == 0 && ny > nz
00757                && (abs(ny-nz) >= abs(ny/2-nz*2))) {
00758           ny /= 2;
00759           nz *= 2;
00760         }
00761       } else {
00762         while (ny % 3 == 0 && ny > nz
00763                && (abs(ny-nz) >= abs(ny/3-nz*3))) {
00764           ny /= 3;
00765           nz *= 3;
00766         }
00767       }
00768     }
00769     /* Sort based on global box (later)... */ 
00770     
00771     /* Now make the coordinates for each box ... */
00772     BBox mt(3,0);
00773     for (int p=0;p<np;p++) boxes[p] = mt;
00774     
00775     int ii,jj,kk;
00776     int *delt = new int[3], *layout = new int[3];
00777 
00778     /* Set up layout and deltas */
00779     layout[0] = nx; layout[1] = ny; layout[2] = nz;
00780     for (int mm=0;mm<3;mm++) {
00781       delt[mm] =  (gub(mm)-glb(mm))/layout[mm];
00782     }
00783 
00784     Coords mylb(3,0),myub(3,0);
00785     for (ii=0;ii<nx;ii++)
00786       for (jj=0;jj<ny;jj++)
00787         for (kk=0;kk<nz;kk++) {
00788           /* We may care about topology here later... */
00789           int whichp = ii + jj*nx + kk*nx*ny;
00790           mylb(0) = delt[0]*ii;
00791           mylb(1) = delt[1]*jj;
00792           mylb(2) = delt[2]*kk;
00793 
00794           myub(0) = 
00795             (ii != nx-1 ? delt[0]*(ii+1)-1 : gub(0));
00796           myub(1) = 
00797             (jj != ny-1 ? delt[1]*(jj+1)-1 : gub(1));
00798           myub(2) = 
00799             (kk != nz-1 ? delt[2]*(kk+1)-1 : gub(2));
00800 
00801           boxes[whichp].setlower(mylb);
00802           boxes[whichp].setupper(myub);
00803           boxes[whichp].setstepsize(0,1);
00804           boxes[whichp].setstepsize(1,1);
00805           boxes[whichp].setstepsize(2,1);
00806         }
00807 }


Quickstart     Users Guide     Programmers Reference     Installation      Examples     Download



AMROC Main      Home      Contact
last update: 06/01/04