X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/fc76eac8d82e65ece481a2d104c34034c9934e14..14618dc3963308a371947b248cef842153acffc1:/examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp diff --git a/examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp b/examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp index c0502b76cb..40a9ad3057 100644 --- a/examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp +++ b/examples/cpp/dag-scheduling/s4u-dag-scheduling.cpp @@ -1,5 +1,4 @@ -/* Copyright (c) 2009-2022. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2009-2022. 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. */ @@ -11,36 +10,35 @@ #include XBT_LOG_NEW_DEFAULT_CATEGORY(dag_scheduling, "Logging specific to this example"); +namespace sg4 = simgrid::s4u; struct HostAttribute { /* Earliest time at which a host is ready to execute a task */ double available_at = 0.0; - simgrid::s4u::Exec* last_scheduled_task = nullptr; + sg4::Exec* last_scheduled_task = nullptr; }; -static double sg_host_get_available_at(const simgrid::s4u::Host* host) +static double sg_host_get_available_at(const sg4::Host* host) { - return static_cast(host->get_data())->available_at; + return host->get_data()->available_at; } -static void sg_host_set_available_at(simgrid::s4u::Host* host, double time) +static void sg_host_set_available_at(const sg4::Host* host, double time) { - auto* attr = static_cast(host->get_data()); - attr->available_at = time; + host->get_data()->available_at = time; } -static simgrid::s4u::Exec* sg_host_get_last_scheduled_task(const simgrid::s4u::Host* host) +static sg4::Exec* sg_host_get_last_scheduled_task(const sg4::Host* host) { - return static_cast(host->get_data())->last_scheduled_task; + return host->get_data()->last_scheduled_task; } -static void sg_host_set_last_scheduled_task(simgrid::s4u::Host* host, simgrid::s4u::ExecPtr task) +static void sg_host_set_last_scheduled_task(const sg4::Host* host, sg4::ExecPtr task) { - auto* attr = static_cast(host->get_data()); - attr->last_scheduled_task = task.get(); + host->get_data()->last_scheduled_task = task.get(); } -static bool dependency_exists(const simgrid::s4u::Exec* src, simgrid::s4u::Exec* dst) +static bool dependency_exists(const sg4::Exec* src, sg4::Exec* dst) { const auto& dependencies = src->get_dependencies(); const auto& successors = src->get_successors(); @@ -48,23 +46,23 @@ static bool dependency_exists(const simgrid::s4u::Exec* src, simgrid::s4u::Exec* dependencies.find(dst) != dependencies.end()); } -static std::vector get_ready_tasks(const std::vector& dax) +static std::vector get_ready_tasks(const std::vector& dax) { - std::vector ready_tasks; - std::map candidate_execs; + std::vector ready_tasks; + std::map candidate_execs; for (auto& a : dax) { - // Only loot at activity that have their dependencies solved but are not assigned + // Only look at activity that have their dependencies solved but are not assigned if (a->dependencies_solved() && not a->is_assigned()) { // if it is an exec, it's ready - auto* exec = dynamic_cast(a.get()); + auto* exec = dynamic_cast(a.get()); if (exec != nullptr) ready_tasks.push_back(exec); // if it a comm, we consider its successor as a candidate. If a candidate solves all its dependencies, // i.e., get all its input data, it's ready - const auto* comm = dynamic_cast(a.get()); + const auto* comm = dynamic_cast(a.get()); if (comm != nullptr) { - auto* next_exec = static_cast(comm->get_successors().front().get()); + auto* next_exec = static_cast(comm->get_successors().front().get()); candidate_execs[next_exec]++; if (next_exec->get_dependencies().size() == candidate_execs[next_exec]) ready_tasks.push_back(next_exec); @@ -75,7 +73,7 @@ static std::vector get_ready_tasks(const std::vector(parent.get()); + const auto* comm = dynamic_cast(parent.get()); if (comm != nullptr) { auto source = comm->get_source(); XBT_DEBUG("transfer from %s to %s", source->get_cname(), host->get_cname()); @@ -102,10 +100,10 @@ static double finish_on_at(const simgrid::s4u::ExecPtr task, const simgrid::s4u: } // We use the user data field to store the finish time of the predecessor of the comm, i.e., its potential start // time - data_available = *(static_cast(comm->get_data())) + redist_time; + data_available = *comm->get_data() + redist_time; } - const auto* exec = dynamic_cast(parent.get()); + const auto* exec = dynamic_cast(parent.get()); /* no transfer, control dependency */ if (exec != nullptr) { data_available = exec->get_finish_time(); @@ -122,9 +120,9 @@ static double finish_on_at(const simgrid::s4u::ExecPtr task, const simgrid::s4u: return result; } -static simgrid::s4u::Host* get_best_host(const simgrid::s4u::ExecPtr exec) +static sg4::Host* get_best_host(const sg4::ExecPtr exec) { - std::vector hosts = simgrid::s4u::Engine::get_instance()->get_all_hosts(); + std::vector hosts = sg4::Engine::get_instance()->get_all_hosts(); auto best_host = hosts.front(); double min_EFT = finish_on_at(exec, best_host); @@ -140,23 +138,38 @@ static simgrid::s4u::Host* get_best_host(const simgrid::s4u::ExecPtr exec) return best_host; } -int main(int argc, char** argv) +static void schedule_on(sg4::ExecPtr exec, sg4::Host* host) { - double min_finish_time = -1.0; - simgrid::s4u::Exec* selected_task = nullptr; - simgrid::s4u::Host* selected_host = nullptr; + exec->set_host(host); + // we can also set the destination of all the input comms of this exec + for (const auto& pred : exec->get_dependencies()) { + auto* comm = dynamic_cast(pred.get()); + if (comm != nullptr) { + comm->set_destination(host); + delete comm->get_data(); + } + } + // we can also set the source of all the output comms of this exec + for (const auto& succ : exec->get_successors()) { + auto* comm = dynamic_cast(succ.get()); + if (comm != nullptr) + comm->set_source(host); + } +} - simgrid::s4u::Engine e(&argc, argv); - std::set vetoed; +int main(int argc, char** argv) +{ + sg4::Engine e(&argc, argv); + std::set vetoed; e.track_vetoed_activities(&vetoed); - simgrid::s4u::Activity::on_completion_cb([](simgrid::s4u::Activity& activity) { + sg4::Activity::on_completion_cb([](sg4::Activity const& activity) { // when an Exec completes, we need to set the potential start time of all its ouput comms - const auto* exec = dynamic_cast(&activity); + const auto* exec = dynamic_cast(&activity); if (exec == nullptr) // Only Execs are concerned here return; for (const auto& succ : exec->get_successors()) { - auto* comm = dynamic_cast(succ.get()); + auto* comm = dynamic_cast(succ.get()); if (comm != nullptr) { auto* finish_time = new double(exec->get_finish_time()); // We use the user data field to store the finish time of the predecessor of the comm, i.e., its potential start @@ -176,18 +189,12 @@ int main(int argc, char** argv) hosts[i]->set_data(&host_attributes[i]); /* load the DAX file */ - std::vector dax = simgrid::s4u::create_DAG_from_DAX(argv[2]); + auto dax = sg4::create_DAG_from_DAX(argv[2]); /* Schedule the root first */ - auto* root = static_cast(dax.front().get()); + auto* root = static_cast(dax.front().get()); auto host = get_best_host(root); - root->set_host(host); - // we can also set the source of all the output comms of the root node - for (const auto& succ : root->get_successors()) { - auto* comm = dynamic_cast(succ.get()); - if (comm != nullptr) - comm->set_source(host); - } + schedule_on(root, host); e.run(); @@ -198,7 +205,6 @@ int main(int argc, char** argv) vetoed.clear(); if (ready_tasks.empty()) { - ready_tasks.clear(); /* there is no ready task, let advance the simulation */ e.run(); continue; @@ -207,6 +213,10 @@ int main(int argc, char** argv) * get the host that minimizes the completion time. * select the task that has the minimum completion time on its best host. */ + double min_finish_time = -1.0; + sg4::Exec* selected_task = nullptr; + sg4::Host* selected_host = nullptr; + for (auto task : ready_tasks) { XBT_DEBUG("%s is ready", task->get_cname()); host = get_best_host(task); @@ -219,21 +229,7 @@ int main(int argc, char** argv) } XBT_INFO("Schedule %s on %s", selected_task->get_cname(), selected_host->get_cname()); - selected_task->set_host(selected_host); - // we can also set the destination of all the input comms of the selected task - for (const auto& pred : selected_task->get_dependencies()) { - auto* comm = dynamic_cast(pred.get()); - if (comm != nullptr) { - comm->set_destination(selected_host); - delete static_cast(comm->get_data()); - } - } - // we can also set the source of all the output comms of the selected task - for (const auto& succ : selected_task->get_successors()) { - auto* comm = dynamic_cast(succ.get()); - if (comm != nullptr) - comm->set_source(selected_host); - } + schedule_on(selected_task, selected_host); /* * tasks can be executed concurrently when they can by default. @@ -245,8 +241,8 @@ int main(int argc, char** argv) */ auto last_scheduled_task = sg_host_get_last_scheduled_task(selected_host); - if (last_scheduled_task && (last_scheduled_task->get_state() != simgrid::s4u::Activity::State::FINISHED) && - (last_scheduled_task->get_state() != simgrid::s4u::Activity::State::FAILED) && + if (last_scheduled_task && (last_scheduled_task->get_state() != sg4::Activity::State::FINISHED) && + (last_scheduled_task->get_state() != sg4::Activity::State::FAILED) && not dependency_exists(sg_host_get_last_scheduled_task(selected_host), selected_task)) last_scheduled_task->add_successor(selected_task); @@ -254,8 +250,6 @@ int main(int argc, char** argv) sg_host_set_available_at(selected_host, min_finish_time); ready_tasks.clear(); - /* reset the min_finish_time for the next set of ready tasks */ - min_finish_time = -1.; e.run(); }