@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,151 @@
1
+ /**
2
+ * The `exclusiveScan` primitive driver (spec 6 row 2; P4-T2, PD-3): a reduce-then-scan over u32 words. Level 0 runs
3
+ * `scan-block` over `count` items into `out` (each workgroup an exclusive Hillis-Steele scan of its WG-wide block) and
4
+ * writes one block sum per workgroup; while a level has more than one block, the next level scans its block sums
5
+ * (exclusive, into `offsets_L`) and writes its own block sums, recursively; the top level has ONE block, so its one
6
+ * sums word is the total. Then, top down, `scan-add` adds `offsets_L[g]` to every element of block `g` of level L's
7
+ * output. u32 addition is exact in any order, so two runs on any two adapters are bitwise identical; there is no
8
+ * subgroup variant (DEP-P4-E) and no decoupled look-back.
9
+ *
10
+ * The driver owns no device objects beyond a one-word zero it keeps for the empty scan: the caller supplies a
11
+ * ReduceScope (the same record `reduce` takes) and the compute pass to record into. `src/primitives/**` never imports
12
+ * `src/context.ts`.
13
+ */
14
+ import { WebGpuGraphError } from "../errors.js";
15
+ import { groupsOf, plan1d } from "../kernel/dispatch.js";
16
+ import { kernelSpec, SCAN_PARAMS } from "../kernels.js";
17
+ /** The largest u32: the largest count `ScanParams.count` can carry. */
18
+ const U32_MAX = 0xffffffff;
19
+ /**
20
+ * Prepares the two scan pipelines of a scope (compiles once) so record() is synchronous. The zero word the empty
21
+ * scan's total points at is a scratch of `scope`, so the planner lives exactly as long as the scope: never use a
22
+ * planner after its scope's dispose().
23
+ * @param scope - the caller's scope (device, caps, cache, scratch, params)
24
+ * @returns the planner
25
+ */
26
+ export async function prepareScan(scope) {
27
+ const block = await scope.pipelines.kernel(kernelSpec("scan-block"));
28
+ const add = await scope.pipelines.kernel(kernelSpec("scan-add"));
29
+ const zero = scope.scratch(4, "scan/zero");
30
+ scope.device.queue.writeBuffer(zero, 0, new Uint32Array(1));
31
+ return new ScanPlannerImpl(scope, block, add, { buffer: zero, offset: 0, size: 4, window: null });
32
+ }
33
+ /**
34
+ * The argument checks of record() (E_INVALID_ARGUMENT before anything is recorded).
35
+ * @param src - the input binding
36
+ * @param count - the word count
37
+ * @param out - the output binding
38
+ */
39
+ function checkRecordArguments(src, count, out) {
40
+ if (!Number.isSafeInteger(count) || count < 0 || count > U32_MAX) {
41
+ throw new WebGpuGraphError("E_INVALID_ARGUMENT", "scan: count must be a non-negative integer below 2^32", {
42
+ argument: "count",
43
+ value: count,
44
+ });
45
+ }
46
+ if (src.size < 4 * count) {
47
+ throw new WebGpuGraphError("E_INVALID_ARGUMENT", "scan: src is smaller than 4 x count bytes", {
48
+ argument: "src",
49
+ value: src.size,
50
+ expected: 4 * count,
51
+ });
52
+ }
53
+ if (out.size < 4 * count) {
54
+ throw new WebGpuGraphError("E_INVALID_ARGUMENT", "scan: out is smaller than 4 x count bytes", {
55
+ argument: "out",
56
+ value: out.size,
57
+ expected: 4 * count,
58
+ });
59
+ }
60
+ }
61
+ /** The planner: the two resolved kernels over one scope. */
62
+ class ScanPlannerImpl {
63
+ /**
64
+ * Wraps the resolved kernels; use prepareScan().
65
+ * @param scope - the caller's scope
66
+ * @param block - the `scan-block` kernel
67
+ * @param add - the `scan-add` kernel
68
+ * @param zero - a one-word binding holding 0 (the total of the empty scan)
69
+ */
70
+ constructor(scope, block, add, zero) {
71
+ this.dispatches = 0;
72
+ this.scope = scope;
73
+ this.block = block;
74
+ this.add = add;
75
+ this.zero = zero;
76
+ }
77
+ /**
78
+ * Dispatches the last record() issued.
79
+ * @returns the count
80
+ */
81
+ get lastDispatches() {
82
+ return this.dispatches;
83
+ }
84
+ /**
85
+ * Records the levels into the pass (see the interface).
86
+ * @param pass - the compute pass
87
+ * @param src - the input words
88
+ * @param count - the word count
89
+ * @param out - the output words
90
+ * @returns the total's location
91
+ */
92
+ record(pass, src, count, out) {
93
+ checkRecordArguments(src, count, out);
94
+ if (count === 0) {
95
+ this.dispatches = 0;
96
+ return { binding: this.zero, index: 0 };
97
+ }
98
+ const wg = this.scope.workgroupSize;
99
+ const levels = [];
100
+ let input = src;
101
+ let output = out;
102
+ let levelCount = count;
103
+ for (;;) {
104
+ const blocks = Math.ceil(levelCount / wg);
105
+ // Sized by the PADDED workgroup count (reduce's shape, reduce.ts partials-1): above MAX_1D_ITEMS plan1d pads
106
+ // the grid to x * y >= blocks, and every padded workgroup still stores its (zero) block sum at its own index.
107
+ // The next level scans only `blocks` words, so the padded tail is written and never read.
108
+ const plan = plan1d(levelCount, wg, this.scope.caps);
109
+ const groups = groupsOf(plan);
110
+ const sums = this.scratch(groups, `scan/sums${levels.length}`);
111
+ levels.push({ input, output, count: levelCount, plan, sums });
112
+ if (blocks === 1) {
113
+ break;
114
+ }
115
+ input = sums;
116
+ output = this.scratch(groups, `scan/offsets${levels.length}`);
117
+ levelCount = blocks;
118
+ }
119
+ for (const level of levels) {
120
+ const params = this.scope.params(SCAN_PARAMS, { count: level.count, pad0: 0, pad1: 0, pad2: 0 });
121
+ const bound = this.block.bind({
122
+ src: level.input,
123
+ out: level.output,
124
+ blockSums: level.sums,
125
+ P: params.binding,
126
+ });
127
+ this.block.dispatch(pass, bound, level.plan, [params.offset]);
128
+ }
129
+ for (let l = levels.length - 2; l >= 0; l--) {
130
+ const level = levels[l];
131
+ const params = this.scope.params(SCAN_PARAMS, { count: level.count, pad0: 0, pad1: 0, pad2: 0 });
132
+ const bound = this.add.bind({ out: level.output, blockOffsets: levels[l + 1].output, P: params.binding });
133
+ this.add.dispatch(pass, bound, level.plan, [params.offset]);
134
+ }
135
+ this.dispatches = 2 * levels.length - 1;
136
+ const top = levels[levels.length - 1];
137
+ return { binding: top.sums, index: 0 };
138
+ }
139
+ /**
140
+ * A scratch of `words` u32 from the scope, bound whole (never zero-length; the pool rounds the buffer up).
141
+ * @param words - the word count (>= 1)
142
+ * @param label - the scratch label
143
+ * @returns the binding
144
+ */
145
+ scratch(words, label) {
146
+ const size = 4 * words;
147
+ const buffer = this.scope.scratch(size, label);
148
+ return { buffer, offset: 0, size, window: null };
149
+ }
150
+ }
151
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/primitives/scan.ts"],"names":[],"mappings":"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"}
@@ -1,20 +1,23 @@
1
1
  /**
2
- * The segmented (per-row) reduction primitive of spec 6 row 3 in its thread-per-row tier (P2-P3): one invocation per
3
- * CSR row folds the caller's VALUE snippet over the row's arcs into `out[row]` (f32), a row with no arcs receiving
4
- * the identity element. The degree tiers of degreeOrder() (subgroup-per-row for the mid tier, workgroup-per-row for
5
- * the high tier) land at P4; until then `tiers !== null` is E_UNSUPPORTED and USE_PERM is always false (the perm
6
- * slot carries the rowPtr dummy of graphBindings). The row and arc counts come from the core's binding sizes: the
7
- * residency binds every array at its exact byte length (contract 3.8), so rowPtr is 4(n + 1) bytes and colIdx
8
- * 4 x arcCount.
2
+ * The segmented (per-row) reduction primitive of spec 6 row 3: the caller's VALUE snippet folded over every CSR
3
+ * row's arcs into `out[row]` (f32), a row with no arcs receiving the identity element. Without tiers it is ONE
4
+ * thread-per-row dispatch (TIER 0, USE_PERM false: the perm slot carries the rowPtr dummy of graphBindings). With
5
+ * the degree tiers of degreeOrder() (P4-T5, PD-6) it is up to three dispatches over the permuted rows: TIER 2, one
6
+ * workgroup per row of degree >= 1024 over [0, hiEnd); TIER 1, 32 lanes per row of degree 32..1023 over [hiEnd,
7
+ * midEnd); TIER 0, one thread per row over [midEnd, n) -- each compiled only when its range is non-empty. The row
8
+ * and arc counts come from the core's binding sizes: the residency binds every array at its exact byte length
9
+ * (contract 3.8), so rowPtr is 4(n + 1) bytes and colIdx 4 x arcCount. On a windowed core (spec 4.2, P4-T7, PD-8)
10
+ * the dispatches repeat per window with `arcBase = w.start`, `arcEnd = w.end` and `accumulate = 1` over an out
11
+ * pre-filled with the identity element (unless the caller asked to accumulate), so a row split across windows
12
+ * combines its partials: the untiered dispatch covers the window's rows [rowFirst, rowLast], while every tier
13
+ * dispatch covers its FULL tier range (permutation positions, not comparable with the window's node rows; a row
14
+ * whose arcs lie outside the window folds nothing and `finish` writes comb(out[i], identity) = out[i]).
9
15
  */
10
16
  import { type CoreBinding } from "../memory/residency.js";
11
17
  import { type Binding } from "../types/memory.js";
18
+ import { type DegreeTiers } from "./core-shape.js";
12
19
  import { type ReduceOp, type ReduceScope } from "./reduce.js";
13
- /** The degree tiers of degreeOrder(): the permutation binding and the CPU-side segmentOffsets [0, hiEnd, midEnd, lowEnd, n]. */
14
- export interface DegreeTiers {
15
- readonly perm: Binding;
16
- readonly segmentOffsets: readonly [number, number, number, number, number];
17
- }
20
+ export { type DegreeTiers } from "./core-shape.js";
18
21
  /** Options of segmentedReduce. `valueSnippet` is the Gunrock-style functor: WGSL statements assigning `v` from (row, arc, nbr, weight) (4.5; `nbr` because `target` is a WGSL reserved word). */
19
22
  export interface SegmentedReduceOptions {
20
23
  readonly op: ReduceOp;
@@ -22,16 +25,21 @@ export interface SegmentedReduceOptions {
22
25
  readonly tiers: DegreeTiers | null;
23
26
  readonly accumulate?: boolean | undefined;
24
27
  }
25
- /** A prepared segmented reduce (P2-P3: the thread-per-row tier only; `tiers !== null` -> E_UNSUPPORTED { feature: "segmentedReduce.tiers" } until P4). */
28
+ /** A prepared segmented reduce: one thread-per-row dispatch without tiers, up to three tier dispatches with them (times the windows of a windowed core, plus its identity fill). */
26
29
  export interface SegmentedReducePlanner {
27
- /** Records one dispatch over rows [0, n) (tiers null) writing out[i] (f32) per row; a row with no arcs gets the identity element. */
30
+ /** Records the dispatches over rows [0, n) writing out[i] (f32) per row; a row with no arcs gets the identity element. */
28
31
  record(pass: GPUComputePassEncoder, core: CoreBinding, out: Binding): void;
32
+ /** Dispatches the last record() issued (0 for n = 0; 1 without tiers; 1 to 3 with them; on a windowed core the identity fill plus that many per window). */
33
+ readonly lastDispatches: number;
29
34
  }
30
35
  /**
31
- * Prepares the thread-per-row pipeline for a snapshot's dummy pattern (USE_PERM, HAS_WEIGHTS) and snippet.
36
+ * Prepares the tier pipelines for a snapshot's dummy pattern (USE_PERM = tiers !== null, HAS_WEIGHTS) and snippet:
37
+ * TIER 0 always; TIER 1 iff a row of degree 32..1023 exists (segmentOffsets[2] > segmentOffsets[1]); TIER 2 iff a
38
+ * row of degree >= 1024 exists (segmentOffsets[1] > 0). The mid tier folds 32 lanes per row, so a device whose
39
+ * workgroup size is below 32 is E_UNSUPPORTED { feature: "segmentedReduce.tiers" }.
32
40
  * @param scope - the reduce scope (pipelines, pool, params writer)
33
- * @param core - the core whose weights pattern selects HAS_WEIGHTS (USE_PERM is false: no tiers at P2)
34
- * @param options - operator, snippet, tiers (must be null), accumulate
41
+ * @param core - the core whose weights pattern selects HAS_WEIGHTS
42
+ * @param options - operator, snippet, tiers (null: the single thread-per-row dispatch), accumulate
35
43
  * @returns the planner
36
44
  */
37
45
  export declare function prepareSegmentedReduce(scope: ReduceScope, core: CoreBinding, options: SegmentedReduceOptions): Promise<SegmentedReducePlanner>;
@@ -1 +1 @@
1
- {"version":3,"file":"segmented-reduce.d.ts","sourceRoot":"","sources":["../../../src/primitives/segmented-reduce.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE9D,gIAAgI;AAChI,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,cAAc,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9E;AAED,iMAAiM;AACjM,MAAM,WAAW,sBAAsB;IACnC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7C;AAED,0JAA0J;AAC1J,MAAM,WAAW,sBAAsB;IACnC,qIAAqI;IACrI,MAAM,CAAC,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;CAC9E;AAgLD;;;;;;GAMG;AACH,wBAAsB,sBAAsB,CACxC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,sBAAsB,GAChC,OAAO,CAAC,sBAAsB,CAAC,CAajC"}
1
+ {"version":3,"file":"segmented-reduce.d.ts","sourceRoot":"","sources":["../../../src/primitives/segmented-reduce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAkB,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAc,KAAK,WAAW,EAA6C,MAAM,iBAAiB,CAAC;AAC1G,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE9D,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,iMAAiM;AACjM,MAAM,WAAW,sBAAsB;IACnC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7C;AAED,oLAAoL;AACpL,MAAM,WAAW,sBAAsB;IACnC,0HAA0H;IAC1H,MAAM,CAAC,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3E,4JAA4J;IAC5J,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACnC;AA6SD;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CACxC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,sBAAsB,GAChC,OAAO,CAAC,sBAAsB,CAAC,CAuCjC"}
@@ -1,16 +1,42 @@
1
1
  /**
2
- * The segmented (per-row) reduction primitive of spec 6 row 3 in its thread-per-row tier (P2-P3): one invocation per
3
- * CSR row folds the caller's VALUE snippet over the row's arcs into `out[row]` (f32), a row with no arcs receiving
4
- * the identity element. The degree tiers of degreeOrder() (subgroup-per-row for the mid tier, workgroup-per-row for
5
- * the high tier) land at P4; until then `tiers !== null` is E_UNSUPPORTED and USE_PERM is always false (the perm
6
- * slot carries the rowPtr dummy of graphBindings). The row and arc counts come from the core's binding sizes: the
7
- * residency binds every array at its exact byte length (contract 3.8), so rowPtr is 4(n + 1) bytes and colIdx
8
- * 4 x arcCount.
2
+ * The segmented (per-row) reduction primitive of spec 6 row 3: the caller's VALUE snippet folded over every CSR
3
+ * row's arcs into `out[row]` (f32), a row with no arcs receiving the identity element. Without tiers it is ONE
4
+ * thread-per-row dispatch (TIER 0, USE_PERM false: the perm slot carries the rowPtr dummy of graphBindings). With
5
+ * the degree tiers of degreeOrder() (P4-T5, PD-6) it is up to three dispatches over the permuted rows: TIER 2, one
6
+ * workgroup per row of degree >= 1024 over [0, hiEnd); TIER 1, 32 lanes per row of degree 32..1023 over [hiEnd,
7
+ * midEnd); TIER 0, one thread per row over [midEnd, n) -- each compiled only when its range is non-empty. The row
8
+ * and arc counts come from the core's binding sizes: the residency binds every array at its exact byte length
9
+ * (contract 3.8), so rowPtr is 4(n + 1) bytes and colIdx 4 x arcCount. On a windowed core (spec 4.2, P4-T7, PD-8)
10
+ * the dispatches repeat per window with `arcBase = w.start`, `arcEnd = w.end` and `accumulate = 1` over an out
11
+ * pre-filled with the identity element (unless the caller asked to accumulate), so a row split across windows
12
+ * combines its partials: the untiered dispatch covers the window's rows [rowFirst, rowLast], while every tier
13
+ * dispatch covers its FULL tier range (permutation positions, not comparable with the window's node rows; a row
14
+ * whose arcs lie outside the window folds nothing and `finish` writes comb(out[i], identity) = out[i]).
9
15
  */
10
16
  import { WebGpuGraphError } from "../errors.js";
11
17
  import { plan1d } from "../kernel/dispatch.js";
12
- import { graphBindings, graphOverrides, kernelSpec, RANGE_PARAMS } from "../kernels.js";
13
- import { assertNotWindowed, rowCountOf } from "./core-shape.js";
18
+ import { FILL_PARAMS, graphBindings, graphOverrides, kernelSpec, RANGE_PARAMS } from "../kernels.js";
19
+ import { arcCountOf, MID_TIER_LANES, rowCountOf, windowBinding } from "./core-shape.js";
20
+ /** The largest finite f32, 0x1.fffffep+127 (the prelude's F32_MAX): the min identity; its negation the max identity. */
21
+ const F32_MAX = 2 ** 128 - 2 ** 104;
22
+ /**
23
+ * The u32 bit pattern the `fill` kernel writes so every out word holds the identity element of the operator before
24
+ * the windowed dispatches accumulate into it (PD-8).
25
+ * @param op - the operator
26
+ * @returns the bits of 0 (sum), F32_MAX (min) or -F32_MAX (max)
27
+ */
28
+ function identityFillWord(op) {
29
+ let identity = 0;
30
+ if (op === "min") {
31
+ identity = F32_MAX;
32
+ }
33
+ else if (op === "max") {
34
+ identity = -F32_MAX;
35
+ }
36
+ const view = new DataView(new ArrayBuffer(4));
37
+ view.setFloat32(0, identity, true);
38
+ return view.getUint32(0, true);
39
+ }
14
40
  /** The identifiers a VALUE snippet may name (contract 3.11, 4.5); every other identifier is rejected textually before compose. */
15
41
  const VALUE_SNIPPET_VOCABULARY = new Set(["row", "arc", "nbr", "weight", "v"]);
16
42
  /**
@@ -106,30 +132,49 @@ function validateValueSnippet(snippet) {
106
132
  throw new WebGpuGraphError("E_SHADER_COMPILE", `segmentedReduce: the VALUE snippet names "${token}"; the only identifiers allowed are row, arc, nbr, weight and v`, { id: "segmented-reduce", stage: "compose", slot: "VALUE", identifier: token });
107
133
  }
108
134
  }
109
- /** The thread-per-row planner: ONE `segmented-reduce` dispatch with TIER 0 over every row. */
110
- class ThreadPerRowPlanner {
135
+ /**
136
+ * The tiered planner: without tiers ONE `segmented-reduce` dispatch with TIER 0 over [0, n); with tiers TIER 2 over
137
+ * [0, hiEnd) (one workgroup per row), then TIER 1 over [hiEnd, midEnd) (WG / 32 rows per workgroup), then TIER 0
138
+ * over [midEnd, n), each with its own RangeParams record and the perm binding.
139
+ */
140
+ class TieredPlanner {
111
141
  /**
112
- * Wraps a compiled thread-per-row pipeline with the pattern it was compiled for.
113
- * @param scope - the scope the pipeline was prepared in
114
- * @param kernel - the compiled kernel
115
- * @param hasWeights - the HAS_WEIGHTS the pipeline was compiled with
142
+ * Wraps the compiled tier pipelines with the pattern they were compiled for.
143
+ * @param scope - the scope the pipelines were prepared in
144
+ * @param tiers - the compiled tiers in dispatch order (TIER 2, 1, 0; only the non-empty ones)
145
+ * @param fill - the `fill` pipeline of the identity pre-fill of a windowed core
146
+ * @param perm - the degreeOrder permutation binding (null: USE_PERM false, rows are node indices)
147
+ * @param hasWeights - the HAS_WEIGHTS the pipelines were compiled with
116
148
  * @param accumulate - whether record() combines into out instead of overwriting
149
+ * @param identityWord - the u32 bits of the operator's identity element (identityFillWord)
117
150
  */
118
- constructor(scope, kernel, hasWeights, accumulate) {
151
+ constructor(scope, tiers, fill, perm, hasWeights, accumulate, identityWord) {
152
+ this.dispatches = 0;
119
153
  this.scope = scope;
120
- this.kernel = kernel;
154
+ this.tiers = tiers;
155
+ this.fill = fill;
156
+ this.perm = perm;
121
157
  this.hasWeights = hasWeights;
122
158
  this.accumulate = accumulate;
159
+ this.identityWord = identityWord;
123
160
  }
124
161
  /**
125
- * Records the dispatch: rows [0, n), arcs [0, arcCount), plan1d(n); nothing for n = 0 (no zero-length binding is
126
- * ever created).
162
+ * Dispatches the last record() issued.
163
+ * @returns 0 for n = 0, else the number of non-empty tier ranges
164
+ */
165
+ get lastDispatches() {
166
+ return this.dispatches;
167
+ }
168
+ /**
169
+ * Records the dispatches: every tier's rows over the arcs [0, arcCount), each with its own params record;
170
+ * nothing for n = 0 (no zero-length binding is ever created). On a windowed core: the identity fill (unless
171
+ * accumulating into the caller's out), then the dispatches once per window (PD-8).
127
172
  * @param pass - the pass to record into
128
- * @param core - a core with the SAME weights pattern as the one prepared (any snapshot)
173
+ * @param core - a core with the SAME weights pattern as the one prepared (any snapshot; with tiers, the one the
174
+ * tiers were built from)
129
175
  * @param out - at least 4n bytes of f32
130
176
  */
131
177
  record(pass, core, out) {
132
- assertNotWindowed(core, "segmentedReduce");
133
178
  if ((core.weights !== null) !== this.hasWeights) {
134
179
  throw new WebGpuGraphError("E_INVALID_ARGUMENT", "segmentedReduce: the core's weights pattern differs from the one prepared", {
135
180
  argument: "core",
@@ -138,10 +183,6 @@ class ThreadPerRowPlanner {
138
183
  });
139
184
  }
140
185
  const n = rowCountOf(core, "segmentedReduce");
141
- if (n === 0) {
142
- return;
143
- }
144
- const arcCount = core.colIdx === null ? 0 : core.colIdx.size / 4;
145
186
  if (out.size < 4 * n) {
146
187
  throw new WebGpuGraphError("E_INVALID_ARGUMENT", `segmentedReduce: out holds ${out.size} bytes, ${4 * n} needed`, {
147
188
  argument: "out",
@@ -149,37 +190,115 @@ class ThreadPerRowPlanner {
149
190
  expected: `>= ${4 * n}`,
150
191
  });
151
192
  }
152
- const params = this.scope.params(RANGE_PARAMS, {
153
- start: 0,
154
- end: n,
155
- arcBase: 0,
156
- arcEnd: arcCount,
157
- accumulate: this.accumulate ? 1 : 0,
158
- n,
193
+ this.dispatches = 0;
194
+ if (n === 0) {
195
+ return;
196
+ }
197
+ if (core.windows === null) {
198
+ this.recordWindow(pass, core, out, n, null, 0);
199
+ return;
200
+ }
201
+ if (!this.accumulate) {
202
+ const params = this.scope.params(FILL_PARAMS, { count: n, value: this.identityWord, mode: 0 });
203
+ const bound = this.fill.bind({ dst: out, P: params.binding });
204
+ this.fill.dispatch(pass, bound, plan1d(n, this.scope.workgroupSize, this.scope.caps), [params.offset]);
205
+ this.dispatches++;
206
+ }
207
+ const { windows } = core;
208
+ windows.forEach((w, k) => {
209
+ const windowed = {
210
+ ...core,
211
+ colIdx: windowBinding(core, "colIdx", w),
212
+ weights: core.weights === null ? null : windowBinding(core, "weights", w),
213
+ };
214
+ this.recordWindow(pass, windowed, out, n, w, k + 1 < windows.length ? windows[k + 1].start : w.end);
159
215
  });
160
- const bound = this.kernel.bind({ ...graphBindings(core, null), out, P: params.binding });
161
- this.kernel.dispatch(pass, bound, plan1d(n, this.scope.workgroupSize, this.scope.caps), [params.offset]);
216
+ }
217
+ /**
218
+ * The tier dispatches over one arc window (or the whole core when `w` is null): every non-empty tier over its
219
+ * full range, except the untiered TIER 0 dispatch, which covers exactly the window's rows. Consecutive windows
220
+ * overlap by up to ARC_WINDOW_ALIGN - 1 arcs (the next window opens at the aligned-down end of this one), and a
221
+ * tier dispatch visits EVERY row, so the tiers fold [w.start, nextStart) and leave the overlap to the next
222
+ * window; the untiered dispatch keeps [w.start, w.end): its rows [rowFirst, rowLast] are exactly the rows whose
223
+ * arcs end inside this window, and the next window's rows start after them.
224
+ * @param pass - the pass to record into
225
+ * @param core - the core with the window's colIdx / weights bound
226
+ * @param out - the output binding
227
+ * @param n - the row count
228
+ * @param w - the window, or null for the single whole-core dispatch
229
+ * @param nextStart - the next window's first arc (w.end for the last window)
230
+ */
231
+ recordWindow(pass, core, out, n, w, nextStart) {
232
+ const wg = this.scope.workgroupSize;
233
+ for (const { tier, kernel, start, end } of this.tiers) {
234
+ let first = start;
235
+ let last = tier === 0 ? n : end;
236
+ let arcEnd = w === null ? arcCountOf(core) : Math.min(w.end, nextStart);
237
+ if (w !== null && this.perm === null) {
238
+ first = w.rowFirst;
239
+ last = w.rowLast + 1;
240
+ arcEnd = w.end;
241
+ }
242
+ const rows = last - first;
243
+ if (rows <= 0) {
244
+ continue;
245
+ }
246
+ const params = this.scope.params(RANGE_PARAMS, {
247
+ start: first,
248
+ end: last,
249
+ arcBase: w === null ? 0 : w.start,
250
+ arcEnd,
251
+ accumulate: w !== null || this.accumulate ? 1 : 0,
252
+ n,
253
+ });
254
+ const bound = kernel.bind({ ...graphBindings(core, this.perm), out, P: params.binding });
255
+ let rowsPerGroup = wg;
256
+ if (tier === 2) {
257
+ rowsPerGroup = 1;
258
+ }
259
+ else if (tier === 1) {
260
+ rowsPerGroup = wg / MID_TIER_LANES;
261
+ }
262
+ kernel.dispatch(pass, bound, plan1d(rows, rowsPerGroup, this.scope.caps), [params.offset]);
263
+ this.dispatches++;
264
+ }
162
265
  }
163
266
  }
164
267
  /**
165
- * Prepares the thread-per-row pipeline for a snapshot's dummy pattern (USE_PERM, HAS_WEIGHTS) and snippet.
268
+ * Prepares the tier pipelines for a snapshot's dummy pattern (USE_PERM = tiers !== null, HAS_WEIGHTS) and snippet:
269
+ * TIER 0 always; TIER 1 iff a row of degree 32..1023 exists (segmentOffsets[2] > segmentOffsets[1]); TIER 2 iff a
270
+ * row of degree >= 1024 exists (segmentOffsets[1] > 0). The mid tier folds 32 lanes per row, so a device whose
271
+ * workgroup size is below 32 is E_UNSUPPORTED { feature: "segmentedReduce.tiers" }.
166
272
  * @param scope - the reduce scope (pipelines, pool, params writer)
167
- * @param core - the core whose weights pattern selects HAS_WEIGHTS (USE_PERM is false: no tiers at P2)
168
- * @param options - operator, snippet, tiers (must be null), accumulate
273
+ * @param core - the core whose weights pattern selects HAS_WEIGHTS
274
+ * @param options - operator, snippet, tiers (null: the single thread-per-row dispatch), accumulate
169
275
  * @returns the planner
170
276
  */
171
277
  export async function prepareSegmentedReduce(scope, core, options) {
172
- if (options.tiers !== null) {
173
- throw new WebGpuGraphError("E_UNSUPPORTED", "segmentedReduce: the degree tiers land at P4; pass tiers: null", {
174
- feature: "segmentedReduce.tiers",
175
- });
176
- }
177
- assertNotWindowed(core, "segmentedReduce");
178
278
  const op = opCode(options.op);
179
279
  validateValueSnippet(options.valueSnippet);
180
- const overrides = { ...graphOverrides(core, null), OP: op, TIER: 0 };
181
- const spec = kernelSpec("segmented-reduce", overrides, { VALUE: options.valueSnippet });
182
- const kernel = await scope.pipelines.kernel(spec);
183
- return new ThreadPerRowPlanner(scope, kernel, core.weights !== null, options.accumulate === true);
280
+ const { tiers } = options;
281
+ const perm = tiers?.perm ?? null;
282
+ if (tiers !== null && scope.workgroupSize < MID_TIER_LANES) {
283
+ throw new WebGpuGraphError("E_UNSUPPORTED", `segmentedReduce: the mid tier folds ${MID_TIER_LANES} lanes per row, more than the workgroup size ${scope.workgroupSize}`, { feature: "segmentedReduce.tiers" });
284
+ }
285
+ const ranges = tiers === null
286
+ ? [{ tier: 0, start: 0, end: rowCountOf(core, "segmentedReduce") }]
287
+ : [
288
+ { tier: 2, start: 0, end: tiers.segmentOffsets[1] },
289
+ { tier: 1, start: tiers.segmentOffsets[1], end: tiers.segmentOffsets[2] },
290
+ { tier: 0, start: tiers.segmentOffsets[2], end: tiers.segmentOffsets[4] },
291
+ ];
292
+ const compiled = [];
293
+ for (const range of ranges) {
294
+ if (range.tier !== 0 && range.end <= range.start) {
295
+ continue;
296
+ }
297
+ const overrides = { ...graphOverrides(core, perm), OP: op, TIER: range.tier };
298
+ const spec = kernelSpec("segmented-reduce", overrides, { VALUE: options.valueSnippet });
299
+ compiled.push({ ...range, kernel: await scope.pipelines.kernel(spec) });
300
+ }
301
+ const fill = await scope.pipelines.kernel(kernelSpec("fill"));
302
+ return new TieredPlanner(scope, compiled, fill, perm, core.weights !== null, options.accumulate === true, identityFillWord(options.op));
184
303
  }
185
304
  //# sourceMappingURL=segmented-reduce.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"segmented-reduce.js","sourceRoot":"","sources":["../../../src/primitives/segmented-reduce.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"segmented-reduce.js","sourceRoot":"","sources":["../../../src/primitives/segmented-reduce.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,6 @@
1
1
  /**
2
- * The pull SpMV primitive of spec 6 row 9 / 8.2 in its thread-per-row tier (P7; M8b plan PD-1 / PD-2): one
3
- * grid-stride dispatch of the `spmv-pull` module over the rows of a REVERSE adjacency, each invocation folding
4
- * `weight * xNorm[nbr]` over its row's in-arcs (Kahan-compensated, f32) and writing
2
+ * The pull SpMV primitive of spec 6 row 9 / 8.2 (P7; M8b plan PD-1 / PD-2): the `spmv-pull` module over the rows of
3
+ * a REVERSE adjacency, each row folding `weight * xNorm[nbr]` over its in-arcs (a two-level f32 sum) and writing
5
4
  * `rankOut[v] = beta * pv + alpha * (sum + danglingMass * pv)`, where `pv` is `personalization[v]` under
6
5
  * HAS_PERSONALIZATION and the uniform `P.uniformP` otherwise, and `danglingMass` is `partials[0].danglingMass`
7
6
  * under USE_DANGLING. PageRank sets alpha to the damping, beta to 1 - alpha and USE_DANGLING; HITS and eigenvector
@@ -9,14 +8,16 @@
9
8
  *
10
9
  * It is its own registry entry rather than a `segmentedReduce` VALUE snippet (PD-1): the snippet vocabulary is
11
10
  * `row, arc, nbr, weight, v` and cannot read `xNorm[nbr]`, and the design's binding table gives the kernel eight
12
- * storage bindings of its own. The in-degree tiers of `reverseDegreeOrder()` land at P4 (PD-2): `tiers !== null` is
13
- * E_UNSUPPORTED and USE_PERM is always false (the perm slot carries the rowPtr dummy of graphBindings). The row and
14
- * arc counts come from the core's binding sizes exactly as segmentedReduce derives them.
11
+ * storage bindings of its own. Without tiers it is ONE grid-stride dispatch (TIER 0, USE_PERM false: the perm slot
12
+ * carries the rowPtr dummy of graphBindings); with the in-degree tiers of `reverseDegreeOrder()` (P4-T5, PD-6) it
13
+ * is up to three dispatches over the permuted rows -- TIER 2 one workgroup per row over [0, hiEnd), TIER 1 32 lanes
14
+ * per row over [hiEnd, midEnd), TIER 0 grid-stride over [midEnd, n) -- each compiled only when its range is
15
+ * non-empty. The row and arc counts come from the core's binding sizes exactly as segmentedReduce derives them.
15
16
  */
16
17
  import { type CoreBinding } from "../memory/residency.js";
17
18
  import { type Binding } from "../types/memory.js";
19
+ import { type DegreeTiers } from "./core-shape.js";
18
20
  import { type ReduceScope } from "./reduce.js";
19
- import { type DegreeTiers } from "./segmented-reduce.js";
20
21
  /** The group-1 bindings of one pull: the pre-scaled input, the output, the personalization (null binds xNorm as the dummy) and the PrPartial block whose header carries danglingMass. */
21
22
  export interface SpmvResources {
22
23
  readonly xNorm: Binding;
@@ -30,7 +31,7 @@ export interface SpmvCoefficients {
30
31
  readonly beta: number;
31
32
  readonly uniformP: number;
32
33
  }
33
- /** Options of prepareSpmvPull: the two variant flags, the weights binding and the tiers (must be null at P7). */
34
+ /** Options of prepareSpmvPull: the two variant flags, the weights binding and the in-degree tiers (null: one grid-stride dispatch). */
34
35
  export interface SpmvPullOptions {
35
36
  readonly personalization: boolean;
36
37
  readonly dangling: boolean;
@@ -38,18 +39,21 @@ export interface SpmvPullOptions {
38
39
  readonly weights?: Binding | null | undefined;
39
40
  readonly tiers: DegreeTiers | null;
40
41
  }
41
- /** A prepared pull: records ONE grid-stride dispatch over the rows of a reverse core into a pass. */
42
+ /** A prepared pull: records one grid-stride dispatch (no tiers) or up to three tier dispatches over the rows of a reverse core into a pass. */
42
43
  export interface SpmvPullPlanner {
43
- /** Records the dispatch over rows [0, n) of `rev` writing rankOut[v] (f32) per row; nothing for n = 0. */
44
+ /** Records the dispatches over rows [0, n) of `rev` writing rankOut[v] (f32) per row; nothing for n = 0. */
44
45
  record(pass: GPUComputePassEncoder, rev: CoreBinding, resources: SpmvResources, coefficients: SpmvCoefficients): void;
45
- /** Dispatches the last record() issued (1, or 0 for n = 0). */
46
+ /** Dispatches the last record() issued (0 for n = 0; 1 without tiers; 1 to 3 with them). */
46
47
  readonly lastDispatches: number;
47
48
  }
48
49
  /**
49
- * Prepares the thread-per-row pull pipeline for a reverse core's weights pattern and the two variant flags.
50
+ * Prepares the pull pipelines for a reverse core's weights pattern and the two variant flags: TIER 0 always
51
+ * (USE_PERM = tiers !== null); TIER 1 iff a row of in-degree 32..1023 exists (segmentOffsets[2] >
52
+ * segmentOffsets[1]); TIER 2 iff a row of in-degree >= 1024 exists (segmentOffsets[1] > 0). The mid tier folds 32
53
+ * lanes per row, so a device whose workgroup size is below 32 is E_UNSUPPORTED { feature: "spmvPull.tiers" }.
50
54
  * @param scope - the reduce scope (pipelines, params writer)
51
- * @param rev - the reverse core whose weights pattern selects HAS_WEIGHTS (USE_PERM is false: no tiers at P7)
52
- * @param options - personalization, dangling, weights, tiers (must be null)
55
+ * @param rev - the reverse core whose weights pattern selects HAS_WEIGHTS
56
+ * @param options - personalization, dangling, weights, tiers (null: the single grid-stride dispatch)
53
57
  * @returns the planner
54
58
  */
55
59
  export declare function prepareSpmvPull(scope: ReduceScope, rev: CoreBinding, options: SpmvPullOptions): Promise<SpmvPullPlanner>;
@@ -1 +1 @@
1
- {"version":3,"file":"spmv.d.ts","sourceRoot":"","sources":["../../../src/primitives/spmv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,yLAAyL;AACzL,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,OAAO,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC9B;AAED,gFAAgF;AAChF,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B;AAED,iHAAiH;AACjH,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,iHAAiH;IACjH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CACtC;AAED,qGAAqG;AACrG,MAAM,WAAW,eAAe;IAC5B,0GAA0G;IAC1G,MAAM,CAAC,IAAI,EAAE,qBAAqB,EAAE,GAAG,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACtH,+DAA+D;IAC/D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACnC;AAyED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACjC,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,eAAe,GACzB,OAAO,CAAC,eAAe,CAAC,CAc1B"}
1
+ {"version":3,"file":"spmv.d.ts","sourceRoot":"","sources":["../../../src/primitives/spmv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAiC,KAAK,WAAW,EAA8B,MAAM,iBAAiB,CAAC;AAC9G,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,yLAAyL;AACzL,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,OAAO,GAAG,IAAI,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC9B;AAED,gFAAgF;AAChF,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B;AAED,uIAAuI;AACvI,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,iHAAiH;IACjH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CACtC;AAED,+IAA+I;AAC/I,MAAM,WAAW,eAAe;IAC5B,4GAA4G;IAC5G,MAAM,CACF,IAAI,EAAE,qBAAqB,EAC3B,GAAG,EAAE,WAAW,EAChB,SAAS,EAAE,aAAa,EACxB,YAAY,EAAE,gBAAgB,GAC/B,IAAI,CAAC;IACR,4FAA4F;IAC5F,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACnC;AA0GD;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACjC,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,eAAe,GACzB,OAAO,CAAC,eAAe,CAAC,CAiC1B"}