11 #include "Tpetra_Details_mpiIsInitialized.hpp"
13 #ifdef HAVE_TPETRACORE_MPI
14 # include <Teuchos_DefaultMpiComm.hpp>
15 #endif // HAVE_TPETRACORE_MPI
16 #include <Teuchos_DefaultSerialComm.hpp>
18 #include <Kokkos_Core.hpp>
19 #include "Tpetra_Details_checkLaunchBlocking.hpp"
27 class HideOutputExceptOnProcess0 {
29 HideOutputExceptOnProcess0 (std::ostream& stream,
32 originalBuffer_ (stream.rdbuf ())
35 stream.rdbuf (blackHole_.rdbuf ());
39 ~HideOutputExceptOnProcess0 () {
40 stream_.rdbuf (originalBuffer_);
43 std::ostream& stream_;
44 decltype (std::cout.rdbuf ()) originalBuffer_;
45 Teuchos::oblackholestream blackHole_;
48 #if defined(HAVE_TPETRACORE_MPI)
49 bool mpiIsInitializedAndNotFinalized ()
56 (void) MPI_Initialized (&isInitialized);
62 (void) MPI_Finalized (&isFinalized);
67 return isInitialized != 0 && isFinalized == 0;
70 int getRankHarmlessly (MPI_Comm comm)
73 if (mpiIsInitializedAndNotFinalized ()) {
75 (void) MPI_Comm_rank (comm, &myRank);
84 #endif // defined(HAVE_TPETRACORE_MPI)
88 bool tpetraIsInitialized_ =
false;
94 bool tpetraInitializedKokkos_ =
false;
96 #ifdef HAVE_TPETRACORE_MPI
100 bool tpetraInitializedMpi_ =
false;
101 #endif // HAVE_TPETRACORE_MPI
105 Teuchos::RCP<const Teuchos::Comm<int> > wrappedDefaultComm_;
108 void initKokkosIfNeeded (
int* argc,
char*** argv,
const int myRank)
110 if (! tpetraInitializedKokkos_) {
114 const bool kokkosIsInitialized =
115 Kokkos::is_initialized ();
116 if (! kokkosIsInitialized) {
117 HideOutputExceptOnProcess0 hideCerr (std::cerr, myRank);
118 HideOutputExceptOnProcess0 hideCout (std::cout, myRank);
121 Kokkos::initialize (*argc, *argv);
122 tpetraInitializedKokkos_ =
true;
125 Details::checkOldCudaLaunchBlocking();
126 const bool kokkosIsInitialized =
127 Kokkos::is_initialized ();
128 TEUCHOS_TEST_FOR_EXCEPTION
129 (! kokkosIsInitialized, std::logic_error,
"At the end of "
130 "initKokkosIfNeeded, Kokkos is not initialized. "
131 "Please report this bug to the Tpetra developers.");
134 #ifdef HAVE_TPETRACORE_MPI
137 void initMpiIfNeeded (
int* argc,
char*** argv)
147 const bool mpiReady = mpiIsInitializedAndNotFinalized ();
154 const int err = MPI_Init (argc, argv);
155 TEUCHOS_TEST_FOR_EXCEPTION
156 (err != MPI_SUCCESS, std::runtime_error,
"MPI_Init failed with "
157 "error code " << err <<
" != MPI_SUCCESS. If MPI was set up "
158 "correctly, then this should not happen, since we have already "
159 "checked that MPI_Init (or MPI_Init_thread) has not yet been "
160 "called. This may indicate that your MPI library is corrupted "
161 "or that it is incorrectly linked to your program.");
162 tpetraInitializedMpi_ =
true;
165 #endif // HAVE_TPETRACORE_MPI
170 return tpetraIsInitialized_;
181 if (wrappedDefaultComm_.is_null ()) {
182 Teuchos::RCP<const Teuchos::Comm<int> > comm;
183 #ifdef HAVE_TPETRACORE_MPI
187 const bool mpiReady = mpiIsInitializedAndNotFinalized ();
189 comm = Teuchos::rcp (
new Teuchos::MpiComm<int> (MPI_COMM_WORLD));
192 comm = Teuchos::rcp (
new Teuchos::SerialComm<int> ());
195 comm = Teuchos::rcp (
new Teuchos::SerialComm<int> ());
196 #endif // HAVE_TPETRACORE_MPI
197 wrappedDefaultComm_ = comm;
199 return wrappedDefaultComm_;
204 if (! tpetraIsInitialized_) {
205 #if defined(HAVE_TPETRACORE_MPI)
206 initMpiIfNeeded (argc, argv);
210 const int myRank = getRankHarmlessly (MPI_COMM_WORLD);
212 const int myRank = 0;
213 #endif // defined(HAVE_TPETRACORE_MPI)
214 initKokkosIfNeeded (argc, argv, myRank);
217 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
218 Tpetra::Details::AddKokkosFenceToTimeMonitor();
219 Tpetra::Details::AddKokkosFunctionsToTimeMonitor();
223 tpetraIsInitialized_ =
true;
226 #ifdef HAVE_TPETRACORE_MPI
227 void initialize (
int* argc,
char*** argv, MPI_Comm comm)
229 if (! tpetraIsInitialized_) {
230 #if defined(HAVE_TPETRACORE_MPI)
231 initMpiIfNeeded (argc, argv);
235 const int myRank = getRankHarmlessly (comm);
237 const int myRank = 0;
238 #endif // defined(HAVE_TPETRACORE_MPI)
239 initKokkosIfNeeded (argc, argv, myRank);
242 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
243 Tpetra::Details::AddKokkosFenceToTimeMonitor();
244 Tpetra::Details::AddKokkosFunctionsToTimeMonitor();
248 tpetraIsInitialized_ =
true;
272 wrappedDefaultComm_ = Teuchos::rcp (
new Teuchos::MpiComm<int> (comm));
274 #endif // HAVE_TPETRACORE_MPI
278 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
280 if (! tpetraIsInitialized_) {
281 #if defined(HAVE_TPETRACORE_MPI)
282 initMpiIfNeeded (argc, argv);
283 #endif // defined(HAVE_TPETRACORE_MPI)
287 const int myRank = comm->getRank ();
288 initKokkosIfNeeded (argc, argv, myRank);
291 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
292 Tpetra::Details::AddKokkosFenceToTimeMonitor();
293 Tpetra::Details::AddKokkosFunctionsToTimeMonitor();
297 tpetraIsInitialized_ =
true;
298 wrappedDefaultComm_ = comm;
303 if (! tpetraIsInitialized_) {
309 if (tpetraInitializedKokkos_ && !Kokkos::is_finalized()) {
316 wrappedDefaultComm_ = Teuchos::null;
318 #ifdef HAVE_TPETRACORE_MPI
321 if (tpetraInitializedMpi_) {
330 (void) MPI_Finalize ();
335 #endif // HAVE_TPETRACORE_MPI
337 tpetraIsInitialized_ =
false;
342 ::Tpetra::initialize (argc, argv);
345 #ifdef HAVE_TPETRA_MPI
348 ::Tpetra::initialize (argc, argv, comm);
350 #endif // HAVE_TPETRA_MPI
354 ::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.