FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

PR11: DSP Runtime SDK by agibsonccc · Pull Request #10444 · deeplearning4j/deeplearning4j · GitHub

PR11: DSP Runtime SDK - #10444

Open
agibsonccc wants to merge 4 commits into
masterfrom
pr/11-dsp-runtime-sdk
Open

PR11: DSP Runtime SDK#10444
agibsonccc wants to merge 4 commits into
masterfrom
pr/11-dsp-runtime-sdk

Conversation

agibsonccc commented Jun 15, 2026
edited
Loading

Copy link
Copy Markdown
Contributor

Summary

PR 11 of 22 PRs in the ag_new_release_updates_2 branch split. Merge after Layer 2 (native core ops + helpers).

  • Versioned C ABI: dsp_runtime_c.h (SDX_RUNTIME_ABI_VERSION=1); 3 opaque handle types, 8 status codes, 9 backend selectors, 15 exported functions
  • Forward ABI compatibility: Every options struct has uint32_t struct_size as first field; newer runtimes silently ignore unknown fields from older callers
  • Lifecycle surface: sdxCreateRuntime → sdxLoadBundle → sdxCreateContext → sdxRun → sdxDestroyContext → sdxUnloadModel → sdxDestroyRuntime; plus sdxMarkInputVariable, sdxMarkInputPlaceholder, sdxFreezeShapes, sdxGetPlanPhase, sdxGetExecutionCount
  • Execution report: sdx_execution_report_t exposes slotCount, executionMode, replayCount, avgLatencyUs, peakMemoryBytes — DSP lifecycle visible without DSP-specific knowledge
  • 6 language bindings: Java (JNA 5.14.0), Kotlin (idiomatic vararg Pair API), Python (ctypes + numpy bridge + gRPC serving stub), Rust (#[repr(C)] with Default impl, RAII Drop), Swift (SPM package, zero-copy UnsafeMutableBufferPointer shape buffer), C# (P/Invoke with IDisposable)
  • JNI bridge: NativeOpsDsp.h deliberately separate from NativeOps.h to avoid rebuild blast radius; parsed by JavaCPP to generate Nd4jCuda.java/Nd4jCpu.java bindings
  • Bundle manifest: manifest.schema.json (JSON Schema draft 2020-12) validates bundle metadata before loading; required: formatVersion, modelId, modelPath, compatibility
  • CI publication: publish-sdk-jars and publish-sdx-runtime-sdk GitHub Actions publish multi-language artifacts to GitHub Releases

What Changed

C ABI header — libnd4j/include/dsp/runtime/ (1 file)

  • dsp_runtime_c.h — SDX_RUNTIME_ABI_VERSION=1; opaque types sdx_runtime_t/sdx_model_t/sdx_context_t; sdx_status_t (8 codes); sdx_backend_t (AUTO/SLOT_BY_SLOT/CUDA_GRAPHS/NVRTC/PTX/TRITON/MLX/ARM_HYBRID/NNAPI); sized structs sdx_runtime_options_t/sdx_model_options_t/sdx_run_options_t/sdx_tensor_view_t/sdx_execution_report_t; SDX_API export macro; extern "C" guards; full 15-function lifecycle API

DSP JNI bridge — libnd4j/include/dsp/ (1 file)

  • NativeOpsDsp.h — separate from NativeOps.h to minimize rebuild scope; parsed by JavaCPP; declares compileDynamicShapePlan(), executeDynamicShapePlan(), freeDynamicShapePlan(), setGraphContextInputArray/OutputArray(), getGraphExecutionMode()/setGraphExecutionMode(), clearDynamicShapePlanCache(), getDspDiagnosticsReport(), setDspProperty(), getPlanPhase(), getPlanExecutionCount(), isPlanReplaying()

Java binding — bindings/java/ (4 files)

  • SdxRuntime.java — JNA Library interface; inner RuntimeOptions/ModelOptions/RunOptions/TensorView/ExecutionReport as JNA Structure subclasses; SdxRuntime.create() loads native lib via platform detection; SdxModel and SdxContext implement AutoCloseable; run() marshals Java float[] / NDArray inputs to sdx_tensor_view_t via JNA Memory
  • pom.xml — org.eclipse.deeplearning4j:nd4j-dsp-runtime-java; depends on JNA 5.x
  • examples/BasicUsage.java, README.md

Kotlin binding — bindings/kotlin/ (4 files)

  • SdxRuntime.kt — KotlinSdxRuntime wrapping Java facade; vararg Pair API for idiomatic Kotlin; all classes implement AutoCloseable
  • build.gradle.kts, settings.gradle.kts, examples/BasicUsage.kt

Python binding — bindings/python/ (12 files)

  • sdx_runtime.py — ctypes wrapper; detect_host_platform_id() maps sys.platform/machine to canonical IDs (linux-x86_64, macos-arm64, android-arm64, etc.); all sdx_*_t types as ctypes Structures; numpy array bridge for float32/int32/float16
  • sdx_sdk_runner.py — REST API runner with JSON tensor I/O
  • sdx_tensor_transport.py — tensor transport for gRPC/REST wire format
  • sdx_serving.proto / sdx_serving_pb2.py / sdx_serving_pb2_grpc.py — gRPC service definition and auto-generated stubs
  • pyproject.toml — nd4j-dsp-runtime; optional numpy/grpcio/protobuf deps
  • tests/test_sdx_runtime_loader.py, test_sdx_sdk_runner_rest.py, test_sdx_tensor_transport.py — unit tests

Rust binding — bindings/rust/ (5 files)

  • src/lib.rs — #[repr(C)] opaque structs; all options structs with Default setting struct_size = mem::size_of::<Self>() as u32; extern "C" block for all sdxXxx() functions; safe RAII wrappers SdxRuntime/SdxModel/SdxContext implementing Drop; SdxError implementing std::error::Error
  • build.rs — links nd4jcuda or nd4jcpu based on features; searches $ND4J_LIB_DIR
  • Cargo.toml, examples/basic_usage.rs, README.md

Swift binding — bindings/swift/ (6 files)

  • Sources/SdxRuntime/SdxRuntime.swift — SdxError enum; SdxTensorViewLease managing UnsafeMutableBufferPointer<Int64> lifetime; SdxRuntime/SdxModel/SdxContext final classes with deinit calling sdxDestroy*
  • Sources/CSdxRuntime/shim.h — C header shim including dsp_runtime_c.h
  • Sources/CSdxRuntime/module.modulemap, Package.swift, examples/BasicUsage.swift, README.md

C# binding — bindings/csharp/ (4 files)

  • SdxRuntime.cs — P/Invoke in Nd4j.Dsp.Runtime namespace; [StructLayout(LayoutKind.Sequential)] structs with Default() factory setting struct_size via Marshal.SizeOf; [DllImport] declarations; SdxRuntime/SdxModel/SdxContext implementing IDisposable with finalizers
  • SdxRuntime.csproj, examples/BasicUsage.cs, examples/BasicUsage.csproj

DSP bundle manifest — resources/dsp/ (1 file)

  • manifest.schema.json — JSON Schema draft 2020-12; required: formatVersion (int ≥1), modelId, modelPath, compatibility; optional: producer, graphSignature (with shapePolicy), targets, optimizationLevel, compressionType

GitHub Actions — .github/actions/ (2 files)

  • publish-sdk-jars/action.yml — collects platform-classified backend JARs; uploads to GitHub Release
  • publish-sdx-runtime-sdk/action.yml — publishes Python wheel, Rust crate, Swift package, C# NuGet, Java JAR as workflow artifacts or to GitHub Release

Dependencies

  • Depends on: PR09 (NativeDynamicShapePlan and NativePlanCache that back the C ABI implementation); PR05/PR06/PR07 (OpaqueContext and NDArray types for NativeOpsDsp.h)
  • Required by: External SDK consumers; no other PRs in this split depend on PR11

Merge Order

These 22 PRs must merge in layer order. Each layer depends on the layers above it being merged first. PRs within the same layer are independent and can merge in parallel.

This PR: Merge after Layer 2 (native core ops + helpers).

Layer PRs
0 (no deps) PR01, PR02, PR20
1 (build/infra) PR03, PR04
2 (native core) PR05, PR06, PR07
3 (native feat) PR08, PR09, PR10, PR11
4 (java core) PR12, PR13, PR14, PR15
5 (java feat) PR16
6 (import/gen) PR17, PR18, PR19, PR21
7 (validation) PR22

Part of the 22-PR split of ag_new_release_updates_2 branch.
Merge layer: 3 (native features)
Files: 48

See pr-plans/00-master-plan.md for the full split plan and merge order.
…hon wildcard import

Remove generated sdx_serving_pb2.py and sdx_serving_pb2_grpc.py protobuf
files which should not be committed; regenerate from sdx_serving.proto as
needed.

Change exit 0 to exit 1 in publish-sdk-jars action so the step properly
fails (rather than silently succeeding) when backend=cuda but cuda-version
is not provided.

Replace wildcard `from .sdx_runtime import *` in __init__.py with explicit
named imports, listing all public constants, functions, and classes exported
by sdx_runtime to avoid polluting the package namespace.
The canonical SdxRuntime.java lives in nd4j-sdx module. The identical
copy under libnd4j/include/dsp/runtime/bindings/java/ was stranded
with no pom.xml reference from any build and would diverge silently.

Copilot AI 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.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Pull request overview

This PR introduces a versioned SDX/DSP Runtime SDK surface centered on a C ABI (dsp_runtime_c.h) plus multi-language bindings (Swift/Rust/Python/Kotlin/C#), a bundle manifest JSON schema, and GitHub Actions to publish the resulting SDK artifacts.

Changes:

  • Added SDX runtime C ABI header (opaque handles, backend/device enums, sized option/report structs, lifecycle API).
  • Added language bindings and examples (Swift/Rust/Python/Kotlin/C#) plus a Python REST+gRPC “runner” and tensor transport helpers.
  • Added manifest.schema.json for bundle metadata validation and CI composite actions to publish SDK artifacts/JARs.

Reviewed changes

Copilot reviewed 42 out of 42 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
resources/dsp/manifest.schema.json Adds JSON Schema for DSP bundle manifests.
libnd4j/include/dsp/runtime/README.md Points readers to ADRs as the source of truth.
libnd4j/include/dsp/runtime/dsp_runtime_c.h Defines the SDX Runtime C ABI v1 (types, structs, functions).
libnd4j/include/dsp/runtime/bindings/README.md Documents available language bindings and runner notes.
libnd4j/include/dsp/runtime/bindings/swift/Package.swift SwiftPM package definition for Swift bindings.
libnd4j/include/dsp/runtime/bindings/swift/README.md Swift binding documentation.
libnd4j/include/dsp/runtime/bindings/swift/examples/BasicUsage.swift Swift usage example.
libnd4j/include/dsp/runtime/bindings/swift/Sources/CSdxRuntime/shim.h Swift C shim header for importing the C ABI.
libnd4j/include/dsp/runtime/bindings/swift/Sources/CSdxRuntime/module.modulemap Module map for importing/linking the runtime library.
libnd4j/include/dsp/runtime/bindings/swift/Sources/SdxRuntime/SdxRuntime.swift Swift wrapper around the C ABI.
libnd4j/include/dsp/runtime/bindings/rust/Cargo.toml Rust crate metadata for the binding.
libnd4j/include/dsp/runtime/bindings/rust/README.md Rust binding documentation and usage sketch.
libnd4j/include/dsp/runtime/bindings/rust/build.rs Rust build script for locating runtime libraries.
libnd4j/include/dsp/runtime/bindings/rust/examples/basic_usage.rs Rust usage example.
libnd4j/include/dsp/runtime/bindings/rust/src/lib.rs Rust FFI + RAII wrapper types.
libnd4j/include/dsp/runtime/bindings/python/init.py Python exports for the ctypes wrapper.
libnd4j/include/dsp/runtime/bindings/python/README.md Python wrapper and runner documentation.
libnd4j/include/dsp/runtime/bindings/python/generate_proto.py Helper to regenerate protobuf stubs.
libnd4j/include/dsp/runtime/bindings/python/pyproject.toml Python packaging config for the bindings.
libnd4j/include/dsp/runtime/bindings/python/requirements-runner.txt Runner dependency pin ranges.
libnd4j/include/dsp/runtime/bindings/python/sdx_runtime.py ctypes wrapper + runtime library auto-discovery.
libnd4j/include/dsp/runtime/bindings/python/sdx_sdk_runner.py FastAPI + gRPC serving runner for the SDK.
libnd4j/include/dsp/runtime/bindings/python/sdx_serving.proto gRPC protocol definition for serving.
libnd4j/include/dsp/runtime/bindings/python/sdx_tensor_transport.py Shared JSON/NPZ tensor transport utilities.
libnd4j/include/dsp/runtime/bindings/python/examples/basic_usage.py Python usage example.
libnd4j/include/dsp/runtime/bindings/python/tests/init.py Python test package marker.
libnd4j/include/dsp/runtime/bindings/python/tests/test_sdx_runtime_loader.py Tests for runtime library discovery and platform detection.
libnd4j/include/dsp/runtime/bindings/python/tests/test_sdx_sdk_runner_rest.py Tests for REST runner behavior.
libnd4j/include/dsp/runtime/bindings/python/tests/test_sdx_tensor_transport.py Tests for tensor transport encode/decode helpers.
libnd4j/include/dsp/runtime/bindings/kotlin/build.gradle.kts Kotlin bindings build definition.
libnd4j/include/dsp/runtime/bindings/kotlin/settings.gradle.kts Kotlin project settings.
libnd4j/include/dsp/runtime/bindings/kotlin/README.md Kotlin binding documentation.
libnd4j/include/dsp/runtime/bindings/kotlin/examples/BasicUsage.kt Kotlin usage example.
libnd4j/include/dsp/runtime/bindings/kotlin/src/main/kotlin/org/nd4j/dsp/runtime/SdxRuntime.kt Kotlin facade over the Java wrapper.
libnd4j/include/dsp/runtime/bindings/csharp/SdxRuntime.csproj .NET project file for the C# binding.
libnd4j/include/dsp/runtime/bindings/csharp/README.md C# binding documentation.
libnd4j/include/dsp/runtime/bindings/csharp/SdxRuntime.cs C# P/Invoke binding + library resolver + wrappers.
libnd4j/include/dsp/runtime/bindings/csharp/examples/BasicUsage.csproj C# example project.
libnd4j/include/dsp/runtime/bindings/csharp/examples/BasicUsage.cs C# usage example.
.github/actions/publish-sdx-runtime-sdk/action.yml Composite action to build and upload SDK artifacts.
.github/actions/publish-sdk-jars/action.yml Composite action to collect/upload platform-classified JARs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

#ifndef CSDXRUNTIME_SHIM_H
#define CSDXRUNTIME_SHIM_H

#include "../../../../include/dsp_runtime_c.h"
Comment on lines +39 to +40
v.shape = UnsafePointer(self.shapeBuffer.baseAddress)
v.rank = Int32(shape.count)
Comment on lines +58 to +62
var runtime: OpaquePointer?
var options = sdx_runtime_options_t()
let status = withUnsafePointer(to: &options) { optPtr in
sdxCreateRuntime(optPtr, &runtime)
}
Comment on lines +214 to +217
public func executionReport() throws -> sdx_execution_report_t {
var report = sdx_execution_report_t()
let status = sdxGetExecutionReport(handle, &report)
guard status == SDX_STATUS_OK else {
Comment on lines +117 to +120
public final class SdxModel {
private unowned let runtime: SdxRuntime
private var handle: OpaquePointer?

Comment on lines +16 to +22
# Prepare input as a numpy array
input_data = np.array([[1.0, 2.0, 3.0, 4.0]], dtype=np.float32)

# Run inference
outputs = ctx.run([input_data])
print(f"Output shape: {outputs[0].shape}")
print(f"Output values: {outputs[0]}")
Comment on lines +93 to +104
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct sdx_execution_report_t {
pub struct_size: u32,
pub requested_backend: i32,
pub applied_backend: i32,
pub status_code: i32,
pub used_fallback: i32,
pub execution_time_ns: u64,
pub requested_gpu_target: i32,
pub applied_gpu_target: i32,
}
Comment on lines +101 to +120
[StructLayout(LayoutKind.Sequential)]
public struct SdxExecutionReport
{
public uint struct_size;
public int requested_backend;
public int applied_backend;
public int status_code;
public int used_fallback;
public ulong execution_time_ns;
public int requested_gpu_target;
public int applied_gpu_target;

public static SdxExecutionReport Default()
{
return new SdxExecutionReport
{
struct_size = (uint)Marshal.SizeOf<SdxExecutionReport>()
};
}
}
Comment on lines +375 to +385
class ExecutionReport(ctypes.Structure):
_fields_ = [
("struct_size", ctypes.c_uint32),
("requested_backend", ctypes.c_int32),
("applied_backend", ctypes.c_int32),
("status_code", ctypes.c_int32),
("used_fallback", ctypes.c_int32),
("execution_time_ns", ctypes.c_uint64),
("requested_gpu_target", ctypes.c_int32),
("applied_gpu_target", ctypes.c_int32),
]
echo " Collected: ${BASENAME} (from ${jar})"
FOUND=1
fi
done < <(find "${GITHUB_WORKSPACE}" -path "*/target/${MODULE}-*.jar" -type f -print0 2>/dev/null | head -z -n 5)

Copy link
Copy Markdown
Contributor Author

Architecture Overview

This PR defines the public C ABI and multi-language SDK for the DSP runtime, enabling external consumers to compile and execute dynamic shape plans without depending on the full ND4J/SameDiff stack. The C header uses a versioned ABI with forward-compatible sized structs, and the 6 language bindings all map to the same 15-function lifecycle.

Highlights

  • Versioned C ABI with forward compatibility — dsp_runtime_c.h (SDX_RUNTIME_ABI_VERSION=1) defines 3 opaque handle types, 8 status codes, 9 backend selectors (AUTO through NNAPI), and 15 exported functions; every options struct has uint32_t struct_size as its first field so newer runtimes silently ignore unknown fields from older callers
  • 6 language bindings — Java (JNA 5.14.0 with AutoCloseable), Kotlin (idiomatic vararg Pair API), Python (ctypes + numpy bridge + gRPC serving stub), Rust (#[repr(C)] with RAII Drop), Swift (SPM package, zero-copy UnsafeMutableBufferPointer), C# (P/Invoke with IDisposable)

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants


Back | FazBrowse Home | New Git URL