KaMPIng 0.2.1
(Near) zero-overhead MPI wrapper for C++
Loading...
Searching...
No Matches
mpi_type_traits.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 Type traits and dispatcher for mapping C++ types to MPI datatypes.
16
17#pragma once
18#include <type_traits>
19
23
24namespace kamping::types {
25
26/// @addtogroup kamping_types
27/// @{
28
29/// @brief Maps a C++ type \p T to a type trait for constructing an MPI_Datatype.
30///
31/// | C++ type | Result |
32/// |----------|--------|
33/// | MPI builtin (`int`, `double`, …, `kabool`) | `builtin_type<T>` |
34/// | Enum | dispatches to `type_dispatcher<underlying_type, Lookup>()` |
35/// | `T[N]`, `std::array<T, N>` | `contiguous_type<T, N, Lookup>` |
36/// | Everything else | `internal::no_matching_type` |
37///
38/// Specialize \ref kamping::types::mpi_type_traits to handle additional types.
39///
40/// @tparam T The C++ type to map.
41/// @tparam Lookup The lookup policy used to resolve element types inside array and enum branches.
42/// Defaults to \ref type_dispatcher_lookup (module-level resolution via
43/// \ref kamping::types::mpi_type_traits). Upper-level frameworks (e.g., full KaMPIng) pass
44/// \ref kamping::kamping_lookup so that array element types benefit from the byte-serialization
45/// fallback.
46/// @returns The corresponding type trait for the type \p T.
47template <typename T, typename Lookup = type_dispatcher_lookup>
49 using T_no_const = std::remove_const_t<T>;
50
51 static_assert(
52 !std::is_pointer_v<T_no_const>,
53 "MPI does not support pointer types. Why do you want to transfer a pointer over MPI?"
54 );
55 static_assert(!std::is_function_v<T_no_const>, "MPI does not support function types.");
56 static_assert(!std::is_union_v<T_no_const>, "MPI does not support union types.");
57 static_assert(!std::is_void_v<T_no_const>, "There is no MPI datatype corresponding to void.");
58
59 if constexpr (is_builtin_type_v<T_no_const>) {
61 } else if constexpr (std::is_enum_v<T_no_const>) {
63 } else if constexpr (std::is_array_v<T_no_const>) {
64 return contiguous_type<std::remove_extent_t<T_no_const>, std::extent_v<T_no_const>, Lookup>{};
66 return contiguous_type<
69 Lookup>{};
70 } else {
72 }
73}
74
75/// @brief Whether the type is handled by the auto-dispatcher \ref kamping::types::type_dispatcher().
76/// @tparam T The C++ type to check.
77/// @tparam Lookup The lookup policy forwarded to \ref kamping::types::type_dispatcher(). Defaults to
78/// \ref type_dispatcher_lookup so all existing call sites are unaffected.
79template <typename T, typename Lookup = type_dispatcher_lookup>
80static constexpr bool has_auto_dispatched_type_v =
81 !std::is_same_v<decltype(type_dispatcher<T, Lookup>()), kamping::internal::no_matching_type>;
82
83/// @brief The type trait that maps a C++ type \p T to an MPI_Datatype for the kamping-types module.
84///
85/// The default behavior is controlled by \ref kamping::types::type_dispatcher(). Specialize this
86/// trait to support additional types within the module.
87/// Upper-level frameworks (e.g., full KaMPIng) define their own extension point on top.
88template <typename T, typename Enable = void>
90
91/// @brief Partial specialization of \ref kamping::types::mpi_type_traits for types matched by
92/// \ref kamping::types::type_dispatcher().
93template <typename T>
94struct mpi_type_traits<T, std::enable_if_t<has_auto_dispatched_type_v<T>>> {
95 /// @brief The base type of this trait obtained via \ref kamping::types::type_dispatcher().
96 using base = decltype(type_dispatcher<T>());
97 /// @brief The category of the type.
98 static constexpr TypeCategory category = base::category;
99 /// @brief Whether the type has to be committed before it can be used in MPI calls.
100 static constexpr bool has_to_be_committed = category_has_to_be_committed(category);
101 /// @brief The MPI_Datatype corresponding to the type T.
103 return decltype(type_dispatcher<T>())::data_type();
104 }
105};
106
107/// @brief Check if the type has a static type definition, i.e. \ref kamping::types::mpi_type_traits is defined.
108template <typename, typename Enable = void>
109struct has_static_type : std::false_type {};
110
111/// @brief Check if the type has a static type definition, i.e. \ref kamping::types::mpi_type_traits is defined.
112template <typename T>
113struct has_static_type<T, std::void_t<decltype(mpi_type_traits<T>::data_type())>> : std::true_type {};
114
115/// @brief `true` if \ref kamping::types::mpi_type_traits provides a `data_type()` function.
116template <typename T>
118
119/// @brief Default lookup policy for \ref contiguous_type and \ref struct_type.
120///
121/// Resolves the MPI_Datatype for a type \p T by consulting \ref kamping::types::mpi_type_traits.
122/// Users of the kamping-types module can extend the supported types by specializing
123/// \ref kamping::types::mpi_type_traits. Upper-level frameworks may supply an alternative Lookup
124/// policy (e.g., to add a byte-serialization fallback).
126 /// @brief `true` if the Lookup can resolve an MPI_Datatype for \p T.
127 template <typename T>
128 static constexpr bool has_type_v = has_static_type_v<T>;
129
130 /// @brief Returns the MPI_Datatype for \p T.
131 template <typename T>
132 static MPI_Datatype get() {
134 }
135};
136
137/// @}
138
139} // namespace kamping::types
STL-compatible allocator for requesting memory using the builtin MPI allocator.
Definition allocator.hpp:32
Forward declarations for contiguous_type and byte_serialized to break include cycles.
static constexpr bool has_auto_dispatched_type_v
Whether the type is handled by the auto-dispatcher kamping::types::type_dispatcher().
Definition mpi_type_traits.hpp:80
TypeCategory
Type groups as defined in Section 6.9.2 of the MPI 4.0 standard.
Definition builtin_types.hpp:32
static constexpr bool has_static_type_v
true if kamping::types::mpi_type_traits provides a data_type() function.
Definition mpi_type_traits.hpp:117
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
auto type_dispatcher()
Maps a C++ type T to a type trait for constructing an MPI_Datatype.
Definition mpi_type_traits.hpp:48
Mapping of C++ datatypes to builtin MPI types.
STL namespace.
Helper to check if a type is a std::array.
Definition type_helpers.hpp:42
Type tag for indicating that no static type definition exists for a type.
Definition type_helpers.hpp:52
Constructs a contiguous MPI type of N elements of type T using MPI_Type_contiguous.
Definition contiguous_type_fwd.hpp:39
Check if the type has a static type definition, i.e. kamping::types::mpi_type_traits is defined.
Definition mpi_type_traits.hpp:109
static MPI_Datatype data_type()
The MPI_Datatype corresponding to the type T.
Definition mpi_type_traits.hpp:102
The type trait that maps a C++ type T to an MPI_Datatype for the kamping-types module.
Definition mpi_type_traits.hpp:89
Default lookup policy for contiguous_type and struct_type.
Definition mpi_type_traits.hpp:125
static constexpr bool has_type_v
true if the Lookup can resolve an MPI_Datatype for T.
Definition mpi_type_traits.hpp:128
static MPI_Datatype get()
Returns the MPI_Datatype for T.
Definition mpi_type_traits.hpp:132
Internal type helpers for the kamping-types module.