Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
allow to call s4u::Exec->setHost() after its start, to migrate it
authorMartin Quinson <martin.quinson@loria.fr>
Tue, 26 Dec 2017 16:49:37 +0000 (17:49 +0100)
committerMartin Quinson <martin.quinson@loria.fr>
Tue, 26 Dec 2017 16:50:20 +0000 (17:50 +0100)
ChangeLog
examples/s4u/exec-remote/s4u-exec-remote.cpp
examples/s4u/exec-remote/s4u-exec-remote.tesh
src/kernel/activity/ExecImpl.cpp
src/kernel/activity/ExecImpl.hpp
src/s4u/s4u_actor.cpp
src/s4u/s4u_exec.cpp
src/simix/popping.cpp

index bd38de7..dd9f694 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 SimGrid (3.19) NOT RELEASED YET (target: March 20 2018, 16:15:27 UTC)
 
+ S4U
+ - Execution->setHost() can be called after start() to migrate it.
+
 SimGrid (3.18) Released December 24 2017
 
  The "Ho Ho Ho! SimGrid 4 beta is coming to town" release.
index bbe37f7..8e14795 100644 (file)
@@ -13,19 +13,37 @@ static void wizard()
 {
   simgrid::s4u::Host* fafard  = simgrid::s4u::Host::by_name("Fafard");
   simgrid::s4u::Host* ginette = simgrid::s4u::Host::by_name("Ginette");
+  simgrid::s4u::Host* boivin  = simgrid::s4u::Host::by_name("Boivin");
 
   XBT_INFO("I'm a wizard! I can run a task on the Fafard host from the Ginette one! Look!");
-  simgrid::s4u::ExecPtr activity = simgrid::s4u::this_actor::exec_init(48.492e6);
-  activity->setHost(ginette);
-  activity->start();
+  simgrid::s4u::ExecPtr exec = simgrid::s4u::this_actor::exec_init(48.492e6);
+  exec->setHost(ginette);
+  exec->start();
   XBT_INFO("It started. Running 48.492Mf takes exactly one second on Ginette (but not on Fafard).");
 
   simgrid::s4u::this_actor::sleep_for(0.1);
-  XBT_INFO("Load on Fafard: %e flops/s; Load on Ginette: %e flops/s.", fafard->getLoad(), ginette->getLoad());
+  XBT_INFO("Loads in flops/s: Boivin=%.0f; Fafard=%.0f; Ginette=%.0f",
+      boivin->getLoad(), fafard->getLoad(), ginette->getLoad());
 
-  activity->wait();
+  exec->wait();
 
   XBT_INFO("Done!");
+  XBT_INFO("And now, harder. Start a remote task on Ginette and move it to Boivin after 0.5 sec");
+  exec = simgrid::s4u::this_actor::exec_init(73293500)->setHost(ginette);
+  exec->start();
+
+  simgrid::s4u::this_actor::sleep_for(0.5);
+  XBT_INFO("Loads before the move: Boivin=%.0f; Fafard=%.0f; Ginette=%.0f",
+      boivin->getLoad(), fafard->getLoad(), ginette->getLoad());
+
+  exec->setHost(boivin);
+
+  simgrid::s4u::this_actor::sleep_for(0.1);
+  XBT_INFO("Loads after the move: Boivin=%.0f; Fafard=%.0f; Ginette=%.0f",
+      boivin->getLoad(), fafard->getLoad(), ginette->getLoad());
+
+  exec->wait();
+  XBT_INFO("Done!");
 }
 
 int main(int argc, char* argv[])
index fd849b5..3c3cbd3 100644 (file)
@@ -4,5 +4,9 @@
 $ $SG_TEST_EXENV ${bindir:=.}/s4u-exec-remote$EXEEXT ${platfdir}/small_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
 > [  0.000000] (1:test@Fafard) I'm a wizard! I can run a task on the Fafard host from the Ginette one! Look!
 > [  0.000000] (1:test@Fafard) It started. Running 48.492Mf takes exactly one second on Ginette (but not on Fafard).
-> [  0.100000] (1:test@Fafard) Load on Fafard: 0.000000e+00 flops/s; Load on Ginette: 4.849200e+07 flops/s.
+> [  0.100000] (1:test@Fafard) Loads in flops/s: Boivin=0; Fafard=0; Ginette=48492000
 > [  1.000000] (1:test@Fafard) Done!
+> [  1.000000] (1:test@Fafard) And now, harder. Start a remote task on Ginette and move it to Boivin after 0.5 sec
+> [  1.500000] (1:test@Fafard) Loads before the move: Boivin=0; Fafard=0; Ginette=48492000
+> [  1.600000] (1:test@Fafard) Loads after the move: Boivin=98095000; Fafard=0; Ginette=0
+> [  2.000000] (1:test@Fafard) Done!
index 0484cc7..d233924 100644 (file)
@@ -3,11 +3,16 @@
 /* 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/Host.hpp"
+#include "simgrid/modelchecker.h"
+#include "src/mc/mc_replay.hpp"
 
 #include "src/kernel/activity/ExecImpl.hpp"
 #include "src/simix/smx_host_private.hpp"
 #include "src/surf/surf_interface.hpp"
+#include "src/surf/cpu_interface.hpp"
+
+
+#include "simgrid/s4u/Host.hpp"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(simix_process);
 
@@ -87,8 +92,34 @@ void simgrid::kernel::activity::ExecImpl::post()
     SIMIX_execution_finish(this);
 }
 
+simgrid::kernel::activity::ActivityImpl*
+simgrid::kernel::activity::ExecImpl::migrate(simgrid::s4u::Host* to)
+{
+
+  if (not MC_is_active() && not MC_record_replay_is_active()) {
+    surf_action_t oldAction = this->surfAction_;
+    surf_action_t newAction = to->pimpl_cpu->execution_start(oldAction->getCost());
+    newAction->setRemains(oldAction->getRemains());
+    newAction->setData(this);
+    newAction->setSharingWeight(oldAction->getPriority());
+
+    // FIXME: the user-defined bound seem to not be kept by LMM, that seem to overwrite it for the multi-core modeling.
+    // I hope that the user did not provide any.
+
+    oldAction->setData(nullptr);
+    oldAction->cancel();
+    oldAction->unref();
+    this->surfAction_ = newAction;
+  }
+
+  onMigration(this, to);
+  return this;
+}
+
+
 /*************
  * Callbacks *
  *************/
 simgrid::xbt::signal<void(simgrid::kernel::activity::ExecImplPtr)> simgrid::kernel::activity::ExecImpl::onCreation;
 simgrid::xbt::signal<void(simgrid::kernel::activity::ExecImplPtr)> simgrid::kernel::activity::ExecImpl::onCompletion;
+simgrid::xbt::signal<void(simgrid::kernel::activity::ExecImplPtr, simgrid::s4u::Host*)> simgrid::kernel::activity::ExecImpl::onMigration;
index f71e3cc..f58d3c2 100644 (file)
@@ -24,6 +24,7 @@ public:
   void post() override;
   double remains();
   double remainingRatio();
+  virtual ActivityImpl* migrate(s4u::Host* to);
 
   /* The host where the execution takes place. If nullptr, then this is a parallel exec (and only surf
                   knows the hosts) */
@@ -32,6 +33,8 @@ public:
   surf::Action* timeoutDetector = nullptr;
   static simgrid::xbt::signal<void(kernel::activity::ExecImplPtr)> onCreation;
   static simgrid::xbt::signal<void(kernel::activity::ExecImplPtr)> onCompletion;
+  static simgrid::xbt::signal<void(simgrid::kernel::activity::ExecImplPtr, simgrid::s4u::Host*)> onMigration;
+
 };
 }
 }
index c888fb3..850069b 100644 (file)
@@ -76,7 +76,9 @@ void Actor::onExit(int_f_pvoid_pvoid_t fun, void* data)
 
 void Actor::migrate(Host* new_host)
 {
-  simgrid::simix::kernelImmediate([this, new_host]() { pimpl_->new_host = new_host; });
+  simgrid::simix::kernelImmediate([this, new_host]() {
+    pimpl_->new_host = new_host;
+  });
 }
 
 s4u::Host* Actor::getHost()
@@ -361,8 +363,7 @@ void onExit(int_f_pvoid_pvoid_t fun, void* data)
 
 void migrate(Host* new_host)
 {
-  smx_actor_t process = SIMIX_process_self();
-  simgrid::simix::kernelImmediate([process, new_host] { process->new_host = new_host; });
+  SIMIX_process_self()->iface()->migrate(new_host);
 }
 }
 }
index d1bc5df..6527dec 100644 (file)
@@ -23,6 +23,7 @@ Activity* Exec::start()
 Activity* Exec::wait()
 {
   simcall_execution_wait(pimpl_);
+  state_ = finished;
   return this;
 }
 
@@ -60,7 +61,9 @@ ExecPtr Exec::setPriority(double priority)
 }
 ExecPtr Exec::setHost(Host* host)
 {
-  xbt_assert(state_ == inited, "Cannot change the host of an exec after its start");
+  xbt_assert(state_ == inited || state_ == started, "Cannot change the host of an exec once it's done (state: %d)", state_);
+  if (state_ == started)
+    boost::static_pointer_cast<simgrid::kernel::activity::ExecImpl>(pimpl_)->migrate(host);
   host_ = host;
   return this;
 }
index 2672a4a..daeacbd 100644 (file)
@@ -34,9 +34,10 @@ void SIMIX_simcall_answer(smx_simcall_t simcall)
   }
 }
 
-void SIMIX_simcall_exit(smx_activity_t synchro)
+void SIMIX_simcall_exit(smx_activity_t activity)
 {
-  synchro->post();
+  if (activity != nullptr) // When migrating, the surf activity is disconnected from its simix activity before cancel
+    activity->post();
 }
 
 void SIMIX_run_kernel(std::function<void()> const* code)