X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/cc74dae45a595ab9bf574d617fdc7ec749745e84..09fcf6b32a677469632d6a2aad754ab4e431c530:/src/bindings/python/simgrid_python.cpp diff --git a/src/bindings/python/simgrid_python.cpp b/src/bindings/python/simgrid_python.cpp index c431875445..97fa4d3302 100644 --- a/src/bindings/python/simgrid_python.cpp +++ b/src/bindings/python/simgrid_python.cpp @@ -12,6 +12,7 @@ #include "simgrid/kernel/routing/NetPoint.hpp" #include "simgrid/plugins/load.h" #include +#include #include #include #include @@ -34,6 +35,10 @@ #include namespace py = pybind11; +using simgrid::s4u::Activity; +using simgrid::s4u::ActivityPtr; +using simgrid::s4u::ActivitySet; +using simgrid::s4u::ActivitySetPtr; using simgrid::s4u::Actor; using simgrid::s4u::ActorPtr; using simgrid::s4u::Barrier; @@ -71,15 +76,6 @@ std::string get_simgrid_version() sg_version_get(&major, &minor, &patch); return simgrid::xbt::string_printf("%i.%i.%i", major, minor, patch); } - -/** @brief Wrap for mailbox::get_async */ -class PyGetAsync { - std::unique_ptr data = std::make_unique(); - -public: - PyObject** get() const { return data.get(); } -}; - } // namespace PYBIND11_DECLARE_HOLDER_TYPE(T, boost::intrusive_ptr) @@ -223,7 +219,8 @@ PYBIND11_MODULE(simgrid, m) } }); }, - "Registers the main function of an actor"); + "Registers the main function of an actor") + .def("set_log_control", [](Engine*, const std::string& settings) { xbt_log_control_set(settings.c_str()); }); /* Class Netzone */ py::class_> netzone( @@ -239,10 +236,17 @@ PYBIND11_MODULE(simgrid, m) .def_static("create_empty_zone", &simgrid::s4u::create_empty_zone, "Creates a zone of type Empty") .def_static("create_wifi_zone", &simgrid::s4u::create_wifi_zone, "Creates a zone of type Wi-Fi") .def("add_route", - py::overload_cast&, bool>(&simgrid::s4u::NetZone::add_route), - "Add a route between 2 netpoints") + [](simgrid::s4u::NetZone* self, simgrid::kernel::routing::NetPoint* src, + simgrid::kernel::routing::NetPoint* dst, simgrid::kernel::routing::NetPoint* gw_src, + simgrid::kernel::routing::NetPoint* gw_dst, const std::vector& links, + bool symmetrical) { + PyErr_WarnEx(PyExc_DeprecationWarning, // XBT_ATTRIB_DEPRECATED_v335. Once removed, uncomment the + // deprecation of the AddRoute function in C++ + "Please call add_route either from Host to Host or NetZone to NetZone. This call will be " + "removed after SimGrid v3.35.", + 1); + self->add_route(src, dst, gw_src, gw_dst, links, symmetrical); + }) .def("add_route", py::overload_cast&, bool>(&simgrid::s4u::NetZone::add_route), @@ -628,26 +632,17 @@ PYBIND11_MODULE(simgrid, m) "get", [](Mailbox* self) { return py::reinterpret_steal(self->get()); }, py::call_guard(), "Blocking data reception") .def( - "get_async", - [](Mailbox* self) -> std::tuple { - PyGetAsync wrap; - auto comm = self->get_async(wrap.get()); - return std::make_tuple(std::move(comm), std::move(wrap)); - }, + "get_async", [](Mailbox* self) -> CommPtr { return self->get_async(); }, py::call_guard(), "Non-blocking data reception. Use data.get() to get the python object after the communication has finished") .def("set_receiver", &Mailbox::set_receiver, py::call_guard(), "Sets the actor as permanent receiver"); - /* Class PyGetAsync */ - py::class_(m, "PyGetAsync", "Wrapper for async get communications") - .def(py::init<>()) - .def( - "get", [](const PyGetAsync* self) { return py::reinterpret_steal(*(self->get())); }, - "Get python object after async communication in receiver side"); + /* class Activity */ + py::class_(m, "Activity", "Activity. See the C++ documentation for details."); /* Class Comm */ - py::class_(m, "Comm", "Communication. See the C++ documentation for details.") + py::class_(m, "Comm", "Communication. See the C++ documentation for details.") .def_property_readonly("dst_data_size", &Comm::get_dst_data_size, py::call_guard(), "Retrieve the size of the received data.") .def_property_readonly("mailbox", &Comm::get_mailbox, py::call_guard(), @@ -684,6 +679,11 @@ PYBIND11_MODULE(simgrid, m) "Block until the completion of that communication, or raises TimeoutException after the specified timeout.") .def("wait_until", &Comm::wait_until, py::call_guard(), py::arg("time_limit"), "Block until the completion of that communication, or raises TimeoutException after the specified time.") + .def( + "get_payload", + [](const Comm* self) { return py::reinterpret_steal((PyObject*)self->get_payload()); }, + py::call_guard(), + "Retrieve the message's payload of a get_async. You cannot call this until after the comm termination.") .def("detach", py::overload_cast<>(&Comm::detach), py::return_value_policy::reference_internal, py::call_guard(), "Start the comm, and ignore its result. It can be completely forgotten after that.") @@ -696,37 +696,19 @@ PYBIND11_MODULE(simgrid, m) py::arg("to"), py::arg("simulated_size_in_bytes"), "Do a blocking communication between two arbitrary hosts.\n\nThis 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.") - .def_static("test_any", &Comm::test_any, py::call_guard(), py::arg("comms"), - "take a vector s4u::CommPtr and return the rank of the first finished one (or -1 if none is done)") - .def_static("wait_all", &Comm::wait_all, py::call_guard(), py::arg("comms"), - "Block until the completion of all communications in the list.") - .def_static("wait_all_for", &Comm::wait_all_for, py::call_guard(), py::arg("comms"), - py::arg("timeout"), - "Block until the completion of all communications in the list, or raises TimeoutException after " - "the specified timeout.") - .def_static("wait_any", &Comm::wait_any, py::call_guard(), py::arg("comms"), - "Block until the completion of any communication in the list and return the index of the " - "terminated one.") - .def_static("wait_any_for", &Comm::wait_any_for, py::call_guard(), py::arg("comms"), - py::arg("timeout"), - "Block until the completion of any communication in the list and return the index of the terminated " - "one, or -1 if a timeout occurred."); + "In particular, the actor does not have to be on one of the involved hosts."); /* Class Io */ - py::class_(m, "Io", "I/O activities. See the C++ documentation for details.") + py::class_(m, "Io", + "I/O activities. See the C++ documentation for details.") .def("test", &simgrid::s4u::Io::test, py::call_guard(), "Test whether the I/O is terminated.") .def("wait", &simgrid::s4u::Io::wait, py::call_guard(), - "Block until the completion of that I/O operation") - .def_static( - "wait_any_for", &simgrid::s4u::Io::wait_any_for, py::call_guard(), - "Block until the completion of any I/O in the list (or timeout) and return the index of the terminated one.") - .def_static("wait_any", &simgrid::s4u::Io::wait_any, py::call_guard(), - "Block until the completion of any I/O in the list and return the index of the terminated one."); + "Block until the completion of that I/O operation"); /* Class Exec */ - py::class_(m, "Exec", "Execution. See the C++ documentation for details.") + py::class_(m, "Exec", + "Execution. See the C++ documentation for details.") .def_property_readonly("remaining", &simgrid::s4u::Exec::get_remaining, py::call_guard(), "Amount of flops that remain to be computed until completion (read-only property).") .def_property_readonly("remaining_ratio", &simgrid::s4u::Exec::get_remaining_ratio, @@ -775,7 +757,8 @@ PYBIND11_MODULE(simgrid, m) py::class_(m, "Mutex", "A classical mutex, but blocking in the simulation world." "See the C++ documentation for details.") - .def(py::init<>(&Mutex::create), py::call_guard(), "Mutex constructor.") + .def(py::init<>(&Mutex::create), py::call_guard(), + "Mutex constructor (pass True as a parameter to get a recursive Mutex).", py::arg("recursive") = false) .def("lock", &Mutex::lock, py::call_guard(), "Block until the mutex is acquired.") .def("try_lock", &Mutex::try_lock, py::call_guard(), "Try to acquire the mutex. Return true if the mutex was acquired, false otherwise.") @@ -886,9 +869,14 @@ PYBIND11_MODULE(simgrid, m) }, "Add a callback called when each task ends.") .def_property_readonly("name", &Task::get_name, "The name of this task (read-only).") - .def_property_readonly("count", &Task::get_count, "The execution count of this task (read-only).") .def_property_readonly("successors", &Task::get_successors, "The successors of this task (read-only).") .def_property("amount", &Task::get_amount, &Task::set_amount, "The amount of work to do for this task.") + .def( + "get_count", [](const TaskPtr t) { return t->get_count("instance_0"); }, + "The execution count of this task instance_0.") + .def( + "get_count", [](const TaskPtr t, const std::string& instance) { return t->get_count(instance); }, + "The execution count of this task instance.") .def("enqueue_firings", py::overload_cast(&Task::enqueue_firings), py::call_guard(), py::arg("n"), "Enqueue firings for this task.") .def("add_successor", py::overload_cast(&Task::add_successor), py::call_guard(), @@ -946,4 +934,41 @@ PYBIND11_MODULE(simgrid, m) .def( "__repr__", [](const IoTaskPtr io) { return "IoTask(" + io->get_name() + ")"; }, "Textual representation of the IoTask"); + + /* Class ActivitySet */ + py::class_(m, "ActivitySet", "ActivitySet. See the C++ documentation for details.") + .def(py::init([](std::vector activities) { + auto* ret = new ActivitySet(); + for (auto a : activities) + ret->push(a); + return ActivitySetPtr(ret); + }), + "The constructor should take the parameters from the command line, as is ") + .def(py::init([]() { return ActivitySetPtr(new ActivitySet()); }), + "The constructor should take the parameters from the command line, as is ") + + .def("push", &ActivitySet::push, py::call_guard(), py::arg("activity"), + "Add an activity to the set") + .def("erase", &ActivitySet::erase, py::call_guard(), py::arg("activity"), + "Remove that activity from the set") + .def_property_readonly("size", &ActivitySet::size, "Count of activities in the set") + .def("empty", &ActivitySet::empty, "Returns whether the set is empty") + .def("has_failed_activities", &ActivitySet::has_failed_activities, + "Returns whether there is any failed activities") + .def("get_failed_activity", &ActivitySet::get_failed_activity, "Returns a failed activity from the set, or None") + + .def("wait_all_for", &ActivitySet::wait_all_for, py::call_guard(), py::arg("timeout"), + "Wait for the completion of all activities in the set, but not longer than the provided timeout") + .def("wait_all", &ActivitySet::wait_all, py::call_guard(), + "Wait for the completion of all activities in the set, endlessly") + .def("test_any", &ActivitySet::test_any, py::call_guard(), + "Returns the first terminated activity if any, or None if no activity is terminated") + .def("wait_any_for", &ActivitySet::wait_any_for, py::call_guard(), py::arg("timeout"), + "Wait for the completion of one activity in the set, but not longer than the provided timeout") + .def("wait_any", &ActivitySet::wait_any, py::call_guard(), + "Wait for the completion of one activity in the set, endlessly") + + .def( + "__repr__", [](const ActivitySetPtr as) { return "ActivitySet([...])"; }, + "Textual representation of the ActivitySet"); }