foreach(example actor-create actor-daemon actor-join actor-kill actor-migrate actor-suspend actor-yield # actor-lifetime
async-wait async-waitall async-waitany
- exec-basic)
+ exec-basic exec-async exec-remote)
set(tesh_files ${tesh_files} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.tesh)
set(examples_src ${examples_src} ${CMAKE_CURRENT_SOURCE_DIR}/${example}/${example}.py)
--- /dev/null
+# Copyright (c) 2018-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 *
+
+
+class Waiter:
+ """ This actor simply waits for its task completion after starting it. That's exactly equivalent to synchronous execution. """
+
+ def __call__(self):
+ computation_amount = this_actor.get_host().speed
+ this_actor.info("Execute {:.0f} flops, should take 1 second.".format(computation_amount))
+ activity = this_actor.exec_init(computation_amount)
+ activity.start()
+ activity.wait()
+
+ this_actor.info("Goodbye now!")
+
+
+class Monitor:
+ """This actor tests the ongoing execution until its completion, and don't wait before it's terminated."""
+
+ def __call__(self):
+ computation_amount = this_actor.get_host().speed
+ this_actor.info("Execute {:.0f} flops, should take 1 second.".format(computation_amount))
+ activity = this_actor.exec_init(computation_amount).start()
+
+ while not activity.test():
+ this_actor.info("Remaining amount of flops: {:.0f} ({:.0f}%)".format(
+ activity.remaining, 100 * activity.remaining_ratio))
+ this_actor.sleep_for(0.3)
+ activity.wait()
+
+ this_actor.info("Goodbye now!")
+
+
+class Canceller:
+ """This actor cancels the ongoing execution after a while."""
+
+ def __call__(self):
+ computation_amount = this_actor.get_host().speed
+ this_actor.info("Execute {:.0f} flops, should take 1 second.".format(computation_amount))
+ activity = this_actor.exec_init(computation_amount).start()
+
+ this_actor.sleep_for(0.5)
+ this_actor.info("I changed my mind, cancel!")
+ activity.cancel()
+
+ this_actor.info("Goodbye now!")
+
+
+if __name__ == '__main__':
+ e = Engine(sys.argv)
+
+ e.load_platform(sys.argv[1])
+
+ Actor.create("wait", Host.by_name("Fafard"), Waiter())
+ Actor.create("monitor", Host.by_name("Ginette"), Monitor())
+ Actor.create("cancel", Host.by_name("Boivin"), Canceller())
+
+ e.run()
--- /dev/null
+#!/usr/bin/env tesh
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${srcdir:=.}/exec-async.py ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [ 0.000000] (1:wait@Fafard) Execute 76296000 flops, should take 1 second.
+> [ 0.000000] (2:monitor@Ginette) Execute 48492000 flops, should take 1 second.
+> [ 0.000000] (3:cancel@Boivin) Execute 98095000 flops, should take 1 second.
+> [ 0.000000] (2:monitor@Ginette) Remaining amount of flops: 48492000 (100%)
+> [ 0.300000] (2:monitor@Ginette) Remaining amount of flops: 33944400 (70%)
+> [ 0.500000] (3:cancel@Boivin) I changed my mind, cancel!
+> [ 0.500000] (3:cancel@Boivin) Goodbye now!
+> [ 0.600000] (2:monitor@Ginette) Remaining amount of flops: 19396800 (40%)
+> [ 0.900000] (2:monitor@Ginette) Remaining amount of flops: 4849200 (10%)
+> [ 1.000000] (1:wait@Fafard) Goodbye now!
+> [ 1.200000] (2:monitor@Ginette) Goodbye now!
--- /dev/null
+# Copyright (c) 2018-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 *
+
+
+class Wizard:
+ def __call__(self):
+
+ fafard = Host.by_name("Fafard")
+ ginette = Host.by_name("Ginette")
+ boivin = Host.by_name("Boivin")
+
+ this_actor.info("I'm a wizard! I can run a task on the Ginette host from the Fafard one! Look!")
+ exec = this_actor.exec_init(48.492e6)
+ exec.host = ginette
+ exec.start()
+ this_actor.info("It started. Running 48.492Mf takes exactly one second on Ginette (but not on Fafard).")
+
+ this_actor.sleep_for(0.1)
+ this_actor.info("Loads in flops/s: Boivin={:.0f}; Fafard={:.0f}; Ginette={:.0f}".format(boivin.load, fafard.load,
+ ginette.load))
+ exec.wait()
+ this_actor.info("Done!")
+
+ this_actor.info("And now, harder. Start a remote task on Ginette and move it to Boivin after 0.5 sec")
+ exec = this_actor.exec_init(73293500)
+ exec.host = ginette
+ exec.start()
+
+ this_actor.sleep_for(0.5)
+ this_actor.info(
+ "Loads before the move: Boivin={:.0f}; Fafard={:.0f}; Ginette={:.0f}".format(
+ boivin.load,
+ fafard.load,
+ ginette.load))
+
+ exec.host = boivin
+
+ this_actor.sleep_for(0.1)
+ this_actor.info(
+ "Loads after the move: Boivin={:.0f}; Fafard={:.0f}; Ginette={:.0f}".format(
+ boivin.load,
+ fafard.load,
+ ginette.load))
+
+ exec.wait()
+ this_actor.info("Done!")
+
+
+if __name__ == '__main__':
+ e = Engine(sys.argv)
+
+ e.load_platform(sys.argv[1])
+
+ Actor.create("test", Host.by_name("Fafard"), Wizard())
+
+ e.run()
--- /dev/null
+#!/usr/bin/env tesh
+
+$ ${pythoncmd:=python3} ${PYTHON_TOOL_OPTIONS:=} ${bindir:=.}/exec-remote.py ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [ 0.000000] (1:test@Fafard) I'm a wizard! I can run a task on the Ginette host from the Fafard one! Look!
+> [ 0.000000] (1:test@Fafard) It started. Running 48.492Mf takes exactly one second on Ginette (but not on Fafard).
+> [ 0.100000] (1:test@Fafard) Loads in flops/s: Boivin=0; Fafard=0; Ginette=48492000
+> [ 1.000000] (1:test@Fafard) Done!
+> [ 1.000000] (1:test@Fafard) And now, harder. Start a remote task on Ginette and move it to Boivin after 0.5 sec
+> [ 1.500000] (1:test@Fafard) Loads before the move: Boivin=0; Fafard=0; Ginette=48492000
+> [ 1.600000] (1:test@Fafard) Loads after the move: Boivin=98095000; Fafard=0; Ginette=0
+> [ 2.000000] (1:test@Fafard) Done!
- **Asynchronous execution:**
You can start asynchronous executions, just like you would fire
background threads.
- |br| `examples/s4u/exec-async/s4u-exec-async.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/exec-async/s4u-exec-async.cpp>`_
+
+ - |cpp| `examples/s4u/exec-async/s4u-exec-async.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/exec-async/s4u-exec-async.cpp>`_
+ - |py| `examples/python/exec-async/exec-async.py <https://framagit.org/simgrid/simgrid/tree/master/examples/python/exec-async/exec-async.py>`_
- **Remote execution:**
You can start executions on remote hosts, or even change the host
on which they occur during their execution.
- |br| `examples/s4u/exec-remote/s4u-exec-remote.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/exec-remote/s4u-exec-remote.cpp>`_
+
+ - |cpp| `examples/s4u/exec-remote/s4u-exec-remote.cpp <https://framagit.org/simgrid/simgrid/tree/master/examples/s4u/exec-remote/s4u-exec-remote.cpp>`_
+ - |py| `examples/python/exec-remote/exec-remote.py <https://framagit.org/simgrid/simgrid/tree/master/examples/python/exec-remote/exec-remote.py>`_
- **Parallel executions:**
These objects are convenient abstractions of parallel
XBT_PUBLIC void intrusive_ptr_release(Exec* e);
XBT_PUBLIC void intrusive_ptr_add_ref(Exec* e);
class ExecSeq;
+typedef boost::intrusive_ptr<ExecSeq> ExecSeqPtr;
class ExecPar;
+typedef boost::intrusive_ptr<ExecPar> ExecParPtr;
class Host;
#include <simgrid/Exception.hpp>
#include <simgrid/s4u/Actor.hpp>
#include <simgrid/s4u/Comm.hpp>
+#include <simgrid/s4u/Exec.hpp>
#include <simgrid/s4u/Engine.hpp>
#include <simgrid/s4u/Host.hpp>
#include <simgrid/s4u/Mailbox.hpp>
"Block the current actor, computing the given amount of flops at the given priority, see :cpp:func:`void "
"simgrid::s4u::this_actor::execute(double, double)`",
py::arg("flops"), py::arg("priority") = 1);
+ m2.def("exec_init", [](double flops){return simgrid::s4u::this_actor::exec_init(flops);});
m2.def("get_host", &simgrid::s4u::this_actor::get_host, "Retrieves host on which the current actor is located");
m2.def("migrate", &simgrid::s4u::this_actor::migrate, "Moves the current actor to another host, see :cpp:func:`void simgrid::s4u::this_actor::migrate()`",
py::arg("dest"));
.def_property_readonly("name", [](Host* self) -> const std::string {
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), see :cpp:func:`simgrid::s4u::Host::get_load()`")
.def_property_readonly("speed", &Host::get_speed,
"The peak computing speed in flops/s at the current pstate, taking the external load into account, see :cpp:func:`simgrid::s4u::Host::get_speed()`");
"wait_any", [](std::vector<simgrid::s4u::CommPtr>* comms) { return simgrid::s4u::Comm::wait_any(comms); },
"Block until the completion of any communication in the list and return the index of the terminated one, see "
":cpp:func:`simgrid::s4u::Comm::wait_any()`");
+ py::class_<simgrid::s4u::Exec, simgrid::s4u::ExecPtr>(m, "Exec", "Execution, see :ref:`class s4u::Exec <API_s4u_Exec>`")
+ .def_property_readonly("remaining", [](simgrid::s4u::ExecPtr self) { return self->get_remaining(); },
+ "Amount of flops that remain to be computed until completion, see :cpp:func:`simgrid::s4u::Exec::get_remaining()`")
+ .def_property_readonly("remaining_ratio", [](simgrid::s4u::ExecPtr self) { return self->get_remaining_ratio(); },
+ "Amount of work remaining until completion from 0 (completely done) to 1 (nothing done yet). See :cpp:func:`simgrid::s4u::Exec::get_remaining_ratio()`")
+ .def_property("host",
+ [](simgrid::s4u::ExecPtr self) {
+ simgrid::s4u::ExecSeqPtr seq = boost::dynamic_pointer_cast<simgrid::s4u::ExecSeq>(self);
+ if (seq != nullptr)
+ return seq->get_host();
+ xbt_throw_unimplemented(__FILE__, __LINE__, "host of parallel executions is not implemented in python yet.");
+ },
+ [](simgrid::s4u::ExecPtr self, simgrid::s4u::Host* host) { self->set_host(host); },
+ "Host on which this execution runs. See :cpp:func:`simgrid::s4u::ExecSeq::get_host()`")
+ .def("test", [](simgrid::s4u::ExecPtr self) { return self->test(); },
+ "Test whether the execution is terminated, see :cpp:func:`simgrid::s4u::Exec::test()`")
+ .def("cancel", [](simgrid::s4u::ExecPtr self) { self->cancel(); },
+ "Cancel that execution, see :cpp:func:`simgrid::s4u::Exec::cancel()`")
+ .def("start", [](simgrid::s4u::ExecPtr self) { return self->start(); },
+ "Start that execution, see :cpp:func:`simgrid::s4u::Exec::start()`")
+ .def("wait", [](simgrid::s4u::ExecPtr self) { return self->wait(); },
+ "Block until the completion of that execution, see :cpp:func:`simgrid::s4u::Exec::wait()`");
/* Class Actor */
py::class_<simgrid::s4u::Actor, ActorPtr>(m, "Actor",