TRIQS/mpi 1.3.0
C++ interface to MPI
Loading...
Searching...
No Matches
communicator.hpp
Go to the documentation of this file.
1// Copyright (c) 2024 Simons Foundation
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0.txt
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// Authors: Thomas Hahn, Alexander Hampel, Olivier Parcollet, Nils Wentzell
16
21
22#pragma once
23
24#include "./environment.hpp"
25#include "./utils.hpp"
26
27#include <mpi.h>
28
29#include <cstdlib>
30#include <unistd.h>
31
32namespace mpi {
33
34 // Forward declaration.
36
49 public:
51 communicator() = default;
52
58 communicator(MPI_Comm c) : comm_(c) {}
59
61 [[nodiscard]] MPI_Comm get() const noexcept { return comm_; }
62
64 [[nodiscard]] bool is_null() const noexcept { return comm_ == MPI_COMM_NULL; }
65
70 [[nodiscard]] int rank() const {
71 int r = 0;
72 if (has_env) check_mpi_call(MPI_Comm_rank(comm_, &r), "MPI_Comm_rank");
73 return r;
74 }
75
80 [[nodiscard]] int size() const {
81 int s = 1;
82 if (has_env) check_mpi_call(MPI_Comm_size(comm_, &s), "MPI_Comm_size");
83 return s;
84 }
85
101 [[nodiscard]] communicator split(int color, int key = 0) const {
102 communicator c{};
103 if (has_env) check_mpi_call(MPI_Comm_split(comm_, color, key, &c.comm_), "MPI_Comm_split");
104 return c;
105 }
106
121 [[nodiscard]] shared_communicator split_shared(int split_type = MPI_COMM_TYPE_SHARED, int key = 0) const;
122
135 [[nodiscard]] communicator duplicate() const {
136 communicator c{};
137 if (has_env) check_mpi_call(MPI_Comm_dup(comm_, &c.comm_), "MPI_Comm_dup");
138 return c;
139 }
140
150 void free() {
151 if (has_env && !is_null()) check_mpi_call(MPI_Comm_free(&comm_), "MPI_Comm_free");
152 }
153
158 void abort(int error_code) const {
159 if (has_env) {
160 check_mpi_call(MPI_Abort(comm_, error_code), "MPI_Abort");
161 } else {
162 std::abort();
163 }
164 }
165
166#ifdef BOOST_MPI_HPP
167 // Conversion to and from boost communicator, Keep for backward compatibility
168 inline operator boost::mpi::communicator() const { return boost::mpi::communicator(comm_, boost::mpi::comm_duplicate); }
169 inline communicator(boost::mpi::communicator c) : comm_(c) {}
170#endif // BOOST_MPI_HPP
171
188 void barrier(long poll_msec = 1) const {
189 if (has_env) {
190 if (poll_msec == 0) {
191 check_mpi_call(MPI_Barrier(comm_), "MPI_Barrier");
192 } else {
193 MPI_Request req{};
194 int flag = 0;
195 check_mpi_call(MPI_Ibarrier(comm_, &req), "MPI_Ibarrier");
196 while (!flag) {
197 check_mpi_call(MPI_Test(&req, &flag, MPI_STATUS_IGNORE), "MPI_Test");
198 usleep(poll_msec * 1000);
199 }
200 }
201 }
202 }
203
204 private:
205 MPI_Comm comm_ = MPI_COMM_WORLD;
206 };
207
217 public:
218 // Make the constructors of mpi::communicator accessible.
220
222 shared_communicator() : communicator(MPI_COMM_NULL) {}
223 };
224
225 [[nodiscard]] inline shared_communicator communicator::split_shared(int split_type, int key) const {
227 if (has_env) check_mpi_call(MPI_Comm_split_type(comm_, split_type, key, MPI_INFO_NULL, &c.comm_), "MPI_Comm_split_type");
228 return c;
229 }
230
231} // namespace mpi
int size() const
Get the size of the communicator.
communicator(MPI_Comm c)
Construct a communicator with a given MPI_Comm object.
shared_communicator split_shared(int split_type=MPI_COMM_TYPE_SHARED, int key=0) const
Partition the communicator into subcommunicators according to their type.
int rank() const
Get the rank of the calling process in the communicator.
communicator duplicate() const
Duplicate the communicator.
void free()
Free the communicator.
communicator split(int color, int key=0) const
Split the communicator into disjoint subgroups.
MPI_Comm get() const noexcept
Get the wrapped MPI_Comm object.
bool is_null() const noexcept
Check if the contained MPI_Comm is MPI_COMM_NULL.
void barrier(long poll_msec=1) const
Barrier synchronization.
void abort(int error_code) const
If mpi::has_env is true, MPI_Abort is called with the given error code, otherwise it calls std::abort...
communicator()=default
Construct a communicator with MPI_COMM_WORLD.
C++ wrapper around MPI_Comm that is a result of the mpi::communicator::split_shared operation.
shared_communicator()
Construct a shared communicator with MPI_COMM_NULL.
communicator()=default
Construct a communicator with MPI_COMM_WORLD.
Provides an MPI environment for initializing and finalizing an MPI program.
static const bool has_env
Boolean variable that is true, if one of the environment variables OMPI_COMM_WORLD_RANK,...
void check_mpi_call(int errcode, const std::string &mpi_routine)
Check the success of an MPI call.
Definition utils.hpp:51
Provides general utilities related to MPI.