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 #include "Teuchos_GlobalMPISession.hpp"
00030 #include "Teuchos_TestForException.hpp"
00031
00032 namespace Teuchos {
00033
00034 bool GlobalMPISession::haveMPIState_ = false;
00035 bool GlobalMPISession::mpiIsFinalized_ = false;
00036 int GlobalMPISession::rank_ = 0 ;
00037 int GlobalMPISession::nProc_ = 1 ;
00038
00039 GlobalMPISession::GlobalMPISession( int* argc, char*** argv, std::ostream *out )
00040 {
00041 std::ostringstream oss;
00042
00043
00044
00045
00046 #ifdef HAVE_MPI
00047
00048 int mpiHasBeenStarted = 0, mpierr = 0;
00049 MPI_Initialized(&mpiHasBeenStarted);
00050 TEST_FOR_EXCEPTION_PRINT(
00051 mpiHasBeenStarted, std::runtime_error
00052 ,"Error, you can only call this constructor once!"
00053 ,out
00054 );
00055
00056 mpierr = ::MPI_Init (argc, (char ***) argv);
00057 TEST_FOR_EXCEPTION_PRINT(
00058 mpierr != 0, std::runtime_error
00059 ,"Error code=" << mpierr << " detected in GlobalMPISession::GlobalMPISession(argc,argv)"
00060 ,out
00061 );
00062
00063 initialize(out);
00064
00065 int nameLen;
00066 char procName[MPI_MAX_PROCESSOR_NAME];
00067 mpierr = ::MPI_Get_processor_name(procName,&nameLen);
00068 TEST_FOR_EXCEPTION_PRINT(
00069 mpierr != 0, std::runtime_error
00070 ,"Error code=" << mpierr << " detected in MPI_Get_processor_name()"
00071 ,out
00072 );
00073
00074 oss << "Teuchos::GlobalMPISession::GlobalMPISession(): started processor with name "
00075 << procName << " and rank " << rank_ << "!" << std::endl;
00076
00077 #else
00078 oss << "Teuchos::GlobalMPISession::GlobalMPISession(): started serial run" << std::endl;
00079 #endif
00080 #ifndef TEUCHOS_SUPPRESS_PROC_STARTUP_BANNER
00081
00082 bool printStartupBanner = true;
00083 const std::string suppress_option("--teuchos-suppress-startup-banner");
00084 for( int opt_i = 0; opt_i < *argc; ++opt_i ) {
00085 if( suppress_option == (*argv)[opt_i] ) {
00086
00087 printStartupBanner = false;
00088
00089
00090 for( int i = opt_i; i < *argc; ++i )
00091 (*argv)[i] = (*argv)[i+1];
00092 --*argc;
00093 }
00094 }
00095 if( out && printStartupBanner )
00096 *out << oss.str() << std::flush;
00097 #endif
00098 }
00099
00100 GlobalMPISession::~GlobalMPISession()
00101 {
00102 haveMPIState_ = false;
00103 mpiIsFinalized_ = true;
00104 #ifdef HAVE_MPI
00105 int mpierr = ::MPI_Finalize();
00106 TEST_FOR_EXCEPTION_PRINT(
00107 mpierr != 0, std::runtime_error
00108 ,"Error code=" << mpierr << " detected in MPI_Finalize()"
00109 ,&std::cerr
00110 );
00111 #endif
00112 }
00113
00114 bool GlobalMPISession::mpiIsInitialized() {
00115 if(!haveMPIState_)
00116 initialize(&std::cerr);
00117 return haveMPIState_;
00118 }
00119
00120 bool GlobalMPISession::mpiIsFinalized()
00121 {
00122 return mpiIsFinalized_;
00123 }
00124
00125 int GlobalMPISession::getRank()
00126 {
00127 if(!haveMPIState_)
00128 initialize(&std::cerr);
00129 return rank_;
00130 }
00131
00132 int GlobalMPISession::getNProc() {
00133 if(!haveMPIState_)
00134 initialize(&std::cerr);
00135 return nProc_;
00136 }
00137
00138
00139
00140 void GlobalMPISession::initialize( std::ostream *out )
00141 {
00142 #ifdef HAVE_MPI
00143
00144 if(mpiIsFinalized_) {
00145
00146 rank_ = 0;
00147 nProc_ = 1;
00148 return;
00149 }
00150
00151 if(haveMPIState_)
00152 return;
00153
00154
00155
00156
00157
00158 int mpiHasBeenStarted = 0, mpierr = 0;
00159 MPI_Initialized(&mpiHasBeenStarted);
00160
00161 if(!mpiHasBeenStarted)
00162 return;
00163
00164
00165
00166 mpierr = ::MPI_Comm_rank( MPI_COMM_WORLD, &rank_ );
00167 TEST_FOR_EXCEPTION_PRINT(
00168 mpierr != 0, std::runtime_error
00169 ,"Error code=" << mpierr << " detected in MPI_Comm_rank()"
00170 ,out
00171 );
00172
00173 mpierr = ::MPI_Comm_size( MPI_COMM_WORLD, &nProc_ );
00174 TEST_FOR_EXCEPTION_PRINT(
00175 mpierr != 0, std::runtime_error
00176 ,"Error code=" << mpierr << " detected in MPI_Comm_size()"
00177 ,out
00178 );
00179
00180 haveMPIState_ = true;
00181 mpiIsFinalized_ = false;
00182
00183 #endif // HAVE_MPI
00184
00185 }
00186
00187 }