-
Notifications
You must be signed in to change notification settings - Fork 226
docs(grpc): document the VRP gRPC client (RoutingClient) #1838
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
10ab62e
4ed2462
23d2937
a728703
638389a
19c640a
89dba0e
da7eca1
6e2185c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,7 +24,10 @@ Add TLS or tuning variables from :doc:`advanced` if your deployment uses them. | |
|
|
||
| .. note:: | ||
|
|
||
| Routing solve over gRPC is not supported. For solving routing problems remotely today, use the HTTP/JSON :doc:`REST self-hosted server <../cuopt-server/index>` and :doc:`Examples <../cuopt-server/examples/index>`. | ||
| Routing does not read ``CUOPT_REMOTE_HOST``/``CUOPT_REMOTE_PORT`` -- | ||
| use the explicit :ref:`VRP gRPC client <cuopt-grpc-examples-routing>` | ||
| below, or the HTTP/JSON :doc:`REST self-hosted server <../cuopt-server/index>` | ||
| and :doc:`Examples <../cuopt-server/examples/index>`. | ||
|
|
||
| Where to Find Examples | ||
| ====================== | ||
|
|
@@ -70,6 +73,17 @@ without ``CUOPT_REMOTE_*``, use ``cuopt.grpc.linear_programming.Client``: | |
| * :doc:`python-async-client-examples` — log streaming and incumbent streaming | ||
| * :doc:`python-async-client-api` — API reference | ||
|
|
||
| Routing (VRP) | ||
| ------------- | ||
|
|
||
| .. _cuopt-grpc-examples-routing: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could we have a sample response here? I think we add it for other example files
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added — routing.rst's Connect and Solve section now has a sample-output block right after the demo's literalinclude, matching the convention from cuopt-python/routing/routing-examples.rst's TSP batch example. Labeled as illustrative rather than a captured run, since there's no GPU in this environment to actually execute it against, and VRP status/objective/route order aren't guaranteed stable across runs. |
||
|
|
||
| For VRP, TSP, and PDP problems, use ``cuopt.grpc.routing.RoutingClient`` -- | ||
| the same submit / wait / result / delete lifecycle, with no | ||
| ``CUOPT_REMOTE_*`` equivalent yet: | ||
|
|
||
| * :doc:`routing` — overview, API reference, and :download:`remote_routing_demo.py <examples/remote_routing_demo.py>` | ||
|
|
||
| Custom gRPC Client | ||
| ------------------ | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| """Minimal VRP demo for the NVIDIA cuOpt VRP gRPC client. | ||
|
|
||
| Unlike LP/MIP, routing has no ``CUOPT_REMOTE_HOST``/``CUOPT_REMOTE_PORT`` | ||
| transparent path yet -- build a :class:`cuopt.routing.DataModel` and solve it | ||
| with :class:`cuopt.grpc.routing.RoutingClient`, an explicit client (host and | ||
| port passed directly). | ||
|
|
||
| Start the server first:: | ||
|
|
||
| cuopt_grpc_server --port 5001 --workers 1 | ||
|
|
||
| Then:: | ||
|
|
||
| python remote_routing_demo.py | ||
| """ | ||
|
|
||
| import numpy as np | ||
| from cuopt import routing | ||
| from cuopt.grpc.routing import RoutingClient | ||
|
|
||
| dm = routing.DataModel(5, 2) | ||
| cost_matrix = np.array( | ||
| [ | ||
| [0, 1, 2, 2, 1], | ||
| [1, 0, 1, 2, 2], | ||
| [2, 1, 0, 1, 2], | ||
| [2, 2, 1, 0, 1], | ||
| [1, 2, 2, 1, 0], | ||
| ], | ||
| dtype=np.float32, | ||
| ) | ||
| dm.add_cost_matrix(cost_matrix) | ||
|
|
||
| client = RoutingClient("localhost", 5001) # tls=None uses CUOPT_TLS_* if set | ||
| solution = client.solve(dm, {"time_limit": 5.0}) | ||
|
|
||
| print("Status: ", solution["status_message"]) | ||
| print("Vehicles: ", solution["vehicle_count"]) | ||
| print("Objective: ", solution["total_objective_value"]) | ||
| print("Route: ", solution["route"]) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,148 @@ | ||
| .. | ||
| SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| ============================= | ||
| VRP gRPC Client (Routing) | ||
| ============================= | ||
|
|
||
| ``cuopt.grpc.routing.RoutingClient`` is an explicit gRPC client for solving | ||
| **VRP** (vehicle routing, including TSP and PDP) problems on | ||
| ``cuopt_grpc_server``. It uses the same job lifecycle as the LP/MIP | ||
| :doc:`Python async gRPC client <python-async-client>`: **submit** → **wait** | ||
| → **result** → **delete**, plus a **solve** convenience method that does all | ||
| four. | ||
|
|
||
| There is no ``CUOPT_REMOTE_HOST``/``CUOPT_REMOTE_PORT`` transparent path for | ||
| routing yet (unlike LP/MIP/QP) -- always construct ``RoutingClient`` with an | ||
| explicit host and port. See :ref:`Limitations and Roadmap | ||
| <cuopt-grpc-routing-limitations>` below. | ||
|
|
||
| Prerequisites | ||
| ============= | ||
|
|
||
| A running ``cuopt_grpc_server`` on a GPU host (see :doc:`quick-start`): | ||
|
|
||
| .. code-block:: bash | ||
|
|
||
| cuopt_grpc_server --port 5001 --workers 1 | ||
|
|
||
| Connect and Solve | ||
| ================== | ||
|
|
||
| ``RoutingClient(host, port, *, tls=None)`` takes the same arguments as the | ||
| LP/MIP client's ``Client(host, port, tls=...)``; see :doc:`python-async-client` | ||
| for the ``tls`` options. | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| ``RoutingClient.submit()`` accepts a :class:`cuopt.routing.DataModel` built | ||
| the same way as for a local :func:`cuopt.routing.Solve`. ``solve()`` submits, | ||
| waits, and deletes the job's server-side state when done (pass | ||
| ``delete=False`` to keep it around for a later ``result()`` call). | ||
|
|
||
| :download:`remote_routing_demo.py <examples/remote_routing_demo.py>` | ||
|
|
||
| .. literalinclude:: examples/remote_routing_demo.py | ||
| :language: python | ||
| :linenos: | ||
|
|
||
| Illustrative output (exact status text, vehicle count, objective, and route | ||
| order depend on the solver run and are not guaranteed to match): | ||
|
|
||
| .. code-block:: text | ||
|
|
||
| Status: Success | ||
| Vehicles: 1 | ||
| Objective: 5.0 | ||
| Route: [0 1 2 3 4 0] | ||
|
|
||
| Job Lifecycle | ||
| ============= | ||
|
|
||
| * ``submit(data_model, settings=None)`` — serializes the problem and settings, returns a ``job_id``. | ||
| * ``wait(job_id, timeout=0)`` — blocks until the job reaches a terminal state; returns the status. | ||
| * ``result(job_id)`` — returns the solution dict, or ``None`` if the job has not finished. | ||
| * ``delete(job_id)`` — releases the job's server-side result. | ||
| * ``solve(data_model, settings=None, *, timeout=0, delete=True)`` — submit + wait + result, deleting the job afterward unless ``delete=False``. | ||
|
|
||
| A failed or non-completed job raises ``RoutingSolveError`` from ``submit``, | ||
| ``wait``, or ``solve``. | ||
|
|
||
| Settings | ||
| ======== | ||
|
|
||
| ``settings`` accepts a ``dict`` or a :class:`cuopt.routing.SolverSettings`. | ||
| Today only ``time_limit`` is forwarded to the remote solve; other | ||
| ``SolverSettings`` options (``verbose``, ``error_logging``, | ||
| ``dump_best_results_path``/``interval``) are not yet mapped over gRPC (see | ||
| :ref:`Limitations and Roadmap <cuopt-grpc-routing-limitations>`). A ``dict`` | ||
| key other than ``time_limit`` is silently ignored rather than raising an | ||
| error. | ||
|
|
||
| Solution Fields | ||
| ================ | ||
|
|
||
| ``result()`` and ``solve()`` return a ``dict`` with the same fields as a | ||
| local :class:`cuopt.routing.Assignment`, read directly off the wire: | ||
|
|
||
| .. list-table:: | ||
| :header-rows: 1 | ||
|
|
||
| * - Key | ||
| - Description | ||
| * - ``status`` / ``status_message`` | ||
| - Integer and human-readable solve status. | ||
| * - ``error_message`` | ||
| - Set when the solve failed. | ||
| * - ``vehicle_count`` | ||
| - Number of vehicles used. | ||
| * - ``total_objective_value`` / ``objective_values`` | ||
| - Overall cost and the per-objective breakdown. | ||
| * - ``route``, ``truck_id``, ``locations``, ``node_types``, ``arrival_stamp`` | ||
| - Per-stop route arrays, one entry per stop across all vehicles. | ||
| * - ``unserviced_nodes`` | ||
| - Orders that cannot be served. | ||
| * - ``accepted`` | ||
| - Orders accepted, for prize-collection problems. | ||
|
|
||
| .. _cuopt-grpc-routing-limitations: | ||
|
|
||
| Limitations and Roadmap | ||
| ========================= | ||
|
|
||
| * **No transparent remote execution** — routing does not read | ||
| ``CUOPT_REMOTE_HOST``/``CUOPT_REMOTE_PORT``; always pass host and port to | ||
| ``RoutingClient`` explicitly. Tracked in `#1633 | ||
| <https://github.com/NVIDIA/cuopt/issues/1633>`_. | ||
| * **Settings surface** — only ``time_limit`` is forwarded today. Tracked in | ||
| `#1632 <https://github.com/NVIDIA/cuopt/issues/1632>`_. | ||
| * **No 2 GiB chunking** — VRP is unary-only; a cost/transit matrix or | ||
| ``RoutingSolution`` that exceeds the gRPC max message size cannot be sent | ||
| or retrieved (the LP/MIP client chunks automatically). Tracked in `#1629 | ||
| <https://github.com/NVIDIA/cuopt/issues/1629>`_. | ||
| * **No log or incumbent streaming** — unlike the LP/MIP client, there is no | ||
| ``start_log_stream``/``start_incumbent_stream`` equivalent yet. Tracked in | ||
| `#1630 <https://github.com/NVIDIA/cuopt/issues/1630>`_. | ||
| * **Input validation** — malformed problems may fail late or with a generic | ||
| error rather than an early, descriptive one. Tracked in `#1631 | ||
| <https://github.com/NVIDIA/cuopt/issues/1631>`_. | ||
|
|
||
| API Reference | ||
| ============= | ||
|
|
||
| Import path: ``cuopt.grpc.routing``. | ||
|
|
||
| .. autoclass:: cuopt.grpc.routing.RoutingClient | ||
| :members: | ||
| :undoc-members: | ||
|
|
||
| .. autoexception:: cuopt.grpc.routing.RoutingSolveError | ||
| :members: | ||
| :show-inheritance: | ||
|
|
||
| See Also | ||
| ======== | ||
|
|
||
| * :doc:`index` — when to use gRPC vs. the REST self-hosted server | ||
| * :doc:`python-async-client` — the LP/MIP/QP equivalent client | ||
| * :doc:`api` — how VRP rides ``CuOptRemoteService``'s RPCs | ||
| * :doc:`../cuopt-python/routing/index` — the local routing Python API | ||
Uh oh!
There was an error while loading. Please reload this page.