KaMPIng 0.1.0
(Near) zero-overhead C++ MPI bindings.
Loading...
Searching...
No Matches
send.hpp
1// This file is part of KaMPIng.
2//
3// Copyright 2022-2024 The KaMPIng Authors
4//
5// KaMPIng is free software : you can redistribute it and/or modify it under the
6// terms of the GNU Lesser General Public License as published by the Free
7// Software Foundation, either version 3 of the License, or (at your option) any
8// later version. KaMPIng is distributed in the hope that it will be useful, but
9// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
11// for more details.
12//
13// You should have received a copy of the GNU Lesser General Public License
14// along with KaMPIng. If not, see <https://www.gnu.org/licenses/>.
15
16#pragma once
17
18#include <type_traits>
19
20#include <kassert/kassert.hpp>
21#include <mpi.h>
22
23#include "kamping/communicator.hpp"
25#include "kamping/implementation_helpers.hpp"
31#include "kamping/p2p/helpers.hpp"
33
34///// @addtogroup kamping_p2p
35/// @{
36
37// @brief Wrapper for \c MPI_Send.
38///
39/// This wraps \c MPI_Send. This operation sends the elements in the input buffer provided via \c
40/// kamping::send_buf() to the specified receiver rank using standard send mode.
41/// The following parameters are required:
42/// - \ref kamping::send_buf() containing the data that is sent.
43///
44/// - \ref kamping::send_count() specifying how many elements of the buffer are sent. If omitted, the size of the send
45/// buffer is used as a default. This parameter is mandatory if \ref kamping::send_type() is given.
46///
47// - \ref kamping::send_type() specifying the \c MPI datatype to use as send type. If omitted, the \c MPI datatype is
48/// derived automatically based on send_buf's underlying \c value_type.
49///
50/// - \ref kamping::destination() the receiving rank.
51///
52/// The following parameters are optional:
53/// - \ref kamping::tag() the tag added to the message. Defaults to the communicator's default tag (\ref
54/// Communicator::default_tag()) if not present.
55///
56/// @tparam Args Automatically deduced template parameters.
57/// @param args All required and any number of the optional parameters described above.
58///
59/// @see \ref docs/parameter_handling.md for general information about parameter handling in KaMPIng.
60/// <hr>
61/// \include{doc} docs/resize_policy.dox
62template <
63 template <typename...>
64 typename DefaultContainerType,
65 template <typename, template <typename...> typename>
66 typename... Plugins>
67template <typename... Args>
69 using namespace kamping::internal;
71 Args,
74 );
75
76 auto&& send_buf = internal::select_parameter_type<internal::ParameterType::send_buf>(args...)
79 if constexpr (is_serialization_used) {
82 send_buf.underlying().serialize();
83 }
84 using send_value_type = typename std::remove_reference_t<decltype(send_buf)>::value_type;
85
86 auto&& send_type = internal::determine_mpi_send_datatype<send_value_type>(args...);
87
89 auto&& send_count =
90 internal::select_parameter_type_or_default<internal::ParameterType::send_count, default_send_count_type>(
91 {},
92 args...
93 )
94 .construct_buffer_or_rebind();
95 if constexpr (has_to_be_computed<decltype(send_count)>) {
96 send_count.underlying() = asserting_cast<int>(send_buf.size());
97 }
98
99 auto const& destination = internal::select_parameter_type<internal::ParameterType::destination>(args...);
100 constexpr auto rank_type = std::remove_reference_t<decltype(destination)>::rank_type;
101 static_assert(
102 rank_type == RankType::value || rank_type == RankType::null,
103 "Please provide an explicit destination or destination(ranks::null)."
104 );
105
106 using default_tag_buf_type = decltype(kamping::tag(this->default_tag()));
107
108 auto&& tag_param = internal::select_parameter_type_or_default<internal::ParameterType::tag, default_tag_buf_type>(
109 std::tuple(this->default_tag()),
110 args...
111 );
112
113 // this ensures that the user does not try to pass MPI_ANY_TAG, which is not allowed for sends
114 static_assert(
115 std::remove_reference_t<decltype(tag_param)>::tag_type == TagType::value,
116 "Please provide a tag for the message."
117 );
118 int tag = tag_param.tag();
119 KASSERT(
121 "invalid tag " << tag << ", must be in range [0, " << Environment<>::tag_upper_bound() << "]"
122 );
123
127 using send_mode = typename std::remove_reference_t<send_mode_obj_type>::send_mode;
128
129 // RankType::null is valid, RankType::any is not.
130 KASSERT(is_valid_rank_in_comm(destination, *this, true, false), "Invalid destination rank.");
131
132 if constexpr (std::is_same_v<send_mode, internal::standard_mode_t>) {
133 [[maybe_unused]] int err = MPI_Send(
134 send_buf.data(), // send_buf
135 send_count.get_single_element(), // send_count
136 send_type.get_single_element(), // send_type
137 destination.rank_signed(), // destination
138 tag, // tag
139 this->mpi_communicator()
140 );
141 this->mpi_error_hook(err, "MPI_Send");
142 } else if constexpr (std::is_same_v<send_mode, internal::buffered_mode_t>) {
143 [[maybe_unused]] int err = MPI_Bsend(
144 send_buf.data(), // send_buf
145 send_count.get_single_element(), // send_count
146 send_type.get_single_element(), // send_type
147 destination.rank_signed(), // destination
148 tag, // tag
149 this->mpi_communicator()
150 );
151 this->mpi_error_hook(err, "MPI_Bsend");
152 } else if constexpr (std::is_same_v<send_mode, internal::synchronous_mode_t>) {
153 [[maybe_unused]] int err = MPI_Ssend(
154 send_buf.data(), // send_buf
155 send_count.get_single_element(), // send_count
156 send_type.get_single_element(), // send_type
157 destination.rank_signed(), // destination
158 tag, // tag
159 this->mpi_communicator()
160 );
161 this->mpi_error_hook(err, "MPI_Ssend");
162 } else if constexpr (std::is_same_v<send_mode, internal::ready_mode_t>) {
163 [[maybe_unused]] int err = MPI_Rsend(
164 send_buf.data(), // send_buf
165 send_count.get_single_element(), // send_count
166 send_type.get_single_element(), // send_type
167 destination.rank_signed(), // destination
168 tag, // tag
169 this->mpi_communicator()
170 );
171 this->mpi_error_hook(err, "MPI_Rsend");
172 }
173}
174
175/// @brief Convenience wrapper for MPI_Bsend. Calls \ref kamping::Communicator::send() with the appropriate send mode
176/// set.
177template <
178 template <typename...>
179 typename DefaultContainerType,
180 template <typename, template <typename...> typename>
181 typename... Plugins>
182template <typename... Args>
184 this->send(std::forward<Args>(args)..., send_mode(send_modes::buffered));
185}
186
187/// @brief Convenience wrapper for MPI_Ssend. Calls \ref kamping::Communicator::send() with the appropriate send mode
188/// set.
189template <
190 template <typename...>
191 typename DefaultContainerType,
192 template <typename, template <typename...> typename>
193 typename... Plugins>
194template <typename... Args>
196 this->send(std::forward<Args>(args)..., send_mode(send_modes::synchronous));
197}
198
199/// @brief Convenience wrapper for MPI_Rsend. Calls \ref kamping::Communicator::send() with the appropriate send mode
200/// set.
201template <
202 template <typename...>
203 typename DefaultContainerType,
204 template <typename, template <typename...> typename>
205 typename... Plugins>
206template <typename... Args>
208 this->send(std::forward<Args>(args)..., send_mode(send_modes::ready));
209}
210/// @}
Wrapper for MPI functions that don't require a communicator. If the template parameter init_finalize_...
Definition environment.hpp:52
STL-compatible allocator for requesting memory using the builtin MPI allocator.
Definition allocator.hpp:32
T value_type
The value type.
Definition allocator.hpp:53
auto tag(internal::any_tag_t)
Indicates to use MPI_ANY_TAG as tag in the underlying call.
Definition named_parameters.hpp:1064
auto destination(int rank)
Passes rank as destination rank to the underlying call. This parameter is needed in point-to-point ex...
Definition named_parameters.hpp:999
auto send_mode(SendModeTag)
Passes the send mode parameter for point to point communication to the underlying call....
Definition named_parameters.hpp:1137
auto send_count(int count)
Passes count as send count to the underlying call.
Definition named_parameters.hpp:321
auto send_type(MPI_Datatype send_type)
Passes send_type as send type to the underlying call.
Definition named_parameters.hpp:1195
auto send_buf(internal::ignore_t< Data > ignore)
Generates a dummy send buf that wraps a nullptr.
Definition named_parameters.hpp:51
auto send_count_out()
Indicates to deduce the send count and return it to the caller as part of the underlying call's resul...
Definition named_parameters.hpp:347
void bsend(Args... args) const
Convenience wrapper for MPI_Bsend. Calls kamping::Communicator::send() with the appropriate send mode...
Definition send.hpp:183
void send(Args... args) const
Definition send.hpp:68
void rsend(Args... args) const
Convenience wrapper for MPI_Rsend. Calls kamping::Communicator::send() with the appropriate send mode...
Definition send.hpp:207
void ssend(Args... args) const
Convenience wrapper for MPI_Ssend. Calls kamping::Communicator::send() with the appropriate send mode...
Definition send.hpp:195
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
@ send_mode
Tag used to represent the send mode used by a send operation.
Utility that maps C++ types to types that can be understood by MPI.
Template magic to check named parameters passed to wrappers at compile time.
#define KAMPING_REQUIRED_PARAMETERS(...)
Wrapper to pass (possibly empty) list of parameter type names as required parameters to KAMPING_CHECK...
Definition named_parameter_check.hpp:52
#define KAMPING_OPTIONAL_PARAMETERS(...)
Wrapper to pass (possibly empty) list of parameter type names as optional parameters to KAMPING_CHECK...
Definition named_parameter_check.hpp:58
#define KAMPING_CHECK_PARAMETERS(args, required, optional)
Assertion macro that checks if passed parameters are correct, i.e., all parameter types are unique,...
Definition named_parameter_check.hpp:80
Template magic to implement named parameters in cpp.
File containing the parameter types used by the KaMPIng library.
Factory methods for buffer wrappers.
Internal namespace marking the code that is not user-facing.
Definition collectives_helpers.hpp:20
static constexpr bool buffer_uses_serialization
Checks if DataBufferType is a serialization buffer.
Definition named_parameter_check.hpp:415
Parameter objects return by named parameter factory functions.
Parameter object for send_mode encapsulating the send mode compile-time tag.
Definition parameter_objects.hpp:478