added simulation
[oweals/gnunet.git] / src / ats / libgnunet_plugin_ats_mlp.c
index f45c5fe0b76b43e55f1d69c451e9ab2360bb1721..07f77161fcfa137608d47a84a4650a709c10fd99 100644 (file)
@@ -1078,10 +1078,12 @@ mlp_propagate_results (void *cls,
 }
 
 static void notify (struct GAS_MLP_Handle *mlp,
-    enum GAS_Solver_Operation op, enum GAS_Solver_Status stat)
+    enum GAS_Solver_Operation op,
+    enum GAS_Solver_Status stat,
+    enum GAS_Solver_Additional_Information add)
 {
   if (NULL != mlp->env->info_cb)
-    mlp->env->info_cb (mlp->env->info_cb_cls, op, stat);
+    mlp->env->info_cb (mlp->env->info_cb_cls, op, stat, add);
 }
 /**
  * Solves the MLP problem
@@ -1096,99 +1098,144 @@ GAS_mlp_solve_problem (void *solver)
   char *filename;
   int res_lp = 0;
   int res_mip = 0;
-  GNUNET_assert (NULL != solver);
+
+  struct GNUNET_TIME_Absolute start;
+  struct GNUNET_TIME_Relative dur_total;
+  struct GNUNET_TIME_Relative dur_setup;
+  struct GNUNET_TIME_Relative dur_lp;
+  struct GNUNET_TIME_Relative dur_mlp;
+
+  GNUNET_assert(NULL != solver);
 
   if (GNUNET_YES == mlp->bulk_lock)
-  {
-    mlp->bulk_request ++;
-    return GNUNET_NO;
-  }
-  notify (mlp, GAS_OP_SOLVE_START, GAS_STAT_SUCCESS);
+    {
+      mlp->bulk_request++;
+      return GNUNET_NO;
+    }
+  notify(mlp, GAS_OP_SOLVE_START, GAS_STAT_SUCCESS,
+      (GNUNET_YES == mlp->mlp_prob_changed) ? GAS_INFO_FULL : GAS_INFO_UPDATED);
+  start = GNUNET_TIME_absolute_get();
 
-  if (0 == GNUNET_CONTAINER_multipeermap_size (mlp->requested_peers))
-  {
-    notify (mlp, GAS_OP_SOLVE_STOP, GAS_STAT_SUCCESS);
-    return GNUNET_OK; /* No pending requests */
-  }
-  if (0 == GNUNET_CONTAINER_multipeermap_size (mlp->addresses))
-  {
-    notify (mlp, GAS_OP_SOLVE_STOP, GAS_STAT_SUCCESS);
-    return GNUNET_OK; /* No addresses available */
-  }
+  if (0 == GNUNET_CONTAINER_multipeermap_size(mlp->requested_peers))
+    {
+      notify(mlp, GAS_OP_SOLVE_STOP, GAS_STAT_SUCCESS, GAS_INFO_NONE);
+      return GNUNET_OK; /* No pending requests */
+    }
+  if (0 == GNUNET_CONTAINER_multipeermap_size(mlp->addresses))
+    {
+      notify(mlp, GAS_OP_SOLVE_STOP, GAS_STAT_SUCCESS, GAS_INFO_NONE);
+      return GNUNET_OK; /* No addresses available */
+    }
 
-  if ((GNUNET_NO == mlp->mlp_prob_changed) && (GNUNET_NO == mlp->mlp_prob_updated))
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "No changes to problem\n");
-    notify (mlp, GAS_OP_SOLVE_STOP, GAS_STAT_SUCCESS);
-    return GNUNET_OK;
-  }
+  if ((GNUNET_NO == mlp->mlp_prob_changed)
+      && (GNUNET_NO == mlp->mlp_prob_updated))
+    {
+      LOG(GNUNET_ERROR_TYPE_DEBUG, "No changes to problem\n");
+      notify(mlp, GAS_OP_SOLVE_STOP, GAS_STAT_SUCCESS, GAS_INFO_NONE);
+      return GNUNET_OK;
+    }
   if (GNUNET_YES == mlp->mlp_prob_changed)
-  {
-      LOG (GNUNET_ERROR_TYPE_DEBUG, "Problem size changed, rebuilding\n");
-      notify (mlp, GAS_OP_SOLVE_SETUP_START, GAS_STAT_SUCCESS);
-      mlp_delete_problem (mlp);
-      if (GNUNET_SYSERR == mlp_create_problem (mlp))
-      {
-        notify (mlp, GAS_OP_SOLVE_SETUP_STOP, GAS_STAT_FAIL);
-        return GNUNET_SYSERR;
-      }
-      notify (mlp, GAS_OP_SOLVE_SETUP_STOP, GAS_STAT_SUCCESS);
+    {
+      LOG(GNUNET_ERROR_TYPE_DEBUG, "Problem size changed, rebuilding\n");
+      notify(mlp, GAS_OP_SOLVE_SETUP_START, GAS_STAT_SUCCESS, GAS_INFO_FULL);
+      mlp_delete_problem(mlp);
+      if (GNUNET_SYSERR == mlp_create_problem(mlp))
+        {
+          notify(mlp, GAS_OP_SOLVE_SETUP_STOP, GAS_STAT_FAIL, GAS_INFO_FULL);
+          return GNUNET_SYSERR;
+        }
+      notify(mlp, GAS_OP_SOLVE_SETUP_STOP, GAS_STAT_SUCCESS, GAS_INFO_FULL);
       mlp->control_param_lp.presolve = GLP_YES;
       mlp->control_param_mlp.presolve = GNUNET_NO; /* No presolver, we have LP solution */
-  }
+    }
   else
-  {
-      LOG (GNUNET_ERROR_TYPE_DEBUG, "Problem was updated, resolving\n");
-  }
+    {
+      LOG(GNUNET_ERROR_TYPE_DEBUG, "Problem was updated, resolving\n");
+    }
 
+  dur_setup = GNUNET_TIME_absolute_get_duration (start);
+  mlp->control_param_lp.presolve = GLP_YES;
   /* Run LP solver */
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Running LP solver %s\n",
+
+  notify(mlp, GAS_OP_SOLVE_MLP_LP_START, GAS_STAT_SUCCESS,
+      (GNUNET_YES == mlp->mlp_prob_changed) ? GAS_INFO_FULL : GAS_INFO_UPDATED);
+  LOG(GNUNET_ERROR_TYPE_DEBUG,
+      "Running LP solver %s\n",
       (GLP_YES == mlp->control_param_lp.presolve)? "with presolver": "without presolver");
-  notify (mlp, GAS_OP_SOLVE_LP_START, GAS_STAT_SUCCESS);
-  res_lp = mlp_solve_lp_problem (mlp);
-  notify (mlp, GAS_OP_SOLVE_LP_STOP, (GNUNET_OK == res_lp) ? GAS_STAT_SUCCESS : GAS_STAT_FAIL);
+  res_lp = mlp_solve_lp_problem(mlp);
+  notify(mlp, GAS_OP_SOLVE_MLP_LP_STOP,
+      (GNUNET_OK == res_lp) ? GAS_STAT_SUCCESS : GAS_STAT_FAIL,
+      (GNUNET_YES == mlp->mlp_prob_changed) ? GAS_INFO_FULL : GAS_INFO_UPDATED);
 
+  dur_lp = GNUNET_TIME_absolute_get_duration (start);
+  dur_lp = GNUNET_TIME_relative_subtract(dur_lp, dur_setup);
 
   /* Run MLP solver */
-  LOG (GNUNET_ERROR_TYPE_DEBUG, "Running MLP solver \n");
-  notify (mlp, GAS_OP_SOLVE_MLP_START, GAS_STAT_SUCCESS);
-  res_mip = mlp_solve_mlp_problem (mlp);
-  notify (mlp, GAS_OP_SOLVE_MLP_STOP, (GNUNET_OK == res_mip) ? GAS_STAT_SUCCESS : GAS_STAT_FAIL);
+  LOG(GNUNET_ERROR_TYPE_DEBUG, "Running MLP solver \n");
+  notify(mlp, GAS_OP_SOLVE_MLP_MLP_START, GAS_STAT_SUCCESS,
+      (GNUNET_YES == mlp->mlp_prob_changed) ? GAS_INFO_FULL : GAS_INFO_UPDATED);
+  res_mip = mlp_solve_mlp_problem(mlp);
+  notify(mlp, GAS_OP_SOLVE_MLP_MLP_STOP,
+      (GNUNET_OK == res_lp) ? GAS_STAT_SUCCESS : GAS_STAT_FAIL,
+      (GNUNET_YES == mlp->mlp_prob_changed) ? GAS_INFO_FULL : GAS_INFO_UPDATED);
+  notify(mlp, GAS_OP_SOLVE_STOP,
+      (GNUNET_OK == res_mip) ? GAS_STAT_SUCCESS : GAS_STAT_FAIL,
+      (GNUNET_YES == mlp->mlp_prob_changed) ? GAS_INFO_FULL : GAS_INFO_UPDATED);
+
+  dur_mlp = GNUNET_TIME_absolute_get_duration (start);
+  dur_mlp = GNUNET_TIME_relative_subtract(dur_mlp, dur_setup);
+  dur_mlp = GNUNET_TIME_relative_subtract(dur_mlp, dur_lp);
+  dur_total = GNUNET_TIME_absolute_get_duration (start);
 
-  notify (mlp, GAS_OP_SOLVE_STOP, (GNUNET_OK == res_mip) ? GAS_STAT_SUCCESS : GAS_STAT_FAIL);
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+      "Execution time for %s solve: (total/setup/lp/mlp) : %llu %llu %llu %llu\n",
+      (GNUNET_YES == mlp->mlp_prob_changed) ? "full" : "updated",
+      (unsigned long long) dur_total.rel_value_us,
+      (unsigned long long) dur_setup.rel_value_us,
+      (unsigned long long) dur_lp.rel_value_us,
+      (unsigned long long) dur_mlp.rel_value_us);
 
   /* Save stats */
   mlp->ps.lp_res = res_lp;
   mlp->ps.mip_res = res_mip;
   mlp->ps.lp_presolv = mlp->control_param_lp.presolve;
   mlp->ps.mip_presolv = mlp->control_param_mlp.presolve;
-  mlp->ps.p_cols = glp_get_num_cols (mlp->p.prob);
-  mlp->ps.p_rows = glp_get_num_rows (mlp->p.prob);
+  mlp->ps.p_cols = glp_get_num_cols(mlp->p.prob);
+  mlp->ps.p_rows = glp_get_num_rows(mlp->p.prob);
   mlp->ps.p_elements = mlp->p.num_elements;
 
   /* Propagate result*/
+  notify(mlp, GAS_OP_SOLVE_UPDATE_NOTIFICATION_START,
+      (GNUNET_OK == res_lp) && (GNUNET_OK == res_mip) ? GAS_STAT_SUCCESS : GAS_STAT_FAIL,
+      GAS_INFO_NONE);
   if ((GNUNET_OK == res_lp) && (GNUNET_OK == res_mip))
-  {
-    GNUNET_CONTAINER_multipeermap_iterate (mlp->addresses, &mlp_propagate_results, mlp);
-  }
+    {
+      GNUNET_CONTAINER_multipeermap_iterate(mlp->addresses,
+          &mlp_propagate_results, mlp);
+    }
+  notify(mlp, GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP,
+      (GNUNET_OK == res_lp) && (GNUNET_OK == res_mip) ? GAS_STAT_SUCCESS : GAS_STAT_FAIL,
+      GAS_INFO_NONE);
 
   struct GNUNET_TIME_Absolute time = GNUNET_TIME_absolute_get();
   if (GNUNET_YES == mlp->write_mip_mps)
-  {
-    /* Write problem to disk */
-    GNUNET_asprintf (&filename, "problem_p_%u_a%u_%llu.mps", mlp->p.num_peers, mlp->p.num_addresses, time.abs_value_us);
-    LOG (GNUNET_ERROR_TYPE_ERROR, "DUMP: %s \n", filename);
-    glp_write_lp(mlp->p.prob, NULL, filename);
-    GNUNET_free (filename);
-  }
+    {
+      /* Write problem to disk */
+      GNUNET_asprintf(&filename, "problem_p_%u_a%u_%llu.mps", mlp->p.num_peers,
+          mlp->p.num_addresses, time.abs_value_us);
+      LOG(GNUNET_ERROR_TYPE_ERROR, "DUMP: %s \n", filename);
+      glp_write_lp(mlp->p.prob, NULL, filename);
+      GNUNET_free(filename);
+    }
   if (GNUNET_YES == mlp->write_mip_sol)
-  {
-    /* Write solution to disk */
-    GNUNET_asprintf (&filename, "problem_p_%u_a%u_%llu.sol", mlp->p.num_peers, mlp->p.num_addresses, time.abs_value_us);
-    glp_print_mip (mlp->p.prob, filename );
-    LOG (GNUNET_ERROR_TYPE_ERROR, "DUMP: %s \n", filename);
-    GNUNET_free (filename);
-  }
+    {
+      /* Write solution to disk */
+      GNUNET_asprintf(&filename, "problem_p_%u_a%u_%llu.sol", mlp->p.num_peers,
+          mlp->p.num_addresses, time.abs_value_us);
+      glp_print_mip(mlp->p.prob, filename);
+      LOG(GNUNET_ERROR_TYPE_ERROR, "DUMP: %s \n", filename);
+      GNUNET_free(filename);
+    }
 
   /* Reset change and update marker */
   mlp->control_param_lp.presolve = GLP_NO;
@@ -1219,6 +1266,12 @@ GAS_mlp_address_add (void *solver,
   GNUNET_assert (NULL != solver);
   GNUNET_assert (NULL != address);
 
+  if (GNUNET_ATS_NetworkTypeCount <= network)
+  {
+   GNUNET_break (0);
+   return;
+  }
+
   if (NULL == address->solver_information)
   {
       address->solver_information = GNUNET_new (struct MLP_information);
@@ -1382,6 +1435,12 @@ GAS_mlp_address_change_network (void *solver,
   GNUNET_assert (NULL != solver);
   GNUNET_assert (NULL != address);
 
+  if (GNUNET_ATS_NetworkTypeCount <= new_network)
+  {
+   GNUNET_break (0);
+   return;
+  }
+
   if (NULL == mlpi)
   {
     GNUNET_break (0);
@@ -1741,8 +1800,9 @@ GAS_mlp_address_change_preference (void *solver,
     return;
   }
   p->f = get_peer_pref_value (mlp, peer);
+  /*
   LOG (GNUNET_ERROR_TYPE_ERROR, "PEER PREF: %s %.2f\n",
-      GNUNET_i2s(peer), p->f);
+      GNUNET_i2s(peer), p->f);*/
   mlp_create_problem_update_value (&mlp->p, p->r_c9, mlp->p.c_r, -p->f, __LINE__);
 
   /* Problem size changed: new address for peer with pending request */