- even more mlp
authorMatthias Wachs <wachs@net.in.tum.de>
Thu, 12 Jan 2012 17:21:26 +0000 (17:21 +0000)
committerMatthias Wachs <wachs@net.in.tum.de>
Thu, 12 Jan 2012 17:21:26 +0000 (17:21 +0000)
src/ats/Makefile.am
src/ats/gnunet-service-ats.c
src/ats/gnunet-service-ats_addresses.c
src/ats/gnunet-service-ats_addresses.h
src/ats/gnunet-service-ats_addresses_mlp.c
src/ats/gnunet-service-ats_addresses_mlp.h

index c8a78bc20bcf43f8ff6e9977bf37485095a070e4..d6ffebc8fbd1bd3c5c23986c8b9797d390f1adef 100644 (file)
@@ -66,7 +66,8 @@ test_ats_mlp_SOURCES = \
  test_ats_mlp.c
 test_ats_mlp_LDADD = \
   $(GN_LIBGLPK) \
-  $(top_builddir)/src/util/libgnunetutil.la
+  $(top_builddir)/src/util/libgnunetutil.la \
+  $(top_builddir)/src/statistics/libgnunetstatistics.la
 endif
 
 test_ats_api_scheduling_SOURCES = \
index ff623594a0401d317d71fa0e034d4ddf0f45b19d..7deca0b62320d8e85a71116ebe127da32c0e0c9a 100644 (file)
@@ -114,7 +114,7 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   if (NULL != GSA_stats)
   {
     GNUNET_STATISTICS_destroy (GSA_stats, GNUNET_NO);
-    GSA_stats = 0;
+    GSA_stats = NULL;
   }
 }
 
@@ -156,7 +156,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
   GAS_reservations_init ();
   GAS_performance_init (server);
   GAS_scheduling_init (server);
-  GAS_addresses_init (cfg);
+  GAS_addresses_init (cfg, GSA_stats);
   GNUNET_SERVER_disconnect_notify (server, &client_disconnect_handler, NULL);
   GNUNET_SERVER_add_handlers (server, handlers);
   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleanup_task,
index 6df44f9c469bcc3f1fc02d1513db5e2523e0f51d..0b2d464b6805feeb05a38dc7290b85a80c02d5ff 100644 (file)
@@ -441,9 +441,11 @@ GAS_addresses_change_preference (const struct GNUNET_PeerIdentity *peer,
  * Initialize address subsystem.
  *
  * @param cfg configuration to use
+ * @param stats the statistics handle to use
  */
 void
-GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
+GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
+                    const struct GNUNET_STATISTICS_Handle *stats)
 {
   GNUNET_assert (GNUNET_OK ==
                  GNUNET_CONFIGURATION_get_value_size (cfg, "ats",
@@ -463,7 +465,7 @@ GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
 #if HAVE_LIBGLPK
           ats_mode = MLP;
           /* Init the MLP solver with default values */
-          GAS_mlp_init (MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS);
+          GAS_mlp_init (stats, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS);
           break;
 #else
           GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP mode was configured, but libglpk is not installed, switching to simple mode");
index 3709853a7c3bee63974e6e0d6611e05f12d0455a..ad34c94f257f525ec9f22efd0c60c60d0e9c6b88 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "gnunet_util_lib.h"
 #include "gnunet_ats_service.h"
+#include "gnunet_statistics_service.h"
 #include "ats.h"
 
 struct ATS_Address
@@ -76,10 +77,13 @@ struct ATS_Address
 
 /**
  * Initialize address subsystem.
+ *
  * @param cfg configuration to use
+ * @param stats the statistics handle to use
  */
 void
-GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg);
+GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
+                    const struct GNUNET_STATISTICS_Handle *stats);
 
 
 /**
index 946a2848d6f4d39ec5474ecc332059fb67ffeca8..ca192b8a45116e6d0464d4b10cf304bbf8d9894c 100644 (file)
@@ -28,6 +28,7 @@
 #include "gnunet_util_lib.h"
 #include "gnunet-service-ats_addresses.h"
 #include "gnunet-service-ats_addresses_mlp.h"
+#include "gnunet_statistics_service.h"
 #if HAVE_LIBGLPK
 #include "glpk.h"
 #endif
@@ -39,13 +40,16 @@ static struct GAS_MLP_Handle *GAS_mlp;
 
 
 /**
- * Solves the MLP problem
+ * Solves the LP problem
  * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
  */
 int
 mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp)
 {
   int res;
+  struct GNUNET_TIME_Relative duration;
+  struct GNUNET_TIME_Absolute end;
+  struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get();
 
   /* LP presolver?
    * Presolver is required if the problem was modified and an existing
@@ -55,7 +59,6 @@ mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp)
   else
     mlp->control_param_lp.presolve = GLP_OFF;
 
-
   /* Solve LP problem to have initial valid solution */
 lp_solv:
   res = glp_simplex(mlp->prob, &mlp->control_param_lp);
@@ -91,6 +94,17 @@ lp_solv:
     }
   }
 
+  end = GNUNET_TIME_absolute_get ();
+  duration = GNUNET_TIME_absolute_get_difference (start, end);
+  mlp->lp_solved++;
+  mlp->lp_total_duration =+ duration.rel_value;
+
+  GNUNET_STATISTICS_update (mlp->stats,"# LP problem solved", 1, GNUNET_NO);
+  GNUNET_STATISTICS_set (mlp->stats,"# LP execution time", duration.rel_value, GNUNET_NO);
+  GNUNET_STATISTICS_set (mlp->stats,"# LP execution time average",
+                         mlp->lp_total_duration / mlp->lp_solved,  GNUNET_NO);
+
+
   /* Analyze problem status  */
   res = glp_get_status (mlp->prob);
   switch (res) {
@@ -116,16 +130,86 @@ lp_solv:
 }
 
 
+/**
+ * Solves the MLP problem
+ * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
+ */
+int
+mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp)
+{
+  int res;
+  struct GNUNET_TIME_Relative duration;
+  struct GNUNET_TIME_Absolute end;
+  struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get();
+
+  /* solve MLP problem */
+  res = glp_intopt(mlp->prob, &mlp->control_param_mlp);
+  if (res == 0)
+  {
+    /* The MLP problem instance has been successfully solved. */
+  }
+  else if (res == GLP_EITLIM)
+  {
+    /* simplex iteration limit has been exceeded. */
+    // TODO Increase iteration limit?
+  }
+  else if (res == GLP_ETMLIM)
+  {
+    /* Time limit has been exceeded.  */
+    // TODO Increase time limit?
+  }
+  else
+  {
+    /* Problem was ill-defined, no way to handle that */
+    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
+        "ats-mlp",
+        "Solving MLP problem failed: glp_intopt error 0x%X", res);
+    return GNUNET_SYSERR;
+  }
+
+  end = GNUNET_TIME_absolute_get ();
+  duration = GNUNET_TIME_absolute_get_difference (start, end);
+  mlp->mlp_solved++;
+  mlp->mlp_total_duration =+ duration.rel_value;
+
+  GNUNET_STATISTICS_update (mlp->stats,"# MLP problem solved", 1, GNUNET_NO);
+  GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time", duration.rel_value, GNUNET_NO);
+  GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time average",
+                         mlp->mlp_total_duration / mlp->mlp_solved,  GNUNET_NO);
+
+  /* Analyze problem status  */
+  res = glp_mip_status(mlp->prob);
+  switch (res) {
+    /* solution is optimal */
+    case GLP_OPT:
+    /* solution is feasible */
+    case GLP_FEAS:
+      break;
+
+    /* Problem was ill-defined, no way to handle that */
+    default:
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
+          "ats-mlp",
+          "Solving MLP problem failed, no solution: glp_mip_status 0x%X", res);
+      return GNUNET_SYSERR;
+      break;
+  }
+
+  return GNUNET_OK;
+}
 
 /**
  * Init the MLP problem solving component
  *
+ * @param stats the GNUNET_STATISTICS handle
  * @param max_duration maximum numbers of iterations for the LP/MLP Solver
  * @param max_iterations maximum time limit for the LP/MLP Solver
  * @return GNUNET_OK on success, GNUNET_SYSERR on fail
  */
 int
-GAS_mlp_init (struct GNUNET_TIME_Relative max_duration, unsigned int max_iterations)
+GAS_mlp_init (const struct GNUNET_STATISTICS_Handle *stats,
+              struct GNUNET_TIME_Relative max_duration,
+              unsigned int max_iterations)
 {
   GAS_mlp = GNUNET_malloc (sizeof (struct GAS_MLP_Handle));
 
@@ -136,6 +220,7 @@ GAS_mlp_init (struct GNUNET_TIME_Relative max_duration, unsigned int max_iterati
   GAS_mlp->prob = glp_create_prob();
   GNUNET_assert (GAS_mlp->prob != NULL);
 
+  GAS_mlp->stats = (struct GNUNET_STATISTICS_Handle *) stats;
   GAS_mlp->max_iterations = max_iterations;
   GAS_mlp->max_exec_duration = max_duration;
 
index 9272a291462130ea0afd1dc226d91246765ea30f..2555846ff0ea535e3b08ecd3b7e6474057a7dec9 100644 (file)
@@ -25,7 +25,8 @@
  * @author Christian Grothoff
  */
 #include "platform.h"
-
+#include "gnunet_statistics_service.h"
+#include "gnunet-service-ats_addresses.h"
 #if HAVE_LIBGLPK
 #include "glpk.h"
 #endif
 #define MLP_MAX_EXEC_DURATION   GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 3)
 #define MLP_MAX_ITERATIONS      INT_MAX
 
+/**
+ * MLP Handle
+ */
 struct GAS_MLP_Handle
 {
+  /**
+   * Statistics handle
+   */
+  struct GNUNET_STATISTICS_Handle *stats;
+
   /**
    * GLPK (MLP) problem object
    */
@@ -70,7 +79,6 @@ struct GAS_MLP_Handle
    */
   unsigned int max_iterations;
 
-
   /* state information */
 
   /**
@@ -84,16 +92,43 @@ struct GAS_MLP_Handle
    * presolver_required == GNUNET_NO
    */
   int presolver_required;
+
+  /* statistics */
+
+  /**
+   * How often was the LP problem solved
+   */
+  unsigned int lp_solved;
+
+  /**
+   * total duration of all lp solver executions
+   */
+  uint64_t lp_total_duration;
+
+  /**
+   * How often was the MLP problem solved
+   */
+  unsigned int mlp_solved;
+
+  /**
+   * total duration of all mlp solver executions
+   */
+  uint64_t mlp_total_duration;
 };
 
+
 /**
  * Init the MLP problem solving component
+ *
+ * @param stats the GNUNET_STATISTICS handle
  * @param max_duration maximum numbers of iterations for the LP/MLP Solver
  * @param max_iterations maximum time limit for the LP/MLP Solver
  * @return GNUNET_OK on success, GNUNET_SYSERR on fail
  */
 int
-GAS_mlp_init (struct GNUNET_TIME_Relative max_duration, unsigned int max_iterations);
+GAS_mlp_init (const struct GNUNET_STATISTICS_Handle *stats,
+              struct GNUNET_TIME_Relative max_duration,
+              unsigned int max_iterations);
 
 /**
  * Update address in the MLP problem