From e31812bc030130c0faf6ff6fe5ca44bee440f4fb Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Thu, 12 Jan 2012 17:21:26 +0000 Subject: [PATCH] - even more mlp --- src/ats/Makefile.am | 3 +- src/ats/gnunet-service-ats.c | 4 +- src/ats/gnunet-service-ats_addresses.c | 6 +- src/ats/gnunet-service-ats_addresses.h | 6 +- src/ats/gnunet-service-ats_addresses_mlp.c | 91 +++++++++++++++++++++- src/ats/gnunet-service-ats_addresses_mlp.h | 41 +++++++++- 6 files changed, 139 insertions(+), 12 deletions(-) diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am index c8a78bc20..d6ffebc8f 100644 --- a/src/ats/Makefile.am +++ b/src/ats/Makefile.am @@ -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 = \ diff --git a/src/ats/gnunet-service-ats.c b/src/ats/gnunet-service-ats.c index ff623594a..7deca0b62 100644 --- a/src/ats/gnunet-service-ats.c +++ b/src/ats/gnunet-service-ats.c @@ -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, diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index 6df44f9c4..0b2d464b6 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c @@ -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"); diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h index 3709853a7..ad34c94f2 100644 --- a/src/ats/gnunet-service-ats_addresses.h +++ b/src/ats/gnunet-service-ats_addresses.h @@ -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); /** diff --git a/src/ats/gnunet-service-ats_addresses_mlp.c b/src/ats/gnunet-service-ats_addresses_mlp.c index 946a2848d..ca192b8a4 100644 --- a/src/ats/gnunet-service-ats_addresses_mlp.c +++ b/src/ats/gnunet-service-ats_addresses_mlp.c @@ -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; diff --git a/src/ats/gnunet-service-ats_addresses_mlp.h b/src/ats/gnunet-service-ats_addresses_mlp.h index 9272a2914..2555846ff 100644 --- a/src/ats/gnunet-service-ats_addresses_mlp.h +++ b/src/ats/gnunet-service-ats_addresses_mlp.h @@ -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 @@ -39,8 +40,16 @@ #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 -- 2.25.1