From d5d6cb58ff031cf45a14c9d07f837c593d368012 Mon Sep 17 00:00:00 2001 From: Martin Quinson Date: Sat, 5 Oct 2019 23:14:43 +0200 Subject: [PATCH] Install a conversion path for our users wrt host_energy plugin This is related to https://github.com/simgrid/simgrid/issues/189 --- ChangeLog | 7 +- examples/platforms/cluster_multi.xml | 12 +- examples/platforms/energy_cluster.xml | 4 +- examples/platforms/energy_platform.xml | 16 +-- examples/s4u/energy-boot/platform_boot.xml | 12 +- .../s4u-energy-exec-ptask.cpp | 4 +- examples/s4u/energy-exec/s4u-energy-exec.cpp | 2 +- src/plugins/host_energy.cpp | 114 ++++++++++++------ src/plugins/link_energy.cpp | 11 +- .../energy-consumption/energy-consumption.c | 2 +- 10 files changed, 115 insertions(+), 69 deletions(-) diff --git a/ChangeLog b/ChangeLog index 23cbc8cca2..249843c987 100644 --- a/ChangeLog +++ b/ChangeLog @@ -26,10 +26,13 @@ S4U: Use them to attach user data to the object and retrieve it. Models: - - Improved the usability of ns-3. Several bugs were ironed out. - Introduce an experimental Wifi model. It sounds reasonable according to the state of the art, but it still has to be properly - validated, at least against ns-3. + validated, at least against ns-3 if not against reality. + - Improved the usability of ns-3. Several bugs were ironed out. + - host_energy: Wattage was expressed as 'idle:oneCore:allCores'. + It is now expressed as 'idle:epsilon:allCores' to properly model the + consumption of non-whole tasks on mono-core hosts. More info in the doc. MSG: - convert a new set of functions to the S4U C interface and move the old MSG diff --git a/examples/platforms/cluster_multi.xml b/examples/platforms/cluster_multi.xml index 01a9441583..efaf30b0b6 100644 --- a/examples/platforms/cluster_multi.xml +++ b/examples/platforms/cluster_multi.xml @@ -24,8 +24,8 @@ So the route from node-0 to node-1 is {l0.UP, l1.DOWN} --> - - + + @@ -40,8 +40,8 @@ The route from node-0 to the outer world begins with: l0.UP ; backbone --> - - + + @@ -53,8 +53,8 @@ - Also, the hosts have 4 cores. --> - - + + diff --git a/examples/platforms/energy_cluster.xml b/examples/platforms/energy_cluster.xml index 4b6dcefe4c..06948d000c 100644 --- a/examples/platforms/energy_cluster.xml +++ b/examples/platforms/energy_cluster.xml @@ -4,7 +4,7 @@ - - + + diff --git a/examples/platforms/energy_platform.xml b/examples/platforms/energy_platform.xml index 17756adf39..2da6ba54d0 100644 --- a/examples/platforms/energy_platform.xml +++ b/examples/platforms/energy_platform.xml @@ -9,25 +9,25 @@ - - + + - - + + - - + + - - + + diff --git a/examples/s4u/energy-boot/platform_boot.xml b/examples/s4u/energy-boot/platform_boot.xml index dfa05d28cd..91a453d523 100644 --- a/examples/s4u/energy-boot/platform_boot.xml +++ b/examples/s4u/energy-boot/platform_boot.xml @@ -24,13 +24,13 @@ If you want a realistic simulation, you must use values coming from a real benchmark of your platform. --> - - - + + + - - - + + + diff --git a/examples/s4u/energy-exec-ptask/s4u-energy-exec-ptask.cpp b/examples/s4u/energy-exec-ptask/s4u-energy-exec-ptask.cpp index aa2c214e50..dfba87ae04 100644 --- a/examples/s4u/energy-exec-ptask/s4u-energy-exec-ptask.cpp +++ b/examples/s4u/energy-exec-ptask/s4u-energy-exec-ptask.cpp @@ -17,10 +17,10 @@ static void runner() double old_energy_host1 = sg_host_get_consumed_energy(host1); double old_energy_host2 = sg_host_get_consumed_energy(host2); - XBT_INFO("[%s] Energetic profile: %s", host1->get_cname(), host1->get_property("watt_per_state")); + XBT_INFO("[%s] Energetic profile: %s", host1->get_cname(), host1->get_property("wattage_per_state")); XBT_INFO("[%s] Initial peak speed=%.0E flop/s; Total energy dissipated =%.0E J", host1->get_cname(), host1->get_speed(), old_energy_host1); - XBT_INFO("[%s] Energetic profile: %s", host2->get_cname(), host2->get_property("watt_per_state")); + XBT_INFO("[%s] Energetic profile: %s", host2->get_cname(), host2->get_property("wattage_per_state")); XBT_INFO("[%s] Initial peak speed=%.0E flop/s; Total energy dissipated =%.0E J", host2->get_cname(), host2->get_speed(), old_energy_host2); diff --git a/examples/s4u/energy-exec/s4u-energy-exec.cpp b/examples/s4u/energy-exec/s4u-energy-exec.cpp index 7e90219ece..8f7984666a 100644 --- a/examples/s4u/energy-exec/s4u-energy-exec.cpp +++ b/examples/s4u/energy-exec/s4u-energy-exec.cpp @@ -13,7 +13,7 @@ static void dvfs() simgrid::s4u::Host* host1 = simgrid::s4u::Host::by_name("MyHost1"); simgrid::s4u::Host* host2 = simgrid::s4u::Host::by_name("MyHost2"); - XBT_INFO("Energetic profile: %s", host1->get_property("watt_per_state")); + XBT_INFO("Energetic profile: %s", host1->get_property("wattage_per_state")); XBT_INFO("Initial peak speed=%.0E flop/s; Energy dissipated =%.0E J", host1->get_speed(), sg_host_get_consumed_energy(host1)); diff --git a/src/plugins/host_energy.cpp b/src/plugins/host_energy.cpp index b3cb2a7379..419c1883df 100644 --- a/src/plugins/host_energy.cpp +++ b/src/plugins/host_energy.cpp @@ -29,30 +29,29 @@ abnormality when all the cores are idle. The full details are in As a result, our energy model takes 4 parameters: - - @b Idle: instantaneous consumption (in Watt) when your host is up and running, but without anything to do. - - @b Epsilon: instantaneous consumption (in Watt) when all cores are at 0 or epsilon%, but not in Idle state. - - @b AllCores: instantaneous consumption (in Watt) when all cores of the host are at 100%. - - @b Off: instantaneous consumption (in Watt) when the host is turned off. + - @b Idle: wattage (i.e., instantaneous consumption in Watt) when your host is up and running, but without anything to +do. + - @b Epsilon: wattage when all cores are at 0 or epsilon%, but not in Idle state. + - @b AllCores: wattage when all cores of the host are at 100%. + - @b Off: wattage when the host is turned off. Here is an example of XML declaration: @code{.xml} - - + + @endcode -Please note that the 'Epsilon' parameter can be omitted in the XML declaration. In that case, the value of 'Epsilon' will -be the same as 'Idle'. - +If the 'Epsilon' parameter is omitted in the XML declaration, 'Idle' is used instead. This example gives the following parameters: @b Off is 10 Watts; @b Idle is 100 Watts; @b Epsilon is 120 Watts and @b AllCores is 200 Watts. -This is enough to compute the consumption as a function of the amount of loaded cores: +This is enough to compute the wattage as a function of the amount of loaded cores: - + @@ -68,8 +67,8 @@ If your host has several DVFS levels (several pstates), then you should give the @code{.xml} - - + + @endcode @@ -187,13 +186,21 @@ void HostEnergy::update() HostEnergy::HostEnergy(simgrid::s4u::Host* ptr) : host_(ptr), last_updated_(surf_get_clock()) { init_watts_range_list(); - - const char* off_power_str = host_->get_property("watt_off"); + static bool warned = false; + + const char* off_power_str = host_->get_property("wattage_off"); + if (off_power_str == nullptr) { + off_power_str = host_->get_property("watt_off"); + if (off_power_str != nullptr && not warned) { + warned = true; + XBT_WARN("Please use 'wattage_off' instead of 'watt_off' to define the idle wattage of hosts in your XML."); + } + } if (off_power_str != nullptr) { try { this->watts_off_ = std::stod(std::string(off_power_str)); } catch (const std::invalid_argument&) { - throw std::invalid_argument(std::string("Invalid value for property watt_off of host ") + host_->get_cname() + + throw std::invalid_argument(std::string("Invalid value for property wattage_off of host ") + host_->get_cname() + ": " + off_power_str); } } @@ -251,7 +258,7 @@ double HostEnergy::get_current_watts_value() else { cpu_load = host_->pimpl_cpu->get_constraint()->get_usage() / current_speed; - /** Divide by the number of cores here to have a value between 0 and 1 **/ + /* Divide by the number of cores here to have a value between 0 and 1 */ cpu_load /= host_->pimpl_cpu->get_core_count(); if (cpu_load > 1) // A machine with a load > 1 consumes as much as a fully loaded machine, not more @@ -260,17 +267,6 @@ double HostEnergy::get_current_watts_value() host_was_used_ = true; } - /* @mquinson: The problem with this model is that the load is always 0 or 1, never something less. - * Another possibility could be to model the total energy as - * - * X/(X+Y)*W_idle + Y/(X+Y)*W_burn - * - * where X is the amount of idling cores, and Y the amount of computing cores. - * - * @Mommessc: I do not think the load is always 0 or 1 anymore. - * Moreover, it is not quite clear how the regular model of power consumption (P = Pstatic + load * Pdynamic) - * is impacted if we separate the number of idle and working cores. - */ return get_current_watts_value(cpu_load); } @@ -326,7 +322,52 @@ double HostEnergy::get_consumed_energy() void HostEnergy::init_watts_range_list() { - const char* all_power_values_str = host_->get_property("watt_per_state"); + const char* old_prop = host_->get_property("watt_per_state"); + if (old_prop != nullptr) { + std::vector all_power_values; + boost::split(all_power_values, old_prop, boost::is_any_of(",")); + + std::string msg = std::string("DEPRECATION WARNING: Property 'watt_per_state' will not work after v3.28.\n"); + msg += std::string("The old syntax 'Idle:OneCore:AllCores' must be converted into 'Idle:Epsilon:AllCores' to " + "properly model the consumption of non-whole tasks on mono-core hosts. Here are the values to " + "use for host '") + + host_->get_cname() + "' in your XML file:\n"; + msg += " current_power_values; + boost::split(current_power_values, current_power_values_str, boost::is_any_of(":")); + double p_idle = xbt_str_parse_double((current_power_values.at(0)).c_str(), + "Invalid obsolete XML file. Fix your watt_per_state property."); + double p_one_core; + double p_full; + double p_epsilon; + + if (current_power_values.size() == 2) { // Case: Idle:AllCores + p_full = xbt_str_parse_double((current_power_values.at(1)).c_str(), + "Invalid obsolete XML file. Fix your watt_per_state property."); + p_epsilon = p_full; + } else { // Case: Idle:Epsilon:AllCores + p_one_core = xbt_str_parse_double((current_power_values.at(1)).c_str(), + "Invalid obsolete XML file. Fix your watt_per_state property."); + p_full = xbt_str_parse_double((current_power_values.at(2)).c_str(), + "Invalid obsolete XML file. Fix your watt_per_state property."); + if (host_->get_core_count() == 1) + p_epsilon = p_full; + else + p_epsilon = p_one_core - ((p_full - p_one_core) / (host_->get_core_count() - 1)); + } + PowerRange range(p_idle, p_epsilon, p_full); + power_range_watts_list_.push_back(range); + + msg += std::to_string(p_idle) + ":" + std::to_string(p_epsilon) + ":" + std::to_string(p_full); + msg += ","; + } + msg.pop_back(); // Remove the extraneous ',' + msg += "\" />"; + XBT_WARN("%s", msg.c_str()); + return; + } + const char* all_power_values_str = host_->get_property("wattage_per_state"); if (all_power_values_str == nullptr) return; @@ -354,15 +395,12 @@ void HostEnergy::init_watts_range_list() char* msg_max = bprintf("Invalid AllCores value for pstate %d on host %s: %%s", i, host_->get_cname()); idle_power = xbt_str_parse_double((current_power_values.at(0)).c_str(), msg_idle); - if (current_power_values.size() == 2) // Case: Idle:AllCores - { - epsilon_power = xbt_str_parse_double((current_power_values.at(0)).c_str(), msg_idle); - max_power = xbt_str_parse_double((current_power_values.at(1)).c_str(), msg_max); - } - else // Case: Idle:Epsilon:AllCores - { - epsilon_power = xbt_str_parse_double((current_power_values.at(1)).c_str(), msg_epsilon); - max_power = xbt_str_parse_double((current_power_values.at(2)).c_str(), msg_max); + if (current_power_values.size() == 2) { // Case: Idle:AllCores + epsilon_power = xbt_str_parse_double((current_power_values.at(0)).c_str(), msg_idle); + max_power = xbt_str_parse_double((current_power_values.at(1)).c_str(), msg_max); + } else { // Case: Idle:Epsilon:AllCores + epsilon_power = xbt_str_parse_double((current_power_values.at(1)).c_str(), msg_epsilon); + max_power = xbt_str_parse_double((current_power_values.at(2)).c_str(), msg_max); } XBT_DEBUG("Creating PowerRange for host %s. Idle:%f, Epsilon:%f, AllCores:%f.", host_->get_cname(), idle_power, epsilon_power, max_power); diff --git a/src/plugins/link_energy.cpp b/src/plugins/link_energy.cpp index 20c9873599..aff0b3130e 100644 --- a/src/plugins/link_energy.cpp +++ b/src/plugins/link_energy.cpp @@ -24,8 +24,8 @@ SIMGRID_REGISTER_PLUGIN(link_energy, "Link energy consumption.", &sg_link_energy @verbatim - - + + @endverbatim @@ -87,7 +87,12 @@ void LinkEnergy::init_watts_range_list() return; inited_ = true; - const char* all_power_values_str = this->link_->get_property("watt_range"); + const char* all_power_values_str = this->link_->get_property("wattage_range"); + if (all_power_values_str == nullptr) { + all_power_values_str = this->link_->get_property("watt_range"); + if (all_power_values_str != nullptr) + XBT_WARN("Please rename the 'watt_range' property of link %s into 'wattage_range'.", link_->get_cname()); + } if (all_power_values_str == nullptr) return; diff --git a/teshsuite/msg/energy-consumption/energy-consumption.c b/teshsuite/msg/energy-consumption/energy-consumption.c index aca6082cca..358775abf1 100644 --- a/teshsuite/msg/energy-consumption/energy-consumption.c +++ b/teshsuite/msg/energy-consumption/energy-consumption.c @@ -13,7 +13,7 @@ static int dvfs(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[]) { msg_host_t host = MSG_host_by_name("MyHost1"); - XBT_INFO("Energetic profile: %s", MSG_host_get_property_value(host, "watt_per_state")); + XBT_INFO("Energetic profile: %s", MSG_host_get_property_value(host, "wattage_per_state")); XBT_INFO("Initial peak speed=%.0E flop/s; Energy dissipated =%.0E J", MSG_host_get_speed(host), sg_host_get_consumed_energy(host)); -- 2.20.1
@#Cores loadedConsumptionExplanation
@#Cores loadedWattageExplanation
0 (idle) 100 WattsIdle value
0 (not idle) 120 WattsEpsilon value
1 140 Wattslinear extrapolation between Epsilon and AllCores