Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
594ec3f
add initial files
akifcorduk Oct 31, 2025
f10535f
add some comments and file name changes
akifcorduk Nov 4, 2025
649062c
initial data structures
akifcorduk Nov 10, 2025
fe4cc7a
find all initial cliques
akifcorduk Nov 12, 2025
1d46ec9
remove small cliques
akifcorduk Nov 13, 2025
1474bc5
renumber cliques on addlt
akifcorduk Nov 13, 2025
b82f63f
clique extension is working
akifcorduk Nov 17, 2025
1289cbc
Merge branch 'main' of github.com:NVIDIA/cuopt into cliques
akifcorduk Nov 17, 2025
60edd8e
add extended cliques into formulation
akifcorduk Nov 18, 2025
103b4c2
find constraints to remove
akifcorduk Nov 18, 2025
adc9c73
wip
akifcorduk Nov 19, 2025
5934c12
Merge branch 'main' of github.com:NVIDIA/cuopt into cliques
akifcorduk Jan 16, 2026
43f2ed0
Merge branch 'main' of github.com:NVIDIA/cuopt into cliques
akifcorduk Jan 23, 2026
3001b52
habdle range constraints
akifcorduk Jan 23, 2026
b45c27e
fix bugs and covert to gpu problem
akifcorduk Jan 26, 2026
21e565a
fix a log
akifcorduk Jan 26, 2026
3ae6047
move preprocessing to presolve
akifcorduk Jan 27, 2026
2c78d02
fix issues and handle ai reviews
akifcorduk Jan 30, 2026
8409f17
fix bugs adj list
akifcorduk Feb 2, 2026
22f778b
style checks
akifcorduk Feb 3, 2026
12c8fcf
fix excluded cliques and fix extended set packing constraints
akifcorduk Feb 3, 2026
5d16246
tests if threre are any complements of a variable in the extended clique
akifcorduk Feb 3, 2026
6319046
fix variables if complements share a clique
akifcorduk Feb 3, 2026
96385fe
add timing
akifcorduk Feb 3, 2026
7cd0a4a
wip
akifcorduk Feb 3, 2026
447713f
fix the knapsack indices
akifcorduk Feb 4, 2026
db8951a
fix weight and set packing issue
akifcorduk Feb 5, 2026
ab2339b
fix obj scale issue
akifcorduk Feb 5, 2026
7e322eb
Merge branch 'main' of github.com:NVIDIA/cuopt into cliques
akifcorduk Feb 6, 2026
d7f6a80
without cliques
akifcorduk Feb 6, 2026
f58b8c5
with cliques
akifcorduk Feb 6, 2026
cb10992
add timer to cliques
akifcorduk Feb 9, 2026
933beb0
add complement of the var to the adj list
akifcorduk Feb 9, 2026
c196ee2
adjust timer
akifcorduk Feb 9, 2026
524207a
fix the bug of fixing more vars
akifcorduk Feb 10, 2026
bc345bb
fix issues on clique table
akifcorduk Feb 10, 2026
b758b9f
fix timer issues
akifcorduk Feb 11, 2026
0392a62
disable jobserver flag when not actually using jobserver
aliceb-nv Feb 11, 2026
ee54477
disable jobserver unless explicitely requested
aliceb-nv Feb 11, 2026
f876fc0
better workaround fix build
aliceb-nv Feb 11, 2026
1c02baa
Merge branch 'main' of github.com:NVIDIA/cuopt into fix_timer
akifcorduk Feb 16, 2026
7de08d2
add timers to right_looking_lu and refactoring the basis
akifcorduk Feb 17, 2026
942de9c
remove timers from cuts
akifcorduk Feb 17, 2026
0b944d1
convert lambda to function and remove unnecessary checks
akifcorduk Feb 17, 2026
01d68c3
Merge branch 'main' of github.com:NVIDIA/cuopt into cliques
akifcorduk Feb 17, 2026
ba1df82
fix merge conflicts, reduce timers
akifcorduk Feb 17, 2026
f395672
fix reverse_iterator
akifcorduk Feb 17, 2026
71b7f2f
fix thrust changes
akifcorduk Feb 17, 2026
82b2d64
handle review comments
akifcorduk Feb 18, 2026
d074884
add extension heuristics and fix mip gap issues
akifcorduk Feb 18, 2026
0c81173
handle review comments
akifcorduk Feb 18, 2026
609c578
move timer with inout parameters
akifcorduk Feb 19, 2026
3d32acd
fix merge conflicts
akifcorduk Feb 19, 2026
0c54ecf
fix merge conflicts
akifcorduk Feb 19, 2026
d01fd3b
Merge branch 'main' of github.com:NVIDIA/cuopt into cliques
akifcorduk Feb 19, 2026
d5791dc
handle ai reviewS
akifcorduk Feb 19, 2026
fc414e7
revert cmake comment
akifcorduk Feb 19, 2026
fff860c
Merge branch 'fix_timer' into cliques
akifcorduk Feb 19, 2026
9803df2
Merge branch 'main' of github.com:NVIDIA/cuopt into cliques
akifcorduk Feb 20, 2026
3acb6a9
fix adjacency checks
akifcorduk Feb 20, 2026
6f6783b
fix adjacency set and var degree
akifcorduk Feb 20, 2026
8bc9fb0
add copy of variable bounds
akifcorduk Feb 20, 2026
ba7b9ff
remove the set packing if it covers set partitioning
akifcorduk Feb 20, 2026
d82e592
use append row
akifcorduk Feb 23, 2026
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
6 changes: 6 additions & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,12 @@ endif()
option(BUILD_MIP_BENCHMARKS "Build MIP benchmarks" OFF)
if(BUILD_MIP_BENCHMARKS AND NOT BUILD_LP_ONLY)
add_executable(solve_MIP ../benchmarks/linear_programming/cuopt/run_mip.cpp)
target_include_directories(solve_MIP
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/src"
PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
)

set_target_properties(solve_MIP
PROPERTIES
Expand Down
6 changes: 6 additions & 0 deletions cpp/src/dual_simplex/sparse_matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,12 @@ i_t csr_matrix_t<i_t, f_t>::check_matrix(std::string matrix_name) const
return 0;
}

template <typename i_t, typename f_t>
std::pair<i_t, i_t> csr_matrix_t<i_t, f_t>::get_constraint_range(i_t cstr_idx) const
{
return std::make_pair(this->row_start[cstr_idx], this->row_start[cstr_idx + 1]);
}
Comment on lines +660 to +664
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a debug bounds assert for cstr_idx.

Without a guard, an invalid cstr_idx can read past row_start. A debug assert keeps the fast path while catching misuse early.

🔧 Suggested change (debug-only assert)
 template <typename i_t, typename f_t>
 std::pair<i_t, i_t> csr_matrix_t<i_t, f_t>::get_constraint_range(i_t cstr_idx) const
 {
+  assert(cstr_idx >= 0);
+  assert(static_cast<size_t>(cstr_idx + 1) < this->row_start.size());
   return std::make_pair(this->row_start[cstr_idx], this->row_start[cstr_idx + 1]);
 }
🤖 Prompt for AI Agents
In `@cpp/src/dual_simplex/sparse_matrix.cpp` around lines 578 - 582, Add a
debug-only bounds check at the start of csr_matrix_t<i_t,
f_t>::get_constraint_range to ensure cstr_idx is within [0, row_start.size()-1]
(so that accessing row_start[cstr_idx+1] is safe); use the project's
debug/assert macro (or <cassert> assert) to verify cstr_idx >= 0 and cstr_idx +
1 < this->row_start.size(), then return the pair as before—this keeps the fast
path in release but catches invalid cstr_idx in debug.


// x <- x + alpha * A(:, j)
template <typename i_t, typename f_t>
void scatter_dense(const csc_matrix_t<i_t, f_t>& A, i_t j, f_t alpha, std::vector<f_t>& x)
Expand Down
2 changes: 2 additions & 0 deletions cpp/src/dual_simplex/sparse_matrix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ class csr_matrix_t {
return true;
}

// get constraint range
std::pair<i_t, i_t> get_constraint_range(i_t cstr_idx) const;
i_t nz_max; // maximum number of nonzero entries
i_t m; // number of rows
i_t n; // number of cols
Expand Down
1 change: 1 addition & 0 deletions cpp/src/mip_heuristics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ set(MIP_NON_LP_FILES
${CMAKE_CURRENT_SOURCE_DIR}/presolve/multi_probe.cu
${CMAKE_CURRENT_SOURCE_DIR}/presolve/probing_cache.cu
${CMAKE_CURRENT_SOURCE_DIR}/presolve/trivial_presolve.cu
${CMAKE_CURRENT_SOURCE_DIR}/presolve/conflict_graph/clique_table.cu
${CMAKE_CURRENT_SOURCE_DIR}/feasibility_jump/feasibility_jump.cu
${CMAKE_CURRENT_SOURCE_DIR}/feasibility_jump/feasibility_jump_kernels.cu
${CMAKE_CURRENT_SOURCE_DIR}/feasibility_jump/fj_cpu.cu)
Expand Down
21 changes: 20 additions & 1 deletion cpp/src/mip_heuristics/diversity/diversity_manager.cu
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "diversity_manager.cuh"

#include <mip_heuristics/mip_constants.hpp>
#include <mip_heuristics/presolve/conflict_graph/clique_table.cuh>
#include <mip_heuristics/presolve/probing_cache.cuh>
#include <mip_heuristics/presolve/trivial_presolve.cuh>
#include <mip_heuristics/problem/problem_helpers.cuh>
Expand All @@ -17,6 +18,8 @@

#include <utilities/scope_guard.hpp>

#include <memory>

constexpr bool fj_only_run = false;

namespace cuopt::linear_programming::detail {
Expand Down Expand Up @@ -204,16 +207,32 @@ bool diversity_manager_t<i_t, f_t>::run_presolve(f_t time_limit)
const bool remap_cache_ids = true;
trivial_presolve(*problem_ptr, remap_cache_ids);
if (!problem_ptr->empty && !check_bounds_sanity(*problem_ptr)) { return false; }
if (!context.settings.heuristics_only && !problem_ptr->empty) {
dual_simplex::user_problem_t<i_t, f_t> host_problem(problem_ptr->handle_ptr);
problem_ptr->get_host_user_problem(host_problem);
std::shared_ptr<clique_table_t<i_t, f_t>> clique_table;
find_initial_cliques(host_problem, context.settings.tolerances, presolve_timer);
problem_ptr->set_constraints_from_host_user_problem(host_problem);
cuopt_assert(host_problem.lower.size() == static_cast<size_t>(problem_ptr->n_variables),
"host lower bound size mismatch");
cuopt_assert(host_problem.upper.size() == static_cast<size_t>(problem_ptr->n_variables),
"host upper bound size mismatch");
std::vector<i_t> all_var_indices(problem_ptr->n_variables);
std::iota(all_var_indices.begin(), all_var_indices.end(), 0);
problem_ptr->update_variable_bounds(all_var_indices, host_problem.lower, host_problem.upper);
trivial_presolve(*problem_ptr, remap_cache_ids);
}
// May overconstrain if Papilo presolve has been run before
if (context.settings.presolver == presolver_t::None) {
if (!problem_ptr->empty) {
// do the resizing no-matter what, bounds presolve might not change the bounds but initial
// trivial presolve might have
ls.constraint_prop.bounds_update.resize(*problem_ptr);
ls.constraint_prop.bounds_update.upd.init_changed_constraints(problem_ptr->handle_ptr);
ls.constraint_prop.conditional_bounds_update.update_constraint_bounds(
*problem_ptr, ls.constraint_prop.bounds_update);
if (!check_bounds_sanity(*problem_ptr)) { return false; }
}
if (!check_bounds_sanity(*problem_ptr)) { return false; }
}
stats.presolve_time = presolve_timer.elapsed_time();
lp_optimal_solution.resize(problem_ptr->n_variables, problem_ptr->handle_ptr->get_stream());
Expand Down
19 changes: 18 additions & 1 deletion cpp/src/mip_heuristics/local_search/local_search.cu
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,24 @@ bool local_search_t<i_t, f_t>::do_fj_solve(solution_t<i_t, f_t>& solution,
if (time_limit == 0.) return solution.get_feasible();

timer_t timer(time_limit);

const auto old_n_cstr_weights = in_fj.cstr_weights.size();
const auto expected_n_cstr_weights = static_cast<size_t>(solution.problem_ptr->n_constraints);
// in case this is the first time run, resize
if (old_n_cstr_weights != expected_n_cstr_weights) {
in_fj.cstr_weights.resize(solution.problem_ptr->n_constraints,
solution.handle_ptr->get_stream());
cuopt_assert(in_fj.cstr_weights.size() == expected_n_cstr_weights,
"Constraint weights must match constraint count after resize");
// Initialize only newly grown entries; shrinking does not need initialization.
if (old_n_cstr_weights < expected_n_cstr_weights) {
cuopt_assert(old_n_cstr_weights <= in_fj.cstr_weights.size(),
"Constraint weight fill start must be within range");
thrust::uninitialized_fill(solution.handle_ptr->get_thrust_policy(),
in_fj.cstr_weights.begin() + old_n_cstr_weights,
in_fj.cstr_weights.end(),
1.);
}
}
auto h_weights = cuopt::host_copy(in_fj.cstr_weights, solution.handle_ptr->get_stream());
auto h_objective_weight = in_fj.objective_weight.value(solution.handle_ptr->get_stream());
for (auto& cpu_fj : ls_cpu_fj) {
Expand Down
Loading