Skip to content

Conversation

@tmckayus
Copy link
Contributor

@tmckayus tmckayus commented Dec 8, 2025

The openapi spec for the status value in lp/mip results says "int" but it is actually a string. This change corrects that.

Unfortunately, the enums defining the values cannot be directly imported because the import causes early cuda initialization which leads to rmm errors.

So, this change uses local copies and then adds a unit test to make sure they don't drift.

Summary by CodeRabbit

Release Notes

  • New Features

    • Termination status values in API responses are now human-readable strings (e.g., "Optimal", "Infeasible") instead of numeric codes.
    • Added validation to ensure termination status values are valid.
  • Tests

    • Added verification test for termination status enumerations synchronization.

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

@tmckayus tmckayus requested a review from a team as a code owner December 8, 2025 21:30
@tmckayus tmckayus added the bug Something isn't working label Dec 8, 2025
@tmckayus tmckayus self-assigned this Dec 8, 2025
@tmckayus tmckayus added this to the 25.12 milestone Dec 8, 2025
@tmckayus tmckayus added the non-breaking Introduces a non-breaking change label Dec 8, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 8, 2025

📝 Walkthrough

Walkthrough

This PR refactors termination status handling from numeric codes to string-based names with validation. It introduces status name collections and a validation function in the data definition module, updates the SolutionResultData schema to enforce validated string statuses, and adds a synchronization test to verify alignment between local status collections and enums.

Changes

Cohort / File(s) Change Summary
Test synchronization
python/cuopt_server/cuopt_server/tests/test_lp.py
Adds new test function test_termination_status_enum_sync() that verifies LP and MILP status name collections remain synchronized with their corresponding enum definitions.
Status validation infrastructure
python/cuopt_server/cuopt_server/utils/linear_programming/data_definition.py
Introduces LP_STATUS_NAMES, MILP_STATUS_NAMES, and ALL_STATUS_NAMES frozensets; adds validate_termination_status() validator function; refactors SolutionResultData.status field from int to Annotated[str, PlainValidator(...)] with default "NoTermination"; updates LP and MILP example responses to use string statuses instead of numeric codes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Areas requiring attention:

  • Verify LP_STATUS_NAMES and MILP_STATUS_NAMES frozensets contain all valid status values and match corresponding enum definitions
  • Confirm the schema change from int to Annotated[str, PlainValidator(...)] doesn't break existing API contracts or client expectations
  • Validate that example data updates cover all documented status scenarios
  • Review validator function for edge cases (None, empty strings, case sensitivity)

Pre-merge checks and finishing touches

✅ Passed checks (3 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: correcting the status field definition in the LP result specification from integer to string type.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
python/cuopt_server/cuopt_server/utils/linear_programming/data_definition.py (1)

949-1010: Example responses now match string-based statuses; duplicate milp_response is dead code

Updating the example lp_response/milp_response status fields to "Optimal" / "FeasibleFound" keeps them consistent with the new string-based status definition and the runtime behavior validated in test_lp.

Note that milp_response is defined twice in this module; the second definition overwrites the first, so the first is effectively dead code. Not new to this PR, but you could drop the duplicate in a follow-up to avoid confusion.

📜 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 b3cdd00 and 237e12b.

📒 Files selected for processing (2)
  • python/cuopt_server/cuopt_server/tests/test_lp.py (1 hunks)
  • python/cuopt_server/cuopt_server/utils/linear_programming/data_definition.py (4 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{h,hpp,py}

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

Verify C API does not break ABI stability (no struct layout changes, field reordering); maintain backward compatibility in Python and server APIs with deprecation warnings

Files:

  • python/cuopt_server/cuopt_server/tests/test_lp.py
  • python/cuopt_server/cuopt_server/utils/linear_programming/data_definition.py
**/*test*.{cpp,cu,py}

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

**/*test*.{cpp,cu,py}: Write tests validating numerical correctness of optimization results (not just 'runs without error'); test degenerate cases (infeasible, unbounded, empty, singleton problems)
Ensure test isolation: prevent GPU state, cached memory, and global variables from leaking between test cases; verify each test independently initializes its environment
Add tests for algorithm phase transitions: verify correct initialization of bounds and state when transitioning from presolve to simplex to diving to crossover
Add tests for problem transformations: verify correctness of original→transformed→postsolve mappings and index consistency across problem representations
Test with free variables, singleton problems, and extreme problem dimensions near resource limits to validate edge case handling

Files:

  • python/cuopt_server/cuopt_server/tests/test_lp.py
🧬 Code graph analysis (1)
python/cuopt_server/cuopt_server/utils/linear_programming/data_definition.py (3)
python/cuopt_server/cuopt_server/utils/routing/data_definition.py (1)
  • StrictModel (23-25)
python/cuopt_server/cuopt_server/utils/data_definition.py (1)
  • StrictModel (50-52)
python/cuopt_self_hosted/cuopt_sh_client/cuopt_self_host_client.py (1)
  • status (985-1008)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.13, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.12, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.10, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.11, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.11, arm64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.12, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.10, amd64, rockylinux8
  • GitHub Check: wheel-build-cuopt-mps-parser / 13.0.2, 3.13, amd64, rockylinux8
  • GitHub Check: checks / check-style
🔇 Additional comments (2)
python/cuopt_server/cuopt_server/tests/test_lp.py (1)

216-241: Good safeguard to keep local status-name sets in sync with enums

This test cleanly enforces that LP_STATUS_NAMES and MILP_STATUS_NAMES track the solver enums without reintroducing the CUDA/RMM-init issue in data_definition. The explicit mismatch messages will make future drift easy to diagnose.

python/cuopt_server/cuopt_server/utils/linear_programming/data_definition.py (1)

813-883: Add deprecation pathway for non-string status values if prior code accepts enums

The status-name sets and validator are logically correct, but this change breaks any code paths that construct SolutionResultData with non-string statuses (enums, ints). Per coding guidelines, backward compatibility in Python APIs requires deprecation warnings. Before merging, confirm:

  • Whether prior versions accepted enum/int statuses and code paths need a deprecation bridge (e.g., accept enums, coerce to .name, warn)
  • If string-only is truly backward compatible across all call sites

Additionally, if surfacing allowed statuses in OpenAPI schema is desired, attach enum via json_schema_extra using sorted(ALL_STATUS_NAMES).

@tmckayus
Copy link
Contributor Author

tmckayus commented Dec 8, 2025

Address #667

@rgsl888prabhu
Copy link
Collaborator

/merge

@rapids-bot rapids-bot bot merged commit 04b8dc2 into NVIDIA:release/25.12 Dec 9, 2025
183 of 185 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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants