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"
57 class HideOutputExceptOnProcess0 {
59 HideOutputExceptOnProcess0 (std::ostream& stream,
62 originalBuffer_ (stream.rdbuf ())
65 stream.rdbuf (blackHole_.rdbuf ());
69 ~HideOutputExceptOnProcess0 () {
70 stream_.rdbuf (originalBuffer_);
73 std::ostream& stream_;
74 decltype (std::cout.rdbuf ()) originalBuffer_;
75 Teuchos::oblackholestream blackHole_;
78 #if defined(HAVE_TPETRACORE_MPI)
79 bool mpiIsInitializedAndNotFinalized ()
86 (void) MPI_Initialized (&isInitialized);
92 (void) MPI_Finalized (&isFinalized);
97 return isInitialized != 0 && isFinalized == 0;
100 int getRankHarmlessly (MPI_Comm comm)
103 if (mpiIsInitializedAndNotFinalized ()) {
105 (void) MPI_Comm_rank (comm, &myRank);
114 #endif // defined(HAVE_TPETRACORE_MPI)
118 bool tpetraIsInitialized_ =
false;
124 bool tpetraInitializedKokkos_ =
false;
126 #ifdef HAVE_TPETRACORE_MPI
130 bool tpetraInitializedMpi_ =
false;
131 #endif // HAVE_TPETRACORE_MPI
135 Teuchos::RCP<const Teuchos::Comm<int> > wrappedDefaultComm_;
138 void initKokkosIfNeeded (
int* argc,
char*** argv,
const int myRank)
140 if (! tpetraInitializedKokkos_) {
144 const bool kokkosIsInitialized =
145 Kokkos::is_initialized ();
146 if (! kokkosIsInitialized) {
147 HideOutputExceptOnProcess0 hideCerr (std::cerr, myRank);
148 HideOutputExceptOnProcess0 hideCout (std::cout, myRank);
151 Kokkos::initialize (*argc, *argv);
152 tpetraInitializedKokkos_ =
true;
155 Details::checkOldCudaLaunchBlocking();
156 const bool kokkosIsInitialized =
157 Kokkos::is_initialized ();
158 TEUCHOS_TEST_FOR_EXCEPTION
159 (! kokkosIsInitialized, std::logic_error,
"At the end of "
160 "initKokkosIfNeeded, Kokkos is not initialized. "
161 "Please report this bug to the Tpetra developers.");
164 #ifdef HAVE_TPETRACORE_MPI
167 void initMpiIfNeeded (
int* argc,
char*** argv)
177 const bool mpiReady = mpiIsInitializedAndNotFinalized ();
184 const int err = MPI_Init (argc, argv);
185 TEUCHOS_TEST_FOR_EXCEPTION
186 (err != MPI_SUCCESS, std::runtime_error,
"MPI_Init failed with "
187 "error code " << err <<
" != MPI_SUCCESS. If MPI was set up "
188 "correctly, then this should not happen, since we have already "
189 "checked that MPI_Init (or MPI_Init_thread) has not yet been "
190 "called. This may indicate that your MPI library is corrupted "
191 "or that it is incorrectly linked to your program.");
192 tpetraInitializedMpi_ =
true;
195 #endif // HAVE_TPETRACORE_MPI
200 return tpetraIsInitialized_;
211 if (wrappedDefaultComm_.is_null ()) {
212 Teuchos::RCP<const Teuchos::Comm<int> > comm;
213 #ifdef HAVE_TPETRACORE_MPI
217 const bool mpiReady = mpiIsInitializedAndNotFinalized ();
219 comm = Teuchos::rcp (
new Teuchos::MpiComm<int> (MPI_COMM_WORLD));
222 comm = Teuchos::rcp (
new Teuchos::SerialComm<int> ());
225 comm = Teuchos::rcp (
new Teuchos::SerialComm<int> ());
226 #endif // HAVE_TPETRACORE_MPI
227 wrappedDefaultComm_ = comm;
229 return wrappedDefaultComm_;
234 if (! tpetraIsInitialized_) {
235 #if defined(HAVE_TPETRACORE_MPI)
236 initMpiIfNeeded (argc, argv);
240 const int myRank = getRankHarmlessly (MPI_COMM_WORLD);
242 const int myRank = 0;
243 #endif // defined(HAVE_TPETRACORE_MPI)
244 initKokkosIfNeeded (argc, argv, myRank);
247 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
248 Tpetra::Details::AddKokkosFenceToTimeMonitor();
249 Tpetra::Details::AddKokkosFunctionsToTimeMonitor();
253 tpetraIsInitialized_ =
true;
256 #ifdef HAVE_TPETRACORE_MPI
257 void initialize (
int* argc,
char*** argv, MPI_Comm comm)
259 if (! tpetraIsInitialized_) {
260 #if defined(HAVE_TPETRACORE_MPI)
261 initMpiIfNeeded (argc, argv);
265 const int myRank = getRankHarmlessly (comm);
267 const int myRank = 0;
268 #endif // defined(HAVE_TPETRACORE_MPI)
269 initKokkosIfNeeded (argc, argv, myRank);
272 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
273 Tpetra::Details::AddKokkosFenceToTimeMonitor();
274 Tpetra::Details::AddKokkosFunctionsToTimeMonitor();
278 tpetraIsInitialized_ =
true;
302 wrappedDefaultComm_ = Teuchos::rcp (
new Teuchos::MpiComm<int> (comm));
304 #endif // HAVE_TPETRACORE_MPI
308 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
310 if (! tpetraIsInitialized_) {
311 #if defined(HAVE_TPETRACORE_MPI)
312 initMpiIfNeeded (argc, argv);
313 #endif // defined(HAVE_TPETRACORE_MPI)
317 const int myRank = comm->getRank ();
318 initKokkosIfNeeded (argc, argv, myRank);
321 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
322 Tpetra::Details::AddKokkosFenceToTimeMonitor();
323 Tpetra::Details::AddKokkosFunctionsToTimeMonitor();
327 tpetraIsInitialized_ =
true;
328 wrappedDefaultComm_ = comm;
333 if (! tpetraIsInitialized_) {
339 if (tpetraInitializedKokkos_ && !Kokkos::is_finalized()) {
346 wrappedDefaultComm_ = Teuchos::null;
348 #ifdef HAVE_TPETRACORE_MPI
351 if (tpetraInitializedMpi_) {
360 (void) MPI_Finalize ();
365 #endif // HAVE_TPETRACORE_MPI
367 tpetraIsInitialized_ =
false;
372 ::Tpetra::initialize (argc, argv);
375 #ifdef HAVE_TPETRA_MPI
378 ::Tpetra::initialize (argc, argv, comm);
380 #endif // HAVE_TPETRA_MPI
384 ::Tpetra::finalize ();
~ScopeGuard()
Finalize Tpetra.
bool isInitialized()
Whether Tpetra is in an initialized state.
void initialize(int *argc, char ***argv)
Initialize Tpetra.
static void reject_unrecognized_env_vars()
Search the environment for TPETRA_ variables and reject unrecognized ones.
Declaration functions that use Kokkos' profiling library to add deep copies between memory spaces...
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)
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.