diff --git a/libs/full/collectives/CMakeLists.txt b/libs/full/collectives/CMakeLists.txt index b2a95b67c932..0c5910f9043d 100644 --- a/libs/full/collectives/CMakeLists.txt +++ b/libs/full/collectives/CMakeLists.txt @@ -54,14 +54,23 @@ set(collectives_compat_headers # Default location is $HPX_ROOT/libs/collectives/src set(collectives_sources + all_gather.cpp + all_reduce.cpp + all_to_all.cpp barrier.cpp + broadcast.cpp create_communication_set.cpp channel_communicator.cpp create_communicator.cpp - latch.cpp detail/barrier_node.cpp detail/channel_communicator_server.cpp detail/communication_set_node.cpp + exclusive_scan.cpp + gather.cpp + inclusive_scan.cpp + latch.cpp + reduce.cpp + scatter.cpp ) include(HPX_AddModule) diff --git a/libs/full/collectives/include/hpx/collectives/all_gather.hpp b/libs/full/collectives/include/hpx/collectives/all_gather.hpp index 59c3aa2bf7b0..0e83de83217f 100644 --- a/libs/full/collectives/include/hpx/collectives/all_gather.hpp +++ b/libs/full/collectives/include/hpx/collectives/all_gather.hpp @@ -130,13 +130,19 @@ namespace hpx { namespace collectives { namespace hpx::traits { namespace communication { + struct all_gather_tag; template <> - constexpr char const* communicator_name() noexcept + struct communicator_data { - return "all_gather"; - } + static constexpr char const* name() noexcept + { + return "all_gather"; + } + + HPX_EXPORT static operation_id_type id() noexcept; + }; } // namespace communication /////////////////////////////////////////////////////////////////////////// @@ -149,8 +155,8 @@ namespace hpx::traits { std::size_t generation, T&& t) { return communicator.template handle_data>( - communication::communicator_name< - communication::all_gather_tag>(), + communication::communicator_data< + communication::all_gather_tag>::id(), which, generation, // step function (invoked for each get) [&t](auto& data, std::size_t which) { diff --git a/libs/full/collectives/include/hpx/collectives/all_reduce.hpp b/libs/full/collectives/include/hpx/collectives/all_reduce.hpp index cb659bd2006b..43bdc4ce0d01 100644 --- a/libs/full/collectives/include/hpx/collectives/all_reduce.hpp +++ b/libs/full/collectives/include/hpx/collectives/all_reduce.hpp @@ -140,10 +140,15 @@ namespace hpx::traits { struct all_reduce_tag; template <> - constexpr char const* communicator_name() noexcept + struct communicator_data { - return "all_reduce"; - } + static constexpr char const* name() noexcept + { + return "all_reduce"; + } + + HPX_EXPORT static operation_id_type id() noexcept; + }; } // namespace communication /////////////////////////////////////////////////////////////////////////// @@ -156,8 +161,8 @@ namespace hpx::traits { std::size_t generation, T&& t, F&& op) { return communicator.template handle_data>( - communication::communicator_name< - communication::all_reduce_tag>(), + communication::communicator_data< + communication::all_reduce_tag>::id(), which, generation, // step function (invoked for each get) [&t](auto& data, std::size_t which) { diff --git a/libs/full/collectives/include/hpx/collectives/all_to_all.hpp b/libs/full/collectives/include/hpx/collectives/all_to_all.hpp index 3f7467939e1b..055f326e7be3 100644 --- a/libs/full/collectives/include/hpx/collectives/all_to_all.hpp +++ b/libs/full/collectives/include/hpx/collectives/all_to_all.hpp @@ -135,10 +135,15 @@ namespace hpx::traits { struct all_to_all_tag; template <> - constexpr char const* communicator_name() noexcept + struct communicator_data { - return "all_to_all"; - } + static constexpr char const* name() noexcept + { + return "all_to_all"; + } + + HPX_EXPORT static operation_id_type id() noexcept; + }; } // namespace communication /////////////////////////////////////////////////////////////////////////// @@ -151,8 +156,8 @@ namespace hpx::traits { std::size_t generation, std::vector&& t) { return communicator.template handle_data>( - communication::communicator_name< - communication::all_to_all_tag>(), + communication::communicator_data< + communication::all_to_all_tag>::id(), which, generation, // step function (invoked for each get) [&t](auto& data, std::size_t which) { diff --git a/libs/full/collectives/include/hpx/collectives/broadcast.hpp b/libs/full/collectives/include/hpx/collectives/broadcast.hpp index b424b6ddfaa1..b70fa309ca28 100644 --- a/libs/full/collectives/include/hpx/collectives/broadcast.hpp +++ b/libs/full/collectives/include/hpx/collectives/broadcast.hpp @@ -217,10 +217,15 @@ namespace hpx::traits { struct broadcast_tag; template <> - constexpr char const* communicator_name() noexcept + struct communicator_data { - return "broadcast"; - } + static constexpr char const* name() noexcept + { + return "broadcast"; + } + + HPX_EXPORT static operation_id_type id() noexcept; + }; } // namespace communication template @@ -233,8 +238,8 @@ namespace hpx::traits { using data_type = typename Result::result_type; return communicator.template handle_data( - communication::communicator_name< - communication::broadcast_tag>(), + communication::communicator_data< + communication::broadcast_tag>::id(), which, generation, // no step function nullptr, @@ -251,8 +256,8 @@ namespace hpx::traits { std::size_t generation, T&& t) { return communicator.template handle_data>( - communication::communicator_name< - communication::broadcast_tag>(), + communication::communicator_data< + communication::broadcast_tag>::id(), which, generation, // step function (invoked once for set) [&t](auto& data, std::size_t) { data[0] = HPX_FORWARD(T, t); }, diff --git a/libs/full/collectives/include/hpx/collectives/detail/communicator.hpp b/libs/full/collectives/include/hpx/collectives/detail/communicator.hpp index 28d85536bc42..ec21d34f192f 100644 --- a/libs/full/collectives/include/hpx/collectives/detail/communicator.hpp +++ b/libs/full/collectives/include/hpx/collectives/detail/communicator.hpp @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -35,12 +34,22 @@ namespace hpx::traits { namespace communication { + using operation_id_type = void const*; + // Retrieve name of the current communicator template - constexpr char const* communicator_name() noexcept + struct communicator_data { - return ""; - } + static constexpr char const* name() noexcept + { + return ""; + } + + static constexpr operation_id_type id() noexcept + { + return nullptr; + } + }; } // namespace communication } // namespace hpx::traits @@ -70,7 +79,8 @@ namespace hpx::collectives::detail { { LHPX_(info, " [COL] ") .format("{}(>>> {}): which({}), generation({})", op, - traits::communication::communicator_name(), + traits::communication::communicator_data< + Operation>::name(), which, generation); } @@ -78,7 +88,8 @@ namespace hpx::collectives::detail { { LHPX_(info, " [COL] ") .format("{}(<<< {}): which({}), generation({})", op_, - traits::communication::communicator_name(), + traits::communication::communicator_data< + Operation>::name(), which_, generation_); } @@ -259,9 +270,10 @@ namespace hpx::collectives::detail { // // Finalizer will be invoked under lock after all sites have checked in. template - auto handle_data(char const* operation, std::size_t which, - std::size_t generation, [[maybe_unused]] Step&& step, - Finalizer&& finalizer, + auto handle_data( + hpx::traits::communication::operation_id_type operation, + std::size_t which, std::size_t generation, + [[maybe_unused]] Step&& step, Finalizer&& finalizer, std::size_t num_values = static_cast(-1)) { auto on_ready = [this, operation, which, num_values, @@ -281,7 +293,7 @@ namespace hpx::collectives::detail { // Verify that there is no overlap between different types of // operations on the same communicator. if (current_operation_ == nullptr || - std::strcmp(current_operation_, operation) != 0) + current_operation_ != operation) { l.unlock(); HPX_THROW_EXCEPTION(hpx::error::invalid_status, @@ -345,7 +357,7 @@ namespace hpx::collectives::detail { } current_operation_ = operation; } - else if (std::strcmp(current_operation_, operation) != 0) + else if (current_operation_ != operation) { l.unlock(); HPX_THROW_EXCEPTION(hpx::error::invalid_status, @@ -423,7 +435,8 @@ namespace hpx::collectives::detail { hpx::lcos::local::and_gate gate_; std::size_t const num_sites_; std::size_t on_ready_count_ = 0; - char const* current_operation_ = nullptr; + hpx::traits::communication::operation_id_type current_operation_ = + nullptr; bool needs_initialization_ = true; bool data_available_ = false; }; diff --git a/libs/full/collectives/include/hpx/collectives/exclusive_scan.hpp b/libs/full/collectives/include/hpx/collectives/exclusive_scan.hpp index 121bd9e7983c..f1b593f2045c 100644 --- a/libs/full/collectives/include/hpx/collectives/exclusive_scan.hpp +++ b/libs/full/collectives/include/hpx/collectives/exclusive_scan.hpp @@ -152,10 +152,15 @@ namespace hpx::traits { struct exclusive_scan_tag; template <> - constexpr char const* communicator_name() noexcept + struct communicator_data { - return "exclusive_scan"; - } + static constexpr char const* name() noexcept + { + return "exclusive_scan"; + } + + HPX_EXPORT static operation_id_type id() noexcept; + }; } // namespace communication /////////////////////////////////////////////////////////////////////////// @@ -169,8 +174,8 @@ namespace hpx::traits { std::size_t generation, T&& t, F&& op) { return communicator.template handle_data>( - communication::communicator_name< - communication::exclusive_scan_tag>(), + communication::communicator_data< + communication::exclusive_scan_tag>::id(), which, generation, // step function (invoked for each get) [&t](auto& data, std::size_t which) { diff --git a/libs/full/collectives/include/hpx/collectives/gather.hpp b/libs/full/collectives/include/hpx/collectives/gather.hpp index ac85cea4e128..76a7f3acbf9f 100644 --- a/libs/full/collectives/include/hpx/collectives/gather.hpp +++ b/libs/full/collectives/include/hpx/collectives/gather.hpp @@ -236,10 +236,15 @@ namespace hpx::traits { struct gather_tag; template <> - constexpr char const* communicator_name() noexcept + struct communicator_data { - return "gather"; - } + static constexpr char const* name() noexcept + { + return "gather"; + } + + HPX_EXPORT static operation_id_type id() noexcept; + }; } // namespace communication template @@ -250,7 +255,8 @@ namespace hpx::traits { std::size_t generation, T&& t) { return communicator.template handle_data>( - communication::communicator_name(), + communication::communicator_data< + communication::gather_tag>::id(), which, generation, // step function (invoked once for get) [&t](auto& data, std::size_t which) { @@ -265,7 +271,8 @@ namespace hpx::traits { std::size_t generation, T&& t) { return communicator.template handle_data>( - communication::communicator_name(), + communication::communicator_data< + communication::gather_tag>::id(), which, generation, // step function (invoked for each set) [&t](auto& data, std::size_t which) { diff --git a/libs/full/collectives/include/hpx/collectives/inclusive_scan.hpp b/libs/full/collectives/include/hpx/collectives/inclusive_scan.hpp index df3c5ce7ec87..e7387cc1299d 100644 --- a/libs/full/collectives/include/hpx/collectives/inclusive_scan.hpp +++ b/libs/full/collectives/include/hpx/collectives/inclusive_scan.hpp @@ -140,10 +140,15 @@ namespace hpx::traits { struct inclusive_scan_tag; template <> - constexpr char const* communicator_name() noexcept + struct communicator_data { - return "inclusive_scan"; - } + static constexpr char const* name() noexcept + { + return "inclusive_scan"; + } + + HPX_EXPORT static operation_id_type id() noexcept; + }; } // namespace communication /////////////////////////////////////////////////////////////////////////// @@ -157,8 +162,8 @@ namespace hpx::traits { std::size_t generation, T&& t, F&& op) { return communicator.template handle_data>( - communication::communicator_name< - communication::inclusive_scan_tag>(), + communication::communicator_data< + communication::inclusive_scan_tag>::id(), which, generation, // step function (invoked for each get) [&t](auto& data, std::size_t which) { diff --git a/libs/full/collectives/include/hpx/collectives/reduce.hpp b/libs/full/collectives/include/hpx/collectives/reduce.hpp index a0a28b8eb8d6..bf1684f31361 100644 --- a/libs/full/collectives/include/hpx/collectives/reduce.hpp +++ b/libs/full/collectives/include/hpx/collectives/reduce.hpp @@ -237,10 +237,15 @@ namespace hpx::traits { struct reduce_tag; template <> - constexpr char const* communicator_name() noexcept + struct communicator_data { - return "reduce"; - } + static constexpr char const* name() noexcept + { + return "reduce"; + } + + HPX_EXPORT static operation_id_type id() noexcept; + }; } // namespace communication /////////////////////////////////////////////////////////////////////////// @@ -253,7 +258,8 @@ namespace hpx::traits { std::size_t generation, T&& t, F&& op) { return communicator.template handle_data>( - communication::communicator_name(), + communication::communicator_data< + communication::reduce_tag>::id(), which, generation, // step function (invoked once for get) [&t](auto& data, std::size_t which) { @@ -280,7 +286,8 @@ namespace hpx::traits { std::size_t generation, T&& t) { return communicator.template handle_data>( - communication::communicator_name(), + communication::communicator_data< + communication::reduce_tag>::id(), which, generation, // step function (invoked for each set) [t = HPX_FORWARD(T, t)](auto& data, std::size_t which) mutable { diff --git a/libs/full/collectives/include/hpx/collectives/scatter.hpp b/libs/full/collectives/include/hpx/collectives/scatter.hpp index e8d3985105b9..fb2ed7609678 100644 --- a/libs/full/collectives/include/hpx/collectives/scatter.hpp +++ b/libs/full/collectives/include/hpx/collectives/scatter.hpp @@ -229,10 +229,15 @@ namespace hpx::traits { struct scatter_tag; template <> - constexpr char const* communicator_name() noexcept + struct communicator_data { - return "scatter"; - } + static constexpr char const* name() noexcept + { + return "scatter"; + } + + HPX_EXPORT static operation_id_type id() noexcept; + }; } // namespace communication template @@ -245,7 +250,8 @@ namespace hpx::traits { using data_type = typename Result::result_type; return communicator.template handle_data( - communication::communicator_name(), + communication::communicator_data< + communication::scatter_tag>::id(), which, generation, // step function (invoked once for get) nullptr, @@ -261,7 +267,8 @@ namespace hpx::traits { std::size_t generation, std::vector&& t) { return communicator.template handle_data( - communication::communicator_name(), + communication::communicator_data< + communication::scatter_tag>::id(), which, generation, // step function (invoked once for set) [&t](auto& data, std::size_t) { data = HPX_MOVE(t); }, diff --git a/libs/full/collectives/src/all_gather.cpp b/libs/full/collectives/src/all_gather.cpp new file mode 100644 index 000000000000..cdcf847e29a4 --- /dev/null +++ b/libs/full/collectives/src/all_gather.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Hartmut Kaiser +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +#if !defined(HPX_COMPUTE_DEVICE_CODE) + +#include + +#include + +namespace hpx::traits::communication { + + // This is explicitly instantiated to ensure that the id is stable across + // shared libraries. + operation_id_type communicator_data::id() noexcept + { + static std::uint8_t id = 0; + return &id; + } +} // namespace hpx::traits::communication + +#endif diff --git a/libs/full/collectives/src/all_reduce.cpp b/libs/full/collectives/src/all_reduce.cpp new file mode 100644 index 000000000000..8847c05f6532 --- /dev/null +++ b/libs/full/collectives/src/all_reduce.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Hartmut Kaiser +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +#if !defined(HPX_COMPUTE_DEVICE_CODE) + +#include + +#include + +namespace hpx::traits::communication { + + // This is explicitly instantiated to ensure that the id is stable across + // shared libraries. + operation_id_type communicator_data::id() noexcept + { + static std::uint8_t id = 0; + return &id; + } +} // namespace hpx::traits::communication + +#endif diff --git a/libs/full/collectives/src/all_to_all.cpp b/libs/full/collectives/src/all_to_all.cpp new file mode 100644 index 000000000000..482b968a98e3 --- /dev/null +++ b/libs/full/collectives/src/all_to_all.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Hartmut Kaiser +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +#if !defined(HPX_COMPUTE_DEVICE_CODE) + +#include + +#include + +namespace hpx::traits::communication { + + // This is explicitly instantiated to ensure that the id is stable across + // shared libraries. + operation_id_type communicator_data::id() noexcept + { + static std::uint8_t id = 0; + return &id; + } +} // namespace hpx::traits::communication + +#endif diff --git a/libs/full/collectives/src/broadcast.cpp b/libs/full/collectives/src/broadcast.cpp new file mode 100644 index 000000000000..87ddffa8b85f --- /dev/null +++ b/libs/full/collectives/src/broadcast.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Hartmut Kaiser +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +#if !defined(HPX_COMPUTE_DEVICE_CODE) + +#include + +#include + +namespace hpx::traits::communication { + + // This is explicitly instantiated to ensure that the id is stable across + // shared libraries. + operation_id_type communicator_data::id() noexcept + { + static std::uint8_t id = 0; + return &id; + } +} // namespace hpx::traits::communication + +#endif diff --git a/libs/full/collectives/src/exclusive_scan.cpp b/libs/full/collectives/src/exclusive_scan.cpp new file mode 100644 index 000000000000..8a8d43864bfc --- /dev/null +++ b/libs/full/collectives/src/exclusive_scan.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Hartmut Kaiser +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +#if !defined(HPX_COMPUTE_DEVICE_CODE) + +#include + +#include + +namespace hpx::traits::communication { + + // This is explicitly instantiated to ensure that the id is stable across + // shared libraries. + operation_id_type communicator_data::id() noexcept + { + static std::uint8_t id = 0; + return &id; + } +} // namespace hpx::traits::communication + +#endif diff --git a/libs/full/collectives/src/gather.cpp b/libs/full/collectives/src/gather.cpp new file mode 100644 index 000000000000..badfd86c0beb --- /dev/null +++ b/libs/full/collectives/src/gather.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Hartmut Kaiser +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +#if !defined(HPX_COMPUTE_DEVICE_CODE) + +#include + +#include + +namespace hpx::traits::communication { + + // This is explicitly instantiated to ensure that the id is stable across + // shared libraries. + operation_id_type communicator_data::id() noexcept + { + static std::uint8_t id = 0; + return &id; + } +} // namespace hpx::traits::communication + +#endif diff --git a/libs/full/collectives/src/inclusive_scan.cpp b/libs/full/collectives/src/inclusive_scan.cpp new file mode 100644 index 000000000000..b75e77e3b9c8 --- /dev/null +++ b/libs/full/collectives/src/inclusive_scan.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Hartmut Kaiser +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +#if !defined(HPX_COMPUTE_DEVICE_CODE) + +#include + +#include + +namespace hpx::traits::communication { + + // This is explicitly instantiated to ensure that the id is stable across + // shared libraries. + operation_id_type communicator_data::id() noexcept + { + static std::uint8_t id = 0; + return &id; + } +} // namespace hpx::traits::communication + +#endif diff --git a/libs/full/collectives/src/reduce.cpp b/libs/full/collectives/src/reduce.cpp new file mode 100644 index 000000000000..444ca2a2d965 --- /dev/null +++ b/libs/full/collectives/src/reduce.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Hartmut Kaiser +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +#if !defined(HPX_COMPUTE_DEVICE_CODE) + +#include + +#include + +namespace hpx::traits::communication { + + // This is explicitly instantiated to ensure that the id is stable across + // shared libraries. + operation_id_type communicator_data::id() noexcept + { + static std::uint8_t id = 0; + return &id; + } +} // namespace hpx::traits::communication + +#endif diff --git a/libs/full/collectives/src/scatter.cpp b/libs/full/collectives/src/scatter.cpp new file mode 100644 index 000000000000..4c7c9c78991c --- /dev/null +++ b/libs/full/collectives/src/scatter.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2024 Hartmut Kaiser +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#include + +#if !defined(HPX_COMPUTE_DEVICE_CODE) + +#include + +#include + +namespace hpx::traits::communication { + + // This is explicitly instantiated to ensure that the id is stable across + // shared libraries. + operation_id_type communicator_data::id() noexcept + { + static std::uint8_t id = 0; + return &id; + } +} // namespace hpx::traits::communication + +#endif