Skip to content

Commit 7eefdf2

Browse files
committed
Make iterative refinement methods flexible
Signed-off-by: yuwenchen95 <yuwchen@nvidia.com>
1 parent 0bc415c commit 7eefdf2

15 files changed

Lines changed: 99 additions & 47 deletions

File tree

cpp/include/cuopt/mathematical_optimization/constants.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#define CUOPT_BARRIER_DUAL_INITIAL_POINT "barrier_dual_initial_point"
5050
#define CUOPT_POSTSOLVE_INFO "postsolve_info"
5151
#define CUOPT_BARRIER_ITERATIVE_REFINEMENT "barrier_iterative_refinement"
52+
#define CUOPT_BARRIER_ITERATIVE_REFINEMENT_METHOD "barrier_iterative_refinement_method"
5253
#define CUOPT_BARRIER_STEP_SCALE "barrier_step_scale"
5354
#define CUOPT_ELIMINATE_DENSE_COLUMNS "eliminate_dense_columns"
5455
#define CUOPT_CUDSS_DETERMINISTIC "cudss_deterministic"

cpp/include/cuopt/mathematical_optimization/pdlp/solver_settings.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ class pdlp_solver_settings_t {
307307
bool eliminate_dense_columns{true};
308308
pdlp_precision_t pdlp_precision{pdlp_precision_t::DefaultPrecision};
309309
bool barrier_iterative_refinement{true};
310+
i_t barrier_iterative_refinement_method{1}; // 0: fixed_point, 1: gmres (default)
310311
i_t barrier_soc_threshold{100};
311312
f_t barrier_step_scale{0.9};
312313
bool save_best_primal_so_far{false};

cpp/src/barrier/barrier.cu

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2279,7 +2279,8 @@ int barrier_solver_t<i_t, f_t>::initial_point(iteration_data_t<i_t, f_t>& data)
22792279

22802280
if (settings.barrier_iterative_refinement) {
22812281
const f_t ir_tol = data.has_sparse_cones() ? f_t(1e-12) : f_t(1e-8);
2282-
iterative_refinement<i_t, f_t, op_t>(op, rhs, soln, ir_tol);
2282+
iterative_refinement<i_t, f_t, op_t>(
2283+
op, rhs, soln, ir_tol, settings.barrier_iterative_refinement_method);
22832284
}
22842285

22852286
for (i_t k = 0; k < lp.num_cols; k++) {
@@ -2904,9 +2905,13 @@ i_t barrier_solver_t<i_t, f_t>::gpu_compute_search_direction(iteration_data_t<i_
29042905
} op(data);
29052906
if (settings.barrier_iterative_refinement) {
29062907
raft::common::nvtx::range fun_scope("Barrier: iterative_refinement");
2907-
const f_t ir_tol = data.has_sparse_cones() ? f_t(1e-12) : f_t(1e-8);
2908-
const f_t solve_err = iterative_refinement<i_t, f_t, op_t>(
2909-
op, data.d_augmented_rhs_, data.d_augmented_soln_, ir_tol);
2908+
const f_t ir_tol = data.has_sparse_cones() ? f_t(1e-12) : f_t(1e-8);
2909+
const f_t solve_err =
2910+
iterative_refinement<i_t, f_t, op_t>(op,
2911+
data.d_augmented_rhs_,
2912+
data.d_augmented_soln_,
2913+
ir_tol,
2914+
settings.barrier_iterative_refinement_method);
29102915
if (solve_err > 1e-1) {
29112916
settings.log.printf("|| Aug (dx, dy) - aug_rhs || %e after IR\n", solve_err);
29122917
}
@@ -2992,8 +2997,8 @@ i_t barrier_solver_t<i_t, f_t>::gpu_compute_search_direction(iteration_data_t<i_
29922997
data_.gpu_solve_adat(b, x);
29932998
}
29942999
} adat_op(data);
2995-
const f_t adat_solve_err =
2996-
iterative_refinement<i_t, f_t, adat_op_t>(adat_op, data.d_h_, data.d_dy_);
3000+
const f_t adat_solve_err = iterative_refinement<i_t, f_t, adat_op_t>(
3001+
adat_op, data.d_h_, data.d_dy_, f_t(1e-8), settings.barrier_iterative_refinement_method);
29973002
if (adat_solve_err > 1e-1) {
29983003
settings.log.printf("||ADAT*dy - h|| %e after IR\n", adat_solve_err);
29993004
}

cpp/src/barrier/iterative_refinement.hpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ struct subtract_scaled_op {
5555
};
5656

5757
template <typename i_t, typename f_t, typename T>
58-
f_t iterative_refinement_simple(T& op,
59-
const rmm::device_uvector<f_t>& b,
60-
rmm::device_uvector<f_t>& x,
61-
f_t tol = 1e-8)
58+
f_t iterative_refinement_fixed_point(T& op,
59+
const rmm::device_uvector<f_t>& b,
60+
rmm::device_uvector<f_t>& x,
61+
f_t tol = 1e-8)
6262
{
6363
rmm::device_uvector<f_t> x_sav(x, x.stream());
6464

@@ -365,13 +365,15 @@ template <typename i_t, typename f_t, typename T>
365365
f_t iterative_refinement(T& op,
366366
const dense_vector_t<i_t, f_t>& b,
367367
dense_vector_t<i_t, f_t>& x,
368-
f_t tol = 1e-8)
368+
f_t tol = 1e-8,
369+
i_t method = 1)
369370
{
370371
rmm::device_uvector<f_t> d_b(b.size(), op.data_.handle_ptr->get_stream());
371372
raft::copy(d_b.data(), b.data(), b.size(), op.data_.handle_ptr->get_stream());
372373
rmm::device_uvector<f_t> d_x(x.size(), op.data_.handle_ptr->get_stream());
373374
raft::copy(d_x.data(), x.data(), x.size(), op.data_.handle_ptr->get_stream());
374-
auto err = iterative_refinement_gmres<i_t, f_t, T>(op, d_b, d_x, tol);
375+
auto err = (method == 0) ? iterative_refinement_fixed_point<i_t, f_t, T>(op, d_b, d_x, tol)
376+
: iterative_refinement_gmres<i_t, f_t, T>(op, d_b, d_x, tol);
375377

376378
raft::copy(x.data(), d_x.data(), x.size(), op.data_.handle_ptr->get_stream());
377379

@@ -383,9 +385,11 @@ template <typename i_t, typename f_t, typename T>
383385
f_t iterative_refinement(T& op,
384386
const rmm::device_uvector<f_t>& b,
385387
rmm::device_uvector<f_t>& x,
386-
f_t tol = 1e-8)
388+
f_t tol = 1e-8,
389+
i_t method = 1)
387390
{
388-
return iterative_refinement_gmres<i_t, f_t, T>(op, b, x, tol);
391+
return (method == 0) ? iterative_refinement_fixed_point<i_t, f_t, T>(op, b, x, tol)
392+
: iterative_refinement_gmres<i_t, f_t, T>(op, b, x, tol);
389393
}
390394

391395
} // namespace cuopt::mathematical_optimization::barrier

cpp/src/dual_simplex/simplex_solver_settings.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct simplex_solver_settings_t {
7474
barrier(false),
7575
eliminate_dense_columns(true),
7676
barrier_iterative_refinement(true),
77+
barrier_iterative_refinement_method(1),
7778
barrier_step_scale(0.9),
7879
barrier_soc_threshold(100),
7980
num_gpus(1),
@@ -172,10 +173,11 @@ struct simplex_solver_settings_t {
172173
// (only takes effect when a cuDSS threading layer is loaded)
173174
bool barrier; // true to use barrier method, false to use dual simplex method
174175
bool deterministic; // true to use B&B deterministic mode, false to use non-deterministic mode
175-
bool eliminate_dense_columns; // true to eliminate dense columns from A*D*A^T
176-
bool barrier_iterative_refinement; // true to use iterative refinement for barrier method
177-
f_t barrier_step_scale; // step scale for barrier method
178-
i_t barrier_soc_threshold; // SOC dimension above which rank-2 sparse scaling is used
176+
bool eliminate_dense_columns; // true to eliminate dense columns from A*D*A^T
177+
bool barrier_iterative_refinement; // true to use iterative refinement for barrier method
178+
i_t barrier_iterative_refinement_method; // 0: fixed_point, 1: gmres
179+
f_t barrier_step_scale; // step scale for barrier method
180+
i_t barrier_soc_threshold; // SOC dimension above which rank-2 sparse scaling is used
179181
int num_gpus; // Number of GPUs to use (maximum of 2 gpus are supported at the moment)
180182
i_t folding; // -1 automatic, 0 don't fold, 1 fold
181183
i_t augmented; // -1 automatic, 0 to solve with ADAT, 1 to solve with augmented system

cpp/src/grpc/codegen/field_registry.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,10 @@ pdlp_settings:
573573
field_num: 37
574574
type: int32
575575
optional: true
576+
- barrier_iterative_refinement_method:
577+
field_num: 38
578+
type: int32
579+
optional: true
576580
- save_best_primal_so_far:
577581
field_num: 28
578582
type: bool

cpp/src/grpc/codegen/generated/cuopt_remote_data.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ message PDLPSolverSettings {
198198
bool cudss_hybrid_mode = 35;
199199
bool cudss_hybrid_execute_mode = 36;
200200
optional int32 cudss_host_nthreads = 37;
201+
optional int32 barrier_iterative_refinement_method = 38;
201202
PDLPWarmStartData warm_start_data = 50;
202203
}
203204

cpp/src/grpc/codegen/generated/generated_pdlp_settings_to_proto.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
pb_settings->set_cudss_hybrid_mode(settings.cudss_hybrid_mode);
4141
pb_settings->set_cudss_hybrid_execute_mode(settings.cudss_hybrid_execute_mode);
4242
pb_settings->set_cudss_host_nthreads(settings.cudss_host_nthreads);
43+
pb_settings->set_barrier_iterative_refinement_method(settings.barrier_iterative_refinement_method);
4344
pb_settings->set_save_best_primal_so_far(settings.save_best_primal_so_far);
4445
pb_settings->set_first_primal_feasible(settings.first_primal_feasible);
4546
pb_settings->set_pdlp_precision(static_cast<int32_t>(settings.pdlp_precision));

cpp/src/grpc/codegen/generated/generated_proto_to_pdlp_settings.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@
9090
if (pb_settings.has_cudss_host_nthreads()) {
9191
settings.cudss_host_nthreads = pb_settings.cudss_host_nthreads();
9292
}
93+
if (pb_settings.has_barrier_iterative_refinement_method()) {
94+
settings.barrier_iterative_refinement_method = pb_settings.barrier_iterative_refinement_method();
95+
}
9396
settings.save_best_primal_so_far = pb_settings.save_best_primal_so_far();
9497
settings.first_primal_feasible = pb_settings.first_primal_feasible();
9598
if (pb_settings.has_pdlp_precision()) {

cpp/src/math_optimization/solver_settings.cu

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ solver_settings_t<i_t, f_t>::solver_settings_t() : pdlp_settings(), mip_settings
138138
{CUOPT_ORDERING, &pdlp_settings.ordering, -1, 1, -1},
139139
{CUOPT_CUDSS_ND_NLEVELS, &pdlp_settings.cudss_nd_nlevels, -1, std::numeric_limits<i_t>::max(), -1},
140140
{CUOPT_CUDSS_HOST_NTHREADS, &pdlp_settings.cudss_host_nthreads, -1, std::numeric_limits<i_t>::max(), -1},
141+
{CUOPT_BARRIER_ITERATIVE_REFINEMENT_METHOD, &pdlp_settings.barrier_iterative_refinement_method, 0, 1, 1},
141142
{CUOPT_BARRIER_DUAL_INITIAL_POINT, &pdlp_settings.barrier_dual_initial_point, -1, 1, -1},
142143
{CUOPT_POSTSOLVE_INFO, &pdlp_settings.postsolve_info, -1, 1, -1},
143144
{CUOPT_MIP_CUT_PASSES, &mip_settings.max_cut_passes, -1, std::numeric_limits<i_t>::max(), 10},

0 commit comments

Comments
 (0)