From 691ad8fcfd10c7c03c272897ff3f309abadf3043 Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Tue, 9 Mar 2021 16:34:31 +0100 Subject: [PATCH] Document direct communications, deprecate Host::sendto() because Comm::sendto() is better for that --- docs/source/app_s4u.rst | 32 +++++++++++++++++-- include/simgrid/s4u/Comm.hpp | 15 +++++++-- include/simgrid/s4u/Host.hpp | 24 +++----------- src/plugins/file_system/s4u_FileSystem.cpp | 7 ++-- src/s4u/s4u_Comm.cpp | 5 +++ src/s4u/s4u_Host.cpp | 13 +++++--- .../testing_comm_direct.cpp | 18 +++++------ 7 files changed, 75 insertions(+), 39 deletions(-) diff --git a/docs/source/app_s4u.rst b/docs/source/app_s4u.rst index f43e02d5ed..635016bdf5 100644 --- a/docs/source/app_s4u.rst +++ b/docs/source/app_s4u.rst @@ -334,6 +334,26 @@ that are marked as permanent receiver, you should call memory gets properly reclaimed. This call should be at the end of the actor's function, not in an on_exit callback. +=============================== +Communicating without Mailboxes +=============================== + +Sometimes you don't want to simulate communications between actors as +allowed by mailboxes, but you want to create a direct communication +between two arbitrary hosts. This can arise when you write a +high-level model of a centralized scheduler, or when you model direct +communications such as one-sided communications in MPI or remote +memory direct access in PGAS. + +For that, :cpp:func:`Comm::sendto() ` +simulates a direct communication between the two specified hosts. No +mailbox is used, and there is no rendezvous between actors. You can +freely mix such direct communications and rendezvous-based +communications. Alternatively, :cpp:func:`Comm::sendto_init() +` and +:cpp:func:`Comm::sendto_async() ` +create asynchronous direct communications. + .. _s4u_raii: Memory Management @@ -1300,6 +1320,9 @@ Execution Platform and routing -------------------- +You can also start direct communications between two arbitrary hosts +using :cpp:func:`Comm::sendto() `. + .. tabs:: .. group-tab:: C++ @@ -1308,8 +1331,6 @@ Platform and routing .. doxygenfunction:: simgrid::s4u::Host::get_netpoint() const .. doxygenfunction:: simgrid::s4u::Host::route_to(const Host *dest, std::vector< Link * > &links, double *latency) const .. doxygenfunction:: simgrid::s4u::Host::route_to(const Host *dest, std::vector< kernel::resource::LinkImpl * > &links, double *latency) const - .. doxygenfunction:: simgrid::s4u::Host::sendto(Host *dest, double byte_amount) - .. doxygenfunction:: simgrid::s4u::Host::sendto_async(Host *dest, double byte_amount) .. group-tab:: C @@ -1851,10 +1872,17 @@ Querying info Life cycle ---------- +Most communications are created using :ref:`s4u_mailbox`, but you can +also start direct communications as shown below. + .. tabs:: .. group-tab:: C++ + .. doxygenfunction:: simgrid::s4u::Comm::sendto + .. doxygenfunction:: simgrid::s4u::Comm::sendto_init + .. doxygenfunction:: simgrid::s4u::Comm::sendto_async + .. doxygenfunction:: simgrid::s4u::Comm::cancel .. doxygenfunction:: simgrid::s4u::Comm::start .. doxygenfunction:: simgrid::s4u::Comm::test diff --git a/include/simgrid/s4u/Comm.hpp b/include/simgrid/s4u/Comm.hpp index 45094324e8..6e33e01334 100644 --- a/include/simgrid/s4u/Comm.hpp +++ b/include/simgrid/s4u/Comm.hpp @@ -46,9 +46,20 @@ public: /*! Creates a communication beween the two given hosts, bypassing the mailbox mechanism. */ static CommPtr sendto_init(Host* from, Host* to); - /*! Creates and start a communication of the given amount of bytes beween the two given hosts, bypassing the mailbox - * mechanism */ + /** Do an asynchronous communication between two arbitrary hosts. + * + * This initializes a communication that completely bypass the mailbox and actors mechanism. + * There is really no limit on the hosts involved. In particular, the actor does not have to be on one of the involved + * hosts. + */ static CommPtr sendto_async(Host* from, Host* to, double simulated_size_in_bytes); + /** Do a blocking communication between two arbitrary hosts. + * + * This starts a blocking communication right away, bypassing the mailbox and actors mechanism. + * The calling actor is blocked until the end of the communication; there is really no limit on the hosts involved. + * In particular, the actor does not have to be on one of the involved hosts. Enjoy the comfort of the simulator :) + */ + static void sendto(Host* from, Host* to, double simulated_size_in_bytes); static xbt::signal on_start; static xbt::signal on_completion; diff --git a/include/simgrid/s4u/Host.hpp b/include/simgrid/s4u/Host.hpp index f50f1484b7..9d658f6d56 100644 --- a/include/simgrid/s4u/Host.hpp +++ b/include/simgrid/s4u/Host.hpp @@ -152,27 +152,13 @@ public: void route_to(const Host* dest, std::vector& links, double* latency) const; void route_to(const Host* dest, std::vector& links, double* latency) const; - /** Do a blocking communication between two arbitrary hosts. - * - * This starts a blocking communication right away, bypassing the mailbox and actors mechanism. - * The calling actor is blocked until the end of the communication; there is really no limit on the hosts involved. - * In particular, the actor does not have to be on one of the involved hosts. Enjoy the comfort of the simulator :) - */ - void sendto(Host* dest, double byte_amount); - - /** Do an asynchronous communication between two arbitrary hosts. - * - * This initializes a communication that completely bypass the mailbox and actors mechanism. - * There is really no limit on the hosts involved. In particular, the actor does not have to be on one of the involved - * hosts. - */ - CommPtr sendto_async(Host* dest, double byte_amount); #ifndef DOXYGEN - XBT_ATTRIB_DEPRECATED_v330("Please use Host::sendto()") void send_to(Host* dest, double byte_amount) - { - sendto(dest, byte_amount); - } + XBT_ATTRIB_DEPRECATED_v331("Please use Comm::sendto()") void sendto(Host* dest, double byte_amount); + + XBT_ATTRIB_DEPRECATED_v331("Please use Comm::sendto_async()") CommPtr sendto_async(Host* dest, double byte_amount); + + XBT_ATTRIB_DEPRECATED_v330("Please use Host::sendto()") void send_to(Host* dest, double byte_amount); #endif NetZone* get_englobing_zone(); diff --git a/src/plugins/file_system/s4u_FileSystem.cpp b/src/plugins/file_system/s4u_FileSystem.cpp index b29dd66d3d..46dcac8c7f 100644 --- a/src/plugins/file_system/s4u_FileSystem.cpp +++ b/src/plugins/file_system/s4u_FileSystem.cpp @@ -5,6 +5,7 @@ #include "simgrid/plugins/file_system.h" #include "simgrid/s4u/Actor.hpp" +#include "simgrid/s4u/Comm.hpp" #include "simgrid/s4u/Engine.hpp" #include "src/surf/HostImpl.hpp" #include "src/surf/xml/platf_private.hpp" @@ -141,7 +142,7 @@ sg_size_t File::read(sg_size_t size) if (host && host->get_name() != Host::current()->get_name() && read_size > 0) { /* the file is hosted on a remote host, initiate a communication between src and dest hosts for data transfer */ XBT_DEBUG("File is on %s remote host, initiate data transfer of %llu bytes.", host->get_cname(), read_size); - host->sendto(Host::current(), read_size); + Comm::sendto(host, Host::current(), read_size); } return read_size; @@ -165,7 +166,7 @@ sg_size_t File::write(sg_size_t size, bool write_inside) if (host && host->get_name() != Host::current()->get_name()) { /* the file is hosted on a remote host, initiate a communication between src and dest hosts for data transfer */ XBT_DEBUG("File is on %s remote host, initiate data transfer of %llu bytes.", host->get_cname(), size); - Host::current()->sendto(host, size); + Comm::sendto(Host::current(), host, size); } XBT_DEBUG("WRITE %s on disk '%s'. size '%llu/%llu' '%llu:%llu'", get_path(), local_disk_->get_cname(), size, size_, sg_disk_get_size_used(local_disk_), sg_disk_get_size(local_disk_)); @@ -307,7 +308,7 @@ int File::remote_copy(sg_host_t host, const std::string& fullpath) if (src_host) { XBT_DEBUG("Initiate data transfer of %llu bytes between %s and %s.", read_size, src_host->get_cname(), dst_host->get_cname()); - src_host->sendto(dst_host, read_size); + Comm::sendto(src_host, dst_host, read_size); } /* Create file on remote host, write it and close it */ diff --git a/src/s4u/s4u_Comm.cpp b/src/s4u/s4u_Comm.cpp index 2d90c616ce..23eaf0d2dc 100644 --- a/src/s4u/s4u_Comm.cpp +++ b/src/s4u/s4u_Comm.cpp @@ -138,6 +138,11 @@ CommPtr Comm::sendto_async(Host* from, Host* to, double simulated_size_in_bytes) return res; } +void Comm::sendto(Host* from, Host* to, double simulated_size_in_bytes) +{ + sendto_async(from, to, simulated_size_in_bytes)->wait(); +} + Comm* Comm::start() { xbt_assert(get_state() == State::INITED || get_state() == State::STARTING, diff --git a/src/s4u/s4u_Host.cpp b/src/s4u/s4u_Host.cpp index b9e8c8b506..47feede354 100644 --- a/src/s4u/s4u_Host.cpp +++ b/src/s4u/s4u_Host.cpp @@ -176,16 +176,21 @@ NetZone* Host::get_englobing_zone() return pimpl_netpoint_->get_englobing_zone()->get_iface(); } -void Host::sendto(Host* dest, double byte_amount) +void Host::sendto(Host* dest, double byte_amount) // deprecated 331 { - sendto_async(dest, byte_amount)->wait(); + Comm::sendto_async(this, dest, byte_amount)->wait(); } -CommPtr Host::sendto_async(Host* dest, double byte_amount) +CommPtr Host::sendto_async(Host* dest, double byte_amount) // deprecated 331 { return Comm::sendto_async(this, dest, byte_amount); } +void Host::send_to(Host* dest, double byte_amount) // deprecated 330 +{ + Comm::sendto(this, dest, byte_amount); +} + /** Get the properties assigned to a host */ const std::unordered_map* Host::get_properties() const { @@ -607,7 +612,7 @@ double sg_host_route_bandwidth(const_sg_host_t from, const_sg_host_t to) // XBT_ void sg_host_sendto(sg_host_t from, sg_host_t to, double byte_amount) { - from->sendto(to, byte_amount); + simgrid::s4u::Comm::sendto(from, to, byte_amount); } /** @brief Displays debugging information about a host */ diff --git a/teshsuite/s4u/activity-lifecycle/testing_comm_direct.cpp b/teshsuite/s4u/activity-lifecycle/testing_comm_direct.cpp index c9411d3e0f..ac4b169aef 100644 --- a/teshsuite/s4u/activity-lifecycle/testing_comm_direct.cpp +++ b/teshsuite/s4u/activity-lifecycle/testing_comm_direct.cpp @@ -16,7 +16,7 @@ TEST_CASE("Activity lifecycle: direct communication activities") simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5", all_hosts[1], [&global]() { assert_exit(true, 5.); - all_hosts[1]->sendto(all_hosts[2], 5000); + simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000); global = true; }); @@ -32,7 +32,7 @@ TEST_CASE("Activity lifecycle: direct communication activities") XBT_INFO("Launch a dcomm(5s), and kill it right after start"); simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5_killed", all_hosts[1], []() { assert_exit(false, 0); - all_hosts[1]->sendto(all_hosts[2], 5000); + simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000); FAIL("I should be dead now"); }); @@ -47,7 +47,7 @@ TEST_CASE("Activity lifecycle: direct communication activities") XBT_INFO("Launch a dcomm(5s), and kill it after 2 secs"); simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5_killed", all_hosts[1], []() { assert_exit(false, 2); - all_hosts[1]->sendto(all_hosts[2], 5000); + simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000); FAIL("I should be dead now"); }); @@ -62,7 +62,7 @@ TEST_CASE("Activity lifecycle: direct communication activities") XBT_INFO("Launch a dcomm(5s), and restart its host right after start"); simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5_restarted", all_hosts[1], []() { assert_exit(false, 0); - all_hosts[1]->sendto(all_hosts[2], 5000); + simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000); FAIL("I should be dead now"); }); @@ -78,7 +78,7 @@ TEST_CASE("Activity lifecycle: direct communication activities") XBT_INFO("Launch a dcomm(5s), and restart its host after 2 secs"); simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5_restarted", all_hosts[1], []() { assert_exit(false, 2); - all_hosts[1]->sendto(all_hosts[2], 5000); + simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000); FAIL("I should be dead now"); }); @@ -96,7 +96,7 @@ TEST_CASE("Activity lifecycle: direct communication activities") simgrid::s4u::Actor::create("dcomm5_restarted", all_hosts[1], [&execution_done]() { assert_exit(true, 5); - all_hosts[1]->sendto(all_hosts[2], 5000); + simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000); execution_done = true; }); @@ -119,7 +119,7 @@ TEST_CASE("Activity lifecycle: direct communication activities") XBT_INFO("Launch a dcomm(5s), and restart the used link right after start"); simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5_restarted", all_hosts[1], []() { assert_exit(true, 0); - REQUIRE_NETWORK_FAILURE(all_hosts[1]->sendto(all_hosts[2], 5000)); + REQUIRE_NETWORK_FAILURE(simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000)); }); simgrid::s4u::this_actor::yield(); @@ -135,7 +135,7 @@ TEST_CASE("Activity lifecycle: direct communication activities") XBT_INFO("Launch a dcomm(5s), and restart the used link after 2 secs"); simgrid::s4u::ActorPtr dcomm5 = simgrid::s4u::Actor::create("dcomm5_restarted", all_hosts[1], []() { assert_exit(true, 2); - REQUIRE_NETWORK_FAILURE(all_hosts[1]->sendto(all_hosts[2], 5000)); + REQUIRE_NETWORK_FAILURE(simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000)); }); simgrid::s4u::this_actor::sleep_for(2); @@ -153,7 +153,7 @@ TEST_CASE("Activity lifecycle: direct communication activities") simgrid::s4u::Actor::create("dcomm5_restarted", all_hosts[1], [&execution_done]() { assert_exit(true, 5); - all_hosts[1]->sendto(all_hosts[2], 5000); + simgrid::s4u::Comm::sendto(all_hosts[1], all_hosts[2], 5000); execution_done = true; }); -- 2.20.1