NVIDIA / NVIDIA/cuopt

[FEA] Routing validation: keep a structural 'simple error set' in Python, move semantic checks to C++

Open
#1,557 3 comments 0 reactions 1 assignee View on GitHub

@chris-maes is already working on this.

Since Jul 10, 2026.

awaiting response feature request
Dominant language
Cuda
Stars
1k
Forks
233
Avg merge
4d 4h
Merged PRs (30d)
95

Description

Is your feature request related to a problem? Please describe.

Routing input validation currently happens in two places: python/cuopt/cuopt/routing/validation.py re-checks things (null values, non-negative values, numeric ranges) that the C++ layer already validates authoritatively (e.g. "Cost matrix input cannot be null.", "Array contains negative or 0 values"). That is duplicated maintenance and can drift.

With store-then-build (PR for routing-cpu-api-phase2), the device model — and thus C++ validation — is built at solve time, which makes it natural to treat C++ as the single source of semantic validation.

Describe the solution you'd like

Draw a clean, non-overlapping boundary:

  • Python keeps a small "simple error set" — cheap, host-side, structural/type checks that catch silly mistakes early with clear messages and do not require building the device model:
    • reject Python lists/tuples; container/dtype type checks (C++ cannot — it only sees pointers),
    • matrix is square and dim == num_locations,
    • array/size consistency (order arrays == num_orders, vehicle arrays == fleet_size, pickup/delivery pairs equal length, capacity dims),
    • obvious sanity (num_locations >= 1, index-in-range).
  • C++ owns everything semantic/numeric (null, negative/zero, solver-specific bounds, feasibility). Remove the duplicated Python checks (_contains_null, validate_positive*, trim validate_range).

This removes the double-checking while preserving fast feedback on structural mistakes.

Additional context

  • Tests that currently assert Python validator messages at set-time (test_dist_mat, test_time_windows, test_range) move their pytest.raises to the Solve() call (as test_invalid_datamodel already does), except the structural ones which stay eager.
  • Before deleting a Python check, confirm C++ raises an equally clear message; otherwise improve the C++ message rather than lose it.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.