Skip to content

Commit a5756eb

Browse files
committed
Merge branch 'add_python_model_builder' of github.com:Iroy30/NvidiaCuopt into add_python_model_builder
2 parents 40abc69 + ee3d0a5 commit a5756eb

File tree

12 files changed

+103
-10
lines changed

12 files changed

+103
-10
lines changed

cpp/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ elseif(CMAKE_CUDA_LINEINFO)
134134
set(CMAKE_CUDA_FLAGS_RELEASE "${CMAKE_CUDA_FLAGS_RELEASE} -lineinfo")
135135
endif(CMAKE_BUILD_TYPE MATCHES Debug)
136136

137+
# Undefine NDEBUG if assert mode is on
138+
if(DEFINE_ASSERT)
139+
message(STATUS "Undefining NDEBUG with assert mode enabled")
140+
add_definitions(-UNDEBUG)
141+
endif()
142+
137143

138144
# ##################################################################################################
139145
# - find CPM based dependencies ------------------------------------------------------------------

cpp/src/linear_programming/solve.cu

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ void run_dual_simplex_thread(
467467

468468
template <typename i_t, typename f_t>
469469
optimization_problem_solution_t<i_t, f_t> run_concurrent(
470-
optimization_problem_t<i_t, f_t>& op_problem,
470+
const optimization_problem_t<i_t, f_t>& op_problem,
471471
detail::problem_t<i_t, f_t>& problem,
472472
pdlp_solver_settings_t<i_t, f_t> const& settings,
473473
bool is_batch_mode)
@@ -540,7 +540,7 @@ optimization_problem_solution_t<i_t, f_t> run_concurrent(
540540

541541
template <typename i_t, typename f_t>
542542
optimization_problem_solution_t<i_t, f_t> solve_lp_with_method(
543-
optimization_problem_t<i_t, f_t>& op_problem,
543+
const optimization_problem_t<i_t, f_t>& op_problem,
544544
detail::problem_t<i_t, f_t>& problem,
545545
pdlp_solver_settings_t<i_t, f_t> const& settings,
546546
bool is_batch_mode)
@@ -714,6 +714,12 @@ optimization_problem_solution_t<i_t, f_t> solve_lp(
714714
bool problem_checking, \
715715
bool use_pdlp_solver_mode); \
716716
\
717+
template optimization_problem_solution_t<int, F_TYPE> solve_lp_with_method( \
718+
const optimization_problem_t<int, F_TYPE>& op_problem, \
719+
detail::problem_t<int, F_TYPE>& problem, \
720+
pdlp_solver_settings_t<int, F_TYPE> const& settings, \
721+
bool is_batch_mode = false); \
722+
\
717723
template optimization_problem_t<int, F_TYPE> mps_data_model_to_optimization_problem( \
718724
raft::handle_t const* handle_ptr, \
719725
const cuopt::mps_parser::mps_data_model_t<int, F_TYPE>& data_model);

cpp/src/linear_programming/solve.cuh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,11 @@ cuopt::linear_programming::optimization_problem_t<i_t, f_t> mps_data_model_to_op
3030
raft::handle_t const* handle_ptr,
3131
const cuopt::mps_parser::mps_data_model_t<i_t, f_t>& data_model);
3232

33+
template <typename i_t, typename f_t>
34+
cuopt::linear_programming::optimization_problem_solution_t<i_t, f_t> solve_lp_with_method(
35+
const optimization_problem_t<i_t, f_t>& op_problem,
36+
detail::problem_t<i_t, f_t>& problem,
37+
pdlp_solver_settings_t<i_t, f_t> const& settings,
38+
bool is_batch_mode = false);
39+
3340
} // namespace cuopt::linear_programming

cpp/src/mip/diversity/assignment_hash_map.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ size_t assignment_hash_map_t<i_t, f_t>::hash_solution(solution_t<i_t, f_t>& solu
9797
hash_solution_kernel<i_t, f_t, TPB>
9898
<<<(integer_assignment.size() + TPB - 1) / TPB, TPB, 0, solution.handle_ptr->get_stream()>>>(
9999
cuopt::make_span(integer_assignment), cuopt::make_span(reduction_buffer));
100-
RAFT_CHECK_CUDA(handle_ptr->get_stream());
100+
RAFT_CHECK_CUDA(solution.handle_ptr->get_stream());
101101
// Get the number of blocks used in the hash_solution_kernel
102102
int num_blocks = (integer_assignment.size() + TPB - 1) / TPB;
103103

cpp/src/mip/solution/solution.cu

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,11 @@ f_t solution_t<i_t, f_t>::compute_max_int_violation()
541541
template <typename i_t, typename f_t>
542542
f_t solution_t<i_t, f_t>::compute_max_variable_violation()
543543
{
544+
cuopt_assert(problem_ptr->n_variables == assignment.size(), "Size mismatch");
545+
cuopt_assert(problem_ptr->n_variables == problem_ptr->variable_lower_bounds.size(),
546+
"Size mismatch");
547+
cuopt_assert(problem_ptr->n_variables == problem_ptr->variable_upper_bounds.size(),
548+
"Size mismatch");
544549
return thrust::transform_reduce(
545550
handle_ptr->get_thrust_policy(),
546551
thrust::make_counting_iterator(0),

cpp/src/mip/solve.cu

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,12 @@ mip_solution_t<i_t, f_t> run_mip(detail::problem_t<i_t, f_t>& problem,
125125
running_mip);
126126

127127
cuopt_func_call(auto saved_problem = scaled_problem);
128-
if (settings.mip_scaling) { scaling.scale_problem(); }
129-
if (settings.initial_solutions.size() > 0) {
130-
for (const auto& initial_solution : settings.initial_solutions) {
131-
scaling.scale_primal(*initial_solution);
128+
if (settings.mip_scaling) {
129+
scaling.scale_problem();
130+
if (settings.initial_solutions.size() > 0) {
131+
for (const auto& initial_solution : settings.initial_solutions) {
132+
scaling.scale_primal(*initial_solution);
133+
}
132134
}
133135
}
134136
// only call preprocess on scaled problem, so we can compute feasibility on the original problem

cpp/src/mip/solver.cu

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
#include "local_search/rounding/simple_rounding.cuh"
2424
#include "solver.cuh"
2525

26+
#include <linear_programming/pdlp.cuh>
27+
#include <linear_programming/solve.cuh>
28+
2629
#include <dual_simplex/branch_and_bound.hpp>
2730
#include <dual_simplex/simplex_solver_settings.hpp>
2831
#include <dual_simplex/solve.hpp>
@@ -124,6 +127,27 @@ solution_t<i_t, f_t> mip_solver_t<i_t, f_t>::run_solver()
124127
return sol;
125128
}
126129

130+
// if the problem was reduced to a LP: run concurrent LP
131+
if (context.problem_ptr->n_integer_vars == 0) {
132+
CUOPT_LOG_INFO("Problem reduced to a LP, running concurrent LP");
133+
pdlp_solver_settings_t<i_t, f_t> settings{};
134+
settings.time_limit = timer_.remaining_time();
135+
settings.method = method_t::Concurrent;
136+
137+
auto opt_sol = solve_lp_with_method<i_t, f_t>(
138+
*context.problem_ptr->original_problem_ptr, *context.problem_ptr, settings);
139+
140+
solution_t<i_t, f_t> sol(*context.problem_ptr);
141+
sol.copy_new_assignment(host_copy(opt_sol.get_primal_solution()));
142+
if (opt_sol.get_termination_status() == pdlp_termination_status_t::Optimal ||
143+
opt_sol.get_termination_status() == pdlp_termination_status_t::PrimalInfeasible ||
144+
opt_sol.get_termination_status() == pdlp_termination_status_t::DualInfeasible) {
145+
sol.set_problem_fully_reduced();
146+
}
147+
context.problem_ptr->post_process_solution(sol);
148+
return sol;
149+
}
150+
127151
namespace dual_simplex = cuopt::linear_programming::dual_simplex;
128152
std::future<dual_simplex::mip_status_t> branch_and_bound_status_future;
129153
dual_simplex::user_problem_t<i_t, f_t> branch_and_bound_problem;

cpp/src/utilities/macros.cuh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
// 2) medium
2424
// 3) heavy
2525
#ifdef ASSERT_MODE
26-
#undef NDEBUG
2726
#include <cassert>
2827
#define cuopt_assert(val, msg) assert(val&& msg)
2928
#define cuopt_func_call(func) func;

cpp/tests/mip/bounds_standardization_test.cu

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ void test_bounds_standardization_test(std::string test_instance)
7171
init_handler(op_problem.get_handle_ptr());
7272
// run the problem constructor of MIP, so that we do bounds standardization
7373
detail::problem_t<int, double> standardized_problem(op_problem);
74+
detail::problem_t<int, double> original_problem(op_problem);
7475
standardized_problem.preprocess_problem();
7576
detail::trivial_presolve(standardized_problem);
7677
detail::solution_t<int, double> solution_1(standardized_problem);
@@ -88,6 +89,7 @@ void test_bounds_standardization_test(std::string test_instance)
8889
// only consider the pdlp results
8990
EXPECT_TRUE(sol_1_feasible);
9091
standardized_problem.post_process_solution(solution_1);
92+
solution_1.problem_ptr = &original_problem;
9193
auto optimization_prob_solution =
9294
solution_1.get_solution(sol_1_feasible, solver_stats_t<int, double>{});
9395
test_objective_sanity(problem,

cpp/tests/mip/elim_var_remap_test.cu

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ void test_elim_var_solution(std::string test_instance)
154154
init_handler(op_problem.get_handle_ptr());
155155
// run the problem constructor of MIP, so that we do bounds standardization
156156
detail::problem_t<int, double> standardized_problem(op_problem);
157+
detail::problem_t<int, double> original_problem(op_problem);
157158
standardized_problem.preprocess_problem();
158159
trivial_presolve(standardized_problem);
159160
detail::problem_t<int, double> sub_problem(standardized_problem);
@@ -171,7 +172,8 @@ void test_elim_var_solution(std::string test_instance)
171172
bool sol_1_feasible = (int)result_1.get_termination_status() == CUOPT_TERIMINATION_STATUS_OPTIMAL;
172173
EXPECT_EQ((int)result_1.get_termination_status(), CUOPT_TERIMINATION_STATUS_OPTIMAL);
173174
standardized_problem.post_process_solution(solution_1);
174-
auto opt_sol_1 = solution_1.get_solution(sol_1_feasible, solver_stats_t<int, double>{});
175+
solution_1.problem_ptr = &original_problem;
176+
auto opt_sol_1 = solution_1.get_solution(sol_1_feasible, solver_stats_t<int, double>{});
175177
test_objective_sanity(
176178
mps_problem, opt_sol_1.get_solution(), opt_sol_1.get_objective_value(), 1e-3);
177179
test_constraint_sanity_per_row(
@@ -198,7 +200,8 @@ void test_elim_var_solution(std::string test_instance)
198200
bool sol_2_feasible = (int)result_2.get_termination_status() == CUOPT_TERIMINATION_STATUS_OPTIMAL;
199201
EXPECT_EQ((int)result_2.get_termination_status(), CUOPT_TERIMINATION_STATUS_OPTIMAL);
200202
sub_problem.post_process_solution(solution_2);
201-
auto opt_sol_2 = solution_2.get_solution(sol_2_feasible, solver_stats_t<int, double>{});
203+
solution_2.problem_ptr = &original_problem;
204+
auto opt_sol_2 = solution_2.get_solution(sol_2_feasible, solver_stats_t<int, double>{});
202205
test_objective_sanity(
203206
mps_problem, opt_sol_2.get_solution(), opt_sol_2.get_objective_value(), 1e-3);
204207
test_constraint_sanity_per_row(

0 commit comments

Comments
 (0)