SOPT
Sparse OPTimisation
session.cc
Go to the documentation of this file.
1 #include "sopt/mpi/session.h"
2 #include "sopt/config.h"
3 #include "sopt/exception.h"
4 #include <mpi.h>
5 #include "sopt/logging.h"
6 #include "sopt/types.h"
7 
8 namespace sopt::mpi {
9 
10 namespace details {
11 void initializer::deleter(initializer *tag) {
12  if (tag == nullptr) return;
13 
14  delete tag;
15 
16  if (finalized() or not initialized()) return;
17 
18  auto const error = MPI_Finalize();
19  if (error != MPI_SUCCESS) {
20  SOPT_ERROR("Error while calling MPI_Initialized ({})", error);
21  throw std::runtime_error("MPI error");
22  }
23 }
24 std::weak_ptr<initializer> initializer::singleton;
25 } // namespace details
26 
27 std::shared_ptr<details::initializer> init(int argc, const char **argv) {
28  if (finalized()) throw std::runtime_error("MPI session has already been finalized");
29  if (not initialized()) {
30  assert(details::initializer::singleton.expired());
31  std::shared_ptr<details::initializer> const ptr(new details::initializer,
32  &details::initializer::deleter);
33 #ifdef SOPT_OPENMP
34  int provided;
35  if (MPI_Init_thread(&argc, const_cast<char ***>(&argv), MPI_THREAD_FUNNELED, &provided) ==
36  MPI_SUCCESS)
37 #else
38  if (MPI_Init(&argc, const_cast<char ***>(&argv)) == MPI_SUCCESS)
39 #endif
40  details::initializer::singleton = ptr;
41 
42 #ifdef SOPT_OPENMP
43  if (provided < MPI_THREAD_FUNNELED) SOPT_THROW("MPI threading support not sufficient.");
44 #endif
45  return details::initializer::singleton.lock();
46  }
47  return session_singleton();
48 }
49 
50 std::shared_ptr<details::initializer> session_singleton() {
51  if (not initialized()) throw std::runtime_error("MPI session not initialized");
52  if (details::initializer::singleton.expired()) {
53  std::shared_ptr<details::initializer> const ptr(new details::initializer,
54  &details::initializer::deleter);
55  details::initializer::singleton = ptr;
56  return details::initializer::singleton.lock();
57  }
58  return details::initializer::singleton.lock();
59 }
60 
61 bool initialized() {
62  int flag;
63  auto const error = MPI_Initialized(&flag);
64  if (error != MPI_SUCCESS) {
65  SOPT_ERROR("Error while calling MPI_Initialized ({})", error);
66  throw std::runtime_error("MPI error");
67  }
68  return static_cast<bool>(flag);
69 }
70 
71 bool finalized() {
72  int finalized;
73  MPI_Finalized(&finalized);
74  return finalized != 0;
75 }
76 
77 void finalize() {
78  if (finalized() or not initialized()) return;
79  MPI_Finalize();
80 }
81 
82 } // namespace sopt::mpi
#define SOPT_THROW(MSG)
Definition: exception.h:46
#define SOPT_ERROR(...)
\macro Something is definitely wrong, algorithm exits
Definition: logging.h:211
bool finalized()
Definition: session.cc:71
std::shared_ptr< details::initializer > session_singleton()
Definition: session.cc:50
void finalize()
Definition: session.cc:77
std::shared_ptr< details::initializer > init(int argc, const char **argv)
Definition: session.cc:27
bool initialized()
Definition: session.cc:61