Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Energy is now a plugin
authorPaul Bédaride <paul.bedaride@gmail.com>
Wed, 15 Jan 2014 09:44:00 +0000 (10:44 +0100)
committerPaul Bédaride <paul.bedaride@gmail.com>
Wed, 15 Jan 2014 14:13:49 +0000 (15:13 +0100)
29 files changed:
.cproject
buildtools/Cmake/CompleteInFiles.cmake
buildtools/Cmake/DefinePackages.cmake
buildtools/Cmake/MakeLib.cmake
buildtools/Cmake/PrintArgs.cmake
buildtools/Cmake/src/internal_config.h.in
examples/msg/energy/e2/e2.c
examples/msg/energy/e2/energy_consumption.tesh
examples/msg/energy/e3/concurrent_tasks.tesh
examples/msg/energy/e3/e3.c
examples/smpi/energy/energy.tesh
examples/smpi/energy/f77/energy.tesh
examples/smpi/energy/f90/energy.tesh
include/simgrid.h
include/simgrid/plugins.h [new file with mode: 0644]
src/include/surf/surf.h
src/simgrid/sg_config.c
src/surf/cpu_cas01.cpp
src/surf/cpu_cas01.hpp
src/surf/cpu_interface.cpp
src/surf/cpu_interface.hpp
src/surf/cpu_ti.hpp
src/surf/plugins/energy.cpp [new file with mode: 0644]
src/surf/plugins/energy.hpp [new file with mode: 0644]
src/surf/surf_c_bindings.cpp
src/surf/surf_interface.cpp
src/surf/surf_interface.hpp
src/surf/workstation_interface.cpp
src/surf/workstation_interface.hpp

index 56ee086..12679b9 100644 (file)
--- a/.cproject
+++ b/.cproject
@@ -1,7 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?fileVersion 5.0.0?>
-
-<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage2">
+<?fileVersion 5.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage2">
        <storageModule moduleId="org.eclipse.cdt.core.settings">
                <cconfiguration id="cdt.managedbuild.toolchain.gnu.base.1053321950">
                        <storageModule externalCElementFile="cdt.managedbuild.toolchain.gnu.base.1053321950_org.eclipse.cdt.core.settings" id="cdt.managedbuild.toolchain.gnu.base.1053321950" name="Default"/>
index 858267f..57cab1c 100644 (file)
@@ -73,6 +73,7 @@ include(TestBigEndian)
 TEST_BIG_ENDIAN(BIGENDIAN)
 
 include(FindGraphviz)
+include(FindLibSigc++)
 
 set(HAVE_GTNETS 0)
 if(enable_gtnets)
index ca554d3..ae3a179 100644 (file)
@@ -40,6 +40,7 @@ set(EXTRA_DIST
   src/smpi/colls/coll_tuned_topo.h
   src/smpi/private.h
   src/smpi/smpi_mpi_dt_private.h
+  src/surf/plugins/energy.hpp
   src/surf/cpu_interface.hpp
   src/surf/cpu_ti.hpp
   src/surf/cpu_cas01.hpp
@@ -299,6 +300,7 @@ set(NS3_SRC
   )
 
 set(SURF_SRC
+  src/surf/plugins/energy.cpp
   src/surf/cpu_interface.cpp
   src/surf/cpu_ti.cpp
   src/surf/cpu_cas01.cpp
@@ -550,6 +552,7 @@ set(headers_to_install
   include/simgrid/modelchecker.h
   include/simgrid/platf.h
   include/simgrid/platf_generator.h
+  include/simgrid/plugins.h
   include/simgrid/simix.h
   include/smpi/mpi.h
   include/smpi/smpi.h
@@ -991,6 +994,7 @@ set(CMAKE_SOURCE_FILES
   buildtools/Cmake/Modules/FindGFortran.cmake
   buildtools/Cmake/Modules/FindGTnets.cmake
   buildtools/Cmake/Modules/FindGraphviz.cmake
+  buildtools/Cmake/Modules/FindLibSigc++.cmake
   buildtools/Cmake/Modules/FindLibunwind.cmake
   buildtools/Cmake/Modules/FindLua51Simgrid.cmake
   buildtools/Cmake/Modules/FindNS3.cmake
index bddc356..8ee81ad 100644 (file)
@@ -82,6 +82,10 @@ if(HAVE_GRAPHVIZ)
   endif()
 endif()
 
+if(HAVE_LIBSIGC++)
+  SET(SIMGRID_DEP "${SIMGRID_DEP} -lsigc-2.0")   
+endif()
+
 if(HAVE_GTNETS)
   SET(SIMGRID_DEP "${SIMGRID_DEP} -lgtnets")
 endif()
index 122fd57..9a4a8c4 100644 (file)
@@ -121,6 +121,7 @@ message("        Tracing mode ........: ${enable_tracing}")
 message("        Jedule  mode ........: ${enable_jedule}")
 message("        Latency bound .......: ${enable_latency_bound_tracking}")
 message("        Graphviz mode .......: ${HAVE_GRAPHVIZ}")
+message("        Sigc++ mode .........: ${HAVE_LIBSIGC++}")
 message("        Mallocators .........: ${enable_mallocators}")
 message("")
 message("        Simgrid dependencies : ${SIMGRID_DEP}")
index 8400694..43270cc 100644 (file)
@@ -61,6 +61,9 @@
 /* If have linux_futex.h */
 #cmakedefine HAVE_FUTEX_H @HAVE_FUTEX_H@
 
+/* Some variable for libsigc++ */
+#cmakedefine HAVE_LIBSIGC @HAVE_LIBSIGC++@
+
 /* Some variable for graphviz */
 #cmakedefine HAVE_GRAPHVIZ @HAVE_GRAPHVIZ@
 #cmakedefine HAVE_GRAPH_H @GRAPH_H@
index d0ea20b..cd40d20 100644 (file)
@@ -70,14 +70,13 @@ int dvfs(int argc, char *argv[])
   consumed_energy = MSG_get_host_consumed_energy(host);
   XBT_INFO("Total energy (Joules): %f", consumed_energy);
 
-
   return 0;
 }
 
 int main(int argc, char *argv[])
 {
   msg_error_t res = MSG_OK;
-
+  sg_energy_plugin_init();
   MSG_init(&argc, argv);
 
   if (argc != 3) {
index 02c620e..105621b 100644 (file)
@@ -14,3 +14,4 @@ $ $SG_TEST_EXENV energy/e2/e2$EXEEXT ${srcdir:=.}/energy/e2/platform_e2.xml ${sr
 > [  9.000000] (1:dvfs_test@MyHost1) Task3 (sleep) simulation time: 4.000000e+00
 > [  9.000000] (1:dvfs_test@MyHost1) Total energy (Joules): 1220.000000
 > [  9.000000] (0:@) Total simulation time: 9.000000e+00
+> [  9.000000] (0:@) Total energy (Joules) of host MyHost1: 1220.000000
index 1bcb927..9cf2d89 100644 (file)
@@ -19,3 +19,4 @@ $ $SG_TEST_EXENV energy/e3/e3$EXEEXT ${srcdir:=.}/energy/e3/platform_e3.xml ${sr
 > [  8.000000] (1:dvfs_test@MyHost1) Task simulation time: 8.000000e+00
 > [  8.000000] (1:dvfs_test@MyHost1) Total energy (Joules): 1390.000000
 > [  8.000000] (0:@) Total simulation time: 8.000000e+00
+> [  8.000000] (0:@) Total energy (Joules) of host MyHost1: 1390.000000
index 4230a8e..40d61cc 100644 (file)
@@ -99,7 +99,7 @@ static int dvfs(int argc, char *argv[])
 int main(int argc, char *argv[])
 {
   msg_error_t res = MSG_OK;
-
+  sg_energy_plugin_init();
   MSG_init(&argc, argv);
 
   if (argc != 3) {
index aac0673..b4aa3a4 100644 (file)
@@ -1,10 +1,13 @@
 p Test smpi bindings for dvfs functions (C example)
-$ ../../../smpi_script/bin/smpirun -np 2 -hostfile ${srcdir:=.}/hostfile  -platform ${srcdir:=.}/platform.xml --cfg=smpi/cpu_threshold:-1 ${bindir:=.}/se
+$ ../../../smpi_script/bin/smpirun -np 2 -hostfile ${srcdir:=.}/hostfile  -platform ${srcdir:=.}/platform.xml --cfg=smpi/cpu_threshold:-1 ${bindir:=.}/se --cfg=plugin:Energy
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'maxmin/precision' to '1e-9'
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/cpu_threshold' to '-1'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'plugin' to 'Energy'
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [80.000000] [surf_energy/INFO] Total energy (Joules) of host MyHost1: 12900.000000
+> [80.000000] [surf_energy/INFO] Total energy (Joules) of host MyHost2: 2000.000000
 > [0.000000] [rank 1] Pstates: 1; Powers: 100000000
 > [0.000000] [rank 0] Pstates: 3; Powers: 100000000, 50000000, 20000000
 > [0.000000] [rank 1] Current pstate: 0; Current power: 100000000
index 10ccab9..83fc49e 100644 (file)
@@ -1,10 +1,13 @@
 p Test smpi bindings for dvfs functions (Fortran 77 example)
-$ ../../../smpi_script/bin/smpirun -np 2 -hostfile ${srcdir:=.}/hostfile  -platform ${srcdir:=.}/platform.xml --cfg=smpi/cpu_threshold:-1 ${bindir:=.}/f77/sef
+$ ../../../smpi_script/bin/smpirun -np 2 -hostfile ${srcdir:=.}/hostfile  -platform ${srcdir:=.}/platform.xml --cfg=smpi/cpu_threshold:-1 ${bindir:=.}/f77/sef --cfg=plugin:Energy
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'maxmin/precision' to '1e-9'
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/cpu_threshold' to '-1'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'plugin' to 'Energy'
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
+> [80.000000] [surf_energy/INFO] Total energy (Joules) of host MyHost1: 12900.000000
+> [80.000000] [surf_energy/INFO] Total energy (Joules) of host MyHost2: 2000.000000
 >  [  0.] [rank  0] 3 pstates available
 >  [  0.] [rank  1] 1 pstates available
 >  [  0.] [rank  0] Power:   100000000.
index fe1859b..5e82975 100644 (file)
@@ -1,9 +1,10 @@
 p Test smpi bindings for dvfs functions (Fortran 90 example)
-$ ../../../smpi_script/bin/smpirun -np 2 -hostfile ${srcdir:=.}/hostfile  -platform ${srcdir:=.}/platform.xml --cfg=smpi/cpu_threshold:-1 ${bindir:=.}/f90/sef90
+$ ../../../smpi_script/bin/smpirun -np 2 -hostfile ${srcdir:=.}/hostfile  -platform ${srcdir:=.}/platform.xml --cfg=smpi/cpu_threshold:-1 ${bindir:=.}/f90/sef90 --cfg=plugin:Energy 
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'maxmin/precision' to '1e-9'
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/model' to 'SMPI'
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'network/TCP_gamma' to '4194304'
 > [0.000000] [xbt_cfg/INFO] Configuration change: Set 'smpi/cpu_threshold' to '-1'
+> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'plugin' to 'Energy'
 > [0.000000] [surf_config/INFO] Switching workstation model to compound since you changed the network and/or cpu model(s)
 >  [   0.0000000000000000      ] [rank            0 ]           3 pstates available
 >  [   0.0000000000000000      ] [rank            1 ]           1 pstates available
@@ -19,3 +20,5 @@ $ ../../../smpi_script/bin/smpirun -np 2 -hostfile ${srcdir:=.}/hostfile  -platf
 >  [   30.000000000000000      ] [rank            0 ] Energy consumed (Joules):    5400.0000000000000     
 >  [   30.000000000000000      ] [rank            0 ] Current pstate:            2 ; Current power:    20000000.000000000     
 >  [   80.000000000000000      ] [rank            0 ] Energy consumed (Joules):    12900.000000000000     
+> [80.000000] [surf_energy/INFO] Total energy (Joules) of host MyHost1: 12900.000000
+> [80.000000] [surf_energy/INFO] Total energy (Joules) of host MyHost2: 2000.000000
index 957f2c7..d4dc185 100644 (file)
@@ -15,7 +15,7 @@
 #include <simgrid/platf_generator.h>
 #include <simgrid/platf.h>
 #include <simgrid/simix.h>
-
+#include <simgrid/plugins.h>
 
 // SG_BEGIN_DECL()
 // nothing
diff --git a/include/simgrid/plugins.h b/include/simgrid/plugins.h
new file mode 100644 (file)
index 0000000..4f6f6a2
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * plugins.h
+ *
+ *  Created on: Jan 15, 2014
+ *      Author: bedaride
+ */
+
+#ifndef PLUGINS_H_
+#define PLUGINS_H_
+
+SG_BEGIN_DECL()
+
+/** \ingroup SURF_plugins
+ *  \brief The cpu energy consumption plugin
+ */
+XBT_PUBLIC(void) sg_energy_plugin_init(void);
+
+SG_END_DECL()
+
+#endif /* PLUGINS_H_ */
index 61ca8f9..5499ec5 100644 (file)
@@ -19,6 +19,7 @@
 #include "surf/surf_routing.h"
 #include "simgrid/platf_interface.h"
 #include "simgrid/datatypes.h"
+#include "simgrid/plugins.h"
 
 SG_BEGIN_DECL()
 /* Actions and models are highly connected structures... */
@@ -299,7 +300,6 @@ XBT_PUBLIC(surf_model_t) surf_resource_model(const void *host, int level);
 /* Implementations of model object */
 /**************************************/
 
-
 /** \ingroup SURF_models
  *  \brief The CPU model object for the physical machine layer
  */
@@ -336,6 +336,11 @@ XBT_PUBLIC(void) surf_cpu_model_init_ti(void);
  */
 XBT_PUBLIC_DATA(s_surf_model_description_t) surf_optimization_mode_description[];
 
+/** \ingroup SURF_plugins
+ *  \brief The list of all available surf plugins
+ */
+XBT_PUBLIC_DATA(s_surf_model_description_t) surf_plugin_description[];
+
 /** \ingroup SURF_models
  *  \brief The list of all available cpu model models
  */
index 11cf929..c57b33c 100644 (file)
@@ -111,6 +111,27 @@ static void sg_config_cmd_line(int *argc, char **argv)
     sg_cfg_exit_early();
 }
 
+/* callback of the plugin variable */
+static void _sg_cfg_cb__plugin(const char *name, int pos)
+{
+  char *val;
+
+  XBT_VERB("PLUGIN");
+  xbt_assert(_sg_cfg_init_status < 2,
+              "Cannot load a plugin after the initialization");
+
+  val = xbt_cfg_get_string(_sg_cfg_set, name);
+
+  if (!strcmp(val, "help")) {
+    model_help("plugin", surf_plugin_description);
+    sg_cfg_exit_early();
+  }
+
+  /* New Module missing */
+  int plugin_id = find_model_description(surf_plugin_description, val);
+  surf_plugin_description[plugin_id].model_init_preparse();
+}
+
 /* callback of the workstation/model variable */
 static void _sg_cfg_cb__workstation_model(const char *name, int pos)
 {
@@ -435,6 +456,21 @@ void sg_config_init(int *argc, char **argv)
 
   /* Create the configuration support */
   if (_sg_cfg_init_status == 0) { /* Only create stuff if not already inited */
+
+       /* Plugins configuration */
+
+       sprintf(description,
+               "The plugins. Possible values: ");
+             p = description;
+       while (*(++p) != '\0');
+       for (i = 0; surf_plugin_description[i].name; i++)
+         p += sprintf(p, "%s%s", (i == 0 ? "" : ", "),
+                      surf_plugin_description[i].name);
+       sprintf(p,
+               ".\n       (use 'help' as a value to see the long description of each plugin)");
+       xbt_cfg_register(&_sg_cfg_set, "plugin", description,
+                        xbt_cfgelm_string, 1, 1, &_sg_cfg_cb__plugin, NULL);
+
     sprintf(description,
             "The model to use for the CPU. Possible values: ");
     p = description;
index 93078ea..1174ac2 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "cpu_cas01.hpp"
 #include "cpu_ti.hpp"
+#include "plugins/energy.hpp"
 #include "maxmin_private.hpp"
 #include "simgrid/sg_config.h"
 
@@ -199,11 +200,6 @@ CpuCas01::CpuCas01(CpuCas01ModelPtr model, const char *name, xbt_dynar_t powerPe
   p_powerPeakList = powerPeak;
   m_pstate = pstate;
 
-  p_energy = xbt_new(s_energy_cpu_cas01_t, 1);
-  p_energy->total_energy = 0;
-  p_energy->power_range_watts_list = getWattsRangeList();
-  p_energy->last_updated = surf_get_clock();
-
   XBT_DEBUG("CPU create: peak=%f, pstate=%d", m_powerPeak, m_pstate);
 
   m_core = core;
@@ -216,13 +212,7 @@ CpuCas01::CpuCas01(CpuCas01ModelPtr model, const char *name, xbt_dynar_t powerPe
 }
 
 CpuCas01::~CpuCas01(){
-  unsigned int iter;
-  xbt_dynar_t power_tuple = NULL;
-  xbt_dynar_foreach(p_energy->power_range_watts_list, iter, power_tuple)
-    xbt_dynar_free(&power_tuple);
-  xbt_dynar_free(&p_energy->power_range_watts_list);
   xbt_dynar_free(&p_powerPeakList);
-  xbt_free(p_energy);
 }
 
 bool CpuCas01::isUsed()
@@ -338,105 +328,6 @@ CpuActionPtr CpuCas01::sleep(double duration)
   return action;
 }
 
-xbt_dynar_t CpuCas01::getWattsRangeList()
-{
-       xbt_dynar_t power_range_list;
-       xbt_dynar_t power_tuple;
-       int i = 0, pstate_nb=0;
-       xbt_dynar_t current_power_values;
-       double min_power, max_power;
-
-       if (getProperties() == NULL)
-               return NULL;
-
-       char* all_power_values_str = (char*)xbt_dict_get_or_null(getProperties(), "power_per_state");
-
-       if (all_power_values_str == NULL)
-               return NULL;
-
-
-       power_range_list = xbt_dynar_new(sizeof(xbt_dynar_t), NULL);
-       xbt_dynar_t all_power_values = xbt_str_split(all_power_values_str, ",");
-
-       pstate_nb = xbt_dynar_length(all_power_values);
-       for (i=0; i< pstate_nb; i++)
-       {
-               /* retrieve the power values associated with the current pstate */
-               current_power_values = xbt_str_split(xbt_dynar_get_as(all_power_values, i, char*), ":");
-               xbt_assert(xbt_dynar_length(current_power_values) > 1,
-                               "Power properties incorrectly defined - could not retrieve min and max power values for host %s",
-                               getName());
-
-               /* min_power corresponds to the idle power (cpu load = 0) */
-               /* max_power is the power consumed at 100% cpu load       */
-               min_power = atof(xbt_dynar_get_as(current_power_values, 0, char*));
-               max_power = atof(xbt_dynar_get_as(current_power_values, 1, char*));
-
-               power_tuple = xbt_dynar_new(sizeof(double), NULL);
-               xbt_dynar_push_as(power_tuple, double, min_power);
-               xbt_dynar_push_as(power_tuple, double, max_power);
-
-               xbt_dynar_push_as(power_range_list, xbt_dynar_t, power_tuple);
-               xbt_dynar_free(&current_power_values);
-       }
-       xbt_dynar_free(&all_power_values);
-       return power_range_list;
-}
-
-/**
- * Computes the power consumed by the host according to the current pstate and processor load
- *
- */
-double CpuCas01::getCurrentWattsValue(double cpu_load)
-{
-       xbt_dynar_t power_range_list = p_energy->power_range_watts_list;
-
-       if (power_range_list == NULL)
-       {
-               XBT_DEBUG("No power range properties specified for host %s", getName());
-               return 0;
-       }
-       xbt_assert(xbt_dynar_length(power_range_list) == xbt_dynar_length(p_powerPeakList),
-                                               "The number of power ranges in the properties does not match the number of pstates for host %s",
-                                               getName());
-
-    /* retrieve the power values associated with the current pstate */
-    xbt_dynar_t current_power_values = xbt_dynar_get_as(power_range_list, m_pstate, xbt_dynar_t);
-
-    /* min_power corresponds to the idle power (cpu load = 0) */
-    /* max_power is the power consumed at 100% cpu load       */
-    double min_power = xbt_dynar_get_as(current_power_values, 0, double);
-    double max_power = xbt_dynar_get_as(current_power_values, 1, double);
-    double power_slope = max_power - min_power;
-
-    double current_power = min_power + cpu_load * power_slope;
-
-       XBT_DEBUG("[get_current_watts] min_power=%f, max_power=%f, slope=%f", min_power, max_power, power_slope);
-    XBT_DEBUG("[get_current_watts] Current power (watts) = %f, load = %f", current_power, cpu_load);
-
-       return current_power;
-}
-
-/**
- * Updates the total energy consumed as the sum of the current energy and
- *                                              the energy consumed by the current action
- */
-void CpuCas01::updateEnergy(double cpu_load)
-{
-  double start_time = p_energy->last_updated;
-  double finish_time = surf_get_clock();
-
-  XBT_DEBUG("[cpu_update_energy] action time interval=(%f-%f), current power peak=%f, current pstate=%d",
-                 start_time, finish_time, m_powerPeak, m_pstate);
-  double current_energy = p_energy->total_energy;
-  double action_energy = getCurrentWattsValue(cpu_load)*(finish_time-start_time);
-
-  p_energy->total_energy = current_energy + action_energy;
-  p_energy->last_updated = finish_time;
-
-  XBT_DEBUG("[cpu_update_energy] old_energy_value=%f, action_energy_value=%f", current_energy, action_energy);
-}
-
 double CpuCas01::getCurrentPowerPeak()
 {
   return m_powerPeak;
@@ -465,11 +356,6 @@ void CpuCas01::setPowerPeakAt(int pstate_index)
   m_powerPeak = new_power_peak;
 }
 
-double CpuCas01::getConsumedEnergy()
-{
-  return p_energy->total_energy;
-}
-
 /**********
  * Action *
  **********/
@@ -489,20 +375,3 @@ CpuCas01Action::CpuCas01Action(ModelPtr model, double cost, bool failed, double
   }
   lmm_expand(model->getMaxminSystem(), constraint, getVariable(), 1.0);
 }
-
-
-/**
- * Update the CPU total energy for a finished action
- *
- */
-void CpuCas01Action::updateEnergy()
-{
-  CpuCas01Ptr cpu  = static_cast<CpuCas01Ptr>(lmm_constraint_id(lmm_get_cnst_from_var
-                                                                                 (getModel()->getMaxminSystem(),
-                                                                                                 getVariable(), 0)));
-
-  if(cpu->p_energy->last_updated < surf_get_clock()) {
-       double load = lmm_constraint_get_usage(cpu->getConstraint()) / cpu->m_powerPeak;
-    cpu->updateEnergy(load);
-  }
-}
index 7f54163..389da41 100644 (file)
@@ -60,22 +60,16 @@ public:
   CpuActionPtr execute(double size);
   CpuActionPtr sleep(double duration);
 
-  xbt_dynar_t getWattsRangeList();
-  double getCurrentWattsValue(double cpu_load);
-  void updateEnergy(double cpu_load);
-
   double getCurrentPowerPeak();
   double getPowerPeakAt(int pstate_index);
   int getNbPstates();
   void setPowerPeakAt(int pstate_index);
-  double getConsumedEnergy();
 
   bool isUsed();
 
   tmgr_trace_event_t p_powerEvent;
   xbt_dynar_t p_powerPeakList;                         /*< List of supported CPU capacities */
   int m_pstate;                                                                /*< Current pstate (index in the power_peak_list)*/
-  energy_cpu_cas01_t p_energy;                         /*< Structure with energy-consumption data */
 };
 
 /**********
@@ -89,5 +83,4 @@ public:
   CpuCas01Action(ModelPtr model, double cost, bool failed, double power, lmm_constraint_t constraint);
 
   ~CpuCas01Action() {};
-  void updateEnergy();
 };
index b496745..730f12e 100644 (file)
@@ -7,6 +7,19 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu, surf,
 CpuModelPtr surf_cpu_model_pm;
 CpuModelPtr surf_cpu_model_vm;
 
+/*************
+ * Callbacks *
+ *************/
+
+CpuPtr getActionCpu(CpuActionPtr action) {
+  return static_cast<CpuPtr>(lmm_constraint_id(lmm_get_cnst_from_var
+                                        (action->getModel()->getMaxminSystem(),
+                                        action->getVariable(), 0)));
+}
+surf_callback(void, CpuPtr) createCpuCallbacks;
+surf_callback(void, CpuPtr) deleteCpuCallbacks;
+surf_callback(void, CpuActionPtr) updateCpuActionCallbacks;
+
 /*********
  * Model *
  *********/
@@ -31,7 +44,7 @@ void CpuModel::updateActionsStateLazy(double now, double /*delta*/)
     action->finish();
     XBT_CDEBUG(surf_kernel, "Action %p finished", action);
 
-    action->updateEnergy();
+    surf_callback_emit(updateCpuActionCallbacks, action);
 
     /* set the remains to 0 due to precision problems when updating the remaining amount */
     action->setRemains(0);
@@ -102,7 +115,8 @@ void CpuModel::updateActionsStateFull(double now, double delta)
       action->finish();
       action->setState(SURF_ACTION_DONE);
     }
-    action->updateEnergy();
+    surf_callback_emit(updateCpuActionCallbacks, action);
+    //action->updateEnergy();
   }
 
   return;
@@ -120,7 +134,7 @@ Cpu::Cpu(ModelPtr model, const char *name, xbt_dict_t props,
  , m_powerScale(powerScale)
  , p_constraintCore(NULL)
  , p_constraintCoreId(NULL)
-{}
+{surf_callback_emit(createCpuCallbacks, this);}
 
 Cpu::Cpu(ModelPtr model, const char *name, xbt_dict_t props,
                 lmm_constraint_t constraint, int core, double powerPeak, double powerScale)
@@ -129,6 +143,7 @@ Cpu::Cpu(ModelPtr model, const char *name, xbt_dict_t props,
  , m_powerPeak(powerPeak)
  , m_powerScale(powerScale)
 {
+  surf_callback_emit(createCpuCallbacks, this);
   /* At now, we assume that a VM does not have a multicore CPU. */
   if (core > 1)
     xbt_assert(model == surf_cpu_model_pm);
@@ -149,6 +164,7 @@ Cpu::Cpu(ModelPtr model, const char *name, xbt_dict_t props,
 }
 
 Cpu::~Cpu(){
+  surf_callback_emit(deleteCpuCallbacks, this);
   if (p_constraintCoreId){
     for (int i = 0; i < m_core; i++) {
          xbt_free(p_constraintCoreId[i]);
index 6b8c405..852d71c 100644 (file)
@@ -16,6 +16,18 @@ typedef Cpu *CpuPtr;
 class CpuAction;
 typedef CpuAction *CpuActionPtr;
 
+class CpuPlugin;
+typedef CpuPlugin *CpuPluginPtr;
+
+/*************
+ * Callbacks *
+ *************/
+CpuPtr getActionCpu(CpuActionPtr action);
+
+extern surf_callback(void, CpuPtr) createCpuCallbacks;
+extern surf_callback(void, CpuPtr) deleteCpuCallbacks;
+extern surf_callback(void, CpuActionPtr) updateCpuActionCallbacks;
+
 /*********
  * Model *
  *********/
@@ -34,8 +46,7 @@ public:
  ************/
 class Cpu : public Resource {
 public:
-  Cpu(){};
-  /*Cpu(lmm_constraint_t constraint);*/
+  Cpu(){surf_callback_emit(createCpuCallbacks, this);};
   Cpu(ModelPtr model, const char *name, xbt_dict_t props,
          lmm_constraint_t constraint, int core, double powerPeak, double powerScale);
   Cpu(ModelPtr model, const char *name, xbt_dict_t props,
@@ -51,7 +62,6 @@ public:
   virtual double getPowerPeakAt(int pstate_index)=0;
   virtual int getNbPstates()=0;
   virtual void setPowerPeakAt(int pstate_index)=0;
-  virtual double getConsumedEnergy()=0;
 
   void addTraces(void);
   int m_core;
@@ -67,6 +77,7 @@ public:
  * Action *
  **********/
 class CpuAction : public Action {
+friend CpuPtr getActionCpu(CpuActionPtr action);
 public:
   CpuAction(){};
   CpuAction(ModelPtr model, double cost, bool failed)
@@ -77,7 +88,6 @@ public:
   virtual void setBound(double bound);
 
   void updateRemainingLazy(double now);
-  virtual void updateEnergy()=0;
   double m_bound;
 };
 
index e2e9406..53f5361 100644 (file)
@@ -71,7 +71,6 @@ public:
   tmgr_trace_t p_powerTrace;
 };
 
-
 /*********
  * Model *
  *********/
@@ -125,15 +124,10 @@ public:
   CpuActionPtr sleep(double duration);
   double getAvailableSpeed();
 
-  xbt_dynar_t getWattsRangeList() {THROW_UNIMPLEMENTED;};
-  double getCurrentWattsValue(double /*cpu_load*/) {THROW_UNIMPLEMENTED;};
-  void updateEnergy(double /*cpu_load*/) {THROW_UNIMPLEMENTED;};
-
   double getCurrentPowerPeak() {THROW_UNIMPLEMENTED;};
   double getPowerPeakAt(int /*pstate_index*/) {THROW_UNIMPLEMENTED;};
   int getNbPstates() {THROW_UNIMPLEMENTED;};
   void setPowerPeakAt(int /*pstate_index*/) {THROW_UNIMPLEMENTED;};
-  double getConsumedEnergy() {THROW_UNIMPLEMENTED;};
 
   CpuTiTgmrPtr p_availTrace;       /*< Structure with data needed to integrate trace file */
   tmgr_trace_event_t p_stateEvent;       /*< trace file with states events (ON or OFF) */
@@ -177,7 +171,6 @@ public:
   double getRemains();
   void setAffinity(CpuPtr /*cpu*/, unsigned long /*mask*/) {};
   void setBound(double /*bound*/) {};
-  void updateEnergy() {};
 
   CpuTiPtr p_cpu;
   int m_indexHeap;
diff --git a/src/surf/plugins/energy.cpp b/src/surf/plugins/energy.cpp
new file mode 100644 (file)
index 0000000..9799f52
--- /dev/null
@@ -0,0 +1,154 @@
+#include "energy.hpp"
+#include "../cpu_cas01.hpp"
+
+XBT_LOG_EXTERNAL_CATEGORY(surf_kernel);
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_energy, surf,
+                                "Logging specific to the SURF energy plugin");
+
+std::map<CpuPtr, CpuEnergyPtr> *surf_energy=NULL;
+
+static void createCpuCallback(CpuPtr cpu){
+  (*surf_energy)[cpu] = new CpuEnergy(cpu);
+}
+
+static void deleteCpuCallback(CpuPtr cpu){
+  std::map<CpuPtr, CpuEnergyPtr>::iterator cpuIt = surf_energy->find(cpu);
+  xbt_assert(cpuIt != surf_energy->end(), "The cpu is not in surf_energy.");
+  XBT_INFO("Total energy (Joules) of host %s: %f", cpu->getName(), cpuIt->second->getConsumedEnergy());
+  delete cpuIt->second;
+  surf_energy->erase(cpuIt);
+}
+
+static void updateActionEnergyCallback(CpuActionPtr action){
+  CpuPtr cpu  = getActionCpu(action);
+  CpuEnergyPtr cpu_energy = (*surf_energy)[cpu];
+
+  if(cpu_energy->last_updated < surf_get_clock()) {
+       double cpu_load = lmm_constraint_get_usage(cpu->getConstraint()) / cpu->m_powerPeak;
+    double start_time = cpu_energy->last_updated;
+    double finish_time = surf_get_clock();
+
+    /*XBT_DEBUG("[cpu_update_energy] action time interval=(%f-%f), current power peak=%f, current pstate=%d",
+                 start_time, finish_time, cpu->m_powerPeak, cpu->m_pstate);*/
+    XBT_DEBUG("[cpu_update_energy] action time interval=(%f-%f), current power peak=%f",
+                 start_time, finish_time, cpu->m_powerPeak);
+    double current_energy = cpu_energy->total_energy;
+    double action_energy = cpu_energy->getCurrentWattsValue(cpu_load)*(finish_time-start_time);
+
+    cpu_energy->total_energy = current_energy + action_energy;
+    cpu_energy->last_updated = finish_time;
+
+    XBT_DEBUG("[cpu_update_energy] old_energy_value=%f, action_energy_value=%f", current_energy, action_energy);
+  }
+}
+
+/* init Energy plugin */
+void sg_energy_plugin_init() {
+  if (surf_energy == NULL) {
+    surf_energy = new std::map<CpuPtr, CpuEnergyPtr>();
+    surf_callback_connect(createCpuCallbacks, createCpuCallback);
+    surf_callback_connect(deleteCpuCallbacks, deleteCpuCallback);
+    surf_callback_connect(updateCpuActionCallbacks, updateActionEnergyCallback);
+  }
+}
+
+CpuEnergy::CpuEnergy(CpuPtr ptr)
+ : cpu(ptr)
+{
+  total_energy = 0;
+  power_range_watts_list = getWattsRangeList();
+  last_updated = surf_get_clock();
+}
+
+CpuEnergy::~CpuEnergy(){
+  unsigned int iter;
+  xbt_dynar_t power_tuple = NULL;
+  xbt_dynar_foreach(power_range_watts_list, iter, power_tuple)
+    xbt_dynar_free(&power_tuple);
+  xbt_dynar_free(&power_range_watts_list);
+}
+
+
+/**
+ * Computes the power consumed by the host according to the current pstate and processor load
+ *
+ */
+double CpuEnergy::getCurrentWattsValue(double cpu_load)
+{
+       xbt_dynar_t power_range_list = power_range_watts_list;
+
+       if (power_range_list == NULL)
+       {
+               XBT_DEBUG("No power range properties specified for host %s", cpu->getName());
+               return 0;
+       }
+       /*xbt_assert(xbt_dynar_length(power_range_list) == xbt_dynar_length(cpu->p_powerPeakList),
+                                               "The number of power ranges in the properties does not match the number of pstates for host %s",
+                                               cpu->getName());*/
+
+    /* retrieve the power values associated with the current pstate */
+    xbt_dynar_t current_power_values = xbt_dynar_get_as(power_range_list, static_cast<CpuCas01Ptr>(cpu)->m_pstate, xbt_dynar_t);
+
+    /* min_power corresponds to the idle power (cpu load = 0) */
+    /* max_power is the power consumed at 100% cpu load       */
+    double min_power = xbt_dynar_get_as(current_power_values, 0, double);
+    double max_power = xbt_dynar_get_as(current_power_values, 1, double);
+    double power_slope = max_power - min_power;
+
+    double current_power = min_power + cpu_load * power_slope;
+
+       XBT_DEBUG("[get_current_watts] min_power=%f, max_power=%f, slope=%f", min_power, max_power, power_slope);
+    XBT_DEBUG("[get_current_watts] Current power (watts) = %f, load = %f", current_power, cpu_load);
+
+       return current_power;
+}
+
+double CpuEnergy::getConsumedEnergy()
+{
+  return total_energy;
+}
+
+xbt_dynar_t CpuEnergy::getWattsRangeList()
+{
+       xbt_dynar_t power_range_list;
+       xbt_dynar_t power_tuple;
+       int i = 0, pstate_nb=0;
+       xbt_dynar_t current_power_values;
+       double min_power, max_power;
+
+       if (cpu->getProperties() == NULL)
+               return NULL;
+
+       char* all_power_values_str = (char*)xbt_dict_get_or_null(cpu->getProperties(), "power_per_state");
+
+       if (all_power_values_str == NULL)
+               return NULL;
+
+
+       power_range_list = xbt_dynar_new(sizeof(xbt_dynar_t), NULL);
+       xbt_dynar_t all_power_values = xbt_str_split(all_power_values_str, ",");
+
+       pstate_nb = xbt_dynar_length(all_power_values);
+       for (i=0; i< pstate_nb; i++)
+       {
+               /* retrieve the power values associated with the current pstate */
+               current_power_values = xbt_str_split(xbt_dynar_get_as(all_power_values, i, char*), ":");
+               xbt_assert(xbt_dynar_length(current_power_values) > 1,
+                               "Power properties incorrectly defined - could not retrieve min and max power values for host %s",
+                               cpu->getName());
+
+               /* min_power corresponds to the idle power (cpu load = 0) */
+               /* max_power is the power consumed at 100% cpu load       */
+               min_power = atof(xbt_dynar_get_as(current_power_values, 0, char*));
+               max_power = atof(xbt_dynar_get_as(current_power_values, 1, char*));
+
+               power_tuple = xbt_dynar_new(sizeof(double), NULL);
+               xbt_dynar_push_as(power_tuple, double, min_power);
+               xbt_dynar_push_as(power_tuple, double, max_power);
+
+               xbt_dynar_push_as(power_range_list, xbt_dynar_t, power_tuple);
+               xbt_dynar_free(&current_power_values);
+       }
+       xbt_dynar_free(&all_power_values);
+       return power_range_list;
+}
diff --git a/src/surf/plugins/energy.hpp b/src/surf/plugins/energy.hpp
new file mode 100644 (file)
index 0000000..decb552
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * callback.hpp
+ *
+ *  Created on: Jan 10, 2014
+ *      Author: bedaride
+ */
+#include "../cpu_interface.hpp"
+#include <map>
+
+#ifndef CALLBACK_HPP_
+#define CALLBACK_HPP_
+
+class CpuEnergy;
+typedef CpuEnergy *CpuEnergyPtr;
+
+extern std::map<CpuPtr, CpuEnergyPtr> *surf_energy;
+
+class CpuEnergy {
+public:
+  CpuEnergy(CpuPtr ptr);
+  ~CpuEnergy();
+
+  double getCurrentWattsValue(double cpu_load);
+  double getConsumedEnergy();
+  xbt_dynar_t getWattsRangeList();
+
+  xbt_dynar_t power_range_watts_list;          /*< List of (min_power,max_power) pairs corresponding to each cpu pstate */
+  double total_energy;                                 /*< Total energy consumed by the host */
+  double last_updated;                                 /*< Timestamp of the last energy update event*/
+  CpuPtr cpu;
+};
+
+#endif /* CALLBACK_HPP_ */
index ecae88f..f085ec9 100644 (file)
@@ -4,6 +4,7 @@
 #include "network_interface.hpp"
 #include "surf_routing_cluster.hpp"
 #include "instr/instr_private.h"
+#include "plugins/energy.hpp"
 
 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_kernel);
 
@@ -334,7 +335,9 @@ void surf_workstation_set_power_peak_at(surf_resource_t resource, int pstate_ind
 }
 
 double surf_workstation_get_consumed_energy(surf_resource_t resource){
-  return get_casted_workstation(resource)->getConsumedEnergy();
+  xbt_assert(surf_energy!=NULL, "The Energy plugin is not active.");
+  std::map<CpuPtr, CpuEnergyPtr>::iterator cpuIt = surf_energy->find(get_casted_workstation(resource)->p_cpu);
+  return cpuIt->second->getConsumedEnergy();
 }
 
 xbt_dict_t surf_workstation_get_storage_list(surf_resource_t workstation){
index 20622d1..0f1c0ea 100644 (file)
@@ -84,6 +84,13 @@ xbt_dynar_t surf_path = NULL;
 xbt_dynar_t host_that_restart = NULL;
 xbt_dict_t watched_hosts_lib;
 
+s_surf_model_description_t surf_plugin_description[] = {
+                 {"Energy",
+                  "Cpu energy consumption.",
+                  sg_energy_plugin_init},
+                 {NULL, NULL,  NULL}      /* this array must be NULL terminated */
+};
+
 /* Don't forget to update the option description in smx_config when you change this */
 s_surf_model_description_t surf_network_model_description[] = {
   {"LV08",
index 741e155..3f5bde6 100644 (file)
 #include "simgrid/platf_interface.h"
 #include "surf/surf.h"
 #include "surf/surf_private.h"
+#include "internal_config.h"
+
+#define LIBSIGC ok
+#ifdef LIBSIGC
+#include <sigc++/sigc++.h>
+#define surf_callback(arg1, ...)  sigc::signal<arg1,__VA_ARGS__>
+#define surf_callback_connect(callback, fun_ptr) callback.connect(sigc::ptr_fun(fun_ptr))
+#define surf_callback_emit(callback, ...) callback.emit(__VA_ARGS__)
+#else
+#include <boost/signals2.hpp>
+#define surf_callback(arg1, ...)  boost::signals2::signal<arg1(__VA_ARGS__)>
+#define surf_callback_connect(callback, fun_ptr) callback.connect(fun_ptr)
+#define surf_callback_emit(callback, ...) callback(__VA_ARGS__)
+#endif
 
 extern tmgr_history_t history;
 #define NO_MAX_DURATION -1.0
@@ -77,6 +91,7 @@ typedef boost::intrusive::list<Action, boost::intrusive::base_hook<boost::intrus
 typedef ActionLmmList* ActionLmmListPtr;
 typedef boost::intrusive::list_base_hook<boost::intrusive::tag<lmmTag> > actionLmmHook;
 
+
 enum heap_action_type{
   LATENCY = 100,
   MAX_DURATION,
@@ -95,7 +110,6 @@ XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_link_avail;
 XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_bandwidth; 
 XBT_PUBLIC_DATA(xbt_dict_t) trace_connect_list_latency;
 
-
 /*********
  * Model *
  *********/
index b6df595..92dd79e 100644 (file)
@@ -123,11 +123,6 @@ void Workstation::setPowerPeakAt(int pstate_index)
        p_cpu->setPowerPeakAt(pstate_index);
 }
 
-double Workstation::getConsumedEnergy()
-{
-  return p_cpu->getConsumedEnergy();
-}
-
 xbt_dict_t Workstation::getProperties()
 {
   return p_cpu->getProperties();
index 2432c0f..cf5f66d 100644 (file)
@@ -69,7 +69,6 @@ public:
   virtual double getPowerPeakAt(int pstate_index);
   virtual int getNbPstates();
   virtual void setPowerPeakAt(int pstate_index);
-  virtual double getConsumedEnergy();
 
   virtual StoragePtr findStorageOnMountList(const char* storage);
   virtual xbt_dict_t getStorageList();