Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
aefe31a
recursive RINS based on HiGHS.
nguidotti Jun 25, 2026
ba99a21
fix time limit violation when solving the submip
nguidotti Jun 29, 2026
727e20e
clean up the code a bit. print submip symbol in the logs instead of H
nguidotti Jun 29, 2026
37182d3
fix potential race condition
nguidotti Jun 29, 2026
bd7777b
allow rins to fire whenever it is idling. fix incorrect recursion check.
nguidotti Jun 29, 2026
c46eecd
added a presolver_t class for MIP so it can be used for presolving su…
nguidotti Jun 30, 2026
6596b6e
added routine for converting from standard form to range form
nguidotti Jun 19, 2026
c78007a
Merge branch 'main' into recursive-submip
nguidotti Jun 30, 2026
20fae2e
Merge branch 'form-conversion' into recursive-submip
nguidotti Jun 30, 2026
d39e424
apply presolver before solving the submip. missing warm start.
nguidotti Jun 30, 2026
3328cda
pass the upper bound from the parent B&B to the children. clean up th…
nguidotti Jun 30, 2026
583a6c4
Merge branch 'main' into recursive-submip
nguidotti Jun 30, 2026
a37acd4
crush the incumbent and pass to the submip B&B. includes #1104
nguidotti Jun 30, 2026
579dc19
warm the submip solve with the crushed pseudocost from the parent.
nguidotti Jun 30, 2026
b43caab
set an iteration limit for the submip solve
nguidotti Jul 1, 2026
234361d
extend the neighbourhood to reach the min fixrate using a coefficient…
nguidotti Jul 1, 2026
f7cd067
properly handle the upper bound changes in the main solve. fixed iter…
nguidotti Jul 1, 2026
b30df80
fix incorrect submip iteration count. moved submipt worker to worker.hpp
nguidotti Jul 1, 2026
ce211f3
fix incorrect subspace of the incumbent
nguidotti Jul 1, 2026
8b9bf67
silence submip logs
nguidotti Jul 1, 2026
92a0f17
fix incorrect conversion from Papilo problem to user_problem
nguidotti Jul 2, 2026
9b48c09
untied the active diving heuristics with the number of diving workers…
nguidotti Jul 2, 2026
d16e641
spawn an CPUFJ task alongside each submip solve
nguidotti Jul 2, 2026
869cc34
merged submip and diving workers. submip not perform a short diving i…
nguidotti Jul 2, 2026
76135a9
address ai reviews
nguidotti Jul 3, 2026
371d15f
fix accumulating an invalid iteration count when the problem is infea…
nguidotti Jul 3, 2026
7d40c07
fix out-of-bound access in GF2 reduction and CliqueMerging
nguidotti Jul 3, 2026
d5f020e
enabled cuts when solving the submip. fix incorrectly limiting the nu…
nguidotti Jul 3, 2026
0a9f7ca
Merge branch 'main' into recursive-submip
nguidotti Jul 6, 2026
c749322
code cleanup
nguidotti Jul 6, 2026
aef9515
fix mismatch tolerance between assert and acceptance in flow cover cuts
nguidotti Jul 8, 2026
bec9c50
Merge branch 'main' into recursive-submip
nguidotti Jul 8, 2026
aae222c
fix assertion failure in dual infer in Papilo (temporary redirect Pap…
nguidotti Jul 8, 2026
d187756
silence Papilo post-solve message (the tolerance in RINS are looser t…
nguidotti Jul 8, 2026
c656ae4
additional fix for assertion failure in Papilo
nguidotti Jul 8, 2026
beb4a3d
handle trivial sub-MIP after presolve. increase time limit and num th…
nguidotti Jul 8, 2026
7d3170b
removed "old" RINS
nguidotti Jul 8, 2026
4a5df0d
set the correct dimensions of the full solution vector at the start. …
nguidotti Jul 8, 2026
fb3d5a1
enable debug logs for CI crash
nguidotti Jul 8, 2026
4a88ad7
disable debug logs
nguidotti Jul 8, 2026
3ddb03c
unified set_solution routine across heuristics and submip. address ot…
nguidotti Jul 9, 2026
4af4d98
refactor CPU FJ worker
nguidotti Jul 9, 2026
332a683
correctly halting the submip instances after converged to the optimal…
nguidotti Jul 10, 2026
662110d
added additional tests. use the worker current solution for cpu fj
nguidotti Jul 10, 2026
49d01e8
run cpu fj when fixrate is slow or we already found an improving solu…
nguidotti Jul 10, 2026
cf664ee
Merge branch 'main' into recursive-submip
nguidotti Jul 10, 2026
45eceba
set the correct guess for cpu fj. do not move lower/upper bounds befo…
nguidotti Jul 10, 2026
3f7c9fc
additional fixes
nguidotti Jul 10, 2026
94319e4
fix delayed termination when the tree is fully explored
nguidotti Jul 13, 2026
346dcfb
potential fix for the flow cuts assertion failure
nguidotti Jul 13, 2026
4ed7233
increase fill-in rate when solving the submip
nguidotti Jul 13, 2026
74bc227
another fix for the flow cover cuts
nguidotti Jul 13, 2026
da4141f
another fix for the delayed termination. add ability to save submip t…
nguidotti Jul 13, 2026
0098b5f
Merge branch 'main' into recursive-submip
nguidotti Jul 14, 2026
8e9a9d8
address the reviewer comments
nguidotti Jul 15, 2026
4fe0198
replaced solve_node_lp in rins since we are not actually solving the …
nguidotti Jul 15, 2026
a6d9ee6
eliminate free rows when building the user problem
nguidotti Jul 15, 2026
619d46d
removed skip_set_bounds flag.
nguidotti Jul 15, 2026
b58a080
simplify the conversion between lp_problem_t and user_problem_t. fix …
nguidotti Jul 15, 2026
57360b1
revert changes to search strategy
nguidotti Jul 15, 2026
657d975
Merge branch 'main' into recursive-submip
nguidotti Jul 15, 2026
45f83c6
fix crush on papilo
nguidotti Jul 15, 2026
1f4b39a
reduced code changes
nguidotti Jul 15, 2026
f2f8f7f
fix compilation
nguidotti Jul 15, 2026
52d5ff6
fix compilation on assert mode
nguidotti Jul 15, 2026
16e74a8
fix incorrect code revert
nguidotti Jul 15, 2026
9bb43f4
silence rins logs
nguidotti Jul 15, 2026
9003603
address additional review comments. revert changes to the solve_node_lp
nguidotti Jul 16, 2026
dfed856
expose rins hyper parameters for tuning
nguidotti Jul 16, 2026
f758886
added comment for the CPU FJ
nguidotti Jul 16, 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
32 changes: 16 additions & 16 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,14 @@ endif ()

FetchContent_Declare(
papilo
GIT_REPOSITORY "https://github.com/scipopt/papilo.git"
GIT_REPOSITORY "https://github.com/nguidotti/papilo.git"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this intentional?

We should not be getting papilo from developer forks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this is only temporary. I will wait for scipopt/papilo#89 to merged before merging this PR

# We would want to get the main branch. However, the main branch
# does not have some of the presolvers and settings that we need
# Mainly, probing and clique merging.
# This is the reason we are using the development branch
# from Oct 12, 2025. Once these changes are merged into the main branch,
#we can switch to the main branch.
GIT_TAG "741a2b9c8155b249d6df574d758b4d97d4417520"
GIT_TAG "0cfea20c5655249174dbd04f0fb7bd6b1f6e9a0c"
Comment on lines 253 to +262

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we pin on your repo? Is it because of a required upstream fix? If so, we probably should wait until it is merged before merging the PR instead of depending on a personal repo (or at least, track that with an issue)

@nguidotti nguidotti Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this is only temporary. I will wait for scipopt/papilo#89 to merged before merging this PR

GIT_PROGRESS TRUE
EXCLUDE_FROM_ALL
SYSTEM
Expand Down Expand Up @@ -293,13 +293,13 @@ set(BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS_SAVED})
# dejavu - header-only graph automorphism library for MIP symmetry detection
# https://github.com/markusa4/dejavu (header-only, skip its CMakeLists.txt)
FetchContent_Declare(
dejavu
GIT_REPOSITORY "https://github.com/markusa4/dejavu.git"
GIT_TAG "v2.1"
GIT_PROGRESS TRUE
EXCLUDE_FROM_ALL
SYSTEM
SOURCE_SUBDIR _nonexistent
dejavu
GIT_REPOSITORY "https://github.com/markusa4/dejavu.git"
GIT_TAG "v2.1"
GIT_PROGRESS TRUE
EXCLUDE_FROM_ALL
SYSTEM
SOURCE_SUBDIR _nonexistent
)
FetchContent_MakeAvailable(dejavu)
message(STATUS "dejavu (graph automorphism): ${dejavu_SOURCE_DIR}")
Expand Down Expand Up @@ -369,7 +369,7 @@ if (NOT SKIP_GRPC_BUILD)

# Proto search paths: manual protos in src/grpc, generated data proto in src/grpc/codegen/generated
set(PROTO_PATH_MANUAL "${CMAKE_CURRENT_SOURCE_DIR}/src/grpc")
set(PROTO_PATH_GEN "${CMAKE_CURRENT_SOURCE_DIR}/src/grpc/codegen/generated")
set(PROTO_PATH_GEN "${CMAKE_CURRENT_SOURCE_DIR}/src/grpc/codegen/generated")

# Generate C++ code from cuopt_remote_data.proto (auto-generated data definitions)
set(DATA_PROTO_FILE "${PROTO_PATH_GEN}/cuopt_remote_data.proto")
Expand Down Expand Up @@ -441,8 +441,8 @@ add_subdirectory(src)
# nvcc 13.0.3 ICE (signal 11) compiling sliding_window.cu with 7 GPU architectures;
# --split-compile breaks the codegen into per-arch sub-jobs to avoid the crash
set_source_files_properties(
${CMAKE_CURRENT_SOURCE_DIR}/src/routing/local_search/sliding_window.cu
PROPERTIES COMPILE_OPTIONS "--split-compile=0")
${CMAKE_CURRENT_SOURCE_DIR}/src/routing/local_search/sliding_window.cu
PROPERTIES COMPILE_OPTIONS "--split-compile=0")

if (HOST_LINEINFO)
set_source_files_properties(${CUOPT_SRC_FILES} DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTIES COMPILE_OPTIONS "-g1")
Expand Down Expand Up @@ -495,8 +495,8 @@ set_target_properties(cuopt
)

target_compile_definitions(cuopt
PUBLIC "CUOPT_LOG_ACTIVE_LEVEL=RAPIDS_LOGGER_LOG_LEVEL_${LIBCUOPT_LOGGING_LEVEL}"
PUBLIC CUSPARSE_ENABLE_EXPERIMENTAL_API
PUBLIC "CUOPT_LOG_ACTIVE_LEVEL=RAPIDS_LOGGER_LOG_LEVEL_${LIBCUOPT_LOGGING_LEVEL}"
PUBLIC CUSPARSE_ENABLE_EXPERIMENTAL_API
)

target_compile_options(cuopt
Expand Down Expand Up @@ -528,8 +528,8 @@ target_include_directories(cuopt PRIVATE
)

target_include_directories(cuopt SYSTEM PRIVATE
"${pslp_SOURCE_DIR}/include"
"${dejavu_SOURCE_DIR}"
"${pslp_SOURCE_DIR}/include"
"${dejavu_SOURCE_DIR}"
)

target_include_directories(cuopt
Expand Down
13 changes: 12 additions & 1 deletion cpp/include/cuopt/mathematical_optimization/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
#define CUOPT_MIP_ZERO_HALF_CUTS "mip_zero_half_cuts"
#define CUOPT_MIP_STRONG_CHVATAL_GOMORY_CUTS "mip_strong_chvatal_gomory_cuts"
#define CUOPT_MIP_REDUCED_COST_STRENGTHENING "mip_reduced_cost_strengthening"
#define CUOPT_MIP_RINS "mip_rins"
#define CUOPT_MIP_OBJECTIVE_STEP "mip_objective_step"
#define CUOPT_MIP_CUT_CHANGE_THRESHOLD "mip_cut_change_threshold"
#define CUOPT_MIP_CUT_MIN_ORTHOGONALITY "mip_cut_min_orthogonality"
Expand Down Expand Up @@ -127,9 +128,19 @@
#define CUOPT_MIP_HYPER_DIVING_NODE_LIMIT "mip_hyper_diving_node_limit"
#define CUOPT_MIP_HYPER_DIVING_ITERATION_LIMIT_FACTOR "mip_hyper_diving_iteration_limit_factor"
#define CUOPT_MIP_HYPER_DIVING_BACKTRACK_LIMIT "mip_hyper_diving_backtrack_limit"
/* @brief Show per-strategy diving symbol in logs (true) instead of a generic 'D' */
/* @brief Show per-strategy diving symbol in logs instead of a generic 'D' */
#define CUOPT_MIP_HYPER_DIVING_SHOW_TYPE "mip_hyper_diving_show_type"

/* @brief Recursive sub-MIP (RINS) hyper-parameters */
#define CUOPT_MIP_HYPER_SUBMIP_BASE_TARGET_FIXRATE "mip_hyper_submip_base_target_fixrate"
#define CUOPT_MIP_HYPER_SUBMIP_MIN_FIXRATE "mip_hyper_submip_min_fixrate"
#define CUOPT_MIP_HYPER_SUBMIP_MIN_FIXRATE_CAP "mip_hyper_submip_min_fixrate_cap"
#define CUOPT_MIP_HYPER_SUBMIP_TARGET_MIP_GAP "mip_hyper_submip_target_mip_gap"
#define CUOPT_MIP_HYPER_SUBMIP_NODE_LIMIT_BASE "mip_hyper_submip_node_limit_base"
#define CUOPT_MIP_HYPER_SUBMIP_MAX_LEVEL "mip_hyper_submip_max_level"
#define CUOPT_MIP_HYPER_SUBMIP_ITERATION_LIMIT_RATIO "mip_hyper_submip_iteration_limit_ratio"
#define CUOPT_MIP_HYPER_SUBMIP_ENABLE_CPUFJ "mip_hyper_submip_enable_cpufj"

/* @brief MIP determinism mode constants */
#define CUOPT_MODE_OPPORTUNISTIC 0
#define CUOPT_MODE_DETERMINISTIC 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,7 @@
namespace cuopt::mathematical_optimization {

/**
* @brief Tuning knobs for the dual-simplex diving heuristics used in MIP B&B.
*
* Used directly as simplex_solver_settings_t::diving_settings and copied into
* branch_and_bound_settings.diving_settings before solve. These are registered
* in the unified parameter framework via solver_settings_t and can be loaded
* from a config file with load_parameters_from_file().
* @brief Tuning knobs for the diving heuristics for the MIP solver.
*/
template <typename i_t, typename f_t>
struct mip_diving_hyper_params_t {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <cuopt/mathematical_optimization/constants.h>
#include <cuopt/mathematical_optimization/mip/diving_hyper_params.hpp>
#include <cuopt/mathematical_optimization/mip/heuristics_hyper_params.hpp>
#include <cuopt/mathematical_optimization/mip/submip_hyper_params.hpp>
#include <cuopt/mathematical_optimization/pdlp/pdlp_hyper_params.cuh>
#include <cuopt/mathematical_optimization/utilities/internals.hpp>

Expand Down Expand Up @@ -184,8 +185,8 @@ class mip_solver_settings_t {
pdlp::pdlp_hyper_params_t hyper_params;

mip_heuristics_hyper_params_t<i_t, f_t> heuristic_params;

mip_diving_hyper_params_t<i_t, f_t> diving_params;
mip_submip_hyper_params_t<i_t, f_t> submip_params;

private:
std::vector<internals::base_solution_callback_t*> mip_callbacks_;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* clang-format off */
/*
* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
/* clang-format on */

#pragma once

/**
* @brief Tuning knobs for the recursive sub-MIP.
*/
template <typename i_t, typename f_t>
struct mip_submip_hyper_params_t {
// Enable or disable (recursive) RINS: -1 automatic, 0 disabled, 1 enabled
i_t rins = -1;

// Base for calculating the target fix rate for the neighbourhood. Actual target value is
// determined automatically according to the success and infeasible rate.
f_t base_target_fixrate = 0.6;

// Minimum fix rate for accepting the neighbourhood.
f_t min_fixrate = 0.25;

// Hard cap for the minimum fix rate for solving a sub-MIP.
f_t min_fixrate_cap = 0.1;

// MIP gap for the sub-MIP (unless the MIP gap from the B&B is lower)
f_t target_mip_gap = 0.01;

// The base node limit for the sub-MIP
i_t node_limit_base = 200;

// The current level in the recursion. This is an internal parameter and will set automatically.
i_t level = 0;

// Maximum recursion level
i_t max_level = 10;

// Limit the number of simplex iterations spent in the submip. Set as a factor of the total
// number of simplex iteration from the parent B&B.
f_t iteration_limit_ratio = 0.8;

// Run CPU FJ over the sub-MIP
bool enable_cpufj = true;
};
Loading
Loading