Skip to content

Commit 31cd9cd

Browse files
committed
Merge branch 'branch-25.05' into branch-25.08-merge-25.05
2 parents ff21913 + 13ca7f6 commit 31cd9cd

File tree

28 files changed

+283
-24
lines changed

28 files changed

+283
-24
lines changed

.github/workflows/build.yaml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,15 @@ jobs:
4747
date: ${{ inputs.date }}
4848
sha: ${{ inputs.sha }}
4949
script: ci/build_python.sh
50+
upload-conda:
51+
needs: [cpp-build, python-build]
52+
secrets: inherit
53+
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
54+
with:
55+
build_type: ${{ inputs.build_type || 'branch' }}
56+
branch: ${{ inputs.branch }}
57+
date: ${{ inputs.date }}
58+
sha: ${{ inputs.sha }}
5059
wheel-build-cuopt-mps-parser:
5160
secrets: inherit
5261
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
@@ -60,6 +69,17 @@ jobs:
6069
package-name: cuopt_mps_parser
6170
package-type: python
6271
append-cuda-suffix: false
72+
wheel-publish-cuopt-mps-parser:
73+
needs: wheel-build-cuopt-mps-parser
74+
secrets: inherit
75+
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
76+
with:
77+
build_type: ${{ inputs.build_type || 'branch' }}
78+
branch: ${{ inputs.branch }}
79+
sha: ${{ inputs.sha }}
80+
date: ${{ inputs.date }}
81+
package-name: cuopt_mps_parser
82+
package-type: python
6383
wheel-build-libcuopt:
6484
needs: wheel-build-cuopt-mps-parser
6585
secrets: inherit
@@ -73,6 +93,17 @@ jobs:
7393
package-name: libcuopt
7494
package-type: cpp
7595
matrix_filter: map(select((.CUDA_VER | startswith("12")) and .PY_VER == "3.12"))
96+
wheel-publish-libcuopt:
97+
needs: wheel-build-libcuopt
98+
secrets: inherit
99+
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
100+
with:
101+
build_type: ${{ inputs.build_type || 'branch' }}
102+
branch: ${{ inputs.branch }}
103+
sha: ${{ inputs.sha }}
104+
date: ${{ inputs.date }}
105+
package-name: libcuopt
106+
package-type: cpp
76107
wheel-build-cuopt:
77108
needs: [wheel-build-cuopt-mps-parser, wheel-build-libcuopt]
78109
secrets: inherit
@@ -86,6 +117,17 @@ jobs:
86117
script: ci/build_wheel_cuopt.sh
87118
package-name: cuopt
88119
package-type: python
120+
wheel-publish-cuopt:
121+
needs: wheel-build-cuopt
122+
secrets: inherit
123+
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
124+
with:
125+
build_type: ${{ inputs.build_type || 'branch' }}
126+
branch: ${{ inputs.branch }}
127+
sha: ${{ inputs.sha }}
128+
date: ${{ inputs.date }}
129+
package-name: cuopt
130+
package-type: python
89131
wheel-build-cuopt-server:
90132
needs: wheel-build-cuopt
91133
secrets: inherit
@@ -99,6 +141,17 @@ jobs:
99141
script: ci/build_wheel_cuopt_server.sh
100142
package-name: cuopt_server
101143
package-type: python
144+
wheel-publish-cuopt-server:
145+
needs: wheel-build-cuopt-server
146+
secrets: inherit
147+
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
148+
with:
149+
build_type: ${{ inputs.build_type || 'branch' }}
150+
branch: ${{ inputs.branch }}
151+
sha: ${{ inputs.sha }}
152+
date: ${{ inputs.date }}
153+
package-name: cuopt_server
154+
package-type: python
102155
#docs-build:
103156
# if: inputs.build_type == 'nightly' || github.ref_type == 'branch'
104157
# needs: [python-build]
@@ -127,6 +180,17 @@ jobs:
127180
package-name: cuopt_sh_client
128181
package-type: python
129182
append-cuda-suffix: false
183+
wheel-publish-cuopt-sh-client:
184+
needs: wheel-build-cuopt-sh-client
185+
secrets: inherit
186+
uses: rapidsai/shared-workflows/.github/workflows/[email protected]
187+
with:
188+
build_type: ${{ inputs.build_type || 'branch' }}
189+
branch: ${{ inputs.branch }}
190+
sha: ${{ inputs.sha }}
191+
date: ${{ inputs.date }}
192+
package-name: cuopt_sh_client
193+
package-type: python
130194
service-container:
131195
if: inputs.build_type == 'nightly'
132196
needs: [wheel-build-cuopt, wheel-build-cuopt-server]

.github/workflows/nightly.yaml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,15 @@ jobs:
2323
export DATE=$(date +%F)
2424
export SHA=$(gh api -q '.commit.sha' "repos/nvidia/cuopt/branches/${CUOPT_BRANCH}")
2525
26-
gh workflow run build.yaml \
26+
RUN_ID=$(gh workflow run build.yaml \
2727
-f branch=${CUOPT_BRANCH} \
2828
-f sha=${SHA} \
2929
-f date=${DATE} \
30-
-f build_type=nightly
30+
-f build_type=nightly \
31+
--json databaseId --jq '.databaseId')
32+
33+
# Wait for workflow to complete
34+
gh run watch $RUN_ID
3135
3236
trigger-test:
3337
runs-on: ubuntu-latest

README.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ For CUDA 12.x:
6363
pip install --extra-index-url=https://pypi.nvidia.com cuopt-server-cu12==25.5.* cuopt-sh-client==25.5.* nvidia-cuda-runtime-cu12==12.8.*
6464
```
6565

66+
Development wheels are available as nightlies, please update `--extra-index-url` to `https://pypi.anaconda.org/rapidsai-wheels-nightly/simple/` to install latest nightly packages.
67+
6668
### Conda
6769

6870
cuOpt can be installed with conda (via [miniforge](https://github.com/conda-forge/miniforge)) from the `nvidia` channel:
@@ -74,19 +76,22 @@ Users who are used to conda env based workflows would benefit with conda package
7476
For CUDA 12.x:
7577
```bash
7678
conda install -c rapidsai -c conda-forge -c nvidia \
77-
cuopt-server=25.05 cuopt-sh-client=25.05 python=3.12 cuda-version=12.8
79+
cuopt-server=25.05.* cuopt-sh-client=25.05.* python=3.12 cuda-version=12.8
7880
```
7981

8082
We also provide [nightly Conda packages](https://anaconda.org/rapidsai-nightly) built from the HEAD
81-
of our latest development branch.
83+
of our latest development branch. Just replace `-c rapidsai` with `-c rapidsai-nightly`.
8284

8385
### Container
8486

8587
Users can pull the cuOpt container from the NVIDIA container registry.
8688

8789
```bash
88-
docker pull nvidia/cuopt:25.5.0-cuda12.8-py312
90+
docker pull nvidia/cuopt:latest-cuda12.8-py312
8991
```
92+
93+
Note: The ``latest`` tag is the latest stable release of cuOpt. If you want to use a specific version, you can use the ``<version>-cuda12.8-py312`` tag. For example, to use cuOpt 25.5.0, you can use the ``25.5.0-cuda12.8-py312`` tag. Please refer to `cuOpt dockerhub page <https://hub.docker.com/r/nvidia/cuopt>`_ for the list of available tags.
94+
9095
More information about the cuOpt container can be found [here](https://docs.nvidia.com/cuopt/user-guide/latest/cuopt-server/quick-start.html#container-from-docker-hub).
9196

9297
Users who are using cuOpt for quick testing or research can use the cuOpt container. Alternatively, users who are planning to plug cuOpt as a service in their workflow can quickly start with the cuOpt container. But users are required to build security layers around the service to safeguard the service from untrusted users.

cpp/include/cuopt/linear_programming/constants.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@
5757
#define CUOPT_MIP_RELATIVE_GAP "mip_relative_gap"
5858
#define CUOPT_MIP_HEURISTICS_ONLY "mip_heuristics_only"
5959
#define CUOPT_MIP_SCALING "mip_scaling"
60-
#define CUOPT_SOL_FILE "solution_file"
60+
#define CUOPT_SOLUTION_FILE "solution_file"
6161
#define CUOPT_NUM_CPU_THREADS "num_cpu_threads"
62+
#define CUOPT_USER_PROBLEM_FILE "user_problem_file"
6263

6364
/* @brief LP/MIP termination status constants */
6465
#define CUOPT_TERIMINATION_STATUS_NO_TERMINATION 0

cpp/include/cuopt/linear_programming/mip/solver_settings.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class mip_solver_settings_t {
9292
bool log_to_console = true;
9393
std::string log_file;
9494
std::string sol_file;
95+
std::string user_problem_file;
9596

9697
/** Initial primal solution */
9798
std::shared_ptr<rmm::device_uvector<f_t>> initial_solution_;

cpp/include/cuopt/linear_programming/pdlp/solver_settings.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ class pdlp_solver_settings_t {
200200
bool log_to_console{true};
201201
std::string log_file{""};
202202
std::string sol_file{""};
203+
std::string user_problem_file{""};
203204
bool per_constraint_residual{false};
204205
bool crossover{false};
205206
bool save_best_primal_so_far{false};

cpp/include/cuopt/linear_programming/utilities/cython_solve.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ struct solver_ret_t {
103103
// Wrapper for solve to expose the API to cython.
104104

105105
std::unique_ptr<solver_ret_t> call_solve(cuopt::mps_parser::data_model_view_t<int, double>*,
106-
linear_programming::solver_settings_t<int, double>*);
106+
linear_programming::solver_settings_t<int, double>*,
107+
unsigned int flags = cudaStreamNonBlocking);
107108

108109
std::pair<std::vector<std::unique_ptr<solver_ret_t>>, double> call_batch_solve(
109110
std::vector<cuopt::mps_parser::data_model_view_t<int, double>*>,

cpp/src/dual_simplex/branch_and_bound.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,8 +463,10 @@ mip_status_t branch_and_bound_t<i_t, f_t>::solve(mip_solution_t<i_t, f_t>& solut
463463
global_variables::mutex_upper.unlock();
464464
// We should be done here
465465
uncrush_primal_solution(original_problem, original_lp, incumbent.x, solution.x);
466-
solution.objective = incumbent.objective;
467-
solution.lower_bound = lower_bound;
466+
solution.objective = incumbent.objective;
467+
solution.lower_bound = lower_bound;
468+
solution.nodes_explored = 0;
469+
solution.simplex_iterations = root_relax_soln.iterations;
468470
settings.log.printf("Optimal solution found at root node. Objective %.16e. Time %.2f.\n",
469471
compute_user_objective(original_lp, root_objective),
470472
toc(start_time));

cpp/src/linear_programming/solve.cu

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,11 @@ optimization_problem_solution_t<i_t, f_t> solve_lp(optimization_problem_t<i_t, f
569569
problem.presolve_data.objective_offset,
570570
problem.presolve_data.objective_scaling_factor);
571571

572+
if (settings.user_problem_file != "") {
573+
CUOPT_LOG_INFO("Writing user problem to file: %s", settings.user_problem_file.c_str());
574+
problem.write_as_mps(settings.user_problem_file);
575+
}
576+
572577
// Set the hyper-parameters based on the solver_settings
573578
if (use_pdlp_solver_mode) { set_pdlp_solver_mode(settings); }
574579

cpp/src/linear_programming/utilities/cython_solve.cu

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,13 @@ mip_ret_t call_solve_mip(
208208

209209
std::unique_ptr<solver_ret_t> call_solve(
210210
cuopt::mps_parser::data_model_view_t<int, double>* data_model,
211-
cuopt::linear_programming::solver_settings_t<int, double>* solver_settings)
211+
cuopt::linear_programming::solver_settings_t<int, double>* solver_settings,
212+
unsigned int flags)
212213
{
213214
raft::common::nvtx::range fun_scope("Call Solve");
214215

215216
cudaStream_t stream;
216-
RAFT_CUDA_TRY(cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking));
217+
RAFT_CUDA_TRY(cudaStreamCreateWithFlags(&stream, flags));
217218
const raft::handle_t handle_{stream};
218219

219220
auto op_problem = data_model_to_optimization_problem(data_model, solver_settings, &handle_);
@@ -283,9 +284,11 @@ std::pair<std::vector<std::unique_ptr<solver_ret_t>>, double> call_batch_solve(
283284
solver_settings->set_parameter(CUOPT_METHOD, CUOPT_METHOD_PDLP);
284285
}
285286

287+
// Use a default stream instead of a non-blocking to avoid invalid operations while some CUDA
288+
// Graph might be capturing in another stream
286289
#pragma omp parallel for num_threads(max_thread)
287290
for (std::size_t i = 0; i < size; ++i)
288-
list[i] = std::move(call_solve(data_models[i], solver_settings));
291+
list[i] = std::move(call_solve(data_models[i], solver_settings, cudaStreamDefault));
289292

290293
auto end = std::chrono::high_resolution_clock::now();
291294
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start_solver);

0 commit comments

Comments
 (0)