From ad6c13e59372de15e361f15bbb7f5861c6873d4d Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Sun, 23 Jan 2022 00:46:39 +0100 Subject: [PATCH 1/1] Extend the python bindings and cosmetics --- MANIFEST.in | 2 + docs/source/Tutorial_Algorithms.rst | 2 +- docs/source/app_s4u.rst | 42 +++++++++++++- examples/README.rst | 2 + examples/python/CMakeLists.txt | 7 ++- .../platform-profile/platform-profile.py | 50 +++++++++++++++++ .../platform-profile/platform-profile.tesh | 14 +++++ include/simgrid/actor.h | 2 + include/simgrid/s4u/Link.hpp | 3 + src/bindings/python/simgrid_python.cpp | 55 ++++++++++++++++--- 10 files changed, 165 insertions(+), 14 deletions(-) create mode 100644 examples/python/platform-profile/platform-profile.py create mode 100644 examples/python/platform-profile/platform-profile.tesh diff --git a/MANIFEST.in b/MANIFEST.in index 3e6119611a..02cbfc1ce8 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -532,6 +532,8 @@ include examples/python/io-degradation/io-degradation.py include examples/python/io-degradation/io-degradation.tesh include examples/python/network-nonlinear/network-nonlinear.py include examples/python/network-nonlinear/network-nonlinear.tesh +include examples/python/platform-profile/platform-profile.py +include examples/python/platform-profile/platform-profile.tesh include examples/smpi/NAS/DGraph.c include examples/smpi/NAS/DGraph.h include examples/smpi/NAS/README.install diff --git a/docs/source/Tutorial_Algorithms.rst b/docs/source/Tutorial_Algorithms.rst index d5b6d8b3aa..ab0cb3590d 100644 --- a/docs/source/Tutorial_Algorithms.rst +++ b/docs/source/Tutorial_Algorithms.rst @@ -854,7 +854,7 @@ Retrieve all links in the platform with :cpp:func:`simgrid::s4u::Engine::get_all Retrieve the list of links from one host to another with :cpp:func:`simgrid::s4u::Host::route_to` (C++) or :py:func:`simgrid.Host.route_to` (python). Modify the bandwidth of a given link with :cpp:func:`simgrid::s4u::Link::set_bandwidth` (C++) or :py:func:`simgrid.Link.set_bandwidth` (python). -You can even have the bandwidth automatically vary over time with :cpp:func:`simgrid::s4u::Link::set_bandwidth_profile` (C++) or :py:func:`simgrid.Link.set_bandwidth_profile` (python). +You can even have the bandwidth automatically vary over time with :cpp:func:`simgrid::s4u::Link::set_bandwidth_profile` (C++) or :py:func:`simgrid.Link.set_bandwidth_profile` (python). Once implemented, you will notice that slow communications may still result in situations where one worker only works at a given point of time. To overcome that, your master needs diff --git a/docs/source/app_s4u.rst b/docs/source/app_s4u.rst index 117b85d8e4..c961b65caf 100644 --- a/docs/source/app_s4u.rst +++ b/docs/source/app_s4u.rst @@ -484,6 +484,7 @@ Retrieving actors .. doxygenfunction:: sg_actor_by_pid(aid_t pid) .. doxygenfunction:: sg_actor_self() + .. doxygenfunction:: sg_actor_list() Querying info ------------- @@ -655,8 +656,8 @@ Querying info .. autofunction:: simgrid.this_actor.get_host .. autofunction:: simgrid.this_actor.set_host - .. autofunction:: simgrid.this_actor.get_pid() - .. autofunction:: simgrid.this_actor.get_ppid() + .. autofunction:: simgrid.this_actor.get_pid + .. autofunction:: simgrid.this_actor.get_ppid .. group-tab:: C @@ -922,6 +923,10 @@ Retrieving links .. doxygenfunction:: simgrid::s4u::Engine::link_by_name .. doxygenfunction:: simgrid::s4u::Engine::link_by_name_or_null + .. group-tab:: Python + + .. automethod:: simgrid.Engine.get_all_links + Interacting with the routing ---------------------------- @@ -936,6 +941,14 @@ Interacting with the routing .. doxygenfunction:: simgrid::s4u::Engine::netzone_by_name_or_null .. doxygenfunction:: simgrid::s4u::Engine::set_netzone_root(const NetZone *netzone) + .. group-tab:: Python + + .. automethod:: simgrid.Engine.get_all_netpoints + .. automethod:: simgrid.Engine.get_netzone_root + .. automethod:: simgrid.Engine.netpoint_by_name_or_null + .. automethod:: simgrid.Engine.netzone_by_name_or_null + .. automethod:: simgrid.Engine.set_netzone_root + Signals ------- @@ -1110,6 +1123,11 @@ Resources .. autoclass:: simgrid.Disk + .. group-tab:: C + + .. doxygentypedef:: sg_disk_t + .. doxygentypedef:: const_sg_disk_t + Basic management ---------------- @@ -1391,6 +1409,7 @@ DVFS .. automethod:: simgrid.Host.get_pstate_count .. automethod:: simgrid.Host.get_pstate_speed + .. automethod:: simgrid.Host.set_speed_profile .. group-tab:: C @@ -1432,6 +1451,8 @@ using :cpp:func:`Comm::sendto() `. .. automethod:: simgrid.Host.get_netpoint .. automethod:: simgrid.Host.create_disk + + .. automethod:: simgrid.Host.route_to .. group-tab:: C @@ -1521,6 +1542,8 @@ Retrieving links .. group-tab:: Python + See also :py:func:`simgrid.Engine.get_all_links`. + .. automethod:: simgrid.Link.by_name .. autoattribute:: simgrid.Link.name @@ -1545,6 +1568,11 @@ Querying info .. doxygenfunction:: simgrid::s4u::Link::get_usage() const .. doxygenfunction:: simgrid::s4u::Link::is_used() const + .. group-tab:: Python + + .. autoattribute:: simgrid.Link.bandwidth + .. autoattribute:: simgrid.Link.latency + .. group-tab:: C .. doxygenfunction:: sg_link_get_bandwidth(const_sg_link_t link) @@ -1567,6 +1595,7 @@ Modifying characteristics .. group-tab:: Python + .. automethod:: simgrid.Link.set_bandwidth .. automethod:: simgrid.Link.set_latency .. automethod:: simgrid.Link.set_concurrency_limit .. automethod:: simgrid.Link.set_sharing_policy @@ -1604,6 +1633,14 @@ On/Off .. doxygenfunction:: simgrid::s4u::Link::turn_off() .. doxygenfunction:: simgrid::s4u::Link::turn_on() + .. group-tab:: Python + + See also :py:func:`simgrid.Link.set_state_profile`. + + .. automethod:: simgrid.Link.is_on + .. automethod:: simgrid.Link.turn_off + .. automethod:: simgrid.Link.turn_on + Dynamic profiles ---------------- @@ -2459,6 +2496,7 @@ Locking #include .. doxygentypedef:: sg_bar_t + .. doxygentypedef:: const_sg_bar_t .. cpp:type:: const s4u_Barrier* const_sg_bar_t Pointer to a constant barrier object. diff --git a/examples/README.rst b/examples/README.rst index 7d6dc0b499..86c5f8945e 100644 --- a/examples/README.rst +++ b/examples/README.rst @@ -735,6 +735,8 @@ Shows how to specify an external load to resources, variating their peak speed o .. example-tab:: examples/cpp/platform-profile/s4u-platform-profile.cpp + .. example-tab:: examples/python/platform-profile/platform-profile.py + .. group-tab:: XML .. showfile:: examples/platforms/small_platform_profile.xml diff --git a/examples/python/CMakeLists.txt b/examples/python/CMakeLists.txt index 7edc4bc78e..f1692ef7de 100644 --- a/examples/python/CMakeLists.txt +++ b/examples/python/CMakeLists.txt @@ -1,8 +1,9 @@ foreach(example actor-create actor-daemon actor-join actor-kill actor-migrate actor-suspend actor-yield actor-lifetime app-masterworkers - comm-wait comm-waitall comm-waitany - exec-async exec-basic exec-dvfs exec-remote - network-nonlinear clusters-multicpu io-degradation exec-cpu-nonlinear) + comm-wait comm-waitall comm-waitany + exec-async exec-basic exec-dvfs exec-remote + platform-profile + network-nonlinear clusters-multicpu io-degradation exec-cpu-nonlinear) set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.tesh) set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.py) diff --git a/examples/python/platform-profile/platform-profile.py b/examples/python/platform-profile/platform-profile.py new file mode 100644 index 0000000000..399fde7299 --- /dev/null +++ b/examples/python/platform-profile/platform-profile.py @@ -0,0 +1,50 @@ +# Copyright (c) 2010-2022. The SimGrid Team. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the license (GNU LGPL) which comes with this package. + +from simgrid import Actor, Comm, Engine, Host, Mailbox, Link, this_actor +import sys + +# This example demonstrates how to attach a profile to a host or a link, to specify external changes to the resource speed. +# The first way to do so is to use a file in the XML, while the second is to use the programmatic interface. + +def watcher(): + jupiter = Host.by_name("Jupiter") + fafard = Host.by_name("Fafard") + lilibeth = Host.by_name("Lilibeth") + link1 = Link.by_name("1") + link2 = Link.by_name("2") + + (links, lat) = jupiter.route_to(fafard) + path = "" + for l in links: + path += ("" if len(path)==0 else ", ") + "link '" + l.name + "'" + this_actor.info(f"Path from Jupiter to Fafard: {path} (latency: {lat:.6f}s).") + + for i in range(10): + this_actor.info("Fafard: %.0fMflops, Jupiter: %4.0fMflops, Lilibeth: %3.1fMflops, Link1: (%.2fMB/s %.0fms), Link2: (%.2fMB/s %.0fms)" % ( + fafard.speed * fafard.available_speed / 1000000, + jupiter.speed * jupiter.available_speed / 1000000, + lilibeth.speed * lilibeth.available_speed / 1000000, + link1.bandwidth / 1000, link1.latency * 1000, + link2.bandwidth / 1000, link2.latency * 1000)) + this_actor.sleep_for(1) + +if __name__ == '__main__': + e = Engine(sys.argv) + # Load the platform description + e.load_platform(sys.argv[1]) + + # Add a new host programmatically, and attach a simple speed profile to it (alternate between full and half speed every two seconds + lili = e.get_netzone_root().create_host("Lilibeth", 25e6) + lili.set_speed_profile(""" +0 1.0 +2 0.5 +""", 2) + lili.seal() + + # Add a watcher of the changes + Actor.create("watcher", Host.by_name("Fafard"), watcher) + + e.run() diff --git a/examples/python/platform-profile/platform-profile.tesh b/examples/python/platform-profile/platform-profile.tesh new file mode 100644 index 0000000000..1d148237e1 --- /dev/null +++ b/examples/python/platform-profile/platform-profile.tesh @@ -0,0 +1,14 @@ +#!/usr/bin/env tesh + +$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/platform-profile.py ${platfdir}/small_platform_profile.xml "--log=root.fmt:[%10.6r]%e[%a]%e%m%n" +> [ 0.000000] [watcher] Path from Jupiter to Fafard: link '1', link '2' (latency: 0.020000s). +> [ 0.000000] [watcher] Fafard: 25Mflops, Jupiter: 12Mflops, Lilibeth: 25.0Mflops, Link1: (1000.00MB/s 10ms), Link2: (1000.00MB/s 10ms) +> [ 1.000000] [watcher] Fafard: 25Mflops, Jupiter: 12Mflops, Lilibeth: 25.0Mflops, Link1: (1000.00MB/s 3ms), Link2: (1000.00MB/s 10ms) +> [ 2.000000] [watcher] Fafard: 25Mflops, Jupiter: 25Mflops, Lilibeth: 12.5Mflops, Link1: (2000.00MB/s 3ms), Link2: (1000.00MB/s 10ms) +> [ 3.000000] [watcher] Fafard: 25Mflops, Jupiter: 25Mflops, Lilibeth: 12.5Mflops, Link1: (2000.00MB/s 15ms), Link2: (1000.00MB/s 10ms) +> [ 4.000000] [watcher] Fafard: 25Mflops, Jupiter: 18Mflops, Lilibeth: 25.0Mflops, Link1: (3000.00MB/s 15ms), Link2: (1000.00MB/s 10ms) +> [ 5.000000] [watcher] Fafard: 25Mflops, Jupiter: 18Mflops, Lilibeth: 25.0Mflops, Link1: (3000.00MB/s 15ms), Link2: (1000.00MB/s 10ms) +> [ 6.000000] [watcher] Fafard: 25Mflops, Jupiter: 2Mflops, Lilibeth: 12.5Mflops, Link1: (3000.00MB/s 15ms), Link2: (1000.00MB/s 10ms) +> [ 7.000000] [watcher] Fafard: 25Mflops, Jupiter: 2Mflops, Lilibeth: 12.5Mflops, Link1: (3000.00MB/s 15ms), Link2: (1000.00MB/s 10ms) +> [ 8.000000] [watcher] Fafard: 25Mflops, Jupiter: 100Mflops, Lilibeth: 25.0Mflops, Link1: (3000.00MB/s 15ms), Link2: (1000.00MB/s 10ms) +> [ 9.000000] [watcher] Fafard: 25Mflops, Jupiter: 100Mflops, Lilibeth: 25.0Mflops, Link1: (3000.00MB/s 15ms), Link2: (1000.00MB/s 10ms) diff --git a/include/simgrid/actor.h b/include/simgrid/actor.h index b18004b009..1a064b23b7 100644 --- a/include/simgrid/actor.h +++ b/include/simgrid/actor.h @@ -47,10 +47,12 @@ XBT_PUBLIC void sg_actor_on_exit(void_f_int_pvoid_t fun, void* data); XBT_PUBLIC aid_t sg_actor_get_pid(const_sg_actor_t actor); XBT_PUBLIC aid_t sg_actor_get_ppid(const_sg_actor_t actor); XBT_PUBLIC sg_actor_t sg_actor_by_pid(aid_t pid); +#ifndef DOXYGEN XBT_ATTRIB_DEPRECATED_v331("Please use sg_actor_get_pid() instead") XBT_PUBLIC aid_t sg_actor_get_PID(const_sg_actor_t actor); XBT_ATTRIB_DEPRECATED_v331("Please use sg_actor_get_ppid() instead") XBT_PUBLIC aid_t sg_actor_get_PPID(const_sg_actor_t actor); +#endif XBT_ATTRIB_DEPRECATED_v331("Please use sg_actor_by_pid() instead") XBT_PUBLIC sg_actor_t sg_actor_by_PID(aid_t pid); XBT_PUBLIC const char* sg_actor_get_name(const_sg_actor_t actor); XBT_PUBLIC sg_host_t sg_actor_get_host(const_sg_actor_t actor); diff --git a/include/simgrid/s4u/Link.hpp b/include/simgrid/s4u/Link.hpp index 5939fe35e9..fec2d9a8d2 100644 --- a/include/simgrid/s4u/Link.hpp +++ b/include/simgrid/s4u/Link.hpp @@ -134,8 +134,11 @@ public: /** @brief Check if the Link is shared (not a FATPIPE) */ bool is_shared() const; + /** Turns the link on. */ void turn_on(); + /** Turns the link off. */ void turn_off(); + /** Checks whether the link is on. */ bool is_on() const; Link* seal(); diff --git a/src/bindings/python/simgrid_python.cpp b/src/bindings/python/simgrid_python.cpp index 47c669a422..c423bf7eec 100644 --- a/src/bindings/python/simgrid_python.cpp +++ b/src/bindings/python/simgrid_python.cpp @@ -22,6 +22,7 @@ #pragma GCC diagnostic pop #endif +#include "simgrid/kernel/ProfileBuilder.hpp" #include "simgrid/kernel/routing/NetPoint.hpp" #include "src/kernel/context/Context.hpp" #include @@ -145,6 +146,15 @@ PYBIND11_MODULE(simgrid, m) .def_static( "instance", []() { return Engine::get_instance(); }, "Retrieve the simulation engine") .def("get_all_hosts", &Engine::get_all_hosts, "Returns the list of all hosts found in the platform") + .def("get_all_links", &Engine::get_all_links, "Returns the list of all links found in the platform") + + .def("get_netzone_root", &Engine::get_netzone_root, "Retrieve the root netzone, containing all others.") + .def("get_all_netpoints", &Engine::get_all_netpoints) + .def("get_netzone_root", &Engine::get_netzone_root) + .def("netpoint_by_name", &Engine::netpoint_by_name_or_null) + .def("netzone_by_name", &Engine::netzone_by_name_or_null) + .def("set_netzone_root", &Engine::set_netzone_root) + .def("load_platform", &Engine::load_platform, "Load a platform file describing the environment") .def("load_deployment", &Engine::load_deployment, "Load a deployment file and launch the actors that it contains") .def("run", &Engine::run, py::call_guard(), "Run the simulation until its end") @@ -251,6 +261,19 @@ PYBIND11_MODULE(simgrid, m) py::class_> host( m, "Host", "Simulated host. See the C++ documentation for details."); host.def("by_name", &Host::by_name, "Retrieves a host from its name, or die") + .def( + "route_to", + [](simgrid::s4u::Host* h, simgrid::s4u::Host* to) { + auto* list = new std::vector(); + double bw = 0; + h->route_to(to, *list, &bw); + return make_tuple(list, bw); + }, + "Retrieves the list of links and the bandwidth between two hosts") + .def("set_speed_profile", + [](Host* h, const std::string& profile, double period) { + h->set_speed_profile(simgrid::kernel::profile::ProfileBuilder::from_string("", profile, period)); + }) .def("get_pstate_count", &Host::get_pstate_count, "Retrieve the count of defined pstate levels") .def("get_pstate_speed", &Host::get_pstate_speed, "Retrieve the maximal speed at the given pstate") .def("get_netpoint", &Host::get_netpoint, "Retrieve the netpoint associated to this host") @@ -282,13 +305,17 @@ PYBIND11_MODULE(simgrid, m) return std::string(self->get_name().c_str()); // Convert from xbt::string because of MC }, "The name of this host") - .def_property_readonly( - "load", &Host::get_load, - "Returns the current computation load (in flops per second). This is the currently achieved speed.") + .def_property_readonly("load", &Host::get_load, + "Returns the current computation load (in flops per second), NOT taking the external load " + "into account. This is the currently achieved speed.") .def_property_readonly( "speed", &Host::get_speed, - "The peak computing speed in flops/s at the current pstate, taking the external load into account. " - "This is the max potential speed."); + "The peak computing speed in flops/s at the current pstate, NOT taking the external load into account. " + "This is the max potential speed.") + .def_property_readonly( + "available_speed", &Host::get_available_speed, + "Get the available speed ratio, between 0 and 1.\n" + "This accounts for external load (see :py:func:`set_speed_profile() `)."); py::enum_(host, "SharingPolicy") .value("NONLINEAR", simgrid::s4u::Host::SharingPolicy::NONLINEAR) .value("LINEAR", simgrid::s4u::Host::SharingPolicy::LINEAR) @@ -329,9 +356,18 @@ PYBIND11_MODULE(simgrid, m) py::class_> link( m, "Link", "Network link. See the C++ documentation for details."); link.def("set_latency", py::overload_cast(&simgrid::s4u::Link::set_latency), - py::call_guard(), "Set the latency") + py::call_guard(), + "Set the latency as a string. Accepts values with units, such as ‘1s’ or ‘7ms’.\nFull list of accepted " + "units: w (week), d (day), h, s, ms, us, ns, ps.") .def("set_latency", py::overload_cast(&simgrid::s4u::Link::set_latency), - py::call_guard(), "Set the latency") + py::call_guard(), "Set the latency as a float (in seconds).") + .def("set_bandwidth", &simgrid::s4u::Link::set_bandwidth, py::call_guard(), + "Set the bandwidth (in byte per second).") + + .def("turn_on", &simgrid::s4u::Link::turn_on, py::call_guard(), "Turns the link on.") + .def("turn_off", &simgrid::s4u::Link::turn_off, py::call_guard(), "Turns the link off.") + .def("is_on", &simgrid::s4u::Link::is_on, "Check whether the link is on.") + .def("set_sharing_policy", &simgrid::s4u::Link::set_sharing_policy, py::call_guard(), "Set sharing policy for this link") .def("set_concurrency_limit", &simgrid::s4u::Link::set_concurrency_limit, @@ -345,7 +381,10 @@ PYBIND11_MODULE(simgrid, m) [](const simgrid::s4u::Link* self) { return std::string(self->get_name().c_str()); // Convert from xbt::string because of MC }, - "The name of this link"); + "The name of this link") + .def_property_readonly("bandwidth", &simgrid::s4u::Link::get_bandwidth, "The bandwidth (in bytes per second)") + .def_property_readonly("latency", &simgrid::s4u::Link::get_latency, "The latency (in seconds)"); + py::enum_(link, "SharingPolicy") .value("NONLINEAR", simgrid::s4u::Link::SharingPolicy::NONLINEAR) .value("WIFI", simgrid::s4u::Link::SharingPolicy::WIFI) -- 2.20.1