00001
00002 #include "mpi.h"
00003 #include "petsc.h"
00004 #include "sys.h"
00005 #include "octUtils.h"
00006 #include "parUtils.h"
00007 #include "TreeNode.h"
00008 #include <cstdlib>
00009 #include <cstring>
00010 #include "externVars.h"
00011 #include "dendro.h"
00012
00013
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 bool rePart = 1;
00024 bool checkBailOut = 1;
00025 unsigned int numPts;
00026 unsigned int rippleType = 2;
00027 unsigned int writePOut = 0;
00028 unsigned int writeBOut = 0;
00029 unsigned int readPtsFile = 0;
00030 unsigned int readOctFile =0;
00031 unsigned int runOpt =2;
00032 char Kstr[20];
00033 char inpFileName[50],p2nOut[50],n2oOut[50],balOut[50];
00034 double gSize[3];
00035
00036 PetscInitialize(&argc,&argv,"options",NULL);
00037 ot::RegisterEvents();
00038
00039 #ifdef PETSC_USE_LOG
00040 int stages[4];
00041 PetscLogStageRegister(&stages[0],"Prepare Input.");
00042 PetscLogStageRegister(&stages[1],"P2O");
00043 PetscLogStageRegister(&stages[2],"N2O");
00044 PetscLogStageRegister(&stages[3],"Bal");
00045 #endif
00046
00047 MPI_Comm_size(MPI_COMM_WORLD,&size);
00048 MPI_Comm_rank(MPI_COMM_WORLD,&rank);
00049 if(argc < 3) {
00050 std::cerr << "Usage: " << argv[0] << " inpfile complx incInt[1] runOpt[2]"<<
00051 "readPtsFile[0] readOctFile[0] maxDepth[30] writePOut[0] writeBOut[0]"<<
00052 " dim[3] maxNumPtsPerOctant[1] incCorner[1] checkBailOut[1] rePart[1]"<<
00053 " rippleType[2]" << std::endl;
00054 return -1;
00055 }
00056 unsigned int maxNumPts= 1;
00057 int complx = atoi(argv[2]);
00058 unsigned int dim=3;
00059 unsigned int maxDepth=30;
00060 if(argc > 3) {
00061 incInt = atoi(argv[3]);
00062 }
00063 if(argc > 4) {
00064 runOpt = atoi(argv[4]);
00065 }
00066 if(argc > 5) {
00067 readPtsFile = atoi(argv[5]);
00068 }
00069 if(argc > 6) {
00070 readOctFile = atoi(argv[6]);
00071 }
00072 if(argc > 7) {
00073 maxDepth = atoi(argv[7]);
00074 }
00075 if(argc > 8) {
00076 writePOut = atoi(argv[8]);
00077 }
00078 if(argc > 9) {
00079 writeBOut = atoi(argv[9]);
00080 }
00081 if(argc > 10) {
00082 dim = atoi(argv[10]);
00083 }
00084 if(argc > 11) {
00085 maxNumPts = atoi(argv[11]);
00086 }
00087 if(argc > 12) { incCorner = (bool)(atoi(argv[12]));}
00088 if(argc > 13) { checkBailOut = (bool)(atoi(argv[13]));}
00089 if(argc > 14) { rePart = (bool)(atoi(argv[14]));}
00090 if(argc > 15) { rippleType = atoi(argv[15]);}
00091
00092 strcpy(inpFileName, argv[1]);
00093 strcpy(balOut,inpFileName);
00094 ot::int2str(rank,Kstr);
00095 strcat(balOut,Kstr);
00096 strcat(balOut,"_\0");
00097 ot::int2str(size,Kstr);
00098 strcat(balOut,Kstr);
00099 strcpy(n2oOut,balOut);
00100 strcpy(p2nOut,balOut);
00101 strcat(balOut,"_Bal.ot\0");
00102 strcat(n2oOut,"_Con.ot\0");
00103 strcat(p2nOut,".pts\0");
00104 strcat(inpFileName,".inp\0");
00105 std::vector<ot::TreeNode> nodes;
00106 std::vector<double> pts;
00107 unsigned int ptsLen;
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 #ifdef PETSC_USE_LOG
00118 PetscLogStagePush(stages[0]);
00119 #endif
00120 if(runOpt == 1 || runOpt == 2) {
00121 if(readPtsFile) {
00122 if(!rank){
00123 std::cout << " reading "<<p2nOut<<std::endl;
00124 }
00125 ot::readPtsFromFile(p2nOut, pts);
00126 if(!rank){
00127 std::cout << " finished reading "<<p2nOut<<std::endl;
00128 }
00129 ptsLen = pts.size();
00130 std::vector<ot::TreeNode> tmpNodes;
00131 for(int i=0;i<ptsLen;i+=3) {
00132 if( (pts[i] > 0.0) &&
00133 (pts[i+1] > 0.0)
00134 && (pts[i+2] > 0.0) &&
00135 ( ((unsigned int)(pts[i]*((double)(1u << maxDepth)))) < (1u << maxDepth)) &&
00136 ( ((unsigned int)(pts[i+1]*((double)(1u << maxDepth)))) < (1u << maxDepth)) &&
00137 ( ((unsigned int)(pts[i+2]*((double)(1u << maxDepth)))) < (1u << maxDepth)) ) {
00138 tmpNodes.push_back( ot::TreeNode((unsigned int)(pts[i]*(double)(1u << maxDepth)),
00139 (unsigned int)(pts[i+1]*(double)(1u << maxDepth)),
00140 (unsigned int)(pts[i+2]*(double)(1u << maxDepth)),
00141 maxDepth,dim,maxDepth) );
00142 }
00143 }
00144 pts.clear();
00145
00146 par::removeDuplicates<ot::TreeNode>(tmpNodes,false,MPI_COMM_WORLD);
00147
00148 nodes = tmpNodes;
00149 tmpNodes.clear();
00150 par::partitionW<ot::TreeNode>(nodes, NULL,MPI_COMM_WORLD);
00151
00152 DendroIntL locSz, totalSz;
00153 locSz = nodes.size();
00154
00155 par::Mpi_Reduce<DendroIntL>(&locSz, &totalSz, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00156
00157 if(rank==0) {
00158 std::cout<<"rank= "<<rank<<" size= " << size << " total pts= " << totalSz<<std::endl;
00159 }
00160
00161 pts.resize(3*(nodes.size()));
00162 ptsLen = (3*(nodes.size()));
00163 for(int i=0;i<nodes.size();i++) {
00164 pts[3*i] = (((double)(nodes[i].getX())) + 0.5)/((double)(1u << maxDepth));
00165 pts[(3*i)+1] = (((double)(nodes[i].getY())) +0.5)/((double)(1u << maxDepth));
00166 pts[(3*i)+2] = (((double)(nodes[i].getZ())) +0.5)/((double)(1u << maxDepth));
00167 }
00168 nodes.clear();
00169 }
00170 gSize[0] = 1.;
00171 gSize[1] = 1.;
00172 gSize[2] = 1.;
00173 if(writePOut) {
00174 ot::writePtsToFile(p2nOut,pts);
00175 }
00176 #ifdef PETSC_USE_LOG
00177 PetscLogStagePop();
00178 #endif
00179 MPI_Barrier(MPI_COMM_WORLD);
00180 #ifdef PETSC_USE_LOG
00181 PetscLogStagePush(stages[1]);
00182 #endif
00183 startTime = MPI_Wtime();
00184 ot::points2Octree(pts, gSize, nodes, dim, maxDepth, maxNumPts, MPI_COMM_WORLD);
00185 endTime = MPI_Wtime();
00186 #ifdef PETSC_USE_LOG
00187 PetscLogStagePop();
00188 #endif
00189 double locTime, totalTime, minTime;
00190 locTime = endTime - startTime;
00191 par::Mpi_Reduce<double>(&locTime, &totalTime, 1, MPI_MAX, 0, MPI_COMM_WORLD);
00192 par::Mpi_Reduce<double>(&locTime, &minTime, 1, MPI_MIN, 0, MPI_COMM_WORLD);
00193 if(!rank){
00194 std::cout <<"P2n Time: "<<totalTime << " " << "secs imbalance: "<< totalTime/minTime << std::endl;
00195 }
00196 pts.clear();
00197 }
00198
00199 if(runOpt == 0 || runOpt == 2) {
00200 if(readOctFile) {
00201 ot::readNodesFromFile(n2oOut,nodes);
00202 }
00203 std::vector<ot::TreeNode > linOct;
00204 #ifdef PETSC_USE_LOG
00205 PetscLogStagePush(stages[2]);
00206 #endif
00207 DendroIntL inputNodes = nodes.size();
00208 DendroIntL totInp;
00209 par::Mpi_Reduce<DendroIntL>(&inputNodes, &totInp, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00210 if(!rank) {
00211 std::cout << "Nodes after p2o: "<< totInp << std::endl;
00212 }
00213 ot::completeOctree(nodes,linOct,dim,maxDepth,false, false, false, MPI_COMM_WORLD);
00214 #ifdef PETSC_USE_LOG
00215 PetscLogStagePop();
00216 #endif
00217
00218 assert(!linOct.empty());
00219 if(writeBOut) {
00220 ot::writeNodesToFile(n2oOut,linOct);
00221 }
00222 inputNodes = linOct.size();
00223 nodes.clear();
00224 std::vector<ot::TreeNode > balOct;
00225
00226 par::Mpi_Reduce<DendroIntL>(&inputNodes, &totInp, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00227 if(!rank) {
00228 std::cout << "Nodes before balancing: "<< totInp << std::endl;
00229 }
00230
00231 balOct = linOct;
00232 linOct.clear();
00233
00234 MPI_Barrier(MPI_COMM_WORLD);
00235 #ifdef PETSC_USE_LOG
00236 PetscLogStagePush(stages[3]);
00237 #endif
00238 startTime = MPI_Wtime();
00239 if(rippleType == 1) {
00240 if(!rank) {
00241 std::cout<<"Type -1 ripple."<<std::endl;
00242 }
00243 ot::parallelRippleType1(balOct,incCorner,checkBailOut,rePart,dim, maxDepth, MPI_COMM_WORLD);
00244 }else if(rippleType == 2) {
00245 if(!rank) {
00246 std::cout<<"Type -2 ripple."<<std::endl;
00247 }
00248 ot::parallelRippleType2(balOct,incCorner,checkBailOut,rePart,dim, maxDepth, MPI_COMM_WORLD);
00249 }else {
00250 if(!rank) {
00251 std::cout<<"Type -3 ripple."<<std::endl;
00252 }
00253 ot::parallelRippleType3(balOct,incCorner,checkBailOut,rePart,dim, maxDepth, MPI_COMM_WORLD);
00254 }
00255 endTime = MPI_Wtime();
00256 #ifdef PETSC_USE_LOG
00257 PetscLogStagePop();
00258 #endif
00259 assert(!balOct.empty());
00260 if(writeBOut) {
00261 ot::writeNodesToFile(balOut,balOct);
00262 }
00263
00264 DendroIntL locBalNodes = balOct.size();
00265 DendroIntL totBal;
00266 double balTime, totTime;
00267 balTime = endTime - startTime;
00268 par::Mpi_Reduce<DendroIntL>(&locBalNodes, &totBal, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00269 par::Mpi_Reduce<double>(&balTime, &totTime, 1, MPI_MAX, 0, MPI_COMM_WORLD);
00270 par::Mpi_Reduce<double>(&balTime, &minTime, 1, MPI_MIN, 0, MPI_COMM_WORLD);
00271
00272 if(!rank) {
00273 std::cout << "Nodes after balancing: "<< totBal << std::endl;
00274 std::cout << "bal Time: "<<totTime << " " << "secs imbalance: "<< totTime/minTime << std::endl;
00275 }
00276
00277 balOct.clear();
00278 }
00279 PetscFinalize();
00280 }
00281