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"
22 #include "KokkosKernels_EagerInitialize.hpp"
28 class HideOutputExceptOnProcess0 {
30 HideOutputExceptOnProcess0(std::ostream& stream,
33 , originalBuffer_(stream.rdbuf()) {
35 stream.rdbuf(blackHole_.rdbuf());
39 ~HideOutputExceptOnProcess0() {
40 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() {
56 (void)MPI_Initialized(&isInitialized);
61 (void)MPI_Finalized(&isFinalized);
65 return isInitialized != 0 && isFinalized == 0;
68 int getRankHarmlessly(MPI_Comm comm) {
70 if (mpiIsInitializedAndNotFinalized()) {
72 (void)MPI_Comm_rank(comm, &myRank);
80 #endif // defined(HAVE_TPETRACORE_MPI)
83 bool tpetraIsInitialized_ =
false;
89 bool tpetraInitializedKokkos_ =
false;
91 #ifdef HAVE_TPETRACORE_MPI
95 bool tpetraInitializedMpi_ =
false;
96 #endif // HAVE_TPETRACORE_MPI
100 Teuchos::RCP<const Teuchos::Comm<int> > wrappedDefaultComm_;
103 void initKokkosIfNeeded(
int* argc,
char*** argv,
const int myRank) {
104 if (!tpetraInitializedKokkos_) {
108 const bool kokkosIsInitialized =
109 Kokkos::is_initialized();
110 if (!kokkosIsInitialized) {
111 HideOutputExceptOnProcess0 hideCerr(std::cerr, myRank);
112 HideOutputExceptOnProcess0 hideCout(std::cout, myRank);
115 Kokkos::initialize(*argc, *argv);
116 tpetraInitializedKokkos_ =
true;
119 Details::checkOldCudaLaunchBlocking();
120 const bool kokkosIsInitialized =
121 Kokkos::is_initialized();
122 TEUCHOS_TEST_FOR_EXCEPTION(!kokkosIsInitialized, std::logic_error,
124 "initKokkosIfNeeded, Kokkos is not initialized. "
125 "Please report this bug to the Tpetra developers.");
128 KokkosKernels::eager_initialize();
131 #ifdef HAVE_TPETRACORE_MPI
134 void initMpiIfNeeded(
int* argc,
char*** argv) {
143 const bool mpiReady = mpiIsInitializedAndNotFinalized();
150 const int err = MPI_Init(argc, argv);
151 TEUCHOS_TEST_FOR_EXCEPTION(err != MPI_SUCCESS, std::runtime_error,
152 "MPI_Init failed with "
154 << err <<
" != MPI_SUCCESS. If MPI was set up "
155 "correctly, then this should not happen, since we have already "
156 "checked that MPI_Init (or MPI_Init_thread) has not yet been "
157 "called. This may indicate that your MPI library is corrupted "
158 "or that it is incorrectly linked to your program.");
159 tpetraInitializedMpi_ =
true;
162 #endif // HAVE_TPETRACORE_MPI
167 return tpetraIsInitialized_;
177 if (wrappedDefaultComm_.is_null()) {
178 Teuchos::RCP<const Teuchos::Comm<int> > comm;
179 #ifdef HAVE_TPETRACORE_MPI
183 const bool mpiReady = mpiIsInitializedAndNotFinalized();
185 comm = Teuchos::rcp(
new Teuchos::MpiComm<int>(MPI_COMM_WORLD));
187 comm = Teuchos::rcp(
new Teuchos::SerialComm<int>());
190 comm = Teuchos::rcp(
new Teuchos::SerialComm<int>());
191 #endif // HAVE_TPETRACORE_MPI
192 wrappedDefaultComm_ = comm;
194 return wrappedDefaultComm_;
198 if (!tpetraIsInitialized_) {
199 #if defined(HAVE_TPETRACORE_MPI)
200 initMpiIfNeeded(argc, argv);
204 const int myRank = getRankHarmlessly(MPI_COMM_WORLD);
206 const int myRank = 0;
207 #endif // defined(HAVE_TPETRACORE_MPI)
208 initKokkosIfNeeded(argc, argv, myRank);
211 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
212 Tpetra::Details::AddKokkosFenceToTimeMonitor();
213 Tpetra::Details::AddKokkosFunctionsToTimeMonitor();
217 tpetraIsInitialized_ =
true;
220 #ifdef HAVE_TPETRACORE_MPI
221 void initialize(
int* argc,
char*** argv, MPI_Comm comm) {
222 if (!tpetraIsInitialized_) {
223 #if defined(HAVE_TPETRACORE_MPI)
224 initMpiIfNeeded(argc, argv);
228 const int myRank = getRankHarmlessly(comm);
230 const int myRank = 0;
231 #endif // defined(HAVE_TPETRACORE_MPI)
232 initKokkosIfNeeded(argc, argv, myRank);
235 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
236 Tpetra::Details::AddKokkosFenceToTimeMonitor();
237 Tpetra::Details::AddKokkosFunctionsToTimeMonitor();
241 tpetraIsInitialized_ =
true;
265 wrappedDefaultComm_ = Teuchos::rcp(
new Teuchos::MpiComm<int>(comm));
267 #endif // HAVE_TPETRACORE_MPI
270 const Teuchos::RCP<
const Teuchos::Comm<int> >& comm) {
271 if (!tpetraIsInitialized_) {
272 #if defined(HAVE_TPETRACORE_MPI)
273 initMpiIfNeeded(argc, argv);
274 #endif // defined(HAVE_TPETRACORE_MPI)
278 const int myRank = comm->getRank();
279 initKokkosIfNeeded(argc, argv, myRank);
282 Tpetra::Details::AddKokkosDeepCopyToTimeMonitor();
283 Tpetra::Details::AddKokkosFenceToTimeMonitor();
284 Tpetra::Details::AddKokkosFunctionsToTimeMonitor();
288 tpetraIsInitialized_ =
true;
289 wrappedDefaultComm_ = comm;
293 if (!tpetraIsInitialized_) {
299 if (tpetraInitializedKokkos_ && !Kokkos::is_finalized()) {
306 wrappedDefaultComm_ = Teuchos::null;
308 #ifdef HAVE_TPETRACORE_MPI
311 if (tpetraInitializedMpi_) {
320 (void)MPI_Finalize();
325 #endif // HAVE_TPETRACORE_MPI
327 tpetraIsInitialized_ =
false;
331 ::Tpetra::initialize(argc, argv);
334 #ifdef HAVE_TPETRA_MPI
336 ::Tpetra::initialize(argc, argv, comm);
338 #endif // HAVE_TPETRA_MPI
341 ::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.