@graphty/webgpu-graph-algorithms 0.6.3 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -32
- package/dist/browser.js +1 -1
- package/dist/chunks/{context-BXqgCifx.js → context-hzGggHeM.js} +68 -24
- package/dist/chunks/context-hzGggHeM.js.map +1 -0
- package/dist/node.js +1 -1
- package/dist/src/accelerator.d.ts +8 -6
- package/dist/src/accelerator.d.ts.map +1 -1
- package/dist/src/accelerator.js +57 -6
- package/dist/src/accelerator.js.map +1 -1
- package/dist/src/algorithms/bellman-ford.d.ts +60 -0
- package/dist/src/algorithms/bellman-ford.d.ts.map +1 -0
- package/dist/src/algorithms/bellman-ford.js +301 -0
- package/dist/src/algorithms/bellman-ford.js.map +1 -0
- package/dist/src/algorithms/bfs.d.ts +67 -0
- package/dist/src/algorithms/bfs.d.ts.map +1 -0
- package/dist/src/algorithms/bfs.js +534 -0
- package/dist/src/algorithms/bfs.js.map +1 -0
- package/dist/src/algorithms/closeness.d.ts +53 -0
- package/dist/src/algorithms/closeness.d.ts.map +1 -0
- package/dist/src/algorithms/closeness.js +323 -0
- package/dist/src/algorithms/closeness.js.map +1 -0
- package/dist/src/algorithms/scope.d.ts +3 -1
- package/dist/src/algorithms/scope.d.ts.map +1 -1
- package/dist/src/algorithms/scope.js +1 -0
- package/dist/src/algorithms/scope.js.map +1 -1
- package/dist/src/algorithms/sssp.d.ts +72 -0
- package/dist/src/algorithms/sssp.d.ts.map +1 -0
- package/dist/src/algorithms/sssp.js +586 -0
- package/dist/src/algorithms/sssp.js.map +1 -0
- package/dist/src/constants.d.ts +10 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +10 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +8 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/kernel/prelude.d.ts +4 -4
- package/dist/src/kernel/prelude.d.ts.map +1 -1
- package/dist/src/kernel/prelude.js +39 -5
- package/dist/src/kernel/prelude.js.map +1 -1
- package/dist/src/kernel/uniform-ring.d.ts +8 -0
- package/dist/src/kernel/uniform-ring.d.ts.map +1 -1
- package/dist/src/kernel/uniform-ring.js +13 -0
- package/dist/src/kernel/uniform-ring.js.map +1 -1
- package/dist/src/kernels.d.ts +45 -4
- package/dist/src/kernels.d.ts.map +1 -1
- package/dist/src/kernels.js +368 -3
- package/dist/src/kernels.js.map +1 -1
- package/dist/src/primitives/advance.d.ts +63 -0
- package/dist/src/primitives/advance.d.ts.map +1 -0
- package/dist/src/primitives/advance.js +95 -0
- package/dist/src/primitives/advance.js.map +1 -0
- package/dist/src/primitives/compact.d.ts +89 -0
- package/dist/src/primitives/compact.d.ts.map +1 -0
- package/dist/src/primitives/compact.js +233 -0
- package/dist/src/primitives/compact.js.map +1 -0
- package/dist/src/primitives/core-shape.d.ts +22 -1
- package/dist/src/primitives/core-shape.d.ts.map +1 -1
- package/dist/src/primitives/core-shape.js +33 -3
- package/dist/src/primitives/core-shape.js.map +1 -1
- package/dist/src/primitives/frontier.d.ts +151 -0
- package/dist/src/primitives/frontier.d.ts.map +1 -0
- package/dist/src/primitives/frontier.js +250 -0
- package/dist/src/primitives/frontier.js.map +1 -0
- package/dist/src/types/accelerator.d.ts +16 -7
- package/dist/src/types/accelerator.d.ts.map +1 -1
- package/dist/src/types/traversal.d.ts +53 -0
- package/dist/src/types/traversal.d.ts.map +1 -0
- package/dist/src/types/traversal.js +10 -0
- package/dist/src/types/traversal.js.map +1 -0
- package/dist/src/wgsl/advance-expand.wgsl.d.ts +19 -0
- package/dist/src/wgsl/advance-expand.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/advance-expand.wgsl.js +69 -0
- package/dist/src/wgsl/advance-expand.wgsl.js.map +1 -0
- package/dist/src/wgsl/bf-relax.wgsl.d.ts +22 -0
- package/dist/src/wgsl/bf-relax.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/bf-relax.wgsl.js +58 -0
- package/dist/src/wgsl/bf-relax.wgsl.js.map +1 -0
- package/dist/src/wgsl/bfs-bitset-build.wgsl.d.ts +15 -0
- package/dist/src/wgsl/bfs-bitset-build.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/bfs-bitset-build.wgsl.js +24 -0
- package/dist/src/wgsl/bfs-bitset-build.wgsl.js.map +1 -0
- package/dist/src/wgsl/bfs-bottom-up.wgsl.d.ts +20 -0
- package/dist/src/wgsl/bfs-bottom-up.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/bfs-bottom-up.wgsl.js +67 -0
- package/dist/src/wgsl/bfs-bottom-up.wgsl.js.map +1 -0
- package/dist/src/wgsl/bfs-contract.wgsl.d.ts +20 -0
- package/dist/src/wgsl/bfs-contract.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/bfs-contract.wgsl.js +55 -0
- package/dist/src/wgsl/bfs-contract.wgsl.js.map +1 -0
- package/dist/src/wgsl/bfs-fused.wgsl.d.ts +25 -0
- package/dist/src/wgsl/bfs-fused.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/bfs-fused.wgsl.js +78 -0
- package/dist/src/wgsl/bfs-fused.wgsl.js.map +1 -0
- package/dist/src/wgsl/bfs-unvisited-flags.wgsl.d.ts +18 -0
- package/dist/src/wgsl/bfs-unvisited-flags.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/bfs-unvisited-flags.wgsl.js +42 -0
- package/dist/src/wgsl/bfs-unvisited-flags.wgsl.js.map +1 -0
- package/dist/src/wgsl/closeness-reduce.wgsl.d.ts +17 -0
- package/dist/src/wgsl/closeness-reduce.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/closeness-reduce.wgsl.js +65 -0
- package/dist/src/wgsl/closeness-reduce.wgsl.js.map +1 -0
- package/dist/src/wgsl/closeness-sweep.wgsl.d.ts +20 -0
- package/dist/src/wgsl/closeness-sweep.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/closeness-sweep.wgsl.js +96 -0
- package/dist/src/wgsl/closeness-sweep.wgsl.js.map +1 -0
- package/dist/src/wgsl/compact-scatter.wgsl.d.ts +9 -0
- package/dist/src/wgsl/compact-scatter.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/compact-scatter.wgsl.js +17 -0
- package/dist/src/wgsl/compact-scatter.wgsl.js.map +1 -0
- package/dist/src/wgsl/dedupe-claim.wgsl.d.ts +10 -0
- package/dist/src/wgsl/dedupe-claim.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/dedupe-claim.wgsl.js +19 -0
- package/dist/src/wgsl/dedupe-claim.wgsl.js.map +1 -0
- package/dist/src/wgsl/dedupe-filter.wgsl.d.ts +12 -0
- package/dist/src/wgsl/dedupe-filter.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/dedupe-filter.wgsl.js +46 -0
- package/dist/src/wgsl/dedupe-filter.wgsl.js.map +1 -0
- package/dist/src/wgsl/frontier-finalize.wgsl.d.ts +53 -0
- package/dist/src/wgsl/frontier-finalize.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/frontier-finalize.wgsl.js +164 -0
- package/dist/src/wgsl/frontier-finalize.wgsl.js.map +1 -0
- package/dist/src/wgsl/sssp-pred.wgsl.d.ts +28 -0
- package/dist/src/wgsl/sssp-pred.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/sssp-pred.wgsl.js +80 -0
- package/dist/src/wgsl/sssp-pred.wgsl.js.map +1 -0
- package/dist/src/wgsl/sssp-relax.wgsl.d.ts +30 -0
- package/dist/src/wgsl/sssp-relax.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/sssp-relax.wgsl.js +72 -0
- package/dist/src/wgsl/sssp-relax.wgsl.js.map +1 -0
- package/dist/webgpu-graph-algorithms.js +3155 -384
- package/dist/webgpu-graph-algorithms.js.map +1 -1
- package/package.json +5 -4
- package/src/accelerator.ts +65 -7
- package/src/algorithms/bellman-ford.ts +387 -0
- package/src/algorithms/bfs.ts +626 -0
- package/src/algorithms/closeness.ts +395 -0
- package/src/algorithms/scope.ts +4 -1
- package/src/algorithms/sssp.ts +768 -0
- package/src/constants.ts +10 -0
- package/src/index.ts +14 -1
- package/src/kernel/prelude.ts +39 -4
- package/src/kernel/uniform-ring.ts +14 -0
- package/src/kernels.ts +447 -6
- package/src/primitives/advance.ts +131 -0
- package/src/primitives/compact.ts +323 -0
- package/src/primitives/core-shape.ts +41 -3
- package/src/primitives/frontier.ts +372 -0
- package/src/types/accelerator.ts +18 -5
- package/src/types/traversal.ts +56 -0
- package/src/wgsl/advance-expand.wgsl.ts +68 -0
- package/src/wgsl/bf-relax.wgsl.ts +57 -0
- package/src/wgsl/bfs-bitset-build.wgsl.ts +23 -0
- package/src/wgsl/bfs-bottom-up.wgsl.ts +66 -0
- package/src/wgsl/bfs-contract.wgsl.ts +54 -0
- package/src/wgsl/bfs-fused.wgsl.ts +77 -0
- package/src/wgsl/bfs-unvisited-flags.wgsl.ts +41 -0
- package/src/wgsl/closeness-reduce.wgsl.ts +64 -0
- package/src/wgsl/closeness-sweep.wgsl.ts +95 -0
- package/src/wgsl/compact-scatter.wgsl.ts +16 -0
- package/src/wgsl/dedupe-claim.wgsl.ts +18 -0
- package/src/wgsl/dedupe-filter.wgsl.ts +45 -0
- package/src/wgsl/frontier-finalize.wgsl.ts +163 -0
- package/src/wgsl/sssp-pred.wgsl.ts +79 -0
- package/src/wgsl/sssp-relax.wgsl.ts +71 -0
- 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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"}
|
|
@@ -8,12 +8,14 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { type GpuContext } from "../context.js";
|
|
10
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. */
|
|
11
|
+
/** A ReduceScope over a context plus the two lifecycle calls an algorithm makes: flush() before submit, dispose() in its finally. (The `indirect()` lease it once added for the frontier's args buffer went with that buffer, 2026-09-25.) */
|
|
12
12
|
export interface AlgorithmScope extends ReduceScope {
|
|
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,
|
|
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,8OAA8O;AAC9O,MAAM,WAAW,cAAe,SAAQ,WAAW;IAC/C,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,CAwB5F"}
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../../src/algorithms/scope.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,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,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,72 @@
|
|
|
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 the round consumed),
|
|
15
|
+
* and `sssp-relax` twice (role 0 over `nearIn` sized by `frontierCount`, role 1 over `farIn` sized by `farCount`;
|
|
16
|
+
* the block's `path` word, 5 a near round and 6 a far one, makes the other role's dispatch a no-op). Nothing in a
|
|
17
|
+
* round is an indirect dispatch (2026-09-25). The far pile is re-bucketed by the
|
|
18
|
+
* relax kernel's pass-through, not by `compact` (PD-20): a far entry whose settled distance fell below the previous
|
|
19
|
+
* threshold was relaxed in the near band already and is dropped, the rest go back to near or far against the raised
|
|
20
|
+
* threshold. The near pile is ONE pile (no sub-partitions). The host records `MAX_LEVELS_PER_SUBMIT` rounds per
|
|
21
|
+
* submit and reads four bytes, the `done` word: 1 finished, 2 a raw half above its capacity (E_TOO_LARGE
|
|
22
|
+
* `sssp.pile`: the far half accumulates one entry per improving relaxation beyond the threshold across a bucket's
|
|
23
|
+
* near rounds and is deduped only at the split, so the refusal is reachable on a graph whose vertices improve many
|
|
24
|
+
* times inside one bucket), 3 the f32 threshold absorbed the delta (E_UNSUPPORTED `sssp.thresholdAbsorbed`). The
|
|
25
|
+
* rounds are at most `n + ceil(sum / delta) + 1` (each near round settles the pile's minimum, one pass-through per
|
|
26
|
+
* bucket), so more submits than that is E_VALIDATION, never a hang.
|
|
27
|
+
*
|
|
28
|
+
* The two routings (PD-22) are decided by the RUN's weight vector: `options.weights` when given (`arcCount` long or
|
|
29
|
+
* E_INVALID_ARGUMENT; narrowed to `Float32Array` when it is not one -- a `U32` or `I32` value above 2^24, or the
|
|
30
|
+
* bits of an `F64` value below the f32 ulp, is rounded silently, the package-wide f32 caveat and not a refusal --
|
|
31
|
+
* uploaded into a lease buffer and bound in the graph group's weights slot with `HAS_WEIGHTS` set even on an
|
|
32
|
+
* unweighted snapshot), else the snapshot's column, else none. A run whose vector is all ones, or has none, is the
|
|
33
|
+
* unit-weight BFS of P8-T6 with a depth cap derived from `cutoff` (`dv <= cutoff` on unit weights is
|
|
34
|
+
* `depth <= floor(cutoff)`), its `predArc` from `sssp-pred` in depth mode writing arc indices, `reachedCount` the
|
|
35
|
+
* visited count -- not a fallback, a better algorithm for the input. A negative weight is E_UNSUPPORTED
|
|
36
|
+
* `sssp.negativeWeights` (use bellmanFord), a non-finite one E_UNSUPPORTED `sssp.nonFiniteWeights` (the bit-pattern
|
|
37
|
+
* order is undefined for NaN); `cutoff: NaN` is E_INVALID_ARGUMENT, because the CPU port's `dv <= NaN` relaxes
|
|
38
|
+
* nothing while the kernel's `nd > NaN` guard would relax everything (PD-19). All host-side, before any device work.
|
|
39
|
+
* The delta is `SSSP_DELTA_FACTOR x avgWeight / avgDegree` over the vector in use (1 for an all-zero vector), seeded
|
|
40
|
+
* into the counters block as `deltaBits` and `thresholdBits`.
|
|
41
|
+
*
|
|
42
|
+
* `predArc` is a second pass over the settled distances (PD-11), never packed into the distance atomic: `sssp-pred`
|
|
43
|
+
* in `MODE 0` follows PD-27's plateau rule -- the smallest TIGHT arc whose source sits one key step below `v`, the
|
|
44
|
+
* key `(dist, hops)` with `hops` the plateau depth from a root -- through three roles over one buffer (the arcs,
|
|
45
|
+
* the hop counts, the changed word and the orphan word), so the chain strictly decreases the key, ends at the
|
|
46
|
+
* source, and is bitwise reproducible. A hop batch of `MAX_LEVELS_PER_SUBMIT` passes that still changed something
|
|
47
|
+
* is recorded again without the roots pass; a reached node the key never reached is a kernel bug (E_VALIDATION),
|
|
48
|
+
* never a result. The tuning entry `ssspWithTuning` (PD-26's shape) is what the tests drive; nothing public
|
|
49
|
+
* exposes it.
|
|
50
|
+
*
|
|
51
|
+
* The host-side helpers of the two routings (`resolveWeights`, `normaliseCutoff`, `checkDest`, `assertSource`,
|
|
52
|
+
* `unitWeightRoute`) and the predecessor pass (`predecessorPass`, both PD-27 keys) are shared with
|
|
53
|
+
* `bellman-ford.ts` (P8-T10), which is the same seam type over the same `SsspOptions`; they take the algorithm's
|
|
54
|
+
* name for their messages and are `@internal`.
|
|
55
|
+
*/
|
|
56
|
+
import { type GpuContext } from "../context.js";
|
|
57
|
+
import { type SsspOptions } from "../types/accelerator.js";
|
|
58
|
+
import { type GpuRunOptions } from "../types/run.js";
|
|
59
|
+
import { type GpuSsspResult } from "../types/traversal.js";
|
|
60
|
+
/**
|
|
61
|
+
* Single-source shortest paths on the device (spec 3.3 line 808, design 8.4, 9.7): `dist` in f32, bitwise equal to
|
|
62
|
+
* the f32 Dijkstra (PD-9), `predArc` a tight arc one PD-27 key step below each reached node (the chain always ends
|
|
63
|
+
* at the source), `reachedCount`; `cutoff` as the CPU port reads it (`dv <= cutoff`), `weights` a per-arc override
|
|
64
|
+
* of the snapshot's column for this run; a run with unit weights is the BFS (PD-22).
|
|
65
|
+
* @param ctx - the context whose device runs the kernels
|
|
66
|
+
* @param s - the snapshot (uploaded through ctx.residency, or found there)
|
|
67
|
+
* @param source - the source node index (E_INVALID_ARGUMENT outside `[0, n)`)
|
|
68
|
+
* @param options - `cutoff` and `weights`, plus dest (a Float32Array of length n for `dist`) / signal / onProgress
|
|
69
|
+
* @returns the distances, the predecessor arcs and the reached count
|
|
70
|
+
*/
|
|
71
|
+
export declare function sssp(ctx: GpuContext, s: GraphSnapshot, source: number, options?: SsspOptions & GpuRunOptions): Promise<GpuSsspResult>;
|
|
72
|
+
//# sourceMappingURL=sssp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sssp.d.ts","sourceRoot":"","sources":["../../../src/algorithms/sssp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;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"}
|