Skip to content

Commit b3a20a0

Browse files
Merge branch 'main' into modernize-dependencies
2 parents 7a40ef7 + 3be4325 commit b3a20a0

File tree

21 files changed

+190
-100
lines changed

21 files changed

+190
-100
lines changed

cpp/src/linear_programming/solve.cu

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -924,17 +924,9 @@ optimization_problem_solution_t<i_t, f_t> solve_lp(
924924
reduced_costs,
925925
cuopt::linear_programming::problem_category_t::LP,
926926
status_to_skip,
927+
settings.dual_postsolve,
927928
op_problem.get_handle_ptr()->get_stream());
928929

929-
thrust::fill(rmm::exec_policy(op_problem.get_handle_ptr()->get_stream()),
930-
dual_solution.data(),
931-
dual_solution.data() + dual_solution.size(),
932-
std::numeric_limits<f_t>::signaling_NaN());
933-
thrust::fill(rmm::exec_policy(op_problem.get_handle_ptr()->get_stream()),
934-
reduced_costs.data(),
935-
reduced_costs.data() + reduced_costs.size(),
936-
std::numeric_limits<f_t>::signaling_NaN());
937-
938930
auto full_stats = solution.get_additional_termination_information();
939931

940932
// Create a new solution with the full problem solution

cpp/src/linear_programming/utilities/problem_checking.cu

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,8 @@ void problem_checking_t<i_t, f_t>::check_csr_representation(
4545
cuopt_expects(thrust::all_of(op_problem.get_handle_ptr()->get_thrust_policy(),
4646
op_problem.get_constraint_matrix_indices().cbegin(),
4747
op_problem.get_constraint_matrix_indices().cend(),
48-
[n_variables = op_problem.get_n_variables()] __device__(i_t val) {
49-
return val >= 0 && val < n_variables;
50-
}),
48+
[n_variables = op_problem.get_n_variables()] __device__(
49+
i_t val) -> bool { return val >= 0 && val < n_variables; }),
5150
error_type_t::ValidationError,
5251
"A_indices values must positive lower than the number of variables (c size).");
5352
}
@@ -72,7 +71,7 @@ void problem_checking_t<i_t, f_t>::check_initial_primal_representation(
7271
[lower_bounds = make_span(op_problem.get_variable_lower_bounds()),
7372
upper_bounds = make_span(op_problem.get_variable_upper_bounds()),
7473
assignment_span = make_span(primal_initial_solution),
75-
int_tol = 1e-8] __device__(i_t idx) {
74+
int_tol = 1e-8] __device__(i_t idx) -> bool {
7675
return assignment_span[idx] < lower_bounds[idx] - int_tol ||
7776
assignment_span[idx] > upper_bounds[idx] + int_tol;
7877
}),
@@ -171,13 +170,14 @@ void problem_checking_t<i_t, f_t>::check_problem_representation(
171170

172171
// Check row type if set
173172
if (!op_problem.get_row_types().is_empty()) {
174-
cuopt_expects(
175-
thrust::all_of(op_problem.get_handle_ptr()->get_thrust_policy(),
176-
op_problem.get_row_types().cbegin(),
177-
op_problem.get_row_types().cend(),
178-
[] __device__(char val) { return val == 'E' || val == 'G' || val == 'L'; }),
179-
error_type_t::ValidationError,
180-
"row_types values must equal to 'E', 'G' or 'L'.");
173+
cuopt_expects(thrust::all_of(op_problem.get_handle_ptr()->get_thrust_policy(),
174+
op_problem.get_row_types().cbegin(),
175+
op_problem.get_row_types().cend(),
176+
[] __device__(char val) -> bool {
177+
return val == 'E' || val == 'G' || val == 'L';
178+
}),
179+
error_type_t::ValidationError,
180+
"row_types values must equal to 'E', 'G' or 'L'.");
181181

182182
cuopt_expects(
183183
op_problem.get_row_types().size() == op_problem.get_constraint_bounds().size(),
@@ -322,19 +322,17 @@ bool problem_checking_t<i_t, f_t>::has_crossing_bounds(
322322
thrust::make_counting_iterator(0),
323323
thrust::make_counting_iterator(0) + op_problem.get_variable_upper_bounds().size(),
324324
[upper_bounds = make_span(op_problem.get_variable_upper_bounds()),
325-
lower_bounds = make_span(op_problem.get_variable_lower_bounds())] __device__(size_t i) {
326-
return upper_bounds[i] >= lower_bounds[i];
327-
});
325+
lower_bounds = make_span(op_problem.get_variable_lower_bounds())] __device__(size_t i)
326+
-> bool { return upper_bounds[i] >= lower_bounds[i]; });
328327

329328
// Check if all constraint bounds are valid (upper >= lower)
330329
bool all_constraint_bounds_valid = thrust::all_of(
331330
op_problem.get_handle_ptr()->get_thrust_policy(),
332331
thrust::make_counting_iterator(0),
333332
thrust::make_counting_iterator(0) + op_problem.get_constraint_upper_bounds().size(),
334333
[upper_bounds = make_span(op_problem.get_constraint_upper_bounds()),
335-
lower_bounds = make_span(op_problem.get_constraint_lower_bounds())] __device__(size_t i) {
336-
return upper_bounds[i] >= lower_bounds[i];
337-
});
334+
lower_bounds = make_span(op_problem.get_constraint_lower_bounds())] __device__(size_t i)
335+
-> bool { return upper_bounds[i] >= lower_bounds[i]; });
338336

339337
// Return true if any bounds are invalid (crossing)
340338
return !all_variable_bounds_valid || !all_constraint_bounds_valid;

cpp/src/mip/diversity/recombiners/bound_prop_recombiner.cuh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "recombiner.cuh"
1111

12+
#include <thrust/pair.h>
1213
#include <mip/local_search/rounding/constraint_prop.cuh>
1314
#include <mip/relaxed_lp/relaxed_lp.cuh>
1415
#include <mip/solution/solution.cuh>

cpp/src/mip/feasibility_jump/utils.cuh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "feasibility_jump.cuh"
1111

12+
#include <thrust/pair.h>
1213
#include <cuda/atomic>
1314
#include <raft/core/device_span.hpp>
1415
#include <rmm/device_scalar.hpp>

cpp/src/mip/local_search/rounding/bounds_repair.cu

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ void bounds_repair_t<i_t, f_t>::compute_damages(problem_t<i_t, f_t>& problem, i_
268268
sort_iterator + n_candidates,
269269
thrust::make_zip_iterator(thrust::make_tuple(
270270
candidates.bound_shift.data(), candidates.variable_index.data())),
271-
[] __device__(auto tuple1, auto tuple2) {
271+
[] __device__(auto tuple1, auto tuple2) -> bool {
272272
if (thrust::get<0>(tuple1) < thrust::get<0>(tuple2)) {
273273
return true;
274274
} else if (thrust::get<0>(tuple1) == thrust::get<0>(tuple2) &&
@@ -291,7 +291,7 @@ i_t bounds_repair_t<i_t, f_t>::find_cutoff_index(const candidates_t<i_t, f_t>& c
291291
handle_ptr->get_thrust_policy(),
292292
iterator,
293293
iterator + n_candidates,
294-
[best_cstr_delta, best_damage] __device__(auto tuple) {
294+
[best_cstr_delta, best_damage] __device__(auto tuple) -> bool {
295295
if (thrust::get<0>(tuple) == best_cstr_delta && thrust::get<1>(tuple) <= best_damage) {
296296
return true;
297297
}

cpp/src/mip/local_search/rounding/constraint_prop.cuh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#pragma once
99

10+
#include <thrust/pair.h>
1011
#include <mip/local_search/rounding/bounds_repair.cuh>
1112
#include <mip/presolve/bounds_presolve.cuh>
1213
#include <mip/presolve/conditional_bound_strengthening.cuh>

cpp/src/mip/presolve/bounds_presolve.cuh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
#include <utilities/timer.hpp>
1818

19+
#include <thrust/pair.h>
20+
1921
#include "bounds_update_data.cuh"
2022
#include "utils.cuh"
2123

cpp/src/mip/presolve/bounds_update_helpers.cuh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
/* clang-format on */
77

8+
#include <thrust/pair.h>
89
#include <mip/problem/problem.cuh>
910
#include <mip/utils.cuh>
1011
#include "bounds_update_data.cuh"

cpp/src/mip/presolve/third_party_presolve.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,11 +356,16 @@ void set_presolve_options(papilo::Presolve<f_t>& presolver,
356356
f_t absolute_tolerance,
357357
f_t relative_tolerance,
358358
double time_limit,
359+
bool dual_postsolve,
359360
i_t num_cpu_threads)
360361
{
361362
presolver.getPresolveOptions().tlim = time_limit;
362363
presolver.getPresolveOptions().threads = num_cpu_threads; // user setting or 0 (automatic)
363364
presolver.getPresolveOptions().feastol = 1e-5;
365+
if (dual_postsolve) {
366+
presolver.getPresolveOptions().componentsmaxint = -1;
367+
presolver.getPresolveOptions().detectlindep = 0;
368+
}
364369
}
365370

366371
template <typename f_t>
@@ -404,8 +409,13 @@ std::optional<third_party_presolve_result_t<i_t, f_t>> third_party_presolve_t<i_
404409
if (category == problem_category_t::MIP) { dual_postsolve = false; }
405410
papilo::Presolve<f_t> presolver;
406411
set_presolve_methods<f_t>(presolver, category, dual_postsolve);
407-
set_presolve_options<i_t, f_t>(
408-
presolver, category, absolute_tolerance, relative_tolerance, time_limit, num_cpu_threads);
412+
set_presolve_options<i_t, f_t>(presolver,
413+
category,
414+
absolute_tolerance,
415+
relative_tolerance,
416+
time_limit,
417+
dual_postsolve,
418+
num_cpu_threads);
409419
set_presolve_parameters<f_t>(
410420
presolver, category, op_problem.get_n_constraints(), op_problem.get_n_variables());
411421

@@ -446,6 +456,7 @@ void third_party_presolve_t<i_t, f_t>::undo(rmm::device_uvector<f_t>& primal_sol
446456
rmm::device_uvector<f_t>& reduced_costs,
447457
problem_category_t category,
448458
bool status_to_skip,
459+
bool dual_postsolve,
449460
rmm::cuda_stream_view stream_view)
450461
{
451462
if (status_to_skip) { return; }
@@ -455,8 +466,12 @@ void third_party_presolve_t<i_t, f_t>::undo(rmm::device_uvector<f_t>& primal_sol
455466
raft::copy(dual_sol_vec_h.data(), dual_solution.data(), dual_solution.size(), stream_view);
456467
std::vector<f_t> reduced_costs_vec_h(reduced_costs.size());
457468
raft::copy(reduced_costs_vec_h.data(), reduced_costs.data(), reduced_costs.size(), stream_view);
458-
459469
papilo::Solution<f_t> reduced_sol(primal_sol_vec_h);
470+
if (dual_postsolve) {
471+
reduced_sol.dual = dual_sol_vec_h;
472+
reduced_sol.reducedCosts = reduced_costs_vec_h;
473+
reduced_sol.type = papilo::SolutionType::kPrimalDual;
474+
}
460475
papilo::Solution<f_t> full_sol;
461476

462477
papilo::Message Msg{};

cpp/src/mip/presolve/third_party_presolve.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class third_party_presolve_t {
3939
rmm::device_uvector<f_t>& reduced_costs,
4040
problem_category_t category,
4141
bool status_to_skip,
42+
bool dual_postsolve,
4243
rmm::cuda_stream_view stream_view);
4344
};
4445

0 commit comments

Comments
 (0)