← quantChapter 4 · Picking an engine2 min read

One tape, optional engines

Distinguish scalar replay from tensor backends, optional engines from validated hardware, and legacy browser examples from current jax4j.

A backend name is only the start. The module must be on the classpath, its runtime must load, and the operation you request must be supported. This matters when reading an old table with six engine names: the current library has two separate execution interfaces, and their provider lists differ.

Scalar replay and tensor execution

The scalar tape API records a numerical function, then replays it with new inputs. In jax4j 0.2.1, cpu interprets that tape and cpu-jit generates JVM bytecode. Both ship in jax4j-core. Optional simd uses Vector API lanes to replay multiple scenarios together; it is not a separate tensor placement.

The tensor API places shaped arrays on devices. Its CPU provider is in core; optional CUDA, ROCm, Vulkan and wgpu modules provide device implementations. The native wgpu module has no scalar replay adapter. You cannot infer that .on("wgpu") works on a scalar Monte Carlo tape just because a tensor can live on Device.wgpu().

What is implemented today?

EngineCurrent jax4j 0.2.1 status
cpu, cpu-jitIncluded in core and core validation
vulkanTensor and scalar implementations; hardware validated
wgpuTensor implementation; hardware validated; no scalar adapter
cudaTensor and scalar implementations; builds; execution last validated in 0.2.0
rocmTensor and scalar implementations; published; hardware validation absent
simdOptional scalar implementation; published; execution unverified for this release
openclNo current module or provider

Vulkan and wgpu validation establishes the tested operations on the recorded hardware, not every possible device or transformation. CUDA scalar replay also rejects multi-output tapes, uniform draws and named random streams.

All current jax4j engine artifacts above were confirmed on Maven Central on 21 October 2026. Presence in the repository or on Central is not a successful hardware run. See the full support and installation guide.

Inspect a native process

With core and your chosen optional modules on the classpath:

import com.nablatensor.jax4j.engine.AadEngines;
import com.nablatensor.jax4j.tensor.Tensors;

AadEngines.discovered().forEach(engine ->
    System.out.println(engine.name() + " available=" + engine.isAvailable()));
Tensors.backends().forEach(backend -> System.out.println(backend.name()));
System.out.println(Tensors.devices());

Native GPU applications need --enable-native-access=ALL-UNNAMED and matching libraries and drivers. SIMD needs jax4j-simd and --add-modules jdk.incubator.vector. Adding the flag without the engine JAR does not install a provider. Explicit selection of an unavailable engine raises an error; it does not quietly change the requested calculation to CPU.

Run the legacy browser example

Java · compile and run in this browser

This finance cell still uses bundled NablaTensor 0.1.0-SNAPSHOT JARs through TeaVM, on its portable cpu engine. It is not a Quant 0.4.0 or jax4j 0.2.1 engine benchmark. The jax4j provider lesson uses the current tensor library and can inspect the separate browser WebGPU adapter. Neither browser path supplies native ROCm or Vector API SIMD.

The old throughput illustration is retained as a historical figure, not a current engine matrix or a fresh benchmark:

Historical pre-split NablaTensor throughput comparison. These recorded figures do not establish engine availability or performance in current jax4j.

Continue with checkpointing for the memory tradeoff, or GPU execution paths for the compiler and runtime differences. Historical timing claims need the original source revision, launch flags and hardware record before they can be reproduced.


Questions or corrections? open an issue