00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "PetscTools.hpp"
00031 #include "Exception.hpp"
00032 #include <iostream>
00033 #include <cassert>
00034 #include <cstring>
00035
00036 bool PetscTools::mPetscIsInitialised = false;
00037 unsigned PetscTools::mNumProcessors = 0;
00038 unsigned PetscTools::mRank = 0;
00039 unsigned PetscTools::mMaxNumNonzerosIfMatMpiAij = 54;
00040
00041 #ifdef DEBUG_BARRIERS
00042 unsigned PetscTools::mNumBarriers = 0u;
00043 #endif
00044
00045 void PetscTools::ResetCache()
00046 {
00047 #ifdef SPECIAL_SERIAL
00048 mPetscIsInitialised = false;
00049 mNumProcessors = 1;
00050 mRank = 0;
00051 #else
00052 PetscTruth is_there;
00053 PetscInitialized(&is_there);
00054 if (is_there)
00055 {
00056 mPetscIsInitialised = true;
00057
00058 PetscInt num_procs;
00059 MPI_Comm_size(PETSC_COMM_WORLD, &num_procs);
00060 mNumProcessors = (unsigned) num_procs;
00061
00062 PetscInt my_rank;
00063 MPI_Comm_rank(PETSC_COMM_WORLD, &my_rank);
00064 mRank = (unsigned) my_rank;
00065 }
00066 else
00067 {
00068
00069 mPetscIsInitialised = false;
00070 mNumProcessors = 1;
00071 mRank = 0;
00072 }
00073 #endif
00074 }
00075
00076
00077
00078
00079
00080 bool PetscTools::IsSequential()
00081 {
00082 CheckCache();
00083 return (mNumProcessors == 1);
00084 }
00085
00086 unsigned PetscTools::GetNumProcs()
00087 {
00088 CheckCache();
00089 return mNumProcessors;
00090 }
00091
00092 unsigned PetscTools::GetMyRank()
00093 {
00094 CheckCache();
00095 return mRank;
00096 }
00097
00098 bool PetscTools::AmMaster()
00099 {
00100 CheckCache();
00101 return (mRank == MASTER_RANK);
00102 }
00103
00104 bool PetscTools::AmTopMost()
00105 {
00106 CheckCache();
00107 return (mRank == mNumProcessors - 1);
00108 }
00109
00110
00111
00112
00113
00114 void PetscTools::Barrier(const std::string callerId)
00115 {
00116 CheckCache();
00117 if (mPetscIsInitialised)
00118 {
00119 #ifdef DEBUG_BARRIERS
00120 std::cout << "DEBUG: proc " << PetscTools::GetMyRank() << ": Pre " << callerId << " Barrier " << mNumBarriers << "." << std::endl << std::flush;
00121 #endif
00122 PetscBarrier(PETSC_NULL);
00123 #ifdef DEBUG_BARRIERS
00124 std::cout << "DEBUG: proc " << PetscTools::GetMyRank() << ": Post " << callerId << " Barrier " << mNumBarriers++ << "." << std::endl << std::flush;
00125 #endif
00126 }
00127 }
00128
00129 #ifndef SPECIAL_SERIAL
00130
00131 bool PetscTools::ReplicateBool(bool flag)
00132 {
00133 unsigned my_flag = (unsigned) flag;
00134 unsigned anyones_flag_is_true;
00135 MPI_Allreduce(&my_flag, &anyones_flag_is_true, 1, MPI_UNSIGNED, MPI_MAX, PETSC_COMM_WORLD);
00136 return (anyones_flag_is_true == 1);
00137 }
00138
00139 void PetscTools::ReplicateException(bool flag)
00140 {
00141 bool anyones_error=ReplicateBool(flag);
00142 if (flag)
00143 {
00144
00145 return;
00146 }
00147 if (anyones_error)
00148 {
00149 EXCEPTION("Another process threw an exception; bailing out.");
00150 }
00151 }
00152
00153
00154
00155
00156
00157 Vec PetscTools::CreateVec(int size)
00158 {
00159 assert(size>0);
00160 Vec ret;
00161 VecCreate(PETSC_COMM_WORLD, &ret);
00162 VecSetSizes(ret, PETSC_DECIDE, size);
00163 VecSetFromOptions(ret);
00164 return ret;
00165 }
00166
00167 Vec PetscTools::CreateVec(int size, double value)
00168 {
00169 assert(size>0);
00170 Vec ret = CreateVec(size);
00171
00172 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00173 VecSet(&value, ret);
00174 #else
00175 VecSet(ret, value);
00176 #endif
00177
00178 VecAssemblyBegin(ret);
00179 VecAssemblyEnd(ret);
00180 return ret;
00181 }
00182
00183 Vec PetscTools::CreateVec(std::vector<double> data)
00184 {
00185 assert(data.size() > 0);
00186 Vec ret = CreateVec(data.size());
00187
00188 double* p_ret;
00189 VecGetArray(ret, &p_ret);
00190 int lo, hi;
00191 VecGetOwnershipRange(ret, &lo, &hi);
00192
00193 for (int global_index=lo; global_index<hi; global_index++)
00194 {
00195 int local_index = global_index - lo;
00196 p_ret[local_index] = data[global_index];
00197 }
00198 VecRestoreArray(ret, &p_ret);
00199 VecAssemblyBegin(ret);
00200 VecAssemblyEnd(ret);
00201
00202 return ret;
00203 }
00204
00205 void PetscTools::SetupMat(Mat& rMat, int numRows, int numColumns,
00206 MatType matType,
00207 int numLocalRows,
00208 int numLocalColumns)
00209 {
00210 assert(numRows>0);
00211 assert(numColumns>0);
00212
00213 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00214 MatCreate(PETSC_COMM_WORLD,numLocalRows,numLocalColumns,numRows,numColumns,&rMat);
00215 #else //New API
00216 MatCreate(PETSC_COMM_WORLD,&rMat);
00217 MatSetSizes(rMat,numLocalRows,numLocalColumns,numRows,numColumns);
00218 #endif
00219
00220 MatSetType(rMat, matType);
00221
00222 if (strcmp(matType,MATMPIAIJ)==0)
00223 {
00224 MatMPIAIJSetPreallocation(rMat, mMaxNumNonzerosIfMatMpiAij, PETSC_NULL, (PetscInt) (mMaxNumNonzerosIfMatMpiAij*0.5), PETSC_NULL);
00225 }
00226
00227 MatSetFromOptions(rMat);
00228 }
00229
00230 void PetscTools::DumpPetscObject(const Mat& rMat, const std::string& rOutputFileFullPath)
00231 {
00232 PetscViewer view;
00233 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00234 PetscViewerFileType type = PETSC_FILE_CREATE;
00235 #else
00236 PetscFileMode type = FILE_MODE_WRITE;
00237 #endif
00238
00239 PetscViewerBinaryOpen(PETSC_COMM_WORLD, rOutputFileFullPath.c_str(),
00240 type, &view);
00241 MatView(rMat, view);
00242 PetscViewerDestroy(view);
00243 }
00244
00245 void PetscTools::DumpPetscObject(const Vec& rVec, const std::string& rOutputFileFullPath)
00246 {
00247 PetscViewer view;
00248 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00249 PetscViewerFileType type = PETSC_FILE_CREATE;
00250 #else
00251 PetscFileMode type = FILE_MODE_WRITE;
00252 #endif
00253
00254 PetscViewerBinaryOpen(PETSC_COMM_WORLD, rOutputFileFullPath.c_str(),
00255 type, &view);
00256 VecView(rVec, view);
00257 PetscViewerDestroy(view);
00258 }
00259
00260 void PetscTools::ReadPetscObject(Mat& rMat, const std::string& rOutputFileFullPath)
00261 {
00262 PetscViewer view;
00263 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00264 PetscViewerFileType type = PETSC_FILE_RDONLY;
00265 #else
00266 PetscFileMode type = FILE_MODE_READ;
00267 #endif
00268
00269 PetscViewerBinaryOpen(PETSC_COMM_WORLD, rOutputFileFullPath.c_str(),
00270 type, &view);
00271 MatLoad(view, MATMPIAIJ, &rMat);
00272 PetscViewerDestroy(view);
00273 }
00274
00275 void PetscTools::ReadPetscObject(Vec& rVec, const std::string& rOutputFileFullPath)
00276 {
00277 PetscViewer view;
00278 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00279 PetscViewerFileType type = PETSC_FILE_RDONLY;
00280 #else
00281 PetscFileMode type = FILE_MODE_READ;
00282 #endif
00283
00284 PetscViewerBinaryOpen(PETSC_COMM_WORLD, rOutputFileFullPath.c_str(),
00285 type, &view);
00286 VecLoad(view, VECMPI, &rVec);
00287 PetscViewerDestroy(view);
00288 }
00289
00290 void PetscTools::SetMaxNumNonzerosIfMatMpiAij(unsigned maxColsPerRowIfMatMpiAij)
00291 {
00292 mMaxNumNonzerosIfMatMpiAij = maxColsPerRowIfMatMpiAij;
00293 }
00294
00295 #endif //SPECIAL_SERIAL