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
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
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
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
--- /dev/null
+/* 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;
+}
--- /dev/null
+#!/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
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);
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[])
> [ 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.
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()));
/* 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++) {
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)
{
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();
}
}
-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));
}
}
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;