Skip to content

Patch Papilo to skip unchanged coefficients in sparsify - #2267

Open
ramakrishnap-nv wants to merge 1 commit into
NVIDIA:mainfrom
ramakrishnap-nv:fix-papilo-skip-unchanged-coeff
Open

ramakrishnap-nv wants to merge 1 commit into
NVIDIA:mainfrom
ramakrishnap-nv:fix-papilo-skip-unchanged-coeff

Conversation

@ramakrishnap-nv

@ramakrishnap-nv ramakrishnap-nv commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Description

SparseStorage::changeRow in Papilo called the coefficient-changed callback even when the merged value equalled the old one. The Sparsify activity update asserts the two differ, so a sub-MIP presolve aborted in builds with assertions on (the INCUMBENT_CALLBACK_TEST crash in mip_solve.initial_solution_survives_papilo_crush, seen in CI run 41664476906 on #2247).

This adds a small patch that only calls the callback when the value changes. Release builds are unaffected, since they have no asserts and an unchanged-value callback did nothing harmful.

I reproduced the crash about 1 in 100 runs on an assertion-enabled build of main. With the patch, 500 runs had no Papilo abort, and 4 runs hit the old condition and passed.

Upstream: scipopt/papilo#103 (issue) and scipopt/papilo#104 (PR). When a Papilo update includes it, this patch and the PATCH_COMMAND can be removed.

The other abort seen in those runs, current_incumbent.size() == leaf_problem.num_cols, is #1909 and is not changed here.

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

🤖 Generated with Claude Code

changeRow called the coefficient-changed callback even when the merged
value equalled the old one. The Sparsify activity update asserts that the
old and new coefficients differ, so sub-MIP presolve aborted in builds with
assertions on (INCUMBENT_CALLBACK_TEST, about 1 in 100 runs). Only call the
callback when the value changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@ramakrishnap-nv
ramakrishnap-nv requested review from a team as code owners November 3, 2026 21:48
@ramakrishnap-nv ramakrishnap-nv added this to the 27.02 milestone Nov 3, 2026
@ramakrishnap-nv ramakrishnap-nv added bug Something isn't working non-breaking Introduces a non-breaking change labels Nov 3, 2026
@coderabbitai

coderabbitai Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Walkthrough

The Papilo SparseStorage merge path now calls coeffChanged only when the merged coefficient differs from its previous value. CMake applies this patch to the fetched Papilo source.

Changes: Papilo callback guard

Layer / File(s) Summary
Guard coefficient-change callbacks
cpp/patches/papilo_skip_unchanged_coeff.patch, cpp/CMakeLists.txt
The patch checks whether newval differs from values[i] before calling coeffChanged. CMake applies the patch to the fetched Papilo source.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Possibly related PRs

  • NVIDIA/cuopt#2203: Changes the pinned Papilo revision and patch list in the same FetchContent_Declare block.

Suggested labels: bug, non-breaking

Suggested reviewers: kh4ster, tmckayus

Merge Risk: Minimal · up to c2fae

The intended Papilo callback guard and patch wiring introduce no identified merge-blocking risk.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title "Patch Papilo to skip unchanged coefficients in sparsify" matches the main change: a new patch to Papilo's SparseStorage so the coefficient-changed callback runs only when the merged value d…
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.
Description check Passed The description directly explains the Papilo patch, the unchanged-coefficient callback issue, the assertion failure, testing, and the intended upstream follow-up. It matches the changeset.
Full details: Title check

Explanation

The title "Patch Papilo to skip unchanged coefficients in sparsify" matches the main change: a new patch to Papilo's SparseStorage so the coefficient-changed callback runs only when the merged value differs from the old value. It names the patched library, the behavior change, and the context (sparsify). It is specific and does not include file lists or vague terms.

Finishing Touches
Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
Recent review info
Run configuration
  • Source mode: Auto
  • Repository: NVIDIA/cuopt
  • Branch: main
  • File: .coderabbit.yaml
  • Commit: 3d71290
  • Layers: Repository YAML
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: aad69a13-0e51-4f59-b0ae-46cf5e243d9f
Commits

Reviewing files that changed from the base of the PR and between 3d71290 and c2faefe.

Files selected for processing: 2
  • cpp/CMakeLists.txt
  • cpp/patches/papilo_skip_unchanged_coeff.patch

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

CI Test Summary

✅ All 21 test job(s) 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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants