00001
00002 #include "mpi.h"
00003 #include "petsc.h"
00004 #include "sys.h"
00005 #include "parUtils.h"
00006 #include "octUtils.h"
00007 #include "TreeNode.h"
00008 #include <cstdlib>
00009 #include "externVars.h"
00010 #include "dendro.h"
00011
00012 #ifdef MPI_WTIME_IS_GLOBAL
00013 #undef MPI_WTIME_IS_GLOBAL
00014 #endif
00015
00016 double gaussian(double mean, double std_deviation);
00017
00018 int main(int argc, char ** argv ) {
00019 int size, rank;
00020 double startTime, endTime;
00021 double localTime, globalTime;
00022 double gSize[3];
00023 unsigned int local_num_pts = 5000;
00024 unsigned int dim = 3;
00025 unsigned int maxDepth = 30;
00026 unsigned int maxNumPts = 1;
00027 bool writePts = false;
00028 bool incCorner = 1;
00029 std::vector<ot::TreeNode> linOct;
00030 std::vector<ot::TreeNode> balOct;
00031 std::vector<ot::TreeNode> tmpNodes;
00032 std::vector<double> pts;
00033 unsigned int ptsLen;
00034 DendroIntL localSz, totalSz;
00035
00036 PetscInitialize(&argc, &argv, "options", NULL);
00037 ot::RegisterEvents();
00038
00039 #ifdef PETSC_USE_LOG
00040 int stages[3];
00041 PetscLogStageRegister(&stages[0], "Main");
00042 PetscLogStageRegister(&stages[1], "P2O");
00043 PetscLogStageRegister(&stages[2], "Bal");
00044 #endif
00045
00046 #ifdef PETSC_USE_LOG
00047 PetscLogStagePush(stages[0]);
00048 #endif
00049
00050 MPI_Comm_size(MPI_COMM_WORLD, &size);
00051 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
00052
00053 if(argc > 1) {
00054 local_num_pts = atoi(argv[1]);
00055 }
00056
00057 if(argc > 2) {
00058 dim = atoi(argv[2]);
00059 }
00060
00061 if(argc > 3) {
00062 maxDepth = atoi(argv[3]);
00063 }
00064
00065 if(argc > 4) {
00066 maxNumPts = atoi(argv[4]);
00067 }
00068
00069 if(argc > 5) {
00070 incCorner = (bool)(atoi(argv[5]));
00071 }
00072
00073 if(argc > 6) {
00074 writePts = (bool)(atoi(argv[6]));
00075 }
00076
00077 MPI_Barrier(MPI_COMM_WORLD);
00078 if(!rank){
00079 std::cout << "Creating points on the fly... "<<std::endl;
00080 }
00081
00082 startTime = MPI_Wtime();
00083
00084 srand48(0x12345678 + 76543*rank);
00085
00086 pts.resize(3*local_num_pts);
00087 for(unsigned int i = 0; i < (3*local_num_pts); i++) {
00088 pts[i]= gaussian(0.5, 0.16);
00089 }
00090
00091 MPI_Barrier(MPI_COMM_WORLD);
00092 if(!rank){
00093 std::cout << " finished creating points "<<std::endl;
00094 }
00095 endTime = MPI_Wtime();
00096 localTime = endTime - startTime;
00097 if(!rank){
00098 std::cout <<"point generation time: "<<localTime << std::endl;
00099 }
00100
00101 ptsLen = pts.size();
00102
00103 if(writePts) {
00104 char ptsFileName[100];
00105 sprintf(ptsFileName, "tempPts%d_%d.pts", rank, size);
00106 ot::writePtsToFile(ptsFileName, pts);
00107 }
00108
00109 for(unsigned int i = 0; i < ptsLen; i+=3) {
00110 if( (pts[i] > 0.0) &&
00111 (pts[i+1] > 0.0)
00112 && (pts[i+2] > 0.0) &&
00113 ( ((unsigned int)(pts[i]*((double)(1u << maxDepth)))) < (1u << maxDepth)) &&
00114 ( ((unsigned int)(pts[i+1]*((double)(1u << maxDepth)))) < (1u << maxDepth)) &&
00115 ( ((unsigned int)(pts[i+2]*((double)(1u << maxDepth)))) < (1u << maxDepth)) ) {
00116 tmpNodes.push_back( ot::TreeNode((unsigned int)(pts[i]*(double)(1u << maxDepth)),
00117 (unsigned int)(pts[i+1]*(double)(1u << maxDepth)),
00118 (unsigned int)(pts[i+2]*(double)(1u << maxDepth)),
00119 maxDepth,dim,maxDepth) );
00120 }
00121 }
00122 pts.clear();
00123
00124 MPI_Barrier(MPI_COMM_WORLD);
00125
00126 if(!rank){
00127 std::cout <<"Removing bad points... "<<localTime << std::endl;
00128 }
00129
00130 par::removeDuplicates<ot::TreeNode>(tmpNodes, false, MPI_COMM_WORLD);
00131 linOct = tmpNodes;
00132 tmpNodes.clear();
00133
00134 MPI_Barrier(MPI_COMM_WORLD);
00135
00136 if(!rank){
00137 std::cout <<"Partitioning Input... "<<localTime << std::endl;
00138 }
00139
00140 par::partitionW<ot::TreeNode>(linOct, NULL, MPI_COMM_WORLD);
00141
00142
00143 localSz = linOct.size();
00144 par::Mpi_Reduce<DendroIntL>(&localSz, &totalSz, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00145
00146 MPI_Barrier(MPI_COMM_WORLD);
00147
00148 if(!rank) {
00149 std::cout<<"# pts= " << totalSz<<std::endl;
00150 }
00151
00152 MPI_Barrier(MPI_COMM_WORLD);
00153
00154 pts.resize(3*(linOct.size()));
00155 ptsLen = (3*(linOct.size()));
00156 for(int i = 0; i < linOct.size(); i++) {
00157 pts[3*i] = (((double)(linOct[i].getX())) + 0.5)/((double)(1u << maxDepth));
00158 pts[(3*i)+1] = (((double)(linOct[i].getY())) +0.5)/((double)(1u << maxDepth));
00159 pts[(3*i)+2] = (((double)(linOct[i].getZ())) +0.5)/((double)(1u << maxDepth));
00160 }
00161 linOct.clear();
00162
00163 gSize[0] = 1.0;
00164 gSize[1] = 1.0;
00165 gSize[2] = 1.0;
00166
00167 #ifdef PETSC_USE_LOG
00168 PetscLogStagePop();
00169 #endif
00170
00171 MPI_Barrier(MPI_COMM_WORLD);
00172
00173 #ifdef PETSC_USE_LOG
00174 PetscLogStagePush(stages[1]);
00175 #endif
00176 startTime = MPI_Wtime();
00177 ot::points2Octree(pts, gSize, linOct, dim, maxDepth, maxNumPts, MPI_COMM_WORLD);
00178 endTime = MPI_Wtime();
00179 localTime = endTime - startTime;
00180 #ifdef PETSC_USE_LOG
00181 PetscLogStagePop();
00182 #endif
00183 par::Mpi_Reduce<double>(&localTime, &globalTime, 1, MPI_MAX, 0, MPI_COMM_WORLD);
00184 if(!rank){
00185 std::cout <<"P2n Time: "<<globalTime << "secs " << std::endl;
00186 }
00187 pts.clear();
00188
00189 localSz = linOct.size();
00190 par::Mpi_Reduce<DendroIntL>(&localSz, &totalSz, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00191 if(rank==0) {
00192 std::cout<<"linOct.size = " << totalSz<<std::endl;
00193 }
00194
00195 MPI_Barrier(MPI_COMM_WORLD);
00196
00197 #ifdef PETSC_USE_LOG
00198 PetscLogStagePush(stages[2]);
00199 #endif
00200 startTime = MPI_Wtime();
00201 ot::balanceOctree (linOct, balOct, dim, maxDepth, incCorner, MPI_COMM_WORLD, NULL, NULL);
00202 endTime = MPI_Wtime();
00203 localTime = endTime - startTime;
00204 #ifdef PETSC_USE_LOG
00205 PetscLogStagePop();
00206 #endif
00207 par::Mpi_Reduce<double>(&localTime, &globalTime, 1, MPI_MAX, 0, MPI_COMM_WORLD);
00208 if(!rank){
00209 std::cout <<"Bal Time: "<<globalTime << "secs " << std::endl;
00210 }
00211 linOct.clear();
00212
00213 localSz = balOct.size();
00214 par::Mpi_Reduce<DendroIntL>(&localSz, &totalSz, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00215 if(rank==0) {
00216 std::cout<<"balOct.size = " << totalSz<<std::endl;
00217 }
00218 balOct.clear();
00219
00220 PetscFinalize();
00221 }
00222
00223 double gaussian(double mean, double std_deviation) {
00224 static double t1 = 0, t2=0;
00225 double x1, x2, x3, r;
00226
00227 using namespace std;
00228
00229
00230 if(t1) {
00231 const double tmp = t1;
00232 t1 = 0;
00233 return mean + std_deviation * tmp;
00234 }
00235 if(t2) {
00236 const double tmp = t2;
00237 t2 = 0;
00238 return mean + std_deviation * tmp;
00239 }
00240
00241
00242 do {
00243 x1 = 2 * drand48() - 1;
00244 x2 = 2 * drand48() - 1;
00245 x3 = 2 * drand48() - 1;
00246 r = x1 * x1 + x2 * x2 + x3*x3;
00247 } while(r >= 1);
00248
00249
00250 r = sqrt(-2.0 * log(r) / r);
00251
00252
00253 t1 = (r * x2);
00254 t2 = (r * x3);
00255
00256 return mean + (std_deviation * r * x1);
00257 }
00258
00259