/*****************************************************************************/
-void BmfSystem::get_flows_data(Eigen::MatrixXd& A, Eigen::MatrixXd& maxA, Eigen::VectorXd& phi)
+void BmfSystem::get_flows_data(int number_cnsts, Eigen::MatrixXd& A, Eigen::MatrixXd& maxA, Eigen::VectorXd& phi)
{
- A.resize(active_constraint_set.size(), variable_set.size());
+ A.resize(number_cnsts, variable_set.size());
A.setZero();
- maxA.resize(active_constraint_set.size(), variable_set.size());
+ maxA.resize(number_cnsts, variable_set.size());
maxA.setZero();
phi.resize(variable_set.size());
if (var.sharing_penalty_ <= 0)
continue;
bool active = false;
- var.value_ = 1; // assign something by default for tasks with 0 consumption
+ bool linked = false; // variable is linked to some constraint (specially for selective_update)
for (const Element& elem : var.cnsts_) {
+ boost::intrusive::list_member_hook<>& cnst_hook = selective_update_active
+ ? elem.constraint->modified_constraint_set_hook_
+ : elem.constraint->active_constraint_set_hook_;
+ if (not cnst_hook.is_linked())
+ continue;
+ /* active and linked variable, lets check its consumption */
+ linked = true;
double consumption = elem.consumption_weight;
if (consumption > 0) {
int cnst_idx = cnst2idx_[elem.constraint];
active = true;
}
}
+ /* skip variables not linked to any modified or active constraint */
+ if (not linked)
+ continue;
if (active) {
- phi[var_idx] = var.get_bound();
+ phi[var_idx] = var.get_bound();
idx2Var_[var_idx] = &var;
var_idx++;
+ } else {
+ var.value_ = 1; // assign something by default for tasks with 0 consumption
}
}
// resize matrix to active variables only
phi.conservativeResize(var_idx);
}
-void BmfSystem::get_constraint_data(Eigen::VectorXd& C)
+template <class CnstList> void BmfSystem::get_constraint_data(const CnstList& cnst_list, Eigen::VectorXd& C)
{
- C.resize(active_constraint_set.size());
+ C.resize(cnst_list.size());
cnst2idx_.clear();
int cnst_idx = 0;
- for (const Constraint& cnst : active_constraint_set) {
+ for (const Constraint& cnst : cnst_list) {
C(cnst_idx) = cnst.bound_;
cnst2idx_[&cnst] = cnst_idx;
cnst_idx++;
}
}
-void BmfSystem::bmf_solve()
+void BmfSystem::solve()
{
- if (not modified_)
- return;
+ if (modified_) {
+ if (selective_update_active)
+ bmf_solve(modified_constraint_set);
+ else
+ bmf_solve(active_constraint_set);
+ }
+}
+template <class CnstList> void BmfSystem::bmf_solve(const CnstList& cnst_list)
+{
/* initialize players' weight and constraint matrices */
idx2Var_.clear();
cnst2idx_.clear();
Eigen::MatrixXd A, maxA;
Eigen::VectorXd C, bounds;
- get_constraint_data(C);
- get_flows_data(A, maxA, bounds);
+ get_constraint_data(cnst_list, C);
+ get_flows_data(C.size(), A, maxA, bounds);
auto solver = BmfSolver(A, maxA, C, bounds);
auto rho = solver.solve();
public:
using System::System;
/** @brief Implements the solve method to calculate a BMF allocation */
- void solve() final { bmf_solve(); }
+ void solve() final;
private:
using allocation_map_t = std::unordered_map<int, std::unordered_set<int>>;
- /** @brief Solve equation system to find a fair-sharing of resources */
- void bmf_solve();
+ /**
+ * @brief Solve equation system to find a fair-sharing of resources
+ *
+ * @param cnst_list Constraint list (modified for selective update or active)
+ */
+ template <class CnstList> void bmf_solve(const CnstList& cnst_list);
/**
* @brief Iterates over system and build the consumption matrix A_ji and maxA_ji
*
*
* Considers only active variables to build the matrix.
*
+ * @param number_cnsts Number of constraints in the system
* @param A Consumption matrix (OUTPUT)
* @param maxA Max subflow consumption matrix (OUTPUT)
* @param phi Bounds for variables
*/
- void get_flows_data(Eigen::MatrixXd& A, Eigen::MatrixXd& maxA, Eigen::VectorXd& phi);
+ void get_flows_data(int number_cnsts, Eigen::MatrixXd& A, Eigen::MatrixXd& maxA, Eigen::VectorXd& phi);
/**
* @brief Builds the vector C_ with resource's capacity
*
+ * @param cnst_list Constraint list (modified for selective update or active)
* @param C Resource capacity vector
*/
- void get_constraint_data(Eigen::VectorXd& C);
+ template <class CnstList> void get_constraint_data(const CnstList& cnst_list, Eigen::VectorXd& C);
std::unordered_map<int, Variable*> idx2Var_; //!< Map player index (and position in matrices) to system's variable
std::unordered_map<const Constraint*, int> cnst2idx_; //!< Conversely map constraint to index
std::unique_ptr<resource::Action::ModifiedSet> modified_set_ = nullptr;
+protected:
+ bool selective_update_active; /* flag to update partially the system only selecting changed portions */
+ boost::intrusive::list<Constraint, boost::intrusive::member_hook<Constraint, boost::intrusive::list_member_hook<>,
+ &Constraint::modified_constraint_set_hook_>>
+ modified_constraint_set;
+
private:
using dyn_light_t = std::vector<int>;
std::vector<ConstraintLight> cnst_light_vec;
dyn_light_t saturated_constraints;
- bool selective_update_active; /* flag to update partially the system only selecting changed portions */
unsigned visited_counter_ = 1; /* used by System::update_modified_set() and System::remove_all_modified_set() to
* cleverly (un-)flag the constraints (more details in these functions) */
boost::intrusive::list<Constraint, boost::intrusive::member_hook<Constraint, boost::intrusive::list_member_hook<>,
&Constraint::constraint_set_hook_>>
constraint_set;
- boost::intrusive::list<Constraint, boost::intrusive::member_hook<Constraint, boost::intrusive::list_member_hook<>,
- &Constraint::modified_constraint_set_hook_>>
- modified_constraint_set;
xbt_mallocator_t variable_mallocator_ =
xbt_mallocator_new(65536, System::variable_mallocator_new_f, System::variable_mallocator_free_f, nullptr);
};
simgrid::config::bind_flag(sg_bmf_max_iterations, "bmf/max-iterations",
"Maximum number of steps to be performed while searching for a BMF allocation");
+ simgrid::config::declare_flag<bool>("bmf/selective-update",
+ "Update the constraint set propagating recursively to others constraints "
+ "(off by default)",
+ false);
+
/* The parameters of network models */
sg_latency_factor = 13.01; // comes from the default LV08 network model
{
XBT_CINFO(xbt_cfg, "Switching to the BMF model to handle parallel tasks.");
- auto* system = new simgrid::kernel::lmm::BmfSystem(false);
+ bool select = simgrid::config::get_value<bool>("bmf/selective-update");
+ auto* system = new simgrid::kernel::lmm::BmfSystem(select);
auto host_model = std::make_shared<simgrid::kernel::resource::HostL07Model>("Host_Ptask", system);
auto* engine = simgrid::kernel::EngineImpl::get_instance();
engine->add_model(host_model);