Skip to content

[FEA] Add Java bindings for AST JIT operations - #23117

Merged
rapids-bot[bot] merged 14 commits into
NVIDIA:mainfrom
thirtiseven:codex-ansi-jit-java-bindings-main-upmerge
Jul 20, 2026
Merged

[FEA] Add Java bindings for AST JIT operations#23117
rapids-bot[bot] merged 14 commits into
NVIDIA:mainfrom
thirtiseven:codex-ansi-jit-java-bindings-main-upmerge

Conversation

@thirtiseven

@thirtiseven thirtiseven commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Description

Adds cuDF Java/JNI bindings for the libcudf AST JIT operations introduced by #22602.

Why

cudf-spark needs to lower fused ANSI and TRY expressions to libcudf row IR while preserving row-level overflow and error semantics. JIT-only AST operations also need an explicit Java execution path: routing them through the existing CompiledExpression.computeColumn makes execution depend on the process-level LIBCUDF_JIT_ENABLED backend selection.

What changed

  • Add JitOperation, JitOperator, and JitErrorPolicy, with Java and JNI validation for operator arity, error-policy use, and decimal target scales.
  • Add CompiledExpression.computeColumnJit(Table) to call cudf::compute_column_jit directly.
  • Add Cudf.initializeJitRuntime() as an idempotent JIT runtime and cache preflight. It does not change the backend selected by computeColumn.
  • Add decimal AST literals for DECIMAL32, DECIMAL64, and DECIMAL128, including null and range validation.
  • Cover regular and overflow-checking arithmetic, PROPAGATE/NULLIFY, shifts, casts, decimal precision and rescaling, conditionals, and nested legacy/JIT expression trees.

API impact

This adds the public JitOperation, JitOperator, and JitErrorPolicy types, CompiledExpression.computeColumnJit(Table), Cudf.initializeJitRuntime(), and Literal.ofDecimal(DType, BigInteger). Existing APIs remain source-compatible, and CompiledExpression.computeColumn retains its current backend-selection behavior. Expressions containing JitOperation must be evaluated with computeColumnJit unless the process-level JIT backend is enabled.

Validation

  • All 134 CompiledExpressionTest cases pass on a local GPU against matching locally built shared libcudf and JNI libraries with LIBCUDF_JIT_ENABLED=0.
  • A clean cudf-spark Spark 3.5.2 sql-plugin compile passes against the resulting JNI jar.
  • Relevant clang-format, codespell, whitespace, and EOF pre-commit checks pass.

Checklist

  • I am familiar with the Contributing Guidelines.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

@copy-pr-bot

copy-pr-bot Bot commented Jul 6, 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.

@github-actions github-actions Bot added the Java Affects Java cuDF API. label Jul 6, 2026
@thirtiseven thirtiseven added feature request New feature or request non-breaking Non-breaking change labels Jul 6, 2026
Signed-off-by: Haoyang Li <haoyangl@nvidia.com>
Signed-off-by: Haoyang Li <haoyangl@nvidia.com>
@thirtiseven
thirtiseven marked this pull request as ready for review July 7, 2026 09:18
@thirtiseven
thirtiseven requested a review from a team as a code owner July 7, 2026 09:18
@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

This PR adds Java and JNI support for libcudf JIT AST expressions, decimal literal serialization, native AST construction, separate default and JIT execution paths, and validation and execution tests.

Changes

JIT AST Execution

Layer / File(s) Summary
JIT AST and serialization contracts
java/src/main/java/ai/rapids/cudf/ast/AstExpression.java, java/src/main/java/ai/rapids/cudf/ast/AstUtils.java, java/src/main/java/ai/rapids/cudf/ast/Jit*.java, java/src/main/java/ai/rapids/cudf/ast/*Operator.java, java/src/main/java/ai/rapids/cudf/ast/TableReference.java
Adds JIT expression types, operators, error policies, checked native-id conversion, and serialized JIT operation support.
Decimal literal representation
java/src/main/java/ai/rapids/cudf/ast/Literal.java
Adds BigInteger decimal literal construction, four-byte decimal scale serialization, and decimal128 byte-order conversion.
Native AST tree construction
java/src/main/native/src/jni_compiled_expr.hpp
Refactors native expression storage to use an AST tree and adds reference-based construction APIs.
Native JIT compilation and execution
java/src/main/native/src/CompiledExpression.cpp, java/src/main/java/ai/rapids/cudf/ast/CompiledExpression.java
Decodes and validates JIT expressions, preserves decimal scale, and exposes separate default and JIT execution paths.
JIT and decimal validation
java/src/test/java/ai/rapids/cudf/ast/CompiledExpressionTest.java
Adds tests for decimal literals, JIT operators, overflow policies, conditionals, casts, rescaling, precision handling, and execution errors.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related issues

  • rapidsai/cudf#18023: Covers expanding Java bindings with libcudf JIT expression support.

Suggested labels: libcudf, improvement

Suggested reviewers: revans2, ttnghia

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% 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
Title check ✅ Passed The title clearly summarizes the main change: adding Java bindings for AST JIT operations.
Description check ✅ Passed The description is directly related to the changeset and describes the new JIT bindings, decimal literals, and tests.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@thirtiseven

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
java/src/main/java/ai/rapids/cudf/ast/Literal.java (1)

130-132: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Unverified doc claim: legacy computeColumn support for DECIMAL32/64 literals.

The javadoc states only DECIMAL128 literals require computeColumnJit, implying DECIMAL32/DECIMAL64 decimal literals work with legacy computeColumn. No test in CompiledExpressionTest exercises a decimal literal via computeColumn (all testJitDecimalLiteralTransform cases use computeColumnJit), so this claim is currently untested here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@java/src/main/java/ai/rapids/cudf/ast/Literal.java` around lines 130 - 132,
The javadoc in Literal is making an unverified claim about decimal literal
support with computeColumn versus computeColumnJit. Update the documentation to
match the actual behavior for DECIMAL32/DECIMAL64/DECIMAL128 literals, and add
or adjust coverage in CompiledExpressionTest (for example around
testJitDecimalLiteralTransform and computeColumn) so the supported execution
path is explicitly verified.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@java/src/main/java/ai/rapids/cudf/ast/Literal.java`:
- Around line 130-132: The javadoc in Literal is making an unverified claim
about decimal literal support with computeColumn versus computeColumnJit. Update
the documentation to match the actual behavior for
DECIMAL32/DECIMAL64/DECIMAL128 literals, and add or adjust coverage in
CompiledExpressionTest (for example around testJitDecimalLiteralTransform and
computeColumn) so the supported execution path is explicitly verified.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 61abb19d-7bb0-44a3-991b-d21254a99a70

📥 Commits

Reviewing files that changed from the base of the PR and between ba255bb and 83f500a.

📒 Files selected for processing (11)
  • java/src/main/java/ai/rapids/cudf/Cudf.java
  • java/src/main/java/ai/rapids/cudf/ast/AstExpression.java
  • java/src/main/java/ai/rapids/cudf/ast/CompiledExpression.java
  • java/src/main/java/ai/rapids/cudf/ast/JitErrorPolicy.java
  • java/src/main/java/ai/rapids/cudf/ast/JitOperation.java
  • java/src/main/java/ai/rapids/cudf/ast/JitOperator.java
  • java/src/main/java/ai/rapids/cudf/ast/Literal.java
  • java/src/main/native/src/CompiledExpression.cpp
  • java/src/main/native/src/CudfJni.cpp
  • java/src/main/native/src/jni_compiled_expr.hpp
  • java/src/test/java/ai/rapids/cudf/ast/CompiledExpressionTest.java

Signed-off-by: Haoyang Li <haoyangl@nvidia.com>
@thirtiseven
thirtiseven requested review from lamarrr and revans2 July 9, 2026 08:25
Comment thread java/src/main/java/ai/rapids/cudf/ast/JitOperation.java Outdated
Comment thread java/src/main/java/ai/rapids/cudf/ast/JitOperator.java
Signed-off-by: Haoyang Li <haoyangl@nvidia.com>
@GregoryKimball GregoryKimball moved this to Burndown in libcudf Jul 13, 2026

@lamarrr lamarrr 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.

The C++ changes look good to me.
I took a look at the Java changes too, but I believe we'll need more eyes on it.

auto const op_info = jni_to_jit_operator(jni_ast.read_byte());
auto const error_policy = jni_to_jit_error_policy(jni_ast.read_byte());
auto const arity = static_cast<int32_t>(jni_ast.read_byte());
if (arity < 0) { throw std::invalid_argument("unexpected JNI AST JIT operator arity"); }

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 checking the arity comparison below is sufficient

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.

Agreed. I removed the separate negative-arity check. The single expected-arity comparison rejects both negative and otherwise mismatched values.

@lamarrr

lamarrr commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

/ok to test 30cceaf

Comment thread java/src/main/java/ai/rapids/cudf/ast/JitOperation.java Outdated
Comment thread java/src/main/java/ai/rapids/cudf/ast/JitOperation.java Outdated
Comment thread java/src/main/java/ai/rapids/cudf/ast/JitOperation.java Outdated
Comment thread java/src/main/java/ai/rapids/cudf/ast/JitOperation.java
Comment thread java/src/main/native/src/CompiledExpression.cpp Outdated
Comment thread java/src/test/java/ai/rapids/cudf/ast/CompiledExpressionTest.java
Comment thread java/src/main/java/ai/rapids/cudf/Cudf.java Outdated
Comment thread java/src/main/native/src/CompiledExpression.cpp Outdated
Comment thread java/src/main/native/src/CompiledExpression.cpp Outdated
Comment thread java/src/main/java/ai/rapids/cudf/ast/Literal.java Outdated
Signed-off-by: Haoyang Li <haoyangl@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@java/src/main/native/src/CompiledExpression.cpp`:
- Around line 560-562: Add benchmark coverage for the JIT branch in the result
computation around compute_column_jit, using representative GPU expressions that
exercise standard AST execution, decimal handling, and overflow-policy behavior.
Follow existing benchmark conventions and retain equivalent coverage for the
non-JIT path where applicable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: fc60ee7f-d81f-4b70-a8af-4d97ba53b4cc

📥 Commits

Reviewing files that changed from the base of the PR and between 30cceaf and 4f2dd1b.

📒 Files selected for processing (13)
  • java/src/main/java/ai/rapids/cudf/Cudf.java
  • java/src/main/java/ai/rapids/cudf/ast/AstExpression.java
  • java/src/main/java/ai/rapids/cudf/ast/AstUtils.java
  • java/src/main/java/ai/rapids/cudf/ast/BinaryOperator.java
  • java/src/main/java/ai/rapids/cudf/ast/JitErrorPolicy.java
  • java/src/main/java/ai/rapids/cudf/ast/JitOperation.java
  • java/src/main/java/ai/rapids/cudf/ast/JitOperator.java
  • java/src/main/java/ai/rapids/cudf/ast/Literal.java
  • java/src/main/java/ai/rapids/cudf/ast/TableReference.java
  • java/src/main/java/ai/rapids/cudf/ast/UnaryOperator.java
  • java/src/main/native/src/CompiledExpression.cpp
  • java/src/main/native/src/CudfJni.cpp
  • java/src/test/java/ai/rapids/cudf/ast/CompiledExpressionTest.java
💤 Files with no reviewable changes (2)
  • java/src/main/native/src/CudfJni.cpp
  • java/src/main/java/ai/rapids/cudf/Cudf.java
🚧 Files skipped from review as they are similar to previous changes (5)
  • java/src/main/java/ai/rapids/cudf/ast/JitErrorPolicy.java
  • java/src/main/java/ai/rapids/cudf/ast/AstExpression.java
  • java/src/main/java/ai/rapids/cudf/ast/Literal.java
  • java/src/main/java/ai/rapids/cudf/ast/JitOperator.java
  • java/src/main/java/ai/rapids/cudf/ast/JitOperation.java

Comment thread java/src/main/native/src/CompiledExpression.cpp
Comment thread java/src/main/java/ai/rapids/cudf/ast/Literal.java
Comment thread java/src/main/native/src/CompiledExpression.cpp
Comment thread java/src/main/native/src/CompiledExpression.cpp
auto const& expression = compiled_expr_ptr->get_top_expression();
if (backend == execution_backend::DEFAULT) {
auto const* literal = dynamic_cast<cudf::ast::literal const*>(&expression);
// The legacy evaluator silently corrupts decimal128 literal outputs in release builds.

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.

Would a DECIMAL128 literal nested within an expression also be corrupted, or does that only apply to root literals?

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.

Good catch. The limitation is not specific to a bare root literal: the legacy evaluator cannot materialize any DECIMAL128 root result. I moved the validation into expression_parser so it uses the inferred root output type, while nested comparisons producing BOOL8 remain supported. This follows the fail-fast behavior introduced for unsupported DECIMAL128 AST operations in #22982.

@lamarrr @davidwendt, could you sanity-check whether the root-output routing is the right place for this validation? The alternative would be to keep this as a separate libcudf follow-up, but the JNI-only literal check was too narrow and allowed explicit IDENTITY expressions to reach the same silent-corruption path.

Signed-off-by: Haoyang Li <haoyangl@nvidia.com>
@thirtiseven
thirtiseven requested a review from a team as a code owner July 16, 2026 04:01
@thirtiseven
thirtiseven requested a review from vuule July 16, 2026 04:01
@github-actions github-actions Bot added the libcudf Affects libcudf (C++/CUDA) code. label Jul 16, 2026
Comment thread cpp/tests/ast/transform_tests.cpp Outdated
Comment thread cpp/tests/ast/transform_tests.cpp Outdated
Signed-off-by: Haoyang Li <haoyangl@nvidia.com>

@igorpeshansky igorpeshansky 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 :shipit: modulo a tiny consistency nit.

Comment thread cpp/tests/ast/transform_tests.cpp Outdated
Comment thread cpp/tests/ast/transform_tests.cpp
@thirtiseven

Copy link
Copy Markdown
Contributor Author

/ok to test f869b70

Signed-off-by: Haoyang Li <haoyangl@nvidia.com>
@thirtiseven

Copy link
Copy Markdown
Contributor Author

/ok to test 3aeba52

@thirtiseven

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit 4206875 into NVIDIA:main Jul 20, 2026
255 of 261 checks passed
@GregoryKimball GregoryKimball moved this from Burndown to Landed in libcudf Jul 20, 2026
abigalekim pushed a commit to abigalekim/cudf that referenced this pull request Jul 20, 2026
Adds cuDF Java/JNI bindings for the libcudf AST JIT operations introduced by NVIDIA#22602.

### Why

cudf-spark needs to lower fused ANSI and TRY expressions to libcudf row IR while preserving row-level overflow and error semantics. JIT-only AST operations also need an explicit Java execution path: routing them through the existing `CompiledExpression.computeColumn` makes execution depend on the process-level `LIBCUDF_JIT_ENABLED` backend selection.

### What changed

- Add `JitOperation`, `JitOperator`, and `JitErrorPolicy`, with Java and JNI validation for operator arity, error-policy use, and decimal target scales.
- Add `CompiledExpression.computeColumnJit(Table)` to call `cudf::compute_column_jit` directly.
- Add `Cudf.initializeJitRuntime()` as an idempotent JIT runtime and cache preflight. It does not change the backend selected by `computeColumn`.
- Add decimal AST literals for `DECIMAL32`, `DECIMAL64`, and `DECIMAL128`, including null and range validation.
- Cover regular and overflow-checking arithmetic, `PROPAGATE`/`NULLIFY`, shifts, casts, decimal precision and rescaling, conditionals, and nested legacy/JIT expression trees.

### API impact

This adds the public `JitOperation`, `JitOperator`, and `JitErrorPolicy` types, `CompiledExpression.computeColumnJit(Table)`, `Cudf.initializeJitRuntime()`, and `Literal.ofDecimal(DType, BigInteger)`. Existing APIs remain source-compatible, and `CompiledExpression.computeColumn` retains its current backend-selection behavior. Expressions containing `JitOperation` must be evaluated with `computeColumnJit` unless the process-level JIT backend is enabled.

### Validation

- All 134 `CompiledExpressionTest` cases pass on a local GPU against matching locally built shared libcudf and JNI libraries with `LIBCUDF_JIT_ENABLED=0`.
- A clean cudf-spark Spark 3.5.2 `sql-plugin` compile passes against the resulting JNI jar.
- Relevant clang-format, codespell, whitespace, and EOF pre-commit checks pass.

Authors:
  - Haoyang Li (https://github.com/thirtiseven)

Approvers:
  - Basit Ayantunde (https://github.com/lamarrr)
  - Igor Peshansky (https://github.com/igorpeshansky)

URL: NVIDIA#23117
@GregoryKimball GregoryKimball removed this from libcudf Aug 21, 2026
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 Java Affects Java cuDF API. libcudf Affects libcudf (C++/CUDA) code. non-breaking Non-breaking change

Projects

Status: Landed

Development

Successfully merging this pull request may close these issues.

5 participants