Skip to content
2 changes: 2 additions & 0 deletions cpp/src/mip_heuristics/presolve/bounds_presolve.cu
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ bool bound_presolve_t<i_t, f_t>::calculate_bounds_update(problem_t<i_t, f_t>& pb
constexpr i_t zero = 0;
constexpr auto n_threads = 256;

upd.candidate_bound_scale =
pb.tolerances.absolute_tolerance / context.settings.semi_continuous_big_m;
upd.bounds_changed.set_value_async(zero, pb.handle_ptr->get_stream());
update_bounds_kernel<i_t, f_t, n_threads>
<<<pb.n_variables, n_threads, 0, pb.handle_ptr->get_stream()>>>(pb.view(), upd.view());
Expand Down
4 changes: 3 additions & 1 deletion cpp/src/mip_heuristics/presolve/bounds_update_data.cu
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ bounds_update_data_t<i_t, f_t>::bounds_update_data_t(problem_t<i_t, f_t>& proble
ub(problem.n_variables, problem.handle_ptr->get_stream()),
changed_constraints(problem.n_constraints, problem.handle_ptr->get_stream()),
next_changed_constraints(problem.n_constraints, problem.handle_ptr->get_stream()),
changed_variables(problem.n_variables, problem.handle_ptr->get_stream())
changed_variables(problem.n_variables, problem.handle_ptr->get_stream()),
candidate_bound_scale(f_t(0))
{
}

Expand Down Expand Up @@ -49,6 +50,7 @@ typename bounds_update_data_t<i_t, f_t>::view_t bounds_update_data_t<i_t, f_t>::
v.changed_constraints = make_span(changed_constraints);
v.next_changed_constraints = make_span(next_changed_constraints);
v.changed_variables = make_span(changed_variables);
v.candidate_bound_scale = candidate_bound_scale;
return v;
}

Expand Down
2 changes: 2 additions & 0 deletions cpp/src/mip_heuristics/presolve/bounds_update_data.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct bounds_update_data_t {
rmm::device_uvector<i_t> changed_constraints;
rmm::device_uvector<i_t> next_changed_constraints;
rmm::device_uvector<i_t> changed_variables;
f_t candidate_bound_scale;

struct view_t {
i_t* bounds_changed;
Expand All @@ -34,6 +35,7 @@ struct bounds_update_data_t {
raft::device_span<i_t> changed_constraints;
raft::device_span<i_t> next_changed_constraints;
raft::device_span<i_t> changed_variables;
f_t candidate_bound_scale;
};

bounds_update_data_t(problem_t<i_t, f_t>& pb);
Expand Down
25 changes: 21 additions & 4 deletions cpp/src/mip_heuristics/presolve/bounds_update_helpers.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ inline __device__ f_t update_ub(f_t curr_ub, f_t coeff, f_t delta_min_act, f_t d
return min(curr_ub, comp_bnd);
}

template <typename f_t>
inline __device__ bool accept_candidate_bound_update(f_t bound,
f_t abs_tol,
f_t candidate_bound_scale)
{
return abs(bound) * candidate_bound_scale <= abs_tol;
}

template <typename i_t, typename f_t, i_t BDIM>
__global__ void calc_activity_kernel(typename problem_t<i_t, f_t>::view_t pb,
typename bounds_update_data_t<i_t, f_t>::view_t upd_0,
Expand Down Expand Up @@ -185,10 +193,19 @@ inline __device__ thrust::pair<f_t, f_t> update_bounds_per_cnst(
}
min_a -= (coeff < 0) ? coeff * thrust::get<1>(old_bnd) : coeff * thrust::get<0>(old_bnd);
max_a -= (coeff > 0) ? coeff * thrust::get<1>(old_bnd) : coeff * thrust::get<0>(old_bnd);
auto delta_min_act = cnst_ub - min_a;
auto delta_max_act = cnst_lb - max_a;
thrust::get<0>(bnd) = update_lb(thrust::get<0>(bnd), coeff, delta_min_act, delta_max_act);
thrust::get<1>(bnd) = update_ub(thrust::get<1>(bnd), coeff, delta_min_act, delta_max_act);
auto delta_min_act = cnst_ub - min_a;
auto delta_max_act = cnst_lb - max_a;
auto new_lb = update_lb(thrust::get<0>(bnd), coeff, delta_min_act, delta_max_act);
auto new_ub = update_ub(thrust::get<1>(bnd), coeff, delta_min_act, delta_max_act);

if (accept_candidate_bound_update(
new_lb, pb.tolerances.absolute_tolerance, upd.candidate_bound_scale)) {
thrust::get<0>(bnd) = new_lb;
}
if (accept_candidate_bound_update(
new_ub, pb.tolerances.absolute_tolerance, upd.candidate_bound_scale)) {
thrust::get<1>(bnd) = new_ub;
}
return bnd;
}

Expand Down
4 changes: 4 additions & 0 deletions cpp/src/mip_heuristics/presolve/multi_probe.cu
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ bool multi_probe_t<i_t, f_t>::calculate_bounds_update(problem_t<i_t, f_t>& pb,
constexpr i_t zero = 0;
constexpr auto n_threads = 256;

upd_0.candidate_bound_scale =
pb.tolerances.absolute_tolerance / context.settings.semi_continuous_big_m;
upd_1.candidate_bound_scale =
pb.tolerances.absolute_tolerance / context.settings.semi_continuous_big_m;
if (skip_0 && skip_1) {
return false;
} else if (skip_0) {
Expand Down
8 changes: 8 additions & 0 deletions cpp/src/mip_heuristics/solve.cu
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,14 @@ mip_solution_t<i_t, f_t> solve_mip_helper(optimization_problem_t<i_t, f_t>& op_p
{
try {
mip_solver_settings_t<i_t, f_t> settings(settings_const);
cuopt_expects(std::isfinite(settings.tolerances.absolute_tolerance) &&
settings.tolerances.absolute_tolerance > f_t(0) &&
std::isfinite(settings.semi_continuous_big_m) &&
settings.semi_continuous_big_m > settings.tolerances.absolute_tolerance,
error_type_t::ValidationError,
"mip_absolute_tolerance must be finite and strictly positive, and "
"mip_semi_continuous_big_m must be finite and greater than "
"mip_absolute_tolerance");
Comment thread
coderabbitai[bot] marked this conversation as resolved.
if (settings.presolver == presolver_t::Default || settings.presolver == presolver_t::PSLP) {
if (settings.presolver == presolver_t::PSLP) {
CUOPT_LOG_INFO(
Expand Down
Loading