Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 <[email protected]>", "Ramakrishna Prabhu <[email protected]>"]
version = "0.1.1"
version = "0.1.2"

[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
82 changes: 77 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
149 changes: 147 additions & 2 deletions test/C_wrapper.jl
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,151 @@ function test_Direct_C_call()

cuOpt.cuOptDestroySolution(solution_ref)
cuOpt.cuOptDestroySolverSettings(settings_ref)
return cuOpt.cuOptDestroyProblem(problem_ref)
cuOpt.cuOptDestroyProblem(problem_ref)
return
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)
cuOpt.cuOptDestroyProblem(problem_ref)
return
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)
cuOpt.cuOptDestroyProblem(problem_ref)
return
end

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

function runtests()
Expand All @@ -114,8 +258,9 @@ function runtests()
end
end
end
return
end

end
end # TestCCuOpt

TestCCuOpt.runtests()
Loading