@graphty/webgpu-graph-algorithms 0.6.3 → 0.6.4

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 (167) hide show
  1. package/README.md +62 -32
  2. package/dist/browser.js +1 -1
  3. package/dist/chunks/{context-BXqgCifx.js → context-Dvq-Cc6v.js} +71 -25
  4. package/dist/chunks/context-Dvq-Cc6v.js.map +1 -0
  5. package/dist/node.js +1 -1
  6. package/dist/src/accelerator.d.ts +8 -6
  7. package/dist/src/accelerator.d.ts.map +1 -1
  8. package/dist/src/accelerator.js +57 -6
  9. package/dist/src/accelerator.js.map +1 -1
  10. package/dist/src/algorithms/bellman-ford.d.ts +60 -0
  11. package/dist/src/algorithms/bellman-ford.d.ts.map +1 -0
  12. package/dist/src/algorithms/bellman-ford.js +301 -0
  13. package/dist/src/algorithms/bellman-ford.js.map +1 -0
  14. package/dist/src/algorithms/bfs.d.ts +67 -0
  15. package/dist/src/algorithms/bfs.d.ts.map +1 -0
  16. package/dist/src/algorithms/bfs.js +534 -0
  17. package/dist/src/algorithms/bfs.js.map +1 -0
  18. package/dist/src/algorithms/closeness.d.ts +53 -0
  19. package/dist/src/algorithms/closeness.d.ts.map +1 -0
  20. package/dist/src/algorithms/closeness.js +323 -0
  21. package/dist/src/algorithms/closeness.js.map +1 -0
  22. package/dist/src/algorithms/scope.d.ts +5 -3
  23. package/dist/src/algorithms/scope.d.ts.map +1 -1
  24. package/dist/src/algorithms/scope.js +3 -0
  25. package/dist/src/algorithms/scope.js.map +1 -1
  26. package/dist/src/algorithms/sssp.d.ts +71 -0
  27. package/dist/src/algorithms/sssp.d.ts.map +1 -0
  28. package/dist/src/algorithms/sssp.js +585 -0
  29. package/dist/src/algorithms/sssp.js.map +1 -0
  30. package/dist/src/constants.d.ts +12 -0
  31. package/dist/src/constants.d.ts.map +1 -1
  32. package/dist/src/constants.js +12 -0
  33. package/dist/src/constants.js.map +1 -1
  34. package/dist/src/index.d.ts +8 -2
  35. package/dist/src/index.d.ts.map +1 -1
  36. package/dist/src/index.js +7 -1
  37. package/dist/src/index.js.map +1 -1
  38. package/dist/src/kernel/prelude.d.ts +4 -4
  39. package/dist/src/kernel/prelude.d.ts.map +1 -1
  40. package/dist/src/kernel/prelude.js +39 -5
  41. package/dist/src/kernel/prelude.js.map +1 -1
  42. package/dist/src/kernel/uniform-ring.d.ts +8 -0
  43. package/dist/src/kernel/uniform-ring.d.ts.map +1 -1
  44. package/dist/src/kernel/uniform-ring.js +13 -0
  45. package/dist/src/kernel/uniform-ring.js.map +1 -1
  46. package/dist/src/kernels.d.ts +44 -4
  47. package/dist/src/kernels.d.ts.map +1 -1
  48. package/dist/src/kernels.js +371 -3
  49. package/dist/src/kernels.js.map +1 -1
  50. package/dist/src/primitives/advance.d.ts +62 -0
  51. package/dist/src/primitives/advance.d.ts.map +1 -0
  52. package/dist/src/primitives/advance.js +95 -0
  53. package/dist/src/primitives/advance.js.map +1 -0
  54. package/dist/src/primitives/compact.d.ts +89 -0
  55. package/dist/src/primitives/compact.d.ts.map +1 -0
  56. package/dist/src/primitives/compact.js +233 -0
  57. package/dist/src/primitives/compact.js.map +1 -0
  58. package/dist/src/primitives/core-shape.d.ts +22 -1
  59. package/dist/src/primitives/core-shape.d.ts.map +1 -1
  60. package/dist/src/primitives/core-shape.js +33 -3
  61. package/dist/src/primitives/core-shape.js.map +1 -1
  62. package/dist/src/primitives/frontier.d.ts +156 -0
  63. package/dist/src/primitives/frontier.d.ts.map +1 -0
  64. package/dist/src/primitives/frontier.js +259 -0
  65. package/dist/src/primitives/frontier.js.map +1 -0
  66. package/dist/src/types/accelerator.d.ts +16 -7
  67. package/dist/src/types/accelerator.d.ts.map +1 -1
  68. package/dist/src/types/traversal.d.ts +53 -0
  69. package/dist/src/types/traversal.d.ts.map +1 -0
  70. package/dist/src/types/traversal.js +10 -0
  71. package/dist/src/types/traversal.js.map +1 -0
  72. package/dist/src/wgsl/advance-expand.wgsl.d.ts +19 -0
  73. package/dist/src/wgsl/advance-expand.wgsl.d.ts.map +1 -0
  74. package/dist/src/wgsl/advance-expand.wgsl.js +69 -0
  75. package/dist/src/wgsl/advance-expand.wgsl.js.map +1 -0
  76. package/dist/src/wgsl/bf-relax.wgsl.d.ts +22 -0
  77. package/dist/src/wgsl/bf-relax.wgsl.d.ts.map +1 -0
  78. package/dist/src/wgsl/bf-relax.wgsl.js +58 -0
  79. package/dist/src/wgsl/bf-relax.wgsl.js.map +1 -0
  80. package/dist/src/wgsl/bfs-bitset-build.wgsl.d.ts +15 -0
  81. package/dist/src/wgsl/bfs-bitset-build.wgsl.d.ts.map +1 -0
  82. package/dist/src/wgsl/bfs-bitset-build.wgsl.js +24 -0
  83. package/dist/src/wgsl/bfs-bitset-build.wgsl.js.map +1 -0
  84. package/dist/src/wgsl/bfs-bottom-up.wgsl.d.ts +20 -0
  85. package/dist/src/wgsl/bfs-bottom-up.wgsl.d.ts.map +1 -0
  86. package/dist/src/wgsl/bfs-bottom-up.wgsl.js +67 -0
  87. package/dist/src/wgsl/bfs-bottom-up.wgsl.js.map +1 -0
  88. package/dist/src/wgsl/bfs-contract.wgsl.d.ts +20 -0
  89. package/dist/src/wgsl/bfs-contract.wgsl.d.ts.map +1 -0
  90. package/dist/src/wgsl/bfs-contract.wgsl.js +55 -0
  91. package/dist/src/wgsl/bfs-contract.wgsl.js.map +1 -0
  92. package/dist/src/wgsl/bfs-fused.wgsl.d.ts +25 -0
  93. package/dist/src/wgsl/bfs-fused.wgsl.d.ts.map +1 -0
  94. package/dist/src/wgsl/bfs-fused.wgsl.js +78 -0
  95. package/dist/src/wgsl/bfs-fused.wgsl.js.map +1 -0
  96. package/dist/src/wgsl/bfs-unvisited-flags.wgsl.d.ts +18 -0
  97. package/dist/src/wgsl/bfs-unvisited-flags.wgsl.d.ts.map +1 -0
  98. package/dist/src/wgsl/bfs-unvisited-flags.wgsl.js +42 -0
  99. package/dist/src/wgsl/bfs-unvisited-flags.wgsl.js.map +1 -0
  100. package/dist/src/wgsl/closeness-reduce.wgsl.d.ts +17 -0
  101. package/dist/src/wgsl/closeness-reduce.wgsl.d.ts.map +1 -0
  102. package/dist/src/wgsl/closeness-reduce.wgsl.js +65 -0
  103. package/dist/src/wgsl/closeness-reduce.wgsl.js.map +1 -0
  104. package/dist/src/wgsl/closeness-sweep.wgsl.d.ts +20 -0
  105. package/dist/src/wgsl/closeness-sweep.wgsl.d.ts.map +1 -0
  106. package/dist/src/wgsl/closeness-sweep.wgsl.js +96 -0
  107. package/dist/src/wgsl/closeness-sweep.wgsl.js.map +1 -0
  108. package/dist/src/wgsl/compact-scatter.wgsl.d.ts +9 -0
  109. package/dist/src/wgsl/compact-scatter.wgsl.d.ts.map +1 -0
  110. package/dist/src/wgsl/compact-scatter.wgsl.js +17 -0
  111. package/dist/src/wgsl/compact-scatter.wgsl.js.map +1 -0
  112. package/dist/src/wgsl/dedupe-claim.wgsl.d.ts +10 -0
  113. package/dist/src/wgsl/dedupe-claim.wgsl.d.ts.map +1 -0
  114. package/dist/src/wgsl/dedupe-claim.wgsl.js +19 -0
  115. package/dist/src/wgsl/dedupe-claim.wgsl.js.map +1 -0
  116. package/dist/src/wgsl/dedupe-filter.wgsl.d.ts +12 -0
  117. package/dist/src/wgsl/dedupe-filter.wgsl.d.ts.map +1 -0
  118. package/dist/src/wgsl/dedupe-filter.wgsl.js +46 -0
  119. package/dist/src/wgsl/dedupe-filter.wgsl.js.map +1 -0
  120. package/dist/src/wgsl/frontier-finalize.wgsl.d.ts +59 -0
  121. package/dist/src/wgsl/frontier-finalize.wgsl.d.ts.map +1 -0
  122. package/dist/src/wgsl/frontier-finalize.wgsl.js +210 -0
  123. package/dist/src/wgsl/frontier-finalize.wgsl.js.map +1 -0
  124. package/dist/src/wgsl/sssp-pred.wgsl.d.ts +28 -0
  125. package/dist/src/wgsl/sssp-pred.wgsl.d.ts.map +1 -0
  126. package/dist/src/wgsl/sssp-pred.wgsl.js +80 -0
  127. package/dist/src/wgsl/sssp-pred.wgsl.js.map +1 -0
  128. package/dist/src/wgsl/sssp-relax.wgsl.d.ts +30 -0
  129. package/dist/src/wgsl/sssp-relax.wgsl.d.ts.map +1 -0
  130. package/dist/src/wgsl/sssp-relax.wgsl.js +72 -0
  131. package/dist/src/wgsl/sssp-relax.wgsl.js.map +1 -0
  132. package/dist/webgpu-graph-algorithms.js +3207 -377
  133. package/dist/webgpu-graph-algorithms.js.map +1 -1
  134. package/package.json +5 -4
  135. package/src/accelerator.ts +65 -7
  136. package/src/algorithms/bellman-ford.ts +387 -0
  137. package/src/algorithms/bfs.ts +626 -0
  138. package/src/algorithms/closeness.ts +395 -0
  139. package/src/algorithms/scope.ts +13 -3
  140. package/src/algorithms/sssp.ts +767 -0
  141. package/src/constants.ts +12 -0
  142. package/src/index.ts +14 -1
  143. package/src/kernel/prelude.ts +39 -4
  144. package/src/kernel/uniform-ring.ts +14 -0
  145. package/src/kernels.ts +450 -6
  146. package/src/primitives/advance.ts +130 -0
  147. package/src/primitives/compact.ts +323 -0
  148. package/src/primitives/core-shape.ts +41 -3
  149. package/src/primitives/frontier.ts +388 -0
  150. package/src/types/accelerator.ts +18 -5
  151. package/src/types/traversal.ts +56 -0
  152. package/src/wgsl/advance-expand.wgsl.ts +68 -0
  153. package/src/wgsl/bf-relax.wgsl.ts +57 -0
  154. package/src/wgsl/bfs-bitset-build.wgsl.ts +23 -0
  155. package/src/wgsl/bfs-bottom-up.wgsl.ts +66 -0
  156. package/src/wgsl/bfs-contract.wgsl.ts +54 -0
  157. package/src/wgsl/bfs-fused.wgsl.ts +77 -0
  158. package/src/wgsl/bfs-unvisited-flags.wgsl.ts +41 -0
  159. package/src/wgsl/closeness-reduce.wgsl.ts +64 -0
  160. package/src/wgsl/closeness-sweep.wgsl.ts +95 -0
  161. package/src/wgsl/compact-scatter.wgsl.ts +16 -0
  162. package/src/wgsl/dedupe-claim.wgsl.ts +18 -0
  163. package/src/wgsl/dedupe-filter.wgsl.ts +45 -0
  164. package/src/wgsl/frontier-finalize.wgsl.ts +209 -0
  165. package/src/wgsl/sssp-pred.wgsl.ts +79 -0
  166. package/src/wgsl/sssp-relax.wgsl.ts +71 -0
  167. package/dist/chunks/context-BXqgCifx.js.map +0 -1
@@ -0,0 +1,323 @@
1
+ /**
2
+ * Closeness centrality on the device (design 8.4, 3.3 line 810, 9.7; P8-T11, the P8 plan's PD-13 / PD-19 / PD-25 /
3
+ * DEP-P8-E / DEP-P8-F): `score[s] = 1 / sumDist_s`, with `sumDist_s` the exact sum of the finite distances from `s`
4
+ * to every OTHER node -- an unreached node adds nothing -- and `0` when nothing is reached. No reached factor and no
5
+ * Wasserman-Faust scaling: this is EXACTLY the legacy default (`normalized: false`) of `closenessCentrality` in
6
+ * `@graphty/algorithms`, the number graphty-element's closeness panel shows today, so a future `indexed` port has one
7
+ * number to match (the NetworkX form is 33x it on karate and could never have been substituted silently).
8
+ *
9
+ * The unweighted route is ONE bit-parallel multi-source search per batch of 32 sources (`ceil(n / 32)` batches):
10
+ * the batch's state is one `bits` buffer of four regions of `bitsBase = roundUp(n, 64)` words (`visited`, two
11
+ * frontier regions that swap by the level's parity, `flags`), bit `s` of word `v` meaning "source `s` has reached /
12
+ * is at / is next at `v`"; a level is, all host-recorded, `closeness-reduce` role 0 (the boundary: `done` from the
13
+ * previous level's compacted count, the level's claims folded into the exact 64-bit per-source sums at `level + 1`),
14
+ * `compact` of the flags into the frontier list, two `fill`s zeroing the level's next region and the flags (AFTER
15
+ * the compaction that consumed them), and `closeness-sweep` (the block-mapped expansion with the claim inline, a
16
+ * direct grid-stride dispatch looping to the list's count). `MAX_LEVELS_PER_SUBMIT` levels per submit and
17
+ * one readback per submit (the `done` word and the 512-byte `perSource` block together, so the finished batch needs
18
+ * no extra map); the host folds `sumHi x 2^32 + sumLo` into `1 / sum` in f64 and stores f32. The weighted route
19
+ * (`weighted` true on a snapshot whose column is not all ones) is one `sssp` per source with the sums reduced on the
20
+ * host between calls: design 8.4's own answer, slow and correct. `weighted` defaults to the snapshot's `flags.weighted`;
21
+ * `weighted: false` on a weighted snapshot ignores the column by request and sweeps; `weighted: true` over unit
22
+ * weights or no column sweeps too (every `sssp` would route to a BFS anyway). `maxIterations` and `tolerance` are the
23
+ * seam's placeholder keys and an exact traversal has neither, so a defined value is REFUSED before any device work
24
+ * (`E_UNSUPPORTED { option }`, the package's rule for an option it does not implement, PD-25); `undefined` is legal.
25
+ * `iterations` reports the source batches run (the sources, on the weighted route), `converged` is always true.
26
+ *
27
+ * Cost, stated so nobody is surprised: closeness is O(n x m) on any device -- at 1M nodes it is 31,250 batches of a
28
+ * full multi-source traversal, minutes on the card, and no target in design 10.4 asks for less. `compact.record`
29
+ * leases its offsets and the scan's block sums afresh on every call, once per LEVEL here, so the planner is given a
30
+ * scope whose `scratch` hands the same buffer back for the same label and size: the dispatches of one pass run in
31
+ * order, a level's scan overwrites the previous level's, and the run holds one set instead of `levels x batches`.
32
+ * The sweep keeps DEP-P8-E's refusal of a windowed core (`assertWholeCore`): the bit-parallel claim needs the whole
33
+ * arc array bound. The tuning entry `closenessWithTuning` (PD-26's shape) is what the tests drive; nothing public
34
+ * exposes it.
35
+ */
36
+ import { MAX_LEVELS_PER_SUBMIT } from "../constants.js";
37
+ import { WebGpuGraphError } from "../errors.js";
38
+ import { CommandBatch } from "../kernel/batch.js";
39
+ import { plan1d, planGridStride } from "../kernel/dispatch.js";
40
+ import { FILL_PARAMS, FRONTIER_COUNTERS, FRONTIER_PARAMS, graphBindings, graphOverrides, kernelSpec, } from "../kernels.js";
41
+ import { prepareCompact } from "../primitives/compact.js";
42
+ import { assertWholeCore } from "../primitives/core-shape.js";
43
+ import { W } from "../primitives/frontier.js";
44
+ import { assertDeviceComputes } from "../primitives/verify.js";
45
+ import { algorithmScope } from "./scope.js";
46
+ import { aborted, bindingOf, checkDest, sssp } from "./sssp.js";
47
+ const ALGORITHM = "closenessCentrality";
48
+ /**
49
+ * Design 8.4: 32 sources per `u32` word, one batch per word.
50
+ * @internal
51
+ */
52
+ export const SOURCES_PER_BATCH = 32;
53
+ /**
54
+ * The `perSource` block of a batch: `newCount[32]` @0, `reached[32]` @32, `sumLo[32]` @64, `sumHi[32]` @96.
55
+ * @internal
56
+ */
57
+ export const PER_SOURCE_WORDS = 4 * SOURCES_PER_BATCH;
58
+ /**
59
+ * Params slots of the ring, COUNTED (`UniformRing.reserve` wraps silently): per level `compact`'s records (its scan
60
+ * is at most four levels for any n below 2^32, so at most 8 records) while the boundary, the finalize, the fill and
61
+ * the two sweep records (one per parity) are written once per submit, plus the seed's two records on a batch's first
62
+ * submit (the iota fill flushes in its own submit).
63
+ */
64
+ const RING_SLOTS = 8 * MAX_LEVELS_PER_SUBMIT + 16;
65
+ /**
66
+ * A scope whose `scratch` hands the SAME buffer back for the same label and size (see the file comment).
67
+ * @param scope - the algorithm's scope
68
+ * @returns the reusing scope
69
+ */
70
+ function reusingScratch(scope) {
71
+ const held = new Map();
72
+ return {
73
+ ...scope,
74
+ scratch: (byteLength, label) => {
75
+ const key = `${label}/${byteLength}`;
76
+ let buffer = held.get(key);
77
+ if (buffer === undefined) {
78
+ buffer = scope.scratch(byteLength, label);
79
+ held.set(key, buffer);
80
+ }
81
+ return buffer;
82
+ },
83
+ };
84
+ }
85
+ /**
86
+ * The weighted route: one `sssp` per source, the sums reduced on the host.
87
+ * @param ctx - the context
88
+ * @param s - the snapshot
89
+ * @param scores - the destination
90
+ * @param options - the run options
91
+ * @returns the result
92
+ */
93
+ async function weightedRoute(ctx, s, scores, options) {
94
+ const n = s.nodeCount;
95
+ for (let source = 0; source < n; source++) {
96
+ if (options?.signal?.aborted) {
97
+ throw aborted(ALGORITHM);
98
+ }
99
+ const { dist } = await sssp(ctx, s, source, { signal: options?.signal });
100
+ let sum = 0;
101
+ for (let v = 0; v < n; v++) {
102
+ const d = dist[v];
103
+ if (v !== source && d !== Infinity) {
104
+ sum += d;
105
+ }
106
+ }
107
+ scores[source] = sum === 0 ? 0 : 1 / sum;
108
+ options?.onProgress?.(source + 1, n);
109
+ }
110
+ return { scores, iterations: n, converged: true, precision: "f32" };
111
+ }
112
+ /**
113
+ * The bit-parallel route (see the file comment).
114
+ * @param ctx - the context
115
+ * @param s - the snapshot
116
+ * @param scores - the destination
117
+ * @param levelsPerSubmit - the submit cadence
118
+ * @param options - the run options
119
+ * @param tuning - the knobs
120
+ * @returns the result
121
+ */
122
+ async function sweepRoute(ctx, s, scores, levelsPerSubmit, options, tuning) {
123
+ const n = s.nodeCount;
124
+ if (n === 0) {
125
+ return { scores, iterations: 0, converged: true, precision: "f32" };
126
+ }
127
+ const core = ctx.residency.core(s);
128
+ assertWholeCore(core, s.arcCount, ctx.caps.limits.maxStorageBufferBindingSize, ALGORITHM);
129
+ const scope = algorithmScope(ctx, ALGORITHM, RING_SLOTS);
130
+ try {
131
+ const wg = ctx.workgroupSize;
132
+ const bytes = 4 * n;
133
+ // the four regions of the bits buffer, each bitsBase words so its byte offset is 256-aligned and fill and
134
+ // compact can bind one alone: visited 0, the frontier pair 1 and 2, flags 3
135
+ const bitsBase = Math.ceil(n / 64) * 64;
136
+ const regionBytes = 4 * bitsBase;
137
+ const bits = bindingOf(scope.scratch(4 * regionBytes, "bits"), 4 * regionBytes);
138
+ const region = (index) => ({
139
+ buffer: bits.buffer,
140
+ offset: index * regionBytes,
141
+ size: regionBytes,
142
+ window: null,
143
+ });
144
+ const flags = region(3);
145
+ const frontierList = bindingOf(scope.scratch(bytes, "frontier-list"), bytes);
146
+ const iota = bindingOf(scope.scratch(bytes, "iota"), bytes);
147
+ const counters = bindingOf(scope.scratch(FRONTIER_COUNTERS.byteLength, "counters"), FRONTIER_COUNTERS.byteLength);
148
+ const perSourceBytes = 4 * PER_SOURCE_WORDS;
149
+ const perSource = bindingOf(scope.scratch(perSourceBytes, "per-source"), perSourceBytes);
150
+ await ctx.allocator.check();
151
+ const compact = await prepareCompact(reusingScratch(scope));
152
+ const sweep = await ctx.pipelines.kernel(kernelSpec("closeness-sweep", graphOverrides(core, null)));
153
+ const reduce = await ctx.pipelines.kernel(kernelSpec("closeness-reduce"));
154
+ const fill = await ctx.pipelines.kernel(kernelSpec("fill"));
155
+ const graph = graphBindings(core, null);
156
+ const onePlan = plan1d(1, wg, ctx.caps);
157
+ const regionPlan = plan1d(bitsBase, wg, ctx.caps);
158
+ const sweepPlan = planGridStride(n, wg, ctx.caps); // the list holds at most n entries; the sweep loops to the count word
159
+ const recordFill = (pass, dst, count, mode) => {
160
+ const params = scope.params(FILL_PARAMS, { count, value: 0, mode, pad0: 0 });
161
+ fill.dispatch(pass, fill.bind({ dst, P: params.binding }), plan1d(count, wg, ctx.caps), [params.offset]);
162
+ };
163
+ const submit = (batch) => {
164
+ scope.flush();
165
+ return batch.submit();
166
+ };
167
+ // setup: the iota queue compact reads, once per run
168
+ const setup = new CommandBatch(ctx, `${ALGORITHM}/setup`);
169
+ recordFill(setup.pass("fill"), iota, n, 1);
170
+ setup.endPass();
171
+ await submit(setup).readback;
172
+ ctx.assertReady();
173
+ let batches = 0;
174
+ for (let batchStart = 0; batchStart < n; batchStart += SOURCES_PER_BATCH) {
175
+ let level = 0;
176
+ for (let first = true;; first = false) {
177
+ const batch = new CommandBatch(ctx, `${ALGORITHM}/levels`);
178
+ const pass = batch.pass("closeness");
179
+ if (first) {
180
+ // the batch's seed: the four regions and the block zeroed, then role 1 (the sources' bits, their
181
+ // flags, counters[0] = k, level = U32_MAX)
182
+ recordFill(pass, bits, 4 * bitsBase, 0);
183
+ recordFill(pass, perSource, PER_SOURCE_WORDS, 0);
184
+ const seed = scope.params(FRONTIER_PARAMS, { role: 1, n, bitsBase, source: batchStart });
185
+ reduce.dispatch(pass, reduce.bind({ counters, perSource, bits, P: seed.binding }), onePlan, [
186
+ seed.offset,
187
+ ]);
188
+ }
189
+ // the records every level of the submit shares (the ring wraps, so they are written per submit)
190
+ const boundary = scope.params(FRONTIER_PARAMS, { role: 0, n, bitsBase });
191
+ const boundBoundary = reduce.bind({ counters, perSource, bits, P: boundary.binding });
192
+ const clear = scope.params(FILL_PARAMS, { count: bitsBase, value: 0, mode: 0, pad0: 0 });
193
+ // parity 0 sweeps region 1 into region 2, parity 1 region 2 into region 1: the next region is cleared
194
+ const boundClearNext = [region(2), region(1)].map((dst) => fill.bind({ dst, P: clear.binding }));
195
+ const boundClearFlags = fill.bind({ dst: flags, P: clear.binding });
196
+ const boundSweep = [0, 1].map((mode) => {
197
+ const params = scope.params(FRONTIER_PARAMS, {
198
+ wg,
199
+ n,
200
+ bitsBase,
201
+ arcBase: 0,
202
+ arcEnd: s.arcCount,
203
+ mode,
204
+ stride: sweepPlan.stride ?? wg,
205
+ });
206
+ return {
207
+ bound: sweep.bind({ ...graph, frontierList, counters, bits, perSource, P: params.binding }),
208
+ offset: params.offset,
209
+ };
210
+ });
211
+ for (let k = 0; k < levelsPerSubmit; k++, level++) {
212
+ const parity = level % 2;
213
+ reduce.dispatch(pass, boundBoundary, onePlan, [boundary.offset]);
214
+ compact.record(pass, {
215
+ queue: iota,
216
+ flags,
217
+ count: n,
218
+ out: frontierList,
219
+ outCount: counters,
220
+ outIndex: W.frontierCount,
221
+ });
222
+ fill.dispatch(pass, boundClearNext[parity], regionPlan, [clear.offset]);
223
+ fill.dispatch(pass, boundClearFlags, regionPlan, [clear.offset]);
224
+ sweep.dispatch(pass, boundSweep[parity].bound, sweepPlan, [boundSweep[parity].offset]);
225
+ }
226
+ batch.endPass();
227
+ const doneRequest = batch.readback(counters.buffer, counters.offset + 4 * W.done, 4);
228
+ const blockRequest = batch.readback(perSource.buffer, perSource.offset, perSourceBytes);
229
+ const submitted = submit(batch);
230
+ const back = await submitted.readback;
231
+ ctx.assertReady();
232
+ if (options?.signal?.aborted) {
233
+ throw aborted(ALGORITHM, submitted.id);
234
+ }
235
+ if (new Uint32Array(back, doneRequest.offset, 1)[0] !== 0) {
236
+ const block = new Uint32Array(back, blockRequest.offset, PER_SOURCE_WORDS);
237
+ const count = Math.min(SOURCES_PER_BATCH, n - batchStart);
238
+ for (let i = 0; i < count; i++) {
239
+ const sum = block[3 * SOURCES_PER_BATCH + i] * 2 ** 32 + block[2 * SOURCES_PER_BATCH + i];
240
+ scores[batchStart + i] = sum === 0 ? 0 : 1 / sum;
241
+ }
242
+ tuning.onBatch?.(batchStart, block.slice());
243
+ break;
244
+ }
245
+ if (level > n + 3) {
246
+ // a batch claims at most n - 1 levels deep, then one level claims nothing and one is empty
247
+ throw new WebGpuGraphError("E_VALIDATION", `${ALGORITHM}: the done flag never rose in ${level} levels of the batch at ${batchStart}`, { label: ALGORITHM, message: `the done flag never rose in ${level} levels` });
248
+ }
249
+ }
250
+ batches += 1;
251
+ options?.onProgress?.(Math.min(batchStart + SOURCES_PER_BATCH, n), n);
252
+ }
253
+ return { scores, iterations: batches, converged: true, precision: "f32" };
254
+ }
255
+ finally {
256
+ scope.dispose();
257
+ }
258
+ }
259
+ /**
260
+ * Closeness with the test knobs of PD-26's shape; `closenessCentrality` is this with an empty tuning.
261
+ * @internal
262
+ * @param ctx - the context whose device runs the kernels
263
+ * @param s - the snapshot (uploaded through ctx.residency, or found there)
264
+ * @param options - the seam's `HitsOptionsLike` (`weighted` honoured, the other two refused when defined), plus dest / signal / onProgress
265
+ * @param tuning - the knobs
266
+ * @returns the scores, the batches run, `converged: true` and `precision: "f32"`
267
+ */
268
+ export async function closenessWithTuning(ctx, s, options, tuning) {
269
+ ctx.assertReady();
270
+ await assertDeviceComputes(ctx);
271
+ for (const key of ["maxIterations", "tolerance"]) {
272
+ if (options?.[key] !== undefined) {
273
+ throw new WebGpuGraphError("E_UNSUPPORTED", `${ALGORITHM}: ${key} has no meaning for an exact traversal`, {
274
+ option: key,
275
+ hint: "closeness is an exact traversal; the option has no meaning here",
276
+ });
277
+ }
278
+ }
279
+ const n = s.nodeCount;
280
+ const levelsPerSubmit = tuning.levelsPerSubmit ?? MAX_LEVELS_PER_SUBMIT;
281
+ if (!Number.isInteger(levelsPerSubmit) || levelsPerSubmit < 1 || levelsPerSubmit > MAX_LEVELS_PER_SUBMIT) {
282
+ throw new WebGpuGraphError("E_INVALID_ARGUMENT", `${ALGORITHM}: levelsPerSubmit must be an integer in [1, ${MAX_LEVELS_PER_SUBMIT}]`, {
283
+ argument: "levelsPerSubmit",
284
+ value: levelsPerSubmit,
285
+ expected: `an integer in [1, ${MAX_LEVELS_PER_SUBMIT}]`,
286
+ });
287
+ }
288
+ const scores = checkDest(ALGORITHM, options?.dest, n) ?? new Float32Array(n);
289
+ const weighted = options?.weighted ?? s.flags.weighted;
290
+ if (options?.signal?.aborted) {
291
+ throw aborted(ALGORITHM);
292
+ }
293
+ if (weighted && s.weights !== null && !s.flags.allWeightsOne) {
294
+ if (!s.flags.nonNegativeWeights) {
295
+ throw new WebGpuGraphError("E_UNSUPPORTED", `${ALGORITHM}: a negative weight has no shortest-path distance to sum`, {
296
+ feature: "closenessCentrality.negativeWeights",
297
+ hint: "pass weighted: false to ignore the column",
298
+ });
299
+ }
300
+ if (!s.flags.finiteWeights) {
301
+ throw new WebGpuGraphError("E_UNSUPPORTED", `${ALGORITHM}: a NaN or infinite weight has no shortest path`, {
302
+ feature: "closenessCentrality.nonFiniteWeights",
303
+ });
304
+ }
305
+ return weightedRoute(ctx, s, scores, options);
306
+ }
307
+ return sweepRoute(ctx, s, scores, levelsPerSubmit, options, tuning);
308
+ }
309
+ /**
310
+ * Closeness centrality on the device (spec 3.3 line 810, design 8.4, 9.7): `scores[s] = 1 / sumDist_s` over the finite
311
+ * distances from `s` to every other node, `0` when nothing is reached -- the legacy default of `@graphty/algorithms`'
312
+ * `closenessCentrality`, unweighted by one bit-parallel multi-source search per 32 sources, weighted by one `sssp`
313
+ * per source; `weighted` defaults to the snapshot's flag, `maxIterations` / `tolerance` are refused when defined
314
+ * (PD-25). `iterations` is the source batches run and `converged` is always true.
315
+ * @param ctx - the context whose device runs the kernels
316
+ * @param s - the snapshot (uploaded through ctx.residency, or found there)
317
+ * @param options - the seam's `HitsOptionsLike`, plus dest (a Float32Array of length n for `scores`) / signal / onProgress
318
+ * @returns the scores, the batches run, `converged: true` and `precision: "f32"`
319
+ */
320
+ export function closenessCentrality(ctx, s, options) {
321
+ return closenessWithTuning(ctx, s, options, {});
322
+ }
323
+ //# sourceMappingURL=closeness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"closeness.js","sourceRoot":"","sources":["../../../src/algorithms/closeness.ts"],"names":[],"mappings":"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"}
@@ -7,13 +7,15 @@
7
7
  * wraps, so a ring too small silently reuses a slot another dispatch of the same batch still reads.
8
8
  */
9
9
  import { type GpuContext } from "../context.js";
10
- import { type ReduceScope } from "../primitives/reduce.js";
11
- /** A ReduceScope over a context plus the two lifecycle calls an algorithm makes: flush() before submit, dispose() in its finally. */
12
- export interface AlgorithmScope extends ReduceScope {
10
+ import { type FrontierScope } from "../primitives/frontier.js";
11
+ /** A FrontierScope (a ReduceScope plus `indirect()`, P8-T4) over a context plus the two lifecycle calls an algorithm makes: flush() before submit, dispose() in its finally. */
12
+ export interface AlgorithmScope extends FrontierScope {
13
13
  /** queue.writeBuffer of the params slots written since the last flush (called before the batch is submitted). */
14
14
  flush(): void;
15
15
  /** Destroys the ring and releases every scratch buffer of the lease; idempotent. */
16
16
  dispose(): void;
17
+ /** The ring's `overruns` so far: reservations that wrapped over a record the batch being recorded still reads (0 on a correctly sized ring; P8-T12). */
18
+ ringOverruns(): number;
17
19
  }
18
20
  /**
19
21
  * The scope of one algorithm call.
@@ -1 +1 @@
1
- {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../src/algorithms/scope.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,qIAAqI;AACrI,MAAM,WAAW,cAAe,SAAQ,WAAW;IAC/C,iHAAiH;IACjH,KAAK,IAAI,IAAI,CAAC;IACd,oFAAoF;IACpF,OAAO,IAAI,IAAI,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CAuB5F"}
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../src/algorithms/scope.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,gLAAgL;AAChL,MAAM,WAAW,cAAe,SAAQ,aAAa;IACjD,iHAAiH;IACjH,KAAK,IAAI,IAAI,CAAC;IACd,oFAAoF;IACpF,OAAO,IAAI,IAAI,CAAC;IAChB,wJAAwJ;IACxJ,YAAY,IAAI,MAAM,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,CA8B5F"}
@@ -6,6 +6,7 @@
6
6
  * (test/helpers/segmented-reduce.ts). `slots` sizes the ring for the LARGEST batch the caller records: reserve()
7
7
  * wraps, so a ring too small silently reuses a slot another dispatch of the same batch still reads.
8
8
  */
9
+ import { BufferUsage } from "../device/webgpu-constants.js";
9
10
  import { UniformRing } from "../kernel/uniform-ring.js";
10
11
  /**
11
12
  * The scope of one algorithm call.
@@ -24,6 +25,7 @@ export function algorithmScope(ctx, label, slots) {
24
25
  pool: ctx.pool,
25
26
  workgroupSize: ctx.workgroupSize,
26
27
  scratch: (byteLength, scratchLabel) => lease.storage(byteLength, `${label}/${scratchLabel}`),
28
+ indirect: (byteLength, indirectLabel) => lease.acquire(byteLength, BufferUsage.STORAGE | BufferUsage.INDIRECT | BufferUsage.COPY_DST | BufferUsage.COPY_SRC, `${label}/${indirectLabel}`),
27
29
  params(block, values) {
28
30
  const slot = ring.reserve(1);
29
31
  ring.write(slot, block, values);
@@ -36,6 +38,7 @@ export function algorithmScope(ctx, label, slots) {
36
38
  ring.destroy();
37
39
  lease.release();
38
40
  },
41
+ ringOverruns: () => ring.overruns,
39
42
  };
40
43
  }
41
44
  //# sourceMappingURL=scope.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../../src/algorithms/scope.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAWxD;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,GAAe,EAAE,KAAa,EAAE,KAAa;IACxE,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC;IAChF,OAAO;QACH,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,OAAO,EAAE,CAAC,UAAU,EAAE,YAAY,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,KAAK,IAAI,YAAY,EAAE,CAAC;QAC5F,MAAM,CAAC,KAAK,EAAE,MAAM;YAChB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YAChC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACzE,CAAC;QACD,KAAK,EAAE,GAAG,EAAE;YACR,IAAI,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;QACD,OAAO;YACH,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,KAAK,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;KACJ,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"scope.js","sourceRoot":"","sources":["../../../src/algorithms/scope.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAaxD;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,GAAe,EAAE,KAAa,EAAE,KAAa;IACxE,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC;IAChF,OAAO;QACH,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,aAAa,EAAE,GAAG,CAAC,aAAa;QAChC,OAAO,EAAE,CAAC,UAAU,EAAE,YAAY,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,KAAK,IAAI,YAAY,EAAE,CAAC;QAC5F,QAAQ,EAAE,CAAC,UAAU,EAAE,aAAa,EAAE,EAAE,CACpC,KAAK,CAAC,OAAO,CACT,UAAU,EACV,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,QAAQ,GAAG,WAAW,CAAC,QAAQ,GAAG,WAAW,CAAC,QAAQ,EACxF,GAAG,KAAK,IAAI,aAAa,EAAE,CAC9B;QACL,MAAM,CAAC,KAAK,EAAE,MAAM;YAChB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YAChC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACzE,CAAC;QACD,KAAK,EAAE,GAAG,EAAE;YACR,IAAI,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;QACD,OAAO;YACH,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,KAAK,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;QACD,YAAY,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ;KACpC,CAAC;AACN,CAAC"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Weighted single-source shortest paths on the device (design 8.4, 3.3 line 808, 9.7; P8-T9, the P8 plan's PD-9 /
3
+ * PD-10 / PD-11 / PD-14 / PD-19 / PD-20 / PD-22 / PD-27 / DEP-P8-E): Davidson's near-far queue over the `Frontier`
4
+ * of P8-T4 with the `dedupe` of P8-T3, every per-round decision made ON THE DEVICE. `dist` is `array<atomic<u32>>`
5
+ * holding the f32 bit patterns of the distances (`F32_INF_BITS` = unreached), claimed by `atomicMin`, which is
6
+ * exact on non-negative floats (PD-9): the settled value is the minimum of a fixed set of f32 sums, so it is
7
+ * bitwise reproducible, bitwise identical across adapters, and bitwise equal to the f32 Dijkstra oracle.
8
+ *
9
+ * A round is eight recorded dispatches: `frontier-finalize` role 2 (the round boundary: a non-empty raw near half
10
+ * is deduped into `nearIn` for a near round; an empty one with a non-empty far half raises the threshold by the
11
+ * delta and dedupes the far half into `farIn` for a pass-through; both empty is `done`), `dedupe-claim` and
12
+ * `dedupe-filter` over each half (direct grid-stride dispatches; role 2 writes the chosen half's raw count into that
13
+ * dedupe's count word -- `edgeCount` for the near half, `edgeCountUnclamped` for the far one, two words SSSP borrows
14
+ * -- and 0 into the other's, so the half not chosen is a no-op), role 3 (restarts the raw half), and `sssp-relax`
15
+ * twice (role 0 over `nearIn`, role 1 over `farIn`; the block's `path` word, 5 a near round and 6 a far one, makes
16
+ * the other role's dispatch a no-op). The far pile is re-bucketed by the
17
+ * relax kernel's pass-through, not by `compact` (PD-20): a far entry whose settled distance fell below the previous
18
+ * threshold was relaxed in the near band already and is dropped, the rest go back to near or far against the raised
19
+ * threshold. The near pile is ONE pile (no sub-partitions). The host records `MAX_LEVELS_PER_SUBMIT` rounds per
20
+ * submit and reads four bytes, the `done` word: 1 finished, 2 a raw half above its capacity (E_TOO_LARGE
21
+ * `sssp.pile`: the far half accumulates one entry per improving relaxation beyond the threshold across a bucket's
22
+ * near rounds and is deduped only at the split, so the refusal is reachable on a graph whose vertices improve many
23
+ * times inside one bucket), 3 the f32 threshold absorbed the delta (E_UNSUPPORTED `sssp.thresholdAbsorbed`). The
24
+ * rounds are at most `n + ceil(sum / delta) + 1` (each near round settles the pile's minimum, one pass-through per
25
+ * bucket), so more submits than that is E_VALIDATION, never a hang.
26
+ *
27
+ * The two routings (PD-22) are decided by the RUN's weight vector: `options.weights` when given (`arcCount` long or
28
+ * E_INVALID_ARGUMENT; narrowed to `Float32Array` when it is not one -- a `U32` or `I32` value above 2^24, or the
29
+ * bits of an `F64` value below the f32 ulp, is rounded silently, the package-wide f32 caveat and not a refusal --
30
+ * uploaded into a lease buffer and bound in the graph group's weights slot with `HAS_WEIGHTS` set even on an
31
+ * unweighted snapshot), else the snapshot's column, else none. A run whose vector is all ones, or has none, is the
32
+ * unit-weight BFS of P8-T6 with a depth cap derived from `cutoff` (`dv <= cutoff` on unit weights is
33
+ * `depth <= floor(cutoff)`), its `predArc` from `sssp-pred` in depth mode writing arc indices, `reachedCount` the
34
+ * visited count -- not a fallback, a better algorithm for the input. A negative weight is E_UNSUPPORTED
35
+ * `sssp.negativeWeights` (use bellmanFord), a non-finite one E_UNSUPPORTED `sssp.nonFiniteWeights` (the bit-pattern
36
+ * order is undefined for NaN); `cutoff: NaN` is E_INVALID_ARGUMENT, because the CPU port's `dv <= NaN` relaxes
37
+ * nothing while the kernel's `nd > NaN` guard would relax everything (PD-19). All host-side, before any device work.
38
+ * The delta is `SSSP_DELTA_FACTOR x avgWeight / avgDegree` over the vector in use (1 for an all-zero vector), seeded
39
+ * into the counters block as `deltaBits` and `thresholdBits`.
40
+ *
41
+ * `predArc` is a second pass over the settled distances (PD-11), never packed into the distance atomic: `sssp-pred`
42
+ * in `MODE 0` follows PD-27's plateau rule -- the smallest TIGHT arc whose source sits one key step below `v`, the
43
+ * key `(dist, hops)` with `hops` the plateau depth from a root -- through three roles over one buffer (the arcs,
44
+ * the hop counts, the changed word and the orphan word), so the chain strictly decreases the key, ends at the
45
+ * source, and is bitwise reproducible. A hop batch of `MAX_LEVELS_PER_SUBMIT` passes that still changed something
46
+ * is recorded again without the roots pass; a reached node the key never reached is a kernel bug (E_VALIDATION),
47
+ * never a result. The tuning entry `ssspWithTuning` (PD-26's shape) is what the tests drive; nothing public
48
+ * exposes it.
49
+ *
50
+ * The host-side helpers of the two routings (`resolveWeights`, `normaliseCutoff`, `checkDest`, `assertSource`,
51
+ * `unitWeightRoute`) and the predecessor pass (`predecessorPass`, both PD-27 keys) are shared with
52
+ * `bellman-ford.ts` (P8-T10), which is the same seam type over the same `SsspOptions`; they take the algorithm's
53
+ * name for their messages and are `@internal`.
54
+ */
55
+ import { type GpuContext } from "../context.js";
56
+ import { type SsspOptions } from "../types/accelerator.js";
57
+ import { type GpuRunOptions } from "../types/run.js";
58
+ import { type GpuSsspResult } from "../types/traversal.js";
59
+ /**
60
+ * Single-source shortest paths on the device (spec 3.3 line 808, design 8.4, 9.7): `dist` in f32, bitwise equal to
61
+ * the f32 Dijkstra (PD-9), `predArc` a tight arc one PD-27 key step below each reached node (the chain always ends
62
+ * at the source), `reachedCount`; `cutoff` as the CPU port reads it (`dv <= cutoff`), `weights` a per-arc override
63
+ * of the snapshot's column for this run; a run with unit weights is the BFS (PD-22).
64
+ * @param ctx - the context whose device runs the kernels
65
+ * @param s - the snapshot (uploaded through ctx.residency, or found there)
66
+ * @param source - the source node index (E_INVALID_ARGUMENT outside `[0, n)`)
67
+ * @param options - `cutoff` and `weights`, plus dest (a Float32Array of length n for `dist`) / signal / onProgress
68
+ * @returns the distances, the predecessor arcs and the reached count
69
+ */
70
+ export declare function sssp(ctx: GpuContext, s: GraphSnapshot, source: number, options?: SsspOptions & GpuRunOptions): Promise<GpuSsspResult>;
71
+ //# sourceMappingURL=sssp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sssp.d.ts","sourceRoot":"","sources":["../../../src/algorithms/sssp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAKH,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAkBhD,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AA6pB3D;;;;;;;;;;GAUG;AACH,wBAAgB,IAAI,CAChB,GAAG,EAAE,UAAU,EACf,CAAC,EAAE,aAAa,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,WAAW,GAAG,aAAa,GACtC,OAAO,CAAC,aAAa,CAAC,CAExB"}