diff --git a/docs/sphinx/api/public_distributed_api.rst b/docs/sphinx/api/public_distributed_api.rst index f614189ca927..aa217800be67 100644 --- a/docs/sphinx/api/public_distributed_api.rst +++ b/docs/sphinx/api/public_distributed_api.rst @@ -63,7 +63,7 @@ Classes .. table:: `hpx` classes of header ``hpx/collectives.hpp`` +-----------------------------------------------------+ - | Class | + | Class | +=====================================================+ | :cpp:struct:`hpx::collectives::num_sites_arg` | +-----------------------------------------------------+ @@ -79,12 +79,10 @@ Classes +-----------------------------------------------------+ | :cpp:struct:`hpx::collectives::arity_arg` | +-----------------------------------------------------+ - | :cpp:class:`hpx::collectives::communicator` | + | :cpp:struct:`hpx::collectives::communicator` | +-----------------------------------------------------+ | :cpp:class:`hpx::collectives::channel_communicator` | +-----------------------------------------------------+ - | :cpp:class:`hpx::collectives::communicator` | - +-----------------------------------------------------+ Functions --------- diff --git a/libs/full/collectives/include/hpx/collectives/barrier.hpp b/libs/full/collectives/include/hpx/collectives/barrier.hpp index 564c0644719e..e846f61a7651 100644 --- a/libs/full/collectives/include/hpx/collectives/barrier.hpp +++ b/libs/full/collectives/include/hpx/collectives/barrier.hpp @@ -8,6 +8,85 @@ #pragma once +#if defined(DOXYGEN) +// clang-format off +namespace hpx { namespace distributed { + + /// The barrier is an implementation performing a barrier over a number of + /// participating threads. The different threads don't have to be on the + /// same locality. This barrier can be invoked in a distributed application. + /// + /// For a local only barrier \see hpx::barrier. + class HPX_EXPORT barrier; + + /// Creates a barrier, rank is locality id, size is number of localities + /// + /// \param base_name The name of the barrier + /// + /// A barrier \a base_name is created. It expects that + /// hpx::get_num_localities() participate and the local rank is + /// hpx::get_locality_id(). + explicit barrier(std::string const& base_name); + + /// Creates a barrier with a given size, rank is locality id + /// + /// \param base_name The name of the barrier + /// \param num The number of participating threads + /// + /// A barrier \a base_name is created. It expects that + /// \a num participate and the local rank is hpx::get_locality_id(). + barrier(std::string const& base_name, std::size_t num); + + /// Creates a barrier with a given size and rank + /// + /// \param base_name The name of the barrier + /// \param num The number of participating threads + /// \param rank The rank of the calling site for this invocation + /// + /// A barrier \a base_name is created. It expects that + /// \a num participate and the local rank is \a rank. + barrier( + std::string const& base_name, std::size_t num, std::size_t rank); + + /// Creates a barrier with a vector of ranks + /// + /// \param base_name The name of the barrier + /// \param ranks Gives a list of participating ranks (this could be derived + /// from a list of locality ids + /// \param rank The rank of the calling site for this invocation + /// + /// A barrier \a base_name is created. It expects that ranks.size() + /// and the local rank is \a rank (must be contained in \a ranks). + barrier(std::string const& base_name, + std::vector const& ranks, std::size_t rank); + + /// Wait until each participant entered the barrier. Must be called by + /// all participants + /// + /// \returns This function returns once all participants have entered + /// the barrier (have called \a wait). + void wait() const; + + /// Wait until each participant entered the barrier. Must be called by + /// all participants + /// + /// \returns a future that becomes ready once all participants have + /// entered the barrier (have called \a wait). + hpx::future wait(hpx::launch::async_policy) const; + + /// Perform a global synchronization using the default global barrier + /// The barrier is created once at startup and can be reused throughout + /// the lifetime of an HPX application. + /// + /// \note This function currently does not support dynamic connection + /// and disconnection of localities. + static void synchronize(); + +}} // namespace hpx::distributed + +// clang-format on +#else + #include #include #include @@ -24,90 +103,36 @@ namespace hpx::distributed { - /// \cond NOINTERNAL namespace detail { struct barrier_node; } - /// \endcond - /// The barrier is an implementation performing a barrier over a number of - /// participating threads. The different threads don't have to be on the - /// same locality. This barrier can be invoked in a distributed application. - /// - /// For a local only barrier \see hpx::barrier. class HPX_EXPORT barrier { - /// \cond NOINTERNAL typedef detail::barrier_node wrapped_type; typedef components::managed_component wrapping_type; - /// \endcond public: - /// Creates a barrier, rank is locality id, size is number of localities - /// - /// \param base_name The name of the barrier - /// - /// A barrier \a base_name is created. It expects that - /// hpx::get_num_localities() participate and the local rank is - /// hpx::get_locality_id(). explicit barrier(std::string const& base_name); - /// Creates a barrier with a given size, rank is locality id - /// - /// \param base_name The name of the barrier - /// \param num The number of participating threads - /// - /// A barrier \a base_name is created. It expects that - /// \a num participate and the local rank is hpx::get_locality_id(). barrier(std::string const& base_name, std::size_t num); - /// Creates a barrier with a given size and rank - /// - /// \param base_name The name of the barrier - /// \param num The number of participating threads - /// \param rank The rank of the calling site for this invocation - /// - /// A barrier \a base_name is created. It expects that - /// \a num participate and the local rank is \a rank. barrier( std::string const& base_name, std::size_t num, std::size_t rank); - /// Creates a barrier with a vector of ranks - /// - /// \param base_name The name of the barrier - /// \param ranks Gives a list of participating ranks (this could be derived - /// from a list of locality ids - /// \param rank The rank of the calling site for this invocation - /// - /// A barrier \a base_name is created. It expects that ranks.size() - /// and the local rank is \a rank (must be contained in \a ranks). barrier(std::string const& base_name, std::vector const& ranks, std::size_t rank); - /// \cond NOINTERNAL barrier(barrier&& other) noexcept; barrier& operator=(barrier&& other) noexcept; - /// \cond NOINTERNAL ~barrier(); - /// \endcond - /// Wait until each participant entered the barrier. Must be called by - /// all participants - /// - /// \returns This function returns once all participants have entered - /// the barrier (have called \a wait). void wait() const; - /// Wait until each participant entered the barrier. Must be called by - /// all participants - /// - /// \returns a future that becomes ready once all participants have - /// entered the barrier (have called \a wait). hpx::future wait(hpx::launch::async_policy) const; - /// \cond NOINTERNAL // Resets this barrier instance. void release(); @@ -116,32 +141,23 @@ namespace hpx::distributed { // Get the instance of the global barrier static std::array& get_global_barrier(); static std::array create_global_barrier(); - /// \endcond - - /// Perform a global synchronization using the default global barrier - /// The barrier is created once at startup and can be reused throughout - /// the lifetime of an HPX application. - /// - /// \note This function currently does not support dynamic connection - /// and disconnection of localities. + static void synchronize(); private: - /// \cond NOINTERNAL barrier(); hpx::intrusive_ptr node_; - /// \endcond }; } // namespace hpx::distributed -/// \cond NOINTERNAL namespace hpx::lcos { using barrier HPX_DEPRECATED_V(1, 8, "hpx::lcos::barrier is deprecated, use hpx::distributed::barrier " "instead") = hpx::distributed::barrier; } -/// \endcond #include + +#endif // DOXYGEN diff --git a/libs/full/collectives/include/hpx/collectives/channel_communicator.hpp b/libs/full/collectives/include/hpx/collectives/channel_communicator.hpp index 30381a5c5f47..f1d997a24d1c 100644 --- a/libs/full/collectives/include/hpx/collectives/channel_communicator.hpp +++ b/libs/full/collectives/include/hpx/collectives/channel_communicator.hpp @@ -11,8 +11,14 @@ #include #if defined(DOXYGEN) -// clang-format off + +/// Top level HPX namespace namespace hpx { namespace collectives { + // clang-format off + + /// A handle identifying the communication channel to use for get/set + /// operations + class channel_communicator; /// Create a new communicator object usable with peer-to-peer /// channel-based operations @@ -91,9 +97,8 @@ namespace hpx { namespace collectives { template hpx::future get(channel_communicator comm, that_site_arg site, tag_arg tag = tag_arg()); - -}} -// clang-format on + // clang-format on +}} // namespace hpx::collectives #else @@ -112,13 +117,9 @@ namespace hpx { namespace collectives { #include #include -/////////////////////////////////////////////////////////////////////////////// namespace hpx { namespace collectives { - /////////////////////////////////////////////////////////////////////////// // forward declarations - /// a handle identifying the communication channel to use for get/set - /// operations class channel_communicator; template @@ -129,7 +130,6 @@ namespace hpx { namespace collectives { hpx::future set( channel_communicator, that_site_arg, T&&, tag_arg = tag_arg()); - /////////////////////////////////////////////////////////////////////////// class channel_communicator { private: diff --git a/libs/full/collectives/include/hpx/collectives/communication_set.hpp b/libs/full/collectives/include/hpx/collectives/communication_set.hpp index f3353a08524f..d96a391a2dd1 100644 --- a/libs/full/collectives/include/hpx/collectives/communication_set.hpp +++ b/libs/full/collectives/include/hpx/collectives/communication_set.hpp @@ -4,12 +4,19 @@ // 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) +/// \file communication_setup.hpp + #pragma once #if defined(DOXYGEN) -// clang-format off +/// Top level HPX namespace namespace hpx::collectives { + // clang-format off + + /// A handle identifying the communication channel to use for a particular + /// collective operation + struct communicator; /// The function \a create_communication_set sets up a (distributed) /// tree-like communication structure that can be used with any of the @@ -38,8 +45,8 @@ namespace hpx::collectives { this_site_arg this_site = this_site_arg(), generation_arg generation = generation_arg(), arity_arg arity = arity_arg()); -} -// clang-format on + // clang-format on +} // namespace hpx::collectives #else // DOXYGEN diff --git a/libs/full/collectives/include/hpx/collectives/create_communicator.hpp b/libs/full/collectives/include/hpx/collectives/create_communicator.hpp index 1de3933d768d..79b49b3d117b 100644 --- a/libs/full/collectives/include/hpx/collectives/create_communicator.hpp +++ b/libs/full/collectives/include/hpx/collectives/create_communicator.hpp @@ -114,9 +114,6 @@ struct hpx::util::extra_data_helper namespace hpx::collectives { - /////////////////////////////////////////////////////////////////////////// - /// a handle identifying the communication channel to use for a particular - /// collective operation struct communicator : hpx::components::client_base diff --git a/libs/full/collectives/include/hpx/collectives/latch.hpp b/libs/full/collectives/include/hpx/collectives/latch.hpp index 41f3ff2a1a7d..311aac31e477 100644 --- a/libs/full/collectives/include/hpx/collectives/latch.hpp +++ b/libs/full/collectives/include/hpx/collectives/latch.hpp @@ -4,8 +4,97 @@ // 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) +/// \file hpx/collectives/latch.hpp + #pragma once +#if defined(DOXYGEN) +// clang-format off +namespace hpx { namespace distributed { + + /// Latch is an implementation of a synchronization primitive that allows + /// multiple threads to wait for a shared event to occur before proceeding. + /// This latch can be invoked in a distributed application. + /// + /// For a local only latch \see hpx::latch. + class HPX_EXPORT latch; + + /// Initialize the latch + /// + /// Requires: count >= 0. + /// Synchronization: None + /// Postconditions: counter_ == count. + /// + explicit latch(std::ptrdiff_t count); + + /// Extension: Create a client side representation for the existing + /// \a server#latch instance with the given global id \a id. + latch(hpx::id_type const& id); + + /// Extension: Create a client side representation for the existing + /// \a server#latch instance with the given global id \a id. + latch(hpx::future&& f); + + /// Extension: Create a client side representation for the existing + /// \a server#latch instance with the given global id \a id. + latch(hpx::shared_future const& id); + + /// Decrements counter_ by 1 . Blocks at the synchronization point + /// until counter_ reaches 0. + /// + /// Requires: counter_ > 0. + /// + /// Synchronization: Synchronizes with all calls that block on this + /// latch and with all is_ready calls on this latch that return true. + /// + /// \throws Nothing. + void count_down_and_wait(); + + /// Decrements counter_ by update . Blocks at the synchronization point + /// until counter_ reaches 0. + /// + /// Requires: counter_ > 0. + /// + /// Synchronization: Synchronizes with all calls that block on this + /// latch and with all is_ready calls on this latch that return true. + /// + /// \throws Nothing. + void arrive_and_wait(); + + /// Decrements counter_ by n. Does not block. + /// + /// Requires: counter_ >= n and n >= 0. + /// + /// Synchronization: Synchronizes with all calls that block on this + /// latch and with all is_ready calls on this latch that return true . + /// + /// \throws Nothing. + void count_down(std::ptrdiff_t n); + + /// Returns: counter_ == 0. Does not block. + /// + /// \throws Nothing. + bool is_ready() const noexcept; + + /// Returns: counter_ == 0. Does not block. + /// + /// \throws Nothing. + /// + bool try_wait() const noexcept; + + /// If counter_ is 0, returns immediately. Otherwise, blocks the + /// calling thread at the synchronization point until counter_ + /// reaches 0. + /// + /// \throws Nothing. + /// + void wait() const; + +}} // namespace hpx::distributed + +// clang-format on +#else + #include #include #include @@ -17,9 +106,13 @@ #include -/////////////////////////////////////////////////////////////////////////////// namespace hpx::distributed { + /// Latch is an implementation of a synchronization primitive that allows + /// multiple threads to wait for a shared event to occur before proceeding. + /// This latch can be invoked in a distributed application. + /// + /// For a local only latch \see hpx::latch. class HPX_EXPORT latch : public components::client_base { @@ -72,7 +165,6 @@ namespace hpx::distributed { /// latch and with all is_ready calls on this latch that return true. /// /// \throws Nothing. - /// void count_down_and_wait() { count_down_and_wait_async().get(); @@ -87,7 +179,6 @@ namespace hpx::distributed { /// latch and with all is_ready calls on this latch that return true. /// /// \throws Nothing. - /// void arrive_and_wait() { count_down_and_wait_async().get(); @@ -101,7 +192,6 @@ namespace hpx::distributed { /// latch and with all is_ready calls on this latch that return true . /// /// \throws Nothing. - /// void count_down(std::ptrdiff_t n) { count_down_async(n).get(); @@ -110,7 +200,6 @@ namespace hpx::distributed { /// Returns: counter_ == 0. Does not block. /// /// \throws Nothing. - /// bool is_ready() const noexcept { return is_ready_async().get(); @@ -166,3 +255,5 @@ namespace hpx::lcos { } // namespace hpx::lcos #include + +#endif // DOXYGEN