KaMPIng 0.1.0
(Near) zero-overhead C++ MPI bindings.
Loading...
Searching...
No Matches
helpers.hpp
1// This file is part of KaMPIng.
2//
3// Copyright 2023 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#pragma once
15
18
19namespace kamping::internal {
20/// @brief Deduce the MPI_Datatype to use as send_type in a p2p send operation.If \ref kamping::send_type() is given,
21/// the \c MPI_Datatype wrapped inside will be used as send_type. Otherwise, the \c MPI_datatype is derived
22/// automatically based on send_buf's underlying \c value_type.
23///
24/// @tparam send_value_type Value type of the send buffer.
25/// @tparam Args Types of all arguments passed to the wrapped MPI call.
26/// @param args All arguments passed to a wrapped MPI call.
27/// @return Return the \c MPI send_type wrapped in a DataBuffer. This is either an lvalue reference to the
28/// send_type DataBuffer if the send_type is provided by the user or a newly created send_type DataBuffer
29/// otherwise.
30template <typename send_value_type, typename... Args>
34 decltype(kamping::send_type_out())>(std::make_tuple(), args...)
35 .construct_buffer_or_rebind()) {
36 // Some assertions:
37 // If a send_type is given, the send_count information has to be provided, too.
39 if constexpr (is_send_type_given_as_in_param) {
41 static_assert(
43 "If a custom send type is provided, the send count has to be provided, too."
44 );
45 }
46 // Get the send type
48
49 // decltype(auto) becomes an lvalue reference type if the initializer is an lvalue and a non-reference type if the
50 // the initializer is a pr-value (e.g. a function call returning by value). These are the only two value categories
51 // we accept for the return value of select_parameter_type_or_default.
52 decltype(auto) mpi_send_type =
53 internal::select_parameter_type_or_default<internal::ParameterType::send_type, default_mpi_send_type>(
54 std::make_tuple(),
55 args...
56 )
57 .construct_buffer_or_rebind();
58
59 // assure that our expectation about the return value value category (lvalue or pr-value) is true. This ensures
60 // that the return value of the function does not become a dangling rvalue reference bound to a function-local
61 // object.
62 static_assert(
63 !std::is_rvalue_reference_v<decltype(mpi_send_type)>,
64 "mpi_send_type is either a lvalue reference (in this case it returned by reference), or a non-reference type "
65 "(in "
66 "this case it is returned by value)."
67 );
68
69 if constexpr (!is_send_type_given_as_in_param) {
71 }
72
73 return mpi_send_type;
74}
75
76/// @brief Deduce the MPI_Datatype to use as recv_type in a p2p recv operation.If \ref kamping::recv_type() is given,
77/// the \c MPI_Datatype wrapped inside will be used as recv_type. Otherwise, the \c MPI_datatype is derived
78/// automatically based on recv_buf's underlying \c value_type.
79///
80/// @tparam recv_value_type Value type of the recv buffer.
81/// @tparam recv_buf Type of the recv buffer.
82/// @tparam Args Types of all arguments passed to the wrapped MPI call.
83/// @param args All arguments passed to a wrapped MPI call.
84/// @return Return the \c MPI recv_type wrapped in a DataBuffer. This is either an lvalue reference to the
85/// recv_type DataBuffer if the recv_type is provided by the user or a newly created recv_type DataBuffer
86/// otherwise.
87template <typename recv_value_type, typename recv_buf, typename... Args>
91 decltype(kamping::recv_type_out())>(std::make_tuple(), args...)
92 .construct_buffer_or_rebind()) {
93 // Get the recv type
95
96 // decltype(auto) becomes an lvalue reference type if the initializer is an lvalue and a non-reference type if the
97 // the initializer is a pr-value (e.g. a function call returning by value). These are the only two value categories
98 // we accept for the return value of select_parameter_type_or_default.
99 decltype(auto) mpi_recv_type =
100 internal::select_parameter_type_or_default<internal::ParameterType::recv_type, default_mpi_recv_type>(
101 std::make_tuple(),
102 args...
103 )
104 .construct_buffer_or_rebind();
105
106 // assure that our expectation about the return value value category (lvalue or pr-value) is true. This ensures
107 // that the return value of the function does not become a dangling rvalue reference bound to a function-local
108 // object.
109 static_assert(
110 !std::is_rvalue_reference_v<decltype(mpi_recv_type)>,
111 "mpi_recv_type is either a lvalue reference (in this case it returned by reference), or a non-reference type "
112 "(in "
113 "this case it is returned by value)."
114 );
115
117 // Recv buffer resize policy assertion
118 constexpr bool do_not_resize_recv_buf = std::remove_reference_t<recv_buf>::resize_policy == no_resize;
119 static_assert(
121 "If a custom recv type is given, kamping is not able to deduce the correct size of the "
122 "recv buffer. "
123 "Therefore, a sufficiently large recv buffer (with resize policy \"no_resize\") must be provided by "
124 "the user."
125 );
126
127 if constexpr (!is_recv_type_given_as_in_param) {
129 }
130
131 return mpi_recv_type;
132}
133} // namespace kamping::internal
STL-compatible allocator for requesting memory using the builtin MPI allocator.
Definition allocator.hpp:32
constexpr BufferResizePolicy no_resize
Definition data_buffer.hpp:270
auto recv_type_out()
Indicates to deduce the receive type in the underlying call and return it as part of underlying call'...
Definition named_parameters.hpp:1252
auto send_type_out()
Indicates to deduce the send type in the underlying call and return it as part of underlying call's r...
Definition named_parameters.hpp:1209
decltype(auto) select_parameter_type_or_default(std::tuple< DefaultArguments... > default_arguments, Args &... args)
Checks if parameter with requested parameter type exists, if not constructs a default value.
Definition named_parameter_selection.hpp:239
@ recv_type
Tag used to represent a recv type in an MPI call.
@ send_type
Tag used to represent a send type in an MPI call.
@ send_count
Tag used to represent the number of elements to be sent.
Template magic to check named parameters passed to wrappers at compile time.
Factory methods for buffer wrappers.
Internal namespace marking the code that is not user-facing.
Definition collectives_helpers.hpp:20
static constexpr bool is_parameter_given_as_in_buffer
Checks if a data buffer with requested parameter type exists and it is an input parameter (i....
Definition named_parameter_check.hpp:384
constexpr auto determine_mpi_recv_datatype(Args &... args) -> decltype(internal::select_parameter_type_or_default< internal::ParameterType::recv_type, decltype(kamping::recv_type_out())>(std::make_tuple(), args...) .construct_buffer_or_rebind())
Deduce the MPI_Datatype to use as recv_type in a p2p recv operation.If kamping::recv_type() is given,...
Definition helpers.hpp:88
constexpr auto determine_mpi_send_datatype(Args &... args) -> decltype(internal::select_parameter_type_or_default< internal::ParameterType::send_type, decltype(kamping::send_type_out())>(std::make_tuple(), args...) .construct_buffer_or_rebind())
Deduce the MPI_Datatype to use as send_type in a p2p send operation.If kamping::send_type() is given,...
Definition helpers.hpp:31