@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.
Files changed (264) hide show
  1. package/README.md +104 -52
  2. package/dist/browser.js +1 -1
  3. package/dist/chunks/{context-CRbw2Wyo.js → context-BXqgCifx.js} +225 -33
  4. package/dist/chunks/context-BXqgCifx.js.map +1 -0
  5. package/dist/node.js +1 -1
  6. package/dist/src/accelerator.d.ts +12 -10
  7. package/dist/src/accelerator.d.ts.map +1 -1
  8. package/dist/src/accelerator.js +32 -10
  9. package/dist/src/accelerator.js.map +1 -1
  10. package/dist/src/algorithms/components.d.ts.map +1 -1
  11. package/dist/src/algorithms/components.js +12 -13
  12. package/dist/src/algorithms/components.js.map +1 -1
  13. package/dist/src/algorithms/degree.d.ts +6 -8
  14. package/dist/src/algorithms/degree.d.ts.map +1 -1
  15. package/dist/src/algorithms/degree.js +58 -35
  16. package/dist/src/algorithms/degree.js.map +1 -1
  17. package/dist/src/algorithms/pagerank.d.ts.map +1 -1
  18. package/dist/src/algorithms/pagerank.js +16 -14
  19. package/dist/src/algorithms/pagerank.js.map +1 -1
  20. package/dist/src/algorithms/power-iteration.d.ts +2 -2
  21. package/dist/src/algorithms/power-iteration.d.ts.map +1 -1
  22. package/dist/src/algorithms/power-iteration.js +17 -14
  23. package/dist/src/algorithms/power-iteration.js.map +1 -1
  24. package/dist/src/constants.d.ts +85 -8
  25. package/dist/src/constants.d.ts.map +1 -1
  26. package/dist/src/constants.js +85 -8
  27. package/dist/src/constants.js.map +1 -1
  28. package/dist/src/errors.d.ts +3 -2
  29. package/dist/src/errors.d.ts.map +1 -1
  30. package/dist/src/errors.js +2 -1
  31. package/dist/src/errors.js.map +1 -1
  32. package/dist/src/index.d.ts +10 -5
  33. package/dist/src/index.d.ts.map +1 -1
  34. package/dist/src/index.js +14 -5
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/kernel/dispatch.d.ts +8 -3
  37. package/dist/src/kernel/dispatch.d.ts.map +1 -1
  38. package/dist/src/kernel/dispatch.js +18 -7
  39. package/dist/src/kernel/dispatch.js.map +1 -1
  40. package/dist/src/kernel/kernel.d.ts +30 -1
  41. package/dist/src/kernel/kernel.d.ts.map +1 -1
  42. package/dist/src/kernel/kernel.js +49 -5
  43. package/dist/src/kernel/kernel.js.map +1 -1
  44. package/dist/src/kernel/prelude.d.ts.map +1 -1
  45. package/dist/src/kernel/prelude.js +9 -1
  46. package/dist/src/kernel/prelude.js.map +1 -1
  47. package/dist/src/kernel/profiler.d.ts +15 -3
  48. package/dist/src/kernel/profiler.d.ts.map +1 -1
  49. package/dist/src/kernel/profiler.js +27 -4
  50. package/dist/src/kernel/profiler.js.map +1 -1
  51. package/dist/src/kernels.d.ts +18 -8
  52. package/dist/src/kernels.d.ts.map +1 -1
  53. package/dist/src/kernels.js +345 -22
  54. package/dist/src/kernels.js.map +1 -1
  55. package/dist/src/layouts/calibrate.d.ts +51 -0
  56. package/dist/src/layouts/calibrate.d.ts.map +1 -0
  57. package/dist/src/layouts/calibrate.js +172 -0
  58. package/dist/src/layouts/calibrate.js.map +1 -0
  59. package/dist/src/layouts/force-simulation.d.ts +42 -5
  60. package/dist/src/layouts/force-simulation.d.ts.map +1 -1
  61. package/dist/src/layouts/force-simulation.js +84 -22
  62. package/dist/src/layouts/force-simulation.js.map +1 -1
  63. package/dist/src/layouts/forceatlas2.d.ts +107 -38
  64. package/dist/src/layouts/forceatlas2.d.ts.map +1 -1
  65. package/dist/src/layouts/forceatlas2.js +297 -290
  66. package/dist/src/layouts/forceatlas2.js.map +1 -1
  67. package/dist/src/layouts/fruchterman-reingold.d.ts +241 -0
  68. package/dist/src/layouts/fruchterman-reingold.d.ts.map +1 -0
  69. package/dist/src/layouts/fruchterman-reingold.js +739 -0
  70. package/dist/src/layouts/fruchterman-reingold.js.map +1 -0
  71. package/dist/src/layouts/model-common.d.ts +140 -0
  72. package/dist/src/layouts/model-common.d.ts.map +1 -0
  73. package/dist/src/layouts/model-common.js +269 -0
  74. package/dist/src/layouts/model-common.js.map +1 -0
  75. package/dist/src/layouts/repulsion-grid.d.ts +152 -0
  76. package/dist/src/layouts/repulsion-grid.d.ts.map +1 -0
  77. package/dist/src/layouts/repulsion-grid.js +318 -0
  78. package/dist/src/layouts/repulsion-grid.js.map +1 -0
  79. package/dist/src/layouts/spring-electrical.d.ts +224 -0
  80. package/dist/src/layouts/spring-electrical.d.ts.map +1 -0
  81. package/dist/src/layouts/spring-electrical.js +665 -0
  82. package/dist/src/layouts/spring-electrical.js.map +1 -0
  83. package/dist/src/memory/residency.d.ts +6 -2
  84. package/dist/src/memory/residency.d.ts.map +1 -1
  85. package/dist/src/memory/residency.js +84 -14
  86. package/dist/src/memory/residency.js.map +1 -1
  87. package/dist/src/primitives/core-shape.d.ts +38 -2
  88. package/dist/src/primitives/core-shape.d.ts.map +1 -1
  89. package/dist/src/primitives/core-shape.js +71 -3
  90. package/dist/src/primitives/core-shape.js.map +1 -1
  91. package/dist/src/primitives/grid-pyramid.d.ts +71 -0
  92. package/dist/src/primitives/grid-pyramid.d.ts.map +1 -0
  93. package/dist/src/primitives/grid-pyramid.js +143 -0
  94. package/dist/src/primitives/grid-pyramid.js.map +1 -0
  95. package/dist/src/primitives/grid.d.ts +118 -0
  96. package/dist/src/primitives/grid.d.ts.map +1 -0
  97. package/dist/src/primitives/grid.js +225 -0
  98. package/dist/src/primitives/grid.js.map +1 -0
  99. package/dist/src/primitives/histogram.d.ts +67 -0
  100. package/dist/src/primitives/histogram.d.ts.map +1 -0
  101. package/dist/src/primitives/histogram.js +190 -0
  102. package/dist/src/primitives/histogram.js.map +1 -0
  103. package/dist/src/primitives/radix-sort.d.ts +75 -0
  104. package/dist/src/primitives/radix-sort.d.ts.map +1 -0
  105. package/dist/src/primitives/radix-sort.js +168 -0
  106. package/dist/src/primitives/radix-sort.js.map +1 -0
  107. package/dist/src/primitives/scan.d.ts +44 -0
  108. package/dist/src/primitives/scan.d.ts.map +1 -0
  109. package/dist/src/primitives/scan.js +151 -0
  110. package/dist/src/primitives/scan.js.map +1 -0
  111. package/dist/src/primitives/segmented-reduce.d.ts +25 -17
  112. package/dist/src/primitives/segmented-reduce.d.ts.map +1 -1
  113. package/dist/src/primitives/segmented-reduce.js +166 -47
  114. package/dist/src/primitives/segmented-reduce.js.map +1 -1
  115. package/dist/src/primitives/spmv.d.ts +18 -14
  116. package/dist/src/primitives/spmv.d.ts.map +1 -1
  117. package/dist/src/primitives/spmv.js +94 -58
  118. package/dist/src/primitives/spmv.js.map +1 -1
  119. package/dist/src/primitives/verify.d.ts +49 -0
  120. package/dist/src/primitives/verify.d.ts.map +1 -0
  121. package/dist/src/primitives/verify.js +229 -0
  122. package/dist/src/primitives/verify.js.map +1 -0
  123. package/dist/src/types/accelerator.d.ts +7 -3
  124. package/dist/src/types/accelerator.d.ts.map +1 -1
  125. package/dist/src/types/context.d.ts +53 -0
  126. package/dist/src/types/context.d.ts.map +1 -1
  127. package/dist/src/types/layout.d.ts +52 -0
  128. package/dist/src/types/layout.d.ts.map +1 -1
  129. package/dist/src/types/options.d.ts +43 -1
  130. package/dist/src/types/options.d.ts.map +1 -1
  131. package/dist/src/wgsl/counting-scatter.wgsl.d.ts +8 -0
  132. package/dist/src/wgsl/counting-scatter.wgsl.d.ts.map +1 -0
  133. package/dist/src/wgsl/counting-scatter.wgsl.js +17 -0
  134. package/dist/src/wgsl/counting-scatter.wgsl.js.map +1 -0
  135. package/dist/src/wgsl/fa2-attraction.wgsl.d.ts +23 -8
  136. package/dist/src/wgsl/fa2-attraction.wgsl.d.ts.map +1 -1
  137. package/dist/src/wgsl/fa2-attraction.wgsl.js +100 -17
  138. package/dist/src/wgsl/fa2-attraction.wgsl.js.map +1 -1
  139. package/dist/src/wgsl/fa2-integrate.wgsl.d.ts +7 -2
  140. package/dist/src/wgsl/fa2-integrate.wgsl.d.ts.map +1 -1
  141. package/dist/src/wgsl/fa2-integrate.wgsl.js +28 -2
  142. package/dist/src/wgsl/fa2-integrate.wgsl.js.map +1 -1
  143. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.d.ts +4 -2
  144. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.d.ts.map +1 -1
  145. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.js +14 -5
  146. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.js.map +1 -1
  147. package/dist/src/wgsl/fa2-stats-finalize.wgsl.d.ts +12 -1
  148. package/dist/src/wgsl/fa2-stats-finalize.wgsl.d.ts.map +1 -1
  149. package/dist/src/wgsl/fa2-stats-finalize.wgsl.js +54 -0
  150. package/dist/src/wgsl/fa2-stats-finalize.wgsl.js.map +1 -1
  151. package/dist/src/wgsl/grid-cell-key.wgsl.d.ts +8 -0
  152. package/dist/src/wgsl/grid-cell-key.wgsl.d.ts.map +1 -0
  153. package/dist/src/wgsl/grid-cell-key.wgsl.js +30 -0
  154. package/dist/src/wgsl/grid-cell-key.wgsl.js.map +1 -0
  155. package/dist/src/wgsl/grid-centroid-hub.wgsl.d.ts +8 -0
  156. package/dist/src/wgsl/grid-centroid-hub.wgsl.d.ts.map +1 -0
  157. package/dist/src/wgsl/grid-centroid-hub.wgsl.js +29 -0
  158. package/dist/src/wgsl/grid-centroid-hub.wgsl.js.map +1 -0
  159. package/dist/src/wgsl/grid-centroid.wgsl.d.ts +8 -0
  160. package/dist/src/wgsl/grid-centroid.wgsl.d.ts.map +1 -0
  161. package/dist/src/wgsl/grid-centroid.wgsl.js +29 -0
  162. package/dist/src/wgsl/grid-centroid.wgsl.js.map +1 -0
  163. package/dist/src/wgsl/grid-downsample.wgsl.d.ts +7 -0
  164. package/dist/src/wgsl/grid-downsample.wgsl.d.ts.map +1 -0
  165. package/dist/src/wgsl/grid-downsample.wgsl.js +28 -0
  166. package/dist/src/wgsl/grid-downsample.wgsl.js.map +1 -0
  167. package/dist/src/wgsl/grid-far-field.wgsl.d.ts +13 -0
  168. package/dist/src/wgsl/grid-far-field.wgsl.d.ts.map +1 -0
  169. package/dist/src/wgsl/grid-far-field.wgsl.js +98 -0
  170. package/dist/src/wgsl/grid-far-field.wgsl.js.map +1 -0
  171. package/dist/src/wgsl/grid-near-field.wgsl.d.ts +19 -0
  172. package/dist/src/wgsl/grid-near-field.wgsl.d.ts.map +1 -0
  173. package/dist/src/wgsl/grid-near-field.wgsl.js +129 -0
  174. package/dist/src/wgsl/grid-near-field.wgsl.js.map +1 -0
  175. package/dist/src/wgsl/histogram.wgsl.d.ts +7 -0
  176. package/dist/src/wgsl/histogram.wgsl.d.ts.map +1 -0
  177. package/dist/src/wgsl/histogram.wgsl.js +15 -0
  178. package/dist/src/wgsl/histogram.wgsl.js.map +1 -0
  179. package/dist/src/wgsl/indirect-finalize.wgsl.d.ts +8 -0
  180. package/dist/src/wgsl/indirect-finalize.wgsl.d.ts.map +1 -0
  181. package/dist/src/wgsl/indirect-finalize.wgsl.js +26 -0
  182. package/dist/src/wgsl/indirect-finalize.wgsl.js.map +1 -0
  183. package/dist/src/wgsl/radix-hist.wgsl.d.ts +9 -0
  184. package/dist/src/wgsl/radix-hist.wgsl.d.ts.map +1 -0
  185. package/dist/src/wgsl/radix-hist.wgsl.js +31 -0
  186. package/dist/src/wgsl/radix-hist.wgsl.js.map +1 -0
  187. package/dist/src/wgsl/radix-scatter.wgsl.d.ts +9 -0
  188. package/dist/src/wgsl/radix-scatter.wgsl.d.ts.map +1 -0
  189. package/dist/src/wgsl/radix-scatter.wgsl.js +40 -0
  190. package/dist/src/wgsl/radix-scatter.wgsl.js.map +1 -0
  191. package/dist/src/wgsl/scan-add.wgsl.d.ts +6 -0
  192. package/dist/src/wgsl/scan-add.wgsl.d.ts.map +1 -0
  193. package/dist/src/wgsl/scan-add.wgsl.js +14 -0
  194. package/dist/src/wgsl/scan-add.wgsl.js.map +1 -0
  195. package/dist/src/wgsl/scan-block.wgsl.d.ts +8 -0
  196. package/dist/src/wgsl/scan-block.wgsl.d.ts.map +1 -0
  197. package/dist/src/wgsl/scan-block.wgsl.js +30 -0
  198. package/dist/src/wgsl/scan-block.wgsl.js.map +1 -0
  199. package/dist/src/wgsl/segmented-reduce.wgsl.d.ts +22 -8
  200. package/dist/src/wgsl/segmented-reduce.wgsl.d.ts.map +1 -1
  201. package/dist/src/wgsl/segmented-reduce.wgsl.js +84 -15
  202. package/dist/src/wgsl/segmented-reduce.wgsl.js.map +1 -1
  203. package/dist/src/wgsl/spmv-pull.wgsl.d.ts +22 -11
  204. package/dist/src/wgsl/spmv-pull.wgsl.d.ts.map +1 -1
  205. package/dist/src/wgsl/spmv-pull.wgsl.js +110 -36
  206. package/dist/src/wgsl/spmv-pull.wgsl.js.map +1 -1
  207. package/dist/tsconfig.build.tsbuildinfo +1 -1
  208. package/dist/webgpu-graph-algorithms.js +5016 -1130
  209. package/dist/webgpu-graph-algorithms.js.map +1 -1
  210. package/package.json +10 -7
  211. package/src/accelerator.ts +46 -12
  212. package/src/algorithms/components.ts +12 -16
  213. package/src/algorithms/degree.ts +58 -43
  214. package/src/algorithms/pagerank.ts +20 -18
  215. package/src/algorithms/power-iteration.ts +19 -18
  216. package/src/constants.ts +108 -8
  217. package/src/errors.ts +3 -1
  218. package/src/index.ts +25 -5
  219. package/src/kernel/dispatch.ts +18 -7
  220. package/src/kernel/kernel.ts +59 -5
  221. package/src/kernel/prelude.ts +15 -0
  222. package/src/kernel/profiler.ts +28 -4
  223. package/src/kernels.ts +378 -24
  224. package/src/layouts/calibrate.ts +187 -0
  225. package/src/layouts/force-simulation.ts +111 -26
  226. package/src/layouts/forceatlas2.ts +346 -324
  227. package/src/layouts/fruchterman-reingold.ts +918 -0
  228. package/src/layouts/model-common.ts +323 -0
  229. package/src/layouts/repulsion-grid.ts +451 -0
  230. package/src/layouts/spring-electrical.ts +845 -0
  231. package/src/memory/residency.ts +126 -20
  232. package/src/primitives/core-shape.ts +91 -4
  233. package/src/primitives/grid-pyramid.ts +221 -0
  234. package/src/primitives/grid.ts +349 -0
  235. package/src/primitives/histogram.ts +273 -0
  236. package/src/primitives/radix-sort.ts +246 -0
  237. package/src/primitives/scan.ts +197 -0
  238. package/src/primitives/segmented-reduce.ts +214 -56
  239. package/src/primitives/spmv.ts +125 -65
  240. package/src/primitives/verify.ts +249 -0
  241. package/src/types/accelerator.ts +15 -3
  242. package/src/types/context.ts +56 -0
  243. package/src/types/layout.ts +58 -0
  244. package/src/types/options.ts +45 -1
  245. package/src/wgsl/counting-scatter.wgsl.ts +16 -0
  246. package/src/wgsl/fa2-attraction.wgsl.ts +100 -17
  247. package/src/wgsl/fa2-integrate.wgsl.ts +28 -2
  248. package/src/wgsl/fa2-repulsion-exact.wgsl.ts +14 -5
  249. package/src/wgsl/fa2-stats-finalize.wgsl.ts +54 -0
  250. package/src/wgsl/grid-cell-key.wgsl.ts +29 -0
  251. package/src/wgsl/grid-centroid-hub.wgsl.ts +28 -0
  252. package/src/wgsl/grid-centroid.wgsl.ts +28 -0
  253. package/src/wgsl/grid-downsample.wgsl.ts +27 -0
  254. package/src/wgsl/grid-far-field.wgsl.ts +97 -0
  255. package/src/wgsl/grid-near-field.wgsl.ts +128 -0
  256. package/src/wgsl/histogram.wgsl.ts +14 -0
  257. package/src/wgsl/indirect-finalize.wgsl.ts +25 -0
  258. package/src/wgsl/radix-hist.wgsl.ts +30 -0
  259. package/src/wgsl/radix-scatter.wgsl.ts +39 -0
  260. package/src/wgsl/scan-add.wgsl.ts +13 -0
  261. package/src/wgsl/scan-block.wgsl.ts +29 -0
  262. package/src/wgsl/segmented-reduce.wgsl.ts +84 -15
  263. package/src/wgsl/spmv-pull.wgsl.ts +110 -36
  264. 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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"}