Skip to content

Commit 56072b8

Browse files
committed
Merge branch 'main' of github.com:NVIDIA/cuopt into fea/sccache-dist
2 parents c708cb5 + 51addf5 commit 56072b8

46 files changed

Lines changed: 753 additions & 348 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/release.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
changelog:
2+
exclude:
3+
labels:
4+
- ignore-for-release
5+
- dependencies
6+
authors:
7+
- rapids-bot[bot]
8+
- dependabot[bot]
9+
categories:
10+
- title: "\U0001F6A8 Breaking Changes"
11+
labels:
12+
- breaking
13+
- title: "\U0001F41B Bug Fixes"
14+
labels:
15+
- bug
16+
- title: "\U0001F4D6 Documentation"
17+
labels:
18+
- doc
19+
- title: "\U0001F680 New Features"
20+
labels:
21+
- feature request
22+
- title: "\U0001F6E0\uFE0F Improvements"
23+
labels:
24+
- improvement

.github/workflows/nightly.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
matrix:
1818
cuopt_branch:
1919
- "main"
20-
- "release/26.02"
20+
- "release/26.04"
2121
steps:
2222
- uses: actions/checkout@v4
2323
- name: Trigger Pipeline

benchmarks/linear_programming/cuopt/run_pdlp.cu

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,23 @@ static void parse_arguments(argparse::ArgumentParser& program)
7070
"Path to PDLP hyper-params file to configure PDLP solver. Has priority over PDLP solver "
7171
"modes.");
7272

73-
program.add_argument("--presolve")
74-
.help("enable/disable presolve (default: true for MIP problems, false for LP problems)")
75-
.default_value(0)
76-
.scan<'i', int>()
77-
.choices(0, 1);
73+
program.add_argument("--presolver")
74+
.help("Presolver to use. Possible values: None, Papilo, PSLP, Default")
75+
.default_value("Default")
76+
.choices("None", "Papilo", "PSLP", "Default");
7877

7978
program.add_argument("--solution-path").help("Path where solution file will be generated");
8079
}
8180

81+
static cuopt::linear_programming::presolver_t string_to_presolver(const std::string& presolver)
82+
{
83+
if (presolver == "None") return cuopt::linear_programming::presolver_t::None;
84+
if (presolver == "Papilo") return cuopt::linear_programming::presolver_t::Papilo;
85+
if (presolver == "PSLP") return cuopt::linear_programming::presolver_t::PSLP;
86+
if (presolver == "Default") return cuopt::linear_programming::presolver_t::Default;
87+
return cuopt::linear_programming::presolver_t::Default;
88+
}
89+
8290
static cuopt::linear_programming::pdlp_solver_mode_t string_to_pdlp_solver_mode(
8391
const std::string& mode)
8492
{
@@ -107,7 +115,7 @@ static cuopt::linear_programming::pdlp_solver_settings_t<int, double> create_sol
107115
string_to_pdlp_solver_mode(program.get<std::string>("--pdlp-solver-mode"));
108116
settings.method = static_cast<cuopt::linear_programming::method_t>(program.get<int>("--method"));
109117
settings.crossover = program.get<int>("--crossover");
110-
settings.presolve = program.get<int>("--presolve");
118+
settings.presolver = string_to_presolver(program.get<std::string>("--presolver"));
111119

112120
return settings;
113121
}

cpp/src/branch_and_bound/branch_and_bound.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1886,6 +1886,7 @@ lp_status_t branch_and_bound_t<i_t, f_t>::solve_root_relaxation(
18861886
root_crossover_settings,
18871887
original_lp_.lower,
18881888
original_lp_.upper,
1889+
exploration_stats_.start_time,
18891890
basic_list,
18901891
nonbasic_list,
18911892
crossover_vstatus_);
@@ -2285,6 +2286,7 @@ mip_status_t branch_and_bound_t<i_t, f_t>::solve(mip_solution_t<i_t, f_t>& solut
22852286
mutex_original_lp_.lock();
22862287
remove_cuts(original_lp_,
22872288
settings_,
2289+
exploration_stats_.start_time,
22882290
Arow_,
22892291
new_slacks_,
22902292
original_rows,

cpp/src/branch_and_bound/branch_and_bound.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ class branch_and_bound_t {
106106

107107
void set_concurrent_lp_root_solve(bool enable) { enable_concurrent_lp_root_solve_ = enable; }
108108

109+
bool stop_for_time_limit(mip_solution_t<i_t, f_t>& solution);
110+
109111
// Repair a low-quality solution from the heuristics.
110112
bool repair_solution(const std::vector<f_t>& leaf_edge_norms,
111113
const std::vector<f_t>& potential_solution,

cpp/src/branch_and_bound/pseudo_costs.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,9 @@ void strong_branching(const user_problem_t<i_t, f_t>& original_problem,
314314
pc.strong_branch_up.assign(fractional.size(), 0);
315315
pc.num_strong_branches_completed = 0;
316316

317+
const f_t elapsed_time = toc(start_time);
318+
if (elapsed_time > settings.time_limit) { return; }
319+
317320
if (settings.mip_batch_pdlp_strong_branching) {
318321
settings.log.printf("Batch PDLP strong branching enabled\n");
319322

@@ -334,9 +337,16 @@ void strong_branching(const user_problem_t<i_t, f_t>& original_problem,
334337
fraction_values.push_back(original_root_soln_x[j]);
335338
}
336339

337-
const auto mps_model = simplex_problem_to_mps_data_model(original_problem);
340+
const auto mps_model = simplex_problem_to_mps_data_model(original_problem);
341+
const f_t batch_elapsed_time = toc(start_time);
342+
const f_t batch_remaining_time =
343+
std::max(static_cast<f_t>(0.0), settings.time_limit - batch_elapsed_time);
344+
if (batch_remaining_time <= 0.0) { return; }
345+
pdlp_solver_settings_t<i_t, f_t> pdlp_settings;
346+
pdlp_settings.time_limit = batch_remaining_time;
347+
const raft::handle_t batch_pdlp_handle;
338348
const auto solutions =
339-
batch_pdlp_solve(original_problem.handle_ptr, mps_model, fractional, fraction_values);
349+
batch_pdlp_solve(&batch_pdlp_handle, mps_model, fractional, fraction_values, pdlp_settings);
340350
f_t batch_pdlp_strong_branching_time = toc(start_batch);
341351

342352
// Find max iteration on how many are done accross the batch

cpp/src/cuts/cuts.cpp

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2501,20 +2501,21 @@ i_t add_cuts(const simplex_solver_settings_t<i_t, f_t>& settings,
25012501
}
25022502

25032503
template <typename i_t, typename f_t>
2504-
void remove_cuts(lp_problem_t<i_t, f_t>& lp,
2505-
const simplex_solver_settings_t<i_t, f_t>& settings,
2506-
csr_matrix_t<i_t, f_t>& Arow,
2507-
std::vector<i_t>& new_slacks,
2508-
i_t original_rows,
2509-
std::vector<variable_type_t>& var_types,
2510-
std::vector<variable_status_t>& vstatus,
2511-
std::vector<f_t>& edge_norms,
2512-
std::vector<f_t>& x,
2513-
std::vector<f_t>& y,
2514-
std::vector<f_t>& z,
2515-
std::vector<i_t>& basic_list,
2516-
std::vector<i_t>& nonbasic_list,
2517-
basis_update_mpf_t<i_t, f_t>& basis_update)
2504+
i_t remove_cuts(lp_problem_t<i_t, f_t>& lp,
2505+
const simplex_solver_settings_t<i_t, f_t>& settings,
2506+
f_t start_time,
2507+
csr_matrix_t<i_t, f_t>& Arow,
2508+
std::vector<i_t>& new_slacks,
2509+
i_t original_rows,
2510+
std::vector<variable_type_t>& var_types,
2511+
std::vector<variable_status_t>& vstatus,
2512+
std::vector<f_t>& edge_norms,
2513+
std::vector<f_t>& x,
2514+
std::vector<f_t>& y,
2515+
std::vector<f_t>& z,
2516+
std::vector<i_t>& basic_list,
2517+
std::vector<i_t>& nonbasic_list,
2518+
basis_update_mpf_t<i_t, f_t>& basis_update)
25182519
{
25192520
std::vector<i_t> cuts_to_remove;
25202521
cuts_to_remove.reserve(lp.num_rows - original_rows);
@@ -2644,9 +2645,13 @@ void remove_cuts(lp_problem_t<i_t, f_t>& lp,
26442645
lp.A.col_start[lp.A.n]);
26452646

26462647
basis_update.resize(lp.num_rows);
2647-
basis_update.refactor_basis(
2648-
lp.A, settings, lp.lower, lp.upper, basic_list, nonbasic_list, vstatus);
2648+
i_t refactor_status = basis_update.refactor_basis(
2649+
lp.A, settings, lp.lower, lp.upper, start_time, basic_list, nonbasic_list, vstatus);
2650+
if (refactor_status == CONCURRENT_HALT_RETURN) { return CONCURRENT_HALT_RETURN; }
2651+
if (refactor_status == TIME_LIMIT_RETURN) { return TIME_LIMIT_RETURN; }
26492652
}
2653+
2654+
return 0;
26502655
}
26512656

26522657
template <typename i_t, typename f_t>
@@ -2793,20 +2798,21 @@ template int add_cuts(const simplex_solver_settings_t<int, double>& settings,
27932798
std::vector<variable_status_t>& vstatus,
27942799
std::vector<double>& edge_norms);
27952800

2796-
template void remove_cuts<int, double>(lp_problem_t<int, double>& lp,
2797-
const simplex_solver_settings_t<int, double>& settings,
2798-
csr_matrix_t<int, double>& Arow,
2799-
std::vector<int>& new_slacks,
2800-
int original_rows,
2801-
std::vector<variable_type_t>& var_types,
2802-
std::vector<variable_status_t>& vstatus,
2803-
std::vector<double>& edge_norms,
2804-
std::vector<double>& x,
2805-
std::vector<double>& y,
2806-
std::vector<double>& z,
2807-
std::vector<int>& basic_list,
2808-
std::vector<int>& nonbasic_list,
2809-
basis_update_mpf_t<int, double>& basis_update);
2801+
template int remove_cuts<int, double>(lp_problem_t<int, double>& lp,
2802+
const simplex_solver_settings_t<int, double>& settings,
2803+
double start_time,
2804+
csr_matrix_t<int, double>& Arow,
2805+
std::vector<int>& new_slacks,
2806+
int original_rows,
2807+
std::vector<variable_type_t>& var_types,
2808+
std::vector<variable_status_t>& vstatus,
2809+
std::vector<double>& edge_norms,
2810+
std::vector<double>& x,
2811+
std::vector<double>& y,
2812+
std::vector<double>& z,
2813+
std::vector<int>& basic_list,
2814+
std::vector<int>& nonbasic_list,
2815+
basis_update_mpf_t<int, double>& basis_update);
28102816

28112817
template void read_saved_solution_for_cut_verification<int, double>(
28122818
const lp_problem_t<int, double>& lp,

cpp/src/cuts/cuts.hpp

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -461,19 +461,20 @@ i_t add_cuts(const simplex_solver_settings_t<i_t, f_t>& settings,
461461
std::vector<f_t>& edge_norms);
462462

463463
template <typename i_t, typename f_t>
464-
void remove_cuts(lp_problem_t<i_t, f_t>& lp,
465-
const simplex_solver_settings_t<i_t, f_t>& settings,
466-
csr_matrix_t<i_t, f_t>& Arow,
467-
std::vector<i_t>& new_slacks,
468-
i_t original_rows,
469-
std::vector<variable_type_t>& var_types,
470-
std::vector<variable_status_t>& vstatus,
471-
std::vector<f_t>& edge_norms,
472-
std::vector<f_t>& x,
473-
std::vector<f_t>& y,
474-
std::vector<f_t>& z,
475-
std::vector<i_t>& basic_list,
476-
std::vector<i_t>& nonbasic_list,
477-
basis_update_mpf_t<i_t, f_t>& basis_update);
464+
i_t remove_cuts(lp_problem_t<i_t, f_t>& lp,
465+
const simplex_solver_settings_t<i_t, f_t>& settings,
466+
f_t start_time,
467+
csr_matrix_t<i_t, f_t>& Arow,
468+
std::vector<i_t>& new_slacks,
469+
i_t original_rows,
470+
std::vector<variable_type_t>& var_types,
471+
std::vector<variable_status_t>& vstatus,
472+
std::vector<f_t>& edge_norms,
473+
std::vector<f_t>& x,
474+
std::vector<f_t>& y,
475+
std::vector<f_t>& z,
476+
std::vector<i_t>& basic_list,
477+
std::vector<i_t>& nonbasic_list,
478+
basis_update_mpf_t<i_t, f_t>& basis_update);
478479

479480
} // namespace cuopt::linear_programming::dual_simplex

cpp/src/dual_simplex/basis_solves.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ template <typename i_t, typename f_t>
160160
i_t factorize_basis(const csc_matrix_t<i_t, f_t>& A,
161161
const simplex_solver_settings_t<i_t, f_t>& settings,
162162
const std::vector<i_t>& basic_list,
163+
f_t start_time,
163164
csc_matrix_t<i_t, f_t>& L,
164165
csc_matrix_t<i_t, f_t>& U,
165166
std::vector<i_t>& p,
@@ -383,15 +384,16 @@ i_t factorize_basis(const csc_matrix_t<i_t, f_t>& A,
383384
settings,
384385
settings.threshold_partial_pivoting_tol,
385386
identity,
387+
start_time,
386388
S_col_perm,
387389
SL,
388390
SU,
389391
S_perm_inv,
390392
work_estimate);
391393
if (settings.concurrent_halt != nullptr && *settings.concurrent_halt == 1) {
392-
settings.log.printf("Concurrent halt\n");
393394
return CONCURRENT_HALT_RETURN;
394395
}
396+
if (Srank < 0) { return Srank; }
395397
if (Srank != Sdim) {
396398
// Get the rank deficient columns
397399
deficient.clear();
@@ -618,7 +620,14 @@ i_t factorize_basis(const csc_matrix_t<i_t, f_t>& A,
618620
q.resize(m);
619621
work_estimate += m;
620622
f_t fact_start = tic();
621-
rank = right_looking_lu(A, settings, medium_tol, basic_list, q, L, U, pinv, work_estimate);
623+
rank =
624+
right_looking_lu(A, settings, medium_tol, basic_list, start_time, q, L, U, pinv, work_estimate);
625+
if (rank < 0) {
626+
if (settings.concurrent_halt != nullptr && *settings.concurrent_halt == 1) {
627+
return CONCURRENT_HALT_RETURN;
628+
}
629+
return rank;
630+
}
622631
inverse_permutation(pinv, p);
623632
work_estimate += 3 * pinv.size();
624633

@@ -638,7 +647,6 @@ i_t factorize_basis(const csc_matrix_t<i_t, f_t>& A,
638647
work_estimate += 3 * (m - rank);
639648
}
640649
if (settings.concurrent_halt != nullptr && *settings.concurrent_halt == 1) {
641-
settings.log.printf("Concurrent halt\n");
642650
return CONCURRENT_HALT_RETURN;
643651
}
644652
if (verbose) {
@@ -938,6 +946,7 @@ template void get_basis_from_vstatus<int>(int m,
938946
template int factorize_basis<int>(const csc_matrix_t<int, double>& A,
939947
const simplex_solver_settings_t<int, double>& settings,
940948
const std::vector<int>& basis_list,
949+
double start_time,
941950
csc_matrix_t<int, double>& L,
942951
csc_matrix_t<int, double>& U,
943952
std::vector<int>& p,

cpp/src/dual_simplex/basis_solves.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ template <typename i_t, typename f_t>
3030
i_t factorize_basis(const csc_matrix_t<i_t, f_t>& A,
3131
const simplex_solver_settings_t<i_t, f_t>& settings,
3232
const std::vector<i_t>& basis_list,
33+
f_t start_time,
3334
csc_matrix_t<i_t, f_t>& L,
3435
csc_matrix_t<i_t, f_t>& U,
3536
std::vector<i_t>& p,

0 commit comments

Comments
 (0)