11#include "Tpetra_Details_mpiIsInitialized.hpp"
13#ifdef HAVE_TPETRACORE_MPI
14# include <Teuchos_DefaultMpiComm.hpp>
16#include <Teuchos_DefaultSerialComm.hpp>
18#include <Kokkos_Core.hpp>
19#include "Tpetra_Details_checkLaunchBlocking.hpp"
22#include "KokkosKernels_EagerInitialize.hpp"
28 class HideOutputExceptOnProcess0 {
30 HideOutputExceptOnProcess0 (std::ostream& stream,
33 originalBuffer_ (stream.rdbuf ())
36 stream.rdbuf (blackHole_.rdbuf ());
40 ~HideOutputExceptOnProcess0 () {
41 stream_.rdbuf (originalBuffer_);
44 std::ostream& stream_;
45 decltype (std::cout.rdbuf ()) originalBuffer_;
46 Teuchos::oblackholestream blackHole_;
49#if defined(HAVE_TPETRACORE_MPI)
50 bool mpiIsInitializedAndNotFinalized ()
63 (void) MPI_Finalized (&isFinalized);
71 int getRankHarmlessly (MPI_Comm comm)
74 if (mpiIsInitializedAndNotFinalized ()) {
76 (void) MPI_Comm_rank (comm, &myRank);
89 bool tpetraIsInitialized_ =
false;
95 bool tpetraInitializedKokkos_ =
false;
97#ifdef HAVE_TPETRACORE_MPI
101 bool tpetraInitializedMpi_ =
false;
106 Teuchos::RCP<const Teuchos::Comm<int> > wrappedDefaultComm_;
109 void initKokkosIfNeeded (
int* argc,
char*** argv,
const int myRank)
111 if (! tpetraInitializedKokkos_) {
115 const bool kokkosIsInitialized =
116 Kokkos::is_initialized ();
117 if (! kokkosIsInitialized) {
118 HideOutputExceptOnProcess0 hideCerr (std::cerr, myRank);
119 HideOutputExceptOnProcess0 hideCout (std::cout, myRank);
122 Kokkos::initialize (*argc, *argv);
123 tpetraInitializedKokkos_ =
true;
126 Details::checkOldCudaLaunchBlocking();
127 const bool kokkosIsInitialized =
128 Kokkos::is_initialized ();
129 TEUCHOS_TEST_FOR_EXCEPTION
130 (! kokkosIsInitialized, std::logic_error,
"At the end of "
131 "initKokkosIfNeeded, Kokkos is not initialized. "
132 "Please report this bug to the Tpetra developers.");
135 KokkosKernels::eager_initialize();
138#ifdef HAVE_TPETRACORE_MPI
141 void initMpiIfNeeded (
int* argc,
char*** argv)
151 const bool mpiReady = mpiIsInitializedAndNotFinalized ();
158 const int err = MPI_Init (argc, argv);
159 TEUCHOS_TEST_FOR_EXCEPTION
160 (err != MPI_SUCCESS, std::runtime_error,
"MPI_Init failed with "
161 "error code " << err <<
" != MPI_SUCCESS. If MPI was set up "
162 "correctly, then this should not happen, since we have already "
163 "checked that MPI_Init (or MPI_Init_thread) has not yet been "
164 "called. This may indicate that your MPI library is corrupted "
165 "or that it is incorrectly linked to your program.");
166 tpetraInitializedMpi_ =
true;
174 return tpetraIsInitialized_;
185 if (wrappedDefaultComm_.is_null ()) {
186 Teuchos::RCP<const Teuchos::Comm<int> > comm;
187#ifdef HAVE_TPETRACORE_MPI
191 const bool mpiReady = mpiIsInitializedAndNotFinalized ();
193 comm = Teuchos::rcp (
new Teuchos::MpiComm<int> (MPI_COMM_WORLD));
196 comm = Teuchos::rcp (
new Teuchos::SerialComm<int> ());
199 comm = Teuchos::rcp (
new Teuchos::SerialComm<int> ());
201 wrappedDefaultComm_ = comm;
203 return wrappedDefaultComm_;
208 if (! tpetraIsInitialized_) {
209#if defined(HAVE_TPETRACORE_MPI)
210 initMpiIfNeeded (argc, argv);
214 const int myRank = getRankHarmlessly (MPI_COMM_WORLD);
216 const int myRank = 0;
218 initKokkosIfNeeded (argc, argv, myRank);
221 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
222 Tpetra::Details::AddKokkosFenceToTimeMonitor();
223 Tpetra::Details::AddKokkosFunctionsToTimeMonitor();
227 tpetraIsInitialized_ =
true;
230#ifdef HAVE_TPETRACORE_MPI
231 void initialize (
int* argc,
char*** argv, MPI_Comm comm)
233 if (! tpetraIsInitialized_) {
234#if defined(HAVE_TPETRACORE_MPI)
235 initMpiIfNeeded (argc, argv);
239 const int myRank = getRankHarmlessly (comm);
241 const int myRank = 0;
243 initKokkosIfNeeded (argc, argv, myRank);
246 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
247 Tpetra::Details::AddKokkosFenceToTimeMonitor();
248 Tpetra::Details::AddKokkosFunctionsToTimeMonitor();
252 tpetraIsInitialized_ =
true;
276 wrappedDefaultComm_ = Teuchos::rcp (
new Teuchos::MpiComm<int> (comm));
282 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
284 if (! tpetraIsInitialized_) {
285#if defined(HAVE_TPETRACORE_MPI)
286 initMpiIfNeeded (argc, argv);
291 const int myRank = comm->getRank ();
292 initKokkosIfNeeded (argc, argv, myRank);
295 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
296 Tpetra::Details::AddKokkosFenceToTimeMonitor();
297 Tpetra::Details::AddKokkosFunctionsToTimeMonitor();
301 tpetraIsInitialized_ =
true;
302 wrappedDefaultComm_ = comm;
307 if (! tpetraIsInitialized_) {
313 if (tpetraInitializedKokkos_ && !Kokkos::is_finalized()) {
320 wrappedDefaultComm_ = Teuchos::null;
322#ifdef HAVE_TPETRACORE_MPI
325 if (tpetraInitializedMpi_) {
334 (void) MPI_Finalize ();
341 tpetraIsInitialized_ =
false;
349#ifdef HAVE_TPETRA_MPI
Functions for initializing and finalizing Tpetra.
Declaration of Tpetra::Details::Behavior, a class that describes Tpetra's behavior.
Declaration functions that use Kokkos' profiling library to add deep copies between memory spaces,...
static void reject_unrecognized_env_vars()
Search the environment for TPETRA_ variables and reject unrecognized ones.
ScopeGuard()=delete
Default constructor (FORBIDDEN).
~ScopeGuard()
Finalize Tpetra.
bool mpiIsInitialized()
Has MPI_Init been called (on this process)?
Namespace Tpetra contains the class and methods constituting the Tpetra library.
void initialize(int *argc, char ***argv)
Initialize Tpetra.
bool isInitialized()
Whether Tpetra is in an initialized state.
void finalize()
Finalize Tpetra.
Teuchos::RCP< const Teuchos::Comm< int > > getDefaultComm()
Get Tpetra's default communicator.