X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/39c935d6d5ee86d153f6f7e6a10d723ae7c57f6f..3dac5ff35d86983862226dd0ecf222c22f87b9d4:/src/bindings/python/simgrid_python.cpp diff --git a/src/bindings/python/simgrid_python.cpp b/src/bindings/python/simgrid_python.cpp index a31a5b68f7..ee852108dd 100644 --- a/src/bindings/python/simgrid_python.cpp +++ b/src/bindings/python/simgrid_python.cpp @@ -13,14 +13,33 @@ #pragma GCC diagnostic ignored "-Wunused-value" #endif -#include +#ifndef NDEBUG +/* Many tests are failing after pybind11 commit ad6bf5cd39ca64b4a9bf846b84b11c4c8df1c8e1 "Adding PyGILState_Check() in + * object_api<>::operator(). (#2919)". + * See https://github.com/pybind/pybind11/commit/ad6bf5cd39ca64b4a9bf846b84b11c4c8df1c8e1 + * + * The failing tests are mostly those with boost/raw/sysv contexts. As a workaround, define NDEBUG before pybind11 + * includes. + */ +#define NDEBUG +#define NDEBUG_LOCALLY_DEFINED +#endif + #include // Must come before our own stuff + +#include #include +#ifdef NDEBUG_LOCALLY_DEFINED +#undef NDEBUG_LOCALLY_DEFINED +#undef NDEBUG +#endif + #if defined(__GNUG__) #pragma GCC diagnostic pop #endif +#include "simgrid/kernel/routing/NetPoint.hpp" #include "src/kernel/context/Context.hpp" #include #include @@ -28,7 +47,9 @@ #include #include #include +#include #include +#include #include #include @@ -56,6 +77,14 @@ std::string get_simgrid_version() 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(); } +}; + /* Classes GilScopedAcquire and GilScopedRelease have the same purpose as pybind11::gil_scoped_acquire and * pybind11::gil_scoped_release. Refer to the manual of pybind11 for details: * https://pybind11.readthedocs.io/en/stable/advanced/misc.html#global-interpreter-lock-gil @@ -176,7 +205,6 @@ PYBIND11_MODULE(simgrid, m) params[i - 1] = py::cast(args[i]); py::object res = fun_or_class(*params); - /* If I was passed a class, I just built an instance, so I need to call it now */ if (py::isinstance(res)) res(); @@ -185,8 +213,7 @@ PYBIND11_MODULE(simgrid, m) py_context.reset(); if (ffk) { XBT_VERB("Actor killed"); - /* Forward that ForcefulKill exception */ - simgrid::ForcefulKillException::do_throw(); + simgrid::ForcefulKillException::do_throw(); // Forward that ForcefulKill exception } throw; } @@ -194,11 +221,29 @@ PYBIND11_MODULE(simgrid, m) }, "Registers the main function of an actor"); + /* Class Netzone */ + py::class_>(m, "NetZone", + "Networking Zones") + .def_static("create_full_zone", &simgrid::s4u::create_full_zone, "Creates a netzone of type FullZone") + .def("add_route", + py::overload_cast&, bool>(&simgrid::s4u::NetZone::add_route), + "Add a route between 2 netpoints") + .def("create_host", py::overload_cast(&simgrid::s4u::NetZone::create_host), + "Creates a host") + .def("create_split_duplex_link", + py::overload_cast(&simgrid::s4u::NetZone::create_split_duplex_link), + "Creates a split-duplex link") + .def("seal", &simgrid::s4u::NetZone::seal, "Seal this NetZone"); + /* Class Host */ py::class_>(m, "Host", "Simulated host") .def("by_name", &Host::by_name, "Retrieves a host from its name, or die") .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") + .def("seal", &Host::seal, "Seal this host") .def_property( "pstate", &Host::get_pstate, [](Host* h, int i) { @@ -222,6 +267,47 @@ PYBIND11_MODULE(simgrid, m) "The peak computing speed in flops/s at the current pstate, taking the external load into account. " "This is the max potential speed."); + /* Class NetPoint */ + py::class_>( + m, "NetPoint", "NetPoint object"); + + /* Class Link */ + py::class_> link(m, "Link", "Network link"); + link.def("set_latency", py::overload_cast(&simgrid::s4u::Link::set_latency), "Set the latency"); + link.def("set_latency", py::overload_cast(&simgrid::s4u::Link::set_latency), "Set the latency"); + link.def("set_sharing_policy", &simgrid::s4u::Link::set_sharing_policy, "Set sharing policy for this link"); + link.def("seal", &simgrid::s4u::Link::seal, "Seal this link"); + link.def_property_readonly( + "name", + [](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"); + py::enum_(link, "SharingPolicy") + .value("NONLINEAR", simgrid::s4u::Link::SharingPolicy::NONLINEAR) + .value("WIFI", simgrid::s4u::Link::SharingPolicy::WIFI) + .value("SPLITDUPLEX", simgrid::s4u::Link::SharingPolicy::SPLITDUPLEX) + .value("SHARED", simgrid::s4u::Link::SharingPolicy::SHARED) + .value("FATPIPE", simgrid::s4u::Link::SharingPolicy::FATPIPE) + .export_values(); + + /* Class LinkInRoute */ + py::class_ linkinroute(m, "LinkInRoute", "Abstraction to add link in routes"); + linkinroute.def(py::init()); + linkinroute.def(py::init()); + py::enum_(linkinroute, "Direction") + .value("UP", simgrid::s4u::LinkInRoute::Direction::UP) + .value("DOWN", simgrid::s4u::LinkInRoute::Direction::DOWN) + .value("NONE", simgrid::s4u::LinkInRoute::Direction::NONE) + .export_values(); + + /* Class Split-Duplex Link */ + py::class_>(m, "SplitDuplexLink", + "Network split-duplex link") + .def("get_link_up", &simgrid::s4u::SplitDuplexLink::get_link_up, "Get link direction up") + .def("get_link_down", &simgrid::s4u::SplitDuplexLink::get_link_down, "Get link direction down"); + /* Class Mailbox */ py::class_>(m, "Mailbox", "Mailbox") .def( @@ -256,12 +342,25 @@ PYBIND11_MODULE(simgrid, m) return data; }, py::call_guard(), "Blocking data reception") - .def("set_receiver", - [](Mailbox* self, ActorPtr actor) { - self->set_receiver(actor); - }, - py::call_guard(), - "Sets the actor as permanent receiver"); + .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)); + }, + py::call_guard(), + "Non-blocking data reception. Use data.get() to get the python object after the communication has finished") + .def( + "set_receiver", [](Mailbox* self, ActorPtr actor) { self->set_receiver(actor); }, + 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", [](PyGetAsync* self) { return py::reinterpret_steal(*(self->get())); }, + "Get python object after async communication in receiver side"); /* Class Comm */ py::class_(m, "Comm", "Communication") @@ -269,10 +368,14 @@ PYBIND11_MODULE(simgrid, m) "Test whether the communication is terminated.") .def("wait", &simgrid::s4u::Comm::wait, py::call_guard(), "Block until the completion of that communication.") - .def("wait_all", &simgrid::s4u::Comm::wait_all, py::call_guard(), - "Block until the completion of all communications in the list.") - .def("wait_any", &simgrid::s4u::Comm::wait_any, py::call_guard(), - "Block until the completion of any communication in the list and return the index of the terminated one."); + // use py::overload_cast for wait_all/wait_any, until the overload marked XBT_ATTRIB_DEPRECATED_v332 is removed + .def_static("wait_all", + py::overload_cast&>(&simgrid::s4u::Comm::wait_all), + py::call_guard(), "Block until the completion of all communications in the list.") + .def_static( + "wait_any", py::overload_cast&>(&simgrid::s4u::Comm::wait_any), + py::call_guard(), + "Block until the completion of any communication in the list and return the index of the terminated one."); /* Class Exec */ py::class_(m, "Exec", "Execution") @@ -318,8 +421,7 @@ PYBIND11_MODULE(simgrid, m) py_context.reset(); if (ffk) { XBT_VERB("Actor killed"); - /* Forward that ForcefulKill exception */ - simgrid::ForcefulKillException::do_throw(); + simgrid::ForcefulKillException::do_throw(); // Forward that ForcefulKill exception } throw; }