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> 49 #include "Tpetra_Details_checkLaunchBlocking.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 ()
90 (void) MPI_Finalized (&isFinalized);
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;
153 Details::checkOldCudaLaunchBlocking();
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.
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)