Skip to content

Commit 686a2d7

Browse files
niklas-uhlmschimek
andauthored
Add named parameters send_tag and recv_tag. (#762)
* Add named parameters `send_tag` and `recv_tag`. These are required for implementing `sendrecv`. * Add test for `send_tag` and `recv_tag`. * Update include/kamping/named_parameters.hpp --------- Co-authored-by: Matthias Schimek <matthias.schimek@kit.edu>
1 parent dc69ae1 commit 686a2d7

File tree

4 files changed

+177
-10
lines changed

4 files changed

+177
-10
lines changed

include/kamping/named_parameter_types.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ enum class ParameterType {
6060
request, ///< Tag used to represent an \c MPI_Request.
6161
root, ///< Tag used to represent the root PE in a \c MPI collectives call.
6262
tag, ///< Tag used to represent the message tag in a \c MPI call.
63+
send_tag, ///< Tag used to represent the message send tag in a \c MPI call.
64+
recv_tag, ///< Tag used to represent the message recv tag in a \c MPI call.
6365
send_mode, ///< Tag used to represent the send mode used by a send operation.
6466
values_on_rank_0, ///< Tag used to represent the value of the exclusive scan
6567
///< operation on rank 0.

include/kamping/named_parameters.hpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,7 @@ inline auto tag(int value) {
10761076
return internal::TagParam<internal::TagType::value>{value};
10771077
}
10781078

1079-
/// @brief Converts the passed enum \p value to its integer representaiton and passes this value to the underlying call.
1079+
/// @brief Converts the passed enum \p value to its integer representation and passes this value to the underlying call.
10801080
///
10811081
/// @param value The tag value.
10821082
/// @return The corresponding parameter object.
@@ -1090,6 +1090,68 @@ inline auto tag(EnumType value) {
10901090
return tag(static_cast<int>(value));
10911091
}
10921092

1093+
/// @brief Indicates to use \c MPI_ANY_TAG as send tag in the underlying call.
1094+
///
1095+
/// @return The corresponding parameter object.
1096+
/// @see \ref docs/parameter_handling.md for general information about parameter handling in KaMPIng.
1097+
inline auto send_tag(internal::any_tag_t) {
1098+
return internal::TagParam<internal::TagType::any, internal::ParameterType::send_tag>{};
1099+
}
1100+
1101+
/// @brief Passes \p value as send tag to the underlying call.
1102+
///
1103+
/// @param value The tag value.
1104+
/// @return The corresponding parameter object.
1105+
/// @see \ref docs/parameter_handling.md for general information about parameter handling in KaMPIng.
1106+
inline auto send_tag(int value) {
1107+
return internal::TagParam<internal::TagType::value, internal::ParameterType::send_tag>{value};
1108+
}
1109+
1110+
/// @brief Converts the passed enum \p value to its integer representation and passes this value to the underlying call.
1111+
///
1112+
/// @param value The send tag value.
1113+
/// @return The corresponding parameter object.
1114+
/// @see \ref docs/parameter_handling.md for general information about parameter handling in KaMPIng.
1115+
template <typename EnumType, typename = std::enable_if_t<std::is_enum_v<EnumType>>>
1116+
inline auto send_tag(EnumType value) {
1117+
static_assert(
1118+
std::is_convertible_v<std::underlying_type_t<EnumType>, int>,
1119+
"The underlying enum type must be implicitly convertible to int."
1120+
);
1121+
return send_tag(static_cast<int>(value));
1122+
}
1123+
1124+
/// @brief Indicates to use \c MPI_ANY_TAG as recv tag in the underlying call.
1125+
///
1126+
/// @return The corresponding parameter object.
1127+
/// @see \ref docs/parameter_handling.md for general information about parameter handling in KaMPIng.
1128+
inline auto recv_tag(internal::any_tag_t) {
1129+
return internal::TagParam<internal::TagType::any, internal::ParameterType::recv_tag>{};
1130+
}
1131+
1132+
/// @brief Passes \p value as recv tag to the underlying call.
1133+
///
1134+
/// @param value The tag value.
1135+
/// @return The corresponding parameter object.
1136+
/// @see \ref docs/parameter_handling.md for general information about parameter handling in KaMPIng.
1137+
inline auto recv_tag(int value) {
1138+
return internal::TagParam<internal::TagType::value, internal::ParameterType::recv_tag>{value};
1139+
}
1140+
1141+
/// @brief Converts the passed enum \p value to its integer representation and passes this value to the underlying call.
1142+
///
1143+
/// @param value The recv tag value.
1144+
/// @return The corresponding parameter object.
1145+
/// @see \ref docs/parameter_handling.md for general information about parameter handling in KaMPIng.
1146+
template <typename EnumType, typename = std::enable_if_t<std::is_enum_v<EnumType>>>
1147+
inline auto recv_tag(EnumType value) {
1148+
static_assert(
1149+
std::is_convertible_v<std::underlying_type_t<EnumType>, int>,
1150+
"The underlying enum type must be implicitly convertible to int."
1151+
);
1152+
return recv_tag(static_cast<int>(value));
1153+
}
1154+
10931155
/// @brief Passes a request handle to the underlying MPI call.
10941156
/// @param request The request handle.
10951157
/// @return The corresponding parameter object.

include/kamping/parameter_objects.hpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -509,17 +509,18 @@ enum class TagType {
509509

510510
/// @brief Encapsulates a message tag.
511511
/// @tparam The type of the tag.
512-
template <TagType tag_type>
512+
/// @tparam The parameter type associated with the tag parameter object. Defaults to \ref ParameterType::tag.
513+
template <TagType tag_type, ParameterType parameter_type = ParameterType::tag>
513514
class TagParam {};
514515

515516
/// @brief Encapsulates a message tag. Specialization if an explicit tag value is provided.
516-
template <>
517-
class TagParam<TagType::value> : private CopyMoveEnabler<> {
517+
template <ParameterType parameter_type_>
518+
class TagParam<TagType::value, parameter_type_> : private CopyMoveEnabler<> {
518519
public:
519520
/// @param tag The tag.
520521
TagParam(int tag) : _tag_value(tag) {}
521-
static constexpr ParameterType parameter_type = ParameterType::tag; ///< The parameter type.
522-
static constexpr TagType tag_type = TagType::value; ///< The tag type.
522+
static constexpr ParameterType parameter_type = parameter_type_; ///< The parameter type.
523+
static constexpr TagType tag_type = TagType::value; ///< The tag type.
523524
/// @return The tag.
524525
[[nodiscard]] int tag() const {
525526
return _tag_value;
@@ -537,11 +538,11 @@ class TagParam<TagType::value> : private CopyMoveEnabler<> {
537538
};
538539

539540
/// @brief Encapsulates a message tag. Specialization if the value is MPI_ANY_TAG.
540-
template <>
541-
class TagParam<TagType::any> : private CopyMoveEnabler<> {
541+
template <ParameterType parameter_type_>
542+
class TagParam<TagType::any, parameter_type_> : private CopyMoveEnabler<> {
542543
public:
543-
static constexpr ParameterType parameter_type = ParameterType::tag; ///< The parameter type.
544-
static constexpr TagType tag_type = TagType::any; ///< The tag type.
544+
static constexpr ParameterType parameter_type = parameter_type_; ///< The parameter type.
545+
static constexpr TagType tag_type = TagType::any; ///< The tag type.
545546
/// @return The tag.
546547
[[nodiscard]] int tag() const {
547548
return MPI_ANY_TAG;

tests/named_parameters_test.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,108 @@ TEST(ParameterFactoriesTest, tag_enum_class) {
12031203
}
12041204
}
12051205

1206+
TEST(ParameterFactoriesTest, send_tag_basics) {
1207+
{
1208+
auto tag_obj = send_tag(22);
1209+
EXPECT_EQ(tag_obj.tag(), 22);
1210+
EXPECT_EQ(decltype(tag_obj)::parameter_type, ParameterType::send_tag);
1211+
EXPECT_EQ(decltype(tag_obj)::tag_type, TagType::value);
1212+
}
1213+
{
1214+
auto tag_obj = send_tag(tags::any);
1215+
EXPECT_EQ(tag_obj.tag(), MPI_ANY_TAG);
1216+
EXPECT_EQ(decltype(tag_obj)::tag_type, TagType::any);
1217+
}
1218+
}
1219+
1220+
TEST(ParameterFactoriesTest, send_tag_enum) {
1221+
enum Tags : int {
1222+
type_a = 27,
1223+
type_b = 3,
1224+
};
1225+
{
1226+
auto tag_obj = send_tag(Tags::type_a);
1227+
EXPECT_EQ(tag_obj.tag(), 27);
1228+
EXPECT_EQ(decltype(tag_obj)::parameter_type, ParameterType::send_tag);
1229+
EXPECT_EQ(decltype(tag_obj)::tag_type, TagType::value);
1230+
}
1231+
{
1232+
auto tag_obj = send_tag(Tags::type_b);
1233+
EXPECT_EQ(tag_obj.tag(), 3);
1234+
EXPECT_EQ(decltype(tag_obj)::parameter_type, ParameterType::send_tag);
1235+
EXPECT_EQ(decltype(tag_obj)::tag_type, TagType::value);
1236+
}
1237+
}
1238+
1239+
TEST(ParameterFactoriesTest, send_tag_enum_class) {
1240+
enum class Tags {
1241+
type_a = 27,
1242+
type_b = 3,
1243+
};
1244+
{
1245+
auto tag_obj = send_tag(Tags::type_a);
1246+
EXPECT_EQ(tag_obj.tag(), 27);
1247+
EXPECT_EQ(decltype(tag_obj)::tag_type, TagType::value);
1248+
}
1249+
{
1250+
auto tag_obj = send_tag(Tags::type_b);
1251+
EXPECT_EQ(tag_obj.tag(), 3);
1252+
EXPECT_EQ(decltype(tag_obj)::parameter_type, ParameterType::send_tag);
1253+
EXPECT_EQ(decltype(tag_obj)::tag_type, TagType::value);
1254+
}
1255+
}
1256+
1257+
TEST(ParameterFactoriesTest, recv_tag_basics) {
1258+
{
1259+
auto tag_obj = recv_tag(22);
1260+
EXPECT_EQ(tag_obj.tag(), 22);
1261+
EXPECT_EQ(decltype(tag_obj)::parameter_type, ParameterType::recv_tag);
1262+
EXPECT_EQ(decltype(tag_obj)::tag_type, TagType::value);
1263+
}
1264+
{
1265+
auto tag_obj = recv_tag(tags::any);
1266+
EXPECT_EQ(tag_obj.tag(), MPI_ANY_TAG);
1267+
EXPECT_EQ(decltype(tag_obj)::tag_type, TagType::any);
1268+
}
1269+
}
1270+
1271+
TEST(ParameterFactoriesTest, recv_tag_enum) {
1272+
enum Tags : int {
1273+
type_a = 27,
1274+
type_b = 3,
1275+
};
1276+
{
1277+
auto tag_obj = recv_tag(Tags::type_a);
1278+
EXPECT_EQ(tag_obj.tag(), 27);
1279+
EXPECT_EQ(decltype(tag_obj)::parameter_type, ParameterType::recv_tag);
1280+
EXPECT_EQ(decltype(tag_obj)::tag_type, TagType::value);
1281+
}
1282+
{
1283+
auto tag_obj = recv_tag(Tags::type_b);
1284+
EXPECT_EQ(tag_obj.tag(), 3);
1285+
EXPECT_EQ(decltype(tag_obj)::parameter_type, ParameterType::recv_tag);
1286+
EXPECT_EQ(decltype(tag_obj)::tag_type, TagType::value);
1287+
}
1288+
}
1289+
1290+
TEST(ParameterFactoriesTest, recv_tag_enum_class) {
1291+
enum class Tags {
1292+
type_a = 27,
1293+
type_b = 3,
1294+
};
1295+
{
1296+
auto tag_obj = recv_tag(Tags::type_a);
1297+
EXPECT_EQ(tag_obj.tag(), 27);
1298+
EXPECT_EQ(decltype(tag_obj)::tag_type, TagType::value);
1299+
}
1300+
{
1301+
auto tag_obj = recv_tag(Tags::type_b);
1302+
EXPECT_EQ(tag_obj.tag(), 3);
1303+
EXPECT_EQ(decltype(tag_obj)::parameter_type, ParameterType::recv_tag);
1304+
EXPECT_EQ(decltype(tag_obj)::tag_type, TagType::value);
1305+
}
1306+
}
1307+
12061308
TEST(ParameterFactoriesTest, status_basics) {
12071309
{
12081310
auto status_obj = status(kamping::ignore<>).construct_buffer_or_rebind();

0 commit comments

Comments
 (0)