56#ifndef FENIX_MPIXX_UTIL_HPP
57#define FENIX_MPIXX_UTIL_HPP
62namespace fenix::tags {
68 DETECT_FAILURES_TAG = 1000,
74static_assert(FENIX_TAG_MAX < (1 << 15));
78namespace fenix::mpixx {
80inline std::string mpi_error_string(
int errcode) {
82 ret.resize(MPI_MAX_ERROR_STRING + 1);
84 MPI_Error_string(errcode, &ret[0], &len);
89inline int comm_size(MPI_Comm c) {
91 MPI_Comm_size(c, &ret);
95inline int comm_rank(MPI_Comm c) {
97 MPI_Comm_rank(c, &ret);
101static inline int type_size(MPI_Datatype d) {
102 if (d == MPI_DATATYPE_NULL)
return 0;
104 MPI_Type_size(d, &size);
108static inline bool mpi_finalized() noexcept {
110 MPI_Finalized(&flag);
114static inline bool mpi_initialized() noexcept {
116 MPI_Initialized(&flag);
120static inline bool mpi_active() noexcept {
121 return mpi_initialized() && !mpi_finalized();
127 static_assert(std::is_trivially_copyable_v<T>);
133#define MPI_TASK_TYPE(u, r, ...) \
134 if constexpr (std::is_same_v<u, __VA_ARGS__>) return r;
138MPI_Datatype datatype() {
139 using U = std::remove_cv_t<std::remove_pointer_t<std::decay_t<T>>>;
140 static_assert(std::is_trivially_copyable_v<U>);
142 MPI_TASK_TYPE(U, MPI_CHAR,
char);
143 MPI_TASK_TYPE(U, MPI_FLOAT,
float);
144 MPI_TASK_TYPE(U, MPI_DOUBLE,
double);
145 MPI_TASK_TYPE(U, MPI_SHORT,
short);
146 MPI_TASK_TYPE(U, MPI_UNSIGNED_SHORT,
unsigned short);
147 MPI_TASK_TYPE(U, MPI_INT,
int);
148 MPI_TASK_TYPE(U, MPI_UNSIGNED,
unsigned int);
149 MPI_TASK_TYPE(U, MPI_LONG,
long);
150 MPI_TASK_TYPE(U, MPI_UNSIGNED_LONG,
unsigned long);
151 MPI_TASK_TYPE(U, MPI_LOGICAL,
bool);
169MPI_Datatype datatype(T&& t) {
170 return datatype<T>();
174constexpr int datatype_count(T&& t,
int in_count) {
175 if (datatype<T>() == MPI_BYTE) {
176 return in_count *
sizeof(std::remove_pointer_t<std::decay_t<T>>);