Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix set_read_bandwidth and set_write_bandwidth for disks
[simgrid.git] / src / kernel / lmm / maxmin.cpp
index 793c0f7..80d0519 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "src/kernel/lmm/maxmin.hpp"
 #include <boost/core/demangle.hpp>
+#include <typeinfo>
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_maxmin, surf, "Logging specific to SURF (maxmin)");
 
@@ -116,8 +117,7 @@ void System::var_free(Variable* var)
       simgrid::xbt::intrusive_erase(elem.constraint->disabled_element_set_, elem);
     if (elem.active_element_set_hook.is_linked())
       simgrid::xbt::intrusive_erase(elem.constraint->active_element_set_, elem);
-    int nelements = elem.constraint->enabled_element_set_.size() + elem.constraint->disabled_element_set_.size();
-    if (nelements == 0)
+    if (elem.constraint->enabled_element_set_.empty() && elem.constraint->disabled_element_set_.empty())
       make_constraint_inactive(elem.constraint);
     else
       on_disabled_var(elem.constraint);
@@ -236,7 +236,7 @@ void System::expand(Constraint* cnst, Variable* var, double consumption_weight)
 
   xbt_assert(var->cnsts_.size() < var->cnsts_.capacity(), "Too much constraints");
 
-  var->cnsts_.resize(var->cnsts_.size() + 1);
+  var->cnsts_.emplace_back();
   Element& elem = var->cnsts_.back();
 
   elem.consumption_weight = consumption_weight;
@@ -276,7 +276,7 @@ void System::expand_add(Constraint* cnst, Variable* var, double value)
     if (var->sharing_penalty_ != 0.0)
       elem.decrease_concurrency();
 
-    if (cnst->sharing_policy_ != s4u::Link::SharingPolicy::FATPIPE)
+    if (cnst->sharing_policy_ != Constraint::SharingPolicy::FATPIPE)
       elem.consumption_weight += value;
     else
       elem.consumption_weight = std::max(elem.consumption_weight, value);
@@ -335,7 +335,7 @@ Variable* Constraint::get_variable(const Element** elem) const
 
 // if we modify the list between calls, normal version may loop forever
 // this safe version ensures that we browse the list elements only once
-Variable* Constraint::get_variable_safe(const Element** elem, const Element** nextelem, int* numelem) const
+Variable* Constraint::get_variable_safe(const Element** elem, const Element** nextelem, size_t* numelem) const
 {
   if (*elem == nullptr) {
     *numelem = enabled_element_set_.size() + disabled_element_set_.size() - 1;
@@ -402,14 +402,14 @@ static inline void saturated_variable_set_update(const ConstraintLight* cnst_lig
 }
 
 template <class ElemList>
-static void format_element_list(const ElemList& elem_list, s4u::Link::SharingPolicy sharing_policy, double& sum,
+static void format_element_list(const ElemList& elem_list, Constraint::SharingPolicy sharing_policy, double& sum,
                                 std::string& buf)
 {
   for (Element const& elem : elem_list) {
     buf += std::to_string(elem.consumption_weight) + ".'" + std::to_string(elem.variable->rank_) + "'(" +
            std::to_string(elem.variable->value_) + ")" +
-           (sharing_policy != s4u::Link::SharingPolicy::FATPIPE ? " + " : " , ");
-    if (sharing_policy != s4u::Link::SharingPolicy::FATPIPE)
+           (sharing_policy != Constraint::SharingPolicy::FATPIPE ? " + " : " , ");
+    if (sharing_policy != Constraint::SharingPolicy::FATPIPE)
       sum += elem.consumption_weight * elem.variable->value_;
     else
       sum = std::max(sum, elem.consumption_weight * elem.variable->value_);
@@ -433,14 +433,14 @@ void System::print() const
     double sum            = 0.0;
     // Show  the enabled variables
     buf += "\t";
-    buf += cnst.sharing_policy_ != s4u::Link::SharingPolicy::FATPIPE ? "(" : "max(";
+    buf += cnst.sharing_policy_ != Constraint::SharingPolicy::FATPIPE ? "(" : "max(";
     format_element_list(cnst.enabled_element_set_, cnst.sharing_policy_, sum, buf);
     // TODO: Adding disabled elements only for test compatibility, but do we really want them to be printed?
     format_element_list(cnst.disabled_element_set_, cnst.sharing_policy_, sum, buf);
 
     buf += "0) <= " + std::to_string(cnst.bound_) + " ('" + std::to_string(cnst.rank_) + "')";
 
-    if (cnst.sharing_policy_ == s4u::Link::SharingPolicy::FATPIPE) {
+    if (cnst.sharing_policy_ == Constraint::SharingPolicy::FATPIPE) {
       buf += " [MAX-Constraint]";
     }
     XBT_DEBUG("%s", buf.c_str());
@@ -490,15 +490,19 @@ template <class CnstList> void System::lmm_solve(CnstList& cnst_list)
   for (Constraint& cnst : cnst_list) {
     /* INIT: Collect constraints that actually need to be saturated (i.e remaining  and usage are strictly positive)
      * into cnst_light_tab. */
-    cnst.remaining_ = cnst.bound_;
-    if (not double_positive(cnst.remaining_, cnst.bound_ * sg_maxmin_precision))
+    cnst.dynamic_bound_ = cnst.bound_;
+    if (cnst.get_sharing_policy() == Constraint::SharingPolicy::NONLINEAR && cnst.dyn_constraint_cb_) {
+      cnst.dynamic_bound_ = cnst.dyn_constraint_cb_(cnst.bound_, cnst.concurrency_current_);
+    }
+    cnst.remaining_ = cnst.dynamic_bound_;
+    if (not double_positive(cnst.remaining_, cnst.dynamic_bound_ * sg_maxmin_precision))
       continue;
     cnst.usage_ = 0;
     for (Element& elem : cnst.enabled_element_set_) {
       xbt_assert(elem.variable->sharing_penalty_ > 0.0);
       elem.variable->value_ = 0.0;
       if (elem.consumption_weight > 0) {
-        if (cnst.sharing_policy_ != s4u::Link::SharingPolicy::FATPIPE)
+        if (cnst.sharing_policy_ != Constraint::SharingPolicy::FATPIPE)
           cnst.usage_ += elem.consumption_weight / elem.variable->sharing_penalty_;
         else if (cnst.usage_ < elem.consumption_weight / elem.variable->sharing_penalty_)
           cnst.usage_ = elem.consumption_weight / elem.variable->sharing_penalty_;
@@ -571,17 +575,18 @@ template <class CnstList> void System::lmm_solve(CnstList& cnst_list)
       /* Update the usage of constraints where this variable is involved */
       for (Element& elem : var.cnsts_) {
         Constraint* cnst = elem.constraint;
-        if (cnst->sharing_policy_ != s4u::Link::SharingPolicy::FATPIPE) {
+        if (cnst->sharing_policy_ != Constraint::SharingPolicy::FATPIPE) {
           // Remember: shared constraints require that sum(elem.value * var.value) < cnst->bound
-          double_update(&(cnst->remaining_), elem.consumption_weight * var.value_, cnst->bound_ * sg_maxmin_precision);
+          double_update(&(cnst->remaining_), elem.consumption_weight * var.value_,
+                        cnst->dynamic_bound_ * sg_maxmin_precision);
           double_update(&(cnst->usage_), elem.consumption_weight / var.sharing_penalty_, sg_maxmin_precision);
           // If the constraint is saturated, remove it from the set of active constraints (light_tab)
           if (not double_positive(cnst->usage_, sg_maxmin_precision) ||
-              not double_positive(cnst->remaining_, cnst->bound_ * sg_maxmin_precision)) {
+              not double_positive(cnst->remaining_, cnst->dynamic_bound_ * sg_maxmin_precision)) {
             if (cnst->cnst_light_) {
-              int index = (cnst->cnst_light_ - cnst_light_tab);
-              XBT_DEBUG("index: %d \t cnst_light_num: %d \t || usage: %f remaining: %f bound: %f  ", index,
-                        cnst_light_num, cnst->usage_, cnst->remaining_, cnst->bound_);
+              size_t index = (cnst->cnst_light_ - cnst_light_tab);
+              XBT_DEBUG("index: %zu \t cnst_light_num: %d \t || usage: %f remaining: %f bound: %f  ", index,
+                        cnst_light_num, cnst->usage_, cnst->remaining_, cnst->dynamic_bound_);
               cnst_light_tab[index]                  = cnst_light_tab[cnst_light_num - 1];
               cnst_light_tab[index].cnst->cnst_light_ = &cnst_light_tab[index];
               cnst_light_num--;
@@ -606,13 +611,13 @@ template <class CnstList> void System::lmm_solve(CnstList& cnst_list)
           }
           // If the constraint is saturated, remove it from the set of active constraints (light_tab)
           if (not double_positive(cnst->usage_, sg_maxmin_precision) ||
-              not double_positive(cnst->remaining_, cnst->bound_ * sg_maxmin_precision)) {
+              not double_positive(cnst->remaining_, cnst->dynamic_bound_ * sg_maxmin_precision)) {
             if (cnst->cnst_light_) {
-              int index = (cnst->cnst_light_ - cnst_light_tab);
-              XBT_DEBUG("index: %d \t cnst_light_num: %d \t || \t cnst: %p \t cnst->cnst_light: %p "
+              size_t index = (cnst->cnst_light_ - cnst_light_tab);
+              XBT_DEBUG("index: %zu \t cnst_light_num: %d \t || \t cnst: %p \t cnst->cnst_light: %p "
                         "\t cnst_light_tab: %p usage: %f remaining: %f bound: %f  ",
                         index, cnst_light_num, cnst, cnst->cnst_light_, cnst_light_tab, cnst->usage_, cnst->remaining_,
-                        cnst->bound_);
+                        cnst->dynamic_bound_);
               cnst_light_tab[index]                  = cnst_light_tab[cnst_light_num - 1];
               cnst_light_tab[index].cnst->cnst_light_ = &cnst_light_tab[index];
               cnst_light_num--;
@@ -677,7 +682,7 @@ void System::update_variable_bound(Variable* var, double bound)
 }
 
 void Variable::initialize(resource::Action* id_value, double sharing_penalty, double bound_value,
-                          int number_of_constraints, unsigned visited_value)
+                          size_t number_of_constraints, unsigned visited_value)
 {
   id_     = id_value;
   rank_   = next_rank_++;
@@ -773,8 +778,8 @@ void System::on_disabled_var(Constraint* cnstr)
   if (cnstr->get_concurrency_limit() < 0)
     return;
 
-  int numelem = cnstr->disabled_element_set_.size();
-  if (not numelem)
+  size_t numelem = cnstr->disabled_element_set_.size();
+  if (numelem == 0)
     return;
 
   Element* elem = &cnstr->disabled_element_set_.front();
@@ -812,7 +817,6 @@ void System::on_disabled_var(Constraint* cnstr)
 void System::update_variable_penalty(Variable* var, double penalty)
 {
   xbt_assert(penalty >= 0, "Variable penalty should not be negative!");
-
   if (penalty == var->sharing_penalty_)
     return;
 
@@ -914,7 +918,7 @@ void System::remove_all_modified_set()
 double Constraint::get_usage() const
 {
   double result              = 0.0;
-  if (sharing_policy_ != s4u::Link::SharingPolicy::FATPIPE) {
+  if (sharing_policy_ != SharingPolicy::FATPIPE) {
     for (Element const& elem : enabled_element_set_)
       if (elem.consumption_weight > 0)
         result += elem.consumption_weight * elem.variable->value_;
@@ -932,6 +936,14 @@ int Constraint::get_variable_amount() const
                                         [](const Element& elem) { return elem.consumption_weight > 0; }));
 }
 
+void Constraint::set_sharing_policy(SharingPolicy policy, const s4u::NonLinearResourceCb& cb)
+{
+  xbt_assert(policy == SharingPolicy::NONLINEAR || not cb,
+             "Invalid sharing policy for constraint. Callback should be used with NONLINEAR sharing policy");
+  sharing_policy_    = policy;
+  dyn_constraint_cb_ = cb;
+}
+
 } // namespace lmm
 } // namespace kernel
 } // namespace simgrid