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/// @brief Maps a C++ type \p T to a type trait for constructing an MPI_Datatype.
42///
43/// Extends \ref kamping::types::type_dispatcher() with:
44/// - All trivially copyable types not otherwise handled → `types::byte_serialized`.
45///
46/// @returns The corresponding type trait for the type \p T.
47template <typename T>
49 using T_no_const = std::remove_const_t<T>;
50 if constexpr (types::has_auto_dispatched_type_v<T>) {
51 return types::type_dispatcher<T>();
52 } else if constexpr (std::is_trivially_copyable_v<T_no_const>) {
54 } else {
56 }
57}
58
59/// @brief Whether the type is handled by the auto-dispatcher \ref type_dispatcher,
60/// i.e. whether \ref mpi_type_traits is defined without a user-provided specialization.
61template <typename T>
62static constexpr bool has_auto_dispatched_type_v =
63 !std::is_same_v<decltype(type_dispatcher<T>()), internal::no_matching_type>;
64
65/// @brief The type trait that maps a C++ type \p T to an MPI_Datatype for full KaMPIng.
66///
67/// The default behavior is controlled by \ref type_dispatcher. Specialize this trait in
68/// `namespace kamping` to support additional types. Specializations of
69/// \ref kamping::types::mpi_type_traits are intentionally ignored here.
70template <typename T, typename Enable = void>
72
73/// @brief Partial specialization of \ref mpi_type_traits for types handled by \ref type_dispatcher.
74template <typename T>
75struct mpi_type_traits<T, std::enable_if_t<has_auto_dispatched_type_v<T>>> {
76 /// @brief The base type of this trait obtained via \ref type_dispatcher.
77 using base = decltype(type_dispatcher<T>());
78 /// @brief The category of the type.
79 static constexpr types::TypeCategory category = base::category;
80 /// @brief Whether the type has to be committed before it can be used in MPI calls.
81 static constexpr bool has_to_be_committed = types::category_has_to_be_committed(category);
82 /// @brief The MPI_Datatype corresponding to the type T.
84 return decltype(type_dispatcher<T>())::data_type();
85 }
86};
87
88/// @brief Check if the type has a static type definition, i.e. \ref kamping::mpi_type_traits is defined.
89template <typename, typename Enable = void>
90struct has_static_type : std::false_type {};
91
92/// @brief Check if the type has a static type definition, i.e. \ref kamping::mpi_type_traits is defined.
93template <typename T>
94struct has_static_type<T, std::void_t<decltype(mpi_type_traits<T>::data_type())>> : std::true_type {};
95
96/// @brief `true` if \ref kamping::mpi_type_traits provides a `data_type()` function.
97template <typename T>
99
100/// @brief Register a new \c MPI_Datatype for \p T with the MPI environment. It will be freed when the environment is
101/// finalized.
102///
103/// The \c MPI_Datatype is created using \c mpi_type_traits<T>::data_type() and committed using \c MPI_Type_commit.
104///
105/// @tparam T The type to register.
106template <typename T>
109 MPI_Type_commit(&type);
111 mpi_env.register_mpi_type(type);
112 return type;
113}
114
115/// @brief Translate type \p T to an MPI_Datatype using the type defined via \ref mpi_type_traits.
116///
117/// If the type has not been registered with MPI yet, it will be created and committed and automatically registered with
118/// the MPI environment, such that it will be freed when the environment is finalized.
119///
120/// @tparam T The type to translate into an MPI_Datatype.
121template <typename T>
123 static_assert(
125 "\n --> Type not supported directly by KaMPIng. Please provide a specialization for mpi_type_traits."
126 );
128 // using static initialization to ensure that the type is only committed once
130 return type;
131 } else {
133 }
134}
135
136/// @brief Lookup policy for KaMPIng that resolves MPI_Datatypes via \ref kamping::mpi_type_traits.
137///
138/// Unlike the module-level \ref kamping::types::type_dispatcher_lookup, this policy also covers
139/// trivially-copyable types not matched by \ref kamping::types::type_dispatcher() (i.e., those
140/// handled via `types::byte_serialized`).
142 /// @brief `true` if KaMPIng can resolve an MPI_Datatype for \p T.
143 template <typename T>
144 static constexpr bool has_type_v = has_static_type_v<T>;
145
146 /// @brief Returns the MPI_Datatype for \p T.
147 template <typename T>
148 static MPI_Datatype get() {
150 }
151};
152
153// Backward-compatible aliases for types moved to kamping::types::
154using types::builtin_type;
155using types::byte_serialized;
158using types::kamping_tag;
159using types::ScopedDatatype;
160using types::type_dispatcher_lookup;
162
163/// @brief Constructs a contiguous MPI type of \p N elements of type \p T, using \ref kamping_lookup
164/// to resolve element types (includes the byte-serialization fallback for trivially-copyable types).
165/// @see kamping::types::contiguous_type
166template <typename T, size_t N>
168
169/// @brief Constructs an MPI struct type for \p T, using \ref kamping_lookup to resolve field types
170/// (includes the byte-serialization fallback for trivially-copyable types).
171/// @see kamping::types::struct_type
172template <typename T>
174
175/// @}
176
177} // 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:48
static constexpr bool has_static_type_v
true if kamping::mpi_type_traits provides a data_type() function.
Definition mpi_datatype.hpp:98
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:122
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:62
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:107
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:69
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:90
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:141
static MPI_Datatype get()
Returns the MPI_Datatype for T.
Definition mpi_datatype.hpp:148
static constexpr bool has_type_v
true if KaMPIng can resolve an MPI_Datatype for T.
Definition mpi_datatype.hpp:144
static MPI_Datatype data_type()
The MPI_Datatype corresponding to the type T.
Definition mpi_datatype.hpp:83
The type trait that maps a C++ type T to an MPI_Datatype for full KaMPIng.
Definition mpi_datatype.hpp:71
Constructs a type serialized as a sequence of sizeof(T) bytes using MPI_BYTE.
Definition contiguous_type_fwd.hpp:48
Constructs a contiguous MPI type of N elements of type T using MPI_Type_contiguous.
Definition contiguous_type_fwd.hpp:39
Constructs an MPI_Datatype for a struct-like type.
Definition struct_type.hpp:52
Internal type helpers for the kamping-types module.