Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
name = "cuOpt"
uuid = "29a73d17-8276-40b7-9ffb-d89e58023643"
authors = ["Rajesh Gandham <rgandham@nvidia.com>", "Ramakrishna Prabhu <ramakrishnap@nvidia.com>"]
version = "0.1.1"
version = "0.2.0"

[deps]
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ To use cuOpt.jl, you must first separately install cuOpt.

**Installing cuOpt requires Linux.**

Note: This version of cuOpt.jl supports the Nvidia cuOpt 25.08 and 25.10 releases.
Note: This version of cuOpt.jl supports the Nvidia cuOpt 25.08, 25.10, and 25.12 releases.

Please refer to the [NVIDIA cuOpt documentation](https://docs.nvidia.com/cuopt/user-guide/latest/cuopt-c/quick-start.html#installation) for installation instructions.

Expand All @@ -48,7 +48,7 @@ Pkg.add("cuOpt")

To install cuOpt on [Google Colab](https://colab.research.google.com), do:
```julia
julia> cmd = run(`pip install --extra-index-url=https://pypi.nvidia.com libcuopt-cu12==25.8.\* nvidia-cuda-runtime-cu12==12.8.\*`);
julia> cmd = run(`pip install --extra-index-url=https://pypi.nvidia.com libcuopt-cu12==25.12.\* nvidia-cuda-runtime-cu12==12.8.\*`);

julia> push!(Base.DL_LOAD_PATH, "/usr/local/lib/python3.12/dist-packages/libcuopt/lib64")
```
Expand Down
2 changes: 1 addition & 1 deletion src/cuOpt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ function __init__()
error("Failed to get cuOpt library version (status code: $status)")
end
version = VersionNumber(major[], minor[], patch[])
min, max = v"25.08", v"25.11"
min, max = v"25.08", v"25.13"
if !(min <= version < max)
error(
"Incompatible cuOpt library version. Got $version, but supported versions are [$min, $max)",
Expand Down
83 changes: 78 additions & 5 deletions src/gen/libcuopt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ The type of the integer number used by the solver. Use `[`cuOptGetIntSize`](@ref
"""
const cuopt_int_t = Int32

# no prototype is found for this function at cuopt_c.h:89:8, please use with caution
# no prototype is found for this function at cuopt_c.h:79:8, please use with caution
"""
cuOptGetFloatSize()

Expand All @@ -54,7 +54,7 @@ function cuOptGetFloatSize()
ccall((:cuOptGetFloatSize, libcuopt), Int8, ())
end

# no prototype is found for this function at cuopt_c.h:94:8, please use with caution
# no prototype is found for this function at cuopt_c.h:84:8, please use with caution
"""
cuOptGetIntSize()

Expand Down Expand Up @@ -104,9 +104,9 @@ end
Create an optimization problem of the form

```c++
minimize/maximize cᵀx + offset
subject to A x {=, ≤, ≥} b
l x u
minimize/maximize c^T x + offset
subject to A x {=, <=, >=} b
l <= x <= u
x_i integer for some i
```

Expand Down Expand Up @@ -166,6 +166,76 @@ function cuOptCreateRangedProblem(num_constraints, num_variables, objective_sens
ccall((:cuOptCreateRangedProblem, libcuopt), cuopt_int_t, (cuopt_int_t, cuopt_int_t, cuopt_int_t, cuopt_float_t, Ptr{cuopt_float_t}, Ptr{cuopt_int_t}, Ptr{cuopt_int_t}, Ptr{cuopt_float_t}, Ptr{cuopt_float_t}, Ptr{cuopt_float_t}, Ptr{cuopt_float_t}, Ptr{cuopt_float_t}, Ptr{Cchar}, Ptr{cuOptOptimizationProblem}), num_constraints, num_variables, objective_sense, objective_offset, objective_coefficients, constraint_matrix_row_offsets, constraint_matrix_column_indices, constraint_matrix_coefficients, constraint_lower_bounds, constraint_upper_bounds, variable_lower_bounds, variable_upper_bounds, variable_types, problem_ptr)
end

"""
cuOptCreateQuadraticProblem(num_constraints, num_variables, objective_sense, objective_offset, objective_coefficients, quadratic_objective_matrix_row_offsets, quadratic_objective_matrix_column_indices, quadratic_objective_matrix_coefficent_values, constraint_matrix_row_offsets, constraint_matrix_column_indices, constraint_matrix_coefficent_values, constraint_sense, rhs, lower_bounds, upper_bounds, problem_ptr)

Create an optimization problem of the form

```c++
minimize/maximize c^T x + x^T Q x + offset
subject to A x {=, <=, >=} b
l ≤ x ≤ u
```

# Arguments
* `num_constraints`:\\[in\\] The number of constraints
* `num_variables`:\\[in\\] The number of variables
* `objective_sense`:\\[in\\] The objective sense ([`CUOPT_MINIMIZE`](@ref) for minimization or [`CUOPT_MAXIMIZE`](@ref) for maximization)
* `objective_offset`:\\[in\\] An offset to add to the linear objective
* `objective_coefficients`:\\[in\\] A pointer to an array of type [`cuopt_float_t`](@ref) of size num\\_variables containing the coefficients of the linear objective
* `quadratic_objective_matrix_row_offsets`:\\[in\\] A pointer to an array of type [`cuopt_int_t`](@ref) of size num\\_variables + 1. quadratic\\_objective\\_matrix\\_row\\_offsets[i] is the index of the first non-zero element of the i-th row of the quadratic objective matrix in quadratic\\_objective\\_matrix\\_column\\_indices and quadratic\\_objective\\_matrix\\_coefficent\\_values. This is part of the compressed sparse row representation of the quadratic objective matrix.
* `quadratic_objective_matrix_column_indices`:\\[in\\] A pointer to an array of type [`cuopt_int_t`](@ref) of size quadratic\\_objective\\_matrix\\_row\\_offsets[num\\_variables] containing the column indices of the non-zero elements of the quadratic objective matrix. This is part of the compressed sparse row representation of the quadratic objective matrix.
* `quadratic_objective_matrix_coefficent_values`:\\[in\\] A pointer to an array of type [`cuopt_float_t`](@ref) of size quadratic\\_objective\\_matrix\\_row\\_offsets[num\\_variables] containing the values of the non-zero elements of the quadratic objective matrix.
* `constraint_matrix_row_offsets`:\\[in\\] A pointer to an array of type [`cuopt_int_t`](@ref) of size num\\_constraints + 1. constraint\\_matrix\\_row\\_offsets[i] is the index of the first non-zero element of the i-th constraint in constraint\\_matrix\\_column\\_indices and constraint\\_matrix\\_coefficent\\_values. This is part of the compressed sparse row representation of the constraint matrix
* `constraint_matrix_column_indices`:\\[in\\] A pointer to an array of type [`cuopt_int_t`](@ref) of size constraint\\_matrix\\_row\\_offsets[num\\_constraints] containing the column indices of the non-zero elements of the constraint matrix. This is part of the compressed sparse row representation of the constraint matrix
* `constraint_matrix_coefficent_values`:\\[in\\] A pointer to an array of type [`cuopt_float_t`](@ref) of size constraint\\_matrix\\_row\\_offsets[num\\_constraints] containing the values of the non-zero elements of the constraint matrix. This is part of the compressed sparse row representation of the constraint matrix
* `constraint_sense`:\\[in\\] A pointer to an array of type char of size num\\_constraints containing the sense of the constraints ([`CUOPT_LESS_THAN`](@ref), [`CUOPT_GREATER_THAN`](@ref), or [`CUOPT_EQUAL`](@ref))
* `rhs`:\\[in\\] A pointer to an array of type [`cuopt_float_t`](@ref) of size num\\_constraints containing the right-hand side of the constraints
* `lower_bounds`:\\[in\\] A pointer to an array of type [`cuopt_float_t`](@ref) of size num\\_variables containing the lower bounds of the variables
* `upper_bounds`:\\[in\\] A pointer to an array of type [`cuopt_float_t`](@ref) of size num\\_variables containing the upper bounds of the variables
* `problem_ptr`:\\[out\\] Pointer to store the created optimization problem
# Returns
[`CUOPT_SUCCESS`](@ref) if successful, CUOPT\\_ERROR otherwise
"""
function cuOptCreateQuadraticProblem(num_constraints, num_variables, objective_sense, objective_offset, objective_coefficients, quadratic_objective_matrix_row_offsets, quadratic_objective_matrix_column_indices, quadratic_objective_matrix_coefficent_values, constraint_matrix_row_offsets, constraint_matrix_column_indices, constraint_matrix_coefficent_values, constraint_sense, rhs, lower_bounds, upper_bounds, problem_ptr)
ccall((:cuOptCreateQuadraticProblem, libcuopt), cuopt_int_t, (cuopt_int_t, cuopt_int_t, cuopt_int_t, cuopt_float_t, Ptr{cuopt_float_t}, Ptr{cuopt_int_t}, Ptr{cuopt_int_t}, Ptr{cuopt_float_t}, Ptr{cuopt_int_t}, Ptr{cuopt_int_t}, Ptr{cuopt_float_t}, Ptr{Cchar}, Ptr{cuopt_float_t}, Ptr{cuopt_float_t}, Ptr{cuopt_float_t}, Ptr{cuOptOptimizationProblem}), num_constraints, num_variables, objective_sense, objective_offset, objective_coefficients, quadratic_objective_matrix_row_offsets, quadratic_objective_matrix_column_indices, quadratic_objective_matrix_coefficent_values, constraint_matrix_row_offsets, constraint_matrix_column_indices, constraint_matrix_coefficent_values, constraint_sense, rhs, lower_bounds, upper_bounds, problem_ptr)
end

"""
cuOptCreateQuadraticRangedProblem(num_constraints, num_variables, objective_sense, objective_offset, objective_coefficients, quadratic_objective_matrix_row_offsets, quadratic_objective_matrix_column_indices, quadratic_objective_matrix_coefficent_values, constraint_matrix_row_offsets, constraint_matrix_column_indices, constraint_matrix_coefficients, constraint_lower_bounds, constraint_upper_bounds, variable_lower_bounds, variable_upper_bounds, problem_ptr)

Create an optimization problem of the form *

```c++
minimize/maximize c^T x + x^T Q x + offset
subject to bl <= A*x <= bu
l <= x <= u
```

# Arguments
* `num_constraints`:\\[in\\] - The number of constraints.
* `num_variables`:\\[in\\] - The number of variables.
* `objective_sense`:\\[in\\] - The objective sense ([`CUOPT_MINIMIZE`](@ref) for minimization or [`CUOPT_MAXIMIZE`](@ref) for maximization)
* `objective_offset`:\\[in\\] - An offset to add to the linear objective.
* `objective_coefficients`:\\[in\\] - A pointer to an array of type [`cuopt_float_t`](@ref) of size num\\_variables containing the coefficients of the linear objective.
* `quadratic_objective_matrix_row_offsets`:\\[in\\] - A pointer to an array of type [`cuopt_int_t`](@ref) of size num\\_variables + 1. quadratic\\_objective\\_matrix\\_row\\_offsets[i] is the index of the first non-zero element of the i-th row of the quadratic objective matrix in quadratic\\_objective\\_matrix\\_column\\_indices and quadratic\\_objective\\_matrix\\_coefficent\\_values. This is part of the compressed sparse row representation of the quadratic objective matrix.
* `quadratic_objective_matrix_column_indices`:\\[in\\] - A pointer to an array of type [`cuopt_int_t`](@ref) of size quadratic\\_objective\\_matrix\\_row\\_offsets[num\\_variables] containing the column indices of the non-zero elements of the quadratic objective matrix. This is part of the compressed sparse row representation of the quadratic objective matrix.
* `quadratic_objective_matrix_coefficent_values`:\\[in\\] - A pointer to an array of type [`cuopt_float_t`](@ref) of size quadratic\\_objective\\_matrix\\_row\\_offsets[num\\_variables] containing the values of the non-zero elements of the quadratic objective matrix.
* `constraint_matrix_row_offsets`:\\[in\\] - A pointer to an array of type [`cuopt_int_t`](@ref) of size num\\_constraints + 1. constraint\\_matrix\\_row\\_offsets[i] is the index of the first non-zero element of the i-th constraint in constraint\\_matrix\\_column\\_indices and constraint\\_matrix\\_coefficients.
* `constraint_matrix_column_indices`:\\[in\\] - A pointer to an array of type [`cuopt_int_t`](@ref) of size constraint\\_matrix\\_row\\_offsets[num\\_constraints] containing the column indices of the non-zero elements of the constraint matrix.
* `constraint_matrix_coefficients`:\\[in\\] - A pointer to an array of type [`cuopt_float_t`](@ref) of size constraint\\_matrix\\_row\\_offsets[num\\_constraints] containing the values of the non-zero elements of the constraint matrix.
* `constraint_lower_bounds`:\\[in\\] - A pointer to an array of type [`cuopt_float_t`](@ref) of size num\\_constraints containing the lower bounds of the constraints.
* `constraint_upper_bounds`:\\[in\\] - A pointer to an array of type [`cuopt_float_t`](@ref) of size num\\_constraints containing the upper bounds of the constraints.
* `variable_lower_bounds`:\\[in\\] - A pointer to an array of type [`cuopt_float_t`](@ref) of size num\\_variables containing the lower bounds of the variables.
* `variable_upper_bounds`:\\[in\\] - A pointer to an array of type [`cuopt_float_t`](@ref) of size num\\_variables containing the upper bounds of the variables.
* `problem_ptr`:\\[out\\] - A pointer to a [`cuOptOptimizationProblem`](@ref). On output the problem will be created and initialized with the provided data.
# Returns
A status code indicating success or failure.
"""
function cuOptCreateQuadraticRangedProblem(num_constraints, num_variables, objective_sense, objective_offset, objective_coefficients, quadratic_objective_matrix_row_offsets, quadratic_objective_matrix_column_indices, quadratic_objective_matrix_coefficent_values, constraint_matrix_row_offsets, constraint_matrix_column_indices, constraint_matrix_coefficients, constraint_lower_bounds, constraint_upper_bounds, variable_lower_bounds, variable_upper_bounds, problem_ptr)
ccall((:cuOptCreateQuadraticRangedProblem, libcuopt), cuopt_int_t, (cuopt_int_t, cuopt_int_t, cuopt_int_t, cuopt_float_t, Ptr{cuopt_float_t}, Ptr{cuopt_int_t}, Ptr{cuopt_int_t}, Ptr{cuopt_float_t}, Ptr{cuopt_int_t}, Ptr{cuopt_int_t}, Ptr{cuopt_float_t}, Ptr{cuopt_float_t}, Ptr{cuopt_float_t}, Ptr{cuopt_float_t}, Ptr{cuopt_float_t}, Ptr{cuOptOptimizationProblem}), num_constraints, num_variables, objective_sense, objective_offset, objective_coefficients, quadratic_objective_matrix_row_offsets, quadratic_objective_matrix_column_indices, quadratic_objective_matrix_coefficent_values, constraint_matrix_row_offsets, constraint_matrix_column_indices, constraint_matrix_coefficients, constraint_lower_bounds, constraint_upper_bounds, variable_lower_bounds, variable_upper_bounds, problem_ptr)
end

"""
cuOptDestroyProblem(problem_ptr)

Expand Down Expand Up @@ -772,6 +842,8 @@ const CUOPT_SOLUTION_FILE = "solution_file"

const CUOPT_NUM_CPU_THREADS = "num_cpu_threads"

const CUOPT_NUM_GPUS = "num_gpus"

const CUOPT_USER_PROBLEM_FILE = "user_problem_file"

const CUOPT_TERIMINATION_STATUS_NO_TERMINATION = 0
Expand Down Expand Up @@ -841,3 +913,4 @@ const CUOPT_VALIDATION_ERROR = 4
const CUOPT_OUT_OF_MEMORY = 5

const CUOPT_RUNTIME_ERROR = 6

140 changes: 140 additions & 0 deletions test/C_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,146 @@ function test_Direct_C_call()
return cuOpt.cuOptDestroyProblem(problem_ref)
end

function test_QuadraticProblem_C_call()
n_col = Cint(2)
n_row = Cint(1)

colcost = Cdouble[0.0, 0.0]
collower = Cdouble[0.0, 0.0]
colupper = Cdouble[10.0, 10.0]

q_row_offsets = Cint[0, 1, 2]
q_col_indices = Cint[0, 1]
q_values = Cdouble[1.0, 1.0]

a_row_offsets = Cint[0, 2]
a_col_indices = Cint[0, 1]
a_values = Cdouble[1.0, 1.0]

constraint_sense = Cchar[cuOpt.CUOPT_GREATER_THAN]
rhs = Cdouble[1.0]

objective_sense = Int32(cuOpt.CUOPT_MINIMIZE)
problem_ref = Ref{cuOpt.cuOptOptimizationProblem}()

ret = cuOpt.cuOptCreateQuadraticProblem(
n_row,
n_col,
objective_sense,
0.0,
colcost,
q_row_offsets,
q_col_indices,
q_values,
a_row_offsets,
a_col_indices,
a_values,
constraint_sense,
rhs,
collower,
colupper,
problem_ref,
)
@test ret == 0
problem = problem_ref[]

settings_ref = Ref{cuOpt.cuOptSolverSettings}()
ret = cuOpt.cuOptCreateSolverSettings(settings_ref)
@test ret == 0
settings = settings_ref[]

solution_ref = Ref{cuOpt.cuOptSolution}()
ret = cuOpt.cuOptSolve(problem, settings, solution_ref)
@test ret == 0
solution = solution_ref[]

termination_status = Ref{Cint}(0)
ret = cuOpt.cuOptGetTerminationStatus(solution, termination_status)
@test ret == 0
@test termination_status[] == cuOpt.CUOPT_TERIMINATION_STATUS_OPTIMAL

obj_value = Ref{Cdouble}(0.0)
ret = cuOpt.cuOptGetObjectiveValue(solution, obj_value)
@test ret == 0
@test abs(obj_value[] - 0.5) < 0.01

cuOpt.cuOptDestroySolution(solution_ref)
cuOpt.cuOptDestroySolverSettings(settings_ref)
return cuOpt.cuOptDestroyProblem(problem_ref)
end

function test_QuadraticRangedProblem_C_call()
n_col = Cint(2)
n_row = Cint(1)

colcost = Cdouble[0.0, 0.0]
collower = Cdouble[0.0, 0.0]
colupper = Cdouble[10.0, 10.0]

q_row_offsets = Cint[0, 1, 2]
q_col_indices = Cint[0, 1]
q_values = Cdouble[1.0, 1.0]

a_row_offsets = Cint[0, 2]
a_col_indices = Cint[0, 1]
a_values = Cdouble[1.0, 1.0]

constraint_lower = Cdouble[1.0]
constraint_upper = Cdouble[10.0]

objective_sense = Int32(cuOpt.CUOPT_MINIMIZE)
problem_ref = Ref{cuOpt.cuOptOptimizationProblem}()

ret = cuOpt.cuOptCreateQuadraticRangedProblem(
n_row,
n_col,
objective_sense,
0.0,
colcost,
q_row_offsets,
q_col_indices,
q_values,
a_row_offsets,
a_col_indices,
a_values,
constraint_lower,
constraint_upper,
collower,
colupper,
problem_ref,
)
@test ret == 0
problem = problem_ref[]

settings_ref = Ref{cuOpt.cuOptSolverSettings}()
ret = cuOpt.cuOptCreateSolverSettings(settings_ref)
@test ret == 0
settings = settings_ref[]

solution_ref = Ref{cuOpt.cuOptSolution}()
ret = cuOpt.cuOptSolve(problem, settings, solution_ref)
@test ret == 0
solution = solution_ref[]

termination_status = Ref{Cint}(0)
ret = cuOpt.cuOptGetTerminationStatus(solution, termination_status)
@test ret == 0
@test termination_status[] == cuOpt.CUOPT_TERIMINATION_STATUS_OPTIMAL

obj_value = Ref{Cdouble}(0.0)
ret = cuOpt.cuOptGetObjectiveValue(solution, obj_value)
@test ret == 0
@test abs(obj_value[] - 0.5) < 0.01

cuOpt.cuOptDestroySolution(solution_ref)
cuOpt.cuOptDestroySolverSettings(settings_ref)
return cuOpt.cuOptDestroyProblem(problem_ref)
end

function test_CUOPT_NUM_GPUS_constant()
@test cuOpt.CUOPT_NUM_GPUS == "num_gpus"
end

function runtests()
for name in names(@__MODULE__; all = true)
if startswith(string(name), "test_")
Expand Down
Loading