cuOpt.jl MOI wrapper: unhandled 'Invalid argument' from GetPrimalSolution/GetDualSolution fails 36 conformance tests every nightly run

Aperta
#1,832 3 commenti 0 reazioni 1 assegnatario Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@rg20 ci sta già lavorando.

Dal 31/8/2026.

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

bug

Summary

cuOpt.jl's MOI wrapper optimize! unconditionally calls cuOptGetPrimalSolution/cuOptGetDualSolution after solving, without checking termination status first. This throws an "Invalid argument" C-API error (rather than returning gracefully) whenever:

  • the problem was declared infeasible/unbounded (often at presolve, so no primal solution buffer exists), or
  • the problem has quadratic/second-order-cone constraints (duals are documented as not returned for these: "Dual variables for problems with quadratic constraints not returned.")

This causes the thirdparty jump (Julia MOI conformance) test step to fail on every nightly wheel-tests-cuopt job, across all GPU/driver/dependency combinations, while all Python test suites (LP/MILP/QP/routing/classification) pass cleanly.

Observed in

Nightly test.yaml run 33361623272 (main @ d3af87e3, 2026-08-31) — all wheel-tests-cuopt matrix jobs report thirdparty jump as a failed step, consistently: 1397 passed, 0 failed, 36 errored, 0 broken.

This is not a one-off: test.yaml has failed with this same 36 errored Julia MOI signature on nearly every nightly run since at least 2026-08-13 (3+ weeks), e.g. runs 33295253627, 33237039486, 33154333403, 33053460319, 32936929656, 32814253431.

Distinct from the previously-fixed #1485 (a Julia 1.12.x JIT SIGSEGV on MOI.delete for bridged SOC constraints) — that was a crash bug fixed via an exclude list; this is a separate, still-open error-handling gap in the wrapper's result-fetching path (no crash, just an unhandled C-API error surfaced as a Julia test error).

Example stack trace

test_conic_SecondOrderCone_negative_initial_bound: Error During Test at .../MathOptInterface/Test/Test.jl:264
  Got exception outside of a @test
  Invalid argument in cuOptGetDualSolution.
  Stacktrace:
    [1] error(s::String) @ Base ./error.jl:44
    [2] _check_ret(ret::Int32, msg::String) @ cuOpt .../cuOpt.jl/src/MOI_wrapper.jl:438
    [3] optimize!(model::cuOpt.Optimizer) @ cuOpt .../cuOpt.jl/src/MOI_wrapper.jl:1316
test_infeasible_MAX_SENSE: Error During Test at .../MathOptInterface/Test/Test.jl:264
  Got exception outside of a @test
  Invalid argument in cuOptGetPrimalSolution.
  Stacktrace:
    [1] error(s::String) @ Base ./error.jl:44
    [2] _check_ret(ret::Int32, msg::String) @ cuOpt .../cuOpt.jl/src/MOI_wrapper.jl:438
    [3] optimize!(model::cuOpt.Optimizer) @ cuOpt .../cuOpt.jl/src/MOI_wrapper.jl:1307

Affected tests (36, same set every night)

test_conic_SecondOrderCone_negative_initial_bound
test_conic_SecondOrderCone_negative_post_bound
test_conic_SecondOrderCone_nonnegative_initial_bound
test_constraint_ZeroOne_bounds_3
test_infeasible_affine_MAX_SENSE
test_infeasible_affine_MAX_SENSE_offset
test_infeasible_affine_MIN_SENSE
test_infeasible_affine_MIN_SENSE_offset
test_infeasible_MAX_SENSE
test_infeasible_MAX_SENSE_offset
test_infeasible_MIN_SENSE
test_infeasible_MIN_SENSE_offset
test_linear_DUAL_INFEASIBLE
test_linear_DUAL_INFEASIBLE_2
test_linear_INFEASIBLE
test_linear_INFEASIBLE_2
test_linear_Semicontinuous_integration
test_modification_coef_scalar_objective
test_modification_const_scalar_objective
test_modification_delete_variables_in_a_batch
test_modification_set_singlevariable_lessthan
test_modification_transform_singlevariable_lessthan
test_objective_FEASIBILITY_SENSE_clears_objective
test_objective_ObjectiveFunction_constant
test_objective_ObjectiveFunction_duplicate_terms
test_objective_qp_ObjectiveFunction_edge_cases
test_objective_qp_ObjectiveFunction_zero_ofdiag
test_solve_ObjectiveBound_MAX_SENSE_LP
test_solve_ObjectiveBound_MIN_SENSE_LP
test_solve_TerminationStatus_DUAL_INFEASIBLE
test_unbounded_MAX_SENSE
test_unbounded_MAX_SENSE_offset
test_unbounded_MIN_SENSE
test_unbounded_MIN_SENSE_offset
test_variable_solve_with_lowerbound
test_variable_solve_with_upperbound

Suggested fix

In cuOpt.jl's optimize! (MOI_wrapper.jl, around lines 1300-1320), check the termination/solve status before calling cuOptGetPrimalSolution / cuOptGetDualSolution:

  • Skip primal retrieval when the reported status is infeasible/unbounded/presolve-determined.
  • Skip dual retrieval when the model has quadratic/SOC constraints (consistent with the documented C-API behavior).

Impact

Every nightly wheel-tests-cuopt job across all GPU/driver/dependency combinations is marked failed due to this, masking any other genuine regression in that same CI signal. All other nightly test suites (Python LP/MILP/QP/routing/classification) are green.

Lingua principale
Cuda
Stelle
1.1k
Fork
255
Merge medio
1g 11h
PR unite (30g)
123

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di NVIDIA/cuopt

Tutte le issue di NVIDIA/cuopt

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.