41 #include "Tpetra_Details_mpiIsInitialized.hpp" 43 #ifdef HAVE_TPETRACORE_MPI 44 # include <Teuchos_DefaultMpiComm.hpp> 45 #endif // HAVE_TPETRACORE_MPI 46 #include <Teuchos_DefaultSerialComm.hpp> 48 #include <Kokkos_Core.hpp> 53 class HideOutputExceptOnProcess0 {
55 HideOutputExceptOnProcess0 (std::ostream& stream,
58 originalBuffer_ (stream.rdbuf ())
61 stream.rdbuf (blackHole_.rdbuf ());
65 ~HideOutputExceptOnProcess0 () {
66 stream_.rdbuf (originalBuffer_);
69 std::ostream& stream_;
70 decltype (std::cout.rdbuf ()) originalBuffer_;
71 Teuchos::oblackholestream blackHole_;
74 #if defined(HAVE_TPETRACORE_MPI) 75 bool mpiIsInitializedAndNotFinalized ()
88 (void) MPI_Finalized (&isFinalized);
96 int getRankHarmlessly (MPI_Comm comm)
99 if (mpiIsInitializedAndNotFinalized ()) {
101 (void) MPI_Comm_rank (comm, &myRank);
110 #endif // defined(HAVE_TPETRACORE_MPI) 114 bool tpetraIsInitialized_ =
false;
120 bool tpetraInitializedKokkos_ =
false;
122 #ifdef HAVE_TPETRACORE_MPI 126 bool tpetraInitializedMpi_ =
false;
127 #endif // HAVE_TPETRACORE_MPI 131 Teuchos::RCP<const Teuchos::Comm<int> > wrappedDefaultComm_;
134 void initKokkosIfNeeded (
int* argc,
char*** argv,
const int myRank)
136 if (! tpetraInitializedKokkos_) {
140 const bool kokkosIsInitialized =
141 Kokkos::is_initialized ();
142 if (! kokkosIsInitialized) {
143 HideOutputExceptOnProcess0 hideCerr (std::cerr, myRank);
144 HideOutputExceptOnProcess0 hideCout (std::cout, myRank);
147 Kokkos::initialize (*argc, *argv);
148 tpetraInitializedKokkos_ =
true;
152 const bool kokkosIsInitialized =
153 Kokkos::is_initialized ();
154 TEUCHOS_TEST_FOR_EXCEPTION
155 (! kokkosIsInitialized, std::logic_error,
"At the end of " 156 "initKokkosIfNeeded, Kokkos is not initialized. " 157 "Please report this bug to the Tpetra developers.");
160 #ifdef HAVE_TPETRACORE_MPI 163 void initMpiIfNeeded (
int* argc,
char*** argv)
173 const bool mpiReady = mpiIsInitializedAndNotFinalized ();
180 const int err = MPI_Init (argc, argv);
181 TEUCHOS_TEST_FOR_EXCEPTION
182 (err != MPI_SUCCESS, std::runtime_error,
"MPI_Init failed with " 183 "error code " << err <<
" != MPI_SUCCESS. If MPI was set up " 184 "correctly, then this should not happen, since we have already " 185 "checked that MPI_Init (or MPI_Init_thread) has not yet been " 186 "called. This may indicate that your MPI library is corrupted " 187 "or that it is incorrectly linked to your program.");
188 tpetraInitializedMpi_ =
true;
191 #endif // HAVE_TPETRACORE_MPI 196 return tpetraIsInitialized_;
207 if (wrappedDefaultComm_.is_null ()) {
208 Teuchos::RCP<const Teuchos::Comm<int> > comm;
209 #ifdef HAVE_TPETRACORE_MPI 213 const bool mpiReady = mpiIsInitializedAndNotFinalized ();
215 comm = Teuchos::rcp (
new Teuchos::MpiComm<int> (MPI_COMM_WORLD));
218 comm = Teuchos::rcp (
new Teuchos::SerialComm<int> ());
221 comm = Teuchos::rcp (
new Teuchos::SerialComm<int> ());
222 #endif // HAVE_TPETRACORE_MPI 223 wrappedDefaultComm_ = comm;
225 return wrappedDefaultComm_;
230 if (! tpetraIsInitialized_) {
231 #if defined(HAVE_TPETRACORE_MPI) 232 initMpiIfNeeded (argc, argv);
236 const int myRank = getRankHarmlessly (MPI_COMM_WORLD);
238 const int myRank = 0;
239 #endif // defined(HAVE_TPETRACORE_MPI) 240 initKokkosIfNeeded (argc, argv, myRank);
242 tpetraIsInitialized_ =
true;
245 #ifdef HAVE_TPETRACORE_MPI 246 void initialize (
int* argc,
char*** argv, MPI_Comm comm)
248 if (! tpetraIsInitialized_) {
249 #if defined(HAVE_TPETRACORE_MPI) 250 initMpiIfNeeded (argc, argv);
254 const int myRank = getRankHarmlessly (comm);
256 const int myRank = 0;
257 #endif // defined(HAVE_TPETRACORE_MPI) 258 initKokkosIfNeeded (argc, argv, myRank);
260 tpetraIsInitialized_ =
true;
284 wrappedDefaultComm_ = Teuchos::rcp (
new Teuchos::MpiComm<int> (comm));
286 #endif // HAVE_TPETRACORE_MPI 290 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
292 if (! tpetraIsInitialized_) {
293 #if defined(HAVE_TPETRACORE_MPI) 294 initMpiIfNeeded (argc, argv);
295 #endif // defined(HAVE_TPETRACORE_MPI) 299 const int myRank = comm->getRank ();
300 initKokkosIfNeeded (argc, argv, myRank);
302 tpetraIsInitialized_ =
true;
303 wrappedDefaultComm_ = comm;
308 if (! tpetraIsInitialized_) {
314 if (tpetraInitializedKokkos_) {
321 wrappedDefaultComm_ = Teuchos::null;
323 #ifdef HAVE_TPETRACORE_MPI 326 if (tpetraInitializedMpi_) {
335 (void) MPI_Finalize ();
340 #endif // HAVE_TPETRACORE_MPI 342 tpetraIsInitialized_ =
false;
347 ::Tpetra::initialize (argc, argv);
350 #ifdef HAVE_TPETRA_MPI 353 ::Tpetra::initialize (argc, argv, comm);
355 #endif // HAVE_TPETRA_MPI 359 ::Tpetra::finalize ();
~ScopeGuard()
Finalize Tpetra.
bool isInitialized()
Whether Tpetra is in an initialized state.
void initialize(int *argc, char ***argv)
Initialize Tpetra.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
void finalize()
Finalize Tpetra.
Functions for initializing and finalizing Tpetra.
bool mpiIsInitialized()
Has MPI_Init been called (on this process)?
Teuchos::RCP< const Teuchos::Comm< int > > getDefaultComm()
Get Tpetra's default communicator.
ScopeGuard()=delete
Default constructor (FORBIDDEN)