KaMPIng 0.2.1
(Near) zero-overhead MPI wrapper for C++
Loading...
Searching...
No Matches
mpi_datatype.hpp
Go to the documentation of this file.
1// This file is part of KaMPIng.
2//
3// Copyright 2021-2026 The KaMPIng Authors
4//
5// KaMPIng is free software : you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
7// version. KaMPIng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
8// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
9// for more details.
10//
11// You should have received a copy of the GNU Lesser General Public License along with KaMPIng. If not, see
12// <https://www.gnu.org/licenses/>.
13
14/// @file
15/// @brief Utility that maps C++ types to types that can be understood by MPI.
16
17#pragma once
18
19#include <type_traits>
20
21#include <mpi.h>
22
24#include "kamping/kassert/kassert.hpp"
25#include "kamping/noexcept.hpp"
32
33namespace kamping {
34
35/// @addtogroup kamping_mpi_utility
36/// @{
37
38// Re-export no_matching_type into kamping:: for backward compatibility
39using internal::no_matching_type;
40
41// Forward declaration: fully defined below, after mpi_type_traits.
42struct kamping_lookup;
43
44/// @brief Maps a C++ type \p T to a type trait for constructing an MPI_Datatype.
45///
46/// Extends \ref kamping::types::type_dispatcher() with:
47/// - All trivially copyable types not otherwise handled → `types::byte_serialized`.
48///
49/// \ref kamping_lookup is forwarded into \ref kamping::types::type_dispatcher() so that array and
50/// enum branches resolve element types via the kamping layer (which includes the byte-serialization
51/// fallback for trivially-copyable types).
52///
53/// @returns The corresponding type trait for the type \p T.
54template <typename T>
56 using T_no_const = std::remove_const_t<T>;
57 if constexpr (types::has_auto_dispatched_type_v<T, kamping_lookup>) {
58 return types::type_dispatcher<T, kamping_lookup>();
59 } else if constexpr (std::is_trivially_copyable_v<T_no_const>) {
61 } else {
63 }
64}
65
66/// @brief Whether the type is handled by the auto-dispatcher \ref type_dispatcher,
67/// i.e. whether \ref mpi_type_traits is defined without a user-provided specialization.
68template <typename T>
69static constexpr bool has_auto_dispatched_type_v =
70 !std::is_same_v<decltype(type_dispatcher<T>()), internal::no_matching_type>;
71
72/// @brief The type trait that maps a C++ type \p T to an MPI_Datatype for full KaMPIng.
73///
74/// The default behavior is controlled by \ref type_dispatcher. Specialize this trait in
75/// `namespace kamping` to support additional types. Specializations of
76/// \ref kamping::types::mpi_type_traits are intentionally ignored here.
77template <typename T, typename Enable = void>
79
80/// @brief Partial specialization of \ref mpi_type_traits for types handled by \ref type_dispatcher.
81template <typename T>
82struct mpi_type_traits<T, std::enable_if_t<has_auto_dispatched_type_v<T>>> {
83 /// @brief The base type of this trait obtained via \ref type_dispatcher.
84 using base = decltype(type_dispatcher<T>());
85 /// @brief The category of the type.
86 static constexpr types::TypeCategory category = base::category;
87 /// @brief Whether the type has to be committed before it can be used in MPI calls.
88 static constexpr bool has_to_be_committed = types::category_has_to_be_committed(category);
89 /// @brief The MPI_Datatype corresponding to the type T.
91 return decltype(type_dispatcher<T>())::data_type();
92 }
93};
94
95/// @brief Check if the type has a static type definition, i.e. \ref kamping::mpi_type_traits is defined.
96template <typename, typename Enable = void>
97struct has_static_type : std::false_type {};
98
99/// @brief Check if the type has a static type definition, i.e. \ref kamping::mpi_type_traits is defined.
100template <typename T>
101struct has_static_type<T, std::void_t<decltype(mpi_type_traits<T>::data_type())>> : std::true_type {};
102
103/// @brief `true` if \ref kamping::mpi_type_traits provides a `data_type()` function.
104template <typename T>
106
107/// @brief Register a new \c MPI_Datatype for \p T with the MPI environment. It will be freed when the environment is
108/// finalized.
109///
110/// The \c MPI_Datatype is created using \c mpi_type_traits<T>::data_type() and committed using \c MPI_Type_commit.
111///
112/// @tparam T The type to register.
113template <typename T>
116 MPI_Type_commit(&type);
118 mpi_env.register_mpi_type(type);
119 return type;
120}
121
122/// @brief Translate type \p T to an MPI_Datatype using the type defined via \ref mpi_type_traits.
123///
124/// If the type has not been registered with MPI yet, it will be created and committed and automatically registered with
125/// the MPI environment, such that it will be freed when the environment is finalized.
126///
127/// @tparam T The type to translate into an MPI_Datatype.
128template <typename T>
130 static_assert(
132 "\n --> Type not supported directly by KaMPIng. Please provide a specialization for mpi_type_traits."
133 );
135 // using static initialization to ensure that the type is only committed once
137 return type;
138 } else {
140 }
141}
142
143/// @brief Lookup policy for KaMPIng that resolves MPI_Datatypes via \ref kamping::mpi_type_traits.
144///
145/// Unlike the module-level \ref kamping::types::type_dispatcher_lookup, this policy also covers
146/// trivially-copyable types not matched by \ref kamping::types::type_dispatcher() (i.e., those
147/// handled via `types::byte_serialized`).
149 /// @brief `true` if KaMPIng can resolve an MPI_Datatype for \p T.
150 template <typename T>
151 static constexpr bool has_type_v = has_static_type_v<T>;
152
153 /// @brief Returns the MPI_Datatype for \p T.
154 template <typename T>
155 static MPI_Datatype get() {
157 }
158};
159
160// Backward-compatible aliases for types moved to kamping::types::
161using types::builtin_type;
162using types::byte_serialized;
165using types::kamping_tag;
166using types::ScopedDatatype;
167using types::type_dispatcher_lookup;
169
170/// @brief Constructs a contiguous MPI type of \p N elements of type \p T, using \ref kamping_lookup
171/// to resolve element types (includes the byte-serialization fallback for trivially-copyable types).
172/// @see kamping::types::contiguous_type
173template <typename T, size_t N>
175
176/// @brief Constructs an MPI struct type for \p T, using \ref kamping_lookup to resolve field types
177/// (includes the byte-serialization fallback for trivially-copyable types).
178/// @see kamping::types::struct_type
179template <typename T>
181
182/// @}
183
184} // namespace kamping
STL-compatible allocator for requesting memory using the builtin MPI allocator.
Definition allocator.hpp:32
MPI_Type_contiguous implementation for kamping::types::contiguous_type and kamping::types::byte_seria...
Wrapper for MPI functions that don't require a communicator.
Environment< InitMPIMode::NoInitFinalize > const mpi_env
A global environment object to use when you don't want to create a new Environment object.
Definition environment.hpp:343
auto type_dispatcher()
Maps a C++ type T to a type trait for constructing an MPI_Datatype.
Definition mpi_datatype.hpp:55
static constexpr bool has_static_type_v
true if kamping::mpi_type_traits provides a data_type() function.
Definition mpi_datatype.hpp:105
MPI_Datatype mpi_datatype() KAMPING_NOEXCEPT
Translate type T to an MPI_Datatype using the type defined via mpi_type_traits.
Definition mpi_datatype.hpp:129
static constexpr bool has_auto_dispatched_type_v
Whether the type is handled by the auto-dispatcher type_dispatcher, i.e. whether mpi_type_traits is d...
Definition mpi_datatype.hpp:69
MPI_Datatype construct_and_commit_type()
Register a new MPI_Datatype for T with the MPI environment. It will be freed when the environment is ...
Definition mpi_datatype.hpp:114
TypeCategory
Type groups as defined in Section 6.9.2 of the MPI 4.0 standard.
Definition builtin_types.hpp:32
constexpr bool is_builtin_type_v
Helper variable template for builtin_type.
Definition builtin_types.hpp:70
constexpr bool category_has_to_be_committed(TypeCategory category)
Returns whether an MPI_Datatype of the given category must be committed before use.
Definition builtin_types.hpp:35
Mapping of C++ datatypes to builtin MPI types.
Type traits and dispatcher for mapping C++ types to MPI datatypes.
STL namespace.
Defines the macro KAMPING_NOEXCEPT to be used instad of noexcept.
#define KAMPING_NOEXCEPT
noexcept macro.
Definition noexcept.hpp:19
RAII wrapper that commits an MPI_Datatype on construction and frees it on destruction.
Struct-like MPI type construction via field reflection.
Check if the type has a static type definition, i.e. kamping::mpi_type_traits is defined.
Definition mpi_datatype.hpp:97
Type tag for indicating that no static type definition exists for a type.
Definition type_helpers.hpp:52
Lookup policy for KaMPIng that resolves MPI_Datatypes via kamping::mpi_type_traits.
Definition mpi_datatype.hpp:148
static MPI_Datatype get()
Returns the MPI_Datatype for T.
Definition mpi_datatype.hpp:155
static constexpr bool has_type_v
true if KaMPIng can resolve an MPI_Datatype for T.
Definition mpi_datatype.hpp:151
static MPI_Datatype data_type()
The MPI_Datatype corresponding to the type T.
Definition mpi_datatype.hpp:90
The type trait that maps a C++ type T to an MPI_Datatype for full KaMPIng.
Definition mpi_datatype.hpp:78
Constructs a type serialized as a sequence of sizeof(T) bytes using MPI_BYTE.
Definition contiguous_type_fwd.hpp:49
Constructs a contiguous MPI type of N elements of type T using MPI_Type_contiguous.
Definition contiguous_type_fwd.hpp:40
Constructs an MPI_Datatype for a struct-like type.
Definition struct_type.hpp:52
Internal type helpers for the kamping-types module.