From 39d24b63aa597b0ee886e0f98b2755eb27924b3e Mon Sep 17 00:00:00 2001 From: Arnaud Giersch Date: Tue, 27 Mar 2018 16:16:22 +0200 Subject: [PATCH] Define FairBottleneck and Lagrange as subclasses of lmm::System. --- src/kernel/lmm/fair_bottleneck.cpp | 33 ++++++++------- src/kernel/lmm/lagrange.cpp | 20 +++++---- src/kernel/lmm/maxmin.cpp | 19 ++++----- src/kernel/lmm/maxmin.hpp | 43 +++++++++++++------- src/kernel/resource/Model.cpp | 4 +- src/surf/network_cm02.cpp | 16 +++----- src/surf/network_cm02.hpp | 3 +- src/surf/ptask_L07.cpp | 8 ++-- teshsuite/surf/lmm_usage/lmm_usage.cpp | 42 +++++++++---------- teshsuite/surf/maxmin_bench/maxmin_bench.cpp | 2 +- 10 files changed, 103 insertions(+), 87 deletions(-) diff --git a/src/kernel/lmm/fair_bottleneck.cpp b/src/kernel/lmm/fair_bottleneck.cpp index cd43352447..3651992163 100644 --- a/src/kernel/lmm/fair_bottleneck.cpp +++ b/src/kernel/lmm/fair_bottleneck.cpp @@ -17,19 +17,24 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_maxmin); #define SHOW_EXPR_D(expr) XBT_DEBUG(#expr " = %d", expr); #define SHOW_EXPR_P(expr) XBT_DEBUG(#expr " = %p", expr); -void simgrid::kernel::lmm::bottleneck_solve(lmm::System* sys) +simgrid::kernel::lmm::System* simgrid::kernel::lmm::make_new_fair_bottleneck_system(bool selective_update) { - if (not sys->modified) + return new simgrid::kernel::lmm::FairBottleneck(selective_update); +} + +void simgrid::kernel::lmm::FairBottleneck::bottleneck_solve() +{ + if (not modified) return; - XBT_DEBUG("Variable set : %zu", sys->variable_set.size()); - for (Variable& var : sys->variable_set) { + XBT_DEBUG("Variable set : %zu", variable_set.size()); + for (Variable& var : variable_set) { var.value = 0.0; XBT_DEBUG("Handling variable %p", &var); if (var.sharing_weight > 0.0 && std::find_if(begin(var.cnsts), end(var.cnsts), [](Element const& x) { return x.consumption_weight != 0.0; }) != end(var.cnsts)) { - sys->saturated_variable_set.push_back(var); + saturated_variable_set.push_back(var); } else { XBT_DEBUG("Err, finally, there is no need to take care of variable %p", &var); if (var.sharing_weight > 0.0) @@ -37,11 +42,11 @@ void simgrid::kernel::lmm::bottleneck_solve(lmm::System* sys) } } - XBT_DEBUG("Active constraints : %zu", sys->active_constraint_set.size()); - for (Constraint& cnst : sys->active_constraint_set) { - sys->saturated_constraint_set.push_back(cnst); + XBT_DEBUG("Active constraints : %zu", active_constraint_set.size()); + for (Constraint& cnst : active_constraint_set) { + saturated_constraint_set.push_back(cnst); } - for (Constraint& cnst : sys->saturated_constraint_set) { + for (Constraint& cnst : saturated_constraint_set) { cnst.remaining = cnst.bound; cnst.usage = 0.0; } @@ -51,12 +56,12 @@ void simgrid::kernel::lmm::bottleneck_solve(lmm::System* sys) /* * Compute Usage and store the variables that reach the maximum. */ - auto& var_list = sys->saturated_variable_set; - auto& cnst_list = sys->saturated_constraint_set; + auto& var_list = saturated_variable_set; + auto& cnst_list = saturated_constraint_set; do { if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) { XBT_DEBUG("Fair bottleneck done"); - sys->print(); + print(); } XBT_DEBUG("******* Constraints to process: %zu *******", cnst_list.size()); for (auto iter = std::begin(cnst_list); iter != std::end(cnst_list);) { @@ -142,9 +147,9 @@ void simgrid::kernel::lmm::bottleneck_solve(lmm::System* sys) } while (not var_list.empty()); cnst_list.clear(); - sys->modified = true; + modified = true; if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) { XBT_DEBUG("Fair bottleneck done"); - sys->print(); + print(); } } diff --git a/src/kernel/lmm/lagrange.cpp b/src/kernel/lmm/lagrange.cpp index 7d2afe0e98..bebf316e4c 100644 --- a/src/kernel/lmm/lagrange.cpp +++ b/src/kernel/lmm/lagrange.cpp @@ -33,11 +33,14 @@ double (*func_f_def)(const Variable&, double); double (*func_fp_def)(const Variable&, double); double (*func_fpi_def)(const Variable&, double); +System* make_new_lagrange_system(bool selective_update) +{ + return new Lagrange(selective_update); +} + /* * Local prototypes to implement the Lagrangian optimization with optimal step, also called dichotomy. */ -// solves the proportional fairness using a Lagrangian optimization with dichotomy step -void lagrange_solve(kernel::lmm::System* sys); // computes the value of the dichotomy using a initial values, init, with a specific variable or constraint static double dichotomy(double init, double diff(double, const Constraint&), const Constraint& cnst, double min_error); // computes the value of the differential of constraint cnst applied to lambda @@ -137,7 +140,8 @@ static double dual_objective(const VarList& var_list, const CnstList& cnst_list) return obj; } -void lagrange_solve(kernel::lmm::System* sys) +// solves the proportional fairness using a Lagrangian optimization with dichotomy step +void Lagrange::lagrange_solve() { /* Lagrange Variables. */ int max_iterations = 100; @@ -152,14 +156,14 @@ void lagrange_solve(kernel::lmm::System* sys) XBT_DEBUG("#### Minimum error tolerated (dichotomy) : %e", dichotomy_min_error); if (XBT_LOG_ISENABLED(surf_lagrange, xbt_log_priority_debug)) { - sys->print(); + print(); } - if (not sys->modified) + if (not modified) return; /* Initialize lambda. */ - auto& cnst_list = sys->active_constraint_set; + auto& cnst_list = active_constraint_set; for (Constraint& cnst : cnst_list) { cnst.lambda = 1.0; cnst.new_lambda = 2.0; @@ -169,7 +173,7 @@ void lagrange_solve(kernel::lmm::System* sys) /* * Initialize the var_list variable with only the active variables. Initialize mu. */ - auto& var_list = sys->variable_set; + auto& var_list = variable_set; for (Variable& var : var_list) { if (not var.sharing_weight) var.value = 0.0; @@ -263,7 +267,7 @@ void lagrange_solve(kernel::lmm::System* sys) } if (XBT_LOG_ISENABLED(surf_lagrange, xbt_log_priority_debug)) { - sys->print(); + print(); } } diff --git a/src/kernel/lmm/maxmin.cpp b/src/kernel/lmm/maxmin.cpp index 8bd4ecad4b..42de20657e 100644 --- a/src/kernel/lmm/maxmin.cpp +++ b/src/kernel/lmm/maxmin.cpp @@ -33,6 +33,11 @@ typedef std::vector dyn_light_t; int Variable::Global_debug_id = 1; int Constraint::Global_debug_id = 1; +System* make_new_maxmin_system(bool selective_update) +{ + return new System(selective_update); +} + int Element::get_concurrency() const { // Ignore element with weight less than one (e.g. cross-traffic) @@ -152,7 +157,6 @@ System::System(bool selective_update) : selective_update_active(selective_update variable_mallocator = xbt_mallocator_new(65536, System::variable_mallocator_new_f, System::variable_mallocator_free_f, nullptr); - solve_fun = &lmm_solve; } System::~System() @@ -486,7 +490,7 @@ void System::print() const } } -void System::solve() +void System::lmm_solve() { if (modified) { XBT_IN("(sys=%p)", this); @@ -494,14 +498,14 @@ void System::solve() * constraints that changed are considered. Otherwise all constraints with active actions are considered. */ if (selective_update_active) - solve(modified_constraint_set); + lmm_solve(modified_constraint_set); else - solve(active_constraint_set); + lmm_solve(active_constraint_set); XBT_OUT(); } } -template void System::solve(CnstList& cnst_list) +template void System::lmm_solve(CnstList& cnst_list) { double min_usage = -1; double min_bound = -1; @@ -690,11 +694,6 @@ template void System::solve(CnstList& cnst_list) delete[] cnst_light_tab; } -void lmm_solve(System* sys) -{ - sys->solve(); -} - /** \brief Attribute the value bound to var->bound. * * \param var the Variable* diff --git a/src/kernel/lmm/maxmin.hpp b/src/kernel/lmm/maxmin.hpp index f5006fcb42..e67337031e 100644 --- a/src/kernel/lmm/maxmin.hpp +++ b/src/kernel/lmm/maxmin.hpp @@ -135,15 +135,6 @@ namespace lmm { /** @{ @ingroup SURF_lmm */ -/** - * @brief Solve the lmm system - * @param sys The lmm system to solve - */ -XBT_PUBLIC void lmm_solve(lmm::System* sys); - -XBT_PUBLIC void lagrange_solve(lmm::System* sys); -XBT_PUBLIC void bottleneck_solve(lmm::System* sys); - /** Default functions associated to the chosen protocol. When using the lagrangian approach. */ XBT_PUBLIC void set_default_protocol_function(double (*func_f)(const Variable& var, double x), @@ -448,7 +439,7 @@ public: */ explicit System(bool selective_update); /** @brief Free an existing Linear MaxMin system */ - ~System(); + virtual ~System(); /** * @brief Create a new Linear MaxMin constraint @@ -521,7 +512,10 @@ public: void print() const; /** @brief Solve the lmm system */ - void solve(); + void lmm_solve(); + + /** @brief Solve the lmm system. May be specialized in subclasses. */ + virtual void solve() { lmm_solve(); } private: static void* variable_mallocator_new_f(); @@ -585,7 +579,8 @@ private: void remove_all_modified_set(); void check_concurrency() const; - template void solve(CnstList& cnst_list); + template void lmm_solve(CnstList& cnst_list); + public: bool modified; boost::intrusive::list, @@ -603,8 +598,6 @@ public: simgrid::kernel::resource::Action::ModifiedSet* modified_set_ = nullptr; - void (*solve_fun)(lmm::System* self); - private: bool selective_update_active; /* flag to update partially the system only selecting changed portions */ unsigned visited_counter; /* used by System::update_modified_set() and System::remove_all_modified_set() to @@ -618,6 +611,28 @@ private: xbt_mallocator_t variable_mallocator; }; +class XBT_PUBLIC FairBottleneck : public System { +public: + explicit FairBottleneck(bool selective_update) : System(selective_update) {} + void solve() final { bottleneck_solve(); } + +private: + void bottleneck_solve(); +}; + +class XBT_PUBLIC Lagrange : public System { +public: + explicit Lagrange(bool selective_update) : System(selective_update) {} + void solve() final { lagrange_solve(); } + +private: + void lagrange_solve(); +}; + +XBT_PUBLIC System* make_new_maxmin_system(bool selective_update); +XBT_PUBLIC System* make_new_fair_bottleneck_system(bool selective_update); +XBT_PUBLIC System* make_new_lagrange_system(bool selective_update); + extern XBT_PRIVATE double (*func_f_def)(const Variable&, double); extern XBT_PRIVATE double (*func_fp_def)(const Variable&, double); extern XBT_PRIVATE double (*func_fpi_def)(const Variable&, double); diff --git a/src/kernel/resource/Model.cpp b/src/kernel/resource/Model.cpp index 25a3ee6bb9..e53dd16fc1 100644 --- a/src/kernel/resource/Model.cpp +++ b/src/kernel/resource/Model.cpp @@ -50,7 +50,7 @@ double Model::next_occuring_event(double now) double Model::next_occuring_event_lazy(double now) { XBT_DEBUG("Before share resources, the size of modified actions set is %zu", maxmin_system_->modified_set_->size()); - lmm_solve(maxmin_system_); + maxmin_system_->lmm_solve(); XBT_DEBUG("After share resources, The size of modified actions set is %zu", maxmin_system_->modified_set_->size()); while (not maxmin_system_->modified_set_->empty()) { @@ -112,7 +112,7 @@ double Model::next_occuring_event_lazy(double now) double Model::next_occuring_event_full(double /*now*/) { - maxmin_system_->solve_fun(maxmin_system_); + maxmin_system_->solve(); double min = -1; diff --git a/src/surf/network_cm02.cpp b/src/surf/network_cm02.cpp index 4065a0d315..d81c45c87c 100644 --- a/src/surf/network_cm02.cpp +++ b/src/surf/network_cm02.cpp @@ -94,7 +94,7 @@ void surf_network_model_init_Reno() xbt_cfg_setdefault_double("network/bandwidth-factor", 0.97); xbt_cfg_setdefault_double("network/weight-S", 20537); - surf_network_model = new simgrid::surf::NetworkCm02Model(&simgrid::kernel::lmm::lagrange_solve); + surf_network_model = new simgrid::surf::NetworkCm02Model(&simgrid::kernel::lmm::make_new_lagrange_system); all_existing_models->push_back(surf_network_model); } @@ -111,7 +111,7 @@ void surf_network_model_init_Reno2() xbt_cfg_setdefault_double("network/bandwidth-factor", 0.97); xbt_cfg_setdefault_double("network/weight-S", 20537); - surf_network_model = new simgrid::surf::NetworkCm02Model(&simgrid::kernel::lmm::lagrange_solve); + surf_network_model = new simgrid::surf::NetworkCm02Model(&simgrid::kernel::lmm::make_new_lagrange_system); all_existing_models->push_back(surf_network_model); } @@ -127,15 +127,14 @@ void surf_network_model_init_Vegas() xbt_cfg_setdefault_double("network/bandwidth-factor", 0.97); xbt_cfg_setdefault_double("network/weight-S", 20537); - surf_network_model = new simgrid::surf::NetworkCm02Model(&simgrid::kernel::lmm::lagrange_solve); + surf_network_model = new simgrid::surf::NetworkCm02Model(&simgrid::kernel::lmm::make_new_lagrange_system); all_existing_models->push_back(surf_network_model); } namespace simgrid { namespace surf { -NetworkCm02Model::NetworkCm02Model() - :NetworkModel() +NetworkCm02Model::NetworkCm02Model(kernel::lmm::System* (*make_new_lmm_system)(bool)) : NetworkModel() { std::string optim = xbt_cfg_get_string("network/optim"); bool select = xbt_cfg_get_boolean("network/maxmin-selective-update"); @@ -151,18 +150,13 @@ NetworkCm02Model::NetworkCm02Model() xbt_die("Unsupported optimization (%s) for this model. Accepted: Full, Lazy.", optim.c_str()); } - set_maxmin_system(new simgrid::kernel::lmm::System(select)); + set_maxmin_system(make_new_lmm_system(select)); loopback_ = NetworkCm02Model::createLink("__loopback__", 498000000, 0.000015, SURF_LINK_FATPIPE); if (getUpdateMechanism() == UM_LAZY) get_maxmin_system()->modified_set_ = new kernel::resource::Action::ModifiedSet(); } -NetworkCm02Model::NetworkCm02Model(void (*specificSolveFun)(kernel::lmm::System* self)) : NetworkCm02Model() -{ - get_maxmin_system()->solve_fun = specificSolveFun; -} - LinkImpl* NetworkCm02Model::createLink(const std::string& name, double bandwidth, double latency, e_surf_link_sharing_policy_t policy) { diff --git a/src/surf/network_cm02.hpp b/src/surf/network_cm02.hpp index 29d77fead1..689ba92e34 100644 --- a/src/surf/network_cm02.hpp +++ b/src/surf/network_cm02.hpp @@ -35,8 +35,7 @@ namespace surf { class NetworkCm02Model : public NetworkModel { public: - NetworkCm02Model(); - explicit NetworkCm02Model(void (*solve_fun)(kernel::lmm::System* self)); + explicit NetworkCm02Model(kernel::lmm::System* (*make_new_sys)(bool) = &simgrid::kernel::lmm::make_new_maxmin_system); virtual ~NetworkCm02Model() = default; LinkImpl* createLink(const std::string& name, double bandwidth, double latency, e_surf_link_sharing_policy_t policy) override; diff --git a/src/surf/ptask_L07.cpp b/src/surf/ptask_L07.cpp index 34e525e4ff..94a69e30d3 100644 --- a/src/surf/ptask_L07.cpp +++ b/src/surf/ptask_L07.cpp @@ -34,10 +34,10 @@ namespace simgrid { namespace surf { HostL07Model::HostL07Model() : HostModel() { - set_maxmin_system(new simgrid::kernel::lmm::System(true /* selective update */)); - get_maxmin_system()->solve_fun = &simgrid::kernel::lmm::bottleneck_solve; - surf_network_model = new NetworkL07Model(this, get_maxmin_system()); - surf_cpu_model_pm = new CpuL07Model(this, get_maxmin_system()); + auto* maxmin_system = new simgrid::kernel::lmm::FairBottleneck(true /* selective update */); + set_maxmin_system(maxmin_system); + surf_network_model = new NetworkL07Model(this, maxmin_system); + surf_cpu_model_pm = new CpuL07Model(this, maxmin_system); } HostL07Model::~HostL07Model() diff --git a/teshsuite/surf/lmm_usage/lmm_usage.cpp b/teshsuite/surf/lmm_usage/lmm_usage.cpp index acac3e1e0d..74a3979d99 100644 --- a/teshsuite/surf/lmm_usage/lmm_usage.cpp +++ b/teshsuite/surf/lmm_usage/lmm_usage.cpp @@ -27,6 +27,19 @@ using namespace simgrid::surf; enum method_t { MAXMIN, LAGRANGE_RENO, LAGRANGE_VEGAS }; +static simgrid::kernel::lmm::System* new_system(method_t method, bool update) +{ + switch (method) { + case MAXMIN: + return simgrid::kernel::lmm::make_new_maxmin_system(update); + case LAGRANGE_VEGAS: + case LAGRANGE_RENO: + return simgrid::kernel::lmm::make_new_lagrange_system(update); + default: + xbt_die("Invalid method"); + } +} + static double dichotomy(double func(double), double min, double max, double min_error) { double overall_error = 2 * min_error; @@ -97,7 +110,7 @@ static void test1(method_t method) set_default_protocol_function(simgrid::kernel::lmm::func_reno_f, simgrid::kernel::lmm::func_reno_fpi, simgrid::kernel::lmm::func_reno_fpi); - simgrid::kernel::lmm::System* Sys = new simgrid::kernel::lmm::System(true); + simgrid::kernel::lmm::System* Sys = new_system(method, true); simgrid::kernel::lmm::Constraint* L1 = Sys->constraint_new(nullptr, a); simgrid::kernel::lmm::Constraint* L2 = Sys->constraint_new(nullptr, b); simgrid::kernel::lmm::Constraint* L3 = Sys->constraint_new(nullptr, a); @@ -121,7 +134,7 @@ static void test1(method_t method) Sys->expand(L3, R_3, 1.0); if (method == MAXMIN) { - lmm_solve(Sys); + Sys->solve(); } else { double x; if (method == LAGRANGE_VEGAS) { @@ -146,7 +159,7 @@ static void test1(method_t method) xbt_die( "Invalid method"); } - lagrange_solve(Sys); + Sys->solve(); double max_deviation = 0.0; max_deviation = std::max(max_deviation, fabs(R_1->get_value() - x)); @@ -185,7 +198,8 @@ static void test2(method_t method) set_default_protocol_function(simgrid::kernel::lmm::func_reno_f, simgrid::kernel::lmm::func_reno_fp, simgrid::kernel::lmm::func_reno_fpi); - simgrid::kernel::lmm::System* Sys = new simgrid::kernel::lmm::System(true); + simgrid::kernel::lmm::System* Sys = new_system(method, true); + simgrid::kernel::lmm::Constraint* CPU1 = Sys->constraint_new(nullptr, 200.0); simgrid::kernel::lmm::Constraint* CPU2 = Sys->constraint_new(nullptr, 100.0); @@ -198,13 +212,7 @@ static void test2(method_t method) Sys->expand(CPU1, T1, 1.0); Sys->expand(CPU2, T2, 1.0); - if (method == MAXMIN) { - lmm_solve(Sys); - } else if (method == LAGRANGE_VEGAS || method == LAGRANGE_RENO) { - lagrange_solve(Sys); - } else { - xbt_die("Invalid method"); - } + Sys->solve(); PRINT_VAR(T1); PRINT_VAR(T2); @@ -258,7 +266,7 @@ static void test3(method_t method) set_default_protocol_function(simgrid::kernel::lmm::func_reno_f, simgrid::kernel::lmm::func_reno_fp, simgrid::kernel::lmm::func_reno_fpi); - simgrid::kernel::lmm::System* Sys = new simgrid::kernel::lmm::System(true); + simgrid::kernel::lmm::System* Sys = new_system(method, true); /* Creates the constraints */ simgrid::kernel::lmm::Constraint** tmp_cnst = new simgrid::kernel::lmm::Constraint*[15]; @@ -278,15 +286,7 @@ static void test3(method_t method) if (A[i][j]) Sys->expand(tmp_cnst[i], tmp_var[j], 1.0); - if (method == MAXMIN) { - lmm_solve(Sys); - } else if (method == LAGRANGE_VEGAS) { - lagrange_solve(Sys); - } else if (method == LAGRANGE_RENO) { - lagrange_solve(Sys); - } else { - xbt_die("Invalid method"); - } + Sys->solve(); for (int j = 0; j < 16; j++) PRINT_VAR(tmp_var[j]); diff --git a/teshsuite/surf/maxmin_bench/maxmin_bench.cpp b/teshsuite/surf/maxmin_bench/maxmin_bench.cpp index 2b22d14a70..70bf29f266 100644 --- a/teshsuite/surf/maxmin_bench/maxmin_bench.cpp +++ b/teshsuite/surf/maxmin_bench/maxmin_bench.cpp @@ -81,7 +81,7 @@ static void test(int nb_cnst, int nb_var, int nb_elem, unsigned int pw_base_limi fprintf(stderr,"Starting to solve(%i)\n",myrand()%1000); date = xbt_os_time() * 1000000; - lmm_solve(Sys); + Sys->solve(); date = xbt_os_time() * 1000000 - date; if(mode==2){ -- 2.20.1