@simulatte/webgpu 0.3.0 → 0.3.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/CHANGELOG.md +37 -10
- package/LICENSE +191 -0
- package/README.md +62 -48
- package/api-contract.md +67 -49
- package/architecture.md +317 -0
- package/assets/package-layers.svg +3 -3
- package/docs/doe-api-reference.html +1842 -0
- package/doe-api-design.md +237 -0
- package/examples/doe-api/README.md +19 -0
- package/examples/doe-api/buffers-readback.js +3 -2
- package/examples/{doe-routines/compute-once-like-input.js → doe-api/compute-one-shot-like-input.js} +1 -1
- package/examples/{doe-routines/compute-once-matmul.js → doe-api/compute-one-shot-matmul.js} +2 -2
- package/examples/{doe-routines/compute-once-multiple-inputs.js → doe-api/compute-one-shot-multiple-inputs.js} +1 -1
- package/examples/{doe-routines/compute-once.js → doe-api/compute-one-shot.js} +1 -1
- package/examples/doe-api/{compile-and-dispatch.js → kernel-create-and-dispatch.js} +4 -6
- package/examples/doe-api/{compute-dispatch.js → kernel-run.js} +4 -6
- package/headless-webgpu-comparison.md +3 -3
- package/jsdoc-style-guide.md +435 -0
- package/native/doe_napi.c +1481 -84
- package/package.json +18 -6
- package/prebuilds/darwin-arm64/doe_napi.node +0 -0
- package/prebuilds/darwin-arm64/libwebgpu_doe.dylib +0 -0
- package/prebuilds/darwin-arm64/metadata.json +5 -5
- package/prebuilds/linux-x64/metadata.json +1 -1
- package/scripts/generate-doe-api-docs.js +1607 -0
- package/scripts/generate-readme-assets.js +3 -3
- package/src/build_metadata.js +7 -4
- package/src/bun-ffi.js +1229 -474
- package/src/bun.js +5 -1
- package/src/compute.d.ts +16 -7
- package/src/compute.js +84 -53
- package/src/full.d.ts +16 -7
- package/src/full.js +12 -10
- package/src/index.js +679 -1324
- package/src/runtime_cli.js +17 -17
- package/src/shared/capabilities.js +144 -0
- package/src/shared/compiler-errors.js +78 -0
- package/src/shared/encoder-surface.js +295 -0
- package/src/shared/full-surface.js +514 -0
- package/src/shared/public-surface.js +82 -0
- package/src/shared/resource-lifecycle.js +120 -0
- package/src/shared/validation.js +495 -0
- package/src/webgpu_constants.js +30 -0
- package/support-contracts.md +2 -2
- package/compat-scope.md +0 -46
- package/layering-plan.md +0 -259
- package/src/auto_bind_group_layout.js +0 -32
- package/src/doe.d.ts +0 -184
- package/src/doe.js +0 -641
- package/zig-source-inventory.md +0 -468
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
# API design and JSDoc style guide
|
|
2
|
+
|
|
3
|
+
This guide defines the public JavaScript API design rules and the required
|
|
4
|
+
JSDoc format for `nursery/webgpu`.
|
|
5
|
+
|
|
6
|
+
It is the source of truth for:
|
|
7
|
+
|
|
8
|
+
- public package API shape
|
|
9
|
+
- API style naming
|
|
10
|
+
- public runtime object boundaries
|
|
11
|
+
- JSDoc structure and tone
|
|
12
|
+
|
|
13
|
+
This guide is intentionally opinionated. Public API docs should read more like
|
|
14
|
+
Flutter SDK API docs than like internal code comments: lead with the concrete
|
|
15
|
+
behavior, explain how the API fits the surface, show a small real example, and
|
|
16
|
+
call out the important boundaries.
|
|
17
|
+
|
|
18
|
+
Primary references:
|
|
19
|
+
|
|
20
|
+
- [AnimatedContainer class - Flutter API](https://api.flutter.dev/flutter/widgets/AnimatedContainer-class.html)
|
|
21
|
+
- [FutureBuilder class - Flutter API](https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html)
|
|
22
|
+
- [Effective Dart: Documentation](https://dart.dev/effective-dart/documentation)
|
|
23
|
+
|
|
24
|
+
Related design references:
|
|
25
|
+
|
|
26
|
+
- [doe-api-design.md](./doe-api-design.md)
|
|
27
|
+
- [api-contract.md](./api-contract.md)
|
|
28
|
+
|
|
29
|
+
## Scope
|
|
30
|
+
|
|
31
|
+
This guide applies to:
|
|
32
|
+
|
|
33
|
+
- exported functions and constants in `src/*.js`
|
|
34
|
+
- exported namespaces such as `doe`
|
|
35
|
+
- public classes and public methods returned by package entrypoints
|
|
36
|
+
- public methods exposed through exported objects and facades
|
|
37
|
+
|
|
38
|
+
This guide does not apply to:
|
|
39
|
+
|
|
40
|
+
- private helper functions
|
|
41
|
+
- internal implementation-only transforms
|
|
42
|
+
- internal wrapper utilities that are not part of the public surface
|
|
43
|
+
|
|
44
|
+
## API design rules
|
|
45
|
+
|
|
46
|
+
### 1. Follow the package and API style model
|
|
47
|
+
|
|
48
|
+
The package split, export surfaces, API styles (`Direct WebGPU` vs `Doe API`),
|
|
49
|
+
and helper taxonomy (`gpu.buffer.*`, `gpu.kernel.*`, `gpu.compute(...)`) are
|
|
50
|
+
defined in:
|
|
51
|
+
|
|
52
|
+
- [`./api-contract.md`](./api-contract.md) — current implemented contract
|
|
53
|
+
- [`./doe-api-design.md`](./doe-api-design.md) — target naming and design
|
|
54
|
+
principles
|
|
55
|
+
- [`./architecture.md`](./architecture.md) — full layer stack
|
|
56
|
+
|
|
57
|
+
Do not add new public helper namespaces unless they represent a stable,
|
|
58
|
+
user-visible abstraction layer. One-shot helpers like `gpu.compute(...)` should
|
|
59
|
+
stay narrower than the explicit primitive parts of `Doe API`.
|
|
60
|
+
|
|
61
|
+
### 2. Prefer explicit resource ownership
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
`Doe API` may reduce boilerplate, but it should still make resource ownership
|
|
65
|
+
and execution shape understandable.
|
|
66
|
+
|
|
67
|
+
Good:
|
|
68
|
+
|
|
69
|
+
- `gpu.buffer.create({ size: src.size, usage: "storageReadWrite" })`
|
|
70
|
+
- `gpu.kernel.run({ code, bindings, workgroups })`
|
|
71
|
+
|
|
72
|
+
Risky:
|
|
73
|
+
|
|
74
|
+
- giant option bags that hide allocations, binding rules, and reuse behavior
|
|
75
|
+
- convenience APIs that make it hard to tell when buffers are created or destroyed
|
|
76
|
+
|
|
77
|
+
### 3. Keep JS naming coherent
|
|
78
|
+
|
|
79
|
+
For JavaScript APIs:
|
|
80
|
+
|
|
81
|
+
- functions and methods use `camelCase`
|
|
82
|
+
- public token strings use JS-friendly casing
|
|
83
|
+
- avoid snake_case names on the public surface
|
|
84
|
+
|
|
85
|
+
For example:
|
|
86
|
+
|
|
87
|
+
- `storageRead`
|
|
88
|
+
- `storageReadWrite`
|
|
89
|
+
- `createBufferLike`
|
|
90
|
+
- `requestDevice`
|
|
91
|
+
|
|
92
|
+
### 4. Prefer singular helper namespaces
|
|
93
|
+
|
|
94
|
+
When a namespace represents one object domain, prefer the singular form:
|
|
95
|
+
|
|
96
|
+
- `gpu.buffer.*`
|
|
97
|
+
- `gpu.kernel.*`
|
|
98
|
+
|
|
99
|
+
Treat plural namespaces in the current API as compatibility debt rather than
|
|
100
|
+
the naming target for future design work.
|
|
101
|
+
|
|
102
|
+
### 5. Fail clearly on unsupported states
|
|
103
|
+
|
|
104
|
+
Unsupported or out-of-scope behavior should fail explicitly with actionable
|
|
105
|
+
messages. Public docs should state those boundaries when they are easy to miss.
|
|
106
|
+
|
|
107
|
+
Examples:
|
|
108
|
+
|
|
109
|
+
- compute facade intentionally omits render and surface APIs
|
|
110
|
+
- `compute(...)` rejects raw numeric usage flags
|
|
111
|
+
- bare buffers without Doe metadata require `{ buffer, access }`
|
|
112
|
+
|
|
113
|
+
## Public documentation rules
|
|
114
|
+
|
|
115
|
+
### 1. Put public docs on the `.js` implementation
|
|
116
|
+
|
|
117
|
+
The `.js` file is the source of truth for public behavior. The `.d.ts` files
|
|
118
|
+
carry type shape, but the primary API docs live on the implementation.
|
|
119
|
+
|
|
120
|
+
### 2. Document every public function, class, method, and namespace
|
|
121
|
+
|
|
122
|
+
That includes:
|
|
123
|
+
|
|
124
|
+
- exported functions and constants
|
|
125
|
+
- exported namespaces
|
|
126
|
+
- public runtime classes returned by package entrypoints
|
|
127
|
+
- public methods on returned objects and facades
|
|
128
|
+
|
|
129
|
+
If users can call it directly, it needs JSDoc.
|
|
130
|
+
|
|
131
|
+
### 3. Do not document private helpers
|
|
132
|
+
|
|
133
|
+
Do not add JSDoc to:
|
|
134
|
+
|
|
135
|
+
- private helper functions
|
|
136
|
+
- internal normalization helpers
|
|
137
|
+
- private wrapper utilities that are not part of the public contract
|
|
138
|
+
|
|
139
|
+
Public API comments should not be diluted by internal commentary.
|
|
140
|
+
|
|
141
|
+
### 4. Do not use `//` doc comments in public API files
|
|
142
|
+
|
|
143
|
+
Public API explanation belongs in JSDoc. Do not add one-line `//` comments
|
|
144
|
+
above public functions, classes, or methods when the JSDoc should carry that
|
|
145
|
+
meaning instead.
|
|
146
|
+
|
|
147
|
+
## Required JSDoc structure
|
|
148
|
+
|
|
149
|
+
Use this order for public APIs:
|
|
150
|
+
|
|
151
|
+
```js
|
|
152
|
+
/**
|
|
153
|
+
* One-sentence summary in plain English.
|
|
154
|
+
*
|
|
155
|
+
* Surface: package layer or namespace.
|
|
156
|
+
* Input: short plain-English summary of the main inputs.
|
|
157
|
+
* Returns: short plain-English summary of the main result.
|
|
158
|
+
*
|
|
159
|
+
* Short prose paragraph explaining what the API does, how it behaves, and
|
|
160
|
+
* why a caller would use it.
|
|
161
|
+
*
|
|
162
|
+
* This example shows the API in its basic form.
|
|
163
|
+
*
|
|
164
|
+
* ```js
|
|
165
|
+
* // minimal real usage
|
|
166
|
+
* ```
|
|
167
|
+
*
|
|
168
|
+
* - important defaults
|
|
169
|
+
* - failure modes
|
|
170
|
+
* - scope boundaries
|
|
171
|
+
*/
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Do not add narrative section labels like:
|
|
175
|
+
|
|
176
|
+
- `What this does:`
|
|
177
|
+
- `Example:`
|
|
178
|
+
- `Edge cases:`
|
|
179
|
+
|
|
180
|
+
For future Doe helper docs, the following short contract lines are required:
|
|
181
|
+
|
|
182
|
+
- `Surface:`
|
|
183
|
+
- `Input:`
|
|
184
|
+
- `Returns:`
|
|
185
|
+
|
|
186
|
+
These are machine-scannable anchors, not prose section headings.
|
|
187
|
+
|
|
188
|
+
## JSDoc content rules
|
|
189
|
+
|
|
190
|
+
### Summary line
|
|
191
|
+
|
|
192
|
+
The first line must be a single sentence that states the concrete action.
|
|
193
|
+
|
|
194
|
+
Prefer verbs:
|
|
195
|
+
|
|
196
|
+
- `Create`
|
|
197
|
+
- `Request`
|
|
198
|
+
- `Read`
|
|
199
|
+
- `Run`
|
|
200
|
+
- `Compile`
|
|
201
|
+
- `Report`
|
|
202
|
+
- `Install`
|
|
203
|
+
- `Release`
|
|
204
|
+
- `Return`
|
|
205
|
+
|
|
206
|
+
Good:
|
|
207
|
+
|
|
208
|
+
- `Request a Doe-backed adapter from the full package surface.`
|
|
209
|
+
- `Create a compute-only GPU facade backed by the Doe runtime.`
|
|
210
|
+
- `Read a buffer back into a typed array.`
|
|
211
|
+
|
|
212
|
+
Bad:
|
|
213
|
+
|
|
214
|
+
- `Helper for compute.`
|
|
215
|
+
- `Convenience method.`
|
|
216
|
+
- `Used for device workflows.`
|
|
217
|
+
|
|
218
|
+
### Contract lines
|
|
219
|
+
|
|
220
|
+
Immediately after the summary line, add:
|
|
221
|
+
|
|
222
|
+
- `Surface:`
|
|
223
|
+
- `Input:`
|
|
224
|
+
- `Returns:`
|
|
225
|
+
|
|
226
|
+
Keep them short and concrete.
|
|
227
|
+
|
|
228
|
+
Good:
|
|
229
|
+
|
|
230
|
+
- `Surface: Doe API (\`gpu.kernel.*\`).`
|
|
231
|
+
- `Input: WGSL source, entry point, and representative bindings.`
|
|
232
|
+
- `Returns: A reusable kernel object with \`.dispatch(...)\`.`
|
|
233
|
+
|
|
234
|
+
Bad:
|
|
235
|
+
|
|
236
|
+
- `Surface: API`
|
|
237
|
+
- `Input: options`
|
|
238
|
+
- repeating full type declarations from `.d.ts`
|
|
239
|
+
|
|
240
|
+
### Prose paragraph before the example
|
|
241
|
+
|
|
242
|
+
After the summary line, include a short prose paragraph explaining:
|
|
243
|
+
|
|
244
|
+
- what happens
|
|
245
|
+
- what is returned, allocated, installed, wrapped, or destroyed
|
|
246
|
+
- how it fits the package surface or layer model when relevant
|
|
247
|
+
|
|
248
|
+
This paragraph should usually be 1-3 short sentences.
|
|
249
|
+
|
|
250
|
+
Good:
|
|
251
|
+
|
|
252
|
+
- explain whether the API allocates buffers, submits work, waits, or reads back
|
|
253
|
+
- explain whether an object is full-surface or compute-only
|
|
254
|
+
- explain whether the API belongs to `Direct WebGPU` or `Doe API`, and whether it is an explicit primitive or a more opinionated one-shot helper when that matters
|
|
255
|
+
|
|
256
|
+
Do not:
|
|
257
|
+
|
|
258
|
+
- restate the function name in slightly different words
|
|
259
|
+
- narrate private helper calls
|
|
260
|
+
- paste type information as prose
|
|
261
|
+
|
|
262
|
+
### Example lead-in sentence
|
|
263
|
+
|
|
264
|
+
Immediately above every example block, add one short sentence explaining what
|
|
265
|
+
the example demonstrates.
|
|
266
|
+
|
|
267
|
+
Current default pattern:
|
|
268
|
+
|
|
269
|
+
- `This example shows the API in its basic form.`
|
|
270
|
+
|
|
271
|
+
If a more specific sentence is better, use it.
|
|
272
|
+
|
|
273
|
+
Good alternatives:
|
|
274
|
+
|
|
275
|
+
- `This example shows the common upload-then-dispatch flow.`
|
|
276
|
+
- `This example shows how to reuse a compiled kernel.`
|
|
277
|
+
- `This example shows the unbound helper form with an explicit device.`
|
|
278
|
+
|
|
279
|
+
### Example block
|
|
280
|
+
|
|
281
|
+
Every public API needs a real usage example.
|
|
282
|
+
|
|
283
|
+
Requirements:
|
|
284
|
+
|
|
285
|
+
- use runnable or near-runnable code
|
|
286
|
+
- keep it minimal
|
|
287
|
+
- use actual package exports and actual method names
|
|
288
|
+
- show the most likely usage first
|
|
289
|
+
|
|
290
|
+
Do:
|
|
291
|
+
|
|
292
|
+
- use `await doe.requestDevice()` for the direct Doe API entry path
|
|
293
|
+
- use `gpu.buffer.create({ size: src.size, ... })` when showing size-copy allocation
|
|
294
|
+
- use `gpu.compute(...)` only for true one-shot Doe API examples
|
|
295
|
+
|
|
296
|
+
Do not:
|
|
297
|
+
|
|
298
|
+
- use pseudocode
|
|
299
|
+
- use fake imports
|
|
300
|
+
- add unrelated setup unless the API requires it
|
|
301
|
+
|
|
302
|
+
### Bullet notes after the example
|
|
303
|
+
|
|
304
|
+
After the example, use short bullets for the important constraints:
|
|
305
|
+
|
|
306
|
+
- defaults
|
|
307
|
+
- accepted shorthand forms
|
|
308
|
+
- throws or explicit failure behavior
|
|
309
|
+
- package-surface differences
|
|
310
|
+
- cases where the caller should drop to a lower API style
|
|
311
|
+
|
|
312
|
+
These bullets are where edge cases live, even though the doc does not label
|
|
313
|
+
them as an `Edge cases:` section.
|
|
314
|
+
|
|
315
|
+
## What to document by surface
|
|
316
|
+
|
|
317
|
+
### Package entrypoints
|
|
318
|
+
|
|
319
|
+
For `create`, `setupGlobals`, `requestAdapter`, `requestDevice`,
|
|
320
|
+
`providerInfo`, `createDoeRuntime`, and `runDawnVsDoeCompare`:
|
|
321
|
+
|
|
322
|
+
- explain what object they return
|
|
323
|
+
- explain whether they create, install, request, or report
|
|
324
|
+
- explain whether they are in-process runtime APIs or tooling APIs
|
|
325
|
+
- call out failure behavior when relevant
|
|
326
|
+
|
|
327
|
+
### Runtime classes and facade objects
|
|
328
|
+
|
|
329
|
+
For objects like `GPU`, adapter, device, queue, buffer, command encoder,
|
|
330
|
+
render pass encoder, compute pass encoder, and the compute-only wrapper
|
|
331
|
+
objects:
|
|
332
|
+
|
|
333
|
+
- explain what the object represents
|
|
334
|
+
- explain where callers obtain it
|
|
335
|
+
- explain what subset of the full surface it owns
|
|
336
|
+
|
|
337
|
+
For their public methods:
|
|
338
|
+
|
|
339
|
+
- explain what operation happens
|
|
340
|
+
- explain whether it records, allocates, submits, waits, maps, or destroys
|
|
341
|
+
- explain wrapper behavior when a compute facade forwards into the full surface
|
|
342
|
+
|
|
343
|
+
### Doe namespaces
|
|
344
|
+
|
|
345
|
+
For `doe` and nested namespaces:
|
|
346
|
+
|
|
347
|
+
- explain the API style split
|
|
348
|
+
- explain when to use `requestDevice()` versus `bind(device)`
|
|
349
|
+
- explain bound versus unbound Doe forms
|
|
350
|
+
- explain where a more opinionated one-shot Doe API helper is intentionally narrower than the rest of `Doe API`
|
|
351
|
+
|
|
352
|
+
## Style rules
|
|
353
|
+
|
|
354
|
+
1. Write in present tense.
|
|
355
|
+
2. Prefer short paragraphs and flat bullets.
|
|
356
|
+
3. Use concrete nouns: `GPU`, adapter, device, buffer, pipeline, typed array.
|
|
357
|
+
4. Explain observable behavior, not internal implementation trivia.
|
|
358
|
+
5. Keep examples in ASCII.
|
|
359
|
+
6. Keep examples aligned with the actual shipped API.
|
|
360
|
+
7. Keep docs package-accurate:
|
|
361
|
+
`@simulatte/webgpu` is headless full surface;
|
|
362
|
+
`@simulatte/webgpu/compute` is compute-only;
|
|
363
|
+
browser ownership belongs to `nursery/fawn-browser`.
|
|
364
|
+
|
|
365
|
+
## Anti-patterns
|
|
366
|
+
|
|
367
|
+
Do not write docs like this:
|
|
368
|
+
|
|
369
|
+
```js
|
|
370
|
+
/**
|
|
371
|
+
* Helper for compute.
|
|
372
|
+
*/
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
```js
|
|
376
|
+
/**
|
|
377
|
+
* Binds a device.
|
|
378
|
+
*/
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
```js
|
|
382
|
+
/**
|
|
383
|
+
* Run compute.
|
|
384
|
+
*
|
|
385
|
+
* ```js
|
|
386
|
+
* // omitted
|
|
387
|
+
* ```
|
|
388
|
+
*/
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
These fail because they omit behavior, layering, concrete usage, or the
|
|
392
|
+
important constraints.
|
|
393
|
+
|
|
394
|
+
## Good pattern
|
|
395
|
+
|
|
396
|
+
```js
|
|
397
|
+
/**
|
|
398
|
+
* Run a narrow typed-array routine.
|
|
399
|
+
*
|
|
400
|
+
* This accepts typed-array or Doe input specs, allocates temporary buffers,
|
|
401
|
+
* dispatches the compute job once, reads the output back, and returns the
|
|
402
|
+
* requested typed array result.
|
|
403
|
+
*
|
|
404
|
+
* This example shows a basic one-shot Doe API path with a typed-array input.
|
|
405
|
+
*
|
|
406
|
+
* ```js
|
|
407
|
+
* const out = await gpu.compute({
|
|
408
|
+
* code: WGSL,
|
|
409
|
+
* inputs: [new Float32Array([1, 2, 3, 4])],
|
|
410
|
+
* output: { type: Float32Array },
|
|
411
|
+
* workgroups: [4, 1],
|
|
412
|
+
* });
|
|
413
|
+
* ```
|
|
414
|
+
*
|
|
415
|
+
* - This is intentionally opinionated: it rejects raw numeric WebGPU usage
|
|
416
|
+
* flags and expects Doe usage tokens when usage is specified.
|
|
417
|
+
* - Output size defaults from `likeInput` or the first input when possible;
|
|
418
|
+
* if no size can be derived, it throws instead of guessing.
|
|
419
|
+
* - Temporary buffers created internally are destroyed before the call returns.
|
|
420
|
+
*/
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## Review checklist
|
|
424
|
+
|
|
425
|
+
Before merging a public API doc change, verify:
|
|
426
|
+
|
|
427
|
+
- the summary line states the concrete action
|
|
428
|
+
- the prose paragraph explains what happens and what is returned or changed
|
|
429
|
+
- there is a one-sentence example lead-in immediately above the example
|
|
430
|
+
- the example uses the real package API
|
|
431
|
+
- the bullets cover defaults, throws, and boundary conditions
|
|
432
|
+
- the docs reflect the current full-vs-compute split
|
|
433
|
+
- the docs reflect the current `Direct WebGPU` / `Doe API` model
|
|
434
|
+
- no private helpers were documented
|
|
435
|
+
- no `//` doc comments were added
|