volvoxai 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +145 -0
- package/bin/volvox.js +72 -0
- package/dist/v0.1.0/volvoxai.js +4664 -0
- package/dist/v0.1.0/volvoxai.min.js +1848 -0
- package/dist/v0.1.0/volvoxai.wasm +0 -0
- package/dist/volvoxai.js +4664 -0
- package/dist/volvoxai.min.js +1848 -0
- package/dist/volvoxai.wasm +0 -0
- package/docs/README.md +22 -0
- package/docs/browser-runtime.md +87 -0
- package/docs/efficientdet_tflite_vs_volvoxai.md +445 -0
- package/docs/microkernel_optimization_guide.md +153 -0
- package/docs/model-format.md +108 -0
- package/docs/models.md +103 -0
- package/docs/native-runtime.md +189 -0
- package/docs/operation_list.md +232 -0
- package/docs/operator_fusion_patterns.md +58 -0
- package/docs/quickstart.md +115 -0
- package/docs/roadmap.md +19 -0
- package/docs/testing.md +97 -0
- package/docs/textbook/01-foundations.md +233 -0
- package/docs/textbook/02-tinystories-language-model.md +300 -0
- package/docs/textbook/03-efficientdet-vision-model.md +281 -0
- package/docs/textbook/04-precision-and-quantization.md +208 -0
- package/docs/textbook/05-inside-the-engine.md +155 -0
- package/docs/textbook/06-native-engine-architecture.md +338 -0
- package/docs/textbook/07-glossary-and-next-steps.md +258 -0
- package/docs/textbook/README.md +85 -0
- package/docs/textbook/ko/01-foundations.md +231 -0
- package/docs/textbook/ko/02-tinystories-language-model.md +300 -0
- package/docs/textbook/ko/03-efficientdet-vision-model.md +277 -0
- package/docs/textbook/ko/04-precision-and-quantization.md +206 -0
- package/docs/textbook/ko/05-inside-the-engine.md +154 -0
- package/docs/textbook/ko/06-native-engine-architecture.md +333 -0
- package/docs/textbook/ko/07-glossary-and-next-steps.md +253 -0
- package/docs/textbook/ko/README.md +83 -0
- package/docs/xnnpack_optimization_guide.md +197 -0
- package/js/CPUEngine.js +241 -0
- package/js/Graph.js +49 -0
- package/js/GraphExecutor.js +1020 -0
- package/js/GraphLoader.js +282 -0
- package/js/ShaderLibrary.js +236 -0
- package/js/Tensor.js +25 -0
- package/js/Tokenizer.js +266 -0
- package/js/VolvoxAI.js +130 -0
- package/js/WasmEngine.js +378 -0
- package/js/WebNNEngine.js +169 -0
- package/js/index.js +11 -0
- package/js/ops/add.js +31 -0
- package/js/ops/argMax.js +33 -0
- package/js/ops/averagePool2D.js +38 -0
- package/js/ops/batchNorm2D.js +28 -0
- package/js/ops/cast.js +19 -0
- package/js/ops/clip.js +15 -0
- package/js/ops/concat2.js +18 -0
- package/js/ops/conv1D.js +35 -0
- package/js/ops/conv2D.js +70 -0
- package/js/ops/convTranspose2D.js +45 -0
- package/js/ops/crossAttention.js +69 -0
- package/js/ops/crossSDPA.js +41 -0
- package/js/ops/dequantizeLinear.js +9 -0
- package/js/ops/div.js +15 -0
- package/js/ops/embedding.js +14 -0
- package/js/ops/expand.js +24 -0
- package/js/ops/gELU.js +9 -0
- package/js/ops/gather.js +51 -0
- package/js/ops/gatherElements.js +33 -0
- package/js/ops/globalAveragePool.js +21 -0
- package/js/ops/hardSigmoid.js +12 -0
- package/js/ops/hardSwish.js +12 -0
- package/js/ops/interp1D.js +25 -0
- package/js/ops/layerNorm.js +25 -0
- package/js/ops/leakyReLU.js +10 -0
- package/js/ops/logSoftmax.js +15 -0
- package/js/ops/matMul.js +35 -0
- package/js/ops/maxPool2D.js +36 -0
- package/js/ops/meanHeight.js +17 -0
- package/js/ops/mul.js +31 -0
- package/js/ops/nonMaxSuppression.js +72 -0
- package/js/ops/pReLU.js +11 -0
- package/js/ops/pad.js +35 -0
- package/js/ops/profileX.js +22 -0
- package/js/ops/profileY.js +22 -0
- package/js/ops/rMSNorm.js +14 -0
- package/js/ops/reLU.js +8 -0
- package/js/ops/reduceMean.js +17 -0
- package/js/ops/reduceSum.js +19 -0
- package/js/ops/reshape.js +6 -0
- package/js/ops/resize.js +44 -0
- package/js/ops/sDPA.js +44 -0
- package/js/ops/siLU.js +8 -0
- package/js/ops/sigmoid.js +6 -0
- package/js/ops/slice.js +36 -0
- package/js/ops/softmax.js +18 -0
- package/js/ops/spatialSoftargmaxY.js +28 -0
- package/js/ops/split.js +24 -0
- package/js/ops/sub.js +11 -0
- package/js/ops/tanh.js +7 -0
- package/js/ops/transpose.js +34 -0
- package/js/ops/upsample2x.js +23 -0
- package/js/ops/where.js +15 -0
- package/package.json +33 -0
- package/shaders/add.wgsl +13 -0
- package/shaders/add3Relu.wgsl +23 -0
- package/shaders/addRelu.wgsl +22 -0
- package/shaders/averagePool2D.wgsl +24 -0
- package/shaders/batchNorm2D.wgsl +21 -0
- package/shaders/binaryBroadcast.wgsl +34 -0
- package/shaders/broadcastBinary.wgsl +26 -0
- package/shaders/clip.wgsl +10 -0
- package/shaders/concat2.wgsl +16 -0
- package/shaders/concatCopy.wgsl +10 -0
- package/shaders/concatSigmoidCopy.wgsl +16 -0
- package/shaders/conv1D.wgsl +37 -0
- package/shaders/conv2D.wgsl +80 -0
- package/shaders/conv2DDepthwise4.wgsl +74 -0
- package/shaders/conv2DDepthwise8.wgsl +66 -0
- package/shaders/conv2DPointwise16.wgsl +67 -0
- package/shaders/conv2DPointwise16Tile.wgsl +86 -0
- package/shaders/conv2DPointwise8.wgsl +85 -0
- package/shaders/conv2DPointwise8Vec2.wgsl +70 -0
- package/shaders/conv2DPointwise8Vec4.wgsl +65 -0
- package/shaders/conv2DRegularC3Out16.wgsl +75 -0
- package/shaders/convTranspose2D.wgsl +33 -0
- package/shaders/copy.wgsl +13 -0
- package/shaders/crossAttention.wgsl +140 -0
- package/shaders/crossAttentionF32.wgsl +98 -0
- package/shaders/crossSDPA.wgsl +74 -0
- package/shaders/dequantizeLinear.wgsl +14 -0
- package/shaders/div.wgsl +34 -0
- package/shaders/elementwise.wgsl +13 -0
- package/shaders/embedding.wgsl +22 -0
- package/shaders/expand.wgsl +18 -0
- package/shaders/gELU.wgsl +13 -0
- package/shaders/gather.wgsl +17 -0
- package/shaders/generalTranspose.wgsl +19 -0
- package/shaders/globalAveragePool.wgsl +19 -0
- package/shaders/hardSigmoid.wgsl +13 -0
- package/shaders/hardSwish.wgsl +13 -0
- package/shaders/interp1D.wgsl +28 -0
- package/shaders/layerNorm.wgsl +33 -0
- package/shaders/leakyReLU.wgsl +11 -0
- package/shaders/linearF32.wgsl +33 -0
- package/shaders/linearF32RowMajor.wgsl +24 -0
- package/shaders/linearInt8.wgsl +42 -0
- package/shaders/logSoftmax.wgsl +22 -0
- package/shaders/maxPool2D.wgsl +37 -0
- package/shaders/meanHeight.wgsl +18 -0
- package/shaders/mul.wgsl +32 -0
- package/shaders/nonMaxSuppression.wgsl +92 -0
- package/shaders/pReLU.wgsl +14 -0
- package/shaders/pad.wgsl +19 -0
- package/shaders/profileX.wgsl +28 -0
- package/shaders/profileY.wgsl +28 -0
- package/shaders/quantizeLinear.wgsl +69 -0
- package/shaders/rMSNorm.wgsl +21 -0
- package/shaders/reLU.wgsl +13 -0
- package/shaders/reduce.wgsl +17 -0
- package/shaders/resize.wgsl +52 -0
- package/shaders/sDPA.wgsl +71 -0
- package/shaders/siLU.wgsl +13 -0
- package/shaders/sigmoid.wgsl +13 -0
- package/shaders/slice.wgsl +26 -0
- package/shaders/softmax.wgsl +23 -0
- package/shaders/spatialSoftargmaxY.wgsl +32 -0
- package/shaders/split.wgsl +15 -0
- package/shaders/sub.wgsl +34 -0
- package/shaders/tanh.wgsl +13 -0
- package/shaders/upsample2x.wgsl +24 -0
- package/shaders/where.wgsl +12 -0
- package/volvoxai.wasm +0 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Operation List and Status
|
|
2
|
+
|
|
3
|
+
This document describes the VolvoxAI operation list, what each operation means, where
|
|
4
|
+
its logic lives in the repository, and the current implementation status across browser,
|
|
5
|
+
Node, and native backends.
|
|
6
|
+
|
|
7
|
+
## What the Operation List Is
|
|
8
|
+
|
|
9
|
+
The operation list is the set of `opType` names that can appear in a Volvox blueprint
|
|
10
|
+
graph. A graph node uses one of these names, references input and output tensors, and
|
|
11
|
+
passes op-specific parameters through `params`.
|
|
12
|
+
|
|
13
|
+
The list is used by three parts of the system:
|
|
14
|
+
|
|
15
|
+
1. **Exporters and converters** decide which ONNX, TFLite, PyTorch, or custom graph
|
|
16
|
+
operations can be emitted into Volvox format.
|
|
17
|
+
2. **Graph loading** resolves tensor shapes, weight layouts, quantized weights, and
|
|
18
|
+
aliases before execution.
|
|
19
|
+
3. **Runtime backends** dispatch each node to the best available implementation.
|
|
20
|
+
|
|
21
|
+
The operation list is not a full ONNX or TFLite compatibility promise. It is the smaller
|
|
22
|
+
runtime contract that VolvoxAI currently implements for inference graphs.
|
|
23
|
+
|
|
24
|
+
## Status Legend
|
|
25
|
+
|
|
26
|
+
| Status | Meaning |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| Full | Implemented directly for the normal runtime path. |
|
|
29
|
+
| Partial | Implemented with shape, axis, dtype, layout, size, or execution-mode limits. |
|
|
30
|
+
| Fallback | The backend can run the op by delegating to a lower-level/reference helper. |
|
|
31
|
+
| Missing | Not wired on that backend. |
|
|
32
|
+
| Alias | Shape-only or alternate spelling handled by another operation. |
|
|
33
|
+
| Init only | Backend can initialize but has no per-op runtime dispatch. |
|
|
34
|
+
|
|
35
|
+
## Backend Names
|
|
36
|
+
|
|
37
|
+
| Backend | Runtime role | Main files |
|
|
38
|
+
| --- | --- | --- |
|
|
39
|
+
| CPU(JS) | Pure JavaScript reference backend used by the browser/Node ES module runtime. | [CPUEngine.js](../js/CPUEngine.js), [js/ops](../js/ops) |
|
|
40
|
+
| WASM | Browser/Node WebAssembly tier. Some ops call C kernels; some fall back to CPU(JS) helpers over WASM heap views. | [WasmEngine.js](../js/WasmEngine.js), [native/kernels](../native/kernels) |
|
|
41
|
+
| WebGPU | Browser WebGPU compute-shader backend. | [GraphExecutor.js](../js/GraphExecutor.js), [shaders](../shaders) |
|
|
42
|
+
| WebNN | Opportunistic browser accelerator through `navigator.ml`. Unsupported ops throw during build so lower tiers can run. | [WebNNEngine.js](../js/WebNNEngine.js) |
|
|
43
|
+
| CPU(Native) | Freestanding native runtime CPU path. This is separate from CPU(JS). | [engine_runtime.c](../native/engine_runtime.c), [native/kernels](../native/kernels), [conv_f32_opt.c](../native/conv_f32_opt.c), [quant_cpu_opt.c](../native/quant_cpu_opt.c) |
|
|
44
|
+
| Vulkan(Native) | Native Vulkan compute path. It is called from the native dispatcher and is separate from browser WebGPU. | [engine_runtime.c](../native/engine_runtime.c), [vulkan_engine.c](../native/vulkan_engine.c) |
|
|
45
|
+
| OpenGL(Native) | Native OpenGL ES compute path. It is called from the native dispatcher and is separate from browser WebGPU. | [engine_runtime.c](../native/engine_runtime.c), [opengl_engine.c](../native/opengl_engine.c) |
|
|
46
|
+
| Metal(Native) | Native Metal compute path on Apple platforms. It loads Naga-generated MSL and is called from the native dispatcher for selected F32 graph ops. | [engine_runtime.c](../native/engine_runtime.c), [metal_engine.m](../native/metal_engine.m) |
|
|
47
|
+
|
|
48
|
+
Note: [native/gpu](../native/gpu) contains older scaffold files. The active native
|
|
49
|
+
runtime paths are the files listed above.
|
|
50
|
+
|
|
51
|
+
## Browser and Node Status
|
|
52
|
+
|
|
53
|
+
This table covers the ES module runtime: CPU(JS), WASM, browser WebGPU, and WebNN.
|
|
54
|
+
|
|
55
|
+
| Operation | What it does | CPU(JS) | WASM | WebGPU | WebNN |
|
|
56
|
+
| --- | --- | --- | --- | --- | --- |
|
|
57
|
+
| `MatMul` | Dense matrix multiply with optional bias; FP32 and INT8-packed weight paths. | [Full](../js/ops/matMul.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/linearF32.wgsl) | [Full](../js/WebNNEngine.js) |
|
|
58
|
+
| `Linear`, `Gemm` | Dense-layer aliases used by exporters. | [Missing](../js/CPUEngine.js) | [Missing](../js/WasmEngine.js) | [Missing except layout pre-scan](../js/GraphExecutor.js) | [Full](../js/WebNNEngine.js) |
|
|
59
|
+
| `Conv2D` | NHWC 2D convolution, including grouped/depthwise and dilation. | [Full](../js/ops/conv2D.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/conv2D.wgsl) | [Full](../js/WebNNEngine.js) |
|
|
60
|
+
| `Conv1D` | 1D convolution for sequence/audio tensors. | [Full](../js/ops/conv1D.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/conv1D.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
61
|
+
| `ConvTranspose2D` | Transposed convolution / deconvolution. | [Full](../js/ops/convTranspose2D.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/convTranspose2D.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
62
|
+
| `QConv2D` | Quantized Conv2D node from native/direct TFLite exports. | [Loaded graphs convert to `Conv2D`](../js/GraphLoader.js) | [Loaded graphs convert to `Conv2D`](../js/GraphLoader.js) | [Loaded graphs convert to `Conv2D`](../js/GraphLoader.js) | [Loaded graphs convert to `Conv2D`](../js/GraphLoader.js) |
|
|
63
|
+
| `LayerNorm` | Layer normalization over the last feature axis. | [Full](../js/ops/layerNorm.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/layerNorm.wgsl) | [Full](../js/WebNNEngine.js) |
|
|
64
|
+
| `RMSNorm` | RMS normalization over the last feature axis. | [Full](../js/ops/rMSNorm.js) | [Fallback](../js/WasmEngine.js) | [Full](../shaders/rMSNorm.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
65
|
+
| `BatchNorm2D` | Per-channel image batch normalization. | [Full](../js/ops/batchNorm2D.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/batchNorm2D.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
66
|
+
| `Embedding` | Row lookup from token ids into an embedding table. | [Full](../js/ops/embedding.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/embedding.wgsl) | [Full](../js/WebNNEngine.js) |
|
|
67
|
+
| `SDPA` | Self-attention over packed QKV with causal behavior. | [Full](../js/ops/sDPA.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/sDPA.wgsl) | [Partial](../js/WebNNEngine.js) |
|
|
68
|
+
| `CrossSDPA` | Cross-attention over separate Q, K, and V tensors. | [Full](../js/ops/crossSDPA.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/crossSDPA.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
69
|
+
| `CrossAttention` | Cross-attention variant using Q plus packed KV and optional scale/bias. | [Full](../js/ops/crossAttention.js) | [Fallback](../js/WasmEngine.js) | [Full](../shaders/crossAttention.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
70
|
+
| `MaxPool2D` | 2D max pooling. | [Full](../js/ops/maxPool2D.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/maxPool2D.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
71
|
+
| `AveragePool`, `AveragePool2D` | 2D average pooling. | [Full](../js/ops/averagePool2D.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/averagePool2D.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
72
|
+
| `GlobalAveragePool` | Global spatial average pooling. | [Full](../js/ops/globalAveragePool.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/globalAveragePool.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
73
|
+
| `Resize` | Image resize. Bilinear is the normal path. | [Full](../js/ops/resize.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/resize.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
74
|
+
| `ResizeNearest2D` | Nearest-neighbor image resize. | [Full](../js/ops/resize.js) | [Fallback](../js/WasmEngine.js) | [Full](../shaders/resize.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
75
|
+
| `UpsampleNearest2D`, `Upsample2x` | Nearest-neighbor 2x upsampling aliases. | [Full](../js/ops/upsample2x.js) | [Full for `UpsampleNearest2D`](../js/WasmEngine.js) | [Full for `UpsampleNearest2D`](../shaders/upsample2x.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
76
|
+
| `InterpLinear1D`, `Interp1D` | Linear 1D interpolation aliases. | [Full](../js/ops/interp1D.js) | [Full for `InterpLinear1D`](../js/WasmEngine.js) | [Full for `InterpLinear1D`](../shaders/interp1D.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
77
|
+
| `ReLU` | Rectified linear activation. | [Full](../js/ops/reLU.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/reLU.wgsl) | [Full](../js/WebNNEngine.js) |
|
|
78
|
+
| `LeakyReLU` | Leaky ReLU activation with `alpha`. | [Full](../js/ops/leakyReLU.js) | [Full or fallback](../js/WasmEngine.js) | [Full](../shaders/leakyReLU.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
79
|
+
| `PReLU` | Per-channel parametric ReLU. | [Full](../js/ops/pReLU.js) | [Full or fallback](../js/WasmEngine.js) | [Full](../shaders/pReLU.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
80
|
+
| `GELU` | Gaussian error linear unit. | [Full](../js/ops/gELU.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/gELU.wgsl) | [Full](../js/WebNNEngine.js) |
|
|
81
|
+
| `SiLU`, `Swish` | `x * sigmoid(x)` activation aliases. | [Full](../js/ops/siLU.js) | [Fallback](../js/WasmEngine.js) | [Full](../shaders/siLU.wgsl) | [Full](../js/WebNNEngine.js) |
|
|
82
|
+
| `Sigmoid` | Logistic activation. | [Full](../js/ops/sigmoid.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/sigmoid.wgsl) | [Full](../js/WebNNEngine.js) |
|
|
83
|
+
| `HardSwish` | MobileNet-style hard swish activation. | [Full](../js/ops/hardSwish.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/hardSwish.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
84
|
+
| `HardSigmoid` | Piecewise-linear sigmoid approximation. | [Full](../js/ops/hardSigmoid.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/hardSigmoid.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
85
|
+
| `Tanh` | Hyperbolic tangent activation. | [Full](../js/ops/tanh.js) | [Fallback](../js/WasmEngine.js) | [Full](../shaders/tanh.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
86
|
+
| `Clip` | Clamp values to min/max. | [Full](../js/ops/clip.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/clip.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
87
|
+
| `Add` | Elementwise add with broadcasting. | [Full](../js/ops/add.js) | [Fallback](../js/WasmEngine.js) | [Full](../shaders/broadcastBinary.wgsl) | [Full](../js/WebNNEngine.js) |
|
|
88
|
+
| `Mul` | Elementwise multiply with broadcasting. | [Full](../js/ops/mul.js) | [Fallback](../js/WasmEngine.js) | [Full](../shaders/broadcastBinary.wgsl) | [Full](../js/WebNNEngine.js) |
|
|
89
|
+
| `Sub` | Elementwise subtract with broadcasting. | [Full](../js/ops/sub.js) | [Fallback](../js/WasmEngine.js) | [Full](../shaders/broadcastBinary.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
90
|
+
| `Div` | Elementwise divide with broadcasting. | [Full](../js/ops/div.js) | [Fallback](../js/WasmEngine.js) | [Full](../shaders/broadcastBinary.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
91
|
+
| `Softmax` | Softmax over the last axis. | [Full](../js/ops/softmax.js) | [Fallback](../js/WasmEngine.js) | [Partial, last axis only](../shaders/softmax.wgsl) | [Full](../js/WebNNEngine.js) |
|
|
92
|
+
| `LogSoftmax` | Log-softmax over the last axis. | [Full](../js/ops/logSoftmax.js) | [Fallback](../js/WasmEngine.js) | [Partial, last axis only](../shaders/logSoftmax.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
93
|
+
| `ReduceSum` | Reduction sum. | [Full](../js/ops/reduceSum.js) | [Full](../js/WasmEngine.js) | [Partial, non-2D input is flattened to 1-by-N](../shaders/reduce.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
94
|
+
| `ReduceMean` | Reduction mean. | [Full](../js/ops/reduceMean.js) | [Full](../js/WasmEngine.js) | [Partial, non-2D input is flattened to 1-by-N](../shaders/reduce.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
95
|
+
| `ArgMax` | Index of maximum value. | [Full](../js/ops/argMax.js) | [Fallback](../js/WasmEngine.js) | [Missing](../js/GraphExecutor.js) | [Missing](../js/WebNNEngine.js) |
|
|
96
|
+
| `Transpose` | General N-D tensor permutation. | [Full](../js/ops/transpose.js) | [Fallback](../js/WasmEngine.js) | [Full](../shaders/generalTranspose.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
97
|
+
| `Concat`, `Concat2` | Tensor concatenation. | [Full](../js/ops/concat2.js) | [Fallback](../js/WasmEngine.js) | [Partial, `Concat` only](../shaders/concatCopy.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
98
|
+
| `Split` | Split a tensor into multiple outputs. | [Full](../js/ops/split.js) | [Fallback](../js/WasmEngine.js) | [Partial, equal-sized output slices](../shaders/split.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
99
|
+
| `Slice` | Strided slice with starts, steps, and axes. | [Full](../js/ops/slice.js) | [Full](../js/WasmEngine.js) | [Partial, up to 4D-padded metadata](../shaders/slice.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
100
|
+
| `Pad` | Constant padding. | [Full](../js/ops/pad.js) | [Full](../js/WasmEngine.js) | [Partial, image/4D-oriented metadata](../shaders/pad.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
101
|
+
| `Expand`, `Broadcast` | Broadcast a tensor to a larger shape. | [Full](../js/ops/expand.js) | [Fallback](../js/WasmEngine.js) | [Partial, 4D-padded broadcast](../shaders/expand.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
102
|
+
| `Gather` | Gather values by index. | [Full](../js/ops/gather.js) | [Full](../js/WasmEngine.js) | [Partial, axis 0 only](../shaders/gather.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
103
|
+
| `GatherElements` | Elementwise indexed gather. | [Full](../js/ops/gatherElements.js) | [Fallback](../js/WasmEngine.js) | [Missing](../js/GraphExecutor.js) | [Missing](../js/WebNNEngine.js) |
|
|
104
|
+
| `Where`, `Mask` | Select values by condition. | [Full](../js/ops/where.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/where.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
105
|
+
| `Cast` | Dtype conversion. | [Full](../js/ops/cast.js) | [Fallback](../js/WasmEngine.js) | [Partial, FP32 copy](../shaders/copy.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
106
|
+
| `DequantizeLinear` | Convert quantized values to FP32 with scale and optional zero point. | [Full](../js/ops/dequantizeLinear.js) | [Fallback](../js/WasmEngine.js) | [Full](../shaders/dequantizeLinear.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
107
|
+
| `QuantizeLinear` | Quantize FP32 values. | [Missing](../js/CPUEngine.js) | [Missing](../js/WasmEngine.js) | [Missing](../js/GraphExecutor.js) | [Missing](../js/WebNNEngine.js) |
|
|
108
|
+
| `NonMaxSuppression` | NMS for object-detection boxes. | [Full](../js/ops/nonMaxSuppression.js) | [Fallback](../js/WasmEngine.js) | [Missing](../js/GraphExecutor.js) | [Missing](../js/WebNNEngine.js) |
|
|
109
|
+
| `Reshape` | Shape-only tensor view/copy. | [Alias](../js/ops/reshape.js) | [Alias](../js/WasmEngine.js) | [Alias](../shaders/copy.wgsl) | [Full](../js/WebNNEngine.js) |
|
|
110
|
+
| `Flatten` | Shape-only flatten. | [Alias](../js/ops/reshape.js) | [Alias](../js/WasmEngine.js) | [Alias](../shaders/copy.wgsl) | [Full](../js/WebNNEngine.js) |
|
|
111
|
+
| `Squeeze` | Remove size-1 dimensions. | [Alias](../js/ops/reshape.js) | [Alias](../js/WasmEngine.js) | [Alias](../shaders/copy.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
112
|
+
| `Unsqueeze` | Add size-1 dimensions. | [Alias](../js/ops/reshape.js) | [Alias](../js/WasmEngine.js) | [Alias](../shaders/copy.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
113
|
+
| `Dropout` | Inference-time pass-through. | [Alias](../js/ops/reshape.js) | [Alias](../js/WasmEngine.js) | [Alias](../shaders/copy.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
114
|
+
| `Identity` | Pass-through copy. | [Alias](../js/ops/reshape.js) | [Alias](../js/WasmEngine.js) | [Alias](../shaders/copy.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
115
|
+
| `SpatialSoftargmaxY` | Custom vertical soft-argmax primitive for vision postprocessing. | [Full](../js/ops/spatialSoftargmaxY.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/spatialSoftargmaxY.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
116
|
+
| `ProfileX` | Custom horizontal profile/reduction primitive. | [Full](../js/ops/profileX.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/profileX.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
117
|
+
| `ProfileY` | Custom vertical profile/reduction primitive. | [Full](../js/ops/profileY.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/profileY.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
118
|
+
| `MeanHeight` | Custom height mean primitive. | [Full](../js/ops/meanHeight.js) | [Full](../js/WasmEngine.js) | [Full](../shaders/meanHeight.wgsl) | [Missing](../js/WebNNEngine.js) |
|
|
119
|
+
| `Shape` | Emit tensor shape. | [Missing](../js/CPUEngine.js) | [Missing](../js/WasmEngine.js) | [Missing](../js/GraphExecutor.js) | [Missing](../js/WebNNEngine.js) |
|
|
120
|
+
| `Size` | Emit tensor element count. | [Missing](../js/CPUEngine.js) | [Missing](../js/WasmEngine.js) | [Missing](../js/GraphExecutor.js) | [Missing](../js/WebNNEngine.js) |
|
|
121
|
+
| `TopK` | Top-k values/indices. | [Missing](../js/CPUEngine.js) | [Missing](../js/WasmEngine.js) | [Missing](../js/GraphExecutor.js) | [Missing](../js/WebNNEngine.js) |
|
|
122
|
+
|
|
123
|
+
## Native Backend Status
|
|
124
|
+
|
|
125
|
+
This table separates CPU(Native), Vulkan(Native), OpenGL(Native), and Metal(Native).
|
|
126
|
+
Vulkan and OpenGL graph ops are attempted before CPU(Native), but only for selected F32
|
|
127
|
+
nodes and only outside native decode/prefill modes. If a Vulkan/OpenGL graph op is not
|
|
128
|
+
accepted, the native dispatcher continues to CPU(Native); rows with CPU(Native)
|
|
129
|
+
`Missing` still require the GPU path to accept the node. Large native `MatMul` can also
|
|
130
|
+
use one-shot Vulkan/OpenGL offload when enabled.
|
|
131
|
+
|
|
132
|
+
Native shader generation is separate from native runtime support. The tracked
|
|
133
|
+
`shaders/*.wgsl` files are translated by `make compile_shaders` / Naga into ignored
|
|
134
|
+
build outputs under `native/shaders/{spv,glsl,gles,metal}`. An op is marked supported
|
|
135
|
+
for Vulkan/OpenGL only when `engine_runtime.c` has a dispatcher path and the native
|
|
136
|
+
backend has a C wrapper for that shader. Metal follows the same rule on Apple builds:
|
|
137
|
+
the MSL may be generated for many ops, but a row is marked supported only when
|
|
138
|
+
`engine_runtime.c` dispatches to a `metal_graph_*` wrapper.
|
|
139
|
+
|
|
140
|
+
| Operation | CPU(Native) | Vulkan(Native) | OpenGL(Native) | Metal(Native) |
|
|
141
|
+
| --- | --- | --- | --- | --- |
|
|
142
|
+
| `MatMul` | [Full](../native/kernels/broadcast_ops.c) | [Partial, large one-shot `linearF32` offload only](../native/vulkan_engine.c) | [Partial, large one-shot `linearF32RowMajor` offload only](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
143
|
+
| `Linear`, `Gemm` | [Full](../native/kernels/broadcast_ops.c) | [Partial, large one-shot `linearF32` offload only](../native/vulkan_engine.c) | [Partial, large one-shot `linearF32RowMajor` offload only](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
144
|
+
| `Conv2D` | [Full](../native/conv_f32_opt.c) | [Partial, selected F32 NHWC batch-1 graph path](../native/vulkan_engine.c) | [Partial, selected F32 NHWC batch-1 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
145
|
+
| `QConv2D` | [Full with FP32 fallback](../native/quant_cpu_opt.c) | [Missing](../native/vulkan_engine.c) | [Missing](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
146
|
+
| `Conv1D` | [Missing](../native/engine_runtime.c) | [Partial, F32 batch-1/channel-length graph path](../native/vulkan_engine.c) | [Partial, F32 batch-1/channel-length graph path](../native/opengl_engine.c) | [Partial, Apple-only F32 batch-1/channel-length graph path](../native/metal_engine.m) |
|
|
147
|
+
| `ConvTranspose2D` | [Missing](../native/engine_runtime.c) | [Partial, F32 NHWC graph path](../native/vulkan_engine.c) | [Partial, F32 NHWC graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
148
|
+
| `LayerNorm` | [Full](../native/kernels/layernorm.c) | [Partial, F32 with weight+bias graph path](../native/vulkan_engine.c) | [Partial, F32 with weight+bias graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
149
|
+
| `RMSNorm` | [Full](../native/kernels/math_nlp.c) | [Partial, F32 graph path](../native/vulkan_engine.c) | [Partial, F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
150
|
+
| `BatchNorm2D` | [Full](../native/kernels/edge_primitives.c) | [Partial, F32 NHWC graph path](../native/vulkan_engine.c) | [Partial, F32 NHWC graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
151
|
+
| `Embedding` | [Full](../native/kernels/embedding.c) | [Partial, F32 token-id graph path](../native/vulkan_engine.c) | [Partial, F32 token-id graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
152
|
+
| `SDPA` | [Full, includes decode KV-cache handling](../native/kernels/sdpa.c) | [Partial, full-forward F32 causal graph path, head_dim <= 64](../native/vulkan_engine.c) | [Partial, full-forward F32 causal graph path, head_dim <= 64](../native/opengl_engine.c) | [Partial, Apple-only full-forward F32 causal graph path, head_dim <= 64](../native/metal_engine.m) |
|
|
153
|
+
| `CrossSDPA` | [Full](../native/kernels/cross_sdpa.c) | [Partial, full-forward F32 graph path, head_dim <= 64](../native/vulkan_engine.c) | [Partial, full-forward F32 graph path, head_dim <= 64](../native/opengl_engine.c) | [Partial, Apple-only full-forward F32 graph path, head_dim <= 64](../native/metal_engine.m) |
|
|
154
|
+
| `CrossAttention` | [Missing](../native/engine_runtime.c) | [Partial, F32 Q/KV/weight graph path, d_model/head_dim <= 64](../native/vulkan_engine.c) | [Partial, F32 Q/KV/weight graph path, d_model/head_dim <= 64](../native/opengl_engine.c) | [Partial, Apple-only F32 Q/KV/weight graph path, d_model/head_dim <= 64](../native/metal_engine.m) |
|
|
155
|
+
| `MaxPool2D` | [Full](../native/engine_runtime.c) | [Partial, F32 NHWC batch-1 graph path](../native/vulkan_engine.c) | [Partial, F32 NHWC batch-1 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
156
|
+
| `AveragePool`, `AveragePool2D` | [Missing](../native/engine_runtime.c) | [Partial, F32 NHWC graph path](../native/vulkan_engine.c) | [Partial, F32 NHWC graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
157
|
+
| `GlobalAveragePool` | [Full](../native/kernels/edge_primitives.c) | [Partial, F32 NHWC graph path](../native/vulkan_engine.c) | [Partial, F32 NHWC graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
158
|
+
| `Resize` | [Missing](../native/engine_runtime.c) | [Partial, F32 NHWC batch-1 graph path](../native/vulkan_engine.c) | [Partial, F32 NHWC batch-1 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
159
|
+
| `ResizeNearest2D` | [Full](../native/engine_runtime.c) | [Partial, F32 NHWC batch-1 graph path](../native/vulkan_engine.c) | [Partial, F32 NHWC batch-1 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
160
|
+
| `UpsampleNearest2D` | [Full](../native/kernels/vision_ops.c) | [Partial, F32 NHWC batch-1 graph path](../native/vulkan_engine.c) | [Partial, F32 NHWC batch-1 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
161
|
+
| `InterpLinear1D`, `Interp1D` | [Missing](../native/engine_runtime.c) | [Partial, F32 2D channels-by-length graph path](../native/vulkan_engine.c) | [Partial, F32 2D channels-by-length graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
162
|
+
| `ReLU` | [Full](../native/kernels/activations.c) | [Partial, same-size F32 graph path](../native/vulkan_engine.c) | [Partial, same-size F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
163
|
+
| `LeakyReLU` | [Missing](../native/engine_runtime.c) | [Partial, same-size F32 graph path](../native/vulkan_engine.c) | [Partial, same-size F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
164
|
+
| `PReLU` | [Missing](../native/engine_runtime.c) | [Partial, F32 last-channel graph path](../native/vulkan_engine.c) | [Partial, F32 last-channel graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
165
|
+
| `GELU` | [Full](../native/kernels/activations.c) | [Partial, same-size F32 graph path](../native/vulkan_engine.c) | [Partial, same-size F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
166
|
+
| `SiLU`, `Swish` | [Full](../native/kernels/math_nlp.c) | [Partial, same-size F32 graph path](../native/vulkan_engine.c) | [Partial, same-size F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
167
|
+
| `Sigmoid` | [Full](../native/kernels/edge_primitives.c) | [Partial, same-size F32 graph path](../native/vulkan_engine.c) | [Partial, same-size F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
168
|
+
| `HardSwish` | [Full](../native/kernels/edge_primitives.c) | [Partial, same-size F32 graph path](../native/vulkan_engine.c) | [Partial, same-size F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
169
|
+
| `HardSigmoid` | [Full](../native/kernels/edge_primitives.c) | [Partial, same-size F32 graph path](../native/vulkan_engine.c) | [Partial, same-size F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
170
|
+
| `Tanh` | [Missing](../native/engine_runtime.c) | [Partial, same-size F32 graph path](../native/vulkan_engine.c) | [Partial, same-size F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
171
|
+
| `Clip` | [Full](../native/kernels/math_nlp.c) | [Partial, same-size F32 graph path](../native/vulkan_engine.c) | [Partial, same-size F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
172
|
+
| `Add` | [Full](../native/kernels/broadcast_ops.c) | [Partial, same-shape F32 graph path](../native/vulkan_engine.c) | [Partial, same-shape F32 graph path plus Add3 fusion](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
173
|
+
| `Mul` | [Full](../native/kernels/broadcast_ops.c) | [Partial, F32 scalar/modulo-broadcast graph path](../native/vulkan_engine.c) | [Partial, F32 scalar/modulo-broadcast graph path](../native/opengl_engine.c) | [Partial, Apple-only F32 scalar/modulo-broadcast graph path](../native/metal_engine.m) |
|
|
174
|
+
| `Sub` | [Missing](../native/engine_runtime.c) | [Partial, F32 scalar/modulo-broadcast graph path](../native/vulkan_engine.c) | [Partial, F32 scalar/modulo-broadcast graph path](../native/opengl_engine.c) | [Partial, Apple-only F32 scalar/modulo-broadcast graph path](../native/metal_engine.m) |
|
|
175
|
+
| `Div` | [Missing](../native/engine_runtime.c) | [Partial, F32 scalar/modulo-broadcast graph path](../native/vulkan_engine.c) | [Partial, F32 scalar/modulo-broadcast graph path](../native/opengl_engine.c) | [Partial, Apple-only F32 scalar/modulo-broadcast graph path](../native/metal_engine.m) |
|
|
176
|
+
| `Softmax` | [Full](../native/kernels/math_nlp.c) | [Partial, last-axis F32 graph path](../native/vulkan_engine.c) | [Partial, last-axis F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
177
|
+
| `LogSoftmax` | [Missing](../native/engine_runtime.c) | [Partial, last-axis F32 graph path](../native/vulkan_engine.c) | [Partial, last-axis F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
178
|
+
| `ReduceSum` | [Missing](../native/engine_runtime.c) | [Partial, F32 2D rows or flattened 1-by-N](../native/vulkan_engine.c) | [Partial, F32 2D rows or flattened 1-by-N](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
179
|
+
| `ReduceMean` | [Missing](../native/engine_runtime.c) | [Partial, F32 2D rows or flattened 1-by-N](../native/vulkan_engine.c) | [Partial, F32 2D rows or flattened 1-by-N](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
180
|
+
| `ArgMax` | [Missing](../native/engine_runtime.c) | [Missing](../native/vulkan_engine.c) | [Missing](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
181
|
+
| `Transpose` | [Full](../native/tensor_f32_opt.c) | [Partial, F32 graph path](../native/vulkan_engine.c) | [Partial, F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
182
|
+
| `Concat` | [Full](../native/engine_runtime.c) | [Partial, flat concat axis 0 or axis 1 with batch 1](../native/vulkan_engine.c) | [Partial, flat concat axis 0 or axis 1 with batch 1](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
183
|
+
| `Concat2` | [Missing](../native/engine_runtime.c) | [Missing](../native/vulkan_engine.c) | [Missing](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
184
|
+
| `Split` | [Missing](../native/engine_runtime.c) | [Partial, F32 multi-output axis slices](../native/vulkan_engine.c) | [Partial, F32 multi-output axis slices](../native/opengl_engine.c) | [Partial, Apple-only F32 multi-output axis slices](../native/metal_engine.m) |
|
|
185
|
+
| `Slice` | [Missing](../native/engine_runtime.c) | [Partial, F32 up to 4D with positive steps](../native/vulkan_engine.c) | [Partial, F32 up to 4D with positive steps](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
186
|
+
| `Pad` | [Missing](../native/engine_runtime.c) | [Partial, F32 up to 4D top/left constant pad](../native/vulkan_engine.c) | [Partial, F32 up to 4D top/left constant pad](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
187
|
+
| `Expand`, `Broadcast` | [Missing](../native/engine_runtime.c) | [Partial, F32 up to 4D graph path](../native/vulkan_engine.c) | [Partial, F32 up to 4D graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
188
|
+
| `Gather` | [Missing](../native/engine_runtime.c) | [Partial, F32 axis-0 graph path with F32 indices](../native/vulkan_engine.c) | [Partial, F32 axis-0 graph path with F32 indices](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
189
|
+
| `GatherElements` | [Missing](../native/engine_runtime.c) | [Missing](../native/vulkan_engine.c) | [Missing](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
190
|
+
| `Where`, `Mask` | [Missing](../native/engine_runtime.c) | [Partial, same-size F32 graph path](../native/vulkan_engine.c) | [Partial, same-size F32 graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
191
|
+
| `Cast` | [Missing](../native/engine_runtime.c) | [Partial, FP32 copy graph path](../native/vulkan_engine.c) | [Partial, FP32 copy graph path](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
192
|
+
| `DequantizeLinear` | [Partial, materializes/copies to F32](../native/quant_cpu_opt.c) | [Partial, F32-buffer scale/zero-point shader path](../native/vulkan_engine.c) | [Partial, F32-buffer scale/zero-point shader path](../native/opengl_engine.c) | [Partial, Apple-only F32-buffer scale/zero-point shader path](../native/metal_engine.m) |
|
|
193
|
+
| `QuantizeLinear` | [Full](../native/quant_cpu_opt.c) | [Partial, F32-to-int8 QTensor sidecar graph path](../native/vulkan_engine.c) | [Partial, F32-to-int8 QTensor sidecar graph path](../native/opengl_engine.c) | [Partial, Apple-only F32-to-int8 QTensor sidecar graph path](../native/metal_engine.m) |
|
|
194
|
+
| `NonMaxSuppression` | [Missing](../native/engine_runtime.c) | [Partial, F32 sequential greedy graph path](../native/vulkan_engine.c) | [Partial, F32 sequential greedy graph path](../native/opengl_engine.c) | [Partial, Apple-only F32 sequential greedy graph path](../native/metal_engine.m) |
|
|
195
|
+
| `Reshape` | [Alias](../native/engine_runtime.c) | [Alias, same-numel F32 graph alias](../native/vulkan_engine.c) | [Alias, same-numel F32 graph alias](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
196
|
+
| `Flatten` | [Alias](../native/engine_runtime.c) | [Alias, same-numel F32 graph alias](../native/vulkan_engine.c) | [Alias, same-numel F32 graph alias](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
197
|
+
| `Squeeze` | [Alias](../native/engine_runtime.c) | [Alias, same-numel F32 graph alias](../native/vulkan_engine.c) | [Alias, same-numel F32 graph alias](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
198
|
+
| `Unsqueeze` | [Alias](../native/engine_runtime.c) | [Alias, same-numel F32 graph alias](../native/vulkan_engine.c) | [Alias, same-numel F32 graph alias](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
199
|
+
| `Dropout` | [Alias](../native/engine_runtime.c) | [Alias, same-numel F32 graph alias](../native/vulkan_engine.c) | [Alias, same-numel F32 graph alias](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
200
|
+
| `Identity` | [Alias](../native/engine_runtime.c) | [Alias, same-numel F32 graph alias](../native/vulkan_engine.c) | [Alias, same-numel F32 graph alias](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
201
|
+
| `SpatialSoftargmaxY` | [Missing](../native/engine_runtime.c) | [Partial, F32 NHWC batch-1 graph path](../native/vulkan_engine.c) | [Partial, F32 NHWC batch-1 graph path](../native/opengl_engine.c) | [Partial, Apple-only F32 NHWC batch-1 graph path](../native/metal_engine.m) |
|
|
202
|
+
| `ProfileX` | [Missing](../native/engine_runtime.c) | [Partial, F32 NHWC batch-1 graph path](../native/vulkan_engine.c) | [Partial, F32 NHWC batch-1 graph path](../native/opengl_engine.c) | [Partial, Apple-only F32 NHWC batch-1 graph path](../native/metal_engine.m) |
|
|
203
|
+
| `ProfileY` | [Missing](../native/engine_runtime.c) | [Partial, F32 NHWC batch-1 graph path](../native/vulkan_engine.c) | [Partial, F32 NHWC batch-1 graph path](../native/opengl_engine.c) | [Partial, Apple-only F32 NHWC batch-1 graph path](../native/metal_engine.m) |
|
|
204
|
+
| `MeanHeight` | [Missing](../native/engine_runtime.c) | [Partial, F32 NHWC batch-1 graph path](../native/vulkan_engine.c) | [Partial, F32 NHWC batch-1 graph path](../native/opengl_engine.c) | [Partial, Apple-only F32 NHWC batch-1 graph path](../native/metal_engine.m) |
|
|
205
|
+
| `Shape` | [Missing](../native/engine_runtime.c) | [Missing](../native/vulkan_engine.c) | [Missing](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
206
|
+
| `Size` | [Missing](../native/engine_runtime.c) | [Missing](../native/vulkan_engine.c) | [Missing](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
207
|
+
| `TopK` | [Missing](../native/engine_runtime.c) | [Missing](../native/vulkan_engine.c) | [Missing](../native/opengl_engine.c) | [Init only](../native/metal_engine.m) |
|
|
208
|
+
|
|
209
|
+
## Known Gaps
|
|
210
|
+
|
|
211
|
+
1. **WebGPU output contract:** [GraphExecutor.execute()](../js/GraphExecutor.js)
|
|
212
|
+
returns the first output buffer of the last node, not a map of all
|
|
213
|
+
`graph.outputNames`. Multi-output read-back is a known WebGPU API gap.
|
|
214
|
+
2. **WebGPU partial ops:** `Gather` supports only axis 0. `Softmax` and `LogSoftmax`
|
|
215
|
+
run over the last axis. `Split` assumes equal-sized outputs. Some
|
|
216
|
+
shape/broadcast/pad kernels use 4D-padded metadata.
|
|
217
|
+
3. **WebGPU unsupported op behavior:** Missing shaders log a warning and skip
|
|
218
|
+
the node during pipeline build, leaving that output buffer unwritten. Product code
|
|
219
|
+
should prefer compile-time validation for strict GPU-only deployments.
|
|
220
|
+
4. **WebNN coverage:** WebNN is intentionally narrow. It can run common dense,
|
|
221
|
+
activation, embedding, conv, reshape, layer norm, and decomposed SDPA graphs, but
|
|
222
|
+
most vision postprocessing and shape ops are not mapped yet.
|
|
223
|
+
5. **Browser quantized Conv:** Browser [GraphLoader](../js/GraphLoader.js)
|
|
224
|
+
dequantizes `QConv2D` weights to `Conv2D`. Native keeps a real quantized Conv path.
|
|
225
|
+
6. **Native GPU coverage:** Vulkan(Native), OpenGL(Native), and Metal(Native) are graph
|
|
226
|
+
accelerators for selected F32 nodes; Vulkan/OpenGL also have large one-shot `MatMul`
|
|
227
|
+
offload. They are not equivalent to CPU(Native). Naga may generate native shader files
|
|
228
|
+
for more WGSL kernels than the dispatcher wires. Metal paths are Apple-only and load
|
|
229
|
+
ignored generated MSL from `native/shaders/metal`.
|
|
230
|
+
7. **Alias consistency:** Some aliases are not equally wired across all tiers. For
|
|
231
|
+
example, `Linear` and `Gemm` are handled by WebNN and CPU(Native), but browser
|
|
232
|
+
CPU(JS)/WASM/WebGPU dispatch primarily expects `MatMul`.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# 30 Core Operator Fusion Patterns for High-Performance Inference Engines
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
In edge AI and highly optimized inference engines (like XNNPACK, TFLite, and VolvoxAI), memory bandwidth is the primary bottleneck, not CPU compute limits. Operator Fusion addresses this "Memory Wall" by combining multiple computational nodes into a single microkernel. This keeps intermediate activations resident in L1 cache or CPU registers, drastically reducing slow DRAM read/write round-trips.
|
|
5
|
+
|
|
6
|
+
However, implementing every possible fusion combination leads to "combinatorial explosion" (massive binary bloat). Therefore, lightweight engines focus on a targeted subset of high-value fusions and utilize **selective builds** to compile only what the target model needs.
|
|
7
|
+
|
|
8
|
+
Here are the 30 core fusion patterns that cover the vast majority of modern AI architectures.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. Convolution Family (Core of Vision/CNNs)
|
|
13
|
+
These patterns account for 80%+ of the execution time in Object Detection and Image Classification models.
|
|
14
|
+
|
|
15
|
+
1. **Conv2D + Bias:** The fundamental block.
|
|
16
|
+
2. **Conv2D + Bias + ReLU / ReLU6:** The most ubiquitous standard block.
|
|
17
|
+
3. **Conv2D + Bias + HardSwish / Mish:** Heavily used in modern YOLO architectures.
|
|
18
|
+
4. **Conv2D + Add:** The core of ResNet residual connections. (In-register residual addition).
|
|
19
|
+
5. **Conv2D + Bias + Add + ReLU:** The complete end-stage of a ResNet block.
|
|
20
|
+
6. **Depthwise Conv2D + Bias + Activation:** Essential for MobileNet efficiency.
|
|
21
|
+
7. **Depthwise Conv2D + Pointwise Conv2D (Separable Conv):** Fused directly to avoid writing the intermediate depthwise output to memory.
|
|
22
|
+
8. **Transposed Conv2D (Deconv) + Bias + Activation:** Used in segmentation and generative models.
|
|
23
|
+
9. **Conv1D + Bias + Activation:** Standard for audio and time-series analysis.
|
|
24
|
+
10. **Conv3D + Bias + Activation:** Standard for video processing.
|
|
25
|
+
|
|
26
|
+
## 2. MatMul / Dense Family (Core of Transformers/LLMs)
|
|
27
|
+
Critical for avoiding massive memory bottlenecks in Large Language Models and Attention mechanisms.
|
|
28
|
+
|
|
29
|
+
11. **MatMul + Bias (Fully Connected/Linear):** Standard linear transformation.
|
|
30
|
+
12. **MatMul + Bias + GELU / Swish:** The core of Transformer MLP blocks.
|
|
31
|
+
13. **MatMul + Add:** Residual connections within Transformers.
|
|
32
|
+
14. **MatMul + Softmax:** The fundamental backbone of the Attention mechanism.
|
|
33
|
+
15. **BatchMatMul + Scale + Mask + Softmax:** The "FlashAttention" pattern, computing the entire attention block in-register.
|
|
34
|
+
16. **MatMul + Sigmoid + Mul (GLU/SwiGLU):** Essential for modern LLMs like LLaMA.
|
|
35
|
+
|
|
36
|
+
## 3. Element-wise Family (Math & Activations)
|
|
37
|
+
Though computationally light, these must be fused to prevent catastrophic memory round-trips.
|
|
38
|
+
|
|
39
|
+
17. **Add + ReLU:** Post-residual activation.
|
|
40
|
+
18. **Mul + Add (FMA):** Fused Multiply-Add (often hardware-accelerated via single SIMD instruction).
|
|
41
|
+
19. **Mul + Sigmoid:** Equivalent to SiLU/Swish activation (`x * sigmoid(x)`).
|
|
42
|
+
20. **Add + Add / Mul + Mul:** Consecutive identical operations folded together.
|
|
43
|
+
21. **Add + Clamp (Min/Max):** Value clipping/bounding (e.g., ReLU6 is just `Clamp(0, 6)`).
|
|
44
|
+
22. **Exp + Sum + Div:** Granular operations of a Softmax fused back together.
|
|
45
|
+
|
|
46
|
+
## 4. Normalization Family
|
|
47
|
+
Norm layers scan the entire memory tensor, making them extremely slow unless fused with adjacent ops.
|
|
48
|
+
|
|
49
|
+
23. **LayerNorm + MatMul:** Common in Transformers, performing linear transform immediately after normalization.
|
|
50
|
+
24. **RMSNorm + Mul:** A lighter normalization fusion used heavily in LLaMA.
|
|
51
|
+
25. **InstanceNorm + Activation:** Common in Style Transfer and generative networks.
|
|
52
|
+
|
|
53
|
+
## 5. Miscellaneous (Pooling, Quantization & Special Ops)
|
|
54
|
+
26. **GlobalAveragePooling + Flatten:** Squashes spatial dimensions into a 1D vector in a single pass.
|
|
55
|
+
27. **MaxPool + Activation:** Standard downsampling block.
|
|
56
|
+
28. **ArgMax + Gather:** Finds the highest probability index and retrieves the corresponding data/token.
|
|
57
|
+
29. **Split (Chunk) + MatMul:** Splitting Q, K, V attention vectors and immediately computing.
|
|
58
|
+
30. **Quantize + Conv/Add + Dequantize (Requantization):** Critical for INT8 pipelines. Computes integer math and scales back to floating-point without ever storing intermediate Int32 sums to DRAM.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Quickstart
|
|
2
|
+
|
|
3
|
+
VolvoxAI has three common entry points:
|
|
4
|
+
|
|
5
|
+
- Browser runtime: import `dist/volvoxai.js`, optionally serve `dist/volvoxai.wasm`,
|
|
6
|
+
and load a model package containing `config.json` plus `model.safetensors`.
|
|
7
|
+
- Node CLI: smoke-test model loading on the WASM or CPU tier.
|
|
8
|
+
- Native CLI: build `native/volvoxai` and run tensor, image, generation, or task
|
|
9
|
+
wrappers directly.
|
|
10
|
+
|
|
11
|
+
## Build the Browser Bundle
|
|
12
|
+
|
|
13
|
+
The reproducible path uses the Docker image from this repository:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
make build_web
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
That builds:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
dist/volvoxai.js
|
|
23
|
+
dist/volvoxai.min.js
|
|
24
|
+
dist/volvoxai.wasm
|
|
25
|
+
dist/v<version>/volvoxai.js
|
|
26
|
+
dist/v<version>/volvoxai.min.js
|
|
27
|
+
dist/v<version>/volvoxai.wasm
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
For local development without Docker:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install
|
|
34
|
+
npm run build:all
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The local build bundles WGSL shaders into the JS file using esbuild's text loader.
|
|
38
|
+
It does not compile the WASM module; use `make build_wasm` or copy an existing
|
|
39
|
+
`volvoxai.wasm` into `dist/` when testing the WASM tier in examples.
|
|
40
|
+
|
|
41
|
+
## Browser Usage
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
import { VolvoxAI } from './volvoxai.js';
|
|
45
|
+
|
|
46
|
+
const engine = await VolvoxAI.init(); // auto: WebNN, WebGPU, WASM, CPU
|
|
47
|
+
const graph = await engine.loadGraph('./models/my-model/model.safetensors');
|
|
48
|
+
const executor = await engine.compile(graph);
|
|
49
|
+
|
|
50
|
+
const inputs = {
|
|
51
|
+
images: new Float32Array(1 * 224 * 224 * 3),
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const output = await executor.execute(inputs);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
On WebGPU, `execute()` currently returns a single `GPUBuffer` for the final node's
|
|
58
|
+
first output. Use `executor.readBuffer(buffer, byteLength)` to map it back. WASM
|
|
59
|
+
and CPU return an object keyed by `graph.outputNames`.
|
|
60
|
+
|
|
61
|
+
## Node CLI Smoke Test
|
|
62
|
+
|
|
63
|
+
`bin/volvox.js` is a small development entry point. It verifies initialization,
|
|
64
|
+
model loading, and compilation on WASM or CPU; it is not the production inference
|
|
65
|
+
path.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
node bin/volvox.js info
|
|
69
|
+
node bin/volvox.js run --model ./models/tinystories_1m/model.safetensors --backend wasm
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Native Build
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
make build_native
|
|
76
|
+
./native/volvoxai --help
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Example graph run:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
./native/volvoxai run models/tinystories_1m \
|
|
83
|
+
--input tokens=models/tinystories_1m/tokens.i32 \
|
|
84
|
+
--input positions=models/tinystories_1m/positions.i32 \
|
|
85
|
+
--output logits=out.f32 \
|
|
86
|
+
--last-token 4
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Example text generation:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
./native/volvoxai generate models/tinystories_1m \
|
|
93
|
+
--prompt "Once upon a time, Lily" \
|
|
94
|
+
--max-new 50
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
See [native-runtime.md](native-runtime.md) for native task wrappers and accelerator
|
|
98
|
+
flags.
|
|
99
|
+
|
|
100
|
+
## Get Example Models
|
|
101
|
+
|
|
102
|
+
The `models/` directory is ignored because weights are large. Regenerate it from
|
|
103
|
+
public sources:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
make models_deps
|
|
107
|
+
make models_efficientdet
|
|
108
|
+
make models_tinystories
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Use `ONLY=int8 make models_efficientdet` to fetch and export only the int8
|
|
112
|
+
EfficientDet package.
|
|
113
|
+
|
|
114
|
+
See [models.md](models.md) for model export details.
|
|
115
|
+
|
package/docs/roadmap.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
Current known gaps:
|
|
4
|
+
|
|
5
|
+
- WebGPU multi-output readback should return a map like WASM/CPU.
|
|
6
|
+
- WebNN needs additional one-to-one builder mappings and composite formulas:
|
|
7
|
+
`RMSNorm`, `CrossSDPA`, `LogSoftmax`, `DequantizeLinear`, and `Conv1D`.
|
|
8
|
+
- Native/WebGPU shader coverage is still missing or limited for `GatherElements`,
|
|
9
|
+
`ArgMax`, `NonMaxSuppression`, and general-axis GPU `Gather`.
|
|
10
|
+
- Softmax and LogSoftmax shaders currently focus on the last axis.
|
|
11
|
+
- Browser text generation needs a higher-level streaming/autoregressive helper.
|
|
12
|
+
- INT4 weight formats are not implemented.
|
|
13
|
+
- Tokenizer parity tests against GPT-2/Neo reference BPE should be committed.
|
|
14
|
+
- A cross-tier whole-model parity and benchmark harness should be added to CI.
|
|
15
|
+
|
|
16
|
+
Native note: optimized Linux builds in headless VMs can expose platform Vulkan loader
|
|
17
|
+
issues, especially with Mesa/lavapipe. Treat real GPU validation separately from
|
|
18
|
+
software-loader smoke tests.
|
|
19
|
+
|
package/docs/testing.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Testing and Validation
|
|
2
|
+
|
|
3
|
+
VolvoxAI currently uses targeted smoke tests and per-op parity tests. The root
|
|
4
|
+
`npm test` script is still a placeholder, so publish/CI validation should call the
|
|
5
|
+
commands below directly.
|
|
6
|
+
|
|
7
|
+
## JavaScript Build and Package Checks
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm run build:all
|
|
11
|
+
npm audit
|
|
12
|
+
npm pack --dry-run
|
|
13
|
+
node ./bin/volvox.js info
|
|
14
|
+
node -e "import('./js/index.js').then(m => console.log(Object.keys(m).sort()))"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`npm pack --dry-run` should include the browser package files and not local generated
|
|
18
|
+
models, node_modules, native build outputs, or shader backup folders.
|
|
19
|
+
|
|
20
|
+
## WebGPU Per-Op Tests
|
|
21
|
+
|
|
22
|
+
`tools/webgpu_op_tests.html` builds small graphs, runs them through the real WebGPU
|
|
23
|
+
`GraphExecutor`, and compares readback against `CPUEngine`.
|
|
24
|
+
|
|
25
|
+
Local SwiftShader/software WebGPU:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
node --experimental-websocket tools/run_webgpu_tests.mjs
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Android Chrome over adb:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
adb reverse tcp:8091 tcp:8091
|
|
35
|
+
adb shell am start -a android.intent.action.VIEW -d 'http://localhost:8091/tools/webgpu_op_tests.html' com.android.chrome
|
|
36
|
+
adb forward tcp:9222 localabstract:chrome_devtools_remote
|
|
37
|
+
node --experimental-websocket tools/run_webgpu_tests.mjs --cdp=localhost:9222
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The current suite covers ReLU, Conv2D, Slice, Pad, ConvTranspose2D, Where, Gather,
|
|
41
|
+
ReduceSum, ReduceMean, AveragePool, DequantizeLinear, Cast, and Expand.
|
|
42
|
+
|
|
43
|
+
## Native Build Smoke
|
|
44
|
+
|
|
45
|
+
Compile native C:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
clang -O3 -mavx2 -mfma -pthread -I native \
|
|
49
|
+
native/cJSON.c native/safetensors.c native/kernels.c native/quant_cpu_opt.c \
|
|
50
|
+
native/conv_f32_opt.c native/tensor_f32_opt.c native/engine_runtime.c \
|
|
51
|
+
native/engine.c native/image_io.c native/kie_runtime.c native/vulkan_engine.c \
|
|
52
|
+
native/opengl_engine.c native/tokenizer.c native/nnapi_engine.c native/main.c \
|
|
53
|
+
-o /tmp/volvoxai_native_check -lm -ldl
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Generate a small deterministic model:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm run build:all
|
|
60
|
+
node tools/gen_test_model.mjs /tmp/volvox_model_check
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Run native and compare with the JS reference:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
/tmp/volvoxai_native_check run /tmp/volvox_model_check \
|
|
67
|
+
--input x=/tmp/volvox_model_check/input.f32 \
|
|
68
|
+
--output /tmp/volvox_model_check/out.f32 \
|
|
69
|
+
--debug
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The generated files include `expected.json`; compare it with `out.f32` using a small
|
|
73
|
+
script or CI helper.
|
|
74
|
+
|
|
75
|
+
## WASM Build Smoke
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
clang --target=wasm32 -O3 -msimd128 -nostdlib \
|
|
79
|
+
-Wl,--no-entry -Wl,--export-all -Wl,--allow-undefined \
|
|
80
|
+
-o /tmp/volvoxai_check.wasm native/kernels.c
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Rust Service Tests
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
cargo test --manifest-path runtime/Cargo.toml
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
This validates the Rust service wrapper and generated FFI boundary tests.
|
|
90
|
+
|
|
91
|
+
## Known Validation Limits
|
|
92
|
+
|
|
93
|
+
- Root `npm test` is currently a placeholder.
|
|
94
|
+
- WebGPU whole-model multi-output readback is a known gap.
|
|
95
|
+
- WebNN behavior depends heavily on browser version, flags, OS, and drivers.
|
|
96
|
+
- Native GPU performance claims should be rechecked on the actual target device.
|
|
97
|
+
|