Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge remote-tracking branch 'upstream/master' into issue95
authorBruno Donassolo <bruno.donassolo@inria.fr>
Wed, 5 Jan 2022 14:41:42 +0000 (15:41 +0100)
committerBruno Donassolo <bruno.donassolo@inria.fr>
Wed, 5 Jan 2022 14:41:42 +0000 (15:41 +0100)
.gitignore
ChangeLog
MANIFEST.in
examples/cpp/CMakeLists.txt
examples/cpp/exec-ptask-multicore-latency/s4u-exec-ptask-multicore-latency.cpp [new file with mode: 0644]
examples/cpp/exec-ptask-multicore-latency/s4u-exec-ptask-multicore-latency.tesh [new file with mode: 0644]
examples/cpp/exec-ptask-multicore/s4u-exec-ptask-multicore.cpp
examples/cpp/exec-ptask-multicore/s4u-exec-ptask-multicore.tesh
src/kernel/resource/CpuImpl.cpp
src/surf/ptask_L07.cpp
src/surf/ptask_L07.hpp

index d17cdad..5a680b9 100644 (file)
@@ -206,6 +206,7 @@ examples/cpp/exec-dvfs/s4u-exec-dvfs
 examples/cpp/exec-failure/s4u-exec-failure
 examples/cpp/exec-ptask/s4u-exec-ptask
 examples/cpp/exec-ptask-multicore/s4u-exec-ptask-multicore
+examples/cpp/exec-ptask-multicore-latency/s4u-exec-ptask-multicore-latency
 examples/cpp/exec-remote/s4u-exec-remote
 examples/cpp/exec-unassigned/s4u-exec-unassigned
 examples/cpp/exec-waitany/s4u-exec-waitany
index e4e7958..52bbec7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -44,8 +44,9 @@ Python:
 
 Fixed bugs (FG#.. -> FramaGit bugs; FG!.. -> FG merge requests)
  (FG: issues on Framagit; GF: issues on GForge; GH: issues on GitHub)
+ - FG#95: Wrong computation time for multicore execution after pstate change
+ - FG#97: Wrong computation time for ptask+multicore+pstates
  - FG#99: Weird segfault when not sealing an host
-
 ----------------------------------------------------------------------------
 
 SimGrid (3.29) October 7. 2021
index 4ad8115..29c5e33 100644 (file)
@@ -264,6 +264,8 @@ include examples/cpp/exec-dvfs/s4u-exec-dvfs.cpp
 include examples/cpp/exec-dvfs/s4u-exec-dvfs.tesh
 include examples/cpp/exec-failure/s4u-exec-failure.cpp
 include examples/cpp/exec-failure/s4u-exec-failure.tesh
+include examples/cpp/exec-ptask-multicore-latency/s4u-exec-ptask-multicore-latency.cpp
+include examples/cpp/exec-ptask-multicore-latency/s4u-exec-ptask-multicore-latency.tesh
 include examples/cpp/exec-ptask-multicore/s4u-exec-ptask-multicore.cpp
 include examples/cpp/exec-ptask-multicore/s4u-exec-ptask-multicore.tesh
 include examples/cpp/exec-ptask/s4u-exec-ptask.cpp
index 36fb059..00e51b3 100644 (file)
@@ -106,7 +106,7 @@ foreach (example actor-create actor-daemon actor-exiting actor-join actor-kill
                  energy-exec energy-boot energy-link energy-vm energy-exec-ptask energy-wifi
                  engine-filtering engine-run-partial
                  exec-async exec-basic exec-dvfs exec-remote exec-waitany exec-waitfor exec-dependent exec-unassigned
-                 exec-ptask-multicore exec-cpu-nonlinear exec-cpu-factors exec-failure
+                 exec-ptask-multicore exec-ptask-multicore-latency exec-cpu-nonlinear exec-cpu-factors exec-failure
                  maestro-set
                  mc-bugged1 mc-bugged1-liveness mc-bugged2 mc-bugged2-liveness mc-centralized-mutex mc-electric-fence mc-failing-assert
                  network-ns3 network-ns3-wifi network-wifi
diff --git a/examples/cpp/exec-ptask-multicore-latency/s4u-exec-ptask-multicore-latency.cpp b/examples/cpp/exec-ptask-multicore-latency/s4u-exec-ptask-multicore-latency.cpp
new file mode 100644 (file)
index 0000000..42797f1
--- /dev/null
@@ -0,0 +1,70 @@
+/* Copyright (c) 2017-2021. 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. */
+
+#include <simgrid/s4u.hpp>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_ptask_multicore, "Messages specific for this s4u example");
+
+namespace sg4 = simgrid::s4u;
+
+static void runner()
+{
+  auto e = sg4::Engine::get_instance();
+  std::vector<double> comp(2, 1e9);
+  std::vector<double> comm(4, 0.0);
+  // Different hosts.
+  std::vector<sg4::Host*> hosts_diff = {e->host_by_name("MyHost1"), e->host_by_name("MyHost2")};
+  double start_time                  = sg4::Engine::get_clock();
+  sg4::this_actor::parallel_execute(hosts_diff, comp, comm);
+  XBT_INFO("Computed 2-core activity on two different hosts. Took %g s", e->get_clock() - start_time);
+
+  // Same host, multicore.
+  std::vector<sg4::Host*> multicore_host = {e->host_by_name("MyHost1"), e->host_by_name("MyHost1")};
+  start_time                             = sg4::Engine::get_clock();
+  sg4::this_actor::parallel_execute(multicore_host, comp, comm);
+  XBT_INFO("Computed 2-core activity on one 4-core host. Took %g s", e->get_clock() - start_time);
+
+  // Same host, using too many cores
+  std::vector<double> comp6(6, 1e9);
+  std::vector<double> comm6(36, 0.0);
+  std::vector<sg4::Host*> multicore_overload(6, e->host_by_name("MyHost1"));
+  start_time = sg4::Engine::get_clock();
+  sg4::this_actor::parallel_execute(multicore_overload, comp6, comm6);
+  XBT_INFO("Computed 6-core activity on a 4-core host. Took %g s", e->get_clock() - start_time);
+
+  // Same host, adding some communication
+  std::vector<double> comm2 = {0, 1E7, 1E7, 0};
+  start_time = sg4::Engine::get_clock();
+  sg4::this_actor::parallel_execute(multicore_host, comp, comm2);
+  XBT_INFO("Computed 2-core activity on a 4-core host with some communication. Took %g s", e->get_clock() - start_time);
+
+  // See if the multicore execution continues to work after changing pstate
+  XBT_INFO("Switching machine multicore to pstate 1.");
+  e->host_by_name("MyHost1")->set_pstate(1);
+  XBT_INFO("Switching back to pstate 0.");
+  e->host_by_name("MyHost1")->set_pstate(0);
+
+  start_time                             = sg4::Engine::get_clock();
+  sg4::this_actor::parallel_execute(multicore_host, comp, comm);
+  XBT_INFO("Computed 2-core activity on one 4-core host. Took %g s", e->get_clock() - start_time);
+
+  start_time                  = sg4::Engine::get_clock();
+  sg4::this_actor::parallel_execute(hosts_diff, comp, comm);
+  XBT_INFO("Computed 2-core activity on two different hosts. Took %g s", e->get_clock() - start_time);
+}
+
+int main(int argc, char* argv[])
+{
+  sg4::Engine e(&argc, argv);
+
+  xbt_assert(argc == 2, "Usage: %s <platform file>", argv[0]);
+
+  e.load_platform(argv[1]);
+  sg4::Actor::create("test", sg4::Host::by_name("MyHost1"), runner);
+
+  e.run();
+  XBT_INFO("Simulation done.");
+  return 0;
+}
diff --git a/examples/cpp/exec-ptask-multicore-latency/s4u-exec-ptask-multicore-latency.tesh b/examples/cpp/exec-ptask-multicore-latency/s4u-exec-ptask-multicore-latency.tesh
new file mode 100644 (file)
index 0000000..7d2c2e9
--- /dev/null
@@ -0,0 +1,14 @@
+#!/usr/bin/env tesh
+
+$ ${bindir:=.}/s4u-exec-ptask-multicore-latency ${platfdir}/energy_cluster.xml --cfg=host/model:ptask_L07 --log=no_loc "--log=root.fmt:[%10.6r]%e%m%n"
+> [  0.000000] Configuration change: Set 'host/model' to 'ptask_L07'
+> [  0.000000] Switching to the L07 model to handle parallel tasks.
+> [ 10.000000] Computed 2-core activity on two different hosts. Took 10 s
+> [ 20.000000] Computed 2-core activity on one 4-core host. Took 10 s
+> [ 35.000000] Computed 6-core activity on a 4-core host. Took 15 s
+> [ 45.000600] Computed 2-core activity on a 4-core host with some communication. Took 10.0006 s
+> [ 45.000600] Switching machine multicore to pstate 1.
+> [ 45.000600] Switching back to pstate 0.
+> [ 55.000600] Computed 2-core activity on one 4-core host. Took 10 s
+> [ 65.000600] Computed 2-core activity on two different hosts. Took 10 s
+> [ 65.000600] Simulation done.
\ No newline at end of file
index 1aeceb7..dd3fcbf 100644 (file)
@@ -24,13 +24,13 @@ static void runner()
   std::vector<sg4::Host*> monocore_hosts = {e->host_by_name("MyHost2"), e->host_by_name("MyHost2")};
   start_time                             = sg4::Engine::get_clock();
   sg4::this_actor::parallel_execute(monocore_hosts, comp, comm);
-  XBT_INFO("Computed 2-core activity one 1-core host. Took %g s", e->get_clock() - start_time);
+  XBT_INFO("Computed 2-core activity a 1-core host. Took %g s", e->get_clock() - start_time);
 
   // Same host, multicore.
   std::vector<sg4::Host*> multicore_host = {e->host_by_name("MyHost1"), e->host_by_name("MyHost1")};
   start_time                             = sg4::Engine::get_clock();
   sg4::this_actor::parallel_execute(multicore_host, comp, comm);
-  XBT_INFO("Computed 2-core activity on one 2-core host. Took %g s", e->get_clock() - start_time);
+  XBT_INFO("Computed 2-core activity on a 4-core host. Took %g s", e->get_clock() - start_time);
 
   // Same host, using too many cores
   std::vector<double> comp6(6, 1e9);
@@ -38,7 +38,47 @@ static void runner()
   std::vector<sg4::Host*> multicore_overload(6, e->host_by_name("MyHost1"));
   start_time = sg4::Engine::get_clock();
   sg4::this_actor::parallel_execute(multicore_overload, comp6, comm6);
-  XBT_INFO("Computed 6-core activity of a 4-core host. Took %g s", e->get_clock() - start_time);
+  XBT_INFO("Computed 6-core activity on a 4-core host. Took %g s", e->get_clock() - start_time);
+
+  // Same host, adding some communication
+  std::vector<double> comm2 = {0, 1E7, 1E7, 0};
+  start_time                = sg4::Engine::get_clock();
+  sg4::this_actor::parallel_execute(multicore_host, comp, comm2);
+  XBT_INFO("Computed 2-core activity on a 4-core host with some communication. Took %g s", e->get_clock() - start_time);
+
+  // See if the multicore execution continues to work after changing pstate
+  XBT_INFO("Switching machine multicore to pstate 1.");
+  e->host_by_name("MyHost1")->set_pstate(1);
+  XBT_INFO("Switching back to pstate 0.");
+  e->host_by_name("MyHost1")->set_pstate(0);
+
+  start_time = sg4::Engine::get_clock();
+  sg4::this_actor::parallel_execute(multicore_host, comp, comm);
+  XBT_INFO("Computed 2-core activity on a 4-core host. Took %g s", e->get_clock() - start_time);
+
+  start_time = sg4::Engine::get_clock();
+  sg4::this_actor::parallel_execute(hosts_diff, comp, comm);
+  XBT_INFO("Computed 2-core activity on two different hosts. Took %g s", e->get_clock() - start_time);
+
+  // Add a background task and change ptask on the fly
+  auto MyHost1                          = e->host_by_name("MyHost1");
+  simgrid::s4u::ExecPtr background_task = MyHost1->exec_async(5e9);
+  XBT_INFO("Start a 1-core background task on the 4-core host.");
+
+  start_time = sg4::Engine::get_clock();
+  sg4::this_actor::parallel_execute(multicore_host, comp, comm);
+  XBT_INFO("Computed 2-core activity on the 4-core host. Took %g s", e->get_clock() - start_time);
+  XBT_INFO("Remaining amount of work for the background task: %.0f%%",
+           100 * background_task->get_remaining_ratio());
+
+  XBT_INFO("Switching to pstate 1 while background task is still running.");
+  MyHost1->set_pstate(1);
+  start_time = sg4::Engine::get_clock();
+  sg4::this_actor::parallel_execute(multicore_host, comp, comm);
+  XBT_INFO("Computed again the same 2-core activity on it. Took %g s", e->get_clock() - start_time);
+
+  background_task->wait();
+  XBT_INFO("The background task has ended.");
 }
 
 int main(int argc, char* argv[])
index 2dadba2..889ff1b 100644 (file)
@@ -4,7 +4,18 @@ $ ${bindir:=.}/s4u-exec-ptask-multicore ${platfdir}/energy_platform.xml --cfg=ho
 > [  0.000000] Configuration change: Set 'host/model' to 'ptask_L07'
 > [  0.000000] Switching to the L07 model to handle parallel tasks.
 > [ 10.000000] Computed 2-core activity on two different hosts. Took 10 s
-> [ 30.000000] Computed 2-core activity one 1-core host. Took 20 s
-> [ 40.000000] Computed 2-core activity on one 2-core host. Took 10 s
-> [ 55.000000] Computed 6-core activity of a 4-core host. Took 15 s
-> [ 55.000000] Simulation done.
\ No newline at end of file
+> [ 30.000000] Computed 2-core activity a 1-core host. Took 20 s
+> [ 40.000000] Computed 2-core activity on a 4-core host. Took 10 s
+> [ 55.000000] Computed 6-core activity on a 4-core host. Took 15 s
+> [ 65.000000] Computed 2-core activity on a 4-core host with some communication. Took 10 s
+> [ 65.000000] Switching machine multicore to pstate 1.
+> [ 65.000000] Switching back to pstate 0.
+> [ 75.000000] Computed 2-core activity on a 4-core host. Took 10 s
+> [ 85.000000] Computed 2-core activity on two different hosts. Took 10 s
+> [ 85.000000] Start a 1-core background task on the 4-core host.
+> [ 95.000000] Computed 2-core activity on the 4-core host. Took 10 s
+> [ 95.000000] Remaining amount of work for the background task: 80%
+> [ 95.000000] Switching to pstate 1 while background task is still running.
+> [115.000000] Computed again the same 2-core activity on it. Took 20 s
+> [175.000000] The background task has ended.
+> [175.000000] Simulation done.
index 8bc77b8..5a64cb5 100644 (file)
@@ -67,8 +67,8 @@ void CpuImpl::reset_vcpu(CpuImpl* that)
 CpuImpl* CpuImpl::set_pstate(unsigned long pstate_index)
 {
   xbt_assert(
-      pstate_index <= speed_per_pstate_.size(),
-      "Invalid parameters for CPU %s (pstate %lu > length of pstates %d). Please fix your platform file, or your "
+      pstate_index < speed_per_pstate_.size(),
+      "Invalid parameters for CPU %s (pstate %lu >= length of pstates %d). Please fix your platform file, or your "
       "call to change the pstate.",
       get_cname(), pstate_index, static_cast<int>(speed_per_pstate_.size()));
 
index bd0f778..b6c4e5d 100644 (file)
@@ -191,16 +191,10 @@ L07Action::L07Action(Model* model, const std::vector<s4u::Host*>& host_list, con
 
   /* Expand it for the CPUs even if there is nothing to compute, to make sure that it gets expended even if there is no
    * communication either */
-  double bound = std::numeric_limits<double>::max();
   for (size_t i = 0; i < host_list.size(); i++) {
     model->get_maxmin_system()->expand(host_list[i]->get_cpu()->get_constraint(), get_variable(),
                                        (flops_amount == nullptr ? 0.0 : flops_amount[i]));
-    if (flops_amount && flops_amount[i] > 0)
-      bound = std::min(bound, host_list[i]->get_cpu()->get_speed(1.0) * host_list[i]->get_cpu()->get_speed_ratio() /
-                                  flops_amount[i]);
   }
-  if (bound < std::numeric_limits<double>::max())
-    model->get_maxmin_system()->update_variable_bound(get_variable(), bound);
 
   if (bytes_amount != nullptr) {
     for (size_t k = 0; k < host_list.size() * host_list.size(); k++) {
@@ -218,6 +212,8 @@ L07Action::L07Action(Model* model, const std::vector<s4u::Host*>& host_list, con
     this->set_cost(1.0);
     this->set_remains(0.0);
   }
+  /* finally calculate the initial bound value */
+  updateBound();
 }
 
 Action* NetworkL07Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate)
@@ -284,11 +280,11 @@ void CpuL07::on_speed_change()
 {
   const lmm::Element* elem = nullptr;
 
-  get_model()->get_maxmin_system()->update_constraint_bound(get_constraint(), speed_.peak * speed_.scale);
-  while (const auto* var = get_constraint()->get_variable(&elem)) {
-    const Action* action = var->get_id();
+  get_model()->get_maxmin_system()->update_constraint_bound(get_constraint(), get_core_count() * speed_.peak * speed_.scale);
 
-    get_model()->get_maxmin_system()->update_variable_bound(action->get_variable(), speed_.scale * speed_.peak);
+  while (const auto* var = get_constraint()->get_variable(&elem)) {
+    auto* action = static_cast<L07Action*>(var->get_id());
+    action->updateBound();
   }
 
   CpuImpl::on_speed_change();
@@ -378,32 +374,63 @@ L07Action::~L07Action()
   }
 }
 
-void L07Action::updateBound()
+double L07Action::calculateNetworkBound()
 {
   double lat_current = 0.0;
+  double lat_bound   = std::numeric_limits<double>::max();
 
   size_t host_count = hostList_.size();
 
-  if (communicationAmount_ != nullptr) {
-    for (size_t i = 0; i < host_count; i++) {
-      for (size_t j = 0; j < host_count; j++) {
-        if (communicationAmount_[i * host_count + j] > 0) {
-          double lat = 0.0;
-          std::vector<LinkImpl*> route;
-          hostList_.at(i)->route_to(hostList_.at(j), route, &lat);
+  if (communicationAmount_ == nullptr) {
+    return lat_bound;
+  }
 
-          lat_current = std::max(lat_current, lat * communicationAmount_[i * host_count + j]);
-        }
+  for (size_t i = 0; i < host_count; i++) {
+    for (size_t j = 0; j < host_count; j++) {
+      if (communicationAmount_[i * host_count + j] > 0) {
+        double lat = 0.0;
+        std::vector<LinkImpl*> route;
+        hostList_.at(i)->route_to(hostList_.at(j), route, &lat);
+
+        lat_current = std::max(lat_current, lat * communicationAmount_[i * host_count + j]);
       }
     }
   }
-  double lat_bound = NetworkModel::cfg_tcp_gamma / (2.0 * lat_current);
-  XBT_DEBUG("action (%p) : lat_bound = %g", this, lat_bound);
-  if ((latency_ <= 0.0) && is_running()) {
+  if (lat_current > 0) {
+    lat_bound = NetworkModel::cfg_tcp_gamma / (2.0 * lat_current);
+  }
+  return lat_bound;
+}
+
+double L07Action::calculateCpuBound()
+{
+  double cpu_bound = std::numeric_limits<double>::max();
+
+  if (computationAmount_ == nullptr) {
+    return cpu_bound;
+  }
+
+  for (size_t i = 0; i < hostList_.size(); i++) {
+    if (computationAmount_[i] > 0) {
+      cpu_bound = std::min(cpu_bound, hostList_[i]->get_cpu()->get_speed(1.0) *
+                                          hostList_[i]->get_cpu()->get_speed_ratio() / computationAmount_[i]);
+    }
+  }
+  return cpu_bound;
+}
+
+void L07Action::updateBound()
+{
+  double bound = std::min(calculateNetworkBound(), calculateCpuBound());
+
+  XBT_DEBUG("action (%p) : bound = %g", this, bound);
+
+  /* latency has been paid (or no latency), we can set the appropriate bound for multicore or network limit */
+  if ((bound < std::numeric_limits<double>::max()) && (latency_ <= 0.0)) {
     if (rate_ < 0)
-      get_model()->get_maxmin_system()->update_variable_bound(get_variable(), lat_bound);
+      get_model()->get_maxmin_system()->update_variable_bound(get_variable(), bound);
     else
-      get_model()->get_maxmin_system()->update_variable_bound(get_variable(), std::min(rate_, lat_bound));
+      get_model()->get_maxmin_system()->update_variable_bound(get_variable(), std::min(rate_, bound));
   }
 }
 
index 7187117..7e39862 100644 (file)
@@ -131,6 +131,21 @@ class L07Action : public CpuAction {
   friend CpuAction* HostL07Model::execute_parallel(const std::vector<s4u::Host*>& host_list, const double* flops_amount,
                                                    const double* bytes_amount, double rate);
   friend Action* NetworkL07Model::communicate(s4u::Host* src, s4u::Host* dst, double size, double rate);
+  /**
+   * @brief Calculate the CPU bound for the parallel task
+   *
+   * The task is bounded by the slowest CPU running the ptask, considering the current pstate of each CPU.
+   * Return MAX_DOUBLE if ptask has no computation.
+   */
+  double calculateCpuBound();
+
+  /**
+   * @brief Calculate the network bound for the parallel task
+   *
+   * The network bound depends on the largest latency between the communication in the ptask.
+   * Return MAX_DOUBLE if latency is 0 (or ptask doesn't have any communication)
+   */
+  double calculateNetworkBound();
 
 public:
   L07Action() = delete;