00001
00002 #include "mpi.h"
00003 #include <iostream>
00004 #include "petsc.h"
00005 #include "sys.h"
00006 #include <vector>
00007 #include "parUtils.h"
00008 #include "externVars.h"
00009 #include "dendro.h"
00010
00011 class Vertex {
00012 private:
00013 unsigned int x, y, z, id;
00014 public:
00015 unsigned int getX() const {
00016 return x;
00017 }
00018
00019 unsigned int getY() const {
00020 return y;
00021 }
00022
00023 unsigned int getZ() const {
00024 return z;
00025 }
00026
00027 unsigned int getId() const {
00028 return id;
00029 }
00030
00031 Vertex() {
00032 this->x = static_cast<unsigned int>(-1);
00033 this->y = static_cast<unsigned int>(-1);
00034 this->z = static_cast<unsigned int>(-1);
00035 this->id = static_cast<unsigned int>(-1);
00036 }
00037
00038 Vertex(unsigned int xVal, unsigned int yVal, unsigned int zVal, unsigned int idVal) {
00039 this->x = xVal;
00040 this->y = yVal;
00041 this->z = zVal;
00042 this->id = idVal;
00043 }
00044
00045 Vertex(Vertex const & other) {
00046 this->x = other.x;
00047 this->y = other.y;
00048 this->z = other.z;
00049 this->id = other.id;
00050 }
00051
00052 Vertex & operator = (Vertex const & other) {
00053 if( this == (&other) ) {
00054 return (*this);
00055 }
00056 this->x = other.x;
00057 this->y = other.y;
00058 this->z = other.z;
00059 this->id = other.id;
00060 return (*this);
00061 }
00062
00063 bool operator == ( Vertex const &other) const {
00064 return( (this->x == other.x) && (this->y == other.y) &&
00065 (this->z == other.z) && (this->id == other.id) );
00066 }
00067
00068 bool operator != (Vertex const &other) const {
00069 return (!((*this) == other));
00070 }
00071
00072 bool operator < ( Vertex const &other) const {
00073
00074 if(this->x == other.x) {
00075 if( this->y == other.y) {
00076 if( this->z == other.z) {
00077 return (this->id < other.id);
00078 }else {
00079 return (this->z < other.z);
00080 }
00081 }else {
00082 return(this->y < other.y);
00083 }
00084 } else {
00085 return (this->x < other.x);
00086 }
00087 }
00088
00089 bool operator > ( Vertex const &other) const {
00090 return ( ((*this) != other) && ((*this) >= other) );
00091 }
00092
00093 bool operator <= ( Vertex const &other) const {
00094 return ( ((*this) < other) || ((*this) == other) );
00095 }
00096
00097 bool operator >= ( Vertex const &other) const {
00098 return (!((*this) < other));
00099 }
00100
00101 friend std::ostream & operator << (std::ostream & os, Vertex const & v) ;
00102 };
00103
00104 std::ostream & operator <<(std::ostream & os, Vertex const & v) {
00105 return (os << v.x <<" "<< v.y <<" "<<v.z<<" "<<v.id);
00106 }
00107
00108 namespace par {
00109
00110 template <typename T>
00111 class Mpi_datatype;
00112
00113 template <>
00114 class Mpi_datatype<Vertex> {
00115 public:
00116 static MPI_Datatype value() {
00117 static bool first = true;
00118 static MPI_Datatype datatype;
00119 if (first) {
00120 first = false;
00121 MPI_Type_contiguous(sizeof(Vertex), MPI_BYTE, &datatype);
00122 MPI_Type_commit(&datatype);
00123 }
00124 return datatype;
00125 }
00126 };
00127 }
00128
00129 int main(int argc, char**argv) {
00130
00131 PetscInitialize(&argc,&argv,0,0);
00132 ot::RegisterEvents();
00133
00134 if(argc < 4) {
00135 std::cout<<"exe fileBase file1Procs file2Procs "<<std::endl;
00136 assert(false);
00137 }
00138
00139 int rank, npes;
00140 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
00141 MPI_Comm_size(MPI_COMM_WORLD, &npes);
00142
00143 unsigned int file1Procs = atoi(argv[2]);
00144 unsigned int file2Procs = atoi(argv[3]);
00145
00146 assert(file1Procs <= file2Procs);
00147 assert(file2Procs <= npes);
00148
00149 std::vector<Vertex> vals1;
00150 std::vector<Vertex> vals2;
00151
00152 if(rank < file1Procs) {
00153 char fileName[100];
00154 sprintf(fileName,"%s_%d_%d.out",argv[1],rank,file1Procs);
00155 FILE * fptr = fopen(fileName,"rb");
00156 assert(fptr != NULL);
00157 unsigned int numElems = 0;
00158 fread(&numElems, sizeof(unsigned int), 1, fptr);
00159 vals1.resize(numElems);
00160 for(unsigned int i = 0; i < numElems; i++ ) {
00161 unsigned int xyzi[4];
00162 fread(xyzi, sizeof(unsigned int), 4, fptr);
00163 vals1[i] = Vertex(xyzi[0], xyzi[1], xyzi[2], xyzi[3]);
00164 }
00165 fclose(fptr);
00166 }
00167
00168 MPI_Barrier(MPI_COMM_WORLD);
00169
00170 if(!rank) {
00171 std::cout<<"Read File1 Successfully."<<std::endl;
00172 }
00173
00174 MPI_Barrier(MPI_COMM_WORLD);
00175
00176 if(rank < file2Procs) {
00177 char fileName[100];
00178 sprintf(fileName,"%s_%d_%d.out",argv[1],rank,file2Procs);
00179 FILE * fptr = fopen(fileName,"rb");
00180 assert(fptr != NULL);
00181 unsigned int numElems = 0;
00182 fread(&numElems, sizeof(unsigned int), 1, fptr);
00183 vals2.resize(numElems);
00184 for(unsigned int i = 0; i < numElems; i++ ) {
00185 unsigned int xyzi[4];
00186 fread(xyzi, sizeof(unsigned int), 4, fptr);
00187 vals2[i] = Vertex(xyzi[0], xyzi[1], xyzi[2], xyzi[3]);
00188 }
00189 fclose(fptr);
00190 }
00191
00192 MPI_Barrier(MPI_COMM_WORLD);
00193
00194 if(!rank) {
00195 std::cout<<"Read File2 Successfully."<<std::endl;
00196 }
00197
00198 MPI_Barrier(MPI_COMM_WORLD);
00199
00200 DendroIntL locSz1 = vals1.size();
00201 DendroIntL globSz1 = 0;
00202 par::Mpi_Reduce<DendroIntL>(&locSz1, &globSz1, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00203
00204 DendroIntL locSz2 = vals2.size();
00205 DendroIntL globSz2 = 0;
00206 par::Mpi_Reduce<DendroIntL>(&locSz2, &globSz2, 1, MPI_SUM, 0, MPI_COMM_WORLD);
00207
00208 MPI_Barrier(MPI_COMM_WORLD);
00209
00210 if(!rank) {
00211 assert(globSz1 == globSz2);
00212 std::cout << "Global Size: " << globSz1 << std::endl;
00213 }
00214
00215 MPI_Barrier(MPI_COMM_WORLD);
00216
00217 std::vector<Vertex> vals1Tmp;
00218 std::vector<Vertex> vals2Tmp;
00219
00220 par::sampleSort<Vertex>(vals1, vals1Tmp, MPI_COMM_WORLD);
00221 par::sampleSort<Vertex>(vals2, vals2Tmp, MPI_COMM_WORLD);
00222
00223 vals1 = vals1Tmp;
00224 vals2 = vals2Tmp;
00225 vals1Tmp.clear();
00226 vals2Tmp.clear();
00227
00228 MPI_Barrier(MPI_COMM_WORLD);
00229
00230 if(!rank) {
00231 std::cout<<"Finished Sorting Vertices "<<std::endl;
00232 }
00233
00234 MPI_Barrier(MPI_COMM_WORLD);
00235
00236 par::partitionW<Vertex>(vals1, NULL, MPI_COMM_WORLD);
00237
00238 MPI_Barrier(MPI_COMM_WORLD);
00239
00240 if(!rank) {
00241 std::cout<<"Finished Partitioning List 1 "<<std::endl;
00242 }
00243
00244 MPI_Barrier(MPI_COMM_WORLD);
00245
00246 par::partitionW<Vertex>(vals2, NULL, MPI_COMM_WORLD);
00247
00248 MPI_Barrier(MPI_COMM_WORLD);
00249
00250 if(!rank) {
00251 std::cout<<"Finished Partitioning List 2 "<<std::endl;
00252 }
00253
00254 MPI_Barrier(MPI_COMM_WORLD);
00255
00256 {
00257 char outFile1[100];
00258 sprintf(outFile1,"VtxList1_%d_%d.out",rank,npes);
00259 FILE * fptr1 = fopen(outFile1,"wb");
00260 unsigned int numElems = (vals1.size());
00261 fwrite(&numElems, sizeof(unsigned int), 1, fptr1);
00262 for(unsigned int i = 0; i < numElems; i++ ) {
00263 unsigned int record[4];
00264 record[0] = vals1[i].getX();
00265 record[1] = vals1[i].getY();
00266 record[2] = vals1[i].getZ();
00267 record[3] = vals1[i].getId();
00268 fwrite(record, sizeof(unsigned int), 4, fptr1);
00269 }
00270 fclose(fptr1);
00271 }
00272
00273 {
00274 char outFile2[100];
00275 sprintf(outFile2,"VtxList2_%d_%d.out",rank,npes);
00276 FILE * fptr2 = fopen(outFile2,"wb");
00277 unsigned int numElems = (vals2.size());
00278 fwrite(&numElems, sizeof(unsigned int), 1, fptr2);
00279 for(unsigned int i = 0; i < numElems; i++ ) {
00280 unsigned int record[4];
00281 record[0] = vals2[i].getX();
00282 record[1] = vals2[i].getY();
00283 record[2] = vals2[i].getZ();
00284 record[3] = vals2[i].getId();
00285 fwrite(record, sizeof(unsigned int), 4, fptr2);
00286 }
00287 fclose(fptr2);
00288 }
00289
00290 MPI_Barrier(MPI_COMM_WORLD);
00291
00292 if(!rank) {
00293 std::cout<<"Finished writing out the sorted vertices "<<std::endl;
00294 }
00295
00296 MPI_Barrier(MPI_COMM_WORLD);
00297
00298 assert(vals1.size() == vals2.size());
00299
00300 MPI_Barrier(MPI_COMM_WORLD);
00301
00302 bool Ipassed = false;
00303 if(vals1 == vals2) {
00304 Ipassed = true;
00305 }
00306
00307 bool *IpassedList = new bool[npes];
00308 par::Mpi_Allgather<bool>(&Ipassed, IpassedList, 1, MPI_COMM_WORLD);
00309
00310 bool allPassed = true;
00311 unsigned int lastP = 0;
00312 for(unsigned int i = 0; ((i < npes) && allPassed); i++) {
00313 allPassed = (allPassed && IpassedList[i]);
00314 lastP = i;
00315 }
00316 delete [] IpassedList;
00317
00318 if(!allPassed) {
00319 if(rank == lastP) {
00320 std::cout<<"First Failing on Proc: "<< lastP <<std::endl;
00321 for(unsigned int i = 0; i < vals1.size(); i++) {
00322 if(vals1[i] != vals2[i]) {
00323 std::cout<<"i = "<<i<<" val1 = "<<vals1[i]<<" val2 = "<<vals2[i]<<std::endl;
00324 break;
00325 }
00326 }
00327 }
00328 }
00329
00330 vals1.clear();
00331 vals2.clear();
00332
00333 MPI_Barrier(MPI_COMM_WORLD);
00334
00335 if(!rank) {
00336 if(allPassed) {
00337 std::cout<<"The files match."<<std::endl;
00338 }else {
00339 std::cout<<"The files do not match."<<std::endl;
00340 }
00341 }
00342
00343 MPI_Barrier(MPI_COMM_WORLD);
00344
00345 PetscFinalize();
00346
00347 }
00348