foreach(example actor-create actor-daemon actor-join actor-kill actor-migrate actor-suspend actor-yield # actor-lifetime
+ async-wait
exec-basic)
set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.tesh)
set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.py)
examples/python/actor-lifetime/actor-lifetime_d.xml
examples/python/actor-lifetime/actor-lifetime.py # example broken so far
examples/python/actor-lifetime/actor-lifetime.tesh
+ examples/python/async-wait/async-wait_d.xml
${tesh_files} PARENT_SCOPE)
set(examples_src ${examples_src} PARENT_SCOPE)
--- /dev/null
+# Copyright (c) 2010-2019. 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.
+
+import sys
+from simgrid import *
+
+# This example shows how to use simgrid::s4u::this_actor::wait() to wait for a given communication.
+#
+# As for the other asynchronous examples, the sender initiate all the messages it wants to send and
+# pack the resulting simgrid::s4u::CommPtr objects in a vector. All messages thus occurs concurrently.
+#
+# The sender then loops until there is no ongoing communication.
+
+class Sender:
+ def __init__(self, *args):
+ if len(args) != 3:
+ raise AssertionError(
+ "Actor sender requires 4 parameters, but got {:d}".format(len(args)))
+ self.messages_count = int(args[0]) # number of tasks
+ self.msg_size = int(args[1]) # communication cost (in bytes)
+ self.receivers_count = int(args[2]) # number of receivers
+
+ def __call__(self):
+ # List in which we store all ongoing communications
+ pending_comms = []
+
+ # Vector of the used mailboxes
+ mboxes = [Mailbox.by_name("receiver-{:d}".format(i)) for i in range(0, self.receivers_count)]
+
+ # Start dispatching all messages to receivers, in a round robin fashion
+ for i in range(0, self.messages_count):
+ content = "Message {:d}".format(i)
+ mbox = mboxes[i % self.receivers_count]
+
+ this_actor.info("Send '{:s}' to '{:s}'".format(content, str(mbox)))
+
+ # Create a communication representing the ongoing communication, and store it in pending_comms
+ comm = mbox.put_async(content, self.msg_size)
+ pending_comms.append(comm)
+
+ # Start sending messages to let the workers know that they should stop
+ for i in range(0, self.receivers_count):
+ mbox = mboxes[i]
+ this_actor.info("Send 'finalize' to '{:s}'".format(str(mbox)))
+ comm = mbox.put_async("finalize", 0)
+ pending_comms.append(comm)
+
+ this_actor.info("Done dispatching all messages")
+
+ # Now that all message exchanges were initiated, wait for their completion, in order of creation.
+ for comm in pending_comms:
+ comm.wait()
+ this_actor.info("Goodbye now!")
+
+class Receiver:
+ def __init__(self, *args):
+ if len(args) != 1: # Receiver actor expects 1 argument: its ID
+ raise AssertionError("Actor receiver requires 1 parameter, but got {:d}".format(len(args)))
+ self.mbox = Mailbox.by_name("receiver-{:s}".format(args[0]))
+
+ def __call__(self):
+ this_actor.info("Wait for my first message")
+ while True:
+ received = self.mbox.get()
+ this_actor.info("I got a '{:s}'.".format(received))
+ if received == "finalize":
+ break # If it's a finalize message, we're done.
+
+
+if __name__ == '__main__':
+ e = Engine(sys.argv)
+
+ e.load_platform(sys.argv[1]) # Load the platform description
+
+ # Register the classes representing the actors
+ e.register_actor("sender", Sender)
+ e.register_actor("receiver", Receiver)
+
+ e.load_deployment(sys.argv[2])
+
+ e.run()
--- /dev/null
+#!/usr/bin/env tesh
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/async-wait.py ${platfdir}/small_platform_fatpipe.xml async-wait_d.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [ 0.000000] (1:sender@Tremblay) Send 'Message 0' to 'Mailbox(receiver-0)'
+> [ 0.000000] (2:receiver@Ruby) Wait for my first message
+> [ 0.000000] (1:sender@Tremblay) Send 'Message 1' to 'Mailbox(receiver-0)'
+> [ 0.000000] (1:sender@Tremblay) Send 'Message 2' to 'Mailbox(receiver-0)'
+> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'Mailbox(receiver-0)'
+> [ 0.000000] (1:sender@Tremblay) Done dispatching all messages
+> [ 0.105458] (2:receiver@Ruby) I got a 'Message 0'.
+> [ 0.210917] (2:receiver@Ruby) I got a 'Message 1'.
+> [ 0.316375] (2:receiver@Ruby) I got a 'Message 2'.
+> [ 0.318326] (2:receiver@Ruby) I got a 'finalize'.
+> [ 0.318326] (1:sender@Tremblay) Goodbye now!
\ No newline at end of file
--- /dev/null
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "https://simgrid.org/simgrid.dtd">
+<platform version="4.1">
+ <!-- The master actor (with some arguments) -->
+ <actor host="Tremblay" function="sender">
+ <argument value="3"/> <!-- Number of tasks -->
+ <argument value="50000000"/> <!-- Computation size of tasks -->
+ <argument value="1"/> <!-- Number of receivers -->
+ </actor>
+ <!-- The receiver processes -->
+ <actor host="Ruby" function="receiver">
+ <argument value="0"/> <!-- id -->
+ </actor>
+</platform>
- **Basic asynchronous communications:**
Illustrates how to have non-blocking communications, that are
communications running in the background leaving the process free
- to do something else during their completion. The main functions
- involved are :cpp:func:`simgrid::s4u::Mailbox::put_async()` and
- :cpp:func:`simgrid::s4u::Comm::wait()`.
- |br| `examples/s4u/async-wait/s4u-async-wait.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/async-wait/s4u-async-wait.cpp>`_
+ to do something else during their completion.
+
+ - |cpp| `examples/s4u/async-wait/s4u-async-wait.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/async-wait/s4u-async-wait.cpp>`_
+ :cpp:func:`simgrid::s4u::Mailbox::put_async()` and :cpp:func:`simgrid::s4u::Comm::wait()`
+ - |py| `examples/python/async-wait/async-wait.py <https://framagit.org/simgrid/simgrid/tree/master/examples/python/async-wait/async-wait.py>`_
+ :py:func:`simgrid.Mailbox.put_async()` :py:func:`simgrid.Comm.wait()`
- **Waiting for all communications in a set:**
The :cpp:func:`simgrid::s4u::Comm::wait_all()` function is useful
matter which terminates first.
|br| `examples/s4u/async-waitany/s4u-async-waitany.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/async-waitany/s4u-async-waitany.cpp>`_
-.. todo:: add the `ready` example here
+.. todo:: review the `ready` and `waituntil` examples and add them here.
.. _s4u_ex_execution:
#include "src/kernel/context/Context.hpp"
#include <simgrid/Exception.hpp>
#include <simgrid/s4u/Actor.hpp>
+#include <simgrid/s4u/Comm.hpp>
#include <simgrid/s4u/Engine.hpp>
#include <simgrid/s4u/Host.hpp>
#include <simgrid/s4u/Mailbox.hpp>
/* Class Mailbox */
py::class_<simgrid::s4u::Mailbox, std::unique_ptr<Mailbox, py::nodelete>>(m, "Mailbox", "Mailbox, see :ref:`class s4u::Mailbox <API_s4u_Mailbox>`")
+ .def("__str__", [](Mailbox self) -> const std::string {
+ return std::string("Mailbox(")+self.get_name()+")";
+ }, "Textual representation of the Mailbox`")
.def("by_name", &Mailbox::by_name, "Retrieve a Mailbox from its name, see :cpp:func:`simgrid::s4u::Mailbox::by_name()`")
.def_property_readonly("name", [](Mailbox* self) -> const std::string {
return std::string(self->get_name().c_str()); // Convert from xbt::string because of MC
data.inc_ref();
self.put(data.ptr(), size);
}, "Blocking data transmission, see :cpp:func:`void simgrid::s4u::Mailbox::put(void*, uint64_t)`")
+ .def("put_async", [](Mailbox self, py::object data, int size) -> simgrid::s4u::CommPtr {
+ data.inc_ref();
+ return self.put_async(data.ptr(), size);
+ }, "Non-blocking data transmission, see :cpp:func:`void simgrid::s4u::Mailbox::put_async(void*, uint64_t)`")
.def("get", [](Mailbox self) -> py::object {
py::object data = pybind11::reinterpret_steal<py::object>(pybind11::handle(static_cast<PyObject*>(self.get())));
data.dec_ref();
return data;
}, "Blocking data reception, see :cpp:func:`void* simgrid::s4u::Mailbox::get()`");
+ /* Class Comm */
+ py::class_<simgrid::s4u::Comm, simgrid::s4u::CommPtr>(m, "Comm", "Communication, see :ref:`class s4u::Comm <API_s4u_Comm>`")
+ .def("test", [](simgrid::s4u::CommPtr self) {
+ return self->test();
+ }, "Test whether the communication is terminated, see :cpp:func:`simgrid::s4u::Comm::test()`")
+ .def("wait", [](simgrid::s4u::CommPtr self) {
+ self->wait();
+ }, "Block until the completion of that communication, see :cpp:func:`simgrid::s4u::Comm::wait()`");
+
/* Class Actor */
py::class_<simgrid::s4u::Actor, ActorPtr>(m, "Actor",
"An actor is an independent stream of execution in your distributed "