Skip to content

Root Heuristics (RINS, CPU FJ) - #1699

Closed
nguidotti wants to merge 4 commits into
NVIDIA:mainfrom
nguidotti:root-heuristics
Closed

Root Heuristics (RINS, CPU FJ)#1699
nguidotti wants to merge 4 commits into
NVIDIA:mainfrom
nguidotti:root-heuristics

Conversation

@nguidotti

Copy link
Copy Markdown
Contributor
  • Refactored the root heuristics (more specifically, the CPU FJ launches at the root node) to be more modular, while allowing to use more workers.
  • Extended recursive RINS to run on the root node
  • Fixed incorrect objective passed to the set_solution_from_submip (the objective was on the submip space, which is not comparable with the solution space of the B&B).

Checklist

  • I am familiar with the Contributing Guidelines.
  • Testing
    • New or existing tests cover these changes
    • Added tests
    • Created an issue to follow-up
    • NA
  • Documentation
    • The documentation is up to date with these changes
    • Added new documentation
    • NA

…rom submip.

Signed-off-by: Nicolas L. Guidotti <nguidotti@nvidia.com>
Signed-off-by: Nicolas L. Guidotti <nguidotti@nvidia.com>
Signed-off-by: Nicolas L. Guidotti <nguidotti@nvidia.com>
@nguidotti
nguidotti requested a review from a team as a code owner August 11, 2026 11:16
@nguidotti
nguidotti requested review from kaatish and rg20 August 11, 2026 11:16
@nguidotti nguidotti self-assigned this Aug 11, 2026
@nguidotti nguidotti added non-breaking Introduces a non-breaking change improvement Improves an existing functionality mip labels Aug 11, 2026
@nguidotti nguidotti added this to the 26.10 milestone Aug 11, 2026
@nguidotti
nguidotti requested review from akifcorduk, aliceb-nv and chris-maes and removed request for kaatish and rg20 August 11, 2026 11:17
@nguidotti
nguidotti marked this pull request as draft August 11, 2026 11:17
@copy-pr-bot

copy-pr-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds configurable DFS backtracking for SubMIP feasibility searches. It refactors SubMIP and RINS objective handling, worker-state reuse, postsolve processing, and asynchronous root heuristic scheduling. It also initializes new feasibility-jump constraint weights to one.

Changes

Root heuristic execution

Layer / File(s) Summary
Contracts and objective state
cpp/include/cuopt/mathematical_optimization/mip/submip_hyper_params.hpp, cpp/src/dual_simplex/*, cpp/src/mip_heuristics/presolve/*, cpp/src/branch_and_bound/{branch_and_bound.hpp,worker.hpp}, cpp/src/mip_heuristics/root_heuristics.hpp
Adds dfs_max_backtrack, solver-objective conversion, conditional postsolve checks, root-heuristic helper contracts, and an atomic worker halt flag.
SubMIP and RINS worker execution
cpp/src/branch_and_bound/branch_and_bound.cpp
Reuses worker state, recomputes objectives after postsolve, applies solver-objective cutoffs, controls pseudocost transfer, configures DFS backtracking, and limits diagnostics to DEBUG_SUBMIP.
Asynchronous root heuristic orchestration
cpp/src/branch_and_bound/branch_and_bound.cpp, cpp/src/mip_heuristics/feasibility_jump/{fj_cpu.cu,fj_cpu_worker.cuh}
Schedules RINS and CPU-FJ workers through a shared tracked pipeline, enforces worker limits, refreshes incumbents after cut passes, and updates deterministic-mode documentation and statistics formatting.

Feasibility-jump weight initialization

Layer / File(s) Summary
Constraint-weight resize behavior
cpp/src/mip_heuristics/feasibility_jump/feasibility_jump.cu
Preserves existing constraint weights and initializes newly allocated weights to 1.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • NVIDIA/cuopt#1698: Contains the same feasibility-jump constraint-weight initialization fix.

Suggested labels: bug

Suggested reviewers: rg20, aliceb-nv, akifcorduk

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: refactoring root heuristics involving RINS and CPU Feasibility Jump.
Description check ✅ Passed The description directly explains the root heuristic refactor, recursive RINS support, objective correction, and related fixes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
cpp/src/branch_and_bound/branch_and_bound.cpp (1)

2814-2825: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

heuristics.emplace_back runs before both capacity checks.

Line 2825 appends a root_heuristics_t unconditionally. The RINS check at line 2827 and the CPU FJ check at line 2853 can both fail, for example when there is no incumbent and *worker_count reached settings_.num_threads - 1 between the entry check and line 2853. The list then holds an element with no submip_worker_ and no started FJ worker.

The element is harmless and the list is bounded by settings_.max_cut_passes, so this is not a correctness defect. Move the emplace_back after the first successful capacity check to keep the list meaningful.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/src/branch_and_bound/branch_and_bound.cpp` around lines 2814 - 2825, Move
the heuristics.emplace_back call and references to the created heuristic in
launch_root_heuristics so they occur only after the first RINS capacity check
succeeds. Ensure failed RINS and CPU FJ capacity checks do not append an
uninitialized root_heuristics_t entry, while preserving the existing heuristic
setup and execution behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cpp/src/branch_and_bound/branch_and_bound.cpp`:
- Around line 658-664: In the root-heuristic solution handling at
cpp/src/branch_and_bound/branch_and_bound.cpp:658-664, lock mutex_original_lp_
before accessing original_lp_ for compute_objective and handle leaf_sol values
narrower than original_lp_.num_cols without out-of-bounds access. In rins at
cpp/src/branch_and_bound/branch_and_bound.cpp:2579-2593, snapshot var_types_
under mutex_original_lp_ once at the start into worker-local storage, then pass
that snapshot to fractional_variables instead of repeatedly reading the shared
member.

In `@cpp/src/mip_heuristics/feasibility_jump/fj_cpu_worker.cuh`:
- Around line 50-52: Add a direct include for utilities/omp_helpers.hpp in
fj_cpu_worker.cuh so the omp_atomic_t type used by run_async is declared
independently of transitive includes.

In `@cpp/src/mip_heuristics/root_heuristics.hpp`:
- Around line 29-37: Update the RINS fixing loop condition in
root_heuristics_t::rins() to also require !worker->halt, while preserving the
existing solver_status_ and is_running_ checks. This ensures the loop exits when
root_heuristics_t::stop() signals the worker before the heuristic state is
destroyed.

---

Nitpick comments:
In `@cpp/src/branch_and_bound/branch_and_bound.cpp`:
- Around line 2814-2825: Move the heuristics.emplace_back call and references to
the created heuristic in launch_root_heuristics so they occur only after the
first RINS capacity check succeeds. Ensure failed RINS and CPU FJ capacity
checks do not append an uninitialized root_heuristics_t entry, while preserving
the existing heuristic setup and execution behavior.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c6a6266b-2ede-44d7-b8c8-d8c265d981ac

📥 Commits

Reviewing files that changed from the base of the PR and between 6df36e2 and 89b439c.

📒 Files selected for processing (12)
  • cpp/include/cuopt/mathematical_optimization/mip/submip_hyper_params.hpp
  • cpp/src/branch_and_bound/branch_and_bound.cpp
  • cpp/src/branch_and_bound/branch_and_bound.hpp
  • cpp/src/branch_and_bound/worker.hpp
  • cpp/src/dual_simplex/solve.cpp
  • cpp/src/dual_simplex/solve.hpp
  • cpp/src/mip_heuristics/feasibility_jump/feasibility_jump.cu
  • cpp/src/mip_heuristics/feasibility_jump/fj_cpu.cu
  • cpp/src/mip_heuristics/feasibility_jump/fj_cpu_worker.cuh
  • cpp/src/mip_heuristics/presolve/third_party_presolve.cpp
  • cpp/src/mip_heuristics/presolve/third_party_presolve.hpp
  • cpp/src/mip_heuristics/root_heuristics.hpp

Comment thread cpp/src/branch_and_bound/branch_and_bound.cpp
Comment thread cpp/src/mip_heuristics/feasibility_jump/fj_cpu_worker.cuh
Comment thread cpp/src/mip_heuristics/root_heuristics.hpp
@github-actions

Copy link
Copy Markdown

CI Test Summary

⏭️ All 5 test job(s) skipped.

@nguidotti nguidotti closed this Aug 11, 2026
@nguidotti
nguidotti deleted the root-heuristics branch August 11, 2026 15:21
@coderabbitai coderabbitai Bot mentioned this pull request Aug 11, 2026
8 tasks
@nguidotti nguidotti removed this from the 26.10 milestone Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improves an existing functionality mip non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant