Loading...
Searching...
No Matches
mpi.hpp
Go to the documentation of this file.
1
2#pragma once
3#include <iostream>
4#include <mpi.h>
5#ifdef TERRANEO_USE_NESMIK
6#include <nesmik/nesmik.hpp>
7#endif
8
9namespace terra::mpi {
10
11using MPIRank = int;
12
13inline MPIRank rank()
14{
16 MPI_Comm_rank( MPI_COMM_WORLD, &rank );
17 return rank;
18}
19
20inline MPIRank rank( MPI_Comm comm )
21{
23 MPI_Comm_rank( comm, &rank );
24 return rank;
25}
26
27inline int num_processes()
28{
29 int num_processes;
30 MPI_Comm_size( MPI_COMM_WORLD, &num_processes );
31 return num_processes;
32}
33
34inline int num_processes( MPI_Comm comm )
35{
36 int num_processes;
37 MPI_Comm_size( comm, &num_processes );
38 return num_processes;
39}
40
41inline void barrier()
42{
43 MPI_Barrier(MPI_COMM_WORLD);
44}
45
46namespace detail {
48{
49 public:
50 MPIContext( const MPIContext& ) = delete;
51 MPIContext& operator=( const MPIContext& ) = delete;
52 MPIContext( MPIContext&& ) = delete;
54
55 /// Initialize MPI once. Safe to call only once.
56 static void initialize( int* argc, char*** argv ) { instance( argc, argv ); }
57
58 /// Query whether MPI is initialized
59 static bool is_initialized()
60 {
61 int flag = 0;
62 MPI_Initialized( &flag );
63 return flag != 0;
64 }
65
66 /// Query whether MPI is finalized
67 static bool is_finalized()
68 {
69 int flag = 0;
70 MPI_Finalized( &flag );
71 return flag != 0;
72 }
73
74 private:
75 bool mpi_initialized_ = false;
76
77 // private constructor
78 MPIContext( int* argc, char*** argv )
79 {
80 if ( is_initialized() )
81 {
82 throw std::runtime_error( "MPI already initialized!" );
83 }
84
85 int err = MPI_Init( argc, argv );
86 #ifdef TERRANEO_USE_NESMIK
87 nesmik::init();
88 #endif
89 if ( err != MPI_SUCCESS )
90 {
91 char errstr[MPI_MAX_ERROR_STRING];
92 int len = 0;
93 MPI_Error_string( err, errstr, &len );
94 throw std::runtime_error( std::string( "MPI_Init failed: " ) + std::string( errstr, len ) );
95 }
96
97 mpi_initialized_ = true;
98
99 MPI_Comm_set_errhandler( MPI_COMM_WORLD, MPI_ERRORS_RETURN );
100 }
101
102 // private destructor
103 ~MPIContext()
104 {
105 if ( mpi_initialized_ && !is_finalized() )
106 {
107 #ifdef TERRANEO_USE_NESMIK
108 nesmik::finalize();
109 #endif
110 int err = MPI_Finalize();
111 if ( err != MPI_SUCCESS )
112 {
113 char errstr[MPI_MAX_ERROR_STRING];
114 int len = 0;
115 MPI_Error_string( err, errstr, &len );
116 std::cerr << "[MPI] MPI_Finalize failed: " << std::string( errstr, len ) << std::endl;
117 }
118 }
119 }
120
121 // singleton instance accessor
122 static MPIContext& instance( int* argc = nullptr, char*** argv = nullptr )
123 {
124 static MPIContext guard( argc, argv );
125 return guard;
126 }
127};
128
129} // namespace detail
130
131inline std::string mpi_error_string( int err )
132{
133 char errstr[MPI_MAX_ERROR_STRING];
134 int len = 0;
135 MPI_Error_string( err, errstr, &len );
136 return { errstr, static_cast< size_t >( len ) };
137}
138
139template < typename T >
140MPI_Datatype mpi_datatype()
141{
142 static_assert( sizeof( T ) == 0, "No MPI datatype mapping for this type." );
143 return MPI_DATATYPE_NULL;
144}
145
146template <>
147inline MPI_Datatype mpi_datatype< char >()
148{
149 return MPI_CHAR;
150}
151
152template <>
153inline MPI_Datatype mpi_datatype< signed char >()
154{
155 return MPI_SIGNED_CHAR;
156}
157
158template <>
159inline MPI_Datatype mpi_datatype< unsigned char >()
160{
161 return MPI_UNSIGNED_CHAR;
162}
163
164template <>
165inline MPI_Datatype mpi_datatype< int >()
166{
167 return MPI_INT;
168}
169
170template <>
171inline MPI_Datatype mpi_datatype< unsigned int >()
172{
173 return MPI_UNSIGNED;
174}
175
176template <>
177inline MPI_Datatype mpi_datatype< short >()
178{
179 return MPI_SHORT;
180}
181
182template <>
184{
185 return MPI_UNSIGNED_SHORT;
186}
187
188template <>
189inline MPI_Datatype mpi_datatype< long >()
190{
191 return MPI_LONG;
192}
193
194template <>
195inline MPI_Datatype mpi_datatype< unsigned long >()
196{
197 return MPI_UNSIGNED_LONG;
198}
199
200template <>
201inline MPI_Datatype mpi_datatype< long long >()
202{
203 return MPI_LONG_LONG;
204}
205
206template <>
208{
209 return MPI_UNSIGNED_LONG_LONG;
210}
211
212template <>
213inline MPI_Datatype mpi_datatype< float >()
214{
215 return MPI_FLOAT;
216}
217
218template <>
219inline MPI_Datatype mpi_datatype< double >()
220{
221 return MPI_DOUBLE;
222}
223
224template <>
225inline MPI_Datatype mpi_datatype< long double >()
226{
227 return MPI_LONG_DOUBLE;
228}
229
230template <>
231inline MPI_Datatype mpi_datatype< bool >()
232{
233 return MPI_CXX_BOOL;
234}
235
236} // namespace terra::mpi
Definition mpi.hpp:48
MPIContext(const MPIContext &)=delete
static bool is_finalized()
Query whether MPI is finalized.
Definition mpi.hpp:67
MPIContext(MPIContext &&)=delete
static void initialize(int *argc, char ***argv)
Initialize MPI once. Safe to call only once.
Definition mpi.hpp:56
static bool is_initialized()
Query whether MPI is initialized.
Definition mpi.hpp:59
MPIContext & operator=(MPIContext &&)=delete
MPIContext & operator=(const MPIContext &)=delete
Definition level_comms.hpp:10
MPI_Datatype mpi_datatype< unsigned long long >()
Definition mpi.hpp:207
MPI_Datatype mpi_datatype< float >()
Definition mpi.hpp:213
std::string mpi_error_string(int err)
Definition mpi.hpp:131
MPI_Datatype mpi_datatype< char >()
Definition mpi.hpp:147
MPI_Datatype mpi_datatype< unsigned long >()
Definition mpi.hpp:195
MPI_Datatype mpi_datatype< short >()
Definition mpi.hpp:177
MPI_Datatype mpi_datatype< unsigned char >()
Definition mpi.hpp:159
void barrier()
Definition mpi.hpp:41
int num_processes()
Definition mpi.hpp:27
MPI_Datatype mpi_datatype< unsigned int >()
Definition mpi.hpp:171
int MPIRank
Definition mpi.hpp:11
MPI_Datatype mpi_datatype< bool >()
Definition mpi.hpp:231
MPI_Datatype mpi_datatype< double >()
Definition mpi.hpp:219
MPI_Datatype mpi_datatype< long long >()
Definition mpi.hpp:201
MPI_Datatype mpi_datatype< int >()
Definition mpi.hpp:165
MPI_Datatype mpi_datatype< unsigned short >()
Definition mpi.hpp:183
MPI_Datatype mpi_datatype< long double >()
Definition mpi.hpp:225
MPIRank rank()
Definition mpi.hpp:13
MPI_Datatype mpi_datatype()
Definition mpi.hpp:140
MPI_Datatype mpi_datatype< signed char >()
Definition mpi.hpp:153
MPI_Datatype mpi_datatype< long >()
Definition mpi.hpp:189