Fenix @develop
 
Loading...
Searching...
No Matches
util.hpp
1/*
2//@HEADER
3// ************************************************************************
4//
5//
6// _|_|_|_| _|_|_|_| _| _| _|_|_| _| _|
7// _| _| _|_| _| _| _| _|
8// _|_|_| _|_|_| _| _| _| _| _|
9// _| _| _| _|_| _| _| _|
10// _| _|_|_|_| _| _| _|_|_| _| _|
11//
12//
13//
14//
15// Copyright (C) 2016 Rutgers University and Sandia Corporation
16//
17// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
18// the U.S. Government retains certain rights in this software.
19//
20// Redistribution and use in source and binary forms, with or without
21// modification, are permitted provided that the following conditions are
22// met:
23//
24// 1. Redistributions of source code must retain the above copyright
25// notice, this list of conditions and the following disclaimer.
26//
27// 2. Redistributions in binary form must reproduce the above copyright
28// notice, this list of conditions and the following disclaimer in the
29// documentation and/or other materials provided with the distribution.
30//
31// 3. Neither the name of the Corporation nor the names of the
32// contributors may be used to endorse or promote products derived from
33// this software without specific prior written permission.
34//
35// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
36// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
39// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
40// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
41// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
42// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
43// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
44// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46//
47// Author Marc Gamell, Eric Valenzuela, Keita Teranishi, Manish Parashar
48// Michael Heroux, and Matthew Whitlock
49//
50// Questions? Contact Matthew Whitlock (mwhitlo@sandia.gov)
51//
52// ************************************************************************
53//@HEADER
54*/
55
56#ifndef FENIX_MPIXX_UTIL_HPP
57#define FENIX_MPIXX_UTIL_HPP
58
59#include <mpi.h>
60#include <string>
61
62namespace fenix::tags {
63
64// Ensure non-conflicting tags across Fenix.
65// In particular, it is important that no other operations use the
66// DETECT_FAILURES_TAG, to prevent delayed failure detection.
67enum Tag {
68 DETECT_FAILURES_TAG = 1000,
69
70 FENIX_TAG_MAX
71};
72
73// MPI Standard guarantees tags below 2^15 are valid
74static_assert(FENIX_TAG_MAX < (1 << 15));
75
76} // namespace fenix::tags
77
78namespace fenix::mpixx {
79
80inline std::string mpi_error_string(int errcode) {
81 std::string ret;
82 ret.resize(MPI_MAX_ERROR_STRING + 1);
83 int len;
84 MPI_Error_string(errcode, &ret[0], &len);
85 ret.resize(len + 1);
86 return ret;
87}
88
89inline int comm_size(MPI_Comm c) {
90 int ret;
91 MPI_Comm_size(c, &ret);
92 return ret;
93}
94
95inline int comm_rank(MPI_Comm c) {
96 int ret;
97 MPI_Comm_rank(c, &ret);
98 return ret;
99}
100
101static inline int type_size(MPI_Datatype d) {
102 if (d == MPI_DATATYPE_NULL) return 0;
103 int size;
104 MPI_Type_size(d, &size);
105 return size;
106}
107
108static inline bool mpi_finalized() noexcept {
109 int flag;
110 MPI_Finalized(&flag);
111 return flag;
112}
113
114static inline bool mpi_initialized() noexcept {
115 int flag;
116 MPI_Initialized(&flag);
117 return flag;
118}
119
120static inline bool mpi_active() noexcept {
121 return mpi_initialized() && !mpi_finalized();
122}
123
124// C++ type corresponding to MPI_Datatype index pairs
125template <typename T>
126struct Indexed {
127 static_assert(std::is_trivially_copyable_v<T>);
128 T value;
129 int index;
130};
131
132// Internal macro, undefined before end of this file
133#define MPI_TASK_TYPE(u, r, ...) \
134 if constexpr (std::is_same_v<u, __VA_ARGS__>) return r;
135
136// Helpers for getting an MPI_Datatype and count from some number of a c++ type
137template <typename T>
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>);
141 // clang-format off
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);
152 MPI_TASK_TYPE(U, MPI_FLOAT_INT, Indexed<float>);
153 MPI_TASK_TYPE(U, MPI_DOUBLE_INT, Indexed<double>);
154 MPI_TASK_TYPE(U, MPI_LONG_INT, Indexed<long>);
155 MPI_TASK_TYPE(U, MPI_2INT, Indexed<int>);
156 MPI_TASK_TYPE(U, MPI_SHORT_INT, Indexed<short>);
157 MPI_TASK_TYPE(U, MPI_LONG_DOUBLE_INT, Indexed<long double>);
158 // clang-format on
159
160 // Technically sketch to just make this MPI_BYTE, but only when heterogenenous
161 // so we'll cross that bridge when we get there. Convenient for trivial custom
162 // types for now
163 return MPI_BYTE;
164}
165
166#undef MPI_TASK_TYPE
167
168template <typename T>
169MPI_Datatype datatype(T&& t) {
170 return datatype<T>();
171}
172
173template <typename 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>>);
177 }
178 return in_count;
179}
180
181} // namespace fenix::mpixx
182
183#endif // FENIX_MPIXX_UTIL_HPP
Definition util.hpp:126