Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
1 change: 1 addition & 0 deletions cpp/include/cuopt/mathematical_optimization/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#define CUOPT_POSTSOLVE_INFO "postsolve_info"
#define CUOPT_BARRIER_PRESOLVE_BOUND_FREE_VARIABLES "barrier_presolve_bound_free_variables"
#define CUOPT_BARRIER_ITERATIVE_REFINEMENT "barrier_iterative_refinement"
#define CUOPT_BARRIER_ADAPTIVE_REGULARIZATION "barrier_adaptive_regularization"
#define CUOPT_BARRIER_STEP_SCALE "barrier_step_scale"
#define CUOPT_ELIMINATE_DENSE_COLUMNS "eliminate_dense_columns"
#define CUOPT_CUDSS_DETERMINISTIC "cudss_deterministic"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,7 @@ class pdlp_solver_settings_t {
bool eliminate_dense_columns{true};
pdlp_precision_t pdlp_precision{pdlp_precision_t::DefaultPrecision};
bool barrier_iterative_refinement{true};
i_t barrier_adaptive_regularization{-1}; // -1 automatic, 0 disabled, 1 enabled
i_t barrier_soc_threshold{100};
f_t barrier_step_scale{0.9};
bool save_best_primal_so_far{false};
Expand Down
20 changes: 18 additions & 2 deletions cpp/src/barrier/barrier.cu
Original file line number Diff line number Diff line change
Expand Up @@ -2081,6 +2081,15 @@ class iteration_data_t {
const simplex_solver_settings_t<i_t, f_t>& settings_;
};

// -1 automatic: enable for cones, disable otherwise; 0 off; 1 on
template <typename i_t, typename f_t>
bool should_use_adaptive_regularization(const simplex_solver_settings_t<i_t, f_t>& settings,
const iteration_data_t<i_t, f_t>& data)
{
return settings.barrier_adaptive_regularization > 0 ||
(settings.barrier_adaptive_regularization < 0 && data.has_cones());
}

// Move the Cholesky debug logic to a reusable function.

template <typename i_t, typename f_t>
Expand Down Expand Up @@ -2914,7 +2923,7 @@ i_t barrier_solver_t<i_t, f_t>::gpu_compute_search_direction(iteration_data_t<i_

// Adaptive regularization: increase/decrease based on IR quality.
// Only adapt on calls where we actually (re)factorized — the affine step.
if (did_factorize && data.has_cones()) {
if (did_factorize && should_use_adaptive_regularization(settings, data)) {
constexpr f_t min_perturb = 1e-8;
constexpr f_t max_perturb = 1e-1;
if (solve_err > 1e-2) {
Expand Down Expand Up @@ -4176,6 +4185,13 @@ lp_status_t barrier_solver_t<i_t, f_t>::solve(f_t start_time, lp_solution_t<i_t,
settings.log.printf("Unable to compute initial point\n");
return lp_status_t::NUMERICAL_ISSUES;
}

// Handle automatic adaptive regularization (-1: auto, 0: off, 1: on).
const bool adaptive_regularization = should_use_adaptive_regularization(settings, data);
if (settings.barrier_adaptive_regularization == -1 && adaptive_regularization) {
settings.log.printf("Adaptive regularization enabled\n");
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

// Upload initial point to device and compute initial residuals/norms on GPU
data.d_complementarity_wv_residual_.resize(data.n_upper_bounds, stream_view_);
data.d_complementarity_wv_rhs_.resize(data.n_upper_bounds, stream_view_);
Expand Down Expand Up @@ -4271,7 +4287,7 @@ lp_status_t barrier_solver_t<i_t, f_t>::solve(f_t start_time, lp_solution_t<i_t,
const i_t iteration_limit = settings.iteration_limit;

// Adaptive regularization for the augmented system.
f_t dual_perturb = data.has_cones() ? 1e-8 : 0;
f_t dual_perturb = adaptive_regularization ? 1e-8 : 0;
f_t primal_perturb = data.has_cones() ? 1e-8 : 1e-6;

while (iter < iteration_limit) {
Expand Down
9 changes: 5 additions & 4 deletions cpp/src/dual_simplex/simplex_solver_settings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,11 @@ struct simplex_solver_settings_t {
bool cudss_deterministic; // true to use cuDSS deterministic mode, false for non-deterministic
bool barrier; // true to use barrier method, false to use dual simplex method
bool deterministic; // true to use B&B deterministic mode, false to use non-deterministic mode
bool eliminate_dense_columns; // true to eliminate dense columns from A*D*A^T
bool barrier_iterative_refinement; // true to use iterative refinement for barrier method
f_t barrier_step_scale; // step scale for barrier method
i_t barrier_soc_threshold; // SOC dimension above which rank-2 sparse scaling is used
bool eliminate_dense_columns; // true to eliminate dense columns from A*D*A^T
bool barrier_iterative_refinement; // true to use iterative refinement for barrier method
int barrier_adaptive_regularization; // -1 automatic, 0 disabled, 1 enabled
Comment thread
coderabbitai[bot] marked this conversation as resolved.
f_t barrier_step_scale; // step scale for barrier method
i_t barrier_soc_threshold; // SOC dimension above which rank-2 sparse scaling is used
int num_gpus; // Number of GPUs to use (maximum of 2 gpus are supported at the moment)
i_t folding; // -1 automatic, 0 don't fold, 1 fold
i_t augmented; // -1 automatic, 0 to solve with ADAT, 1 to solve with augmented system
Expand Down
1 change: 1 addition & 0 deletions cpp/src/math_optimization/solver_settings.cu
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ solver_settings_t<i_t, f_t>::solver_settings_t() : pdlp_settings(), mip_settings
{CUOPT_MIP_HYPER_SUBMIP_NODE_LIMIT_BASE, &mip_settings.submip_params.node_limit_base, 0, std::numeric_limits<i_t>::max(), 200, "base node limit for the sub-MIP"},
{CUOPT_MIP_HYPER_SUBMIP_MAX_LEVEL, &mip_settings.submip_params.max_level, 0, std::numeric_limits<i_t>::max(), 10, "maximum sub-MIP recursion level"},
{CUOPT_BARRIER_PRESOLVE_BOUND_FREE_VARIABLES, &pdlp_settings.barrier_presolve_bound_free_variables, -1, 1, -1, "Bound free variables during barrier presolve: -1 automatic (current default behavior), 0 disabled, 1 enabled"},
{CUOPT_BARRIER_ADAPTIVE_REGULARIZATION, &pdlp_settings.barrier_adaptive_regularization, -1, 1, -1, "Adaptive regularization for barrier method: false disabled, true enabled"},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
// QCQP (barrier) scaling hyper-parameter
{CUOPT_QCQP_HYPER_RUIZ_EQUILIBRATION, &pdlp_settings.qcqp_ruiz_equilibration, -1, 1, -1, "Ruiz equilibration for QCQP barrier scaling: -1 automatic (row/column imbalance heuristic), 0 disabled, 1 enabled"},
};
Expand Down
44 changes: 23 additions & 21 deletions cpp/src/pdlp/solve.cu
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ std::tuple<simplex::lp_solution_t<i_t, f_t>, simplex::lp_status_t, f_t, f_t, f_t
barrier_settings.crossover = settings.crossover;
barrier_settings.eliminate_dense_columns = settings.eliminate_dense_columns;
barrier_settings.barrier_iterative_refinement = settings.barrier_iterative_refinement;
barrier_settings.barrier_adaptive_regularization = settings.barrier_adaptive_regularization;
barrier_settings.barrier_soc_threshold = settings.barrier_soc_threshold;
barrier_settings.barrier_step_scale = settings.barrier_step_scale;
barrier_settings.qcqp_ruiz_equilibration = settings.qcqp_ruiz_equilibration;
Expand Down Expand Up @@ -690,27 +691,28 @@ static optimization_problem_solution_t<i_t, double> run_pdlp_solver_in_fp32(
static_cast<float>(settings.tolerances.primal_infeasible_tolerance);
fs.tolerances.dual_infeasible_tolerance =
static_cast<float>(settings.tolerances.dual_infeasible_tolerance);
fs.detect_infeasibility = settings.detect_infeasibility;
fs.strict_infeasibility = settings.strict_infeasibility;
fs.iteration_limit = settings.iteration_limit;
fs.time_limit = static_cast<float>(settings.time_limit);
fs.pdlp_solver_mode = settings.pdlp_solver_mode;
fs.log_to_console = settings.log_to_console;
fs.log_file = settings.log_file;
fs.per_constraint_residual = settings.per_constraint_residual;
fs.save_best_primal_so_far = settings.save_best_primal_so_far;
fs.first_primal_feasible = settings.first_primal_feasible;
fs.all_primal_feasible = settings.all_primal_feasible;
fs.eliminate_dense_columns = settings.eliminate_dense_columns;
fs.barrier_iterative_refinement = settings.barrier_iterative_refinement;
fs.barrier_step_scale = settings.barrier_step_scale;
fs.pdlp_precision = pdlp_precision_t::DefaultPrecision;
fs.method = method_t::PDLP;
fs.inside_mip = settings.inside_mip;
fs.hyper_params = settings.hyper_params;
fs.presolver = settings.presolver;
fs.num_gpus = settings.num_gpus;
fs.concurrent_halt = settings.concurrent_halt;
fs.detect_infeasibility = settings.detect_infeasibility;
fs.strict_infeasibility = settings.strict_infeasibility;
fs.iteration_limit = settings.iteration_limit;
fs.time_limit = static_cast<float>(settings.time_limit);
fs.pdlp_solver_mode = settings.pdlp_solver_mode;
fs.log_to_console = settings.log_to_console;
fs.log_file = settings.log_file;
fs.per_constraint_residual = settings.per_constraint_residual;
fs.save_best_primal_so_far = settings.save_best_primal_so_far;
fs.first_primal_feasible = settings.first_primal_feasible;
fs.all_primal_feasible = settings.all_primal_feasible;
fs.eliminate_dense_columns = settings.eliminate_dense_columns;
fs.barrier_iterative_refinement = settings.barrier_iterative_refinement;
fs.barrier_adaptive_regularization = settings.barrier_adaptive_regularization;
fs.barrier_step_scale = settings.barrier_step_scale;
fs.pdlp_precision = pdlp_precision_t::DefaultPrecision;
fs.method = method_t::PDLP;
fs.inside_mip = settings.inside_mip;
fs.hyper_params = settings.hyper_params;
fs.presolver = settings.presolver;
fs.num_gpus = settings.num_gpus;
fs.concurrent_halt = settings.concurrent_halt;

pdlp::pdlp_solver_t<i_t, float> solver(float_problem, fs, is_batch_mode);
if (settings.inside_mip) { solver.set_inside_mip(true); }
Expand Down
12 changes: 12 additions & 0 deletions docs/cuopt/source/convex-settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -387,3 +387,15 @@ Barrier Step Scale
The step scale must be strictly less than 1. A value like 0.9 is conservative, while a value like 0.999 is aggressive.

.. note:: By default cuOpt selects the step scale automatically.


Barrier Adaptive Regularization
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``CUOPT_BARRIER_ADAPTIVE_REGULARIZATION`` controls whether adaptive regularization is enabled in the barrier method.

* ``-1``: Automatic (default) - cuOpt decides whether to enable adaptive regularization based on problem characteristics
* ``0``: Disable adaptive regularization
* ``1``: Enable adaptive regularization
Comment thread
coderabbitai[bot] marked this conversation as resolved.

.. note:: The default value is ``-1`` (automatic).
Loading