Fenix @develop
 
Loading...
Searching...
No Matches
mpi_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_MPI_UTIL__
57#define __FENIX_MPI_UTIL__
58
59#include <mpi.h>
60#include <tuple>
61#include <string>
62
63namespace fenix::tags {
64
65// Ensure non-conflicting tags across Fenix.
66// In particular, it is important that no other operations use the
67// DETECT_FAILURES_TAG, to prevent delayed failure detection.
68enum Tag {
69 DETECT_FAILURES_TAG = 1000,
70
71 FENIX_TAG_MAX
72};
73
74// MPI Standard guarantees tags below 2^15 are valid
75static_assert(FENIX_TAG_MAX < 1<<15);
76
77} // namespace fenix::tags
78
79namespace fenix::util {
80
81inline std::string mpi_error_string(int errcode) {
82 std::string ret;
83 ret.resize(MPI_MAX_ERROR_STRING+1);
84 int len;
85 MPI_Error_string(errcode, &ret[0], &len);
86 ret.resize(len+1);
87 return ret;
88}
89
90inline int comm_size(MPI_Comm c) {
91 int ret;
92 MPI_Comm_size(c, &ret);
93 return ret;
94}
95
96inline int comm_rank(MPI_Comm c) {
97 int ret;
98 MPI_Comm_rank(c, &ret);
99 return ret;
100}
101
102static inline int type_size(MPI_Datatype d) {
103 if (d == MPI_DATATYPE_NULL) return 0;
104 int size;
105 MPI_Type_size(d, &size);
106 return size;
107}
108
109static inline bool mpi_finalized() {
110 int flag;
111 MPI_Finalized(&flag);
112 return flag;
113}
114
115class Status {
116 public:
117 int return_value;
118 MPI_Status status;
119
120 Status() = default;
121 Status(int r) : return_value(r) {}
122 auto operator=(int r) {
123 return_value = r;
124 return *this;
125 }
126
127 operator bool() const { return return_value == MPI_SUCCESS; }
128
129 operator int() const { return return_value; }
130 bool operator==(int r) const { return return_value == r; }
131
132 operator MPI_Status() const { return status; }
133 operator MPI_Status*() { return &status; }
134
135 // to support structured unbinding
136 template <size_t I>
137 auto&& get() && {
138 if constexpr (I == 0) return std::move(return_value);
139 if constexpr (I == 1) return std::move(status);
140 }
141};
142
143} // namespace fenix::util
144
145// Supporting structured unbinding for Status
146namespace std {
147template <>
148struct tuple_size<fenix::util::Status> : std::integral_constant<size_t, 2> {};
149
150template <>
151struct tuple_element<0, fenix::util::Status> {
152 using type = int;
153};
154template <>
155struct tuple_element<1, fenix::util::Status> {
156 using type = MPI_Status;
157};
158}
159
160#endif
Definition mpi_util.hpp:115