Skip to content

Conversation

@adityasinghz
Copy link

@adityasinghz adityasinghz commented Nov 24, 2025

Description

Added an explicit log message "Optimal solution found during presolve" that is displayed when the problem is fully reduced during presolve (i.e., when the problem is reduced to 0 constraints, 0 variables, and 0 nonzeros). This provides clear feedback to users that the optimal solution was discovered during presolve rather than through the main solving process.

Changes Made:

  • cpp/src/mip/solve.cu: Added log message when problem.empty is true before running the MIP solver
  • cpp/src/mip/solver.cu: Added log message in two locations:
    • When context.problem_ptr->empty is true before running presolve
    • When context.problem_ptr->empty becomes true after running presolve

Example Output:
Before this change, when the optimal solution was found during presolve, users would see:

Presolve status: reduced the problem
Presolve removed: 100 constraints, 200 variables, 560 nonzeros
Presolved problem: 0 constraints, 0 variables, 0 nonzeros
Best feasible: 37.000000

After this change, users will now see:

Presolve status: reduced the problem
Presolve removed: 100 constraints, 200 variables, 560 nonzeros
Presolved problem: 0 constraints, 0 variables, 0 nonzeros
Optimal solution found during presolve
Problem fully reduced in presolve
Best feasible: 37.000000

Issue #524

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

Summary by CodeRabbit

  • Bug Fixes
    • When preprocessing fully eliminates a problem (no rows or columns remain), the solver now clearly notifies that an optimal solution was found during presolve.
    • Improved presolve logging to make outcomes and solver status easier to interpret during initial processing.

✏️ Tip: You can customize this high-level summary in your review settings.

@adityasinghz adityasinghz requested a review from a team as a code owner November 24, 2025 08:04
@copy-pr-bot
Copy link

copy-pr-bot bot commented Nov 24, 2025

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.

Copy link
Contributor

@rg20 rg20 left a comment

Choose a reason for hiding this comment

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

Move the logic of checking if presolver found solution to presolve caller or presolve function itself.

Move the 'Optimal solution found during presolve' message to the
presolve function itself (third_party_presolve.cpp) where we can
accurately detect when presolve finds the optimal solution. This
ensures the message only appears when presolve actually found the
solution, not when the problem is empty for other reasons.

Removed the message from generic empty problem checks in:
- cpp/src/mip/solve.cu (run_mip function)
- cpp/src/mip/solver.cu (run_solver function - both locations)
@adityasinghz adityasinghz requested a review from rg20 November 24, 2025 14:35
@rg20 rg20 added improvement Improves an existing functionality non-breaking Introduces a non-breaking change labels Nov 24, 2025
@rg20 rg20 modified the milestone: 25.12 Nov 24, 2025
@rg20
Copy link
Contributor

rg20 commented Nov 24, 2025

/ok to test 527cd60

@rgsl888prabhu
Copy link
Collaborator

@adityasinghz Is this meant for 25.12 release or 26.02.

If it is meant for 25.12, may I request you to close this PR and use branch release/25.12 branch as your base and create a PR? And also choose merge branch to be 25.12.

@adityasinghz
Copy link
Author

Hi @rgsl888prabhu,

Thank you for the question. This is a user experience improvement (adding a log message when optimal solution is found during presolve), so I'm flexible on which release it targets.

Option 1: If this should go into 25.12:
I can rebase this onto release/25.12 and create a new PR targeting that branch. Should I proceed with this?

Option 2: If this can wait for 26.02:
I can keep the current PR targeting main (which will be part of 26.02).
Could you please let me know which release you'd prefer? I'm happy to adjust accordingly.

Thanks!

@rgsl888prabhu
Copy link
Collaborator

Lets move it to 26.2 since 25.12 is close to code freeze.

@coderabbitai
Copy link

coderabbitai bot commented Dec 3, 2025

📝 Walkthrough

Walkthrough

After presolve reductions are logged, the presolve routine now checks whether the problem has been reduced to zero rows and zero columns and logs "Optimal solution found during presolve" if so. Also updated header copyright year range.

Changes

Cohort / File(s) Summary
Presolve logging enhancement
cpp/src/mip/presolve/third_party_presolve.cpp
In third_party_presolve_t<i_t,f_t>::apply, after logging presolve reductions, added a check that when both row and column counts are zero it logs "Optimal solution found during presolve". Also extended header copyright year range to 2025-2026. No control-flow or behavior changes beyond logging.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a log message when presolve fully reduces the problem to zero rows and columns, indicating an optimal solution was found.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 17a7c33 and 1d85420.

📒 Files selected for processing (1)
  • cpp/src/mip/presolve/third_party_presolve.cpp
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{cu,cuh,cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

**/*.{cu,cuh,cpp,hpp,h}: Track GPU device memory allocations and deallocations to prevent memory leaks; ensure cudaMalloc/cudaFree balance and cleanup of streams/events
Validate algorithm correctness in optimization logic: simplex pivots, branch-and-bound decisions, routing heuristics, and constraint/objective handling must produce correct results
Check numerical stability: prevent overflow/underflow, precision loss, division by zero/near-zero, and use epsilon comparisons for floating-point equality checks
Validate correct initialization of variable bounds, constraint coefficients, and algorithm state before solving; ensure reset when transitioning between algorithm phases (presolve, simplex, diving, crossover)
Ensure variables and constraints are accessed from the correct problem context (original vs presolve vs folded vs postsolve); verify index mapping consistency across problem transformations
For concurrent CUDA operations (barriers, async operations), explicitly create and manage dedicated streams instead of reusing the default stream; document stream lifecycle
Eliminate unnecessary host-device synchronization (cudaDeviceSynchronize) in hot paths that blocks GPU pipeline; use streams and events for async execution
Assess algorithmic complexity for large-scale problems (millions of variables/constraints); ensure O(n log n) or better complexity, not O(n²) or worse
Verify correct problem size checks before expensive GPU/CPU operations; prevent resource exhaustion on oversized problems
Identify assertions with overly strict numerical tolerances that fail on legitimate degenerate/edge cases (near-zero pivots, singular matrices, empty problems)
Ensure race conditions are absent in multi-GPU code and multi-threaded server implementations; verify proper synchronization of shared state
Refactor code duplication in solver components (3+ occurrences) into shared utilities; for GPU kernels, use templated device functions to avoid duplication
Check that hard-coded GPU de...

Files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
**/*.{cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

**/*.{cpp,hpp,h}: Check for unclosed file handles when reading MPS/QPS problem files; ensure RAII patterns or proper cleanup in exception paths
Validate input sanitization to prevent buffer overflows and resource exhaustion attacks; avoid unsafe deserialization of problem files
Prevent thread-unsafe use of global and static variables; use proper mutex/synchronization in server code accessing shared solver state

Files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
**/*.{cu,cpp,hpp,h}

📄 CodeRabbit inference engine (.github/.coderabbit_review_guide.md)

Avoid inappropriate use of exceptions in performance-critical GPU operation paths; prefer error codes or CUDA error checking for latency-sensitive code

Files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
🧠 Learnings (17)
📓 Common learnings
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Validate algorithm correctness in optimization logic: simplex pivots, branch-and-bound decisions, routing heuristics, and constraint/objective handling must produce correct results
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Ensure variables and constraints are accessed from the correct problem context (original vs presolve vs folded vs postsolve); verify index mapping consistency across problem transformations

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Validate algorithm correctness in optimization logic: simplex pivots, branch-and-bound decisions, routing heuristics, and constraint/objective handling must produce correct results

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Refactor code duplication in solver components (3+ occurrences) into shared utilities; for GPU kernels, use templated device functions to avoid duplication

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Validate correct initialization of variable bounds, constraint coefficients, and algorithm state before solving; ensure reset when transitioning between algorithm phases (presolve, simplex, diving, crossover)

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Check that hard-coded GPU device IDs and resource limits are made configurable; abstract multi-backend support for different CUDA versions

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Verify correct problem size checks before expensive GPU/CPU operations; prevent resource exhaustion on oversized problems

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Identify assertions with overly strict numerical tolerances that fail on legitimate degenerate/edge cases (near-zero pivots, singular matrices, empty problems)

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Track GPU device memory allocations and deallocations to prevent memory leaks; ensure cudaMalloc/cudaFree balance and cleanup of streams/events

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Ensure race conditions are absent in multi-GPU code and multi-threaded server implementations; verify proper synchronization of shared state

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cpp,hpp,h} : Avoid inappropriate use of exceptions in performance-critical GPU operation paths; prefer error codes or CUDA error checking for latency-sensitive code

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Verify error propagation from CUDA to user-facing APIs is complete; ensure CUDA errors are caught and mapped to meaningful user error codes

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.cu : Verify race conditions and correctness of GPU kernel shared memory, atomics, and warp-level operations

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : Eliminate unnecessary host-device synchronization (cudaDeviceSynchronize) in hot paths that blocks GPU pipeline; use streams and events for async execution

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-11-25T10:20:49.822Z
Learnt from: CR
Repo: NVIDIA/cuopt PR: 0
File: .github/.coderabbit_review_guide.md:0-0
Timestamp: 2025-11-25T10:20:49.822Z
Learning: Applies to **/*.{cu,cuh,cpp,hpp,h} : For concurrent CUDA operations (barriers, async operations), explicitly create and manage dedicated streams instead of reusing the default stream; document stream lifecycle

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-12-04T04:11:12.640Z
Learnt from: chris-maes
Repo: NVIDIA/cuopt PR: 500
File: cpp/src/dual_simplex/scaling.cpp:68-76
Timestamp: 2025-12-04T04:11:12.640Z
Learning: In the cuOPT dual simplex solver, CSR/CSC matrices (including the quadratic objective matrix Q) are required to have valid dimensions and indices by construction. Runtime bounds checking in performance-critical paths like matrix scaling is avoided to prevent slowdowns. Validation is performed via debug-only check_matrix() calls wrapped in #ifdef CHECK_MATRIX.

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
📚 Learning: 2025-12-04T20:09:09.264Z
Learnt from: chris-maes
Repo: NVIDIA/cuopt PR: 602
File: cpp/src/linear_programming/solve.cu:732-742
Timestamp: 2025-12-04T20:09:09.264Z
Learning: In cpp/src/linear_programming/solve.cu, the barrier solver does not currently return INFEASIBLE or UNBOUNDED status. It only returns OPTIMAL, TIME_LIMIT, NUMERICAL_ISSUES, or CONCURRENT_LIMIT.

Applied to files:

  • cpp/src/mip/presolve/third_party_presolve.cpp
🔇 Additional comments (1)
cpp/src/mip/presolve/third_party_presolve.cpp (1)

441-444: LGTM! Clear user experience improvement.

The logic correctly identifies when presolve has fully reduced the problem to an optimal solution. Since infeasibility and unboundedness are already checked earlier (lines 427-430), an empty problem at this point (0 rows AND 0 columns) definitively indicates optimality with the objective value determined by the offset.

The placement after the presolve statistics makes the sequence intuitive: users first see the reduction results, then understand their meaning.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@adityasinghz
Copy link
Author

Hi @rgsl888prabhu
Thank you for asking. Since 25.12 is close to code freeze, I'd prefer to target this for the 26.02 release, so it can wait for the next release cycle.

I'll keep the current PR targeting main (which will be part of 26.02).

Thanks!

@github-actions
Copy link

🔔 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

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

@adityasinghz
Copy link
Author

Hi @rg20 @rgsl888prabhu , I have one additional request. If there is any task you would like to assign to me, please feel free to do so. I reviewed the issues section, but I am not certain whether the listed issues pertain to the current version or to upcoming releases.

Thank You!

@rgsl888prabhu
Copy link
Collaborator

rgsl888prabhu commented Dec 22, 2025

Hi @rg20 @rgsl888prabhu , I have one additional request. If there is any task you would like to assign to me, please feel free to do so. I reviewed the issues section, but I am not certain whether the listed issues pertain to the current version or to upcoming releases.

Thank You!

That would be awesome @adityasinghz, which part of library are you interested in? Please check the milestones in issues, normally they should highlight if they are slated for this release, and you can also ping if you are interested in any new issues/features or want to work on a other issues not meant for this release. We can always discuss and accommodate if feasible.

@github-actions
Copy link

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

@adityasinghz
Copy link
Author

adityasinghz commented Dec 31, 2025

Hi @rg20 @rgsl888prabhu ,

Thank you for the opportunity! I'm interested in contributing where I can.

Libraries I'm familiar with:

  • MIP library (cpp/src/mip/) - I've worked on presolve and logging improvements
  • Dual Simplex library (cpp/src/dual_simplex/) - I've worked on branch-and-bound code
  • Areas I'd like to explore: Linear Programming (PDLP), Routing, and CUDA implementations

What I'm looking for:

  • Tasks in MIP/Dual Simplex areas where I have experience
  • Issues involving CUDA
  • Bug fixes or improvements in areas I've worked on
  • I'm happy to start with manageable tasks and expand from there

I've checked the issues with milestones. If you have any tasks in the MIP/Dual Simplex libraries that you think would be a good fit, I'd appreciate the guidance. Otherwise, I can browse the issues and ask about specific ones before starting.

Thanks again!

@rgsl888prabhu
Copy link
Collaborator

/ok to test 17a7c33

@rgsl888prabhu
Copy link
Collaborator

/ok to test 5ba6418

@copy-pr-bot
Copy link

copy-pr-bot bot commented Jan 5, 2026

/ok to test 5ba6418

@rgsl888prabhu, there was an error processing your request: E2

See the following link for more information: https://docs.gha-runners.nvidia.com/cpr/e/2/

@rgsl888prabhu
Copy link
Collaborator

/ok to test 1d85420

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants