Skip to content

Fix lost nodes in branch and bound - #1138

Merged
rapids-bot[bot] merged 6 commits into
NVIDIA:mainfrom
hlinsen:fix-bb-rins
May 19, 2026
Merged

Fix lost nodes in branch and bound#1138
rapids-bot[bot] merged 6 commits into
NVIDIA:mainfrom
hlinsen:fix-bb-rins

Conversation

@hlinsen

@hlinsen hlinsen commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Fix lost branch-and-bound nodes when a plunge exits early due to LP solve limits.

  • Requeues pending plunge nodes when the LP solve hits CONCURRENT_LIMIT.
  • Requeues the current node and pending stack when the LP solve hits ITERATION_LIMIT.
  • Ensures pending local stack nodes are returned to the global queue before plunge_with exits early, so the solver does not silently drop unexplored nodes or compute
    an incorrect lower bound.

@hlinsen
hlinsen requested review from aliceb-nv and nguidotti April 23, 2026 14:22
@hlinsen
hlinsen requested a review from a team as a code owner April 23, 2026 14:22
@hlinsen hlinsen added the bug Something isn't working label Apr 23, 2026
@coderabbitai

coderabbitai Bot commented Apr 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The branch-and-bound solver's plunge_with method now tracks whether the dual solver terminates early due to concurrency or iteration limits. When either limit is reached, the current node is re-inserted onto the local stack and a flag is set. After the main loop, any remaining pending nodes are flushed to the global queue, either due to convergence or because nodes were unconsumed during early termination.

Changes

Pending node requeuing on early termination

Layer / File(s) Summary
Requeue pending nodes on early termination
cpp/src/branch_and_bound/branch_and_bound.cpp
Initialize requeue_pending_nodes flag at method entry. When dual solver hits CONCURRENT_LIMIT or ITERATION_LIMIT, push the current node back to the local stack, set the flag, and break. After the main loop, broaden the flush condition to also re-queue remaining local nodes when the flag is set.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 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
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.
Title check ✅ Passed The title 'Fix lost nodes in branch and bound' directly relates to the main objective stated in the PR description: re-stacking nodes when encountering iteration and concurrent limits to prevent lost nodes in branch and bound.
Description check ✅ Passed The PR description accurately describes the changes made to branch_and_bound.cpp, addressing how nodes are requeued when LP solve hits iteration/concurrent limits.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@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.

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

1485-1492: Optional cleanup: merge identical limit branches.

Both status branches perform the same operations; collapsing them reduces maintenance drift.

♻️ Proposed simplification
-    } else if (lp_status == dual::status_t::CONCURRENT_LIMIT) {
-      stack.push_front(node_ptr);
-      requeue_pending_nodes = true;
-      break;
-    } else if (lp_status == dual::status_t::ITERATION_LIMIT) {
+    } else if (lp_status == dual::status_t::CONCURRENT_LIMIT ||
+               lp_status == dual::status_t::ITERATION_LIMIT) {
       stack.push_front(node_ptr);
       requeue_pending_nodes = true;
       break;
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cpp/src/branch_and_bound/branch_and_bound.cpp` around lines 1485 - 1492, The
two consecutive branches checking lp_status == dual::status_t::CONCURRENT_LIMIT
and lp_status == dual::status_t::ITERATION_LIMIT perform identical actions;
collapse them into a single condition to avoid duplication. Replace the two
else-if blocks with a single branch that checks if lp_status is either
dual::status_t::CONCURRENT_LIMIT or dual::status_t::ITERATION_LIMIT, then call
stack.push_front(node_ptr), set requeue_pending_nodes = true, and break;
referencing the existing lp_status variable and the
stack.push_front(node_ptr)/requeue_pending_nodes/break sequence.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@cpp/src/branch_and_bound/branch_and_bound.cpp`:
- Around line 1485-1492: The two consecutive branches checking lp_status ==
dual::status_t::CONCURRENT_LIMIT and lp_status ==
dual::status_t::ITERATION_LIMIT perform identical actions; collapse them into a
single condition to avoid duplication. Replace the two else-if blocks with a
single branch that checks if lp_status is either
dual::status_t::CONCURRENT_LIMIT or dual::status_t::ITERATION_LIMIT, then call
stack.push_front(node_ptr), set requeue_pending_nodes = true, and break;
referencing the existing lp_status variable and the
stack.push_front(node_ptr)/requeue_pending_nodes/break sequence.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a1bddad0-abbf-4409-901c-017c5fabffd6

📥 Commits

Reviewing files that changed from the base of the PR and between 55fb9b9 and 0fed0c7.

📒 Files selected for processing (3)
  • cpp/src/branch_and_bound/branch_and_bound.cpp
  • cpp/src/mip_heuristics/diversity/lns/rins.cu
  • cpp/src/mip_heuristics/diversity/lns/rins.cuh

@nguidotti nguidotti left a comment

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.

Looks good to me! Thanks for the fix, Hugo.

@anandhkb anandhkb added this to the 26.06 milestone Apr 28, 2026
@hlinsen hlinsen added the non-breaking Introduces a non-breaking change label May 5, 2026
@github-actions

Copy link
Copy Markdown

🔔 Hi @anandhkb, this pull request has had no activity for 7 days. Please update or let us know if it can be closed. Thank you!

If this is an "epic" issue, then please add the "epic" label to this issue.
If it is a PR and not ready for review, then please convert this to draft.
If you just want to switch off this notification, then use the "skip inactivity reminder" label.

1 similar comment
@github-actions

Copy link
Copy Markdown

🔔 Hi @anandhkb, this pull request has had no activity for 7 days. Please update or let us know if it can be closed. Thank you!

If this is an "epic" issue, then please add the "epic" label to this issue.
If it is a PR and not ready for review, then please convert this to draft.
If you just want to switch off this notification, then use the "skip inactivity reminder" label.

@anandhkb anandhkb added the P0 label May 19, 2026
@hlinsen hlinsen changed the title Fix race condition in RINS and lost nodes in branch and bound Fix lost nodes in branch and bound May 19, 2026
@hlinsen

hlinsen commented May 19, 2026

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit 415b12d into NVIDIA:main May 19, 2026
189 of 191 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working non-breaking Introduces a non-breaking change P0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants