Skip to content

Fix concurrent root halt on infeasible MILP - #1413

Closed
Rohithmatham12 wants to merge 1 commit into
NVIDIA:mainfrom
Rohithmatham12:fix-cudss-root-interrupt
Closed

Fix concurrent root halt on infeasible MILP#1413
Rohithmatham12 wants to merge 1 commit into
NVIDIA:mainfrom
Rohithmatham12:fix-cudss-root-interrupt

Conversation

@Rohithmatham12

Copy link
Copy Markdown

Summary

  • Signal the root concurrent halt flag when the root dual-simplex task returns a terminal LP status in concurrent root solve.
  • Leave CONCURRENT_LIMIT unchanged, since that means another concurrent solver already requested the stop.
  • Add a cuopt_cli regression that generates an infeasible 120-binary MPS and checks default opportunistic mode returns Infeasible instead of aborting.

Why

  • [BUG] std::terminate (process abort) on an infeasible MILP in opportunistic (default) mode #1396 reproduces as a default opportunistic cuopt_cli abort on an infeasible MILP, while deterministic mode returns Infeasible.
  • The concurrent root path only signaled root_concurrent_halt_ on the crossover-OPTIMAL path. When dual simplex proved infeasibility before crossover produced a solution, the concurrent PDLP/barrier/cuDSS side could remain active into teardown.
  • This matches the existing standalone concurrent LP pattern, where terminal dual-simplex/barrier statuses signal concurrent_halt so peer solvers stop cleanly.

Testing

  • /opt/homebrew/opt/llvm/bin/clang-format -i cpp/src/branch_and_bound/branch_and_bound.cpp
  • bash -n python/libcuopt/libcuopt/tests/test_cli.sh
  • git diff --check

Fixes #1396

@copy-pr-bot

copy-pr-bot Bot commented Jun 9, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@Rohithmatham12

Copy link
Copy Markdown
Author

Hi maintainers, the label checker is waiting for category/breaking labels. Suggested labels for this PR: bug, non-breaking, mip.

This is a fresh, narrow root-cause PR for #1396: it only changes concurrent root-solve halt coordination and adds a default-opportunistic cuopt_cli regression for the infeasible MPS crash path.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 39636acc-8de5-4c66-b6f7-e93a2f27d32c

📥 Commits

Reviewing files that changed from the base of the PR and between 3f3e4c1 and 7dd1aa5.

📒 Files selected for processing (2)
  • cpp/src/branch_and_bound/branch_and_bound.cpp
  • python/libcuopt/libcuopt/tests/test_cli.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • cpp/src/branch_and_bound/branch_and_bound.cpp

📝 Walkthrough

Walkthrough

The root LP solve now requests the concurrent-halt flag for all terminal LP statuses immediately after solving; a new CLI regression test verifies an infeasible MILP returns "Termination Status: Infeasible" in opportunistic concurrent mode.

Changes

Concurrent root-halt signal on terminal LP status

Layer / File(s) Summary
Root concurrent-halt trigger on terminal LP status
cpp/src/branch_and_bound/branch_and_bound.cpp
A helper lambda request_root_concurrent_halt maps terminal LP statuses (optimal, infeasible/unbounded, iteration/time/work limits, numerical issues, cut-off) to set_root_concurrent_halt(1) and is called immediately after the root LP solve, before the taskwait join.
Infeasible MILP regression test
python/libcuopt/libcuopt/tests/test_cli.sh
Adds a CLI test that generates an infeasible MILP, runs cuopt_cli with a time limit in opportunistic mode, and asserts the solver prints Termination Status: Infeasible.

🎯 2 (Simple) | ⏱️ ~10 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
Title check ✅ Passed The title clearly describes the main fix: signaling the root concurrent halt flag when handling infeasible MILPs.
Description check ✅ Passed The description comprehensively explains the problem, solution, rationale, and testing approach, all directly related to the changeset.
Linked Issues check ✅ Passed The PR fully addresses issue #1396 by signaling root_concurrent_halt on terminal LP statuses and adding a regression test for the infeasible MILP abort scenario.
Out of Scope Changes check ✅ Passed All changes (internal helper in branch_and_bound.cpp and CLI regression test) are directly scoped to fixing the concurrent root halt issue for infeasible MILPs.

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

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

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Infer (1.2.0)
cpp/src/branch_and_bound/branch_and_bound.cpp

cpp/src/branch_and_bound/branch_and_bound.cpp:8:10: fatal error: 'branch_and_bound/branch_and_bound.hpp' file not found
8 | #include <branch_and_bound/branch_and_bound.hpp>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Error: the following clang command did not run successfully:
/opt/infer-linux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/bin/clang-18
@/tmp/coderabbit-infer/7dd1aa58810237d8d28c9fe3c30f2d3fa75bee42-df26eec8343bec84/tmp/clang_command_.tmp.574770.txt
++Contents of '/tmp/coderabbit-infer/7dd1aa58810237d8d28c9fe3c30f2d3fa75bee42-df26eec8343bec84/tmp/clang_command_.tmp.574770.txt':
"-cc1" "-load"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../../facebook-clang-plugins/libtooling/build/FacebookClangPlugin.dylib"
"-add-plugin" "BiniouASTExporter" "-plugin-arg-BiniouASTExporter" "-"
"-plugin-arg-BiniouASTExporter" "PREPEND_CURRENT_DIR=1"
"-plugin-arg-BiniouASTExporter" "MAX_STRING_SIZE=6553

... [truncated 1187 characters] ...

nclude"
"-internal-isystem" "/usr/local/include" "-internal-isystem"
"/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
"-internal-externc-isystem" "/usr/include/x86_64-linux-gnu"
"-internal-externc-isystem" "/include" "-internal-externc-isystem"
"/usr/include" "-Wno-ignored-optimization-argument" "-Wno-everything"
"-fdeprecated-macro" "-ferror-limit" "19" "-fgnuc-version=4.2.1"
"-fskip-odr-check-in-gmf" "-fcxx-exceptions" "-fexceptions"
"-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o"
"/tmp/coderabbit-infer/df26eec8343bec84/file.o" "-x" "c++"
"cpp/src/branch_and_bound/branch_and_bound.cpp" "-O0" "-fno-builtin"
"-include"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../lib/clang_wrappers/global_defines.h"
"-Wno-everything"


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)
python/libcuopt/libcuopt/tests/test_cli.sh (1)

35-68: ⚡ Quick win

Pin opportunistic mode explicitly in the regression assertion.

This regression targets the opportunistic concurrent-root path, but the invocation relies on default mode. Please force opportunistic mode and check the status line explicitly so the test keeps covering the intended failure mode even if defaults change.

Suggested update
-cuopt_cli "${tmp_mps}" --time-limit 30 | grep -q "Infeasible" || (echo "Expected infeasible status for opportunistic MILP" && exit 1)
+cuopt_cli "${tmp_mps}" --mip-determinism-mode 0 --time-limit 30 \
+  | grep -q "Status: Infeasible" \
+  || (echo "Expected infeasible status for opportunistic MILP" && exit 1)

As per coding guidelines, regression tests here should validate the specific failure mode and status/exit path for this concurrent-root bug class.

🤖 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 `@python/libcuopt/libcuopt/tests/test_cli.sh` around lines 35 - 68, Update the
test invocation that currently runs cuopt_cli ("cuopt_cli \"${tmp_mps}\"
--time-limit 30 | grep -q \"Infeasible\"") to explicitly pass the CLI flag that
forces opportunistic concurrent-root mode (add the project’s opportunistic-mode
flag to the cuopt_cli invocation) and tighten the assertion to check the solver
status line explicitly (grep for the status output that contains "Infeasible"
rather than relying on defaults). Locate the invocation of cuopt_cli and the
grep assertion in the test script (the tmp_mps creation and the final pipeline)
and modify those two pieces: add the opportunistic-mode option to the cuopt_cli
command and ensure the grep matches the solver status line text.

Source: Coding guidelines

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

Nitpick comments:
In `@python/libcuopt/libcuopt/tests/test_cli.sh`:
- Around line 35-68: Update the test invocation that currently runs cuopt_cli
("cuopt_cli \"${tmp_mps}\" --time-limit 30 | grep -q \"Infeasible\"") to
explicitly pass the CLI flag that forces opportunistic concurrent-root mode (add
the project’s opportunistic-mode flag to the cuopt_cli invocation) and tighten
the assertion to check the solver status line explicitly (grep for the status
output that contains "Infeasible" rather than relying on defaults). Locate the
invocation of cuopt_cli and the grep assertion in the test script (the tmp_mps
creation and the final pipeline) and modify those two pieces: add the
opportunistic-mode option to the cuopt_cli command and ensure the grep matches
the solver status line text.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3af57071-7f24-44a9-befe-19d303555774

📥 Commits

Reviewing files that changed from the base of the PR and between dcb97b7 and 3f3e4c1.

📒 Files selected for processing (2)
  • cpp/src/branch_and_bound/branch_and_bound.cpp
  • python/libcuopt/libcuopt/tests/test_cli.sh

@Rohithmatham12
Rohithmatham12 force-pushed the fix-cudss-root-interrupt branch from 3f3e4c1 to 7dd1aa5 Compare June 9, 2026 23:14
@mlubin

mlubin commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Closing in favor of #1416 which better addresses the root cause.

@mlubin mlubin closed this Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] std::terminate (process abort) on an infeasible MILP in opportunistic (default) mode

2 participants