+TEST_CASE("kernel::bmf Bugs", "[kernel-bmf-bug]")
+{
+ lmm::BmfSystem Sys(false);
+
+ SECTION("DadOu's bug: sum of bounds/phi greater than C")
+ {
+ /*
+ * Ptasks in a g5k platform.
+ * Extracted from original test.
+ * The sum of bounds for 1 resource exceed its capacity, giving a negative value in C'
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 2.5e9);
+ lmm::Constraint* sys_cnst2 = Sys.constraint_new(nullptr, 2.5e9);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, 2.27328e-10, 2);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1, 2.27328e-10, 2);
+ lmm::Variable* rho_3 = Sys.variable_new(nullptr, 1);
+
+ Sys.expand(sys_cnst, rho_1, 1.84467e+19);
+ Sys.expand(sys_cnst2, rho_1, 1.84467e+19);
+ Sys.expand(sys_cnst, rho_2, 1.84467e+19);
+ Sys.expand(sys_cnst, rho_3, 1.91268e+11);
+ Sys.solve();
+ }
+
+ SECTION("DadOu's bug: complete matrix")
+ {
+ constexpr int cnsts = 71;
+ constexpr int flows = 3;
+
+ Eigen::MatrixXd A(cnsts, flows);
+ A << 0, 0, 0, 0, 0, 0, 0, 0, 1.84467e+19, 1.91268e+11, 1.84467e+19, 1.84467e+19, 0, 0, 1.84467e+19, 0, 1.84467e+19,
+ 0, 0, 1.84467e+19, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0,
+ 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11,
+ 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 1.256e+09, 0, 0, 2.2372e+10, 0, 0,
+ 2.2684e+10, 0, 0, 2.2588e+10, 0, 0, 2.3188e+10, 0, 0, 2.228e+10, 0, 0, 2.058e+10, 0, 0, 2.2684e+10, 0, 0,
+ 2.2824e+10, 0, 0, 2.2976e+10, 0, 0, 2.2632e+10, 0, 0, 2.2584e+10, 0, 0, 2.2736e+10, 0, 0, 2.2616e+10, 0, 0,
+ 2.0828e+10, 0, 0, 2.3184e+10, 0, 0, 2.2524e+10, 0, 0, 2.278e+10, 0, 0, 2.2164e+10, 0, 0, 1.26e+09, 0, 0,
+ 2.1872e+10, 0, 0, 1.4e+09, 0, 0, 2.3184e+10, 0, 0, 8.52e+08, 0, 0, 2.2268e+10, 0, 0, 1.756e+09, 0, 0,
+ 2.0636e+10, 0, 0, 3.4e+09, 0, 0, 2.2576e+10, 0, 0, 1.352e+09, 0, 0, 2.2832e+10, 0, 0, 1.2e+09, 0, 0, 2.3092e+10,
+ 0, 0, 9.48e+08, 0, 0, 2.2436e+10, 0, 0, 1.4e+09, 0, 0, 2.2572e+10, 0, 0, 1.452e+09, 0, 0, 2.2692e+10, 0, 0,
+ 1.3e+09, 0, 0, 2.2832e+10, 0, 0, 1.2e+09, 0, 0, 2.1232e+10, 0, 0, 2.804e+09, 0, 0, 2.3184e+10, 0, 0,
+ 8.56001e+08, 0, 0, 2.2512e+10, 0, 0, 1.5e+09, 0, 0;
+
+ Eigen::MatrixXd maxA(cnsts, flows);
+ maxA << 0, 0, 0, 0, 0, 0, 0, 0, 1.84467e+19, 3.1e+09, 1.84467e+19, 1.84467e+19, 0, 0, 1.84467e+19, 0, 1.84467e+19,
+ 0, 0, 1.84467e+19, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 1, 4.975e+11, 0, 0,
+ 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11,
+ 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 4.975e+11, 0, 0, 1.256e+09, 0, 0, 3.504e+09, 0, 0,
+ 3.056e+09, 0, 0, 3.1e+09, 0, 0, 2.952e+09, 0, 0, 2.404e+09, 0, 0, 2.304e+09, 0, 0, 2.556e+09, 0, 0, 2.4e+09, 0,
+ 0, 2.804e+09, 0, 0, 2.552e+09, 0, 0, 2.408e+09, 0, 0, 2.9e+09, 0, 0, 2.4e+09, 0, 0, 2.256e+09, 0, 0, 3.504e+09,
+ 0, 0, 3.244e+09, 0, 0, 2.556e+09, 0, 0, 2.952e+09, 0, 0, 1.26e+09, 0, 0, 2.552e+09, 0, 0, 1.4e+09, 0, 0,
+ 3.244e+09, 0, 0, 8.52e+08, 0, 0, 2.556e+09, 0, 0, 1.756e+09, 0, 0, 2.256e+09, 0, 0, 3.4e+09, 0, 0, 2.6e+09, 0,
+ 0, 1.352e+09, 0, 0, 2.952e+09, 0, 0, 1.2e+09, 0, 0, 2.452e+09, 0, 0, 9.48e+08, 0, 0, 2.804e+09, 0, 0, 1.4e+09,
+ 0, 0, 3.1e+09, 0, 0, 1.452e+09, 0, 0, 2.404e+09, 0, 0, 1.3e+09, 0, 0, 2.952e+09, 0, 0, 1.2e+09, 0, 0, 3.056e+09,
+ 0, 0, 2.804e+09, 0, 0, 2.4e+09, 0, 0, 8.56001e+08, 0, 0, 2.9e+09, 0, 0, 1.5e+09, 0, 0;
+
+ Eigen::VectorXd C(cnsts);
+ C << 3.2e+20, 3.2e+20, 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09, 3.2e+20, 3.2e+20, 3.2e+20, 3.2e+20, 3.2e+20,
+ 3.2e+20, 3.2e+20, 3.2e+20, 3.2e+20, 3.2e+20, 3.2e+20, 3.2e+20, 3.2e+20, 3.2e+20, 3.2e+20, 3.2e+20, 1.83484e+10,
+ 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09,
+ 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09, 2.5e+09, 1.83484e+10, 2.5e+09, 1.83484e+10, 2.5e+09, 1.83484e+10,
+ 2.5e+09, 1.83484e+10, 2.5e+09, 1.83484e+10, 2.5e+09, 1.83484e+10, 2.5e+09, 1.83484e+10, 2.5e+09, 1.83484e+10,
+ 2.5e+09, 1.83484e+10, 2.5e+09, 1.83484e+10, 2.5e+09, 1.83484e+10, 2.5e+09, 1.83484e+10, 2.5e+09, 1.83484e+10,
+ 2.5e+09, 1.83484e+10, 2.5e+09, 1.83484e+10;
+
+ Eigen::VectorXd phi(flows);
+ phi << 1.35273, 2.27328e-10, 2.27328e-10;
+
+ std::vector<bool> shared(cnsts, true);
+ lmm::BmfSolver solver(A, maxA, C, shared, phi);
+ auto rho = solver.solve();
+ REQUIRE((rho.array() > 0).all());
+ }
+
+ SECTION("is_bmf bug: all limited by bound")
+ {
+ /*
+ * Particular case, 1 flow is saturated and the other increases
+ * its speed until the contraint is reached
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 10);
+ lmm::Constraint* sys_cnst2 = Sys.constraint_new(nullptr, 8);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, 1.5, 2);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1, 3, 2);
+
+ Sys.expand(sys_cnst, rho_1, 5.0);
+ Sys.expand(sys_cnst2, rho_1, 1.0);
+ Sys.expand(sys_cnst, rho_2, 1.0);
+ Sys.expand(sys_cnst2, rho_2, 1.0);
+ Sys.solve();
+ REQUIRE(double_equals(rho_1->get_value(), 1.4, sg_precision_workamount));
+ REQUIRE(double_equals(rho_2->get_value(), 3, sg_precision_workamount));
+ }
+
+ SECTION("s4u-cloud-capping bug: all limited by bound extra case")
+ {
+ /*
+ * Inspired by s4u-cloud-capping test.
+ * Step 9: "Put an activity on a PM and an activity on the VM capped by 10%."
+ * Extracted from original test.
+ * The sum of bounds for 1 resource is smaller than C.
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 7.6296e+07);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, 7.6296e+06, 1);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, 1, 3.8148e+07, 1);
+
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.expand(sys_cnst, rho_2, 1);
+ Sys.solve();
+ REQUIRE(double_equals(rho_1->get_value(), 7.6296e+06, sg_precision_workamount));
+ REQUIRE(double_equals(rho_2->get_value(), 3.8148e+07, sg_precision_workamount));
+ }
+
+ SECTION("Variable penalty with bounds: thread bug")
+ {
+ /*
+ * Detected by exec-thread.
+ * Fair-sharing vector depends on the penalty too.
+ */
+
+ /* don't change the order of creation, important to trigger the bug */
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 4e8);
+ lmm::Variable* rho_2 = Sys.variable_new(nullptr, .25, 4e8, 1);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1, 1e8, 1);
+ Sys.expand(sys_cnst, rho_2, 1);
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), 8e7, sg_precision_workamount));
+ REQUIRE(double_equals(rho_2->get_value(), 3.2e8, sg_precision_workamount));
+ }
+
+ SECTION("Variable penalty with bounds greater than C")
+ {
+ /*
+ * Detected by exec-thread. 6 thread running in a 4 core CPU.
+ */
+
+ lmm::Constraint* sys_cnst = Sys.constraint_new(nullptr, 4e8);
+ lmm::Variable* rho_1 = Sys.variable_new(nullptr, 1.0 / 6.0, 6e8, 1);
+ Sys.expand(sys_cnst, rho_1, 1);
+ Sys.solve();
+
+ REQUIRE(double_equals(rho_1->get_value(), 4e8, sg_precision_workamount));
+ }
+
+ Sys.variable_free_all();
+}
+