Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add Barrier Python bindings
authorJean-Edouard BOULANGER <jean.edouard.boulanger@gmail.com>
Tue, 15 Mar 2022 18:35:47 +0000 (19:35 +0100)
committerJean-Edouard BOULANGER <jean.edouard.boulanger@gmail.com>
Tue, 15 Mar 2022 18:35:47 +0000 (19:35 +0100)
ChangeLog
docs/source/app_s4u.rst
examples/README.rst
examples/python/synchro-barrier/synchro-barrier.py [new file with mode: 0644]
examples/python/synchro-barrier/synchro-barrier.tesh [new file with mode: 0644]
src/bindings/python/simgrid_python.cpp

index 76fb566..191b780 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -80,6 +80,7 @@ Python:
      - Comm.wait_any_for()
      - Comm.wait_all_for() [example: examples/python/comm-waitallfor/]
      - Mutex [example: examples/python/synchro-mutex/]
+     - Barrier [example: examples/python/synchro-barrier/]
 
 Build System:
  - Remove target "make uninstall" which was incomplete and no longer maintained.
index be1381f..27401a1 100644 (file)
@@ -2527,7 +2527,15 @@ Locking
 ⁣  Barrier
 ================
 
-.. doxygenclass:: simgrid::s4u::Barrier
+.. tabs::
+
+   .. group-tab:: C++
+
+      .. doxygenclass:: simgrid::s4u::Barrier
+
+   .. group-tab:: Python
+
+      .. autoclass:: simgrid.Barrier
 
 .. tabs::
 
@@ -2543,6 +2551,15 @@ Locking
       .. doxygenfunction:: simgrid::s4u::Barrier::create(unsigned int expected_actors)
       .. doxygenfunction:: simgrid::s4u::Barrier::wait()
 
+   .. group-tab:: Python
+
+      .. code-block:: Python
+
+         from simgrid import Barrier
+         barrier = Barrier(2)
+
+      .. automethod:: simgrid.Barrier.wait()
+
    .. group-tab:: C
 
       .. code-block:: C
index 35ac45f..a91878f 100644 (file)
@@ -614,6 +614,8 @@ Shows how to use :cpp:type:`simgrid::s4u::Barrier` synchronization objects.
 
    .. example-tab:: examples/cpp/synchro-barrier/s4u-synchro-barrier.cpp
 
+   .. example-tab:: examples/python/synchro-barrier/synchro-barrier.py
+
 Condition variable: basic usage
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/examples/python/synchro-barrier/synchro-barrier.py b/examples/python/synchro-barrier/synchro-barrier.py
new file mode 100644 (file)
index 0000000..33cb389
--- /dev/null
@@ -0,0 +1,59 @@
+from argparse import ArgumentParser
+import sys
+
+from simgrid import Actor, Barrier, Engine, Host, this_actor
+
+
+def create_parser() -> ArgumentParser:
+    parser = ArgumentParser()
+    parser.add_argument(
+        '--platform',
+        type=str,
+        required=True,
+        help='path to the platform description'
+    )
+    parser.add_argument(
+        "--actors",
+        type=int,
+        required=True,
+        help="Number of actors to start"
+    )
+    return parser
+
+
+def worker(barrier: Barrier):
+    """ Wait on the barrier and exits.
+    :param barrier: Barrier to be awaited
+    """
+    this_actor.info(f"Waiting on the barrier")
+    barrier.wait()
+    this_actor.info("Bye")
+
+
+def master(actor_count: int):
+    """ Create barrier with `actor_count` expected actors, spawns `actor_count - 1` workers, then wait on the barrier
+    and exits.
+    :param actor_count: Spawn actor_count-1 workers and do a barrier with them
+    """
+    barrier = Barrier(actor_count)
+    workers_count = actor_count - 1
+    this_actor.info(f"Spawning {workers_count} workers")
+    for i in range(workers_count):
+        Actor.create(f"worker-{i}", Host.by_name("Jupiter"), worker, barrier)
+    this_actor.info(f"Waiting on the barrier")
+    barrier.wait()
+    this_actor.info("Bye")
+
+
+def main():
+    settings = create_parser().parse_known_args()[0]
+    if settings.actors < 1:
+        raise ValueError("--actors must be greater than 0")
+    e = Engine(sys.argv)
+    e.load_platform(settings.platform)
+    Actor.create("master", Host.by_name("Tremblay"), master, settings.actors)
+    e.run()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/examples/python/synchro-barrier/synchro-barrier.tesh b/examples/python/synchro-barrier/synchro-barrier.tesh
new file mode 100644 (file)
index 0000000..8322c6f
--- /dev/null
@@ -0,0 +1,38 @@
+#!/usr/bin/env tesh
+
+p Testing Barrier
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/synchro-barrier.py --platform ${platfdir}/two_hosts.xml --actors 1 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n"
+>[  0.000000] (1:master@Tremblay) Spawning 0 workers
+>[  0.000000] (1:master@Tremblay) Waiting on the barrier
+>[  0.000000] (1:master@Tremblay) Bye
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/synchro-barrier.py --platform ${platfdir}/two_hosts.xml --actors 2 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n"
+>[  0.000000] (1:master@Tremblay) Spawning 1 workers
+>[  0.000000] (2:worker-0@Jupiter) Waiting on the barrier
+>[  0.000000] (1:master@Tremblay) Waiting on the barrier
+>[  0.000000] (2:worker-0@Jupiter) Bye
+>[  0.000000] (1:master@Tremblay) Bye
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/synchro-barrier.py --platform ${platfdir}/two_hosts.xml --actors 10 "--log=root.fmt:[%10.6r]%e(%i:%a@%h)%e%m%n"
+>[  0.000000] (1:master@Tremblay) Spawning 9 workers
+>[  0.000000] (2:worker-0@Jupiter) Waiting on the barrier
+>[  0.000000] (3:worker-1@Jupiter) Waiting on the barrier
+>[  0.000000] (4:worker-2@Jupiter) Waiting on the barrier
+>[  0.000000] (5:worker-3@Jupiter) Waiting on the barrier
+>[  0.000000] (6:worker-4@Jupiter) Waiting on the barrier
+>[  0.000000] (7:worker-5@Jupiter) Waiting on the barrier
+>[  0.000000] (8:worker-6@Jupiter) Waiting on the barrier
+>[  0.000000] (9:worker-7@Jupiter) Waiting on the barrier
+>[  0.000000] (10:worker-8@Jupiter) Waiting on the barrier
+>[  0.000000] (1:master@Tremblay) Waiting on the barrier
+>[  0.000000] (2:worker-0@Jupiter) Bye
+>[  0.000000] (3:worker-1@Jupiter) Bye
+>[  0.000000] (4:worker-2@Jupiter) Bye
+>[  0.000000] (5:worker-3@Jupiter) Bye
+>[  0.000000] (6:worker-4@Jupiter) Bye
+>[  0.000000] (7:worker-5@Jupiter) Bye
+>[  0.000000] (8:worker-6@Jupiter) Bye
+>[  0.000000] (9:worker-7@Jupiter) Bye
+>[  0.000000] (10:worker-8@Jupiter) Bye
+>[  0.000000] (1:master@Tremblay) Bye
index 3603e0d..8e054b2 100644 (file)
@@ -26,6 +26,7 @@
 #include "simgrid/kernel/routing/NetPoint.hpp"
 #include <simgrid/Exception.hpp>
 #include <simgrid/s4u/Actor.hpp>
+#include <simgrid/s4u/Barrier.hpp>
 #include <simgrid/s4u/Comm.hpp>
 #include <simgrid/s4u/Disk.hpp>
 #include <simgrid/s4u/Engine.hpp>
@@ -45,6 +46,8 @@
 namespace py = pybind11;
 using simgrid::s4u::Actor;
 using simgrid::s4u::ActorPtr;
+using simgrid::s4u::Barrier;
+using simgrid::s4u::BarrierPtr;
 using simgrid::s4u::Engine;
 using simgrid::s4u::Host;
 using simgrid::s4u::Link;
@@ -791,6 +794,14 @@ PYBIND11_MODULE(simgrid, m)
       .def("__exit__", [](Mutex* self, py::object&, py::object&, py::object&){ self->unlock(); },
           py::call_guard<py::gil_scoped_release>());
 
+  /* Class Barrier */
+  py::class_<Barrier, BarrierPtr>(m, "Barrier",
+                                  "A classical barrier, but blocking in the simulation world.")
+      .def(py::init<>(&Barrier::create), py::call_guard<py::gil_scoped_release>(), py::arg("expected_actors"))
+      .def("wait", &Barrier::wait, py::call_guard<py::gil_scoped_release>(),
+           "Blocks into the barrier. Every waiting actors will be unlocked once the expected amount of actors reaches "
+           "the barrier");
+
   /* Class Actor */
   py::class_<simgrid::s4u::Actor, ActorPtr>(m, "Actor",
                                             "An actor is an independent stream of execution in your distributed "