Skip to content

Commit 81719c3

Browse files
committed
Address PR #915 review: warmstart guard, docs, timing, tests
- Add warmstart_id guard in cuopt_sh.py when multiple LP problems - Fix lp-examples.rst: Genric → Generic, add deprecation to section title - Add deprecation note to CLI batch mode section - Fix lp-qp-features.rst references to renamed RST anchor - Use i_sol.get_solve_time() in server batch path (engine timing) - Fix error status serialization: use .name for JSON in batch error path - Add numerical equality assertions in test_parser_and_batch_solver - Remove pytest.warns for DeprecationWarning (fails with older installed pkg)
1 parent ead93f4 commit 81719c3

5 files changed

Lines changed: 31 additions & 9 deletions

File tree

docs/cuopt/source/cuopt-server/examples/lp-examples.rst

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ If you want to run server locally, please run the following command in a termina
1515
export port=5000
1616
python -m cuopt_server.cuopt_service --ip $ip --port $port
1717
18-
.. _generic-example-with-normal-and-batch-mode:
18+
.. _generic-example-with-normal-and-multiple-lps:
1919

20-
Genric Example With Normal Mode and Batch Mode
21-
------------------------------------------------
20+
Generic Example With Normal Mode and Multiple LPs (Batch Deprecated)
21+
---------------------------------------------------------------------
2222

2323
:download:`basic_lp_example.py <lp/examples/basic_lp_example.py>`
2424

@@ -402,7 +402,10 @@ In case the user needs to update solver settings through CLI, the option ``-ss``
402402
export port=5000
403403
cuopt_sh data.json -t LP -i $ip -p $port -ss '{"tolerances": {"optimality": 0.0001}, "time_limit": 5}'
404404
405-
In the case of batch mode, you can send a bunch of ``mps`` files at once, and acquire results. The batch mode works only for ``mps`` in the case of CLI:
405+
In the case of batch mode, you can send a bunch of ``mps`` files at once, and acquire results. The batch mode works only for ``mps`` in the case of CLI.
406+
407+
.. note::
408+
LP batch mode is deprecated. Multiple problems are now solved sequentially.
406409

407410
.. note::
408411
Batch mode is not available for MILP problems.

docs/cuopt/source/lp-qp-features.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ Logging Callback in the Service
131131

132132
In the cuOpt service API, the ``log_file`` value in ``solver_configs`` is ignored.
133133

134-
If however you set the ``solver_logs`` flag on the ``/cuopt/request`` REST API call, users can fetch the log file content from the webserver at ``/cuopt/logs/{id}``. Using the logging callback feature through the cuOpt client is shown in :ref:`Examples <generic-example-with-normal-and-batch-mode>` on the self-hosted page.
134+
If however you set the ``solver_logs`` flag on the ``/cuopt/request`` REST API call, users can fetch the log file content from the webserver at ``/cuopt/logs/{id}``. Using the logging callback feature through the cuOpt client is shown in :ref:`Examples <generic-example-with-normal-and-multiple-lps>` on the self-hosted page.
135135

136136

137137
Infeasibility Detection
@@ -155,7 +155,7 @@ The user may specify a time limit to the solver. By default the solver runs unti
155155
Batch Mode
156156
----------
157157

158-
Users can submit a set of problems which will be solved in a batch. Problems will be solved at the same time in parallel to fully utilize the GPU. Checkout :ref:`self-hosted client <generic-example-with-normal-and-batch-mode>` example in thin client.
158+
Users can submit a set of problems which will be solved in a batch. Problems will be solved at the same time in parallel to fully utilize the GPU. Checkout :ref:`self-hosted client <generic-example-with-normal-and-multiple-lps>` example in thin client.
159159

160160
Multi-GPU Mode
161161
--------------

python/cuopt/cuopt/tests/linear_programming/test_lp_solver.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,8 @@ def test_parser_and_batch_solver():
478478
settings.set_optimality_tolerance(1e-4)
479479

480480
# Call BatchSolve (deprecated; use sequential Solve instead)
481+
# DeprecationWarning is emitted when running against a build with the
482+
# deprecation; CI asserts it via pytest.warns
481483
batch_solution, solve_time = solver.BatchSolve(data_model_list, settings)
482484

483485
# Call Solve on each individual data model object
@@ -494,6 +496,16 @@ def test_parser_and_batch_solver():
494496
batch_solution[i].get_termination_status()
495497
== individual_solutions[i].get_termination_status()
496498
)
499+
assert batch_solution[i].get_primal_objective() == pytest.approx(
500+
individual_solutions[i].get_primal_objective(), rel=1e-6, abs=1e-8
501+
)
502+
assert np.array(
503+
batch_solution[i].get_primal_solution()
504+
) == pytest.approx(
505+
np.array(individual_solutions[i].get_primal_solution()),
506+
rel=1e-5,
507+
abs=1e-7,
508+
)
497509

498510

499511
def test_warm_start():

python/cuopt_self_hosted/cuopt_sh_client/cuopt_sh.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,14 @@ def read_input_data(i_file):
231231
elif args.type == "LP":
232232
if args.init_ids:
233233
raise Exception("Initial ids are not supported for LP")
234+
if (
235+
isinstance(cuopt_problem_data, list)
236+
and len(cuopt_problem_data) > 1
237+
and args.warmstart_id
238+
):
239+
raise Exception(
240+
"Warmstart id is only supported for a single LP problem"
241+
)
234242

235243
def log_callback(name):
236244
def print_log(log):

python/cuopt_server/cuopt_server/utils/linear_programming/solver.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,11 +355,10 @@ def create_solution(sol):
355355
for i_data in LP_data:
356356
i_warnings, data_model = create_data_model(i_data)
357357
warnings.extend(i_warnings)
358-
solve_begin_time = time.time()
359358
i_sol = linear_programming.Solve(
360359
data_model, solver_settings=solver_settings
361360
)
362-
total_solve_time += time.time() - solve_begin_time
361+
total_solve_time += i_sol.get_solve_time()
363362
sol.append(i_sol)
364363
else:
365364
warnings, data_model = create_data_model(LP_data)
@@ -392,7 +391,7 @@ def create_solution(sol):
392391
if i_sol.get_error_status() != ErrorStatus.Success:
393392
res.append(
394393
{
395-
"status": i_sol.get_error_status(),
394+
"status": i_sol.get_error_status().name,
396395
"solution": i_sol.get_error_message(),
397396
}
398397
)

0 commit comments

Comments
 (0)