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 "Warnings.hpp"
00033 #include <iostream>
00034 #include <sstream>
00035 #include <cassert>
00036 #include <cstring>
00037
00038 bool PetscTools::mPetscIsInitialised = false;
00039 unsigned PetscTools::mNumProcessors = 0;
00040 unsigned PetscTools::mRank = 0;
00041
00042
00043 #ifdef DEBUG_BARRIERS
00044 unsigned PetscTools::mNumBarriers = 0u;
00045 #endif
00046
00047 void PetscTools::ResetCache()
00048 {
00049 #ifdef SPECIAL_SERIAL
00050 mPetscIsInitialised = false;
00051 mNumProcessors = 1;
00052 mRank = 0;
00053 #else
00054 PetscTruth is_there;
00055 PetscInitialized(&is_there);
00056 if (is_there)
00057 {
00058 mPetscIsInitialised = true;
00059
00060 PetscInt num_procs;
00061 MPI_Comm_size(PETSC_COMM_WORLD, &num_procs);
00062 mNumProcessors = (unsigned) num_procs;
00063
00064 PetscInt my_rank;
00065 MPI_Comm_rank(PETSC_COMM_WORLD, &my_rank);
00066 mRank = (unsigned) my_rank;
00067 }
00068 else
00069 {
00070
00071 mPetscIsInitialised = false;
00072 mNumProcessors = 1;
00073 mRank = 0;
00074 }
00075 #endif
00076 }
00077
00078
00079
00080
00081
00082 bool PetscTools::IsSequential()
00083 {
00084 CheckCache();
00085 return (mNumProcessors == 1);
00086 }
00087
00088 unsigned PetscTools::GetNumProcs()
00089 {
00090 CheckCache();
00091 return mNumProcessors;
00092 }
00093
00094 unsigned PetscTools::GetMyRank()
00095 {
00096 CheckCache();
00097 return mRank;
00098 }
00099
00100 bool PetscTools::AmMaster()
00101 {
00102 CheckCache();
00103 return (mRank == MASTER_RANK);
00104 }
00105
00106 bool PetscTools::AmTopMost()
00107 {
00108 CheckCache();
00109 return (mRank == mNumProcessors - 1);
00110 }
00111
00112
00113
00114
00115
00116 void PetscTools::Barrier(const std::string callerId)
00117 {
00118 CheckCache();
00119 if (mPetscIsInitialised)
00120 {
00121 #ifdef DEBUG_BARRIERS
00122 std::cout << "DEBUG: proc " << PetscTools::GetMyRank() << ": Pre " << callerId << " Barrier " << mNumBarriers << "." << std::endl << std::flush;
00123 #endif
00124 PetscBarrier(PETSC_NULL);
00125 #ifdef DEBUG_BARRIERS
00126 std::cout << "DEBUG: proc " << PetscTools::GetMyRank() << ": Post " << callerId << " Barrier " << mNumBarriers++ << "." << std::endl << std::flush;
00127 #endif
00128 }
00129 }
00130
00131 #ifndef SPECIAL_SERIAL
00132
00133 bool PetscTools::ReplicateBool(bool flag)
00134 {
00135 unsigned my_flag = (unsigned) flag;
00136 unsigned anyones_flag_is_true;
00137 MPI_Allreduce(&my_flag, &anyones_flag_is_true, 1, MPI_UNSIGNED, MPI_MAX, PETSC_COMM_WORLD);
00138 return (anyones_flag_is_true == 1);
00139 }
00140
00141 void PetscTools::ReplicateException(bool flag)
00142 {
00143 bool anyones_error=ReplicateBool(flag);
00144 if (flag)
00145 {
00146
00147 return;
00148 }
00149 if (anyones_error)
00150 {
00151 EXCEPTION("Another process threw an exception; bailing out.");
00152 }
00153 }
00154
00155
00156
00157
00158
00159 Vec PetscTools::CreateVec(int size, int localSize)
00160 {
00161 assert(size>=0);
00162 Vec ret;
00163 VecCreate(PETSC_COMM_WORLD, &ret);
00164 VecSetSizes(ret, localSize, size);
00165 VecSetFromOptions(ret);
00166 return ret;
00167 }
00168
00169 Vec PetscTools::CreateVec(std::vector<double> data)
00170 {
00171 assert(data.size() > 0);
00172 Vec ret = CreateVec(data.size());
00173
00174 double* p_ret;
00175 VecGetArray(ret, &p_ret);
00176 int lo, hi;
00177 VecGetOwnershipRange(ret, &lo, &hi);
00178
00179 for (int global_index=lo; global_index<hi; global_index++)
00180 {
00181 int local_index = global_index - lo;
00182 p_ret[local_index] = data[global_index];
00183 }
00184 VecRestoreArray(ret, &p_ret);
00185 VecAssemblyBegin(ret);
00186 VecAssemblyEnd(ret);
00187
00188 return ret;
00189 }
00190
00191 Vec PetscTools::CreateAndSetVec(int size, double value)
00192 {
00193 assert(size>0);
00194 Vec ret = CreateVec(size);
00195
00196 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00197 VecSet(&value, ret);
00198 #else
00199 VecSet(ret, value);
00200 #endif
00201
00202 VecAssemblyBegin(ret);
00203 VecAssemblyEnd(ret);
00204 return ret;
00205 }
00206
00207 void PetscTools::SetupMat(Mat& rMat, int numRows, int numColumns,
00208 unsigned rowPreallocation,
00209 int numLocalRows,
00210 int numLocalColumns)
00211 {
00212 assert(numRows>0);
00213 assert(numColumns>0);
00214 if((int) rowPreallocation>numColumns)
00215 {
00216 WARNING("Preallocation failure: requested number of nonzeros per row greater than number of columns");
00217 rowPreallocation=numColumns;
00218 }
00219
00220 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00221 MatCreate(PETSC_COMM_WORLD,numLocalRows,numLocalColumns,numRows,numColumns,&rMat);
00222 #else //New API
00223 MatCreate(PETSC_COMM_WORLD,&rMat);
00224 MatSetSizes(rMat,numLocalRows,numLocalColumns,numRows,numColumns);
00225 #endif
00226
00227
00228 if(PetscTools::IsSequential())
00229 {
00230 MatSetType(rMat, MATSEQAIJ);
00231 if(rowPreallocation>0)
00232 {
00233 MatSeqAIJSetPreallocation(rMat, rowPreallocation, PETSC_NULL);
00234 }
00235 }
00236 else
00237 {
00238 MatSetType(rMat, MATMPIAIJ);
00239 if(rowPreallocation>0)
00240 {
00242 MatMPIAIJSetPreallocation(rMat, rowPreallocation, PETSC_NULL, (PetscInt) (rowPreallocation*0.7), PETSC_NULL);
00243 }
00244 }
00245
00246 MatSetFromOptions(rMat);
00247 }
00248
00249
00250 void PetscTools::DumpPetscObject(const Mat& rMat, const std::string& rOutputFileFullPath)
00251 {
00252 PetscViewer view;
00253 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00254 PetscViewerFileType type = PETSC_FILE_CREATE;
00255 #else
00256 PetscFileMode type = FILE_MODE_WRITE;
00257 #endif
00258
00259 PetscViewerBinaryOpen(PETSC_COMM_WORLD, rOutputFileFullPath.c_str(),
00260 type, &view);
00261 MatView(rMat, view);
00262 PetscViewerDestroy(view);
00263 }
00264
00265 void PetscTools::DumpPetscObject(const Vec& rVec, const std::string& rOutputFileFullPath)
00266 {
00267 PetscViewer view;
00268 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00269 PetscViewerFileType type = PETSC_FILE_CREATE;
00270 #else
00271 PetscFileMode type = FILE_MODE_WRITE;
00272 #endif
00273
00274 PetscViewerBinaryOpen(PETSC_COMM_WORLD, rOutputFileFullPath.c_str(),
00275 type, &view);
00276 VecView(rVec, view);
00277 PetscViewerDestroy(view);
00278 }
00279
00280 void PetscTools::ReadPetscObject(Mat& rMat, const std::string& rOutputFileFullPath, Vec rParallelLayout)
00281 {
00282
00283
00284
00285
00286
00287
00288
00289 PetscViewer view;
00290 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00291 PetscViewerFileType type = PETSC_FILE_RDONLY;
00292 #else
00293 PetscFileMode type = FILE_MODE_READ;
00294 #endif
00295
00296 PetscViewerBinaryOpen(PETSC_COMM_WORLD, rOutputFileFullPath.c_str(),
00297 type, &view);
00298 MatLoad(view, MATMPIAIJ, &rMat);
00299 PetscViewerDestroy(view);
00300
00301 if (rParallelLayout != NULL)
00302 {
00303
00304
00305
00306
00307 PetscInt num_rows, num_local_rows;
00308
00309 VecGetSize(rParallelLayout, &num_rows);
00310 VecGetLocalSize(rParallelLayout, &num_local_rows);
00311
00312 Mat temp_mat;
00314 PetscTools::SetupMat(temp_mat, num_rows, num_rows, 100, num_local_rows, num_local_rows);
00315
00316 MatCopy(rMat, temp_mat, DIFFERENT_NONZERO_PATTERN);
00317
00318 MatDestroy(rMat);
00319 rMat = temp_mat;
00320
00321 }
00322 }
00323
00324 void PetscTools::ReadPetscObject(Vec& rVec, const std::string& rOutputFileFullPath, Vec rParallelLayout)
00325 {
00326 PetscViewer view;
00327 #if (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 2) //PETSc 2.2
00328 PetscViewerFileType type = PETSC_FILE_RDONLY;
00329 #else
00330 PetscFileMode type = FILE_MODE_READ;
00331 #endif
00332
00333 PetscViewerBinaryOpen(PETSC_COMM_WORLD, rOutputFileFullPath.c_str(),
00334 type, &view);
00335 if (rParallelLayout == NULL)
00336 {
00337 VecLoad(view, VECMPI, &rVec);
00338 }
00339 else
00340 {
00341 VecDuplicate(rParallelLayout, &rVec);
00342 VecLoadIntoVector(view, rVec);
00343 }
00344 PetscViewerDestroy(view);
00345 }
00346 #endif //SPECIAL_SERIAL (ifndef)
00347
00348 #define COVERAGE_IGNORE //Termination NEVER EVER happens under normal testing conditions.
00349 void PetscTools::Terminate(const std::string& rMessage, const std::string& rFilename, unsigned lineNumber)
00350 {
00351 std::stringstream error_message;
00352
00353 error_message<<"\nChaste termination: " << rFilename << ":" << lineNumber << ": " << rMessage<<"\n";
00354 std::cerr<<error_message.str();
00355
00356
00357
00358 PetscTruth is_there;
00359 PetscInitialized(&is_there);
00360 if (is_there)
00361 {
00362 MPI_Abort(PETSC_COMM_WORLD, EXIT_FAILURE);
00363 }
00364 else
00365 {
00366 exit(EXIT_FAILURE);
00367 }
00368 }
00369 #undef COVERAGE_IGNORE //Termination NEVER EVER happens under normal testing conditions.