From 24a3653269533895eda13aacb4cde9b3908a6a06 Mon Sep 17 00:00:00 2001 From: Rajesh Gandham Date: Tue, 19 Aug 2025 10:37:21 -0700 Subject: [PATCH 1/2] Pass tolerances to papilo --- cpp/src/linear_programming/solve.cu | 1 + cpp/src/mip/presolve/third_party_presolve.cpp | 19 +++++++++++++++---- cpp/src/mip/presolve/third_party_presolve.hpp | 1 + cpp/src/mip/solve.cu | 1 + 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/cpp/src/linear_programming/solve.cu b/cpp/src/linear_programming/solve.cu index 504d87bd3..121357e8d 100644 --- a/cpp/src/linear_programming/solve.cu +++ b/cpp/src/linear_programming/solve.cu @@ -604,6 +604,7 @@ optimization_problem_solution_t solve_lp(optimization_problem_tapply(op_problem, cuopt::linear_programming::problem_category_t::LP, settings.tolerances.absolute_primal_tolerance, + settings.tolerances.relative_primal_tolerance, presolve_time_limit); if (!feasible) { return optimization_problem_solution_t( diff --git a/cpp/src/mip/presolve/third_party_presolve.cpp b/cpp/src/mip/presolve/third_party_presolve.cpp index 3d8700756..825391220 100644 --- a/cpp/src/mip/presolve/third_party_presolve.cpp +++ b/cpp/src/mip/presolve/third_party_presolve.cpp @@ -289,11 +289,20 @@ template void set_presolve_options(papilo::Presolve& presolver, problem_category_t category, f_t absolute_tolerance, + f_t relative_tolerance, double time_limit) { - presolver.getPresolveOptions().tlim = time_limit; - presolver.getPresolveOptions().epsilon = absolute_tolerance; - presolver.getPresolveOptions().feastol = absolute_tolerance; + presolver.getPresolveOptions().tlim = time_limit; + + if (category == problem_category_t::LP) { + presolver.getPresolveOptions().useabsfeas = false; + presolver.getPresolveOptions().feastol = relative_tolerance; + presolver.getPresolveOptions().epsilon = absolute_tolerance; + } else if (category == problem_category_t::MIP || category == problem_category_t::IP) { + presolver.getPresolveOptions().useabsfeas = true; + presolver.getPresolveOptions().feastol = absolute_tolerance; + presolver.getPresolveOptions().epsilon = absolute_tolerance; + } } template @@ -301,6 +310,7 @@ std::pair, bool> third_party_presolve_t const& op_problem, problem_category_t category, f_t absolute_tolerance, + f_t relative_tolerance, double time_limit) { cuopt_expects( @@ -316,7 +326,8 @@ std::pair, bool> third_party_presolve_t presolver; set_presolve_methods(presolver, category); - set_presolve_options(presolver, category, absolute_tolerance, time_limit); + set_presolve_options( + presolver, category, absolute_tolerance, relative_tolerance, time_limit); // Disable papilo logs presolver.setVerbosityLevel(papilo::VerbosityLevel::kQuiet); diff --git a/cpp/src/mip/presolve/third_party_presolve.hpp b/cpp/src/mip/presolve/third_party_presolve.hpp index 19a2c71cc..d7096a1a2 100644 --- a/cpp/src/mip/presolve/third_party_presolve.hpp +++ b/cpp/src/mip/presolve/third_party_presolve.hpp @@ -30,6 +30,7 @@ class third_party_presolve_t { optimization_problem_t const& op_problem, problem_category_t category, f_t absolute_tolerance, + f_t relative_tolerance, double time_limit); void undo(rmm::device_uvector& primal_solution, diff --git a/cpp/src/mip/solve.cu b/cpp/src/mip/solve.cu index 7071c33fe..ce6354ae9 100644 --- a/cpp/src/mip/solve.cu +++ b/cpp/src/mip/solve.cu @@ -197,6 +197,7 @@ mip_solution_t solve_mip(optimization_problem_t& op_problem, presolver->apply(op_problem, cuopt::linear_programming::problem_category_t::MIP, settings.tolerances.absolute_tolerance, + settings.tolerances.relative_tolerance, presolve_time_limit); if (!feasible) { return mip_solution_t(mip_termination_status_t::Infeasible, From f76da6fe4cf04736bb4d2a34d33b677819ee4676 Mon Sep 17 00:00:00 2001 From: Rajesh Gandham Date: Wed, 20 Aug 2025 07:34:51 -0700 Subject: [PATCH 2/2] Relax time limit criteria for short time limit case --- cpp/tests/linear_programming/c_api_tests/c_api_tests.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cpp/tests/linear_programming/c_api_tests/c_api_tests.cpp b/cpp/tests/linear_programming/c_api_tests/c_api_tests.cpp index bfd100946..d01f4319b 100644 --- a/cpp/tests/linear_programming/c_api_tests/c_api_tests.cpp +++ b/cpp/tests/linear_programming/c_api_tests/c_api_tests.cpp @@ -57,7 +57,11 @@ TEST_P(TimeLimitTestFixture, time_limit) method), CUOPT_SUCCESS); EXPECT_EQ(termination_status, CUOPT_TERIMINATION_STATUS_TIME_LIMIT); - EXPECT_NEAR(solve_time, target_solve_time, 1.0); + + // Dual simplex is spending some time for factorizing the basis, and this computation does not + // check for time limit + double excess_allowed_time = 2.0; + EXPECT_NEAR(solve_time, target_solve_time, excess_allowed_time); } INSTANTIATE_TEST_SUITE_P( c_api,