1 /* Copyright (c) 2019. The SimGrid Team. All rights reserved. */
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. */
6 #include "src/include/catch.hpp"
7 #include "src/kernel/lmm/maxmin.hpp"
8 #include "src/surf/surf_interface.hpp"
11 namespace lmm = simgrid::kernel::lmm;
13 TEST_CASE("kernel::lmm Single constraint shared systems", "[kernel-lmm-shared-single-sys]")
15 lmm::System* Sys = lmm::make_new_maxmin_system(false);
17 SECTION("Variable penalty")
20 * A variable with twice the penalty gets half of the share
23 * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C
24 * o consumption_weight: a1=1 ; a2=1
25 * o sharing_penalty: p1=1 ; p2=2
28 * o rho1 = 2* rho2 (because rho2 has twice the penalty)
29 * o rho1 + rho2 = C (because all weights are 1)
32 lmm::Constraint* sys_cnst = Sys->constraint_new(nullptr, 3);
33 lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1);
34 lmm::Variable* rho_2 = Sys->variable_new(nullptr, 2);
36 Sys->expand(sys_cnst, rho_1, 1);
37 Sys->expand(sys_cnst, rho_2, 1);
40 REQUIRE(double_equals(rho_1->get_value(), 2, sg_maxmin_precision));
41 REQUIRE(double_equals(rho_2->get_value(), 1, sg_maxmin_precision));
44 SECTION("Consumption weight")
47 * Variables of higher consumption weight consume more resource but get the same share
50 * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C
51 * o consumption_weight: a1=1 ; a2=2
52 * o sharing_penalty: p1=1 ; p2=1
55 * o rho1 = rho2 (because all penalties are 1)
56 * o rho1 + 2* rho2 = C (because weight_2 is 2)
57 * o so, rho1 = rho2 = 1 (because C is 3)
60 lmm::Constraint* sys_cnst = Sys->constraint_new(nullptr, 3);
61 lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1);
62 lmm::Variable* rho_2 = Sys->variable_new(nullptr, 1);
64 Sys->expand(sys_cnst, rho_1, 1);
65 Sys->expand(sys_cnst, rho_2, 2);
68 REQUIRE(double_equals(rho_1->get_value(), 1, sg_maxmin_precision));
69 REQUIRE(double_equals(rho_2->get_value(), 1, sg_maxmin_precision));
72 SECTION("Consumption weight + variable penalty")
76 * Resource proportionality between variable is kept while
77 * varying consumption weight
80 * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C
81 * o consumption_weight: a1=1 ; a2=2
82 * o sharing_penalty: p1=1 ; p2=2
85 * o rho1 = 2* rho2 (because rho2 has twice the penalty)
86 * o rho1 + 2*rho2 = C (because consumption weight of rho2 is 2)
89 lmm::Constraint* sys_cnst = Sys->constraint_new(nullptr, 20);
90 lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1);
91 lmm::Variable* rho_2 = Sys->variable_new(nullptr, 2);
93 Sys->expand(sys_cnst, rho_1, 1);
94 Sys->expand(sys_cnst, rho_2, 2);
97 double rho_1_share = 10;
98 REQUIRE(double_equals(rho_1->get_value(), rho_1_share, sg_maxmin_precision));
99 REQUIRE(double_equals(rho_2->get_value(), rho_1_share / 2, sg_maxmin_precision));
102 SECTION("Multiple constraints systems")
106 * Multiple constraint systems can be solved with shared variables
109 * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C1
110 * a3 * p1 * \rho1 + a4 * p3 * \rho3 < C2
111 * o consumption_weight: a1=1 ; a2=2 ; a3=2 ; a4=1
112 * o sharing_penalty: p1=1 ; p2=2 ; p3=1
113 * o load: load_1=C1/(p1/a1 + p2/a2)=20 ; load_2=C2/(a2/p1 + a3/p3)=30
116 * o First constraint will be solve first (because load_1 < load_2)
117 * o rho1 = 2* rho2 (because rho2 has twice the penalty)
118 * o rho1 + 2*rho2 = C1 (because consumption weight of rho2 is 2)
119 * o 2*rho1 + rho3 = C2 (because consumption weight of rho1 is 2)
122 lmm::Constraint* sys_cnst_1 = Sys->constraint_new(nullptr, 20);
123 lmm::Constraint* sys_cnst_2 = Sys->constraint_new(nullptr, 60);
125 lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1, -1, 2);
126 lmm::Variable* rho_2 = Sys->variable_new(nullptr, 2, -1, 1);
127 lmm::Variable* rho_3 = Sys->variable_new(nullptr, 1, -1, 1);
130 Sys->expand(sys_cnst_1, rho_1, 1);
131 Sys->expand(sys_cnst_1, rho_2, 2);
134 Sys->expand(sys_cnst_2, rho_1, 2);
135 Sys->expand(sys_cnst_2, rho_3, 1);
138 double rho_1_share = 10; // Start by solving the first constraint (results is the same as previous tests)
139 REQUIRE(double_equals(rho_1->get_value(), rho_1_share, sg_maxmin_precision));
140 REQUIRE(double_equals(rho_2->get_value(), rho_1_share / 2, sg_maxmin_precision));
141 REQUIRE(double_equals(rho_3->get_value(), 60 - 2 * rho_1_share, sg_maxmin_precision));
144 Sys->variable_free_all();
148 TEST_CASE("kernel::lmm Single constraint unshared systems", "[kernel-lmm-unshared-single-sys]")
150 lmm::System* Sys = lmm::make_new_maxmin_system(false);
152 SECTION("Variable penalty")
156 * A variable with a penalty of two get half of the max_share
159 * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C1
160 * o consumption_weight: a1=1 ; a2=1
161 * o sharing_penalty: p1=1 ; p2=2
162 * o max_share: max(C1/(a1/p1),C1/(a2/p2))
166 * o rho2 = max_share/2 (because penalty of rho2 is 2)
169 lmm::Constraint* sys_cnst = Sys->constraint_new(nullptr, 10);
170 sys_cnst->unshare(); // FATPIPE
171 lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1);
172 lmm::Variable* rho_2 = Sys->variable_new(nullptr, 2);
174 Sys->expand(sys_cnst, rho_1, 1);
175 Sys->expand(sys_cnst, rho_2, 1);
178 REQUIRE(double_equals(rho_1->get_value(), 10, sg_maxmin_precision));
179 REQUIRE(double_equals(rho_2->get_value(), 10 / 2, sg_maxmin_precision));
182 SECTION("Consumption weight")
186 * In a given constraint with all variable penalty to 1,
187 * the max_share is affected only by the maximum consumption weight
190 * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C1
191 * o consumption_weight: a1=1 ; a2=1
192 * o sharing_penalty: p1=1 ; p2=2
193 * o max_share: max(C1/(a1/p1),C1/(a2/p2))
196 * o rho1 = max_share/2 (because penalty of rho1 is 1)
197 * o rho2 = max_share/2 (because penalty of rho2 is 1)
200 lmm::Constraint* sys_cnst = Sys->constraint_new(nullptr, 10);
201 sys_cnst->unshare(); // FATPIPE
202 lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1);
203 lmm::Variable* rho_2 = Sys->variable_new(nullptr, 1);
205 Sys->expand(sys_cnst, rho_1, 1);
206 Sys->expand(sys_cnst, rho_2, 2);
209 REQUIRE(double_equals(rho_1->get_value(), 5, sg_maxmin_precision));
210 REQUIRE(double_equals(rho_2->get_value(), 5, sg_maxmin_precision));
213 SECTION("Consumption weight + variable penalty")
217 * Resource proportionality between variable is kept but
218 * constraint bound can be violated
221 * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C
222 * o consumption_weight: a1=1 ; a2=2
223 * o sharing_penalty: p1=1 ; p2=2
226 * o rho1 = 2 * rho2 (because rho2 has twice the penalty)
227 * o rho1 + 2*rho2 can be greater than C
228 * o rho1 <= C and 2*rho2 <= C
231 lmm::Constraint* sys_cnst = Sys->constraint_new(nullptr, 10);
233 lmm::Variable* sys_var_1 = Sys->variable_new(nullptr, 1);
234 lmm::Variable* sys_var_2 = Sys->variable_new(nullptr, 2);
236 Sys->expand(sys_cnst, sys_var_1, 1);
237 Sys->expand(sys_cnst, sys_var_2, 2);
240 REQUIRE(double_equals(sys_var_1->get_value(), 10, sg_maxmin_precision));
241 REQUIRE(double_equals(sys_var_2->get_value(), 5, sg_maxmin_precision));
244 SECTION("Multiple constraints systems")
248 * Multiple constraint systems can be solved with shared variables
249 * on unshair constraints.
252 * o System: a1 * p1 * \rho1 + a2 * p2 * \rho2 < C1
253 * a3 * p1 * \rho1 + a4 * p3 * \rho3 < C2
254 * o consumption_weight: a1=1 ; a2=2 ; a3=2 ; a4=1
255 * o sharing_penalty: p1=1 ; p2=2 ; p3=1
256 * o load: load_1=C1/max(p1/a1,p2/a2)=20 ; load_2=C2/max(a3/p1,a4/p3)=30
259 * o First constraint will be solve first (because load_1 < load_2)
260 * o Second constraint load will not be updated !
261 * o Each constraint should satisfy max(a_i * rho_i) <= C_r
264 lmm::Constraint* sys_cnst_1 = Sys->constraint_new(nullptr, 10);
265 lmm::Constraint* sys_cnst_2 = Sys->constraint_new(nullptr, 60);
266 sys_cnst_1->unshare(); // FATPIPE
267 sys_cnst_2->unshare();
269 lmm::Variable* rho_1 = Sys->variable_new(nullptr, 1, -1, 2);
270 lmm::Variable* rho_2 = Sys->variable_new(nullptr, 2, -1, 1);
271 lmm::Variable* rho_3 = Sys->variable_new(nullptr, 1, -1, 1);
274 Sys->expand(sys_cnst_1, rho_1, 1);
275 Sys->expand(sys_cnst_1, rho_2, 2);
278 Sys->expand(sys_cnst_2, rho_1, 2);
279 Sys->expand(sys_cnst_2, rho_3, 1);
282 double rho_1_share = 10; // Start by solving the first constraint (results is the same as previous tests)
283 REQUIRE(double_equals(rho_1->get_value(), rho_1_share, sg_maxmin_precision));
284 REQUIRE(double_equals(rho_2->get_value(), rho_1_share / 2, sg_maxmin_precision));
285 REQUIRE(double_equals(rho_3->get_value(), 60, sg_maxmin_precision));
288 Sys->variable_free_all();