Skip to content

Java bindings for LP, MIP and QP - #1524

Merged
rapids-bot[bot] merged 50 commits into
NVIDIA:mainfrom
nvidiacbrissette:cbrissette/cuopt-bindings
Aug 27, 2026
Merged

Java bindings for LP, MIP and QP#1524
rapids-bot[bot] merged 50 commits into
NVIDIA:mainfrom
nvidiacbrissette:cbrissette/cuopt-bindings

Conversation

@nvidiacbrissette

@nvidiacbrissette nvidiacbrissette commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Description

Java bindings for LP, MIP and QP, built as hand-written JNI over the public C API, with build and CI integration. Contributes to #1535 and #860.

The API is deliberately small. Following review, it covers building a problem, solving it, and reading the result — nothing beyond that. Anything further can be added later with a case for it.

API

Problem builds and solves; Variable and Constraint carry the model and the values from the last solve; SolverSettings configures the solver; Solution reports the outcome.

try (Problem problem = new Problem("burglar")) {
  Variable x = problem.addVariable(0.0, 1.0, 15.0, VariableType.INTEGER, "take_item_0");
  Variable y = problem.addVariable(0.0, 1.0, 100.0, VariableType.INTEGER, "take_item_1");
  problem.addConstraint(LinearExpression.of(x, 2).plus(y, 20).le(102.0), "capacity");
  problem.setObjective(LinearExpression.of(x, 15).plus(y, 100), ObjectiveSense.MAXIMIZE);

  try (SolverSettings settings = new SolverSettings().setSetting(CuOptConstants.CUOPT_TIME_LIMIT, 10.0);
       Solution solution = problem.solve(settings)) {
    System.out.println(solution.getTerminationStatus());
    System.out.println(x.getValue());
  }
}

Solution values are read from the model — Variable.getValue, Variable.getReducedCost, Constraint.getDualValue, Constraint.getSlack — rather than as bulk arrays.

Solver statistics are read as scalar solution attributes, keyed by a CuOptConstants.CUOPT_SOLUTION_ATTR_* value:

double gap   = solution.getFloatAttribute(CuOptConstants.CUOPT_SOLUTION_ATTR_LP_GAP);
int    nodes = solution.getIntAttribute(CuOptConstants.CUOPT_SOLUTION_ATTR_MIP_NUM_NODES);

This mirrors the problem attribute accessors. Because the selectors are generated into CuOptConstants from constants.h, a statistic added later is a new constant rather than new Java. A selector that does not apply to the solution, or that does not have the requested value type, raises CuOptException.

Build integration

java is an opt-in target of the top-level build.sh:

./build.sh libcuopt                 # once
./build.sh java                     # build libcuopt_jni.so and package the jar
./build.sh java --run-java-tests    # the same, then run the suite

It prefers the cpp/build tree so it works without --install, and falls back to the conda prefix, which is what CI uses. ci/build_java.sh calls build.sh rather than duplicating the invocation.

The rmm and raft headers must be the ones libcuopt was compiled against — rmm carries its version in an inline namespace, so a mismatched copy links cleanly and then fails at dlopen. build.sh passes the right include and library paths when it targets a build tree.

CI

Workflow Job Runner Script
pr.yaml java-build gpu-l4-latest-1 ci/test_java.sh
build.yaml java-build cpu4 ci/build_java.sh
test.yaml conda-java-tests gpu-l4-latest-1 ci/test_java.sh

All three are in their workflow's aggregator job, so a Java failure fails the PR. The PR job is gated on the test_java changed-files group (java/**, ci/build_java.sh, ci/test_java.sh) and on test_cpp, so a C++ change that could break the bindings still exercises them. target/ is uploaded as the cuopt-java artifact.

The java dependency file-key pulls libcuopt plus the libraft-headers, librmm and rapids-logger headers that libcuopt's public headers include transitively. ci/release/update-version.sh bumps the POM through a sentinel comment; the artifact version drops the zero-padded RAPIDS patch field, since Maven has no notion of it.

JNI symbol check

The bindings are hand-written, so a static native declaration and its entry point can drift apart. JNI resolves lazily, so the library still loads and the failure appears only when something calls the method.

scripts/check_jni_symbols.sh diffs the prototypes javac -h derives from the Java sources against the symbols the built library exports, and fails on a mismatch either way. It reads the built artifact rather than parsing source, so the macro-generated entry points need no special casing. build_native.sh runs it after every native build, which covers ./build.sh java and both CI jobs. It takes about a second.

Packaging

Version 26.10.0. Sources and javadoc jars are attached, and the POM carries the url, licenses, scm and developers metadata Maven Central requires. Signing and upload are not wired up; that is tracked by the "Publishing & support" item in #1535.

Known gap

cuopt_jni.cpp still includes pdlp/cuopt_c_internal.hpp for parts of the problem path the C API does not cover — setting names, the quadratic objective and quadratic constraint getters, and the problem category. That couples libcuopt_jni.so to a specific libcuopt build rather than to a stable ABI, which matters before this ships as a binary artifact. Tracked in #1703. The related copy-out behaviour was #1706, fixed by #1734 and now in main.

Checklist

@nvidiacbrissette
nvidiacbrissette requested review from a team as code owners July 7, 2026 19:34
@nvidiacbrissette
nvidiacbrissette requested a review from tmckayus July 7, 2026 19:34
@copy-pr-bot

copy-pr-bot Bot commented Jul 7, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Changes

Java bindings

Layer / File(s) Summary
Modeling contracts and expressions
java/cuopt/src/main/java/com/nvidia/cuopt/mathematicalprogramming/*
Adds Java variables, expressions, constraints, objectives, enums, callbacks, statistics, and validation behavior.
JNI bridge and native wrappers
java/cuopt/src/main/native/*, cpp/include/cuopt/mathematical_optimization/cuopt_c.h, cpp/src/pdlp/cuopt_c.cpp
Adds native declarations and JNI implementations for model creation, solving, settings, callbacks, persistence, solution fields, and statistics.
Problem modeling and solve flow
java/cuopt/src/main/java/com/nvidia/cuopt/mathematicalprogramming/Problem.java
Adds model construction, MPS I/O, CSR/QCSR inspection, updates, relaxation, MIP starts, solving, and result propagation.
Build, packaging, and CI
java/cuopt/*, ci/*, build.sh, .github/workflows/*, dependencies.yaml
Adds Maven/CMake builds, native scripts, generated constants, Java dependencies, CI jobs, artifacts, and release version handling.
Validation and documentation
java/cuopt/src/test/*, docs/cuopt/source/cuopt-java/*, docs/cuopt/source/index.rst
Adds modeling and native integration tests plus Java quick-start, convex, and MIP documentation.

Estimated code review effort: 5 (Critical) | ~120 minutes

Suggested reviewers: tmckayus, chris-maes, hlinsen

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.68% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The description clearly explains the Java bindings for LP, MIP, and QP, including the API, build integration, CI, packaging, testing, and known limitations.
Title check ✅ Passed The title concisely and accurately summarizes the main change: Java bindings for LP, MIP, and QP.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@mlubin mlubin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw the PR is closed, sending my comments as I had them already written up.

Comment thread java/cuopt/src/main/java/com/nvidia/cuopt/linearprogramming/BatchSolve.java Outdated

extern "C" {

cuopt_int_t cuOptLoadParametersFromFile(cuOptSolverSettings settings, const char* path);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should discuss merging these extensions into the C API.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly resolved, and split the way you asked. The Java-local shim is gone — cuopt_java_native_api.hpp no longer exists. The solver-statistics extensions became real C API calls in #1715 (CUOPT_SOLUTION_ATTR_* plus scalar getters), and the copy-out behaviour was #1706, fixed by #1734; both merged separately, so this PR's cpp/ diff against main is empty.

What remains is the problem-model side: cuopt_jni.cpp still includes pdlp/cuopt_c_internal.hpp for name setters, the quadratic getters and the problem category. That is tracked in #1703 and is the prerequisite for shipping the jar as a binary. @chris-maes asked for the quadratic getters to be a separate PR, which matches.

@@ -0,0 +1,1367 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend avoiding a test dependency on the python interface. The java interface should stand on its own.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed and done — PythonParityTest.java is removed. The suite has no Python dependency; the three remaining classes exercise the Java API on its own.

Comment thread java/cuopt/README.md Outdated
@@ -0,0 +1,25 @@
# cuOpt Java bindings (beta)

This directory is an isolated, customer-specific beta module for the cuOpt

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this how we want to ship it?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We would want to follow cuvs and try to publish to maven https://mvnrepository.com/artifact/com.nvidia.cuvs/cuvs-java

Comment thread docs/cuopt/source/cuopt-java/convex/convex-api.rst Outdated
@nvidiacbrissette

Copy link
Copy Markdown
Contributor Author

Sorry that was an accident. Reopening.

@@ -0,0 +1,28 @@
/home/cbrissette/cuopt/java/cuopt/src/main/java/com/nvidia/cuopt/linearprogramming/BatchSolve.java

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need these files ? may be we can delete all the run time files so developers can concentrate on main parts.

@ramakrishnap-nv ramakrishnap-nv left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Focused review on APIs and shipping (vs how cuvs ships Java).

APIs: the surface is broad and, pleasingly, closely in sync with the Python API — the algebraic Problem layer matches Python's (camelCase) modeling methods almost 1:1, and DataModel maps cleanly (snake_case→camelCase). A few parity gaps and Java-idiom nits are noted inline.

Shipping: the main blockers — don't commit target/, and wire the build into CI/release the way cuvs does (ci/build_java.sh/ci/test_java.sh, dependencies.yaml java key, workflow jobs, version marker, docs toctree).

Non-blocking review comments below.

Comment thread java/cuopt/scripts/build_native.sh
Comment thread java/cuopt/pom.xml Outdated
Comment thread docs/cuopt/source/cuopt-java/index.rst
}

/** Return true for maximize and false for minimize, matching Python get_sense(). */
public boolean getSense() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parity note (not a rename request): getSense() correctly matches the Python DataModel.get_sense() (bool, True=maximize) — good. Two parity gaps vs Python though: (1) Python puts set_initial_primal_solution/set_initial_dual_solution on DataModel, whereas here they're on SolverSettings; (2) Python DataModel also exposes getters this class seems to lack: get_quadratic_objective_{values,indices,offsets}, get_variable_names/get_row_names, get_objective_name/get_problem_name, get_ascii_row_types.

resetSolvedValues();
}

public Object getObjective() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getObjective() returns Object — callers must downcast. Prefer a typed return (or overloads). Same for SolverSettings.getTypedParameter() / getMipCallbacks(). (The modeling API otherwise tracks the Python Problem layer 1:1 — nice.)

Comment thread java/cuopt/src/main/java/com/nvidia/cuopt/linearprogramming/CsrMatrix.java Outdated
Comment thread docs/cuopt/source/cuopt-java/convex/convex-api.rst Outdated
Comment thread docs/cuopt/source/cuopt-java/convex/convex-api.rst Outdated
Comment thread docs/cuopt/source/cuopt-java/convex/convex-api.rst Outdated
Comment thread docs/cuopt/source/cuopt-java/convex/convex-api.rst Outdated
Comment thread docs/cuopt/source/cuopt-java/convex/convex-api.rst Outdated
Comment thread docs/cuopt/source/cuopt-java/convex/convex-api.rst Outdated
Comment thread docs/cuopt/source/cuopt-java/convex/convex-api.rst Outdated
Comment thread docs/cuopt/source/cuopt-java/convex/convex-examples.rst Outdated
Comment thread docs/cuopt/source/cuopt-java/convex/convex-examples.rst Outdated
Comment thread docs/cuopt/source/cuopt-java/convex/index.rst Outdated
Comment thread docs/cuopt/source/cuopt-java/index.rst Outdated
Comment thread java/cuopt/src/main/java/com/nvidia/cuopt/linearprogramming/PDLPSolverMode.java Outdated
public enum ProblemCategory {
LP(0),
MIP(1),
IP(2);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should deprecate IP across the whole code base.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed for Java.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the Java side this is now moot: ProblemCategory is gone entirely (5992826), so nothing here names IP. NativeProblem reads the engine's category and reduces it to a boolean, which folds the all-integer case into isMIP without surfacing it.

Deprecating IP across the whole code base is the broader change and is outside this PR — worth its own issue if you want it tracked, and I am happy to file one.

Comment thread java/cuopt/src/main/java/com/nvidia/cuopt/linearprogramming/SolverMethod.java Outdated

@chris-maes chris-maes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the JAVA API. Let's make sure that capitalization is consistent before merging.


Solver statistics are read as scalar solution attributes through
``getIntAttribute`` and ``getFloatAttribute``, selected by a
``CuOptConstants.CUOPT_SOLUTION_ATTR_*`` value. This mirrors the problem

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove "This mirrors the C API". I don't think users need to be aware of another API.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in af5e69a. The sentence now just says a statistic added later becomes a new constant rather than a new method, without explaining where the constants come from.

y.setMIPStart(2.0);

try (SolverSettings settings = new SolverSettings()) {
// The array follows the problem's variable-index order.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's better to show a loop over a variable array in index order? So that the users knows how to get the "variable" index order.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in af5e69a — the MIP start example now loops over getVariables() and assigns by variable.getIndex() instead of a hand-written {3.0, 2.0} literal, so the index order is demonstrated rather than asserted.


settings.setMIPCallback(
(solutionBound, userData) ->
new MIPCallbackSolution(new double[] {3.0, 2.0}, 19.0),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what is happening here? Why is MIPCallbackSolution being created?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair — the example showed the mechanics with no explanation of the purpose. Rewritten in af5e69a.

MIPSetSolutionCallback runs in the opposite direction to the incumbent callback: the solver asks your code for a solution to try, and MIPCallbackSolution is the payload carrying it back. It is for feeding in a solution found elsewhere — your own heuristic, or a result from a previous solve. Returning null declines and leaves the search untouched.

The docs now say that, and the example builds the array from getVariables() rather than showing a bare {3.0, 2.0} literal that hid the ordering requirement.

----------------

A problem can be inspected through ``getConstraintMatrix`` and
``getQuadraticObjectiveMatrix``. To examine an LP relaxation, build the problem

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

examine -> create

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in af5e69a.

System.out.println(solution.getPrimalObjective());
}

``SolverSettings.addMIPStart`` takes a full variable-index-ordered array. It

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I worry about the variable-index-order. I think we need to show users how to get this variable index order. Or show an alternative where they don't need to know the ordering of the variables.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in af5e69a, and I think the worry was right — the docs asserted variable-index order without ever showing how to obtain it, so a reader could reasonably assume declaration order.

Two changes. The per-variable setMIPStart form now leads, since it sidesteps ordering entirely. Where a complete array is genuinely needed, the example builds it from getVariables() and indexes with variable.getIndex(), so the ordering comes from the problem rather than from the reader:

double[] values = new double[problem.getNumVariables()];
for (Variable variable : problem.getVariables()) {
  values[variable.getIndex()] = startFor(variable);
}
settings.addMIPStart(values);

}

The callback receives a defensive Java array containing the incumbent vector,
the incumbent objective, the current solution bound, and the user data object.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to provide a function that takes in the incumbent vector and a set of variables and returns the solution in the order. For examples

Variable[] vars = { z, y, x };
fromIncumbent(incumbent, vars) returns { 3.0, 2.0, 1.0}

assuming x = 1, y = 2, and z = 3 in the incumbent.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added as Problem.fromIncumbent in af5e69a, with your signature — Problem.fromIncumbent(incumbent, z, y, x) returns {3.0, 2.0, 1.0} for x=1, y=2, z=3. It is a static taking varargs, so the call site reads as your example did.

It throws IllegalArgumentException naming the variable if an index falls outside the array, rather than an opaque ArrayIndexOutOfBoundsException, which is the likely mistake if someone passes a variable from a different problem. Tested both the reordering and that failure.

@chris-maes chris-maes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Some minor comments about making the MIP callbacks easier to use. These could be addressed in a follow up PR.

Thanks for all the hard work. Excited to have a Java API.

The resolver properties added earlier did not prevent anything: java-build
failed again on the first artifact it fetched, with a 429 from Maven Central
and no retry. Those properties are transport-specific and are ignored unless
the matching transport is the one in use, so they were a no-op here.

cuopt_mvn now retries the invocation with exponential backoff, which does not
depend on the transport. It retries only when the output looks like an
artifact-resolution failure, so a compile or test failure is still returned
immediately rather than being run four times.

Signed-off-by: Ramakrishna Prabhu <ramakrishnap@nvidia.com>
The MIP docs asserted that arrays are in variable-index order without showing
how to obtain it, which left the reader to assume their declaration order
matched. Both the MIP start and the set-solution callback now build the array
from getVariables, so the ordering comes from the problem.

For the other direction, fromIncumbent reads named variables out of an
index-ordered array and returns them in the order asked for, so a callback can
pick out the variables it cares about without indexing by hand.

Also scope the convex reference to convex problems: the MIP-only Solution
fields move to the MIP page, SolverMethod drops the UNSET sentinel, and the
statistics section no longer refers users to the C API.

Signed-off-by: Ramakrishna Prabhu <ramakrishnap@nvidia.com>
@ramakrishnap-nv

Copy link
Copy Markdown
Collaborator

/ok to test af5e69a

int iterations = solution.getIntAttribute(
CuOptConstants.CUOPT_SOLUTION_ATTR_LP_NUM_ITERATIONS);

Which attributes a solution carries depends on the class of problem that

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strike "Which" and replace with "This"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworded in 5ebeb28. It now opens with the subject: "This depends on the class of problem that produced the solution."


``Problem.read`` loads a problem, choosing the parser from the file extension:
``.mps``, ``.qps`` and ``.lp`` are recognised, along with their ``.gz``,
``.bz2`` and ``.lz4`` variants. A boolean overload forces fixed-format MPS.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boolean is typically capitalized

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5ebeb28.

------------

All solver settings are set through ``SolverSettings``. Use the overloaded
``setSetting`` methods for string, integer, floating-point, and boolean

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalize Boolean

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5ebeb28 — capitalized here too, since it names the type rather than the Java keyword.

---------

``SolverSettings`` and ``Solution`` own native handles and implement
``AutoCloseable``. Prefer try-with-resources. They also register a ``Cleaner``

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Prefer try-with-resources." is not a complete sentence. I'm not sure what you're trying to say? Is it something like "These variables prefer try-with-resources"?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right that it did not say anything. It was meant as an instruction to the reader, but read as a fragment. Rewritten in 5ebeb28:

"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."

Comment thread java/cuopt/README.md Outdated
@@ -0,0 +1,85 @@
# cuOpt Java bindings

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bindings should be capitalized since it's a heading

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5ebeb28 — "cuOpt Java Bindings".

Comment thread java/cuopt/README.md Outdated
The standalone native project links to `${CUOPT_PREFIX}/lib/libcuopt.so`. No
Java-specific symbol or source file is required by the main cuOpt build.

## JNI symbol check

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalize Symbol Check

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5ebeb28 — "JNI Symbol Check".

Comment thread java/cuopt/README.md Outdated
bash scripts/check_jni_symbols.sh
```

## Generated constants

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalize Constants

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5ebeb28 — "Generated Constants".

Comment thread java/cuopt/TESTS.md Outdated
SPDX-License-Identifier: Apache-2.0
-->

# cuOpt Java binding tests

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalize Binding Tests

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5ebeb28 — "cuOpt Java Binding Tests".

Comment thread java/cuopt/TESTS.md Outdated

The suite has no dependency on the cuOpt Python interface.

## How to run

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalize Run

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5ebeb28 — "How to Run".

Comment thread java/cuopt/TESTS.md Outdated
equality and ranged constraints, mixed bounds, mixed integer/continuous
variables, metadata, and infeasibility.

## Prerequisite behavior

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capitalize Behavior

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5ebeb28 — "Prerequisite Behavior". That completes the headings in both files; "Building" and "Coverage" were already title case.

@cwilkinson76 cwilkinson76 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few minor edits needed

Title-case the README and TESTS headings, capitalize Boolean as the type name,
and replace the sentence fragment describing AutoCloseable with one that says
what to do. Reword the solution-attribute sentence to open with its subject.

Signed-off-by: Ramakrishna Prabhu <ramakrishnap@nvidia.com>
@ramakrishnap-nv

Copy link
Copy Markdown
Collaborator

/ok to test 5ebeb28

@ramakrishnap-nv

Copy link
Copy Markdown
Collaborator

@cwilkinson76 May I get another round of review on this ?

@cwilkinson76 cwilkinson76 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ramakrishnap-nv

Copy link
Copy Markdown
Collaborator

/merge

@rapids-bot
rapids-bot Bot merged commit 2575418 into NVIDIA:main Aug 27, 2026
71 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature request New feature or request non-breaking Introduces a non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants