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 ()
82 (void) MPI_Initialized (&isInitialized);
88 (void) MPI_Finalized (&isFinalized);
93 return isInitialized != 0 && isFinalized == 0;
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.
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)