From 9ec7c8ee1c9578ccc16b328c5d4992f641a4ead3 Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Tue, 14 Dec 2021 17:17:08 +0100 Subject: [PATCH] New: Engine::run_until(date) to split the simulation --- ChangeLog | 3 +++ include/simgrid/s4u/Engine.hpp | 5 +++- src/bindings/python/simgrid_python.cpp | 5 +++- src/kernel/EngineImpl.cpp | 34 +++++++++++++++++--------- src/kernel/EngineImpl.hpp | 4 +-- src/s4u/s4u_Engine.cpp | 6 ++++- src/smpi/internals/smpi_global.cpp | 2 +- 7 files changed, 41 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index bba357bdd4..c71fe262d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,9 @@ SimGrid (3.29.1) NOT RELEASED YET (v3.30 expected December 21. 2021, 15:59 UTC) +Engine: + - New function: run_until(date) allowing to split the simulation. + SMPI: - Dynamic costs for MPI operations: New API to allow users to dynamically change injected costs for MPI_Recv, MPI_Send and MPI_Isend operations. diff --git a/include/simgrid/s4u/Engine.hpp b/include/simgrid/s4u/Engine.hpp index 2a88c385a9..778bc84969 100644 --- a/include/simgrid/s4u/Engine.hpp +++ b/include/simgrid/s4u/Engine.hpp @@ -43,9 +43,12 @@ public: /** Finalize the default engine and all its dependencies */ void shutdown(); - /** Run the simulation after initialization */ + /** Run the simulation until its end */ void run() const; + /** Run the simulation until the specified date */ + void run_until(double max_date) const; + /** @brief Retrieve the simulation time (in seconds) */ static double get_clock(); /** @brief Retrieve the engine singleton */ diff --git a/src/bindings/python/simgrid_python.cpp b/src/bindings/python/simgrid_python.cpp index 7530f38fc9..3c0eb07064 100644 --- a/src/bindings/python/simgrid_python.cpp +++ b/src/bindings/python/simgrid_python.cpp @@ -139,7 +139,10 @@ PYBIND11_MODULE(simgrid, m) .def("get_all_hosts", &Engine::get_all_hosts, "Returns the list of all hosts found in the platform") .def("load_platform", &Engine::load_platform, "Load a platform file describing the environment") .def("load_deployment", &Engine::load_deployment, "Load a deployment file and launch the actors that it contains") - .def("run", &Engine::run, py::call_guard(), "Run the simulation") + .def("run", &Engine::run, py::call_guard(), "Run the simulation until its end") + .def("run_until", py::overload_cast(&Engine::run_until, py::const_), + py::call_guard(), "Run the simulation until the given date", + py::arg("max_date") = -1) .def( "register_actor", [](Engine* e, const std::string& name, py::object fun_or_class) { diff --git a/src/kernel/EngineImpl.cpp b/src/kernel/EngineImpl.cpp index b6269d0e46..6b08aa1852 100644 --- a/src/kernel/EngineImpl.cpp +++ b/src/kernel/EngineImpl.cpp @@ -672,7 +672,7 @@ double EngineImpl::solve(double max_date) const return time_delta; } -void EngineImpl::run() +void EngineImpl::run(double max_date) { if (MC_record_replay_is_active()) { mc::replay(MC_record_path()); @@ -680,7 +680,7 @@ void EngineImpl::run() return; } - double time = 0; + double elapsed_time = -1; do { XBT_DEBUG("New Schedule Round; size(queue)=%zu", actors_to_run_.size()); @@ -784,11 +784,21 @@ void EngineImpl::run() } } - time = timer::Timer::next(); - if (time > -1.0 || not actor_list_.empty()) { - XBT_DEBUG("Calling solve"); - time = solve(time); - XBT_DEBUG("Moving time ahead : %g", time); + // Compute the max_date of the next solve. + // It's either when a timer occurs, or when user-specified deadline is reached, or -1 if none is given + double next_time = timer::Timer::next(); + if (next_time < 0 && max_date > -1) { + next_time = max_date; + } else if (next_time > -1 && max_date > -1) { // either both <0, or both >0 + next_time = std::min(next_time, max_date); + } + + if (next_time > -1.0 || not actor_list_.empty()) { + XBT_DEBUG("Calling solve(%g) %g", next_time, NOW); + elapsed_time = solve(next_time); + XBT_DEBUG("Moving time ahead. NOW=%g; elapsed: %g", NOW, elapsed_time); + } else { + elapsed_time = -1; } /* Notify all the hosts that have failed */ @@ -807,9 +817,9 @@ void EngineImpl::run() /* Clean actors to destroy */ empty_trash(); - XBT_DEBUG("### time %f, #actors %zu, #to_run %zu", time, actor_list_.size(), actors_to_run_.size()); + XBT_DEBUG("### elapsed time %f, #actors %zu, #to_run %zu", elapsed_time, actor_list_.size(), actors_to_run_.size()); - if (time < 0. && actors_to_run_.empty() && not actor_list_.empty()) { + if (elapsed_time < 0. && actors_to_run_.empty() && not actor_list_.empty()) { if (actor_list_.size() <= daemons_.size()) { XBT_CRITICAL("Oops! Daemon actors cannot do any blocking activity (communications, synchronization, etc) " "once the simulation is over. Please fix your on_exit() functions."); @@ -823,9 +833,9 @@ void EngineImpl::run() maestro_->kill(kv.second); } } - } while (time > -1.0 || has_actors_to_run()); + } while ((elapsed_time > -1.0 && not double_equals(max_date, NOW, 0.00001)) || has_actors_to_run()); - if (not actor_list_.empty()) + if (not actor_list_.empty() && max_date < 0) THROW_IMPOSSIBLE; simgrid::s4u::Engine::on_simulation_end(); @@ -840,5 +850,5 @@ double EngineImpl::get_clock() void SIMIX_run() // XBT_ATTRIB_DEPRECATED_v332 { - simgrid::kernel::EngineImpl::get_instance()->run(); + simgrid::kernel::EngineImpl::get_instance()->run(-1); } diff --git a/src/kernel/EngineImpl.hpp b/src/kernel/EngineImpl.hpp index 3d34761759..ba9ad2cc39 100644 --- a/src/kernel/EngineImpl.hpp +++ b/src/kernel/EngineImpl.hpp @@ -202,8 +202,8 @@ public: */ double solve(double max_date) const; - /** @brief Run the main simulation loop. */ - void run(); + /** @brief Run the main simulation loop until the specified date (or infinitly if max_date is negative). */ + void run(double max_date); /** @brief Return the current time in milliseconds. */ static double get_clock(); diff --git a/src/s4u/s4u_Engine.cpp b/src/s4u/s4u_Engine.cpp index f4531dfd91..e824425168 100644 --- a/src/s4u/s4u_Engine.cpp +++ b/src/s4u/s4u_Engine.cpp @@ -316,6 +316,10 @@ std::vector Engine::get_filtered_actors(const std::functionrun(); + pimpl->run(max_date); } } diff --git a/src/smpi/internals/smpi_global.cpp b/src/smpi/internals/smpi_global.cpp index c26d0cb3e6..2a8d1889ae 100644 --- a/src/smpi/internals/smpi_global.cpp +++ b/src/smpi/internals/smpi_global.cpp @@ -578,7 +578,7 @@ int smpi_main(const char* executable, int argc, char* argv[]) if (MC_is_active()) { MC_run(); } else { - engine.get_impl()->run(); + engine.get_impl()->run(-1); xbt_os_walltimer_stop(global_timer); simgrid::smpi::utils::print_time_analysis(xbt_os_timer_elapsed(global_timer)); -- 2.20.1