43 #include "Tpetra_Details_mpiIsInitialized.hpp"
45 #ifdef HAVE_TPETRACORE_MPI
46 # include <Teuchos_DefaultMpiComm.hpp>
47 #endif // HAVE_TPETRACORE_MPI
48 #include <Teuchos_DefaultSerialComm.hpp>
50 #include <Kokkos_Core.hpp>
55 class HideOutputExceptOnProcess0 {
57 HideOutputExceptOnProcess0 (std::ostream& stream,
60 originalBuffer_ (stream.rdbuf ())
63 stream.rdbuf (blackHole_.rdbuf ());
67 ~HideOutputExceptOnProcess0 () {
68 stream_.rdbuf (originalBuffer_);
71 std::ostream& stream_;
72 decltype (std::cout.rdbuf ()) originalBuffer_;
73 Teuchos::oblackholestream blackHole_;
76 #if defined(HAVE_TPETRACORE_MPI)
77 bool mpiIsInitializedAndNotFinalized ()
84 (void) MPI_Initialized (&isInitialized);
90 (void) MPI_Finalized (&isFinalized);
95 return isInitialized != 0 && isFinalized == 0;
98 int getRankHarmlessly (MPI_Comm comm)
101 if (mpiIsInitializedAndNotFinalized ()) {
103 (void) MPI_Comm_rank (comm, &myRank);
112 #endif // defined(HAVE_TPETRACORE_MPI)
116 bool tpetraIsInitialized_ =
false;
122 bool tpetraInitializedKokkos_ =
false;
124 #ifdef HAVE_TPETRACORE_MPI
128 bool tpetraInitializedMpi_ =
false;
129 #endif // HAVE_TPETRACORE_MPI
133 Teuchos::RCP<const Teuchos::Comm<int> > wrappedDefaultComm_;
136 void initKokkosIfNeeded (
int* argc,
char*** argv,
const int myRank)
138 if (! tpetraInitializedKokkos_) {
142 const bool kokkosIsInitialized =
143 Kokkos::is_initialized ();
144 if (! kokkosIsInitialized) {
145 HideOutputExceptOnProcess0 hideCerr (std::cerr, myRank);
146 HideOutputExceptOnProcess0 hideCout (std::cout, myRank);
149 Kokkos::initialize (*argc, *argv);
150 tpetraInitializedKokkos_ =
true;
154 const bool kokkosIsInitialized =
155 Kokkos::is_initialized ();
156 TEUCHOS_TEST_FOR_EXCEPTION
157 (! kokkosIsInitialized, std::logic_error,
"At the end of "
158 "initKokkosIfNeeded, Kokkos is not initialized. "
159 "Please report this bug to the Tpetra developers.");
162 #ifdef HAVE_TPETRACORE_MPI
165 void initMpiIfNeeded (
int* argc,
char*** argv)
175 const bool mpiReady = mpiIsInitializedAndNotFinalized ();
182 const int err = MPI_Init (argc, argv);
183 TEUCHOS_TEST_FOR_EXCEPTION
184 (err != MPI_SUCCESS, std::runtime_error,
"MPI_Init failed with "
185 "error code " << err <<
" != MPI_SUCCESS. If MPI was set up "
186 "correctly, then this should not happen, since we have already "
187 "checked that MPI_Init (or MPI_Init_thread) has not yet been "
188 "called. This may indicate that your MPI library is corrupted "
189 "or that it is incorrectly linked to your program.");
190 tpetraInitializedMpi_ =
true;
193 #endif // HAVE_TPETRACORE_MPI
198 return tpetraIsInitialized_;
209 if (wrappedDefaultComm_.is_null ()) {
210 Teuchos::RCP<const Teuchos::Comm<int> > comm;
211 #ifdef HAVE_TPETRACORE_MPI
215 const bool mpiReady = mpiIsInitializedAndNotFinalized ();
217 comm = Teuchos::rcp (
new Teuchos::MpiComm<int> (MPI_COMM_WORLD));
220 comm = Teuchos::rcp (
new Teuchos::SerialComm<int> ());
223 comm = Teuchos::rcp (
new Teuchos::SerialComm<int> ());
224 #endif // HAVE_TPETRACORE_MPI
225 wrappedDefaultComm_ = comm;
227 return wrappedDefaultComm_;
232 if (! tpetraIsInitialized_) {
233 #if defined(HAVE_TPETRACORE_MPI)
234 initMpiIfNeeded (argc, argv);
238 const int myRank = getRankHarmlessly (MPI_COMM_WORLD);
240 const int myRank = 0;
241 #endif // defined(HAVE_TPETRACORE_MPI)
242 initKokkosIfNeeded (argc, argv, myRank);
244 tpetraIsInitialized_ =
true;
247 #ifdef HAVE_TPETRACORE_MPI
248 void initialize (
int* argc,
char*** argv, MPI_Comm comm)
250 if (! tpetraIsInitialized_) {
251 #if defined(HAVE_TPETRACORE_MPI)
252 initMpiIfNeeded (argc, argv);
256 const int myRank = getRankHarmlessly (comm);
258 const int myRank = 0;
259 #endif // defined(HAVE_TPETRACORE_MPI)
260 initKokkosIfNeeded (argc, argv, myRank);
262 tpetraIsInitialized_ =
true;
286 wrappedDefaultComm_ = Teuchos::rcp (
new Teuchos::MpiComm<int> (comm));
288 #endif // HAVE_TPETRACORE_MPI
292 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
294 if (! tpetraIsInitialized_) {
295 #if defined(HAVE_TPETRACORE_MPI)
296 initMpiIfNeeded (argc, argv);
297 #endif // defined(HAVE_TPETRACORE_MPI)
301 const int myRank = comm->getRank ();
302 initKokkosIfNeeded (argc, argv, myRank);
304 tpetraIsInitialized_ =
true;
305 wrappedDefaultComm_ = comm;
310 if (! tpetraIsInitialized_) {
316 if (tpetraInitializedKokkos_) {
323 wrappedDefaultComm_ = Teuchos::null;
325 #ifdef HAVE_TPETRACORE_MPI
328 if (tpetraInitializedMpi_) {
337 (void) MPI_Finalize ();
342 #endif // HAVE_TPETRACORE_MPI
344 tpetraIsInitialized_ =
false;
349 ::Tpetra::initialize (argc, argv);
352 #ifdef HAVE_TPETRA_MPI
355 ::Tpetra::initialize (argc, argv, comm);
357 #endif // HAVE_TPETRA_MPI
361 ::Tpetra::finalize ();
~ScopeGuard()
Finalize Tpetra.
bool isInitialized()
Whether Tpetra is in an initialized state.
void initialize(int *argc, char ***argv)
Initialize Tpetra.
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)