j2k-cuda 0.8.1

CUDA adapter for resident HTJ2K decode/encode and shared JPEG 2000 stages
Documentation

j2k-cuda

CUDA adapter for JPEG 2000 / HTJ2K decode, resident encode, and shared encode-stage paths.

CPU and Auto surface requests may return host-backed surfaces. Strict CUDA-resident decode and CUDA-buffer encode use J2K-owned kernels and currently support HTJ2K codestreams: classic J2K subband plans and classic block coding are rejected by those resident paths. Separately, the shared encode-stage adapter can accelerate supported stages without widening the strict resident codec contract. Unsupported explicit CUDA requests return structured errors.

Host-backed fallbacks and the shared adapter/session types compile in default builds. Enable cuda-runtime for CUDA Driver API dispatch, constructible CUDA-resident surface and buffer types, and the CUDA-buffer encode APIs. Without that feature, strict CUDA requests cannot dispatch and return CudaUnavailable or the corresponding structured unsupported-request error.

Host-input lossless encode routing

CudaLosslessEncoder::encode honors the EncodeBackendPreference stored in each job's options. CpuOnly never probes CUDA. Auto may use supported CUDA stages and returns a CPU result when the runtime/device is unavailable or CUDA does not cover every required stage. RequireDevice fails unless CUDA satisfies the complete route. A CUDA execution error is never hidden by retrying the job on the CPU.

The opaque result reports the requested preference, the backend that satisfied the complete encode contract, any Auto fallback reason, and per-stage CUDA dispatches. A CPU backend with nonzero CUDA dispatches means CUDA completed some stages but the CPU satisfied the overall contract.

use j2k::{
    EncodeBackendPreference, J2kBlockCodingMode, J2kLosslessEncodeOptions,
    J2kLosslessSamples,
};
use j2k_cuda::CudaLosslessEncoder;

let pixels = [0_u8; 16 * 16];
let samples = J2kLosslessSamples::new(&pixels, 16, 16, 1, 8, false)?;
let options = J2kLosslessEncodeOptions::default()
    .with_backend(EncodeBackendPreference::Auto)
    .with_block_coding_mode(J2kBlockCodingMode::HighThroughput);
let mut encoder = CudaLosslessEncoder::new();
let result = encoder.encode(samples, &options)?;

assert_eq!(result.requested_backend(), EncodeBackendPreference::Auto);
# Ok::<(), Box<dyn std::error::Error>>(())

CudaLosslessEncoder::encode_strict_cuda and the compatibility encode_j2k_lossless_with_cuda free function deliberately override the stored preference with RequireDevice. The encoder can be moved between threads, but is not shareable by reference: each call takes exclusive mutable access. Input/route/runtime errors clear cached accelerator state before the next job.

cuda-runtime is not proof that every CUDA Oxide kernel was built on the local host. Product PTX is generated only on supported Linux cuda-oxide build hosts; other builds may embed placeholder PTX. Set J2K_REQUIRE_CUDA_OXIDE_BUILD=1 on CUDA validation and benchmark hosts to fail the build when PTX is missing. Runtime errors for placeholder kernels state that CUDA Oxide PTX was not built.

NVIDIA performance claims require self-hosted benchmark evidence.

Links