@graphty/webgpu-graph-algorithms 0.5.0 → 0.6.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/README.md +104 -52
- package/dist/browser.js +1 -1
- package/dist/chunks/{context-CRbw2Wyo.js → context-BXqgCifx.js} +225 -33
- package/dist/chunks/context-BXqgCifx.js.map +1 -0
- package/dist/node.js +1 -1
- package/dist/src/accelerator.d.ts +12 -10
- package/dist/src/accelerator.d.ts.map +1 -1
- package/dist/src/accelerator.js +32 -10
- package/dist/src/accelerator.js.map +1 -1
- package/dist/src/algorithms/components.d.ts.map +1 -1
- package/dist/src/algorithms/components.js +12 -13
- package/dist/src/algorithms/components.js.map +1 -1
- package/dist/src/algorithms/degree.d.ts +6 -8
- package/dist/src/algorithms/degree.d.ts.map +1 -1
- package/dist/src/algorithms/degree.js +58 -35
- package/dist/src/algorithms/degree.js.map +1 -1
- package/dist/src/algorithms/pagerank.d.ts.map +1 -1
- package/dist/src/algorithms/pagerank.js +16 -14
- package/dist/src/algorithms/pagerank.js.map +1 -1
- package/dist/src/algorithms/power-iteration.d.ts +2 -2
- package/dist/src/algorithms/power-iteration.d.ts.map +1 -1
- package/dist/src/algorithms/power-iteration.js +17 -14
- package/dist/src/algorithms/power-iteration.js.map +1 -1
- package/dist/src/constants.d.ts +85 -8
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +85 -8
- package/dist/src/constants.js.map +1 -1
- package/dist/src/errors.d.ts +3 -2
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/errors.js +2 -1
- package/dist/src/errors.js.map +1 -1
- package/dist/src/index.d.ts +10 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +14 -5
- package/dist/src/index.js.map +1 -1
- package/dist/src/kernel/dispatch.d.ts +8 -3
- package/dist/src/kernel/dispatch.d.ts.map +1 -1
- package/dist/src/kernel/dispatch.js +18 -7
- package/dist/src/kernel/dispatch.js.map +1 -1
- package/dist/src/kernel/kernel.d.ts +30 -1
- package/dist/src/kernel/kernel.d.ts.map +1 -1
- package/dist/src/kernel/kernel.js +49 -5
- package/dist/src/kernel/kernel.js.map +1 -1
- package/dist/src/kernel/prelude.d.ts.map +1 -1
- package/dist/src/kernel/prelude.js +9 -1
- package/dist/src/kernel/prelude.js.map +1 -1
- package/dist/src/kernel/profiler.d.ts +15 -3
- package/dist/src/kernel/profiler.d.ts.map +1 -1
- package/dist/src/kernel/profiler.js +27 -4
- package/dist/src/kernel/profiler.js.map +1 -1
- package/dist/src/kernels.d.ts +18 -8
- package/dist/src/kernels.d.ts.map +1 -1
- package/dist/src/kernels.js +345 -22
- package/dist/src/kernels.js.map +1 -1
- package/dist/src/layouts/calibrate.d.ts +51 -0
- package/dist/src/layouts/calibrate.d.ts.map +1 -0
- package/dist/src/layouts/calibrate.js +172 -0
- package/dist/src/layouts/calibrate.js.map +1 -0
- package/dist/src/layouts/force-simulation.d.ts +42 -5
- package/dist/src/layouts/force-simulation.d.ts.map +1 -1
- package/dist/src/layouts/force-simulation.js +84 -22
- package/dist/src/layouts/force-simulation.js.map +1 -1
- package/dist/src/layouts/forceatlas2.d.ts +107 -38
- package/dist/src/layouts/forceatlas2.d.ts.map +1 -1
- package/dist/src/layouts/forceatlas2.js +297 -290
- package/dist/src/layouts/forceatlas2.js.map +1 -1
- package/dist/src/layouts/fruchterman-reingold.d.ts +241 -0
- package/dist/src/layouts/fruchterman-reingold.d.ts.map +1 -0
- package/dist/src/layouts/fruchterman-reingold.js +739 -0
- package/dist/src/layouts/fruchterman-reingold.js.map +1 -0
- package/dist/src/layouts/model-common.d.ts +140 -0
- package/dist/src/layouts/model-common.d.ts.map +1 -0
- package/dist/src/layouts/model-common.js +269 -0
- package/dist/src/layouts/model-common.js.map +1 -0
- package/dist/src/layouts/repulsion-grid.d.ts +152 -0
- package/dist/src/layouts/repulsion-grid.d.ts.map +1 -0
- package/dist/src/layouts/repulsion-grid.js +318 -0
- package/dist/src/layouts/repulsion-grid.js.map +1 -0
- package/dist/src/layouts/spring-electrical.d.ts +224 -0
- package/dist/src/layouts/spring-electrical.d.ts.map +1 -0
- package/dist/src/layouts/spring-electrical.js +665 -0
- package/dist/src/layouts/spring-electrical.js.map +1 -0
- package/dist/src/memory/residency.d.ts +6 -2
- package/dist/src/memory/residency.d.ts.map +1 -1
- package/dist/src/memory/residency.js +84 -14
- package/dist/src/memory/residency.js.map +1 -1
- package/dist/src/primitives/core-shape.d.ts +38 -2
- package/dist/src/primitives/core-shape.d.ts.map +1 -1
- package/dist/src/primitives/core-shape.js +71 -3
- package/dist/src/primitives/core-shape.js.map +1 -1
- package/dist/src/primitives/grid-pyramid.d.ts +71 -0
- package/dist/src/primitives/grid-pyramid.d.ts.map +1 -0
- package/dist/src/primitives/grid-pyramid.js +143 -0
- package/dist/src/primitives/grid-pyramid.js.map +1 -0
- package/dist/src/primitives/grid.d.ts +118 -0
- package/dist/src/primitives/grid.d.ts.map +1 -0
- package/dist/src/primitives/grid.js +225 -0
- package/dist/src/primitives/grid.js.map +1 -0
- package/dist/src/primitives/histogram.d.ts +67 -0
- package/dist/src/primitives/histogram.d.ts.map +1 -0
- package/dist/src/primitives/histogram.js +190 -0
- package/dist/src/primitives/histogram.js.map +1 -0
- package/dist/src/primitives/radix-sort.d.ts +75 -0
- package/dist/src/primitives/radix-sort.d.ts.map +1 -0
- package/dist/src/primitives/radix-sort.js +168 -0
- package/dist/src/primitives/radix-sort.js.map +1 -0
- package/dist/src/primitives/scan.d.ts +44 -0
- package/dist/src/primitives/scan.d.ts.map +1 -0
- package/dist/src/primitives/scan.js +151 -0
- package/dist/src/primitives/scan.js.map +1 -0
- package/dist/src/primitives/segmented-reduce.d.ts +25 -17
- package/dist/src/primitives/segmented-reduce.d.ts.map +1 -1
- package/dist/src/primitives/segmented-reduce.js +166 -47
- package/dist/src/primitives/segmented-reduce.js.map +1 -1
- package/dist/src/primitives/spmv.d.ts +18 -14
- package/dist/src/primitives/spmv.d.ts.map +1 -1
- package/dist/src/primitives/spmv.js +94 -58
- package/dist/src/primitives/spmv.js.map +1 -1
- package/dist/src/primitives/verify.d.ts +49 -0
- package/dist/src/primitives/verify.d.ts.map +1 -0
- package/dist/src/primitives/verify.js +229 -0
- package/dist/src/primitives/verify.js.map +1 -0
- package/dist/src/types/accelerator.d.ts +7 -3
- package/dist/src/types/accelerator.d.ts.map +1 -1
- package/dist/src/types/context.d.ts +53 -0
- package/dist/src/types/context.d.ts.map +1 -1
- package/dist/src/types/layout.d.ts +52 -0
- package/dist/src/types/layout.d.ts.map +1 -1
- package/dist/src/types/options.d.ts +43 -1
- package/dist/src/types/options.d.ts.map +1 -1
- package/dist/src/wgsl/counting-scatter.wgsl.d.ts +8 -0
- package/dist/src/wgsl/counting-scatter.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/counting-scatter.wgsl.js +17 -0
- package/dist/src/wgsl/counting-scatter.wgsl.js.map +1 -0
- package/dist/src/wgsl/fa2-attraction.wgsl.d.ts +23 -8
- package/dist/src/wgsl/fa2-attraction.wgsl.d.ts.map +1 -1
- package/dist/src/wgsl/fa2-attraction.wgsl.js +100 -17
- package/dist/src/wgsl/fa2-attraction.wgsl.js.map +1 -1
- package/dist/src/wgsl/fa2-integrate.wgsl.d.ts +7 -2
- package/dist/src/wgsl/fa2-integrate.wgsl.d.ts.map +1 -1
- package/dist/src/wgsl/fa2-integrate.wgsl.js +28 -2
- package/dist/src/wgsl/fa2-integrate.wgsl.js.map +1 -1
- package/dist/src/wgsl/fa2-repulsion-exact.wgsl.d.ts +4 -2
- package/dist/src/wgsl/fa2-repulsion-exact.wgsl.d.ts.map +1 -1
- package/dist/src/wgsl/fa2-repulsion-exact.wgsl.js +14 -5
- package/dist/src/wgsl/fa2-repulsion-exact.wgsl.js.map +1 -1
- package/dist/src/wgsl/fa2-stats-finalize.wgsl.d.ts +12 -1
- package/dist/src/wgsl/fa2-stats-finalize.wgsl.d.ts.map +1 -1
- package/dist/src/wgsl/fa2-stats-finalize.wgsl.js +54 -0
- package/dist/src/wgsl/fa2-stats-finalize.wgsl.js.map +1 -1
- package/dist/src/wgsl/grid-cell-key.wgsl.d.ts +8 -0
- package/dist/src/wgsl/grid-cell-key.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/grid-cell-key.wgsl.js +30 -0
- package/dist/src/wgsl/grid-cell-key.wgsl.js.map +1 -0
- package/dist/src/wgsl/grid-centroid-hub.wgsl.d.ts +8 -0
- package/dist/src/wgsl/grid-centroid-hub.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/grid-centroid-hub.wgsl.js +29 -0
- package/dist/src/wgsl/grid-centroid-hub.wgsl.js.map +1 -0
- package/dist/src/wgsl/grid-centroid.wgsl.d.ts +8 -0
- package/dist/src/wgsl/grid-centroid.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/grid-centroid.wgsl.js +29 -0
- package/dist/src/wgsl/grid-centroid.wgsl.js.map +1 -0
- package/dist/src/wgsl/grid-downsample.wgsl.d.ts +7 -0
- package/dist/src/wgsl/grid-downsample.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/grid-downsample.wgsl.js +28 -0
- package/dist/src/wgsl/grid-downsample.wgsl.js.map +1 -0
- package/dist/src/wgsl/grid-far-field.wgsl.d.ts +13 -0
- package/dist/src/wgsl/grid-far-field.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/grid-far-field.wgsl.js +98 -0
- package/dist/src/wgsl/grid-far-field.wgsl.js.map +1 -0
- package/dist/src/wgsl/grid-near-field.wgsl.d.ts +19 -0
- package/dist/src/wgsl/grid-near-field.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/grid-near-field.wgsl.js +129 -0
- package/dist/src/wgsl/grid-near-field.wgsl.js.map +1 -0
- package/dist/src/wgsl/histogram.wgsl.d.ts +7 -0
- package/dist/src/wgsl/histogram.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/histogram.wgsl.js +15 -0
- package/dist/src/wgsl/histogram.wgsl.js.map +1 -0
- package/dist/src/wgsl/indirect-finalize.wgsl.d.ts +8 -0
- package/dist/src/wgsl/indirect-finalize.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/indirect-finalize.wgsl.js +26 -0
- package/dist/src/wgsl/indirect-finalize.wgsl.js.map +1 -0
- package/dist/src/wgsl/radix-hist.wgsl.d.ts +9 -0
- package/dist/src/wgsl/radix-hist.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/radix-hist.wgsl.js +31 -0
- package/dist/src/wgsl/radix-hist.wgsl.js.map +1 -0
- package/dist/src/wgsl/radix-scatter.wgsl.d.ts +9 -0
- package/dist/src/wgsl/radix-scatter.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/radix-scatter.wgsl.js +40 -0
- package/dist/src/wgsl/radix-scatter.wgsl.js.map +1 -0
- package/dist/src/wgsl/scan-add.wgsl.d.ts +6 -0
- package/dist/src/wgsl/scan-add.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/scan-add.wgsl.js +14 -0
- package/dist/src/wgsl/scan-add.wgsl.js.map +1 -0
- package/dist/src/wgsl/scan-block.wgsl.d.ts +8 -0
- package/dist/src/wgsl/scan-block.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/scan-block.wgsl.js +30 -0
- package/dist/src/wgsl/scan-block.wgsl.js.map +1 -0
- package/dist/src/wgsl/segmented-reduce.wgsl.d.ts +22 -8
- package/dist/src/wgsl/segmented-reduce.wgsl.d.ts.map +1 -1
- package/dist/src/wgsl/segmented-reduce.wgsl.js +84 -15
- package/dist/src/wgsl/segmented-reduce.wgsl.js.map +1 -1
- package/dist/src/wgsl/spmv-pull.wgsl.d.ts +22 -11
- package/dist/src/wgsl/spmv-pull.wgsl.d.ts.map +1 -1
- package/dist/src/wgsl/spmv-pull.wgsl.js +110 -36
- package/dist/src/wgsl/spmv-pull.wgsl.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/webgpu-graph-algorithms.js +5016 -1130
- package/dist/webgpu-graph-algorithms.js.map +1 -1
- package/package.json +10 -7
- package/src/accelerator.ts +46 -12
- package/src/algorithms/components.ts +12 -16
- package/src/algorithms/degree.ts +58 -43
- package/src/algorithms/pagerank.ts +20 -18
- package/src/algorithms/power-iteration.ts +19 -18
- package/src/constants.ts +108 -8
- package/src/errors.ts +3 -1
- package/src/index.ts +25 -5
- package/src/kernel/dispatch.ts +18 -7
- package/src/kernel/kernel.ts +59 -5
- package/src/kernel/prelude.ts +15 -0
- package/src/kernel/profiler.ts +28 -4
- package/src/kernels.ts +378 -24
- package/src/layouts/calibrate.ts +187 -0
- package/src/layouts/force-simulation.ts +111 -26
- package/src/layouts/forceatlas2.ts +346 -324
- package/src/layouts/fruchterman-reingold.ts +918 -0
- package/src/layouts/model-common.ts +323 -0
- package/src/layouts/repulsion-grid.ts +451 -0
- package/src/layouts/spring-electrical.ts +845 -0
- package/src/memory/residency.ts +126 -20
- package/src/primitives/core-shape.ts +91 -4
- package/src/primitives/grid-pyramid.ts +221 -0
- package/src/primitives/grid.ts +349 -0
- package/src/primitives/histogram.ts +273 -0
- package/src/primitives/radix-sort.ts +246 -0
- package/src/primitives/scan.ts +197 -0
- package/src/primitives/segmented-reduce.ts +214 -56
- package/src/primitives/spmv.ts +125 -65
- package/src/primitives/verify.ts +249 -0
- package/src/types/accelerator.ts +15 -3
- package/src/types/context.ts +56 -0
- package/src/types/layout.ts +58 -0
- package/src/types/options.ts +45 -1
- package/src/wgsl/counting-scatter.wgsl.ts +16 -0
- package/src/wgsl/fa2-attraction.wgsl.ts +100 -17
- package/src/wgsl/fa2-integrate.wgsl.ts +28 -2
- package/src/wgsl/fa2-repulsion-exact.wgsl.ts +14 -5
- package/src/wgsl/fa2-stats-finalize.wgsl.ts +54 -0
- package/src/wgsl/grid-cell-key.wgsl.ts +29 -0
- package/src/wgsl/grid-centroid-hub.wgsl.ts +28 -0
- package/src/wgsl/grid-centroid.wgsl.ts +28 -0
- package/src/wgsl/grid-downsample.wgsl.ts +27 -0
- package/src/wgsl/grid-far-field.wgsl.ts +97 -0
- package/src/wgsl/grid-near-field.wgsl.ts +128 -0
- package/src/wgsl/histogram.wgsl.ts +14 -0
- package/src/wgsl/indirect-finalize.wgsl.ts +25 -0
- package/src/wgsl/radix-hist.wgsl.ts +30 -0
- package/src/wgsl/radix-scatter.wgsl.ts +39 -0
- package/src/wgsl/scan-add.wgsl.ts +13 -0
- package/src/wgsl/scan-block.wgsl.ts +29 -0
- package/src/wgsl/segmented-reduce.wgsl.ts +84 -15
- package/src/wgsl/spmv-pull.wgsl.ts +110 -36
- package/dist/chunks/context-CRbw2Wyo.js.map +0 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The grid pyramid (spec 6 row 12, 7.7 G4-G5; P4-T9): the planner that records, into the caller's pass, the finest
|
|
3
|
+
* centroids (G4, `grid-centroid`: thread per cell over `cells + 1`, the pseudo-cell included), the hub-cell
|
|
4
|
+
* completion (G4a: the T1 `indirect-finalize` over `hubCounters[0]` into `hubArgs` with `wg = 1`, so the finalize's
|
|
5
|
+
* `ceil(count / wg)` is ONE workgroup per hub cell; G4b: `grid-centroid-hub`, one workgroup per hub cell, dispatched
|
|
6
|
+
* indirectly; PD-13, DEP-P4-I) and one `grid-downsample` dispatch per coarser
|
|
7
|
+
* level (G5). Level 0 holds `[sum m x, sum m y, sum m z, sum m]` per cell; every parent is the sum of its 2^dim
|
|
8
|
+
* children; the pseudo-cell (index `cells` of level 0) is never a child. No atomics touch the sums (design 6 row 12:
|
|
9
|
+
* bitwise reproducible); the only atomics are the hub append and the occupancy max.
|
|
10
|
+
*
|
|
11
|
+
* The named grid buffers (`pyramid`, `hubList`, `hubCounters`, `hubArgs`) are the caller's (the model's
|
|
12
|
+
* `BufferSpec`s, so `inspect(name)` reaches them); the static params of the finalize and of every level are written
|
|
13
|
+
* ONCE at bind() through the scope's params writer (PD-11), so record() writes no uniform. `src/primitives/**` never
|
|
14
|
+
* imports `src/context.ts`.
|
|
15
|
+
*/
|
|
16
|
+
import { type Binding } from "../types/memory.js";
|
|
17
|
+
import { type GridSpec } from "./grid.js";
|
|
18
|
+
import { type ReduceScope } from "./reduce.js";
|
|
19
|
+
/**
|
|
20
|
+
* The buffers the pyramid build reads and writes (the model's named buffers). The parameter type of
|
|
21
|
+
* GridPyramidPlanner.bind (knip: exported for the signature, not imported by name).
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export interface GridPyramidBindings {
|
|
25
|
+
/** `array<vec4f>` positions (xyz, mass). */
|
|
26
|
+
readonly pos: Binding;
|
|
27
|
+
/** The `Fa2Params` uniform ring (`dim`, `gridMax`); `record()` takes the iteration's dynamic offset. */
|
|
28
|
+
readonly params: Binding;
|
|
29
|
+
/** `n` words: the sorted node indices (the T8 build). */
|
|
30
|
+
readonly sortedIdx: Binding;
|
|
31
|
+
/** `cells + 2` words: the exclusive scan of the cell histogram (the T8 build). */
|
|
32
|
+
readonly cellStart: Binding;
|
|
33
|
+
/** `pyramidCells` vec4f: every level, level 0 first with the pseudo-cell at index `cells`. */
|
|
34
|
+
readonly pyramid: Binding;
|
|
35
|
+
/** The hub cells' indices, appended by G4 (at least one word; at most `floor(n / (GRID_HUB_CELL + 1))` are ever written, so `ceil(n / GRID_HUB_CELL)` words always suffice). */
|
|
36
|
+
readonly hubList: Binding;
|
|
37
|
+
/** Two u32 (bound whole, at least 8 bytes): `[0]` the hub count, `[1]` the largest cell occupancy; the caller zeroes both before every build (K1, T10). */
|
|
38
|
+
readonly hubCounters: Binding;
|
|
39
|
+
/** One 16-byte indirect args slot with the INDIRECT usage: G4a writes it, G4b dispatches from it. */
|
|
40
|
+
readonly hubArgs: Binding;
|
|
41
|
+
}
|
|
42
|
+
/** Where `record()` stops: after level 0 is whole (G4, G4a and G4b) or after every coarser level (G5, the default). */
|
|
43
|
+
export type GridPyramidStage = "G4" | "G5";
|
|
44
|
+
/** A prepared pyramid build (spec 7.7 G4-G5): binds once per load, records the stages of one iteration into a pass. */
|
|
45
|
+
export interface GridPyramidPlanner {
|
|
46
|
+
/**
|
|
47
|
+
* Binds the named buffers and writes the static params of the finalize and of every level (PD-11); called once
|
|
48
|
+
* per load (a second call rebinds and writes fresh params, so it belongs to a reload, never to an iteration).
|
|
49
|
+
* @param bindings - the buffers
|
|
50
|
+
*/
|
|
51
|
+
bind(bindings: GridPyramidBindings): void;
|
|
52
|
+
/**
|
|
53
|
+
* Records G4, G4a, G4b and then G5 for every coarser level at the `Fa2Params` slot `paramsOffset`; `upTo: "G4"`
|
|
54
|
+
* stops after G4b (level 0 is whole: G4a and G4b are G4's completion).
|
|
55
|
+
* @param pass - the compute pass
|
|
56
|
+
* @param paramsOffset - the dynamic offset of this iteration's `Fa2Params`
|
|
57
|
+
* @param upTo - the last stage to record (default "G5")
|
|
58
|
+
*/
|
|
59
|
+
record(pass: GPUComputePassEncoder, paramsOffset: number, upTo?: GridPyramidStage): void;
|
|
60
|
+
/** Dispatches the last record() issued: 3 after `upTo: "G4"`, `3 + (levels - 1)` for a full record. */
|
|
61
|
+
readonly lastDispatches: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Prepares the pyramid's pipelines over a scope (G4, the finalize, G4b and G5; compiles once) so bind() and record()
|
|
65
|
+
* are synchronous. The planner lives exactly as long as the scope.
|
|
66
|
+
* @param scope - the caller's scope (device, caps, cache, scratch, params)
|
|
67
|
+
* @param spec - the grid
|
|
68
|
+
* @returns the planner
|
|
69
|
+
*/
|
|
70
|
+
export declare function preparePyramid(scope: ReduceScope, spec: GridSpec): Promise<GridPyramidPlanner>;
|
|
71
|
+
//# sourceMappingURL=grid-pyramid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grid-pyramid.d.ts","sourceRoot":"","sources":["../../../src/primitives/grid-pyramid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAChC,4CAA4C;IAC5C,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,wGAAwG;IACxG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,yDAAyD;IACzD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,kFAAkF;IAClF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,gLAAgL;IAChL,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,2JAA2J;IAC3J,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,qGAAqG;IACrG,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC7B;AAED,uHAAuH;AACvH,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,IAAI,CAAC;AAE3C,uHAAuH;AACvH,MAAM,WAAW,kBAAkB;IAC/B;;;;OAIG;IACH,IAAI,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC1C;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACzF,uGAAuG;IACvG,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAMpG"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The grid pyramid (spec 6 row 12, 7.7 G4-G5; P4-T9): the planner that records, into the caller's pass, the finest
|
|
3
|
+
* centroids (G4, `grid-centroid`: thread per cell over `cells + 1`, the pseudo-cell included), the hub-cell
|
|
4
|
+
* completion (G4a: the T1 `indirect-finalize` over `hubCounters[0]` into `hubArgs` with `wg = 1`, so the finalize's
|
|
5
|
+
* `ceil(count / wg)` is ONE workgroup per hub cell; G4b: `grid-centroid-hub`, one workgroup per hub cell, dispatched
|
|
6
|
+
* indirectly; PD-13, DEP-P4-I) and one `grid-downsample` dispatch per coarser
|
|
7
|
+
* level (G5). Level 0 holds `[sum m x, sum m y, sum m z, sum m]` per cell; every parent is the sum of its 2^dim
|
|
8
|
+
* children; the pseudo-cell (index `cells` of level 0) is never a child. No atomics touch the sums (design 6 row 12:
|
|
9
|
+
* bitwise reproducible); the only atomics are the hub append and the occupancy max.
|
|
10
|
+
*
|
|
11
|
+
* The named grid buffers (`pyramid`, `hubList`, `hubCounters`, `hubArgs`) are the caller's (the model's
|
|
12
|
+
* `BufferSpec`s, so `inspect(name)` reaches them); the static params of the finalize and of every level are written
|
|
13
|
+
* ONCE at bind() through the scope's params writer (PD-11), so record() writes no uniform. `src/primitives/**` never
|
|
14
|
+
* imports `src/context.ts`.
|
|
15
|
+
*/
|
|
16
|
+
import { WebGpuGraphError } from "../errors.js";
|
|
17
|
+
import { plan1d } from "../kernel/dispatch.js";
|
|
18
|
+
import { GRID_LEVEL_PARAMS, INDIRECT_PARAMS, kernelSpec } from "../kernels.js";
|
|
19
|
+
/**
|
|
20
|
+
* Prepares the pyramid's pipelines over a scope (G4, the finalize, G4b and G5; compiles once) so bind() and record()
|
|
21
|
+
* are synchronous. The planner lives exactly as long as the scope.
|
|
22
|
+
* @param scope - the caller's scope (device, caps, cache, scratch, params)
|
|
23
|
+
* @param spec - the grid
|
|
24
|
+
* @returns the planner
|
|
25
|
+
*/
|
|
26
|
+
export async function preparePyramid(scope, spec) {
|
|
27
|
+
const centroid = await scope.pipelines.kernel(kernelSpec("grid-centroid"));
|
|
28
|
+
const finalize = await scope.pipelines.kernel(kernelSpec("indirect-finalize"));
|
|
29
|
+
const hub = await scope.pipelines.kernel(kernelSpec("grid-centroid-hub"));
|
|
30
|
+
const downsample = await scope.pipelines.kernel(kernelSpec("grid-downsample"));
|
|
31
|
+
return new GridPyramidPlannerImpl(scope, spec, { centroid, finalize, hub, downsample });
|
|
32
|
+
}
|
|
33
|
+
/** The planner: G4, G4a, G4b and G5 over one scope. */
|
|
34
|
+
class GridPyramidPlannerImpl {
|
|
35
|
+
/**
|
|
36
|
+
* Wraps the resolved kernels; use preparePyramid().
|
|
37
|
+
* @param scope - the caller's scope
|
|
38
|
+
* @param spec - the grid
|
|
39
|
+
* @param kernels - the four kernels
|
|
40
|
+
*/
|
|
41
|
+
constructor(scope, spec, kernels) {
|
|
42
|
+
this.bound = null;
|
|
43
|
+
this.dispatches = 0;
|
|
44
|
+
this.scope = scope;
|
|
45
|
+
this.spec = spec;
|
|
46
|
+
this.kernels = kernels;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Dispatches the last record() issued.
|
|
50
|
+
* @returns the count
|
|
51
|
+
*/
|
|
52
|
+
get lastDispatches() {
|
|
53
|
+
return this.dispatches;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Binds the buffers and writes the static params (see the interface).
|
|
57
|
+
* @param bindings - the buffers
|
|
58
|
+
*/
|
|
59
|
+
bind(bindings) {
|
|
60
|
+
const { centroid, finalize, hub, downsample } = this.kernels;
|
|
61
|
+
const { spec, scope } = this;
|
|
62
|
+
const b = bindings;
|
|
63
|
+
const finalizeParams = scope.params(INDIRECT_PARAMS, {
|
|
64
|
+
countIndex: 0,
|
|
65
|
+
wg: 1, // the finalize plans ceil(count / wg) workgroups over ITEMS; G4b's item is a hub cell, one workgroup each
|
|
66
|
+
slot: 0,
|
|
67
|
+
pad0: 0,
|
|
68
|
+
});
|
|
69
|
+
const levels = [];
|
|
70
|
+
let parentSide = spec.g;
|
|
71
|
+
for (let level = 0; level + 1 < spec.levels; level++) {
|
|
72
|
+
parentSide /= 2;
|
|
73
|
+
const parentCells = parentSide ** spec.dim;
|
|
74
|
+
const params = scope.params(GRID_LEVEL_PARAMS, {
|
|
75
|
+
childBase: spec.levelOffsets[level],
|
|
76
|
+
parentBase: spec.levelOffsets[level + 1],
|
|
77
|
+
parentSide,
|
|
78
|
+
parentCells,
|
|
79
|
+
depth: spec.dim === 3 ? 2 : 1,
|
|
80
|
+
pad0: 0,
|
|
81
|
+
pad1: 0,
|
|
82
|
+
pad2: 0,
|
|
83
|
+
});
|
|
84
|
+
levels.push({
|
|
85
|
+
bound: downsample.bind({ pyramid: b.pyramid, P: params.binding }),
|
|
86
|
+
offset: params.offset,
|
|
87
|
+
parentCells,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
this.bound = {
|
|
91
|
+
hubArgs: b.hubArgs,
|
|
92
|
+
centroid: centroid.bind({
|
|
93
|
+
sortedIdx: b.sortedIdx,
|
|
94
|
+
cellStart: b.cellStart,
|
|
95
|
+
pos: b.pos,
|
|
96
|
+
pyramid: b.pyramid,
|
|
97
|
+
hubList: b.hubList,
|
|
98
|
+
hubCounters: b.hubCounters,
|
|
99
|
+
P: b.params,
|
|
100
|
+
}),
|
|
101
|
+
finalize: finalize.bind({ counters: b.hubCounters, args: b.hubArgs, P: finalizeParams.binding }),
|
|
102
|
+
finalizeOffset: finalizeParams.offset,
|
|
103
|
+
hub: hub.bind({
|
|
104
|
+
sortedIdx: b.sortedIdx,
|
|
105
|
+
cellStart: b.cellStart,
|
|
106
|
+
pos: b.pos,
|
|
107
|
+
pyramid: b.pyramid,
|
|
108
|
+
hubList: b.hubList,
|
|
109
|
+
hubCount: b.hubCounters,
|
|
110
|
+
P: b.params,
|
|
111
|
+
}),
|
|
112
|
+
levels,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Records the stages (see the interface).
|
|
117
|
+
* @param pass - the compute pass
|
|
118
|
+
* @param paramsOffset - the `Fa2Params` dynamic offset
|
|
119
|
+
* @param upTo - the last stage
|
|
120
|
+
*/
|
|
121
|
+
record(pass, paramsOffset, upTo) {
|
|
122
|
+
const { bound, scope, spec } = this;
|
|
123
|
+
if (bound === null) {
|
|
124
|
+
throw new WebGpuGraphError("E_NOT_LOADED", "gridPyramid: record() before bind()", { argument: "bind" });
|
|
125
|
+
}
|
|
126
|
+
const { centroid, finalize, hub, downsample } = this.kernels;
|
|
127
|
+
const one = { x: 1, y: 1, z: 1, items: 1, stride: null };
|
|
128
|
+
centroid.dispatch(pass, bound.centroid, plan1d(spec.cells + 1, scope.workgroupSize, scope.caps), [paramsOffset]);
|
|
129
|
+
finalize.dispatch(pass, bound.finalize, one, [bound.finalizeOffset]);
|
|
130
|
+
hub.dispatchIndirect(pass, bound.hub, bound.hubArgs, 0, [paramsOffset]);
|
|
131
|
+
this.dispatches = 3;
|
|
132
|
+
if ((upTo ?? "G5") === "G4") {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
for (const level of bound.levels) {
|
|
136
|
+
downsample.dispatch(pass, level.bound, plan1d(level.parentCells, scope.workgroupSize, scope.caps), [
|
|
137
|
+
level.offset,
|
|
138
|
+
]);
|
|
139
|
+
this.dispatches += 1;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=grid-pyramid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grid-pyramid.js","sourceRoot":"","sources":["../../../src/primitives/grid-pyramid.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The grid build (spec 6 row 12, 7.7 G1-G3; P4-T8): `GridSpec` on the host (PD-9) and the planner that records, into
|
|
3
|
+
* the caller's pass, the cell keys (G1, `grid-cell-key`), the stable sort by key (G2: `radixSort` at GRID_SORT_BITS,
|
|
4
|
+
* or `countingSortByKey` when the caller asks for the set-deterministic path) and the per-cell histogram with its
|
|
5
|
+
* exclusive scan (G3: the `histogram` kernel over `cellKey` and the `scan` of it; DEP-P4-I names no grid-specific
|
|
6
|
+
* id). `cellHist` and `cellStart` hold `cells + 2` words: every real cell, the outside pseudo-cell at index `cells`
|
|
7
|
+
* and one more so `cellStart[cells + 1] === n` closes the last range. Every zeroing is a `fill` dispatch inside the
|
|
8
|
+
* pass (PD-12), never an encoder clear.
|
|
9
|
+
*
|
|
10
|
+
* The named grid buffers (`cellKey`, `cellVal`, `sortedKey`, `sortedIdx`, `cellHist`, `cellStart`) are the caller's
|
|
11
|
+
* (the model's `BufferSpec`s, so `inspect(name)` reaches them); the anonymous scratch of the sort (the digit-major
|
|
12
|
+
* table and its scan, the counting-sort cursor) is taken from the scope ONCE at bind() so the sub-kernels bind the
|
|
13
|
+
* same buffers every iteration and `Kernel.bind`'s identity cache holds (PD-11). `src/primitives/**` never imports
|
|
14
|
+
* `src/context.ts`.
|
|
15
|
+
*/
|
|
16
|
+
import { type ResolvedLayoutTuning } from "../types/layout.js";
|
|
17
|
+
import { type Binding } from "../types/memory.js";
|
|
18
|
+
import { type ReduceScope } from "./reduce.js";
|
|
19
|
+
/** The grid's geometry (spec 7.7 geometry table; PD-9), computed on the host once per load. */
|
|
20
|
+
export interface GridSpec {
|
|
21
|
+
/** 2 or 3. */
|
|
22
|
+
readonly dim: 2 | 3;
|
|
23
|
+
/** The finest side `G` per axis: a power of two in [GRID_MIN_SIDE, floorPow2(gridMax)]. */
|
|
24
|
+
readonly g: number;
|
|
25
|
+
/** `log2(G / GRID_COARSEST_SIDE) + 1`. */
|
|
26
|
+
readonly levels: number;
|
|
27
|
+
/** `G^dim` finest cells; the outside pseudo-cell is index `cells`. */
|
|
28
|
+
readonly cells: number;
|
|
29
|
+
/** `cells + 2`: the length of `cellHist` / `cellStart`. */
|
|
30
|
+
readonly histWords: number;
|
|
31
|
+
/** The first cell of every level inside the pyramid: `levelOffsets[0] = 0`, level 0 holds `cells + 1` (the pseudo-cell), level L `(G / 2^L)^dim`. */
|
|
32
|
+
readonly levelOffsets: readonly number[];
|
|
33
|
+
/** Every level's cells together: `levelOffsets[levels - 1] + GRID_COARSEST_SIDE^dim`. */
|
|
34
|
+
readonly pyramidCells: number;
|
|
35
|
+
/** Whether G2 is the stable radix sort (true) or the set-deterministic counting sort (false). */
|
|
36
|
+
readonly deterministic: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The grid of `n` nodes in `dim` dimensions under the tuning (spec 7.7 geometry table; PD-9): `G = clamp(nextPow2(2 *
|
|
40
|
+
* ceil(n^(1 / dim))), GRID_MIN_SIDE, floorPow2(gridMax))` where `gridMax` is `gridMax2D` or `gridMax3D`, rounded DOWN
|
|
41
|
+
* to a power of two so every level's side is an integer (512 and 128 stay; 100 becomes 64); `levels = log2(G /
|
|
42
|
+
* GRID_COARSEST_SIDE) + 1`. At the caps: 349,521 pyramid cells in 2D, 2,396,737 in 3D (the design's counts plus the
|
|
43
|
+
* pseudo-cell).
|
|
44
|
+
* @param n - the node count (>= 0)
|
|
45
|
+
* @param dim - 2 or 3
|
|
46
|
+
* @param tuning - the resolved layout tuning (`gridMax2D`, `gridMax3D`, `deterministic`)
|
|
47
|
+
* @returns the spec
|
|
48
|
+
*/
|
|
49
|
+
export declare function gridSpecFor(n: number, dim: 2 | 3, tuning: Pick<ResolvedLayoutTuning, "gridMax2D" | "gridMax3D" | "deterministic">): GridSpec;
|
|
50
|
+
/**
|
|
51
|
+
* The bytes of the pyramid (spec 7.7: 16 B per cell, every level, the pseudo-cell included): 38,347,792 at the 3D cap.
|
|
52
|
+
* @param spec - the grid
|
|
53
|
+
* @returns the byte length
|
|
54
|
+
*/
|
|
55
|
+
export declare function gridPyramidBytes(spec: GridSpec): number;
|
|
56
|
+
/**
|
|
57
|
+
* The buffers the build reads and writes (the model's named buffers; `state` and `params` are the blocks G1 reads).
|
|
58
|
+
* The parameter type of GridBuildPlanner.bind (knip: exported for the signature, not imported by name).
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
export interface GridBuildBindings {
|
|
62
|
+
/** `array<vec4f>` positions (xyz, mass). */
|
|
63
|
+
readonly pos: Binding;
|
|
64
|
+
/** The `Fa2State` block (`gridMin`, `invCellSize`), read-only here. */
|
|
65
|
+
readonly state: Binding;
|
|
66
|
+
/** The `Fa2Params` uniform ring (`n`, `dim`, `gridMax`); `record()` takes the iteration's dynamic offset. */
|
|
67
|
+
readonly params: Binding;
|
|
68
|
+
/**
|
|
69
|
+
* `n` words: G1's keys, node-indexed until G2. On the deterministic path the radix sort ping-pongs through this
|
|
70
|
+
* pair (PD-5: three passes, the even one writes the input pair), so after G2 `cellKey` / `cellVal` hold the
|
|
71
|
+
* sort's last even-pass intermediate -- a permutation of the keys, which is why the histogram recorded after it
|
|
72
|
+
* counts the same multiset; the node-indexed keys of an iteration are read through `upTo: "G1"`. The counting
|
|
73
|
+
* path never writes them.
|
|
74
|
+
*/
|
|
75
|
+
readonly cellKey: Binding;
|
|
76
|
+
/** `n` words: G1's values (`i`); the sort's working pair with `cellKey`. */
|
|
77
|
+
readonly cellVal: Binding;
|
|
78
|
+
/** `n` words: the sorted keys (the radix path's result pair; unused by the counting path). */
|
|
79
|
+
readonly sortedKey: Binding;
|
|
80
|
+
/** `n` words: the sorted node indices. */
|
|
81
|
+
readonly sortedIdx: Binding;
|
|
82
|
+
/** `cells + 2` words: the per-cell counts. */
|
|
83
|
+
readonly cellHist: Binding;
|
|
84
|
+
/** `cells + 2` words: the exclusive scan of `cellHist`. */
|
|
85
|
+
readonly cellStart: Binding;
|
|
86
|
+
}
|
|
87
|
+
/** Where `record()` stops: after the keys (G1), after the sort (G2) or after the histogram and its scan (G3, the default). */
|
|
88
|
+
export type GridBuildStage = "G1" | "G2" | "G3";
|
|
89
|
+
/** A prepared grid build (spec 7.7 G1-G3): binds once per load, records the stages of one iteration into a pass. */
|
|
90
|
+
export interface GridBuildPlanner {
|
|
91
|
+
/**
|
|
92
|
+
* Binds the named buffers and takes the sort's scratch from the scope, sized by `cellKey` (its word count is the
|
|
93
|
+
* node capacity; PD-11); called once per load (a second call rebinds and takes fresh scratch, so it belongs to a
|
|
94
|
+
* reload, never to an iteration).
|
|
95
|
+
* @param bindings - the buffers
|
|
96
|
+
*/
|
|
97
|
+
bind(bindings: GridBuildBindings): void;
|
|
98
|
+
/**
|
|
99
|
+
* Records G1, G2 and G3 for `n` nodes at the `Fa2Params` slot `paramsOffset`; `upTo` stops after the named
|
|
100
|
+
* stage (the counting path has no separate G2 stop: its sort and histogram are one sequence, so "G2" runs it all).
|
|
101
|
+
* @param pass - the compute pass
|
|
102
|
+
* @param n - the node count (in [1, the capacity]; the caller never records a grid iteration for an empty graph)
|
|
103
|
+
* @param paramsOffset - the dynamic offset of this iteration's `Fa2Params`
|
|
104
|
+
* @param upTo - the last stage to record (default "G3")
|
|
105
|
+
*/
|
|
106
|
+
record(pass: GPUComputePassEncoder, n: number, paramsOffset: number, upTo?: GridBuildStage): void;
|
|
107
|
+
/** Dispatches the last record() issued. */
|
|
108
|
+
readonly lastDispatches: number;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Prepares the grid build's pipelines over a scope (G1 and the sort / histogram / scan planners it composes; compiles
|
|
112
|
+
* once) so bind() and record() are synchronous. The planner lives exactly as long as the scope.
|
|
113
|
+
* @param scope - the caller's scope (device, caps, cache, scratch, params)
|
|
114
|
+
* @param spec - the grid
|
|
115
|
+
* @returns the planner
|
|
116
|
+
*/
|
|
117
|
+
export declare function prepareGridBuild(scope: ReduceScope, spec: GridSpec): Promise<GridBuildPlanner>;
|
|
118
|
+
//# sourceMappingURL=grid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grid.d.ts","sourceRoot":"","sources":["../../../src/primitives/grid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,OAAO,EAAE,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAQlD,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAG/C,+FAA+F;AAC/F,MAAM,WAAW,QAAQ;IACrB,cAAc;IACd,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IACpB,2FAA2F;IAC3F,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,qJAAqJ;IACrJ,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,yFAAyF;IACzF,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,iGAAiG;IACjG,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACnC;AA4BD;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACvB,CAAC,EAAE,MAAM,EACT,GAAG,EAAE,CAAC,GAAG,CAAC,EACV,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,WAAW,GAAG,WAAW,GAAG,eAAe,CAAC,GAChF,QAAQ,CA0BV;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAEvD;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAC9B,4CAA4C;IAC5C,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,6GAA6G;IAC7G,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,8FAA8F;IAC9F,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,0CAA0C;IAC1C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC/B;AAED,8HAA8H;AAC9H,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhD,oHAAoH;AACpH,MAAM,WAAW,gBAAgB;IAC7B;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,EAAE,qBAAqB,EAAE,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAClG,2CAA2C;IAC3C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACnC;AAYD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAWpG"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The grid build (spec 6 row 12, 7.7 G1-G3; P4-T8): `GridSpec` on the host (PD-9) and the planner that records, into
|
|
3
|
+
* the caller's pass, the cell keys (G1, `grid-cell-key`), the stable sort by key (G2: `radixSort` at GRID_SORT_BITS,
|
|
4
|
+
* or `countingSortByKey` when the caller asks for the set-deterministic path) and the per-cell histogram with its
|
|
5
|
+
* exclusive scan (G3: the `histogram` kernel over `cellKey` and the `scan` of it; DEP-P4-I names no grid-specific
|
|
6
|
+
* id). `cellHist` and `cellStart` hold `cells + 2` words: every real cell, the outside pseudo-cell at index `cells`
|
|
7
|
+
* and one more so `cellStart[cells + 1] === n` closes the last range. Every zeroing is a `fill` dispatch inside the
|
|
8
|
+
* pass (PD-12), never an encoder clear.
|
|
9
|
+
*
|
|
10
|
+
* The named grid buffers (`cellKey`, `cellVal`, `sortedKey`, `sortedIdx`, `cellHist`, `cellStart`) are the caller's
|
|
11
|
+
* (the model's `BufferSpec`s, so `inspect(name)` reaches them); the anonymous scratch of the sort (the digit-major
|
|
12
|
+
* table and its scan, the counting-sort cursor) is taken from the scope ONCE at bind() so the sub-kernels bind the
|
|
13
|
+
* same buffers every iteration and `Kernel.bind`'s identity cache holds (PD-11). `src/primitives/**` never imports
|
|
14
|
+
* `src/context.ts`.
|
|
15
|
+
*/
|
|
16
|
+
import { GRID_COARSEST_SIDE, GRID_MIN_SIDE, GRID_SORT_BITS } from "../constants.js";
|
|
17
|
+
import { WebGpuGraphError } from "../errors.js";
|
|
18
|
+
import { plan1d } from "../kernel/dispatch.js";
|
|
19
|
+
import { kernelSpec } from "../kernels.js";
|
|
20
|
+
import { prepareCountingSort, prepareHistogram, } from "./histogram.js";
|
|
21
|
+
import { prepareRadixSort, radixHistBytes } from "./radix-sort.js";
|
|
22
|
+
import { prepareScan } from "./scan.js";
|
|
23
|
+
/**
|
|
24
|
+
* The smallest power of two >= x (by doubling; 1 for x <= 1).
|
|
25
|
+
* @param x - a non-negative number
|
|
26
|
+
* @returns the power of two
|
|
27
|
+
*/
|
|
28
|
+
function nextPow2(x) {
|
|
29
|
+
let p = 1;
|
|
30
|
+
while (p < x) {
|
|
31
|
+
p *= 2;
|
|
32
|
+
}
|
|
33
|
+
return p;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The largest power of two <= x (by doubling; 1 for x < 2).
|
|
37
|
+
* @param x - a number >= 1
|
|
38
|
+
* @returns the power of two
|
|
39
|
+
*/
|
|
40
|
+
function floorPow2(x) {
|
|
41
|
+
let p = 1;
|
|
42
|
+
while (p * 2 <= x) {
|
|
43
|
+
p *= 2;
|
|
44
|
+
}
|
|
45
|
+
return p;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The grid of `n` nodes in `dim` dimensions under the tuning (spec 7.7 geometry table; PD-9): `G = clamp(nextPow2(2 *
|
|
49
|
+
* ceil(n^(1 / dim))), GRID_MIN_SIDE, floorPow2(gridMax))` where `gridMax` is `gridMax2D` or `gridMax3D`, rounded DOWN
|
|
50
|
+
* to a power of two so every level's side is an integer (512 and 128 stay; 100 becomes 64); `levels = log2(G /
|
|
51
|
+
* GRID_COARSEST_SIDE) + 1`. At the caps: 349,521 pyramid cells in 2D, 2,396,737 in 3D (the design's counts plus the
|
|
52
|
+
* pseudo-cell).
|
|
53
|
+
* @param n - the node count (>= 0)
|
|
54
|
+
* @param dim - 2 or 3
|
|
55
|
+
* @param tuning - the resolved layout tuning (`gridMax2D`, `gridMax3D`, `deterministic`)
|
|
56
|
+
* @returns the spec
|
|
57
|
+
*/
|
|
58
|
+
export function gridSpecFor(n, dim, tuning) {
|
|
59
|
+
const gridMax = dim === 3 ? tuning.gridMax3D : tuning.gridMax2D;
|
|
60
|
+
const side = dim === 3 ? Math.cbrt(n) : Math.sqrt(n);
|
|
61
|
+
const cap = Math.max(GRID_MIN_SIDE, floorPow2(Math.max(1, gridMax)));
|
|
62
|
+
const g = Math.min(cap, Math.max(GRID_MIN_SIDE, nextPow2(2 * Math.ceil(side))));
|
|
63
|
+
let levels = 1;
|
|
64
|
+
for (let s = g; s > GRID_COARSEST_SIDE; s /= 2) {
|
|
65
|
+
levels++;
|
|
66
|
+
}
|
|
67
|
+
const cells = g ** dim;
|
|
68
|
+
const levelOffsets = [0];
|
|
69
|
+
let s = g;
|
|
70
|
+
for (let level = 0; level + 1 < levels; level++) {
|
|
71
|
+
levelOffsets.push(levelOffsets[level] + s ** dim + (level === 0 ? 1 : 0));
|
|
72
|
+
s /= 2;
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
dim,
|
|
76
|
+
g,
|
|
77
|
+
levels,
|
|
78
|
+
cells,
|
|
79
|
+
histWords: cells + 2,
|
|
80
|
+
levelOffsets: Object.freeze(levelOffsets),
|
|
81
|
+
pyramidCells: levelOffsets[levels - 1] + GRID_COARSEST_SIDE ** dim,
|
|
82
|
+
deterministic: tuning.deterministic,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The bytes of the pyramid (spec 7.7: 16 B per cell, every level, the pseudo-cell included): 38,347,792 at the 3D cap.
|
|
87
|
+
* @param spec - the grid
|
|
88
|
+
* @returns the byte length
|
|
89
|
+
*/
|
|
90
|
+
export function gridPyramidBytes(spec) {
|
|
91
|
+
return 16 * spec.pyramidCells;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Prepares the grid build's pipelines over a scope (G1 and the sort / histogram / scan planners it composes; compiles
|
|
95
|
+
* once) so bind() and record() are synchronous. The planner lives exactly as long as the scope.
|
|
96
|
+
* @param scope - the caller's scope (device, caps, cache, scratch, params)
|
|
97
|
+
* @param spec - the grid
|
|
98
|
+
* @returns the planner
|
|
99
|
+
*/
|
|
100
|
+
export async function prepareGridBuild(scope, spec) {
|
|
101
|
+
const cellKey = await scope.pipelines.kernel(kernelSpec("grid-cell-key"));
|
|
102
|
+
const path = spec.deterministic
|
|
103
|
+
? {
|
|
104
|
+
kind: "radix",
|
|
105
|
+
radix: await prepareRadixSort(scope),
|
|
106
|
+
histogram: await prepareHistogram(scope),
|
|
107
|
+
scan: await prepareScan(scope),
|
|
108
|
+
}
|
|
109
|
+
: { kind: "counting", counting: await prepareCountingSort(scope) };
|
|
110
|
+
return new GridBuildPlannerImpl(scope, spec, cellKey, path);
|
|
111
|
+
}
|
|
112
|
+
/** The planner: G1 and the composed sort / histogram / scan over one scope. */
|
|
113
|
+
class GridBuildPlannerImpl {
|
|
114
|
+
/**
|
|
115
|
+
* Wraps the resolved kernel and planners; use prepareGridBuild().
|
|
116
|
+
* @param scope - the caller's scope
|
|
117
|
+
* @param spec - the grid
|
|
118
|
+
* @param cellKey - the `grid-cell-key` kernel
|
|
119
|
+
* @param path - the sort path
|
|
120
|
+
*/
|
|
121
|
+
constructor(scope, spec, cellKey, path) {
|
|
122
|
+
this.bound = null;
|
|
123
|
+
this.dispatches = 0;
|
|
124
|
+
this.scope = scope;
|
|
125
|
+
this.spec = spec;
|
|
126
|
+
this.cellKey = cellKey;
|
|
127
|
+
this.path = path;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Dispatches the last record() issued.
|
|
131
|
+
* @returns the count
|
|
132
|
+
*/
|
|
133
|
+
get lastDispatches() {
|
|
134
|
+
return this.dispatches;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Binds the buffers and takes the sort's scratch (see the interface).
|
|
138
|
+
* @param bindings - the buffers
|
|
139
|
+
*/
|
|
140
|
+
bind(bindings) {
|
|
141
|
+
const capacity = Math.floor(bindings.cellKey.size / 4);
|
|
142
|
+
if (capacity < 1) {
|
|
143
|
+
throw new WebGpuGraphError("E_INVALID_ARGUMENT", "gridBuild: cellKey must hold at least one word", {
|
|
144
|
+
argument: "cellKey",
|
|
145
|
+
value: bindings.cellKey.size,
|
|
146
|
+
expected: 4,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
const words = this.path.kind === "radix" ? radixHistBytes(capacity, this.scope.workgroupSize) / 4 : this.spec.histWords;
|
|
150
|
+
this.bound = {
|
|
151
|
+
bindings,
|
|
152
|
+
capacity,
|
|
153
|
+
scratchA: this.scratch(words, "grid/sort-scratch-a"),
|
|
154
|
+
scratchB: this.scratch(words, "grid/sort-scratch-b"),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Records the stages (see the interface).
|
|
159
|
+
* @param pass - the compute pass
|
|
160
|
+
* @param n - the node count
|
|
161
|
+
* @param paramsOffset - the `Fa2Params` dynamic offset
|
|
162
|
+
* @param upTo - the last stage
|
|
163
|
+
*/
|
|
164
|
+
record(pass, n, paramsOffset, upTo) {
|
|
165
|
+
const { bound } = this;
|
|
166
|
+
if (bound === null) {
|
|
167
|
+
throw new WebGpuGraphError("E_NOT_LOADED", "gridBuild: record() before bind()", { argument: "bind" });
|
|
168
|
+
}
|
|
169
|
+
if (!Number.isSafeInteger(n) || n < 1 || n > bound.capacity) {
|
|
170
|
+
throw new WebGpuGraphError("E_INVALID_ARGUMENT", "gridBuild: n must be an integer in [1, the capacity]", {
|
|
171
|
+
argument: "n",
|
|
172
|
+
value: n,
|
|
173
|
+
expected: bound.capacity,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
const stop = upTo ?? "G3";
|
|
177
|
+
const b = bound.bindings;
|
|
178
|
+
const keyBound = this.cellKey.bind({
|
|
179
|
+
pos: b.pos,
|
|
180
|
+
S: b.state,
|
|
181
|
+
cellKey: b.cellKey,
|
|
182
|
+
cellVal: b.cellVal,
|
|
183
|
+
P: b.params,
|
|
184
|
+
});
|
|
185
|
+
this.cellKey.dispatch(pass, keyBound, plan1d(n, this.scope.workgroupSize, this.scope.caps), [paramsOffset]);
|
|
186
|
+
this.dispatches = 1;
|
|
187
|
+
if (stop === "G1") {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const { histWords: bins } = this.spec;
|
|
191
|
+
if (this.path.kind === "counting") {
|
|
192
|
+
const { counting } = this.path;
|
|
193
|
+
const scratch = { hist: b.cellHist, cursor: bound.scratchA };
|
|
194
|
+
counting.record(pass, b.cellKey, n, bins, scratch, b.sortedIdx, b.cellStart);
|
|
195
|
+
this.dispatches += counting.lastDispatches;
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const { radix, histogram, scan } = this.path;
|
|
199
|
+
radix.record(pass, b.cellKey, b.cellVal, n, GRID_SORT_BITS, {
|
|
200
|
+
keys: b.sortedKey,
|
|
201
|
+
vals: b.sortedIdx,
|
|
202
|
+
hist: bound.scratchA,
|
|
203
|
+
offsets: bound.scratchB,
|
|
204
|
+
});
|
|
205
|
+
this.dispatches += radix.lastDispatches;
|
|
206
|
+
if (stop === "G2") {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
histogram.record(pass, b.cellKey, n, bins, b.cellHist);
|
|
210
|
+
scan.record(pass, b.cellHist, bins, b.cellStart);
|
|
211
|
+
this.dispatches += histogram.lastDispatches + scan.lastDispatches;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* A scratch of `words` u32 from the scope, bound whole.
|
|
215
|
+
* @param words - the word count (>= 1)
|
|
216
|
+
* @param label - the scratch label
|
|
217
|
+
* @returns the binding
|
|
218
|
+
*/
|
|
219
|
+
scratch(words, label) {
|
|
220
|
+
const size = 4 * Math.max(1, words);
|
|
221
|
+
const buffer = this.scope.scratch(size, label);
|
|
222
|
+
return { buffer, offset: 0, size, window: null };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=grid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grid.js","sourceRoot":"","sources":["../../../src/primitives/grid.ts"],"names":[],"mappings":"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"}
|