Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

checkCoarsening.C

Go to the documentation of this file.
00001 
00002 #include "mpi.h"
00003 #include "petsc.h"
00004 #include "sys.h"
00005 #include "octUtils.h"
00006 #include "TreeNode.h"
00007 #include "parUtils.h"
00008 #include "testUtils.h"
00009 #include <cstring>
00010 #include "externVars.h"
00011 #include "dendro.h"
00012 
00013 //Don't want time to be synchronized. Need to check load imbalance.
00014 #ifdef MPI_WTIME_IS_GLOBAL
00015 #undef MPI_WTIME_IS_GLOBAL
00016 #endif
00017 
00018 int main(int argc, char ** argv ) {     
00019   int size, rank;
00020   double startTime, endTime, minTime;
00021   unsigned int incInt = 1;
00022   bool incCorner = 1;  
00023   unsigned int numPts;
00024   unsigned int writePOut = 0;
00025   unsigned int writeBOut = 0;
00026   unsigned int readPtsFile = 0;
00027   unsigned int readOctFile =0;
00028   unsigned int runOpt =2;//2 for both, 1 for pt alone and 0 for bal alone.
00029   char Kstr[20];
00030   char inpFileName[50],p2nOut[50],n2oOut[50],balOut[50],coarseOut[50];
00031   double gSize[3];
00032 
00033   PetscInitialize(&argc,&argv,"options",NULL);
00034   ot::RegisterEvents();
00035 
00036 #ifdef PETSC_USE_LOG
00037   int stages[4];
00038   PetscLogStageRegister(&stages[0],"Prepare Input.");
00039   PetscLogStageRegister(&stages[1],"P2O");
00040   PetscLogStageRegister(&stages[2],"N2O");
00041   PetscLogStageRegister(&stages[3],"Bal");
00042 #endif
00043 
00044   MPI_Comm_size(MPI_COMM_WORLD,&size);
00045   MPI_Comm_rank(MPI_COMM_WORLD,&rank);
00046   if(argc < 3) {
00047     std::cerr << "Usage: " << argv[0] << " inpfile complx incInt[1] runOpt[2]"<<
00048       "readPtsFile[0] readOctFile[0] maxDepth[30] writePOut[0] writeBOut[0]"<<
00049       " dim[3] maxNumPtsPerOctant[1] incCorner[0] "  << std::endl;
00050     return -1;
00051   }
00052   unsigned int maxNumPts= 1;
00053   int complx = atoi(argv[2]);   
00054   unsigned int dim=3;
00055   unsigned int maxDepth=30;
00056   if(argc > 3) {
00057     incInt = atoi(argv[3]);
00058   }
00059   if(argc > 4) {
00060     runOpt = atoi(argv[4]);
00061   }
00062   if(argc > 5) {
00063     readPtsFile = atoi(argv[5]);
00064   }
00065   if(argc > 6) {
00066     readOctFile = atoi(argv[6]);
00067   }
00068   if(argc > 7) {
00069     maxDepth = atoi(argv[7]);
00070   }
00071   if(argc > 8) {
00072     writePOut = atoi(argv[8]);
00073   }
00074   if(argc > 9) {
00075     writeBOut = atoi(argv[9]);
00076   }
00077   if(argc > 10) {
00078     dim = atoi(argv[10]);
00079   }
00080   if(argc > 11) {
00081     maxNumPts = atoi(argv[11]);
00082   }
00083   if(argc > 12) { incCorner = (bool)(atoi(argv[12]));}
00084 
00085   strcpy(inpFileName, argv[1]);
00086   strcpy(balOut,inpFileName);
00087   ot::int2str(rank,Kstr);
00088   strcat(balOut,Kstr);
00089   strcat(balOut,"_\0");
00090   ot::int2str(size,Kstr);
00091   strcat(balOut,Kstr);
00092   strcpy(n2oOut,balOut);
00093   strcpy(p2nOut,balOut);
00094   strcpy(coarseOut,balOut);
00095   strcat(balOut,"_Bal.ot\0");
00096   strcat(coarseOut,"_Coarse.ot\0");
00097   strcat(n2oOut,"_Con.ot\0");
00098   strcat(p2nOut,".pts\0");
00099   strcat(inpFileName,".inp\0"); 
00100   std::vector<ot::TreeNode> nodes;
00101   std::vector<double> pts;
00102   unsigned int ptsLen;
00103 
00104   // print out the format ...
00105   /*
00106      if (!rank) {
00107      cout << "============================================================================================" << endl;
00108      cout << "#Points p2n_time p2n_imbal #cellsConstr #cellsBal bal_time bal_imbal maxLevBef minLevBef avgLevBef maxLevAft minLevAft avgLevAft" << endl;
00109      cout << "============================================================================================" << endl << endl;
00110      }
00111      */
00112 #ifdef PETSC_USE_LOG
00113   PetscLogStagePush(stages[0]);
00114 #endif
00115   if(runOpt == 1 || runOpt == 2)  {
00116     if(readPtsFile) {
00117       if(!rank){
00118         std::cout << " reading  "<<p2nOut<<std::endl; // Point size
00119       }
00120       ot::readPtsFromFile(p2nOut, pts);
00121       if(!rank){
00122         std::cout << " finished reading  "<<p2nOut<<std::endl; // Point size
00123       }
00124       ptsLen = pts.size();
00125       std::vector<ot::TreeNode> tmpNodes;
00126       for(unsigned int i = 0; i < ptsLen; i+= 3) {
00127         if( (pts[i] > 0.0) &&
00128             (pts[i+1] > 0.0)  
00129             && (pts[i+2] > 0.0) &&
00130             ( (static_cast<unsigned int>(pts[i]*(static_cast<double>(1u<<maxDepth)))) < (1u<<maxDepth))  &&
00131             ( (static_cast<unsigned int>(pts[i+1]*(static_cast<double>(1u<<maxDepth)))) < (1u<<maxDepth))  &&
00132             ( (static_cast<unsigned int>(pts[i+2]*(static_cast<double>(1u<<maxDepth)))) < (1u<<maxDepth)) ) {
00133           tmpNodes.push_back( ot::TreeNode(
00134                 static_cast<unsigned int>(pts[i]*static_cast<double>(1u<<maxDepth)),
00135                 static_cast<unsigned int>(pts[i+1]*static_cast<double>(1u<<maxDepth)),
00136                 static_cast<unsigned int>(pts[i+2]*static_cast<double>(1u<<maxDepth)),
00137                 maxDepth,dim,maxDepth) );
00138         }
00139       }
00140       pts.clear();
00141 
00142       par::removeDuplicates<ot::TreeNode>(tmpNodes,false,MPI_COMM_WORLD);       
00143 
00144       nodes = tmpNodes;
00145       tmpNodes.clear();
00146       par::partitionW<ot::TreeNode>(nodes, NULL,MPI_COMM_WORLD);
00147       // reduce and only print the total ...
00148       DendroIntL locSz, totalSz;
00149       locSz = nodes.size();
00150 
00151       par::Mpi_Reduce<DendroIntL>(&locSz, &totalSz, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00152 
00153       if(rank==0) {
00154         std::cout<<"rank= "<<rank<<" size= " << size << " total pts= " << totalSz<<std::endl;
00155       }
00156 
00157       pts.resize(3*(nodes.size()));
00158       ptsLen = (3*(nodes.size()));
00159       for(unsigned int i = 0; i < nodes.size(); i++) {
00160         pts[3*i] = (((double)(nodes[i].getX())) + 0.5)/((double)(1u << maxDepth));
00161         pts[(3*i)+1] = (((double)(nodes[i].getY())) +0.5)/((double)(1u << maxDepth));
00162         pts[(3*i)+2] = (((double)(nodes[i].getZ())) +0.5)/((double)(1u << maxDepth));
00163       }//end for i
00164       nodes.clear();
00165     }
00166     gSize[0] = 1.;
00167     gSize[1] = 1.;
00168     gSize[2] = 1.;
00169 #ifdef PETSC_USE_LOG
00170     PetscLogStagePop();
00171 #endif
00172     MPI_Barrier(MPI_COMM_WORLD);        
00173 #ifdef PETSC_USE_LOG
00174     PetscLogStagePush(stages[1]);
00175 #endif
00176     startTime = MPI_Wtime();
00177     ot::points2Octree(pts, gSize, nodes, dim, maxDepth, maxNumPts, MPI_COMM_WORLD);
00178     endTime = MPI_Wtime();
00179 #ifdef PETSC_USE_LOG
00180     PetscLogStagePop();
00181 #endif
00182     double locTime, totalTime, minTime;
00183     locTime = endTime - startTime;
00184     par::Mpi_Reduce<double>(&locTime, &totalTime, 1, MPI_MAX, 0, MPI_COMM_WORLD);
00185     par::Mpi_Reduce<double>(&locTime, &minTime, 1, MPI_MIN, 0, MPI_COMM_WORLD);
00186     if(!rank){
00187       std::cout <<"P2n Time: "<<totalTime << " " << "secs imbalance: "<< totalTime/minTime << std::endl;
00188     }
00189     pts.clear();
00190   }
00191   //TestBuildOCt from here on:
00192   if(runOpt == 0 || runOpt == 2) {
00193     if(readOctFile) {
00194       ot::readNodesFromFile(n2oOut,nodes);
00195     }
00196     std::vector<ot::TreeNode > linOct;  
00197 #ifdef PETSC_USE_LOG
00198     PetscLogStagePush(stages[2]);
00199 #endif
00200     DendroIntL inputNodes = nodes.size();
00201     DendroIntL totInp;
00202     par::Mpi_Reduce<DendroIntL>(&inputNodes, &totInp, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00203     if(!rank) {
00204       std::cout << "Nodes after p2o: "<< totInp  << std::endl;       
00205     }
00206     ot::completeOctree(nodes, linOct, dim, maxDepth, false, false, false, MPI_COMM_WORLD);
00207 #ifdef PETSC_USE_LOG
00208     PetscLogStagePop();
00209 #endif
00210 
00211     assert(!linOct.empty());
00212     if(writeBOut) { 
00213       ot::writeNodesToFile(n2oOut,linOct);
00214     }
00215     inputNodes = linOct.size();
00216     nodes.clear();
00217     std::vector<ot::TreeNode > balOct;
00218 
00219     par::Mpi_Reduce<DendroIntL>(&inputNodes, &totInp, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00220     if(!rank) {
00221       std::cout << "Nodes before balancing: "<< totInp  << std::endl;       
00222     }
00223 
00224     MPI_Barrier(MPI_COMM_WORLD);        
00225 #ifdef PETSC_USE_LOG
00226     PetscLogStagePush(stages[3]);
00227 #endif
00228     startTime = MPI_Wtime();
00229 
00230     ot::balanceOctree (linOct, balOct, dim, maxDepth, incCorner, MPI_COMM_WORLD, NULL, NULL);
00231     endTime = MPI_Wtime();
00232     MPI_Barrier(MPI_COMM_WORLD);        
00233     if(!rank) {
00234       std::cout << "balancing time: "<< (endTime-startTime)  << std::endl;       
00235     }
00236 
00237 #ifdef PETSC_USE_LOG
00238     PetscLogStagePop();
00239 #endif
00240     assert(!balOct.empty());
00241     if(writeBOut) { 
00242       ot::writeNodesToFile(balOut,balOct);
00243     }
00244     // compute total inp size and output size
00245     DendroIntL locBalNodes = balOct.size();
00246     DendroIntL totBal, totBalC, totBalSc;
00247     double balTime, totTime;
00248     balTime = endTime - startTime;
00249     par::Mpi_Reduce<DendroIntL>(&locBalNodes, &totBal, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00250     if(!rank) {
00251       std::cout << "Nodes after balancing: "<< totBal  << std::endl;       
00252     }
00253 
00254     std::vector<ot::TreeNode> allBal;
00255     std::vector<ot::TreeNode> allBalC;
00256     std::vector<ot::TreeNode> cBalP1;
00257     std::vector<ot::TreeNode> coarserOct;
00258     std::vector<ot::TreeNode> simpleCoarserOct;
00259 
00260     MPI_Barrier(MPI_COMM_WORLD);        
00261     startTime = MPI_Wtime();
00262     ot::coarsenOctree(balOct, coarserOct, dim, maxDepth, MPI_COMM_WORLD, false, NULL, NULL);
00263     endTime = MPI_Wtime();
00264     MPI_Barrier(MPI_COMM_WORLD);        
00265     if(writeBOut) { 
00266       ot::writeNodesToFile(coarseOut,coarserOct);
00267     }
00268     if(!rank) {
00269       std::cout << "coarsening time: "<< (endTime-startTime)  << std::endl;       
00270     }
00271 
00272     MPI_Barrier(MPI_COMM_WORLD);        
00273     startTime = MPI_Wtime();
00274     ot::simpleCoarsen(balOct, simpleCoarserOct, MPI_COMM_WORLD);
00275     endTime = MPI_Wtime();
00276     MPI_Barrier(MPI_COMM_WORLD);        
00277     if(!rank) {
00278       std::cout << " simple coarsening time: "<< (endTime-startTime)  << std::endl;       
00279     }
00280 
00281     DendroIntL locBalC = coarserOct.size();
00282     DendroIntL locBalSc = simpleCoarserOct.size();
00283     par::Mpi_Reduce<DendroIntL>(&locBalC, &totBalC, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00284     par::Mpi_Reduce<DendroIntL>(&locBalSc, &totBalSc, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00285     //nodes are partitioned
00286     if(!rank) {
00287       std::cout << "Nodes after Coarsening: "<< totBalC  << std::endl;       
00288       std::cout << "Nodes after simple Coarsening: "<< totBalSc  << std::endl;       
00289     }
00290 
00291     assert(simpleCoarserOct == coarserOct);
00292     simpleCoarserOct.clear();
00293 
00294     if(!rank) {
00295       std::cout<<"coarsening and simpleCoarsening match."<<std::endl;
00296     }
00297 
00298     if(rank) {
00299       allBal.resize(0);
00300       allBalC.resize(0);
00301     }else {
00302       allBal.resize(totBal);
00303       allBalC.resize(totBalC);
00304     }
00305 
00306     MPI_Barrier(MPI_COMM_WORLD);        
00307     startTime = MPI_Wtime();
00308     par::scatterValues<ot::TreeNode>(balOct, allBal, allBal.size(), MPI_COMM_WORLD);
00309     endTime = MPI_Wtime();
00310     MPI_Barrier(MPI_COMM_WORLD);        
00311     if(!rank) {
00312       std::cout << "scatter-1 time: "<< (endTime-startTime)  << std::endl;       
00313     }
00314 
00315     MPI_Barrier(MPI_COMM_WORLD);        
00316     startTime = MPI_Wtime();
00317     par::scatterValues<ot::TreeNode>(coarserOct, allBalC, allBalC.size(), MPI_COMM_WORLD);
00318     endTime = MPI_Wtime();
00319     MPI_Barrier(MPI_COMM_WORLD);        
00320     if(!rank) {
00321       std::cout << "scatter-2 time: "<< (endTime-startTime)  << std::endl;       
00322     }
00323 
00324     MPI_Comm zeroOnlyComm;
00325     if(size > 1) {
00326       par::splitComm2way(rank, &zeroOnlyComm, MPI_COMM_WORLD);
00327     }
00328 
00329     if(!rank) {
00330       bool failed;
00331       failed = seq::test::isUniqueAndSorted<ot::TreeNode>(allBal);      
00332       assert(failed);   
00333       std::cout<<"Fine is unique and sorted."<<std::endl;
00334 
00335       failed = ot::test::isLinear(allBal);
00336       assert(failed);   
00337       std::cout<<"Fine is linear."<<std::endl;
00338 
00339       failed = ot::test::isComplete(allBal);    
00340       assert(failed);   
00341       std::cout<<"Fine is complete."<<std::endl;
00342 
00343       failed = ot::test::isBalanced(dim,maxDepth,
00344           "failedCheck_2_1_",allBal, incCorner,1);
00345       assert(failed);   
00346       std::cout<<"Fine is balanced."<<std::endl;
00347 
00348       //coarser
00349       failed = seq::test::isUniqueAndSorted<ot::TreeNode>(allBalC);     
00350       assert(failed);   
00351       std::cout<<"Coarse is unique and sorted."<<std::endl;
00352 
00353       failed = ot::test::isLinear(allBalC);     
00354       assert(failed);   
00355       std::cout<<"Coarse is linear."<<std::endl;
00356 
00357       failed = ot::test::isComplete(allBalC);   
00358       assert(failed);   
00359       std::cout<<"Coarse is complete."<<std::endl;
00360 
00361       failed = ot::test::isBalanced(dim,maxDepth,
00362           "failedCheck_4_1_",allBalC, incCorner,2);     
00363       assert(failed);   
00364       std::cout<<"Coarse is balanced."<<std::endl;
00365 
00366       if(size > 1) {
00367         ot::coarsenOctree(allBal, cBalP1, dim, maxDepth, zeroOnlyComm, false, NULL, NULL);
00368         assert(cBalP1 == allBalC);
00369         std::cout<<"Coarsening in parallel is the same as coarsening on 1 processor."<<std::endl;
00370       }
00371     }
00372 
00373     allBal.clear();
00374     allBalC.clear();
00375 
00376     par::Mpi_Reduce<double>(&balTime, &totTime, 1, MPI_MAX, 0, MPI_COMM_WORLD);
00377     par::Mpi_Reduce<double>(&balTime, &minTime, 1, MPI_MIN, 0, MPI_COMM_WORLD);
00378 
00379     if(!rank) {
00380       std::cout << "bal Time: "<<totTime << " " << "secs imbalance: "<< totTime/minTime << std::endl;
00381     }
00382     linOct.clear();
00383     balOct.clear();
00384   }
00385 
00386   PetscFinalize();
00387 
00388 }
00389 

Generated on Tue Mar 24 16:14:07 2009 for DENDRO by  doxygen 1.3.9.1