Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Cleanup in log categories
[simgrid.git] / src / kernel / lmm / fair_bottleneck.cpp
1 /* Copyright (c) 2007-2022. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "src/kernel/lmm/maxmin.hpp"
7 #include "src/surf/surf_interface.hpp"
8 #include "xbt/sysdep.h"
9
10 #include <algorithm>
11 #include <cfloat>
12 #include <cmath>
13 #include <cstdlib>
14 #include <xbt/utility.hpp>
15
16 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(ker_lmm);
17
18 void simgrid::kernel::lmm::FairBottleneck::bottleneck_solve()
19 {
20   if (not modified_)
21     return;
22
23   XBT_DEBUG("Variable set : %zu", variable_set.size());
24   for (Variable& var : variable_set) {
25     var.value_ = 0.0;
26     XBT_DEBUG("Handling variable %p", &var);
27     if (var.sharing_penalty_ > 0.0 && std::find_if(begin(var.cnsts_), end(var.cnsts_), [](Element const& x) {
28                                         return x.consumption_weight != 0.0;
29                                       }) != end(var.cnsts_)) {
30       saturated_variable_set.push_back(var);
31     } else {
32       XBT_DEBUG("Err, finally, there is no need to take care of variable %p", &var);
33       if (var.sharing_penalty_ > 0.0)
34         var.value_ = 1.0;
35     }
36   }
37
38   XBT_DEBUG("Active constraints : %zu", active_constraint_set.size());
39   saturated_constraint_set.insert(saturated_constraint_set.end(), active_constraint_set.begin(),
40                                   active_constraint_set.end());
41   for (Constraint& cnst : saturated_constraint_set) {
42     cnst.remaining_ = cnst.bound_;
43     cnst.usage_     = 0.0;
44   }
45
46   XBT_DEBUG("Fair bottleneck Initialized");
47
48   /*
49    * Compute Usage and store the variables that reach the maximum.
50    */
51   auto& var_list  = saturated_variable_set;
52   auto& cnst_list = saturated_constraint_set;
53   do {
54     if (XBT_LOG_ISENABLED(ker_lmm, xbt_log_priority_debug)) {
55       XBT_DEBUG("Fair bottleneck done");
56       print();
57     }
58     XBT_DEBUG("******* Constraints to process: %zu *******", cnst_list.size());
59     for (auto iter = std::begin(cnst_list); iter != std::end(cnst_list);) {
60       Constraint& cnst = *iter;
61       int nb = 0;
62       XBT_DEBUG("Processing cnst %p ", &cnst);
63       cnst.usage_ = 0.0;
64       for (const Element& elem : cnst.enabled_element_set_) {
65         xbt_assert(elem.variable->sharing_penalty_ > 0);
66         if (elem.consumption_weight > 0 && elem.variable->saturated_variable_set_hook_.is_linked())
67           nb++;
68       }
69       XBT_DEBUG("\tThere are %d variables", nb);
70       if (nb > 0 && cnst.sharing_policy_ == Constraint::SharingPolicy::FATPIPE)
71         nb = 1;
72       if (nb == 0) {
73         cnst.remaining_ = 0.0;
74         cnst.usage_     = 0.0;
75         iter           = cnst_list.erase(iter);
76       } else {
77         cnst.usage_ = cnst.remaining_ / nb;
78         XBT_DEBUG("\tConstraint Usage %p : %f with %d variables", &cnst, cnst.usage_, nb);
79         iter++;
80       }
81     }
82
83     for (auto iter = std::begin(var_list); iter != std::end(var_list);) {
84       Variable& var  = *iter;
85       double min_inc = DBL_MAX;
86       for (Element const& elm : var.cnsts_) {
87         if (elm.consumption_weight > 0)
88           min_inc = std::min(min_inc, elm.constraint->usage_ / elm.consumption_weight);
89       }
90       if (var.bound_ > 0)
91         min_inc = std::min(min_inc, var.bound_ - var.value_);
92       var.mu_ = min_inc;
93       XBT_DEBUG("Updating variable %p maximum increment: %g", &var, var.mu_);
94       var.value_ += var.mu_;
95       if (var.value_ == var.bound_)
96         iter = var_list.erase(iter);
97       else
98         iter++;
99     }
100
101     for (auto iter = std::begin(cnst_list); iter != std::end(cnst_list);) {
102       Constraint& cnst = *iter;
103       XBT_DEBUG("Updating cnst %p ", &cnst);
104       if (cnst.sharing_policy_ != Constraint::SharingPolicy::FATPIPE) {
105         for (const Element& elem : cnst.enabled_element_set_) {
106           xbt_assert(elem.variable->sharing_penalty_ > 0);
107           XBT_DEBUG("\tUpdate constraint %p (%g) with variable %p by %g", &cnst, cnst.remaining_, elem.variable,
108                     elem.variable->mu_);
109           double_update(&cnst.remaining_, elem.consumption_weight * elem.variable->mu_, sg_maxmin_precision);
110         }
111       } else {
112         for (const Element& elem : cnst.enabled_element_set_) {
113           xbt_assert(elem.variable->sharing_penalty_ > 0);
114           XBT_DEBUG("\tNon-Shared variable. Update constraint usage of %p (%g) with variable %p by %g", &cnst,
115                     cnst.usage_, elem.variable, elem.variable->mu_);
116           cnst.usage_ = std::min(cnst.usage_, elem.consumption_weight * elem.variable->mu_);
117         }
118         XBT_DEBUG("\tUpdate constraint %p (%g) by %g", &cnst, cnst.remaining_, cnst.usage_);
119         double_update(&cnst.remaining_, cnst.usage_, sg_maxmin_precision);
120       }
121
122       XBT_DEBUG("\tRemaining for %p : %g", &cnst, cnst.remaining_);
123       if (cnst.remaining_ <= 0.0) {
124         XBT_DEBUG("\tGet rid of constraint %p", &cnst);
125
126         iter = cnst_list.erase(iter);
127         for (const Element& elem : cnst.enabled_element_set_) {
128           if (elem.variable->sharing_penalty_ <= 0)
129             break;
130           if (elem.consumption_weight > 0 && elem.variable->saturated_variable_set_hook_.is_linked()) {
131             XBT_DEBUG("\t\tGet rid of variable %p", elem.variable);
132             simgrid::xbt::intrusive_erase(var_list, *elem.variable);
133           }
134         }
135       } else {
136         iter++;
137       }
138     }
139   } while (not var_list.empty());
140
141   cnst_list.clear();
142   modified_ = true;
143   if (XBT_LOG_ISENABLED(ker_lmm, xbt_log_priority_debug)) {
144     XBT_DEBUG("Fair bottleneck done");
145     print();
146   }
147 }