@simulatte/webgpu-doe 0.1.0 → 0.1.2
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/README.md +128 -72
- package/native/doe_napi.c +633 -80
- package/package.json +12 -7
- package/prebuilds/darwin-arm64/doe_napi.node +0 -0
- package/prebuilds/darwin-arm64/libdoe_webgpu.dylib +0 -0
- package/src/index.js +143 -5
package/README.md
CHANGED
|
@@ -1,116 +1,172 @@
|
|
|
1
1
|
# @simulatte/webgpu-doe
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Headless WebGPU for Node.js on the Doe runtime.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
standard `wgpu*` C ABI. This package wraps it as a Node.js N-API addon, giving
|
|
7
|
-
JavaScript code a WebGPU compute surface without depending on browser runtimes.
|
|
5
|
+
**[Fawn](https://github.com/clocksmith/fawn/tree/main/nursery/webgpu-doe)** · **[npm](https://www.npmjs.com/package/@simulatte/webgpu-doe)** · **[simulatte.world](https://simulatte.world)**
|
|
8
6
|
|
|
9
|
-
##
|
|
7
|
+
## Install
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
```sh
|
|
10
|
+
npm install @simulatte/webgpu-doe
|
|
11
|
+
```
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
The published package currently targets `darwin-arm64`. The N-API addon builds
|
|
14
|
+
from C source during install via `node-gyp`, so a local C toolchain is
|
|
15
|
+
required (`xcode-select --install` on macOS).
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
- A C compiler (node-gyp builds the N-API addon on `npm install`)
|
|
19
|
-
- `libdoe_webgpu` shared library (`.dylib` / `.so` / `.dll`)
|
|
20
|
-
- Dawn sidecar library (`libwebgpu_dawn`) — loaded by `libdoe_webgpu` at runtime
|
|
17
|
+
## Quick start
|
|
21
18
|
|
|
22
|
-
|
|
19
|
+
```js
|
|
20
|
+
import { create, globals } from '@simulatte/webgpu-doe';
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
const gpu = create();
|
|
23
|
+
const adapter = await gpu.requestAdapter();
|
|
24
|
+
const device = await adapter.requestDevice();
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
zig build dropin
|
|
29
|
-
# produces zig-out/lib/libdoe_webgpu.{dylib,so}
|
|
30
|
-
```
|
|
26
|
+
console.log(device.limits.maxComputeWorkgroupSizeX); // 1024
|
|
27
|
+
console.log(device.features.has('shader-f16')); // true
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
// Standard WebGPU compute workflow
|
|
30
|
+
const buffer = device.createBuffer({
|
|
31
|
+
size: 64,
|
|
32
|
+
usage: globals.GPUBufferUsage.STORAGE | globals.GPUBufferUsage.COPY_SRC,
|
|
33
|
+
});
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
const shader = device.createShaderModule({
|
|
36
|
+
code: `
|
|
37
|
+
@group(0) @binding(0) var<storage, read_write> data: array<f32>;
|
|
38
|
+
@compute @workgroup_size(64)
|
|
39
|
+
fn main(@builtin(global_invocation_id) id: vec3u) {
|
|
40
|
+
data[id.x] = data[id.x] * 2.0;
|
|
41
|
+
}
|
|
42
|
+
`,
|
|
43
|
+
});
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
npm install @simulatte/webgpu-doe
|
|
45
|
+
// ... create pipeline, bind group, encode, dispatch, readback
|
|
39
46
|
```
|
|
40
47
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
48
|
+
The package loads `libdoe_webgpu` and exposes a WebGPU-shaped API for
|
|
49
|
+
headless compute and basic render work. See [more examples](#more-examples)
|
|
50
|
+
below for `navigator.gpu` setup and provider inspection.
|
|
44
51
|
|
|
45
|
-
##
|
|
52
|
+
## Why Doe
|
|
46
53
|
|
|
47
|
-
|
|
54
|
+
- Native path: JavaScript calls into an N-API addon, which loads
|
|
55
|
+
`libdoe_webgpu` and submits work through Doe's Metal backend.
|
|
56
|
+
- Runtime ownership: WGSL is compiled to MSL inside Doe's AST-based compiler
|
|
57
|
+
instead of going through Dawn.
|
|
58
|
+
- Small package payload: the shared library is about 2 MB on `darwin-arm64`.
|
|
59
|
+
- WebGPU-shaped surface: `requestAdapter`, `requestDevice`, buffer mapping,
|
|
60
|
+
bind groups, compute pipelines, command encoders, and basic render passes are
|
|
61
|
+
exposed directly from the package.
|
|
48
62
|
|
|
49
|
-
|
|
50
|
-
2. `<package>/prebuilds/<platform>-<arch>/libdoe_webgpu.{ext}` (future prebuilds)
|
|
51
|
-
3. `<workspace>/zig/zig-out/lib/libdoe_webgpu.{ext}` (monorepo dev layout)
|
|
52
|
-
4. `<cwd>/zig/zig-out/lib/libdoe_webgpu.{ext}`
|
|
63
|
+
## Status
|
|
53
64
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
`libwebgpu_dawn.dylib` / `libwebgpu_dawn.so`.
|
|
65
|
+
Current package target:
|
|
66
|
+
- macOS arm64: prebuilt library and tested package path
|
|
57
67
|
|
|
58
|
-
|
|
59
|
-
export DOE_WEBGPU_LIB=/path/to/libdoe_webgpu.dylib
|
|
60
|
-
export DYLD_LIBRARY_PATH=/path/to/dawn/out/Release
|
|
61
|
-
node your-app.js
|
|
62
|
-
```
|
|
68
|
+
Backend readiness:
|
|
63
69
|
|
|
64
|
-
|
|
70
|
+
| Backend | Compute | Render | WGSL compiler | Status |
|
|
71
|
+
|---------|---------|--------|---------------|--------|
|
|
72
|
+
| **Metal** (macOS) | Production | Basic (no vertex/index) | WGSL -> MSL (AST-based) | Ready for package use |
|
|
73
|
+
| **Vulkan** (Linux) | WIP | Not started | WGSL -> SPIR-V needed | Experimental |
|
|
74
|
+
| **D3D12** (Windows) | WIP | Not started | WGSL -> HLSL/DXIL needed | Experimental |
|
|
65
75
|
|
|
66
|
-
|
|
76
|
+
Metal currently covers the package's intended use: bind groups 0-3, buffer
|
|
77
|
+
map/unmap, indirect dispatch, `shader-f16`, subgroups, override constants,
|
|
78
|
+
workgroup shared memory, multiple entry points, textures, samplers, and basic
|
|
79
|
+
render-pass execution.
|
|
67
80
|
|
|
68
|
-
|
|
69
|
-
|
|
81
|
+
Vulkan and D3D12 already have native runtime paths for instance creation,
|
|
82
|
+
compute dispatch, and buffer upload, but they still need shader translation,
|
|
83
|
+
bind group management, buffer map/unmap, textures, and render pipelines.
|
|
70
84
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const device = await adapter.requestDevice();
|
|
85
|
+
Performance snapshot from the Fawn Dawn-vs-Doe harness on Apple Silicon with
|
|
86
|
+
strict comparability checks:
|
|
74
87
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
88
|
+
- Compute e2e: 1.5x faster (0.23ms vs 0.35ms, 4096 threads)
|
|
89
|
+
- Buffer upload: faster across 1 KB to 4 GB (8 sizes claimable)
|
|
90
|
+
- Atomics: workgroup atomic and non-atomic both claimable
|
|
91
|
+
- Matrix-vector multiply: 3 variants claimable
|
|
92
|
+
- Concurrent execution: claimable
|
|
93
|
+
- Zero-init workgroup memory: claimable
|
|
94
|
+
- Draw throughput: 200k draws claimable
|
|
95
|
+
- Binary size: about 2 MB vs Dawn's about 11 MB
|
|
96
|
+
|
|
97
|
+
19 of 30 workloads are currently claimable. The remaining 11 are limited by
|
|
98
|
+
per-command Metal command buffer creation overhead (~350us vs Dawn's ~30us).
|
|
99
|
+
See `fawn/bench/` and [`status.md`](../../status.md) for methodology and the
|
|
100
|
+
broader backend matrix.
|
|
101
|
+
|
|
102
|
+
## API surface
|
|
103
|
+
|
|
104
|
+
Compute:
|
|
105
|
+
|
|
106
|
+
- `create()` / `setupGlobals()` / `requestAdapter()` / `requestDevice()`
|
|
107
|
+
- `device.createBuffer()` / `device.createShaderModule()` (WGSL)
|
|
108
|
+
- `device.createComputePipeline()` / `device.createComputePipelineAsync()`
|
|
109
|
+
- `device.createBindGroupLayout()` / `device.createBindGroup()`
|
|
110
|
+
- `device.createPipelineLayout()` / `pipeline.getBindGroupLayout()`
|
|
111
|
+
- `device.createCommandEncoder()` / `encoder.beginComputePass()`
|
|
112
|
+
- `pass.setPipeline()` / `pass.setBindGroup()` / `pass.dispatchWorkgroups()`
|
|
113
|
+
- `pass.dispatchWorkgroupsIndirect()`
|
|
114
|
+
- `encoder.copyBufferToBuffer()` / `queue.submit()` / `queue.writeBuffer()`
|
|
115
|
+
- `buffer.mapAsync()` / `buffer.getMappedRange()` / `buffer.unmap()`
|
|
116
|
+
- `queue.onSubmittedWorkDone()`
|
|
117
|
+
|
|
118
|
+
Render:
|
|
119
|
+
|
|
120
|
+
- `device.createTexture()` / `texture.createView()` / `device.createSampler()`
|
|
121
|
+
- `device.createRenderPipeline()` / `encoder.beginRenderPass()`
|
|
122
|
+
- `renderPass.setPipeline()` / `renderPass.draw()` / `renderPass.end()`
|
|
80
123
|
|
|
81
|
-
|
|
124
|
+
Device capabilities:
|
|
125
|
+
|
|
126
|
+
- `device.limits` / `adapter.limits`
|
|
127
|
+
- `device.features` / `adapter.features` with `shader-f16`
|
|
128
|
+
|
|
129
|
+
Current gaps:
|
|
130
|
+
- Canvas and surface presentation
|
|
131
|
+
- Vertex and index buffer binding in render passes
|
|
132
|
+
- Full render pipeline descriptor parsing
|
|
133
|
+
|
|
134
|
+
## More examples
|
|
82
135
|
|
|
83
136
|
```js
|
|
84
137
|
import { setupGlobals } from '@simulatte/webgpu-doe';
|
|
85
138
|
|
|
86
139
|
setupGlobals(globalThis);
|
|
87
|
-
|
|
88
140
|
const adapter = await navigator.gpu.requestAdapter();
|
|
89
|
-
const device = await adapter.requestDevice();
|
|
90
141
|
```
|
|
91
142
|
|
|
92
|
-
###
|
|
143
|
+
### Provider info
|
|
93
144
|
|
|
94
145
|
```js
|
|
95
|
-
import {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const device = await requestDevice();
|
|
146
|
+
import { providerInfo } from '@simulatte/webgpu-doe';
|
|
147
|
+
console.log(providerInfo());
|
|
148
|
+
// { module: '@simulatte/webgpu-doe', loaded: true, doeNative: true, ... }
|
|
99
149
|
```
|
|
100
150
|
|
|
101
|
-
##
|
|
151
|
+
## Configuration
|
|
152
|
+
|
|
153
|
+
The library search order:
|
|
154
|
+
|
|
155
|
+
1. `DOE_WEBGPU_LIB` environment variable (full path)
|
|
156
|
+
2. `<package>/prebuilds/<platform>-<arch>/libdoe_webgpu.{ext}`
|
|
157
|
+
3. `<workspace>/zig/zig-out/lib/libdoe_webgpu.{ext}` (monorepo layout)
|
|
158
|
+
4. `<cwd>/zig/zig-out/lib/libdoe_webgpu.{ext}`
|
|
102
159
|
|
|
103
|
-
|
|
160
|
+
## Building from source
|
|
104
161
|
|
|
105
|
-
|
|
106
|
-
- Buffer create, map, unmap, destroy
|
|
107
|
-
- Shader module creation (WGSL)
|
|
108
|
-
- Compute pipeline, bind group layout, bind group, pipeline layout
|
|
109
|
-
- Command encoder, compute pass (setPipeline, setBindGroup, dispatch, end)
|
|
110
|
-
- Buffer-to-buffer copy
|
|
111
|
-
- Queue submit, queue writeBuffer
|
|
162
|
+
Requires [Zig](https://ziglang.org/download/) (0.15+).
|
|
112
163
|
|
|
113
|
-
|
|
164
|
+
```sh
|
|
165
|
+
git clone https://github.com/clocksmith/fawn
|
|
166
|
+
cd fawn/zig
|
|
167
|
+
zig build dropin
|
|
168
|
+
# Output: zig-out/lib/libdoe_webgpu.{dylib,so}
|
|
169
|
+
```
|
|
114
170
|
|
|
115
171
|
## License
|
|
116
172
|
|