Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
80656e6
add non adaptative step size strategy
Kh4ster Sep 1, 2025
08f2687
add new initial step size strategy
Kh4ster Sep 2, 2025
48e7075
add new initial primal weight strategy
Kh4ster Sep 2, 2025
f15fd2f
add new scaling strategy
Kh4ster Sep 2, 2025
cc347fe
add reflected primal and dual, added debug code, fix primal weight wi…
Kh4ster Sep 3, 2025
e5582e2
add halpen update, add fixed point computation, fix bug step pdlp ite…
Kh4ster Sep 5, 2025
539ab5d
Add a new restart stragey:
Kh4ster Sep 10, 2025
a8904c6
fix halpen logic
Kh4ster Sep 10, 2025
ff6f905
introduce condition major and fix its overflow checking, fix not upda…
Kh4ster Sep 10, 2025
353a532
fix return correct solution and use cuda graph
Kh4ster Sep 10, 2025
a16ff2c
update Stable3 as default and update comments
Kh4ster Sep 10, 2025
0a08599
add more nvtx ranges
Kh4ster Sep 10, 2025
49508b4
minor comment and include fixes
Kh4ster Sep 10, 2025
b8f7e19
add a few comments
Kh4ster Sep 10, 2025
dbf5b6d
Merge branch 'branch-25.10' into cupdlp_plus
Kh4ster Sep 10, 2025
b1f8048
Merge branch 'branch-25.10' into cupdlp_plus
aliceb-nv Sep 15, 2025
aaf1473
combined bounds merge
aliceb-nv Sep 16, 2025
a0fffe6
gf2 xor constraint detection
aliceb-nv Sep 19, 2025
e16e608
working, b4 moving to papilo presolver
aliceb-nv Sep 20, 2025
9d95014
added as a papilo presolver
aliceb-nv Sep 20, 2025
182ac18
cleanup
aliceb-nv Sep 20, 2025
2854167
Merge branch 'branch-25.10' into cupdlp_plus
aliceb-nv Sep 21, 2025
cc1ee03
fix test build
aliceb-nv Sep 21, 2025
dc61271
switch to an actually hard instance :)
aliceb-nv Sep 22, 2025
36b5f47
fix crash on reflected primal dual
aliceb-nv Sep 22, 2025
3e1fe0c
Update cpp/src/mip/presolve/gf2_presolve.cpp
aliceb-nv Sep 22, 2025
6a955ea
Update cpp/src/mip/presolve/third_party_presolve.cpp
aliceb-nv Sep 22, 2025
201fb80
Merge branch 'branch-25.10' into gf2-pr
aliceb-nv Sep 22, 2025
7b28b24
transaction guard, fix build
aliceb-nv Sep 22, 2025
1588c15
style fix
aliceb-nv Sep 22, 2025
5becfdb
fix scaling
aliceb-nv Sep 23, 2025
0dd56f3
Merge branch 'gf2-pr' into cupdlp_plus
aliceb-nv Sep 23, 2025
6a99fac
tentative fix
aliceb-nv Sep 24, 2025
84b3b6e
fix relaxed_lp calls
aliceb-nv Sep 24, 2025
5013bc8
Merge branch 'branch-25.10' into cupdlp_plus
aliceb-nv Sep 24, 2025
667ed63
bump
aliceb-nv Sep 25, 2025
0a3b19d
bump 2
aliceb-nv Sep 25, 2025
41bb0d7
dual2 experiments
aliceb-nv Sep 25, 2025
3cb51be
amend[1
aliceb-nv Sep 25, 2025
80c73f1
a
aliceb-nv Sep 25, 2025
7033bea
pdlp iterations fix
aliceb-nv Sep 25, 2025
ac93f87
Merge branch 'branch-25.10' into cupdlp_plus
aliceb-nv Sep 25, 2025
2511ad7
relaxed lp stable2
aliceb-nv Sep 25, 2025
9227119
Merge branch 'branch-25.10' into cupdlp_plus
aliceb-nv Sep 25, 2025
165f638
relaxed lp stable2
aliceb-nv Sep 26, 2025
904b019
Merge branch 'branch-25.10' into cupdlp_plus
aliceb-nv Sep 26, 2025
fb71348
merge
aliceb-nv Sep 26, 2025
af661da
remove leftovers
aliceb-nv Sep 26, 2025
c2445fb
CI fixwa
aliceb-nv Sep 26, 2025
df7ecdb
fix enum order
aliceb-nv Sep 26, 2025
5cfe6ba
tentative CI fixes
aliceb-nv Sep 27, 2025
e809171
CI fixes
aliceb-nv Sep 27, 2025
44b383b
CI
aliceb-nv Sep 27, 2025
ed0d8b6
CI fixes
aliceb-nv Sep 28, 2025
0545a05
fix CLI test abort
aliceb-nv Sep 29, 2025
5600d6f
tentative CI fix
aliceb-nv Sep 29, 2025
9d0bd68
Merge branch 'branch-25.10' into cupdlp_plus
aliceb-nv Sep 29, 2025
7b3b254
remove leftovers
aliceb-nv Sep 29, 2025
94486ba
fix tests
aliceb-nv Sep 29, 2025
089c96a
address review comments
aliceb-nv Sep 29, 2025
bdba7a1
Update release-notes.rst
rgsl888prabhu Sep 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions benchmarks/linear_programming/cuopt/benchmark_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ void fill_pdlp_hyper_params(const std::string& pdlp_hyper_params_path)
handle_some_primal_gradients_on_finite_bounds_as_residuals},
{"project_initial_primal",
&cuopt::linear_programming::pdlp_hyper_params::project_initial_primal},
{"use_adaptive_step_size_strategy",
&cuopt::linear_programming::pdlp_hyper_params::use_adaptive_step_size_strategy},
};

while (std::getline(file, line)) {
Expand Down
11 changes: 7 additions & 4 deletions benchmarks/linear_programming/cuopt/run_pdlp.cu
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@ static void parse_arguments(argparse::ArgumentParser& program)
.default_value(1e-4)
.scan<'g', double>();

// TODO replace all comments with Stable2 with Stable3
program.add_argument("--pdlp-solver-mode")
.help("Solver mode for PDLP. Possible values: Stable2 (default), Methodical1, Fast1")
.default_value("Stable2")
.choices("Stable2", "Methodical1", "Fast1");
.help("Solver mode for PDLP. Possible values: Stable3 (default), Methodical1, Fast1")
.default_value("Stable3")
.choices("Stable3", "Methodical1", "Fast1");

program.add_argument("--method")
.help(
Expand Down Expand Up @@ -90,7 +91,9 @@ static cuopt::linear_programming::pdlp_solver_mode_t string_to_pdlp_solver_mode(
return cuopt::linear_programming::pdlp_solver_mode_t::Methodical1;
else if (mode == "Fast1")
return cuopt::linear_programming::pdlp_solver_mode_t::Fast1;
return cuopt::linear_programming::pdlp_solver_mode_t::Stable2;
else if (mode == "Stable3")
return cuopt::linear_programming::pdlp_solver_mode_t::Stable3;
return cuopt::linear_programming::pdlp_solver_mode_t::Stable3;
}

static cuopt::linear_programming::pdlp_solver_settings_t<int, double> create_solver_settings(
Expand Down
12 changes: 6 additions & 6 deletions cpp/cuopt_cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,13 @@ int run_single_file(const std::string& file_path,
(op_problem.get_problem_category() == cuopt::linear_programming::problem_category_t::MIP ||
op_problem.get_problem_category() == cuopt::linear_programming::problem_category_t::IP);

auto initial_solution =
initial_solution_file.empty()
? std::vector<double>()
: cuopt::linear_programming::solution_reader_t::get_variable_values_from_sol_file(
initial_solution_file, mps_data_model.get_variable_names());

try {
auto initial_solution =
initial_solution_file.empty()
? std::vector<double>()
: cuopt::linear_programming::solution_reader_t::get_variable_values_from_sol_file(
initial_solution_file, mps_data_model.get_variable_names());

if (is_mip && !solve_relaxation) {
auto& mip_settings = settings.get_mip_settings();
if (initial_solution.size() > 0) {
Expand Down
1 change: 1 addition & 0 deletions cpp/include/cuopt/linear_programming/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@
#define CUOPT_PDLP_SOLVER_MODE_STABLE2 1
#define CUOPT_PDLP_SOLVER_MODE_METHODICAL1 2
#define CUOPT_PDLP_SOLVER_MODE_FAST1 3
#define CUOPT_PDLP_SOLVER_MODE_STABLE3 4

#define CUOPT_METHOD_CONCURRENT 0
#define CUOPT_METHOD_PDLP 1
Expand Down
12 changes: 12 additions & 0 deletions cpp/include/cuopt/linear_programming/pdlp/pdlp_hyper_params.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,17 @@ extern bool update_primal_weight_on_initial_solution;
extern bool update_step_size_on_initial_solution;
extern bool handle_some_primal_gradients_on_finite_bounds_as_residuals;
extern bool project_initial_primal;
extern bool use_adaptive_step_size_strategy;
extern bool initial_step_size_max_singular_value;
extern bool initial_primal_weight_combined_bounds;
extern bool bound_objective_rescaling;
extern bool use_reflected_primal_dual;
extern bool use_fixed_point_error;
extern double reflection_coefficient;
extern double restart_k_p;
extern double restart_k_i;
extern double restart_k_d;
extern double restart_i_smooth;
extern bool use_conditional_major;

} // namespace cuopt::linear_programming::pdlp_hyper_params
11 changes: 6 additions & 5 deletions cpp/include/cuopt/linear_programming/pdlp/solver_settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,22 @@ class solver_settings_t;
* @brief Enum representing the different solver modes under which PDLP can
* operate.
*
* Stable2: Best overall mode from experiments; balances speed and convergence
* success. If you want to use the legacy version, use Stable1.
* Stable3: Best overall mode from experiments; balances speed and convergence
* success. If you want to use the legacy version, use Stable2.
* Methodical1: Usually leads to slower individual steps but fewer are needed to
* converge. It uses from 1.3x up to 1.7x times more memory.
* Fast1: Less convergence success but usually yields the highest speed
*
* @note Default mode is Stable2.
* @note Default mode is Stable3.
*/
// Forced to use an enum instead of an enum class for compatibility with the
// Cython layer
enum pdlp_solver_mode_t : int {
Stable1 = CUOPT_PDLP_SOLVER_MODE_STABLE1,
Stable2 = CUOPT_PDLP_SOLVER_MODE_STABLE2,
Methodical1 = CUOPT_PDLP_SOLVER_MODE_METHODICAL1,
Fast1 = CUOPT_PDLP_SOLVER_MODE_FAST1
Fast1 = CUOPT_PDLP_SOLVER_MODE_FAST1,
Stable3 = CUOPT_PDLP_SOLVER_MODE_STABLE3
};

/**
Expand Down Expand Up @@ -200,7 +201,7 @@ class pdlp_solver_settings_t {
bool strict_infeasibility{false};
i_t iteration_limit{std::numeric_limits<i_t>::max()};
double time_limit{std::numeric_limits<double>::infinity()};
pdlp_solver_mode_t pdlp_solver_mode{pdlp_solver_mode_t::Stable2};
pdlp_solver_mode_t pdlp_solver_mode{pdlp_solver_mode_t::Stable3};
bool log_to_console{true};
std::string log_file{""};
std::string sol_file{""};
Expand Down
26 changes: 21 additions & 5 deletions cpp/src/linear_programming/cusparse_view.cu
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ cusparse_view_t<i_t, f_t>::cusparse_view_t(
saddle_point_state_t<i_t, f_t>& current_saddle_point_state,
rmm::device_uvector<f_t>& _tmp_primal,
rmm::device_uvector<f_t>& _tmp_dual,
rmm::device_uvector<f_t>& _potential_next_dual_solution)
rmm::device_uvector<f_t>& _potential_next_dual_solution,
rmm::device_uvector<f_t>& _reflected_primal_solution)
: handle_ptr_(handle_ptr),
A{},
A_T{},
Expand Down Expand Up @@ -218,6 +219,12 @@ cusparse_view_t<i_t, f_t>::cusparse_view_t(
&tmp_primal, op_problem_scaled.n_variables, _tmp_primal.data()));
RAFT_CUSPARSE_TRY(raft::sparse::detail::cusparsecreatednvec(
&tmp_dual, op_problem_scaled.n_constraints, _tmp_dual.data()));
if (pdlp_hyper_params::use_reflected_primal_dual) {
cuopt_assert(_reflected_primal_solution.size() > 0, "Reflected primal solution empty");
RAFT_CUSPARSE_TRY(raft::sparse::detail::cusparsecreatednvec(&reflected_primal_solution,
op_problem_scaled.n_variables,
_reflected_primal_solution.data()));
}

const rmm::device_scalar<f_t> alpha{1, handle_ptr->get_stream()};
const rmm::device_scalar<f_t> beta{1, handle_ptr->get_stream()};
Expand Down Expand Up @@ -284,6 +291,8 @@ cusparse_view_t<i_t, f_t>::cusparse_view_t(raft::handle_t const* handle_ptr,
rmm::device_uvector<f_t>& _dual_solution,
rmm::device_uvector<f_t>& _tmp_primal,
rmm::device_uvector<f_t>& _tmp_dual,
rmm::device_uvector<f_t>& _potential_next_primal,
rmm::device_uvector<f_t>& _potential_next_dual,
const rmm::device_uvector<f_t>& _A_T,
const rmm::device_uvector<i_t>& _A_T_offsets,
const rmm::device_uvector<i_t>& _A_T_indices)
Expand Down Expand Up @@ -335,10 +344,17 @@ cusparse_view_t<i_t, f_t>::cusparse_view_t(raft::handle_t const* handle_ptr,
RAFT_CUSPARSE_TRY(raft::sparse::detail::cusparsecreatednvec(
&c, op_problem.n_variables, const_cast<f_t*>(op_problem.objective_coefficients.data())));

RAFT_CUSPARSE_TRY(raft::sparse::detail::cusparsecreatednvec(
&primal_solution, op_problem.n_variables, _primal_solution.data()));
RAFT_CUSPARSE_TRY(raft::sparse::detail::cusparsecreatednvec(
&dual_solution, op_problem.n_constraints, _dual_solution.data()));
if (!pdlp_hyper_params::use_adaptive_step_size_strategy) {
RAFT_CUSPARSE_TRY(raft::sparse::detail::cusparsecreatednvec(
&primal_solution, op_problem.n_variables, _potential_next_primal.data()));
RAFT_CUSPARSE_TRY(raft::sparse::detail::cusparsecreatednvec(
&dual_solution, op_problem.n_constraints, _potential_next_dual.data()));
} else {
RAFT_CUSPARSE_TRY(raft::sparse::detail::cusparsecreatednvec(
&primal_solution, op_problem.n_variables, _primal_solution.data()));
RAFT_CUSPARSE_TRY(raft::sparse::detail::cusparsecreatednvec(
&dual_solution, op_problem.n_constraints, _dual_solution.data()));
}

RAFT_CUSPARSE_TRY(raft::sparse::detail::cusparsecreatednvec(
&tmp_primal, op_problem.n_variables, _tmp_primal.data()));
Expand Down
8 changes: 7 additions & 1 deletion cpp/src/linear_programming/cusparse_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,17 @@ class cusparse_view_t {
saddle_point_state_t<i_t, f_t>& current_saddle_point_state,
rmm::device_uvector<f_t>& _tmp_primal,
rmm::device_uvector<f_t>& _tmp_dual,
rmm::device_uvector<f_t>& _potential_next_dual_solution);
rmm::device_uvector<f_t>& _potential_next_dual_solution,
rmm::device_uvector<f_t>& _reflected_primal_solution);

cusparse_view_t(raft::handle_t const* handle_ptr,
const problem_t<i_t, f_t>& op_problem,
rmm::device_uvector<f_t>& _primal_solution,
rmm::device_uvector<f_t>& _dual_solution,
rmm::device_uvector<f_t>& _tmp_primal,
rmm::device_uvector<f_t>& _tmp_dual,
rmm::device_uvector<f_t>& _potential_next_primal,
rmm::device_uvector<f_t>& _potential_next_dual,
const rmm::device_uvector<f_t>& _A_T,
const rmm::device_uvector<i_t>& _A_T_offsets,
const rmm::device_uvector<i_t>& _A_T_indices);
Expand Down Expand Up @@ -89,6 +92,9 @@ class cusparse_view_t {
rmm::device_uvector<uint8_t> buffer_non_transpose;
rmm::device_uvector<uint8_t> buffer_transpose;

// Only when using reflection
cusparseDnVecDescr_t reflected_primal_solution;

// Ref to the A_T found in either
// Initial problem, we use it to have an unscaled A_T
// PDLP copy of the problem which holds the scaled version
Expand Down
Loading
Loading