Java Quickstart Guide#
NVIDIA cuOpt provides experimental Java bindings for LP, MIP, QP, QCQP, and
SOCP, built from java/cuopt. It is not part of the top-level cuOpt build.
Installation#
Choose your install method below; the selector is pre-set for Java. Copy the
Docker command and run it in your environment — cuopt.jar and
libcuopt_jni.so are already at /opt/cuopt/java inside the container,
so no build step is needed. Use -cp /opt/cuopt/java/cuopt.jar for both
compilation and execution, and pass -Dcuopt.native.dir=/opt/cuopt/java
only to the java command. See Installation for all interfaces and
options.
Using the Maven Artifact#
com.nvidia.cuopt:cuopt publishes classifier jars (cuda12,
cuda12-arm64, cuda13, cuda13-arm64) to the Sonatype snapshot and
release repositories. Each classifier jar embeds libcuopt_jni.so and
cuOpt’s own native dependencies (libcuopt, rmm, cuDSS, NCCL, TBB), which
NativeLibraryLoader extracts to a temp directory and loads automatically —
no cuopt.native.dir is required:
<repositories>
<repository>
<id>sonatype-snapshots</id>
<url>https://central.sonatype.com/repository/maven-snapshots</url>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<dependency>
<groupId>com.nvidia.cuopt</groupId>
<artifactId>cuopt</artifactId>
<version>26.10.0-SNAPSHOT</version>
<classifier>cuda12</classifier>
</dependency>
Note
The embedded libraries do not include the CUDA toolkit’s own math libraries
(libcublas, libcusolver, etc.) — install them separately, or use an
nvidia/cuda:*-runtime-* base image instead, which already has them
without installing cuOpt itself. Loading the jar without them fails with an
UnsatisfiedLinkError naming the missing CUDA library.
# Debian/Ubuntu (with NVIDIA's apt repo already configured)
sudo apt-get install cuda-libraries-12-9
# RHEL/Rocky/Fedora (with NVIDIA's dnf repo already configured)
sudo dnf install cuda-libraries-12-9
cuda-libraries is much lighter than the full CUDA toolkit. See
NVIDIA’s CUDA repository setup
if the repo isn’t configured yet.
Building from source is covered in java/cuopt/README.md.
Smoke Test#
After installation, verify cuOpt Java is working by compiling and running a minimal LP inside the container.
1/*
2 * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5import com.nvidia.cuopt.mathematicaloptimization.*;
6
7public class SmokeTest {
8 public static void main(String[] args) throws Exception {
9 try (Problem problem = new Problem("smoke-test")) {
10 Variable x = problem.addVariable(0, Double.POSITIVE_INFINITY, 0,
11 VariableType.CONTINUOUS, "x");
12 Variable y = problem.addVariable(0, Double.POSITIVE_INFINITY, 0,
13 VariableType.CONTINUOUS, "y");
14 problem.addConstraint(LinearExpression.of(x).plus(y).ge(1.0), "c0");
15 problem.setObjective(LinearExpression.of(x).plus(y), ObjectiveSense.MINIMIZE);
16 try (Solution solution = problem.solve()) {
17 System.out.println(solution.getTerminationStatus());
18 System.out.println(solution.getPrimalObjective());
19 }
20 }
21 }
22}
javac -cp /opt/cuopt/java/cuopt.jar -d . SmokeTest.java
java -Dcuopt.native.dir=/opt/cuopt/java -cp /opt/cuopt/java/cuopt.jar:. SmokeTest
Example Response:
OPTIMAL
1.0
LP Example#
A Problem owns the variables and constraints. Expressions are assembled
with methods that return a new expression, and a constraint is formed by
comparing one against a bound with le, ge or eq.
1/*
2 * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5import com.nvidia.cuopt.mathematicaloptimization.*;
6
7public class LpExample {
8 public static void main(String[] args) throws Exception {
9 try (Problem problem = new Problem("simple")) {
10 Variable x = problem.addVariable(0, Double.POSITIVE_INFINITY, 0,
11 VariableType.CONTINUOUS, "x");
12 Variable y = problem.addVariable(0, Double.POSITIVE_INFINITY, 0,
13 VariableType.CONTINUOUS, "y");
14
15 problem.addConstraint(LinearExpression.of(x).plus(y).ge(1.0), "c0");
16 problem.setObjective(LinearExpression.of(x).plus(y), ObjectiveSense.MINIMIZE);
17
18 try (SolverSettings settings = new SolverSettings()
19 .setSetting(CuOptConstants.CUOPT_METHOD, SolverMethod.PDLP.nativeValue());
20 Solution solution = problem.solve(settings)) {
21 System.out.println(solution.getTerminationStatus());
22 System.out.println(solution.getPrimalObjective());
23 }
24 }
25 }
26}
MIP Example#
1/*
2 * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5import com.nvidia.cuopt.mathematicaloptimization.*;
6
7public class MipExample {
8 public static void main(String[] args) throws Exception {
9 try (Problem problem = new Problem("integer")) {
10 Variable x = problem.addVariable(0, 10, 1.0, VariableType.INTEGER, "x");
11 problem.addConstraint(LinearExpression.of(x).ge(1.0));
12
13 try (SolverSettings settings = new SolverSettings()
14 .setSetting(CuOptConstants.CUOPT_TIME_LIMIT, 10.0);
15 Solution solution = problem.solve(settings)) {
16 System.out.println(solution.getMIPGap());
17 System.out.println(solution.getSolutionBound());
18 }
19 }
20 }
21}
QP Example#
1/*
2 * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5import com.nvidia.cuopt.mathematicaloptimization.*;
6
7public class QpQuickstart {
8 public static void main(String[] args) throws Exception {
9 try (Problem problem = new Problem("quadratic")) {
10 Variable x = problem.addVariable(0.0, 10.0, 0.0, VariableType.CONTINUOUS, "x");
11 Variable y = problem.addVariable(0.0, 10.0, 0.0, VariableType.CONTINUOUS, "y");
12 problem.addConstraint(LinearExpression.of(x).plus(y).ge(5.0));
13 problem.setObjective(
14 QuadraticExpression.of(x, x, 1.0).plus(y, y, 4.0),
15 ObjectiveSense.MINIMIZE);
16 try (Solution solution = problem.solve()) {
17 System.out.println(solution.getPrimalObjective());
18 }
19 }
20 }
21}
MPS I/O#
MpsRoundtrip.java and
sample.mps
1/*
2 * SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5import com.nvidia.cuopt.mathematicaloptimization.*;
6
7public class MpsRoundtrip {
8 public static void main(String[] args) throws Exception {
9 try (Problem problem = Problem.read("sample.mps")) {
10 System.out.println("Variables: " + problem.getNumVariables());
11 problem.write("roundtrip.mps");
12 }
13 }
14}
Lifecycle#
SolverSettings and Solution own native handles and implement
AutoCloseable, so close them with try-with-resources. They also register a
Cleaner fallback, but closing them deterministically keeps native memory
pressure predictable.
Expressions are built and compared through methods — plus, minus,
le, ge and eq — each returning a new object rather than mutating
the receiver. The following pages document the implemented LP/MIP/QP/QCQP/SOCP
surface.