#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)
}
}
- 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;
}
/*
* 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);) {
} 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();
}
}
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
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;
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;
/*
* 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;
}
if (XBT_LOG_ISENABLED(surf_lagrange, xbt_log_priority_debug)) {
- sys->print();
+ print();
}
}
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)
variable_mallocator =
xbt_mallocator_new(65536, System::variable_mallocator_new_f, System::variable_mallocator_free_f, nullptr);
- solve_fun = &lmm_solve;
}
System::~System()
}
}
-void System::solve()
+void System::lmm_solve()
{
if (modified) {
XBT_IN("(sys=%p)", this);
* 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 <class CnstList> void System::solve(CnstList& cnst_list)
+template <class CnstList> void System::lmm_solve(CnstList& cnst_list)
{
double min_usage = -1;
double min_bound = -1;
delete[] cnst_light_tab;
}
-void lmm_solve(System* sys)
-{
- sys->solve();
-}
-
/** \brief Attribute the value bound to var->bound.
*
* \param var the Variable*
/** @{ @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),
*/
explicit System(bool selective_update);
/** @brief Free an existing Linear MaxMin system */
- ~System();
+ virtual ~System();
/**
* @brief Create a new Linear MaxMin constraint
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();
void remove_all_modified_set();
void check_concurrency() const;
- template <class CnstList> void solve(CnstList& cnst_list);
+ template <class CnstList> void lmm_solve(CnstList& cnst_list);
+
public:
bool modified;
boost::intrusive::list<Variable, boost::intrusive::member_hook<Variable, boost::intrusive::list_member_hook<>,
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
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);
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()) {
double Model::next_occuring_event_full(double /*now*/)
{
- maxmin_system_->solve_fun(maxmin_system_);
+ maxmin_system_->solve();
double min = -1;
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);
}
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);
}
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");
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)
{
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;
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()
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;
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);
Sys->expand(L3, R_3, 1.0);
if (method == MAXMIN) {
- lmm_solve(Sys);
+ Sys->solve();
} else {
double x;
if (method == LAGRANGE_VEGAS) {
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));
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);
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);
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];
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]);
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){