static void *lmm_variable_mallocator_new_f(void);
static void lmm_variable_mallocator_free_f(void *var);
static void lmm_variable_mallocator_reset_f(void *var);
-
+static void lmm_update_modified_set(lmm_system_t sys, lmm_constraint_t cnst);
+static void lmm_remove_all_modified_set(lmm_system_t sys);
+int sg_maxmin_selective_update = 0;
+static int Global_debug_id = 1;
+static int Global_const_debug_id = 1;
lmm_system_t lmm_system_new(void)
{
lmm_system_t l = NULL;
l = xbt_new0(s_lmm_system_t, 1);
l->modified = 0;
+ l->selective_update_active = sg_maxmin_selective_update;
+
+ DEBUG1("Setting selective_update_active flag to %d\n",
+ l->selective_update_active);
+
xbt_swag_init(&(l->variable_set),
xbt_swag_offset(var, variable_set_hookup));
xbt_swag_init(&(l->constraint_set),
xbt_swag_init(&(l->active_constraint_set),
xbt_swag_offset(cnst, active_constraint_set_hookup));
+ xbt_swag_init(&(l->modified_constraint_set),
+ xbt_swag_offset(cnst, modified_constraint_set_hookup));
xbt_swag_init(&(l->saturated_variable_set),
xbt_swag_offset(var, saturated_variable_set_hookup));
xbt_swag_init(&(l->saturated_constraint_set),
xbt_swag_offset(cnst, saturated_constraint_set_hookup));
+ xbt_swag_init(&(l->modified_variable_set),
+ xbt_swag_offset(var, modified_variable_set_hookup));
+
l->variable_mallocator = xbt_mallocator_new(64,
lmm_variable_mallocator_new_f,
lmm_variable_mallocator_free_f,
xbt_swag_remove(elem, &(elem->constraint->active_element_set));
if (!xbt_swag_size(&(elem->constraint->element_set)))
make_constraint_inactive(sys, elem->constraint);
+ else
+ lmm_update_modified_set(sys, elem->constraint);
}
var->cnsts_number = 0;
XBT_OUT;
cnst = xbt_new0(s_lmm_constraint_t, 1);
cnst->id = id;
+ cnst->id_int = Global_const_debug_id++;
xbt_swag_init(&(cnst->element_set),
xbt_swag_offset(elem, element_set_hookup));
xbt_swag_init(&(cnst->active_element_set),
var = xbt_mallocator_get(sys->variable_mallocator);
var->id = id;
+ var->id_int = Global_debug_id++;
var->cnsts = xbt_new0(s_lmm_element_t, number_of_constraints);
for (i = 0; i < number_of_constraints; i++) {
/* Should be useless because of the
xbt_swag_insert_at_tail(elem, &(elem->constraint->element_set));
make_constraint_active(sys, cnst);
+ lmm_update_modified_set(sys, cnst);
}
void lmm_expand_add(lmm_system_t sys, lmm_constraint_t cnst,
var->cnsts[i].value += value;
else
var->cnsts[i].value = MAX(var->cnsts[i].value, value);
+ lmm_update_modified_set(sys, cnst);
} else
lmm_expand(sys, cnst, var, value);
}
if (i < var->cnsts_number) {
var->cnsts[i].value = value;
sys->modified = 1;
+ lmm_update_modified_set(sys, cnst);
} else
DIE_IMPOSSIBLE;
}
xbt_realloc(trace_buf, strlen(trace_buf) + strlen(print_buf) + 1);
strcat(trace_buf, print_buf);
xbt_swag_foreach(var, var_list) {
- sprintf(print_buf, "'%p'(%f) ", var, var->weight);
+ sprintf(print_buf, "'%d'(%f) ", var->id_int, var->weight);
trace_buf =
xbt_realloc(trace_buf, strlen(trace_buf) + strlen(print_buf) + 1);
strcat(trace_buf, print_buf);
trace_buf =
xbt_realloc(trace_buf, strlen(trace_buf) + strlen(print_buf) + 1);
strcat(trace_buf, print_buf);
- DEBUG1("%s", trace_buf);
+ fprintf(stderr, "%s", trace_buf);
+ //DEBUG1("%20s", trace_buf); FIXME
trace_buf[0] = '\000';
DEBUG0("Constraints");
xbt_realloc(trace_buf, strlen(trace_buf) + strlen(print_buf) + 1);
strcat(trace_buf, print_buf);
xbt_swag_foreach(elem, elem_list) {
- sprintf(print_buf, "%f.'%p'(%f) + ", elem->value,
- elem->variable, elem->variable->value);
+ sprintf(print_buf, "%f.'%d'(%f) + ", elem->value,
+ elem->variable->id_int, elem->variable->value);
trace_buf =
xbt_realloc(trace_buf, strlen(trace_buf) + strlen(print_buf) + 1);
strcat(trace_buf, print_buf);
sum += elem->value * elem->variable->value;
}
- sprintf(print_buf, "0 <= %f ('%p')", cnst->bound, cnst);
+ sprintf(print_buf, "0 <= %f ('%d')", cnst->bound, cnst->id_int);
trace_buf =
xbt_realloc(trace_buf, strlen(trace_buf) + strlen(print_buf) + 1);
strcat(trace_buf, print_buf);
xbt_realloc(trace_buf, strlen(trace_buf) + strlen(print_buf) + 1);
strcat(trace_buf, print_buf);
}
- DEBUG1("%s", trace_buf);
+ // DEBUG1("%s", trace_buf);
+ fprintf(stderr, "%s", trace_buf);
trace_buf[0] = '\000';
xbt_assert3(!double_positive(sum - cnst->bound),
"Incorrect value (%f is not smaller than %f): %g",
/* Printing Result */
xbt_swag_foreach(var, var_list) {
if (var->bound > 0) {
- DEBUG4("'%p'(%f) : %f (<=%f)", var, var->weight, var->value,
+ DEBUG4("'%d'(%f) : %f (<=%f)", var->id_int, var->weight, var->value,
var->bound);
xbt_assert2(!double_positive(var->value - var->bound),
"Incorrect value (%f is not smaller than %f",
var->value, var->bound);
- } else
- DEBUG3("'%p'(%f) : %f", var, var->weight, var->value);
+ } else {
+ DEBUG3("'%d'(%f) : %f", var->id_int, var->weight, var->value);
+ }
}
free(trace_buf);
if (!(sys->modified))
return;
- /* Init */
+ /*
+ * Compute Usage and store the variables that reach the maximum.
+ */
+ cnst_list = sys->selective_update_active ? &(sys->modified_constraint_set) :
+ &(sys->active_constraint_set);
+
+ DEBUG1("Active constraints : %d", xbt_swag_size(cnst_list));
+ /* Init: Only modified code portions */
+ xbt_swag_foreach(cnst, cnst_list) {
+ elem_list = &(cnst->element_set);
+ //DEBUG1("Variable set : %d", xbt_swag_size(elem_list));
+ xbt_swag_foreach(elem, elem_list) {
+ var = elem->variable;
+ xbt_swag_insert(var, &(sys->modified_variable_set));
+ /* FIXME: modified this test because we need all actions in cpu_im */
+ if (var->weight <= 0.0)
+ //break;
+ continue;
+ var->value = 0.0;
+ }
+ }
+
+ /* Init: special case where all constraints are 0 */
var_list = &(sys->variable_set);
DEBUG1("Variable set : %d", xbt_swag_size(var_list));
xbt_swag_foreach(var, var_list) {
int i;
if (var->weight <= 0.0)
break;
- var->value = 0.0;
for (i = 0; i < var->cnsts_number; i++) {
if (var->cnsts[i].value == 0.0)
nb++;
var->value = 1.0;
}
- /*
- * Compute Usage and store the variables that reach the maximum.
- */
- cnst_list = &(sys->active_constraint_set);
DEBUG1("Active constraints : %d", xbt_swag_size(cnst_list));
xbt_swag_foreach(cnst, cnst_list) {
/* INIT */
cnst->usage += elem->value / elem->variable->weight;
else if (cnst->usage < elem->value / elem->variable->weight)
cnst->usage = elem->value / elem->variable->weight;
- DEBUG2("Constraint Usage %p : %f", cnst, cnst->usage);
+
make_elem_active(elem);
}
}
+ DEBUG2("Constraint Usage %d : %f", cnst->id_int, cnst->usage);
/* Saturated constraints update */
saturated_constraint_set_update(sys, cnst, &min_usage);
}
/* First check if some of these variables have reach their upper
bound and update min_usage accordingly. */
DEBUG5
- ("var=%p, var->bound=%f, var->weight=%f, min_usage=%f, var->bound*var->weight=%f",
- var, var->bound, var->weight, min_usage, var->bound * var->weight);
+ ("var=%d, var->bound=%f, var->weight=%f, min_usage=%f, var->bound*var->weight=%f",
+ var->id_int, var->bound, var->weight, min_usage,
+ var->bound * var->weight);
if ((var->bound > 0) && (var->bound * var->weight < min_usage)) {
if (min_bound < 0)
min_bound = var->bound;
while ((var = xbt_swag_getFirst(var_list))) {
int i;
+ xbt_swag_insert(var, &(sys->modified_variable_set));
if (min_bound < 0) {
var->value = min_usage / var->weight;
continue;
}
}
- DEBUG5("Min usage: %f, Var(%p)->weight: %f, Var(%p)->value: %f ",
- min_usage, var, var->weight, var, var->value);
+ DEBUG5("Min usage: %f, Var(%d)->weight: %f, Var(%d)->value: %f ",
+ min_usage, var->id_int, var->weight, var->id_int, var->value);
/* Update usage */
if ((elem->value > 0)) {
if (cnst->usage < elem->value / elem->variable->weight)
cnst->usage = elem->value / elem->variable->weight;
- DEBUG2("Constraint Usage %p : %f", cnst, cnst->usage);
+ DEBUG2("Constraint Usage %d : %f", cnst->id_int, cnst->usage);
make_elem_active(elem);
}
}
}
/* Find out which variables reach the maximum */
- cnst_list = &(sys->active_constraint_set);
+ cnst_list =
+ sys->selective_update_active ? &(sys->
+ modified_constraint_set) :
+ &(sys->active_constraint_set);
min_usage = -1;
min_bound = -1;
xbt_swag_foreach(cnst, cnst_list) {
} while (xbt_swag_size(&(sys->saturated_variable_set)));
sys->modified = 0;
+ if (sys->selective_update_active)
+ lmm_remove_all_modified_set(sys);
+
if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
lmm_print(sys);
}
{
int i;
- sys->modified = 1;
for (i = 0; i < var->cnsts_number; i++)
if (var->cnsts[i].constraint == cnst) {
var->cnsts[i].value = value;
+ sys->modified = 1;
+ lmm_update_modified_set(sys, cnst);
return;
}
}
void lmm_update_variable_bound(lmm_system_t sys, lmm_variable_t var,
double bound)
{
+ int i;
+
sys->modified = 1;
var->bound = bound;
+
+ for (i = 0; i < var->cnsts_number; i++)
+ lmm_update_modified_set(sys, var->cnsts[i].constraint);
+
}
xbt_swag_insert_at_head(elem, &(elem->constraint->element_set));
else
xbt_swag_insert_at_tail(elem, &(elem->constraint->element_set));
+
+ lmm_update_modified_set(sys, elem->constraint);
}
if (!weight)
var->value = 0.0;
double bound)
{
sys->modified = 1;
+ lmm_update_modified_set(sys, cnst);
cnst->bound = bound;
}
{
return xbt_swag_getNext(cnst, (sys->active_constraint_set).offset);
}
+
+/** \brief Update the constraint set propagating recursively to
+ * other constraints so the system should not be entirely computed.
+ *
+ * \param sys the lmm_system_t
+ * \param cnst the lmm_constraint_t affected by the change
+ *
+ * A recursive algorithm to optimize the system recalculation selecting only
+ * constraints that have changed. Each constraint change is propagated
+ * to the list of constraints for each variable.
+ */
+static void lmm_update_modified_set(lmm_system_t sys, lmm_constraint_t cnst)
+{
+ lmm_element_t elem = NULL;
+ lmm_variable_t var = NULL;
+ xbt_swag_t elem_list = NULL;
+ int i;
+
+ /* return if selective update isn't active */
+ if (!sys->selective_update_active)
+ return;
+
+ //DEBUG1("Updating modified constraint set with constraint %d", cnst->id_int);
+
+ if (xbt_swag_belongs(cnst, &(sys->modified_constraint_set)))
+ return;
+
+ //DEBUG1("Inserting into modified constraint set %d", cnst->id_int);
+
+ /* add to modified set */
+ xbt_swag_insert(cnst, &(sys->modified_constraint_set));
+
+ elem_list = &(cnst->element_set);
+ xbt_swag_foreach(elem, elem_list) {
+ var = elem->variable;
+ for (i = 0; i < var->cnsts_number; i++)
+ if (cnst != var->cnsts[i].constraint) {
+ //DEBUG2("Updating modified %d calling for %d", cnst->id_int, var->cnsts[i].constraint->id_int);
+ lmm_update_modified_set(sys, var->cnsts[i].constraint);
+ }
+ }
+}
+
+/** \brief Remove all constraints of the modified_constraint_set.
+ *
+ * \param sys the lmm_system_t
+ */
+static void lmm_remove_all_modified_set(lmm_system_t sys)
+{
+ lmm_element_t elem = NULL;
+ lmm_element_t elem_next = NULL;
+ xbt_swag_t elem_list = NULL;
+
+ elem_list = &(sys->modified_constraint_set);
+ xbt_swag_foreach_safe(elem, elem_next, elem_list) {
+ xbt_swag_remove(elem, elem_list);
+ }
+}
+
+void *lmm_extract_modified_variable(lmm_system_t sys)
+{
+ lmm_variable_t var;
+ var = xbt_swag_extract(&(sys->modified_variable_set));
+ if (var)
+ return var->id;
+ return NULL;
+}