Skip to content

Commit 9dfbe3a

Browse files
committed
fix seeding the initial population before properly handling the free variables. added a guard to check if the variables are fixed to infinite or NaN bounds.
Signed-off-by: Nicolas L. Guidotti <nguidotti@nvidia.com>
1 parent 5658d72 commit 9dfbe3a

2 files changed

Lines changed: 22 additions & 4 deletions

File tree

cpp/src/mip_heuristics/diversity/diversity_manager.cu

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,16 @@ void diversity_manager_t<i_t, f_t>::add_user_given_solutions(
240240
}
241241

242242
if (problem_ptr->pre_process_assignment(init_sol_assignment)) {
243+
// Seed the solution with the provided assignment BEFORE fixing integers and running the
244+
// completion LP. Otherwise the fix uses the solution_t constructor's default assignment
245+
// (the variable lower bounds), which is -inf for free variables; fixing such a variable
246+
// makes fix_given_variables compute a NaN constraint bound (inf - inf) and trips the
247+
// problem-representation validation. Seeding first also lets us keep the LP's repaired
248+
// continuous values (previously overwritten by a post-LP copy).
249+
raft::copy(sol.assignment.data(),
250+
init_sol_assignment.data(),
251+
init_sol_assignment.size(),
252+
sol.handle_ptr->get_stream());
243253
relaxed_lp_settings_t lp_settings;
244254
lp_settings.time_limit = std::min(60., timer.remaining_time() / 2);
245255
lp_settings.tolerance = problem_ptr->tolerances.absolute_tolerance;
@@ -250,10 +260,6 @@ void diversity_manager_t<i_t, f_t>::add_user_given_solutions(
250260
problem_ptr->integer_indices,
251261
lp_settings,
252262
static_cast<bound_presolve_t<i_t, f_t>*>(nullptr));
253-
raft::copy(sol.assignment.data(),
254-
init_sol_assignment.data(),
255-
init_sol_assignment.size(),
256-
sol.handle_ptr->get_stream());
257263
bool is_feasible = sol.compute_feasibility();
258264
cuopt_func_call(sol.test_variable_bounds(true));
259265
CUOPT_LOG_DEBUG("Adding initial solution success! feas %d objective %f excess %f",

cpp/src/mip_heuristics/problem/problem.cu

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,6 +1706,18 @@ void problem_t<i_t, f_t>::fix_given_variables(problem_t<i_t, f_t>& original_prob
17061706
variables_to_fix.end(),
17071707
[variable_fix_mask = make_span(fixing_helpers.variable_fix_mask)] __device__(
17081708
i_t x) { variable_fix_mask[x] = 1; });
1709+
// Guard: fixing a variable to a non-finite value corrupts the constraint RHS below
1710+
// (coeff * floor(+-inf) = +-inf, then original_bound - inf can be inf - inf = NaN), which
1711+
// otherwise surfaces much later as an opaque "Constraints bounds are invalid" validation
1712+
// error. Fail loudly at the source instead. Callers must seed a finite assignment before
1713+
// fixing (e.g. free variables must not be left at their -inf lower-bound default).
1714+
cuopt_func_call(thrust::for_each(handle_ptr->get_thrust_policy(),
1715+
variables_to_fix.begin(),
1716+
variables_to_fix.end(),
1717+
[assignment = make_span(assignment)] __device__(i_t x) {
1718+
cuopt_assert(isfinite(assignment[x]),
1719+
"Fixing a variable to a non-finite value");
1720+
}));
17091721
const i_t num_segments = original_problem.n_constraints;
17101722
f_t initial_value{0.};
17111723

0 commit comments

Comments
 (0)