Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
finish the integration of the new link_energy plugin
authorMartin Quinson <martin.quinson@loria.fr>
Tue, 21 Nov 2017 22:54:01 +0000 (23:54 +0100)
committerMartin Quinson <martin.quinson@loria.fr>
Tue, 21 Nov 2017 23:06:03 +0000 (00:06 +0100)
.gitignore
examples/platforms/energy_platform.xml
examples/s4u/CMakeLists.txt
examples/s4u/energy-link/s4u-energy-link.cpp [new file with mode: 0644]
examples/s4u/energy-link/s4u-energy-link.tesh [new file with mode: 0644]
include/simgrid/plugins/energy.h
include/simgrid/plugins/link_energy.h [deleted file]
src/surf/plugins/link_energy.cpp
tools/cmake/DefinePackages.cmake

index 62d7e7d..d342dc4 100644 (file)
@@ -209,6 +209,7 @@ examples/s4u/basic/s4u-basic
 examples/s4u/basic/s4u-basic_deployment
 examples/s4u/basic/s4u-basic_function
 examples/s4u/dht-chord/s4u-dht-chord
+examples/s4u/energy-link/s4u-energy-link
 examples/s4u/io/s4u-io
 examples/s4u/mutex/s4u-mutex
 examples/s4u/plugin-hostload/s4u-plugin-hostload
index 03ce9c7..7d9ace5 100644 (file)
       <prop id="watt_per_state" value="100.0:200.0, 93.0:170.0, 90.0:150.0" />
       <prop id="watt_off" value="10" />
     </host>
-
-    <link id="bus" bandwidth="100kBps" latency="0"/>
+    <link id="bus" bandwidth="100kBps" latency="0" sharing_policy="SHARED">
+<!--   REALISTIC VALUES                    <prop id="watt_range" value="10.3581:10.7479" /> -->
+<!--  IREALISTIC VALUES FOR THE TEST -->   <prop id="watt_range" value="1:3" /> 
+    </link>
     <route src="MyHost1" dst="MyHost2">
       <link_ctn id="bus"/>
     </route>
index dac2b6b..5b88ee4 100644 (file)
@@ -2,6 +2,7 @@ foreach (example actions-comm actions-storage
                  actor-create actor-daemon actor-execute actor-kill actor-lifetime actor-migration actor-suspend actor-priority
                  app-masterworker app-pingpong app-token-ring
                 async-wait async-waitany async-waitall
+                energy-link
                 plugin-hostload io mutex)
   add_executable       (s4u-${example}  ${example}/s4u-${example}.cpp)
   target_link_libraries(s4u-${example}  simgrid)
@@ -62,6 +63,8 @@ foreach(example actions-comm actions-storage
                 actor-create actor-daemon actor-execute actor-kill actor-lifetime actor-migration actor-suspend
                 app-bittorrent app-masterworker app-pingpong app-token-ring 
                async-wait async-waitall async-waitany actor-priority
-               dht-chord plugin-hostload io mutex)
+               dht-chord 
+               energy-link
+               plugin-hostload io mutex)
   ADD_TESH_FACTORIES(s4u-${example} "thread;ucontext;raw;boost" --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/${example} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_HOME_DIRECTORY}/examples/s4u/${example} s4u-${example}.tesh)
 endforeach()
diff --git a/examples/s4u/energy-link/s4u-energy-link.cpp b/examples/s4u/energy-link/s4u-energy-link.cpp
new file mode 100644 (file)
index 0000000..be53d6c
--- /dev/null
@@ -0,0 +1,143 @@
+/* Copyright (c) 2017. 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/plugins/energy.h"
+#include "xbt/log.h"
+#include <simgrid/s4u.hpp>
+
+#include <random>
+
+/* Parameters of the random generation of the flow size */
+static const unsigned long int min_size = 1e6;
+static const unsigned long int max_size = 1e9;
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_app_energyconsumption, "Messages specific for this s4u example");
+
+static void sender(std::vector<std::string> args)
+{
+  xbt_assert(args.size() == 2, "The master function expects 2 arguments.");
+  int flow_amount  = std::stoi(args.at(0));
+  double comm_size = std::stod(args.at(1));
+  XBT_INFO("Send %.0f bytes, in %d flows", comm_size, flow_amount);
+
+  simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::byName(std::string("message"));
+
+  simgrid::s4u::this_actor::sleep_for(10);
+
+  /* - Send the task to the @ref worker */
+  char* payload = bprintf("%f", comm_size);
+
+  if (flow_amount == 1) {
+    mailbox->put(payload, comm_size);
+  } else {
+    // Start all comms in parallel
+    std::vector<simgrid::s4u::CommPtr> comms;
+    for (int i = 0; i < flow_amount; i++)
+      comms.push_back(mailbox->put_async(const_cast<char*>("message"), comm_size));
+
+    // And now, wait for all comms. Manually since wait_all is not part of this_actor yet
+    for (int i = 0; i < flow_amount; i++) {
+      simgrid::s4u::CommPtr comm = comms.at(i);
+      comm->wait();
+    }
+    comms.clear();
+  }
+  XBT_INFO("sender done.");
+}
+
+static void receiver(std::vector<std::string> args)
+{
+  int flow_amount = std::stoi(args.at(0));
+
+  XBT_INFO("Receiving %d flows ...", flow_amount);
+
+  simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::byName(std::string("message"));
+
+  if (flow_amount == 1) {
+    void* res = mailbox->get();
+    xbt_free(res);
+  } else {
+    void* ignored;
+
+    // Start all comms in parallel
+    std::vector<simgrid::s4u::CommPtr> comms;
+    for (int i = 0; i < flow_amount; i++)
+      comms.push_back(mailbox->get_async(&ignored));
+
+    // And now, wait for all comms. Manually since wait_all is not part of this_actor yet
+    for (int i = 0; i < flow_amount; i++)
+      comms.at(i)->wait();
+    comms.clear();
+  }
+  XBT_INFO("receiver done.");
+}
+
+int main(int argc, char* argv[])
+{
+
+  simgrid::s4u::Engine* e = new simgrid::s4u::Engine(&argc, argv);
+
+  /* Check if we got --NS3 on the command line, and activate ecofen if so */
+  bool NS3 = false;
+  for (int i = 0; i < argc; i++) {
+    if (strcmp(argv[i], "--NS3") == 0)
+      NS3 = true;
+    if (NS3) // Found the --NS3 parameter previously; shift the rest of the line
+      argv[i] = argv[i + 1];
+  }
+  if (NS3) {
+    xbt_die("No Ecofen in this build");
+    //    XBT_INFO("Activating the Ecofen energy plugin");
+    //    ns3_link_energy_plugin_init();
+    //    xbt_cfg_set_parse("network/model:NS3");
+    //    argc -= 1; // We removed it from the parameters
+  } else {
+    XBT_INFO("Activating the SimGrid link energy plugin");
+    sg_link_energy_plugin_init();
+  }
+
+  xbt_assert(argc > 1, "\nUsage: %s platform_file [flowCount [datasize]] [--NS3]\n"
+                       "\tExample: %s s4uplatform.xml \n"
+                       "\tIf you add NS3 as last parameter, this will try to activate the ecofen plugin.\n"
+                       "\tWithout it, it will use the SimGrid link energy plugin.\n",
+             argv[0], argv[0]);
+  e->loadPlatform(argv[1]);
+
+  /* prepare to launch the actors */
+  std::vector<std::string> argSender;
+  std::vector<std::string> argReceiver;
+  if (argc > 2) {
+    argSender.push_back(argv[2]); // Take the amount of flows from the command line
+    argReceiver.push_back(argv[2]);
+  } else {
+    argSender.push_back("1"); // Default value
+    argReceiver.push_back("1");
+  }
+  if (argc > 3) {
+    if (strcmp(argv[3], "random") == 0) { // We're asked to get a random size
+      /* Initialize the random number generator */
+      std::random_device rd;
+      std::default_random_engine generator(rd());
+
+      /* Distribution on which to apply the generator */
+      std::uniform_int_distribution<unsigned long int> distribution(min_size, max_size);
+
+      char* size = bprintf("%lu", distribution(generator));
+      argSender.push_back(std::string(size));
+      xbt_free(size);
+    } else {                        // Not "random" ? Then it should be the size to use
+      argSender.push_back(argv[3]); // Take the datasize from the command line
+    }
+  } else { // No parameter at all? Then use the default value
+    argSender.push_back("25000");
+  }
+  simgrid::s4u::Actor::createActor("sender", simgrid::s4u::Host::by_name("MyHost1"), sender, argSender);
+  simgrid::s4u::Actor::createActor("receiver", simgrid::s4u::Host::by_name("MyHost2"), receiver, argReceiver);
+
+  /* And now, launch the simulation */
+  e->run();
+
+  return 0;
+}
diff --git a/examples/s4u/energy-link/s4u-energy-link.tesh b/examples/s4u/energy-link/s4u-energy-link.tesh
new file mode 100644 (file)
index 0000000..2622a4b
--- /dev/null
@@ -0,0 +1,28 @@
+#! ./tesh
+
+p Testing the mechanism for computing link energy consumption (using CM02 as a network model)
+
+$ ${bindir:=.}/s4u-energy-link$EXEEXT ${srcdir:=.}/../platforms/energy_platform.xml  "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=network/model:CM02 --cfg=network/crosstraffic:no
+> [  0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02'
+> [  0.000000] (0:maestro@) Configuration change: Set 'network/crosstraffic' to 'no'
+> [  0.000000] (0:maestro@) Activating the SimGrid link energy plugin
+> [  0.000000] (1:sender@MyHost1) Send 25000 bytes, in 1 flows
+> [  0.000000] (2:receiver@MyHost2) Receiving 1 flows ...
+> [ 10.250000] (2:receiver@MyHost2) receiver done.
+> [ 10.250000] (1:sender@MyHost1) sender done.
+> [ 10.250000] (0:maestro@) Link 'bus' total consumption: 10.750000
+> [ 10.250000] (0:maestro@) Total energy over all links: 10.750000
+
+p And now test with 500000 bytes
+
+$ ${bindir:=.}/s4u-energy-link$EXEEXT ${srcdir:=.}/../platforms/energy_platform.xml 1 50000000 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=network/model:CM02 --cfg=network/crosstraffic:no
+> [  0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02'
+> [  0.000000] (0:maestro@) Configuration change: Set 'network/crosstraffic' to 'no'
+> [  0.000000] (0:maestro@) Activating the SimGrid link energy plugin
+> [  0.000000] (1:sender@MyHost1) Send 50000000 bytes, in 1 flows
+> [  0.000000] (2:receiver@MyHost2) Receiving 1 flows ...
+> [510.000000] (2:receiver@MyHost2) receiver done.
+> [510.000000] (1:sender@MyHost1) sender done.
+> [510.000000] (0:maestro@) Link 'bus' total consumption: 1510.000000
+> [510.000000] (0:maestro@) Total energy over all links: 1510.000000
+
index 2a697ab..a5663c0 100644 (file)
@@ -18,6 +18,9 @@ XBT_PUBLIC(double) sg_host_get_wattmin_at(sg_host_t host, int pstate);
 XBT_PUBLIC(double) sg_host_get_wattmax_at(sg_host_t host, int pstate);
 XBT_PUBLIC(double) sg_host_get_current_consumption(sg_host_t host);
 
+XBT_PUBLIC(void) sg_link_energy_plugin_init();
+XBT_PUBLIC(double) sg_link_get_consumed_energy(sg_link_t link);
+
 #define MSG_host_energy_plugin_init() sg_host_energy_plugin_init()
 #define MSG_host_get_consumed_energy(host) sg_host_get_consumed_energy(host)
 #define MSG_host_get_wattmin_at(host,pstate) sg_host_get_wattmin_at(host,pstate)
diff --git a/include/simgrid/plugins/link_energy.h b/include/simgrid/plugins/link_energy.h
deleted file mode 100644 (file)
index 3ade039..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright (c) 2016. 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. */
-
-#ifndef SIMGRID_PLUGINS_LINK_ENERGY_H_
-#define SIMGRID_PLUGINS_LINK_ENERGY_H_
-
-#include <simgrid/forward.h>
-#include <xbt/base.h>
-
-SG_BEGIN_DECL()
-
-XBT_PUBLIC(double) sg_link_get_consumped_power(sg_link_t link);
-XBT_PUBLIC(double) sg_link_get_usage(sg_link_t link);
-XBT_PUBLIC(void) sg_on_simulation_end();
-XBT_PUBLIC(void) sg_link_energy_plugin_init();
-XBT_PUBLIC(double) sg_link_get_consumed_energy(sg_link_t link);
-
-XBT_PUBLIC(double) ns3__link_get_consumped_power(sg_link_t link);
-XBT_PUBLIC(double) ns3_link_get_usage(sg_link_t link);
-XBT_PUBLIC(void) ns3_on_simulation_end();
-XBT_PUBLIC(double) ns3_link_get_consumed_energy(sg_link_t link);
-XBT_PUBLIC(void) ns3_link_energy_plugin_init();
-
-SG_END_DECL()
-
-#endif
index cf5f297..f7bc8eb 100644 (file)
@@ -1,9 +1,9 @@
-/* Copyright (c) 2010, 2012-2016. The SimGrid Team. All rights reserved.    */
+/* Copyright (c) 2017. 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/plugins/link_energy.h"
+#include "simgrid/plugins/energy.h"
 #include "simgrid/s4u/Engine.hpp"
 #include "simgrid/simix.hpp"
 #include "src/surf/network_interface.hpp"
@@ -59,91 +59,36 @@ public:
   explicit LinkEnergy(simgrid::s4u::Link* ptr);
   ~LinkEnergy();
 
-  double getALinkTotalPower(sg_link_t link);
+  double getALinkTotalPower();
   void initWattsRangeList();
-  double getLinkUsage();
-  double getALinkTotalEnergy(sg_link_t link);
+  double getTotalEnergy();
   void update();
 
 private:
-  double computeALinkPower();
-  void computeALinkTotalEnergy();
+  double getPower();
 
   simgrid::s4u::Link* link{};
-  //   simgrid::s4u::Link *up_link { };
-  //   simgrid::s4u::Link *down_link { };
 
   std::vector<LinkPowerRange> power_range_watts_list{};
 
-  double a_link_total_energy{0.0};
-
+  double total_energy{0.0};
   double last_updated{0.0}; /*< Timestamp of the last energy update event*/
-  double current_link_usage{0.0};
 };
 
 simgrid::xbt::Extension<simgrid::s4u::Link, LinkEnergy> LinkEnergy::EXTENSION_ID;
 
 LinkEnergy::LinkEnergy(simgrid::s4u::Link* ptr) : link(ptr), last_updated(surf_get_clock())
 {
-
-  /*std::string lnk_name(this->link->name());
-   size_t lnk_down = lnk_name.find("_DOWN");
-   size_t lnk_up = lnk_name.find("_UP");
-
-   if (lnk_down != std::string::npos) {
-
-   this->down_link = this->link->byName(lnk_name.c_str());
-   replace(lnk_name, "_DOWN", "_UP", lnk_down);
-   this->up_link = this->link->byName(lnk_name.c_str());
-
-   } else if (lnk_up != std::string::npos) {
-
-   this->up_link = this->link->byName(lnk_name.c_str());
-   replace(lnk_name, "_UP", "_DOWN", lnk_up);
-   this->down_link = this->link->byName(lnk_name.c_str());
-
-   } else {
-   this->up_link = this->link;
-   }*/
 }
 
 LinkEnergy::~LinkEnergy() = default;
 
 void LinkEnergy::update()
 {
-
-  this->current_link_usage = this->link->getUsage();
-
-  computeALinkTotalEnergy();
-
-  /*
-   double uplink_usage{0.0};
-   double downlink_usage{0.0};
-
-   std::string lnk_name(this->link->name());
-   size_t lnk_down = lnk_name.find("_DOWN");
-   size_t lnk_up = lnk_name.find("_UP");
-
-   if (lnk_down != std::string::npos) {
-
-   downlink_usage = lmm_constraint_get_usage(
-   this->down_link->pimpl_->constraint());
-
-   this->up_link->extension<LinkEnergy>()->updateLinkUsage();
-
-   } else if (lnk_up != std::string::npos) {
-
-   uplink_usage = lmm_constraint_get_usage(
-   this->up_link->pimpl_->constraint());
-
-   this->link_usage = downlink_usage + uplink_usage;
-
-   } else {
-
-   this->link_usage = lmm_constraint_get_usage(
-   this->up_link->pimpl_->constraint());
-
-   }*/
+  double power = getPower();
+  double now   = surf_get_clock();
+  total_energy += power * (now - last_updated);
+  last_updated = now;
 }
 
 void LinkEnergy::initWattsRangeList()
@@ -152,10 +97,6 @@ void LinkEnergy::initWattsRangeList()
   if (!power_range_watts_list.empty())
     return;
 
-  xbt_assert(power_range_watts_list.empty(), "Power properties incorrectly defined - "
-                                             "could not retrieve idle and busy power values for link %s",
-             this->link->getCname());
-
   const char* all_power_values_str = this->link->getProperty("watt_range");
 
   if (all_power_values_str == nullptr)
@@ -179,9 +120,7 @@ void LinkEnergy::initWattsRangeList()
 
     double idleVal = xbt_str_parse_double((current_power_values.at(0)).c_str(), idle);
 
-    idleVal *= 2; // the idle value is multiplied by 2 because SimGrid's 1 link is mapped to 2 NetDevices in ECOFEN
     double busyVal = xbt_str_parse_double((current_power_values.at(1)).c_str(), busy);
-    busyVal *= 2; // the busy value is multiplied by 2 because SimGrid's 1 link is mapped to 2 NetDevices in ECOFEN
 
     this->power_range_watts_list.push_back(LinkPowerRange(idleVal, busyVal));
 
@@ -191,14 +130,11 @@ void LinkEnergy::initWattsRangeList()
   }
 }
 
-double LinkEnergy::computeALinkPower()
+double LinkEnergy::getPower()
 {
 
-  double dynamic_power = 0.0;
-
-  if (power_range_watts_list.empty()) {
+  if (power_range_watts_list.empty())
     return 0.0;
-  }
 
   auto range = power_range_watts_list[0];
 
@@ -207,35 +143,16 @@ double LinkEnergy::computeALinkPower()
 
   double power_slope = busy - idle;
 
-  if (this->last_updated > 0) {
-
-    double normalized_link_usage = this->current_link_usage / this->link->bandwidth();
-    dynamic_power                = power_slope * normalized_link_usage;
-
-  } else {
-    dynamic_power = 0.0;
-  }
-  double current_power = idle + dynamic_power;
-
-  return current_power;
-}
-
-void LinkEnergy::computeALinkTotalEnergy()
-{
-  double current_power = computeALinkPower();
-  double now           = surf_get_clock();
-  this->a_link_total_energy += current_power * (now - last_updated);
-  last_updated = now;
-}
+  double normalized_link_usage = link->getUsage() / link->bandwidth();
+  double dynamic_power         = power_slope * normalized_link_usage;
 
-double LinkEnergy::getLinkUsage()
-{
-  return this->current_link_usage;
+  return idle + dynamic_power;
 }
 
-double LinkEnergy::getALinkTotalEnergy(sg_link_t link)
+double LinkEnergy::getTotalEnergy()
 {
-  return this->a_link_total_energy;
+  update();
+  return this->total_energy;
 }
 }
 }
@@ -257,6 +174,7 @@ static void onCommunicate(simgrid::surf::NetworkAction* action, simgrid::s4u::Ho
     if (link == nullptr)
       continue;
 
+    XBT_DEBUG("Update link %s", link->getCname());
     // Get the link_energy extension for the relevant link
     LinkEnergy* link_energy = link->piface_.extension<LinkEnergy>();
     link_energy->initWattsRangeList();
@@ -298,22 +216,18 @@ static void computeAndDisplayTotalEnergy()
 {
   std::vector<simgrid::s4u::Link*> link_list;
   simgrid::s4u::Engine::getInstance()->getLinkList(&link_list);
-  double total_power  = 0.0; // Total power consumption (whole platform)
-  double total_energy = 0.0;
+  double total_energy = 0.0; // Total dissipated energy (whole platform)
   for (const auto link : link_list) {
     LinkEnergy* link_energy = link->extension<LinkEnergy>();
-    link_energy->update();
 
-    double a_link_total_energy = link_energy->getALinkTotalEnergy(link);
+    double a_link_total_energy = link_energy->getTotalEnergy();
     total_energy += a_link_total_energy;
     const char* name = link->getCname();
-    if (strcmp(name, "__loopback__")) {
-      XBT_INFO("%s Usage %f Bandwidth %f Energy %f", name, link_energy->getLinkUsage(), link->bandwidth(),
-               a_link_total_energy);
-    }
+    if (strcmp(name, "__loopback__"))
+      XBT_INFO("Link '%s' total consumption: %f", name, a_link_total_energy);
   }
 
-  XBT_INFO("SgTotalPower %f SgTotalEnergy %f SgTransferTime %f", total_power, total_energy, surf_get_clock());
+  XBT_INFO("Total energy over all links: %f", total_energy);
 }
 
 static void onSimulationEnd()
@@ -342,17 +256,4 @@ void sg_link_energy_plugin_init()
   simgrid::s4u::onSimulationEnd.connect(&onSimulationEnd);
 }
 
-/** @brief Returns the total energy consumed by the link so far (in Joules)
- *
- *  See also @ref SURF_plugin_energy.
- */
-
-double sg_link_get_usage(sg_link_t link)
-{
-  xbt_assert(LinkEnergy::EXTENSION_ID.valid(),
-             "The Energy plugin is not active. Please call sg_energy_plugin_init() during initialization.");
-  LinkEnergy* link_energy = link->extension<LinkEnergy>();
-  return link_energy->getLinkUsage();
-}
-
 SG_END_DECL()
index efb29b2..8b29daf 100644 (file)
@@ -346,6 +346,7 @@ set(SURF_SRC
   src/surf/network_constant.cpp
   src/surf/network_interface.cpp
   src/surf/plugins/host_energy.cpp
+  src/surf/plugins/link_energy.cpp
   src/surf/plugins/host_load.cpp
   src/surf/PropertyHolder.cpp
   src/surf/sg_platf.cpp