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.
{
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[])
$ $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!
/* 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);
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;
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) */
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;
+
};
}
}
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()
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);
}
}
}
Activity* Exec::wait()
{
simcall_execution_wait(pimpl_);
+ state_ = finished;
return this;
}
}
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;
}
}
}
-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)