41#include "Tpetra_Details_mpiIsInitialized.hpp"
43#ifdef HAVE_TPETRACORE_MPI
44# include <Teuchos_DefaultMpiComm.hpp>
46#include <Teuchos_DefaultSerialComm.hpp>
48#include <Kokkos_Core.hpp>
49#include "Tpetra_Details_checkLaunchBlocking.hpp"
56 class HideOutputExceptOnProcess0 {
58 HideOutputExceptOnProcess0 (std::ostream& stream,
61 originalBuffer_ (stream.rdbuf ())
64 stream.rdbuf (blackHole_.rdbuf ());
68 ~HideOutputExceptOnProcess0 () {
69 stream_.rdbuf (originalBuffer_);
72 std::ostream& stream_;
73 decltype (std::cout.rdbuf ()) originalBuffer_;
74 Teuchos::oblackholestream blackHole_;
77#if defined(HAVE_TPETRACORE_MPI)
78 bool mpiIsInitializedAndNotFinalized ()
91 (void) MPI_Finalized (&isFinalized);
99 int getRankHarmlessly (MPI_Comm comm)
102 if (mpiIsInitializedAndNotFinalized ()) {
104 (void) MPI_Comm_rank (comm, &myRank);
117 bool tpetraIsInitialized_ =
false;
123 bool tpetraInitializedKokkos_ =
false;
125#ifdef HAVE_TPETRACORE_MPI
129 bool tpetraInitializedMpi_ =
false;
134 Teuchos::RCP<const Teuchos::Comm<int> > wrappedDefaultComm_;
137 void initKokkosIfNeeded (
int* argc,
char*** argv,
const int myRank)
139 if (! tpetraInitializedKokkos_) {
143 const bool kokkosIsInitialized =
144 Kokkos::is_initialized ();
145 if (! kokkosIsInitialized) {
146 HideOutputExceptOnProcess0 hideCerr (std::cerr, myRank);
147 HideOutputExceptOnProcess0 hideCout (std::cout, myRank);
150 Kokkos::initialize (*argc, *argv);
151 tpetraInitializedKokkos_ =
true;
154 Details::checkOldCudaLaunchBlocking();
155 const bool kokkosIsInitialized =
156 Kokkos::is_initialized ();
157 TEUCHOS_TEST_FOR_EXCEPTION
158 (! kokkosIsInitialized, std::logic_error,
"At the end of "
159 "initKokkosIfNeeded, Kokkos is not initialized. "
160 "Please report this bug to the Tpetra developers.");
163#ifdef HAVE_TPETRACORE_MPI
166 void initMpiIfNeeded (
int* argc,
char*** argv)
176 const bool mpiReady = mpiIsInitializedAndNotFinalized ();
183 const int err = MPI_Init (argc, argv);
184 TEUCHOS_TEST_FOR_EXCEPTION
185 (err != MPI_SUCCESS, std::runtime_error,
"MPI_Init failed with "
186 "error code " << err <<
" != MPI_SUCCESS. If MPI was set up "
187 "correctly, then this should not happen, since we have already "
188 "checked that MPI_Init (or MPI_Init_thread) has not yet been "
189 "called. This may indicate that your MPI library is corrupted "
190 "or that it is incorrectly linked to your program.");
191 tpetraInitializedMpi_ =
true;
199 return tpetraIsInitialized_;
210 if (wrappedDefaultComm_.is_null ()) {
211 Teuchos::RCP<const Teuchos::Comm<int> > comm;
212#ifdef HAVE_TPETRACORE_MPI
216 const bool mpiReady = mpiIsInitializedAndNotFinalized ();
218 comm = Teuchos::rcp (
new Teuchos::MpiComm<int> (MPI_COMM_WORLD));
221 comm = Teuchos::rcp (
new Teuchos::SerialComm<int> ());
224 comm = Teuchos::rcp (
new Teuchos::SerialComm<int> ());
226 wrappedDefaultComm_ = comm;
228 return wrappedDefaultComm_;
233 if (! tpetraIsInitialized_) {
234#if defined(HAVE_TPETRACORE_MPI)
235 initMpiIfNeeded (argc, argv);
239 const int myRank = getRankHarmlessly (MPI_COMM_WORLD);
241 const int myRank = 0;
243 initKokkosIfNeeded (argc, argv, myRank);
246 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
248 tpetraIsInitialized_ =
true;
251#ifdef HAVE_TPETRACORE_MPI
252 void initialize (
int* argc,
char*** argv, MPI_Comm comm)
254 if (! tpetraIsInitialized_) {
255#if defined(HAVE_TPETRACORE_MPI)
256 initMpiIfNeeded (argc, argv);
260 const int myRank = getRankHarmlessly (comm);
262 const int myRank = 0;
264 initKokkosIfNeeded (argc, argv, myRank);
267 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
269 tpetraIsInitialized_ =
true;
293 wrappedDefaultComm_ = Teuchos::rcp (
new Teuchos::MpiComm<int> (comm));
299 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm)
301 if (! tpetraIsInitialized_) {
302#if defined(HAVE_TPETRACORE_MPI)
303 initMpiIfNeeded (argc, argv);
308 const int myRank = comm->getRank ();
309 initKokkosIfNeeded (argc, argv, myRank);
312 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
314 tpetraIsInitialized_ =
true;
315 wrappedDefaultComm_ = comm;
320 if (! tpetraIsInitialized_) {
326 if (tpetraInitializedKokkos_ && !Kokkos::is_finalized()) {
333 wrappedDefaultComm_ = Teuchos::null;
335#ifdef HAVE_TPETRACORE_MPI
338 if (tpetraInitializedMpi_) {
347 (void) MPI_Finalize ();
354 tpetraIsInitialized_ =
false;
362#ifdef HAVE_TPETRA_MPI
Functions for initializing and finalizing Tpetra.
Declaration of Tpetra::Details::DeepCopyTeuchosTimerInjection, a class that uses Kokkos' profiling li...
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.