|
Teuchos - Trilinos Tools Package Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Teuchos: Common Tools Package 00005 // Copyright (2004) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #include "Teuchos_GlobalMPISession.hpp" 00043 #include "Teuchos_Assert.hpp" 00044 00045 namespace Teuchos { 00046 00047 bool GlobalMPISession::haveMPIState_ = false; 00048 bool GlobalMPISession::mpiIsFinalized_ = false; 00049 int GlobalMPISession::rank_ = 0 ; 00050 int GlobalMPISession::nProc_ = 1 ; 00051 00052 GlobalMPISession::GlobalMPISession( int* argc, char*** argv, std::ostream *out ) 00053 { 00054 std::ostringstream oss; 00055 00056 // Above is used to create all output before sending to *out to avoid 00057 // jumbled parallel output between processors 00058 00059 #ifdef HAVE_MPI 00060 // initialize MPI 00061 int mpiHasBeenStarted = 0, mpierr = 0; 00062 MPI_Initialized(&mpiHasBeenStarted); 00063 TEUCHOS_TEST_FOR_EXCEPTION_PRINT( 00064 mpiHasBeenStarted, std::runtime_error 00065 ,"Error, you can only call this constructor once!" 00066 ,out 00067 ); 00068 00069 mpierr = ::MPI_Init (argc, (char ***) argv); 00070 TEUCHOS_TEST_FOR_EXCEPTION_PRINT( 00071 mpierr != 0, std::runtime_error 00072 ,"Error code=" << mpierr << " detected in GlobalMPISession::GlobalMPISession(argc,argv)" 00073 ,out 00074 ); 00075 00076 initialize(out); // Get NProc_ and rank_ 00077 00078 int nameLen; 00079 char procName[MPI_MAX_PROCESSOR_NAME]; 00080 mpierr = ::MPI_Get_processor_name(procName,&nameLen); 00081 TEUCHOS_TEST_FOR_EXCEPTION_PRINT( 00082 mpierr != 0, std::runtime_error 00083 ,"Error code=" << mpierr << " detected in MPI_Get_processor_name()" 00084 ,out 00085 ); 00086 00087 oss << "Teuchos::GlobalMPISession::GlobalMPISession(): started processor with name " 00088 << procName << " and rank " << rank_ << "!" << std::endl; 00089 00090 #else 00091 oss << "Teuchos::GlobalMPISession::GlobalMPISession(): started serial run" << std::endl; 00092 #endif 00093 #ifndef TEUCHOS_SUPPRESS_PROC_STARTUP_BANNER 00094 // See if we should suppress the startup banner 00095 bool printStartupBanner = true; 00096 const std::string suppress_option("--teuchos-suppress-startup-banner"); 00097 for( int opt_i = 0; opt_i < *argc; ++opt_i ) { 00098 if( suppress_option == (*argv)[opt_i] ) { 00099 // We are suppressing the output! 00100 printStartupBanner = false; 00101 // Remove this option! 00102 // Note that (*argv)[*argc]==0 but convention so we copy it too! 00103 for( int i = opt_i; i < *argc; ++i ) 00104 (*argv)[i] = (*argv)[i+1]; 00105 --*argc; 00106 } 00107 } 00108 if( out && printStartupBanner ) 00109 *out << oss.str() << std::flush; 00110 #endif 00111 } 00112 00113 GlobalMPISession::~GlobalMPISession() 00114 { 00115 haveMPIState_ = false; 00116 mpiIsFinalized_ = true; 00117 #ifdef HAVE_MPI 00118 int mpierr = ::MPI_Finalize(); 00119 TEUCHOS_TEST_FOR_EXCEPTION_PRINT( 00120 mpierr != 0, std::runtime_error 00121 ,"Error code=" << mpierr << " detected in MPI_Finalize()" 00122 ,&std::cerr 00123 ); 00124 #endif 00125 } 00126 00127 bool GlobalMPISession::mpiIsInitialized() { 00128 if(!haveMPIState_) 00129 initialize(&std::cerr); 00130 return haveMPIState_; 00131 } 00132 00133 bool GlobalMPISession::mpiIsFinalized() 00134 { 00135 return mpiIsFinalized_; 00136 } 00137 00138 int GlobalMPISession::getRank() 00139 { 00140 if(!haveMPIState_) 00141 initialize(&std::cerr); 00142 return rank_; 00143 } 00144 00145 int GlobalMPISession::getNProc() { 00146 if(!haveMPIState_) 00147 initialize(&std::cerr); 00148 return nProc_; 00149 } 00150 00151 // private 00152 00153 void GlobalMPISession::initialize( std::ostream *out ) 00154 { 00155 #ifdef HAVE_MPI 00156 00157 if(mpiIsFinalized_) { 00158 // MPI has aleady been finalized so we have a serial machine again! 00159 rank_ = 0; 00160 nProc_ = 1; 00161 return; 00162 } 00163 00164 if(haveMPIState_) 00165 return; // We already have what we need! 00166 00167 // We don't have the state of MPI so the constructor for this class must not 00168 // have been called. However, if MPI has been called in another way we 00169 // can still get the state of MPI_COMM_WORLD here. 00170 00171 int mpiHasBeenStarted = 0, mpierr = 0; 00172 MPI_Initialized(&mpiHasBeenStarted); 00173 00174 if(!mpiHasBeenStarted) 00175 return; // We have to give up and just leave NProc_ and rank_ at the default values. 00176 00177 // Get the state of MPI 00178 00179 mpierr = ::MPI_Comm_rank( MPI_COMM_WORLD, &rank_ ); 00180 TEUCHOS_TEST_FOR_EXCEPTION_PRINT( 00181 mpierr != 0, std::runtime_error 00182 ,"Error code=" << mpierr << " detected in MPI_Comm_rank()" 00183 ,out 00184 ); 00185 00186 mpierr = ::MPI_Comm_size( MPI_COMM_WORLD, &nProc_ ); 00187 TEUCHOS_TEST_FOR_EXCEPTION_PRINT( 00188 mpierr != 0, std::runtime_error 00189 ,"Error code=" << mpierr << " detected in MPI_Comm_size()" 00190 ,out 00191 ); 00192 00193 haveMPIState_ = true; 00194 mpiIsFinalized_ = false; 00195 00196 #endif // HAVE_MPI 00197 00198 } 00199 00200 } // namespace Teuchos
1.7.4