Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
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
4bbf743
scaling test
akifcorduk Feb 16, 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
71b7f2f
fix thrust changes
akifcorduk Feb 17, 2026
82b2d64
handle review comments
akifcorduk Feb 18, 2026
0c81173
handle review comments
akifcorduk Feb 18, 2026
8f93926
revert scaling
akifcorduk Feb 18, 2026
80e2650
initial row scaling for mip
akifcorduk Feb 18, 2026
f021ba3
fix pdlp issues and finalize lp scaling
akifcorduk Feb 19, 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
fc414e7
revert cmake comment
akifcorduk Feb 19, 2026
41f5c3e
Merge branch 'fix_timer' into scaling_test
akifcorduk Feb 19, 2026
aa0b795
root node scaling
akifcorduk Feb 20, 2026
1c03794
sscaling off
akifcorduk Feb 20, 2026
74ec555
Merge branch 'main' of github.com:NVIDIA/cuopt into scaling_test
akifcorduk Feb 20, 2026
e849c70
correct mip gap computation
akifcorduk Feb 20, 2026
ea09141
wip
akifcorduk Feb 23, 2026
adfbf7d
with scaling
akifcorduk Feb 23, 2026
92b165e
make pdlp/barrier scaling default
akifcorduk Feb 23, 2026
2b080cc
fix compule error
akifcorduk Feb 23, 2026
7a61d13
skip mip scaling
akifcorduk Feb 23, 2026
0ee8344
without skipping big M
akifcorduk Feb 24, 2026
2a500f4
mip scaling with skipping big M
akifcorduk Feb 24, 2026
d0c5a42
fix thrust build + more timer checks
aliceb-nv Feb 24, 2026
d559b34
Merge branch 'main' into fix-thrust-build
aliceb-nv Feb 24, 2026
5b5909e
Merge commit 'refs/pull/902/head' of github.com:NVIDIA/cuopt into sca…
akifcorduk Feb 24, 2026
84f8fb3
fix headers
akifcorduk Feb 24, 2026
67240f5
review comment
aliceb-nv Feb 24, 2026
a15424f
fix thrust solve
aliceb-nv Feb 24, 2026
6772270
Merge commit 'refs/pull/902/head' of github.com:NVIDIA/cuopt into sca…
akifcorduk Feb 24, 2026
4a1c672
remove nvtx
akifcorduk Feb 24, 2026
7045ae7
fix init issues
akifcorduk Feb 25, 2026
80ac99d
don't skip big m
akifcorduk Feb 25, 2026
8eaebba
do scaling beforehand
akifcorduk Feb 25, 2026
6b2a631
without big M
akifcorduk Feb 25, 2026
cfcf0ab
try with mip scaling
akifcorduk Feb 27, 2026
1db603c
with assertS
akifcorduk Feb 27, 2026
0f39c06
try without any lp scaling
akifcorduk Feb 27, 2026
9e2d2d1
Merge branch 'main' of github.com:NVIDIA/cuopt into scaling_test
akifcorduk Feb 27, 2026
4ecf8f9
Merge branch 'main' of github.com:NVIDIA/cuopt into scaling_test
akifcorduk Mar 4, 2026
ca5b07e
scaling before presolve
akifcorduk Mar 4, 2026
2f58450
fix objective issues and pdlp solver mode
akifcorduk Mar 4, 2026
071ec5d
with stable 3
akifcorduk Mar 4, 2026
a1030a7
fix issues solver mode 2
akifcorduk Mar 4, 2026
5811ebb
without scaling
akifcorduk Mar 5, 2026
8f8fb84
lp only relative tolerance
akifcorduk Mar 5, 2026
7ec1ef7
lp with abs tolerance
akifcorduk Mar 5, 2026
aaa6ef9
only relative tolerance
akifcorduk Mar 5, 2026
68f6ac3
per constraint residual with relative tolerance
akifcorduk Mar 6, 2026
f536037
per constraint, absolute tolerance
akifcorduk Mar 6, 2026
77c4d7a
only relative tolerance with submip scaling
akifcorduk Mar 6, 2026
89bd164
with absolute tolerance of 1e-6 and per constraint
akifcorduk Mar 6, 2026
2d54c28
mip scaling on
akifcorduk Mar 6, 2026
95e14aa
gcd scaling and less agressive
akifcorduk Mar 6, 2026
d52074e
fix scaling changes
akifcorduk Mar 7, 2026
4915897
test fixes
akifcorduk Mar 8, 2026
cc8516c
Merge branch 'release/26.04' of github.com:NVIDIA/cuopt into scaling_…
akifcorduk Apr 1, 2026
b2647a1
remove parsing
akifcorduk Apr 1, 2026
8f95077
fix merge conflcits
akifcorduk Apr 1, 2026
2eb1448
remove upper lower bound checks
akifcorduk Apr 1, 2026
8c69366
fix 0 rows and -inf sentinel also adress review comments
akifcorduk Apr 2, 2026
5c59b05
fix gaps
akifcorduk Apr 2, 2026
1836697
add enum for scaling
akifcorduk Apr 2, 2026
38e6da5
only set the bound if we are feasible on abs tolerances
akifcorduk Apr 2, 2026
93f561f
add asserts for GCD
akifcorduk Apr 2, 2026
538571f
test 10 configs
akifcorduk Apr 2, 2026
d8cf181
decide on one config
akifcorduk Apr 3, 2026
d1dc957
without objective scaling
akifcorduk Apr 3, 2026
fece1ea
without objective scaling and no per constraint
akifcorduk Apr 3, 2026
4bb6582
with objective scaling and no per constraint
akifcorduk Apr 3, 2026
5f0cb51
revert strong branching removal
akifcorduk Apr 3, 2026
e057d01
fix maximization problem issues
akifcorduk Apr 3, 2026
a0afc96
Bump libcuopt size by 5 mb (#1016)
rgsl888prabhu Apr 1, 2026
634519a
best config
akifcorduk Apr 3, 2026
925b6ec
Merge branch 'release/26.04' of github.com:NVIDIA/cuopt into scaling_…
akifcorduk Apr 3, 2026
86590ba
remove scaling option from run_mip
akifcorduk Apr 3, 2026
13e2377
relax the error log from gap is negative
akifcorduk Apr 3, 2026
b91cdab
do literal for now
akifcorduk Apr 3, 2026
4eac4e3
fix gap computation on new primal solution while root relaxation is r…
akifcorduk Apr 3, 2026
0e3c1dc
fix lower bound
akifcorduk Apr 3, 2026
6a72199
fix correct obj reporting
akifcorduk Apr 3, 2026
13c7123
fix dual simplex user bound callback
akifcorduk Apr 3, 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
4 changes: 2 additions & 2 deletions ci/validate_wheel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ PYDISTCHECK_ARGS=(
if [[ "${package_dir}" == "python/libcuopt" ]]; then
if [[ "${RAPIDS_CUDA_MAJOR}" == "12" ]]; then
PYDISTCHECK_ARGS+=(
--max-allowed-size-compressed '645Mi'
--max-allowed-size-compressed '650Mi'
)
else
PYDISTCHECK_ARGS+=(
--max-allowed-size-compressed '490Mi'
--max-allowed-size-compressed '495Mi'
)
fi
elif [[ "${package_dir}" != "python/cuopt" ]] && \
Expand Down
14 changes: 12 additions & 2 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ endif(BUILD_MSAN)
# infrastructure files. Those files include abseil headers, and abseil's shared library
# on conda-forge doesn't export Mutex::Dtor() in NDEBUG builds (abseil-cpp#1624).
# Keeping NDEBUG defined for gRPC files makes the header inline an empty Dtor(),
# avoiding the missing symbol at runtime.
# avoiding the missing symbol at runtime. Additionally, gRPC files are always
# compiled with -DNDEBUG (see below) so Debug builds also avoid the missing symbol.
if(DEFINE_ASSERT)
add_definitions(-DASSERT_MODE)
list(APPEND CUOPT_CUDA_FLAGS -UNDEBUG)
Expand Down Expand Up @@ -390,7 +391,7 @@ if(DEFINE_ASSERT)
endif()

# Add gRPC mapper files and generated protobuf sources
list(APPEND CUOPT_SRC_FILES
set(GRPC_INFRA_FILES
${PROTO_SRCS}
${GRPC_PROTO_SRCS}
${GRPC_SERVICE_SRCS}
Expand All @@ -401,6 +402,15 @@ list(APPEND CUOPT_SRC_FILES
src/grpc/client/grpc_client.cpp
src/grpc/client/solve_remote.cpp
)
list(APPEND CUOPT_SRC_FILES ${GRPC_INFRA_FILES})

# Always keep NDEBUG defined for gRPC infrastructure files so that abseil
# headers inline Mutex::Dtor() instead of emitting an external call.
# The conda-forge abseil shared library is built with NDEBUG and does not
# export that symbol (abseil-cpp#1624). Without this, Debug builds fail
# at runtime with "undefined symbol: absl::…::Mutex::Dtor".
set_property(SOURCE ${GRPC_INFRA_FILES} DIRECTORY ${CMAKE_SOURCE_DIR}
APPEND PROPERTY COMPILE_OPTIONS "-DNDEBUG")

add_library(cuopt SHARED
${CUOPT_SRC_FILES}
Expand Down
5 changes: 5 additions & 0 deletions cpp/include/cuopt/linear_programming/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,9 @@
#define CUOPT_PRESOLVE_PAPILO 1
#define CUOPT_PRESOLVE_PSLP 2

/* @brief MIP scaling mode constants */
#define CUOPT_MIP_SCALING_OFF 0
#define CUOPT_MIP_SCALING_ON 1
#define CUOPT_MIP_SCALING_NO_OBJECTIVE 2

#endif // CUOPT_CONSTANTS_H
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class mip_solver_settings_t {

/** Initial primal solutions */
std::vector<std::shared_ptr<rmm::device_uvector<f_t>>> initial_solutions;
bool mip_scaling = false;
int mip_scaling = CUOPT_MIP_SCALING_NO_OBJECTIVE;
presolver_t presolver{presolver_t::Default};
/**
* @brief Determinism mode for MIP solver.
Expand Down
60 changes: 29 additions & 31 deletions cpp/src/branch_and_bound/branch_and_bound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,14 @@ f_t sgn(f_t x)
return x < 0 ? -1 : 1;
}

template <typename f_t>
f_t relative_gap(f_t obj_value, f_t lower_bound)
template <typename i_t, typename f_t>
f_t compute_user_abs_gap(const lp_problem_t<i_t, f_t>& lp, f_t obj_value, f_t lower_bound)
{
f_t user_mip_gap = obj_value == 0.0
? (lower_bound == 0.0 ? 0.0 : std::numeric_limits<f_t>::infinity())
: std::abs(obj_value - lower_bound) / std::abs(obj_value);
if (std::isnan(user_mip_gap)) { return std::numeric_limits<f_t>::infinity(); }
return user_mip_gap;
// abs_gap = |user_obj - user_lower| = |obj_scale| * |obj_value - lower_bound|
// obj_constant cancels out in the subtraction; obj_scale sign must be removed via abs
f_t gap = std::abs(lp.obj_scale) * (obj_value - lower_bound);
if (gap < -1e-4) { CUOPT_LOG_ERROR("Gap is negative %e", gap); }
return gap;
}

template <typename i_t, typename f_t>
Expand All @@ -191,15 +191,15 @@ f_t user_relative_gap(const lp_problem_t<i_t, f_t>& lp, f_t obj_value, f_t lower
f_t user_lower_bound = compute_user_objective(lp, lower_bound);
f_t user_mip_gap = user_obj == 0.0
? (user_lower_bound == 0.0 ? 0.0 : std::numeric_limits<f_t>::infinity())
: std::abs(user_obj - user_lower_bound) / std::abs(user_obj);
: compute_user_abs_gap(lp, obj_value, lower_bound) / std::abs(user_obj);
if (std::isnan(user_mip_gap)) { return std::numeric_limits<f_t>::infinity(); }
return user_mip_gap;
}

template <typename f_t>
std::string user_mip_gap(f_t obj_value, f_t lower_bound)
template <typename i_t, typename f_t>
std::string user_mip_gap(const lp_problem_t<i_t, f_t>& lp, f_t obj_value, f_t lower_bound)
{
const f_t user_mip_gap = relative_gap(obj_value, lower_bound);
const f_t user_mip_gap = user_relative_gap(lp, obj_value, lower_bound);
if (user_mip_gap == std::numeric_limits<f_t>::infinity()) {
return " - ";
} else {
Expand Down Expand Up @@ -319,7 +319,7 @@ void branch_and_bound_t<i_t, f_t>::report_heuristic(f_t obj)
if (is_running_) {
f_t user_obj = compute_user_objective(original_lp_, obj);
f_t user_lower = compute_user_objective(original_lp_, get_lower_bound());
std::string user_gap = user_mip_gap<f_t>(user_obj, user_lower);
std::string user_gap = user_mip_gap<i_t, f_t>(original_lp_, obj, get_lower_bound());

settings_.log.printf(
"H %+13.6e %+10.6e %s %9.2f\n",
Expand All @@ -329,9 +329,9 @@ void branch_and_bound_t<i_t, f_t>::report_heuristic(f_t obj)
toc(exploration_stats_.start_time));
} else {
if (solving_root_relaxation_.load()) {
f_t user_obj = compute_user_objective(original_lp_, obj);
f_t user_lower = root_lp_current_lower_bound_.load();
std::string user_gap = user_mip_gap<f_t>(user_obj, user_lower);
f_t user_obj = compute_user_objective(original_lp_, obj);
std::string user_gap =
user_mip_gap<i_t, f_t>(original_lp_, obj, root_lp_current_lower_bound_.load());
settings_.log.printf(
"New solution from primal heuristics. Objective %+.6e. Gap %s. Time %.2f\n",
user_obj,
Expand All @@ -356,7 +356,7 @@ void branch_and_bound_t<i_t, f_t>::report(
const f_t user_lower = compute_user_objective(original_lp_, lower_bound);
const f_t iters = static_cast<f_t>(exploration_stats_.total_lp_iters);
const f_t iter_node = nodes_explored > 0 ? iters / nodes_explored : iters;
const std::string user_gap = user_mip_gap<f_t>(user_obj, user_lower);
const std::string user_gap = user_mip_gap<i_t, f_t>(original_lp_, obj, lower_bound);
if (work_time >= 0) {
settings_.log.printf(
"%c %10d %10lu %+13.6e %+10.6e %6d %6d %7.1e %s %9.2f %9.2f\n",
Expand Down Expand Up @@ -717,9 +717,9 @@ void branch_and_bound_t<i_t, f_t>::set_final_solution(mip_solution_t<i_t, f_t>&
settings_.heuristic_preemption_callback();
}

f_t gap = upper_bound_ - lower_bound;
f_t obj = compute_user_objective(original_lp_, upper_bound_.load());
f_t user_bound = compute_user_objective(original_lp_, lower_bound);
f_t gap = std::abs(obj - user_bound);
f_t gap_rel = user_relative_gap(original_lp_, upper_bound_.load(), lower_bound);
bool is_maximization = original_lp_.obj_scale < 0.0;

Expand Down Expand Up @@ -1437,7 +1437,7 @@ void branch_and_bound_t<i_t, f_t>::plunge_with(branch_and_bound_worker_t<i_t, f_
f_t lower_bound = get_lower_bound();
f_t upper_bound = upper_bound_;
f_t rel_gap = user_relative_gap(original_lp_, upper_bound, lower_bound);
f_t abs_gap = upper_bound - lower_bound;
f_t abs_gap = compute_user_abs_gap(original_lp_, upper_bound, lower_bound);

while (stack.size() > 0 && (solver_status_ == mip_status_t::UNSET && is_running_) &&
rel_gap > settings_.relative_mip_gap_tol && abs_gap > settings_.absolute_mip_gap_tol) {
Expand Down Expand Up @@ -1528,13 +1528,13 @@ void branch_and_bound_t<i_t, f_t>::plunge_with(branch_and_bound_worker_t<i_t, f_
lower_bound = get_lower_bound();
upper_bound = upper_bound_;
rel_gap = user_relative_gap(original_lp_, upper_bound, lower_bound);
abs_gap = upper_bound - lower_bound;
abs_gap = compute_user_abs_gap(original_lp_, upper_bound, lower_bound);
}

lower_bound = get_lower_bound();
upper_bound = upper_bound_;
rel_gap = user_relative_gap(original_lp_, upper_bound, lower_bound);
abs_gap = upper_bound - lower_bound;
abs_gap = compute_user_abs_gap(original_lp_, upper_bound, lower_bound);

if (stack.size() > 0 &&
(rel_gap <= settings_.relative_mip_gap_tol || abs_gap <= settings_.absolute_mip_gap_tol)) {
Expand Down Expand Up @@ -1581,7 +1581,7 @@ void branch_and_bound_t<i_t, f_t>::dive_with(branch_and_bound_worker_t<i_t, f_t>
f_t lower_bound = get_lower_bound();
f_t upper_bound = upper_bound_;
f_t rel_gap = user_relative_gap(original_lp_, upper_bound, lower_bound);
f_t abs_gap = upper_bound - lower_bound;
f_t abs_gap = compute_user_abs_gap(original_lp_, upper_bound, lower_bound);

while (stack.size() > 0 && (solver_status_ == mip_status_t::UNSET && is_running_) &&
rel_gap > settings_.relative_mip_gap_tol && abs_gap > settings_.absolute_mip_gap_tol) {
Expand Down Expand Up @@ -1636,7 +1636,7 @@ void branch_and_bound_t<i_t, f_t>::dive_with(branch_and_bound_worker_t<i_t, f_t>
lower_bound = get_lower_bound();
upper_bound = upper_bound_;
rel_gap = user_relative_gap(original_lp_, upper_bound, lower_bound);
abs_gap = upper_bound - lower_bound;
abs_gap = compute_user_abs_gap(original_lp_, upper_bound, lower_bound);
}

worker_pool_.return_worker_to_pool(worker);
Expand Down Expand Up @@ -1667,7 +1667,7 @@ void branch_and_bound_t<i_t, f_t>::run_scheduler()
#endif

f_t lower_bound = get_lower_bound();
f_t abs_gap = upper_bound_ - lower_bound;
f_t abs_gap = compute_user_abs_gap(original_lp_, upper_bound_.load(), lower_bound);
f_t rel_gap = user_relative_gap(original_lp_, upper_bound_.load(), lower_bound);
i_t last_node_depth = 0;
i_t last_int_infeas = 0;
Expand Down Expand Up @@ -1777,7 +1777,7 @@ void branch_and_bound_t<i_t, f_t>::run_scheduler()
}

lower_bound = get_lower_bound();
abs_gap = upper_bound_ - lower_bound;
abs_gap = compute_user_abs_gap(original_lp_, upper_bound_.load(), lower_bound);
rel_gap = user_relative_gap(original_lp_, upper_bound_.load(), lower_bound);

if (abs_gap <= settings_.absolute_mip_gap_tol || rel_gap <= settings_.relative_mip_gap_tol) {
Expand All @@ -1799,7 +1799,7 @@ void branch_and_bound_t<i_t, f_t>::single_threaded_solve()
branch_and_bound_worker_t<i_t, f_t> worker(0, original_lp_, Arow_, var_types_, settings_);

f_t lower_bound = get_lower_bound();
f_t abs_gap = upper_bound_ - lower_bound;
f_t abs_gap = compute_user_abs_gap(original_lp_, upper_bound_.load(), lower_bound);
f_t rel_gap = user_relative_gap(original_lp_, upper_bound_.load(), lower_bound);

while (solver_status_ == mip_status_t::UNSET && abs_gap > settings_.absolute_mip_gap_tol &&
Expand Down Expand Up @@ -1844,7 +1844,7 @@ void branch_and_bound_t<i_t, f_t>::single_threaded_solve()
plunge_with(&worker);

lower_bound = get_lower_bound();
abs_gap = upper_bound_ - lower_bound;
abs_gap = compute_user_abs_gap(original_lp_, upper_bound_.load(), lower_bound);
rel_gap = user_relative_gap(original_lp_, upper_bound_.load(), lower_bound);

if (abs_gap <= settings_.absolute_mip_gap_tol || rel_gap <= settings_.relative_mip_gap_tol) {
Expand Down Expand Up @@ -2466,7 +2466,7 @@ mip_status_t branch_and_bound_t<i_t, f_t>::solve(mip_solution_t<i_t, f_t>& solut
report(' ', obj, root_objective_, 0, num_fractional);

f_t rel_gap = user_relative_gap(original_lp_, upper_bound_.load(), root_objective_);
f_t abs_gap = upper_bound_.load() - root_objective_;
f_t abs_gap = compute_user_abs_gap(original_lp_, upper_bound_.load(), root_objective_);
if (rel_gap < settings_.relative_mip_gap_tol || abs_gap < settings_.absolute_mip_gap_tol) {
set_solution_at_root(solution, cut_info);
set_final_solution(solution, root_objective_);
Expand Down Expand Up @@ -2961,7 +2961,6 @@ void branch_and_bound_t<i_t, f_t>::run_deterministic_bfs_loop(
worker.current_node = node;

f_t upper_bound = worker.local_upper_bound;
f_t rel_gap = user_relative_gap(original_lp_, upper_bound, node->lower_bound);
if (node->lower_bound > upper_bound) {
worker.current_node = nullptr;
worker.record_fathomed(node, node->lower_bound);
Expand Down Expand Up @@ -3073,7 +3072,7 @@ void branch_and_bound_t<i_t, f_t>::deterministic_sync_callback()

f_t lower_bound = deterministic_compute_lower_bound();
f_t upper_bound = upper_bound_.load();
f_t abs_gap = upper_bound - lower_bound;
f_t abs_gap = compute_user_abs_gap(original_lp_, upper_bound, lower_bound);
f_t rel_gap = user_relative_gap(original_lp_, upper_bound, lower_bound);

if (abs_gap <= settings_.absolute_mip_gap_tol || rel_gap <= settings_.relative_mip_gap_tol) {
Expand Down Expand Up @@ -3112,7 +3111,7 @@ void branch_and_bound_t<i_t, f_t>::deterministic_sync_callback()

f_t obj = compute_user_objective(original_lp_, upper_bound);
f_t user_lower = compute_user_objective(original_lp_, lower_bound);
std::string gap_user = user_mip_gap<f_t>(obj, user_lower);
std::string gap_user = user_mip_gap<i_t, f_t>(original_lp_, upper_bound, lower_bound);

std::string idle_workers;
i_t idle_count = 0;
Expand Down Expand Up @@ -3750,7 +3749,6 @@ void branch_and_bound_t<i_t, f_t>::deterministic_dive(
stack.pop_front();

// Prune check using snapshot upper bound
f_t rel_gap = user_relative_gap(original_lp_, worker.local_upper_bound, node_ptr->lower_bound);
if (node_ptr->lower_bound > worker.local_upper_bound) {
worker.recompute_bounds_and_basis = true;
continue;
Expand Down
2 changes: 1 addition & 1 deletion cpp/src/dual_simplex/phase2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3571,7 +3571,7 @@ dual::status_t dual_phase2_with_advanced_basis(i_t phase,
sum_perturb,
now);
if (phase == 2 && settings.inside_mip == 1 && settings.dual_simplex_objective_callback) {
settings.dual_simplex_objective_callback(user_obj);
settings.dual_simplex_objective_callback(obj);
}
}

Expand Down
2 changes: 1 addition & 1 deletion cpp/src/dual_simplex/user_problem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct user_problem_t {
std::vector<std::string> row_names;
std::vector<std::string> col_names;
f_t obj_constant;
f_t obj_scale; // 1.0 for min, -1.0 for max
f_t obj_scale; // positive for min, netagive for max
bool objective_is_integral{false};
std::vector<variable_type_t> var_types;
std::vector<i_t> Q_offsets;
Expand Down
2 changes: 1 addition & 1 deletion cpp/src/grpc/cuopt_remote.proto
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ message MIPSolverSettings {
int32 num_cpu_threads = 12;
int32 num_gpus = 13;
int32 presolver = 14;
bool mip_scaling = 15;
int32 mip_scaling = 15;
}

// LP solve request
Expand Down
7 changes: 6 additions & 1 deletion cpp/src/grpc/grpc_settings_mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,12 @@ void map_proto_to_mip_settings(const cuopt::remote::MIPSolverSettings& pb_settin
? static_cast<presolver_t>(pv)
: presolver_t::Default;
}
settings.mip_scaling = pb_settings.mip_scaling();
{
auto sv = pb_settings.mip_scaling();
settings.mip_scaling = (sv >= CUOPT_MIP_SCALING_OFF && sv <= CUOPT_MIP_SCALING_NO_OBJECTIVE)
? sv
: CUOPT_MIP_SCALING_ON;
}
}

// Explicit template instantiations
Expand Down
2 changes: 1 addition & 1 deletion cpp/src/math_optimization/solver_settings.cu
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ solver_settings_t<i_t, f_t>::solver_settings_t() : pdlp_settings(), mip_settings
{CUOPT_RANDOM_SEED, &mip_settings.seed, -1, std::numeric_limits<i_t>::max(), -1},
{CUOPT_MIP_RELIABILITY_BRANCHING, &mip_settings.reliability_branching, -1, std::numeric_limits<i_t>::max(), -1},
{CUOPT_PDLP_PRECISION, reinterpret_cast<int*>(&pdlp_settings.pdlp_precision), CUOPT_PDLP_DEFAULT_PRECISION, CUOPT_PDLP_MIXED_PRECISION, CUOPT_PDLP_DEFAULT_PRECISION},
{CUOPT_MIP_SCALING, &mip_settings.mip_scaling, CUOPT_MIP_SCALING_OFF, CUOPT_MIP_SCALING_NO_OBJECTIVE, CUOPT_MIP_SCALING_ON},
// MIP heuristic hyper-parameters (hidden from default --help: name contains "hyper_")
{CUOPT_MIP_HYPER_HEURISTIC_POPULATION_SIZE, &mip_settings.heuristic_params.population_size, 1, std::numeric_limits<i_t>::max(), 32, "max solutions in pool"},
{CUOPT_MIP_HYPER_HEURISTIC_NUM_CPUFJ_THREADS, &mip_settings.heuristic_params.num_cpufj_threads, 0, std::numeric_limits<i_t>::max(), 8, "parallel CPU FJ climbers"},
Expand All @@ -163,7 +164,6 @@ solver_settings_t<i_t, f_t>::solver_settings_t() : pdlp_settings(), mip_settings
{CUOPT_PER_CONSTRAINT_RESIDUAL, &pdlp_settings.per_constraint_residual, false},
{CUOPT_SAVE_BEST_PRIMAL_SO_FAR, &pdlp_settings.save_best_primal_so_far, false},
{CUOPT_FIRST_PRIMAL_FEASIBLE, &pdlp_settings.first_primal_feasible, false},
{CUOPT_MIP_SCALING, &mip_settings.mip_scaling, true},
{CUOPT_MIP_HEURISTICS_ONLY, &mip_settings.heuristics_only, false},
{CUOPT_LOG_TO_CONSOLE, &pdlp_settings.log_to_console, true},
{CUOPT_LOG_TO_CONSOLE, &mip_settings.log_to_console, true},
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 @@ -19,6 +19,7 @@ set(MIP_LP_NECESSARY_FILES

# Files that are MIP-specific and not needed for pure LP
set(MIP_NON_LP_FILES
${CMAKE_CURRENT_SOURCE_DIR}/mip_scaling_strategy.cu
${CMAKE_CURRENT_SOURCE_DIR}/solve.cu
${CMAKE_CURRENT_SOURCE_DIR}/solver.cu
${CMAKE_CURRENT_SOURCE_DIR}/diversity/assignment_hash_map.cu
Expand Down
Loading
Loading