@graphty/webgpu-graph-algorithms 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -36
- package/dist/browser.js +1 -1
- package/dist/chunks/{context-E6iKaeuJ.js → context-CRbw2Wyo.js} +178 -19
- package/dist/chunks/{context-E6iKaeuJ.js.map → context-CRbw2Wyo.js.map} +1 -1
- package/dist/node.js +1 -1
- package/dist/src/accelerator.d.ts +9 -6
- package/dist/src/accelerator.d.ts.map +1 -1
- package/dist/src/accelerator.js +85 -6
- package/dist/src/accelerator.js.map +1 -1
- package/dist/src/algorithms/components.d.ts +30 -0
- package/dist/src/algorithms/components.d.ts.map +1 -0
- package/dist/src/algorithms/components.js +300 -0
- package/dist/src/algorithms/components.js.map +1 -0
- package/dist/src/algorithms/pagerank.d.ts +39 -0
- package/dist/src/algorithms/pagerank.d.ts.map +1 -0
- package/dist/src/algorithms/pagerank.js +298 -0
- package/dist/src/algorithms/pagerank.js.map +1 -0
- package/dist/src/algorithms/power-iteration.d.ts +109 -0
- package/dist/src/algorithms/power-iteration.d.ts.map +1 -0
- package/dist/src/algorithms/power-iteration.js +206 -0
- package/dist/src/algorithms/power-iteration.js.map +1 -0
- package/dist/src/algorithms/scope.d.ts +26 -0
- package/dist/src/algorithms/scope.d.ts.map +1 -0
- package/dist/src/algorithms/scope.js +41 -0
- package/dist/src/algorithms/scope.js.map +1 -0
- package/dist/src/algorithms/spectral.d.ts +50 -0
- package/dist/src/algorithms/spectral.d.ts.map +1 -0
- package/dist/src/algorithms/spectral.js +247 -0
- package/dist/src/algorithms/spectral.js.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/kernel/dispatch.d.ts +4 -1
- package/dist/src/kernel/dispatch.d.ts.map +1 -1
- package/dist/src/kernel/dispatch.js +12 -5
- package/dist/src/kernel/dispatch.js.map +1 -1
- package/dist/src/kernels.d.ts +20 -4
- package/dist/src/kernels.d.ts.map +1 -1
- package/dist/src/kernels.js +172 -2
- package/dist/src/kernels.js.map +1 -1
- package/dist/src/memory/residency.d.ts.map +1 -1
- package/dist/src/memory/residency.js +164 -11
- package/dist/src/memory/residency.js.map +1 -1
- package/dist/src/primitives/core-shape.d.ts +41 -0
- package/dist/src/primitives/core-shape.d.ts.map +1 -0
- package/dist/src/primitives/core-shape.js +89 -0
- package/dist/src/primitives/core-shape.js.map +1 -0
- package/dist/src/primitives/segmented-reduce.d.ts.map +1 -1
- package/dist/src/primitives/segmented-reduce.js +4 -30
- package/dist/src/primitives/segmented-reduce.js.map +1 -1
- package/dist/src/primitives/spmv.d.ts +56 -0
- package/dist/src/primitives/spmv.d.ts.map +1 -0
- package/dist/src/primitives/spmv.js +101 -0
- package/dist/src/primitives/spmv.js.map +1 -0
- package/dist/src/types/accelerator.d.ts +14 -2
- package/dist/src/types/accelerator.d.ts.map +1 -1
- package/dist/src/types/algorithms.d.ts +73 -0
- package/dist/src/types/algorithms.d.ts.map +1 -0
- package/dist/src/types/algorithms.js +17 -0
- package/dist/src/types/algorithms.js.map +1 -0
- package/dist/src/wgsl/pr-finalize.wgsl.d.ts +11 -0
- package/dist/src/wgsl/pr-finalize.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/pr-finalize.wgsl.js +36 -0
- package/dist/src/wgsl/pr-finalize.wgsl.js.map +1 -0
- package/dist/src/wgsl/pr-scale.wgsl.d.ts +14 -0
- package/dist/src/wgsl/pr-scale.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/pr-scale.wgsl.js +48 -0
- package/dist/src/wgsl/pr-scale.wgsl.js.map +1 -0
- package/dist/src/wgsl/spmv-pull.wgsl.d.ts +15 -0
- package/dist/src/wgsl/spmv-pull.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/spmv-pull.wgsl.js +47 -0
- package/dist/src/wgsl/spmv-pull.wgsl.js.map +1 -0
- package/dist/src/wgsl/wcc-compress.wgsl.d.ts +9 -0
- package/dist/src/wgsl/wcc-compress.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/wcc-compress.wgsl.js +26 -0
- package/dist/src/wgsl/wcc-compress.wgsl.js.map +1 -0
- package/dist/src/wgsl/wcc-link-edges.wgsl.d.ts +13 -0
- package/dist/src/wgsl/wcc-link-edges.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/wcc-link-edges.wgsl.js +46 -0
- package/dist/src/wgsl/wcc-link-edges.wgsl.js.map +1 -0
- package/dist/src/wgsl/wcc-link-sample.wgsl.d.ts +11 -0
- package/dist/src/wgsl/wcc-link-sample.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/wcc-link-sample.wgsl.js +45 -0
- package/dist/src/wgsl/wcc-link-sample.wgsl.js.map +1 -0
- package/dist/src/wgsl/wcc-sample.wgsl.d.ts +10 -0
- package/dist/src/wgsl/wcc-sample.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/wcc-sample.wgsl.js +18 -0
- package/dist/src/wgsl/wcc-sample.wgsl.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/webgpu-graph-algorithms.js +1550 -29
- package/dist/webgpu-graph-algorithms.js.map +1 -1
- package/package.json +1 -1
- package/src/accelerator.ts +101 -7
- package/src/algorithms/components.ts +348 -0
- package/src/algorithms/pagerank.ts +343 -0
- package/src/algorithms/power-iteration.ts +278 -0
- package/src/algorithms/scope.ts +52 -0
- package/src/algorithms/spectral.ts +300 -0
- package/src/index.ts +18 -0
- package/src/kernel/dispatch.ts +12 -5
- package/src/kernels.ts +206 -5
- package/src/memory/residency.ts +200 -11
- package/src/primitives/core-shape.ts +103 -0
- package/src/primitives/segmented-reduce.ts +4 -36
- package/src/primitives/spmv.ts +155 -0
- package/src/types/accelerator.ts +28 -2
- package/src/types/algorithms.ts +82 -0
- package/src/wgsl/pr-finalize.wgsl.ts +36 -0
- package/src/wgsl/pr-scale.wgsl.ts +48 -0
- package/src/wgsl/spmv-pull.wgsl.ts +47 -0
- package/src/wgsl/wcc-compress.wgsl.ts +26 -0
- package/src/wgsl/wcc-link-edges.wgsl.ts +46 -0
- package/src/wgsl/wcc-link-sample.wgsl.ts +45 -0
- package/src/wgsl/wcc-sample.wgsl.ts +18 -0
package/dist/node.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { W as WebGpuGraphError, G as GpuContext } from "./chunks/context-
|
|
1
|
+
import { W as WebGpuGraphError, G as GpuContext } from "./chunks/context-CRbw2Wyo.js";
|
|
2
2
|
const INSTALL_HINT = "install the optional peer dependency webgpu@0.4.0";
|
|
3
3
|
function isDawnModule(loaded) {
|
|
4
4
|
return typeof loaded === "object" && loaded !== null && typeof loaded.create === "function";
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* createAccelerator (spec 3.3, 9; contract 3.14): the injectable object that satisfies the CPU packages'
|
|
3
3
|
* AlgorithmAccelerator and LayoutAccelerator interfaces STRUCTURALLY (spec 9.2, 9.3; the mirrors of
|
|
4
|
-
* src/types/accelerator.ts until W1, D27).
|
|
5
|
-
* else: the CPU-side dispatchers (`accelerated()`,
|
|
6
|
-
* route to the CPU when the member is
|
|
7
|
-
*
|
|
8
|
-
* from
|
|
4
|
+
* src/types/accelerator.ts until W1, D27). It carries P3's `forceAtlas2`, `release` and `dispose` and P7's seven
|
|
5
|
+
* algorithm members (spec 8.2, 8.3; M8b-T8, PD-14) and nothing else: the CPU-side dispatchers (`accelerated()`,
|
|
6
|
+
* `createSimulation()`) test `acc.betweennessCentrality !== undefined` and route to the CPU when the member is
|
|
7
|
+
* absent (spec 2.4 row "method missing"), so a method the GPU does not implement must not exist here -- never a
|
|
8
|
+
* throwing stub. The remaining algorithm members arrive one per shipped algorithm from P8; `fruchtermanReingold` /
|
|
9
|
+
* `springElectrical` with P5.
|
|
9
10
|
*/
|
|
10
11
|
import { type GpuContext } from "./context.js";
|
|
11
12
|
import { type AcceleratorOptions, type GpuAccelerator } from "./types/accelerator.js";
|
|
12
13
|
/**
|
|
13
14
|
* Spec 3.3 createAccelerator, verbatim: the object implementing AlgorithmAccelerator & LayoutAccelerator
|
|
14
|
-
* structurally;
|
|
15
|
+
* structurally; P3's forceAtlas2, release and dispose plus P7's seven algorithm members, each a delegation to
|
|
16
|
+
* its algorithm with `ctx.assertReady()` first. The accelerator's algorithm defaults are not consulted by any of
|
|
17
|
+
* them: only `betweenness` has any, and it belongs to P9. One per call (the app creates one and injects
|
|
15
18
|
* it, spec 2.4); `kind` is "webgpu"; `options` is a frozen deep copy; `forceAtlas2(o)` is
|
|
16
19
|
* `createForceAtlas2(ctx, { ...o, ...options.layout })`, so the GPU tuning given here wins over anything the
|
|
17
20
|
* CPU-typed option object carries (spec 3.3: tuning never comes from the caller of the accelerator method);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accelerator.d.ts","sourceRoot":"","sources":["../../src/accelerator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"accelerator.d.ts","sourceRoot":"","sources":["../../src/accelerator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAsEtF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,cAAc,CA2G/F"}
|
package/dist/src/accelerator.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* createAccelerator (spec 3.3, 9; contract 3.14): the injectable object that satisfies the CPU packages'
|
|
3
3
|
* AlgorithmAccelerator and LayoutAccelerator interfaces STRUCTURALLY (spec 9.2, 9.3; the mirrors of
|
|
4
|
-
* src/types/accelerator.ts until W1, D27).
|
|
5
|
-
* else: the CPU-side dispatchers (`accelerated()`,
|
|
6
|
-
* route to the CPU when the member is
|
|
7
|
-
*
|
|
8
|
-
* from
|
|
4
|
+
* src/types/accelerator.ts until W1, D27). It carries P3's `forceAtlas2`, `release` and `dispose` and P7's seven
|
|
5
|
+
* algorithm members (spec 8.2, 8.3; M8b-T8, PD-14) and nothing else: the CPU-side dispatchers (`accelerated()`,
|
|
6
|
+
* `createSimulation()`) test `acc.betweennessCentrality !== undefined` and route to the CPU when the member is
|
|
7
|
+
* absent (spec 2.4 row "method missing"), so a method the GPU does not implement must not exist here -- never a
|
|
8
|
+
* throwing stub. The remaining algorithm members arrive one per shipped algorithm from P8; `fruchtermanReingold` /
|
|
9
|
+
* `springElectrical` with P5.
|
|
9
10
|
*/
|
|
11
|
+
import { connectedComponents } from "./algorithms/components.js";
|
|
12
|
+
import { pageRank, personalizedPageRank } from "./algorithms/pagerank.js";
|
|
13
|
+
import { eigenvectorCentrality, hits, katzCentrality } from "./algorithms/spectral.js";
|
|
10
14
|
import { createForceAtlas2 } from "./layouts/forceatlas2.js";
|
|
11
15
|
/**
|
|
12
16
|
* Frozen copy of the betweenness defaults; `sources` is copied into a fresh frozen array so a later mutation of
|
|
@@ -56,7 +60,9 @@ function freezeOptions(options) {
|
|
|
56
60
|
}
|
|
57
61
|
/**
|
|
58
62
|
* Spec 3.3 createAccelerator, verbatim: the object implementing AlgorithmAccelerator & LayoutAccelerator
|
|
59
|
-
* structurally;
|
|
63
|
+
* structurally; P3's forceAtlas2, release and dispose plus P7's seven algorithm members, each a delegation to
|
|
64
|
+
* its algorithm with `ctx.assertReady()` first. The accelerator's algorithm defaults are not consulted by any of
|
|
65
|
+
* them: only `betweenness` has any, and it belongs to P9. One per call (the app creates one and injects
|
|
60
66
|
* it, spec 2.4); `kind` is "webgpu"; `options` is a frozen deep copy; `forceAtlas2(o)` is
|
|
61
67
|
* `createForceAtlas2(ctx, { ...o, ...options.layout })`, so the GPU tuning given here wins over anything the
|
|
62
68
|
* CPU-typed option object carries (spec 3.3: tuning never comes from the caller of the accelerator method);
|
|
@@ -83,6 +89,79 @@ export function createAccelerator(ctx, options) {
|
|
|
83
89
|
ctx.assertReady();
|
|
84
90
|
return createForceAtlas2(ctx, { ...o, ...frozen.layout });
|
|
85
91
|
},
|
|
92
|
+
/**
|
|
93
|
+
* PageRank on the device (spec 8.2; contract 3.14).
|
|
94
|
+
* @param gs - the snapshot
|
|
95
|
+
* @param o - the CPU option record (spec 9.2 PageRankOptions)
|
|
96
|
+
* @returns the f32 scores with `precision: "f32"` (spec 9.7)
|
|
97
|
+
*/
|
|
98
|
+
async pageRank(gs, o) {
|
|
99
|
+
ctx.assertReady();
|
|
100
|
+
return await pageRank(ctx, gs, o);
|
|
101
|
+
},
|
|
102
|
+
/**
|
|
103
|
+
* Personalized PageRank on the device (spec 8.2; contract 3.14). The mirror admits an f64 personalization
|
|
104
|
+
* (spec 9.2 `F32 | F64`); the kernel reads f32, so an f64 vector is narrowed on the host first.
|
|
105
|
+
* @param gs - the snapshot
|
|
106
|
+
* @param personalization - one finite non-negative mass per node, not all zero
|
|
107
|
+
* @param o - the CPU option record (spec 9.2 PageRankOptions)
|
|
108
|
+
* @returns the f32 scores with `precision: "f32"` (spec 9.7)
|
|
109
|
+
*/
|
|
110
|
+
async personalizedPageRank(gs, personalization, o) {
|
|
111
|
+
ctx.assertReady();
|
|
112
|
+
const mass = personalization instanceof Float32Array ? personalization : Float32Array.from(personalization);
|
|
113
|
+
return await personalizedPageRank(ctx, gs, mass, o);
|
|
114
|
+
},
|
|
115
|
+
/**
|
|
116
|
+
* HITS hubs and authorities on the device (spec 8.2; contract 3.14).
|
|
117
|
+
* @param gs - the snapshot
|
|
118
|
+
* @param o - the CPU option record (spec 9.2 HitsOptions)
|
|
119
|
+
* @returns hubs and authorities with `precision: "f32"` (spec 9.7)
|
|
120
|
+
*/
|
|
121
|
+
async hits(gs, o) {
|
|
122
|
+
ctx.assertReady();
|
|
123
|
+
return await hits(ctx, gs, o);
|
|
124
|
+
},
|
|
125
|
+
/**
|
|
126
|
+
* Eigenvector centrality on the device (spec 8.2; contract 3.14).
|
|
127
|
+
* @param gs - the snapshot
|
|
128
|
+
* @param o - the CPU option record (spec 9.2 EigenvectorOptions)
|
|
129
|
+
* @returns the f32 scores with `precision: "f32"` (spec 9.7)
|
|
130
|
+
*/
|
|
131
|
+
async eigenvectorCentrality(gs, o) {
|
|
132
|
+
ctx.assertReady();
|
|
133
|
+
return await eigenvectorCentrality(ctx, gs, o);
|
|
134
|
+
},
|
|
135
|
+
/**
|
|
136
|
+
* Katz centrality on the device (spec 8.2; contract 3.14).
|
|
137
|
+
* @param gs - the snapshot
|
|
138
|
+
* @param o - the CPU option record (spec 9.2 KatzOptions)
|
|
139
|
+
* @returns the f32 scores with `precision: "f32"` (spec 9.7)
|
|
140
|
+
*/
|
|
141
|
+
async katzCentrality(gs, o) {
|
|
142
|
+
ctx.assertReady();
|
|
143
|
+
return await katzCentrality(ctx, gs, o);
|
|
144
|
+
},
|
|
145
|
+
/**
|
|
146
|
+
* Weakly connected components on the device (spec 8.3; contract 3.14): WCC semantics on directed input.
|
|
147
|
+
* @param gs - the snapshot
|
|
148
|
+
* @param o - `renumber` (default true); the mirror passes none
|
|
149
|
+
* @returns the labels, the count and groups() (spec 9.7 LabelResultLike)
|
|
150
|
+
*/
|
|
151
|
+
async connectedComponents(gs, o) {
|
|
152
|
+
ctx.assertReady();
|
|
153
|
+
return await connectedComponents(ctx, gs, o);
|
|
154
|
+
},
|
|
155
|
+
/**
|
|
156
|
+
* The same algorithm as `connectedComponents` under the mirror's other name (spec 3.3, 9.2).
|
|
157
|
+
* @param gs - the snapshot
|
|
158
|
+
* @param o - `renumber` (default true); the mirror passes none
|
|
159
|
+
* @returns the labels, the count and groups() (spec 9.7 LabelResultLike)
|
|
160
|
+
*/
|
|
161
|
+
async weaklyConnectedComponents(gs, o) {
|
|
162
|
+
ctx.assertReady();
|
|
163
|
+
return await connectedComponents(ctx, gs, o);
|
|
164
|
+
},
|
|
86
165
|
/**
|
|
87
166
|
* Destroys every device buffer recorded for the snapshot (spec 4.5); delegates to ctx.release.
|
|
88
167
|
* @param s - the snapshot the app is done with
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accelerator.js","sourceRoot":"","sources":["../../src/accelerator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"accelerator.js","sourceRoot":"","sources":["../../src/accelerator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weakly connected components on the device (spec 8.3, 3.3): Afforest from GAP's cc.cc, step for step. `comp[v] = v`
|
|
3
|
+
* by `fill` mode 1; two sampled link rounds over the r-th out-neighbour of every row plus a compress (one batch, no
|
|
4
|
+
* readback); a 1,024-vertex label sample the host takes the mode of, which is the giant component (PD-12); then
|
|
5
|
+
* each-edge-once link rounds over `edgeList()` -- correct for directed and undirected input alike, which is what
|
|
6
|
+
* makes the partition the WEAK one -- in batches of four `link + compress` pairs, ONE readback of the changed flag per
|
|
7
|
+
* batch, until the flag stays 0; a final compress; readback; `renumberPartition` on the host in first-seen order so
|
|
8
|
+
* the labels are IDENTICAL to the CPU's (spec 9.7), or the raw roots when `renumber: false`.
|
|
9
|
+
*
|
|
10
|
+
* PLAN DECISION PD-4: the changed flag is the word at `comp[n]`, so the link kernels bind three buffers (design 8.10).
|
|
11
|
+
* PLAN DECISION PD-11: `E_PARTITION` is NOT a pass-through. The kernels only ever store a value read out of `comp`,
|
|
12
|
+
* which `fill` seeded with `v < n`, so no label can be `INVALID_INDEX`; the host verifies every label is `< n` before
|
|
13
|
+
* `renumberPartition` sees it and raises `E_VALIDATION { label: "connectedComponents/labels" }` if that ever fails --
|
|
14
|
+
* it would mean a GPU bug, which no caller could act on as `E_PARTITION`.
|
|
15
|
+
* DEP-M8B-C: no `dedupe` primitive; Afforest's link is idempotent, so a repeated edge is a no-op.
|
|
16
|
+
*/
|
|
17
|
+
import { type GraphSnapshot } from "@graphty/graph-format";
|
|
18
|
+
import { type GpuContext } from "../context.js";
|
|
19
|
+
import { type ComponentsOptions, type GpuLabelResult } from "../types/algorithms.js";
|
|
20
|
+
import { type GpuRunOptions } from "../types/run.js";
|
|
21
|
+
/**
|
|
22
|
+
* Weakly connected components on the device (spec 3.3, 8.3): Afforest over the resident core and the edge list;
|
|
23
|
+
* labels dense in first-seen order (`renumber: true`, the default) or the raw roots (`renumber: false`).
|
|
24
|
+
* @param ctx - the context whose device runs the kernels
|
|
25
|
+
* @param s - the snapshot (uploaded through ctx.residency, or found there)
|
|
26
|
+
* @param options - renumber (default true), plus dest / signal / onProgress
|
|
27
|
+
* @returns the labels, the component count and groups()
|
|
28
|
+
*/
|
|
29
|
+
export declare function connectedComponents(ctx: GpuContext, s: GraphSnapshot, options?: ComponentsOptions & GpuRunOptions): Promise<GpuLabelResult>;
|
|
30
|
+
//# sourceMappingURL=components.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../src/algorithms/components.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,KAAK,aAAa,EAA+B,MAAM,uBAAuB,CAAC;AAGxF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAMhD,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAErF,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA6JrD;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACrC,GAAG,EAAE,UAAU,EACf,CAAC,EAAE,aAAa,EAChB,OAAO,CAAC,EAAE,iBAAiB,GAAG,aAAa,GAC5C,OAAO,CAAC,cAAc,CAAC,CAsJzB"}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weakly connected components on the device (spec 8.3, 3.3): Afforest from GAP's cc.cc, step for step. `comp[v] = v`
|
|
3
|
+
* by `fill` mode 1; two sampled link rounds over the r-th out-neighbour of every row plus a compress (one batch, no
|
|
4
|
+
* readback); a 1,024-vertex label sample the host takes the mode of, which is the giant component (PD-12); then
|
|
5
|
+
* each-edge-once link rounds over `edgeList()` -- correct for directed and undirected input alike, which is what
|
|
6
|
+
* makes the partition the WEAK one -- in batches of four `link + compress` pairs, ONE readback of the changed flag per
|
|
7
|
+
* batch, until the flag stays 0; a final compress; readback; `renumberPartition` on the host in first-seen order so
|
|
8
|
+
* the labels are IDENTICAL to the CPU's (spec 9.7), or the raw roots when `renumber: false`.
|
|
9
|
+
*
|
|
10
|
+
* PLAN DECISION PD-4: the changed flag is the word at `comp[n]`, so the link kernels bind three buffers (design 8.10).
|
|
11
|
+
* PLAN DECISION PD-11: `E_PARTITION` is NOT a pass-through. The kernels only ever store a value read out of `comp`,
|
|
12
|
+
* which `fill` seeded with `v < n`, so no label can be `INVALID_INDEX`; the host verifies every label is `< n` before
|
|
13
|
+
* `renumberPartition` sees it and raises `E_VALIDATION { label: "connectedComponents/labels" }` if that ever fails --
|
|
14
|
+
* it would mean a GPU bug, which no caller could act on as `E_PARTITION`.
|
|
15
|
+
* DEP-M8B-C: no `dedupe` primitive; Afforest's link is idempotent, so a repeated edge is a no-op.
|
|
16
|
+
*/
|
|
17
|
+
import { renumberPartition } from "@graphty/graph-format";
|
|
18
|
+
import { U32_MAX } from "../constants.js";
|
|
19
|
+
import { isWebGpuGraphError, WebGpuGraphError } from "../errors.js";
|
|
20
|
+
import { CommandBatch } from "../kernel/batch.js";
|
|
21
|
+
import { plan1d, planGridStride } from "../kernel/dispatch.js";
|
|
22
|
+
import { FILL_PARAMS, graphBindings, graphOverrides, kernelSpec, WCC_PARAMS } from "../kernels.js";
|
|
23
|
+
import { algorithmScope } from "./scope.js";
|
|
24
|
+
const ALGORITHM = "connectedComponents";
|
|
25
|
+
/** Link rounds between two reads of the changed flag (design 8.3: "checked every 4 rounds"). */
|
|
26
|
+
const ROUNDS_PER_BATCH = 4;
|
|
27
|
+
/** The edge-round cap; the flag not settling by then is a hard error, never a fallback. */
|
|
28
|
+
const MAX_WCC_ROUNDS = 64;
|
|
29
|
+
/** The sampled vertices the giant component is found from (design 8.3). */
|
|
30
|
+
const SAMPLE_SIZE = 1024;
|
|
31
|
+
/** The bound of a CAS retry loop and of a compress walk (PD-5). */
|
|
32
|
+
const MAX_STEPS = 1024;
|
|
33
|
+
/** Params slots of the largest batch: four link + four compress blocks; the setup batch uses fill + 2 links + compress. */
|
|
34
|
+
const RING_SLOTS = 2 * ROUNDS_PER_BATCH;
|
|
35
|
+
/**
|
|
36
|
+
* Validates `options.dest` for a label result of `n` elements.
|
|
37
|
+
* @param dest - the caller's destination array, if any
|
|
38
|
+
* @param n - the node count
|
|
39
|
+
* @returns the destination as a U32, or null when none was given
|
|
40
|
+
*/
|
|
41
|
+
function checkDest(dest, n) {
|
|
42
|
+
if (dest === undefined) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
if (dest instanceof Uint32Array && dest.length === n && dest.buffer instanceof ArrayBuffer) {
|
|
46
|
+
return dest;
|
|
47
|
+
}
|
|
48
|
+
throw new WebGpuGraphError("E_INVALID_ARGUMENT", `${ALGORITHM}: dest must be a Uint32Array of length ${n} over an ArrayBuffer`, {
|
|
49
|
+
argument: "dest",
|
|
50
|
+
value: `${dest.constructor.name}(${dest.length})`,
|
|
51
|
+
expected: `Uint32Array(${n}) over an ArrayBuffer`,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The resident core; a windowed plan (`E_TOO_LARGE { path: "windowed", algorithm: null }`, spec 3.8) is re-thrown
|
|
56
|
+
* with the algorithm name (3.12). Transcribed from degree.ts, whose coreOf is module-private.
|
|
57
|
+
* @param ctx - the context
|
|
58
|
+
* @param s - the snapshot
|
|
59
|
+
* @returns the core binding
|
|
60
|
+
*/
|
|
61
|
+
function coreOf(ctx, s) {
|
|
62
|
+
try {
|
|
63
|
+
return ctx.residency.core(s);
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
if (isWebGpuGraphError(error) && error.code === "E_TOO_LARGE" && error.details.path === "windowed") {
|
|
67
|
+
throw new WebGpuGraphError("E_TOO_LARGE", `${ALGORITHM}: the arc arrays need a windowed upload, which P1-P3 plan but do not execute`, { ...error.details, algorithm: ALGORITHM });
|
|
68
|
+
}
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Whole-buffer binding of a scratch buffer over its first `size` bytes.
|
|
74
|
+
* @param buffer - the buffer
|
|
75
|
+
* @param size - the bound byte length
|
|
76
|
+
* @returns the binding
|
|
77
|
+
*/
|
|
78
|
+
function bindingOf(buffer, size) {
|
|
79
|
+
return { buffer, offset: 0, size, window: null };
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The result object over a label array whose labels are all `< n`: `count` blocks, `groups()` built lazily once in
|
|
83
|
+
* first-seen label order (which for renumbered labels is index order).
|
|
84
|
+
* @param labels - the labels
|
|
85
|
+
* @param count - the block count
|
|
86
|
+
* @returns the result
|
|
87
|
+
*/
|
|
88
|
+
function labelResult(labels, count) {
|
|
89
|
+
let groups = null;
|
|
90
|
+
return {
|
|
91
|
+
labels,
|
|
92
|
+
count,
|
|
93
|
+
groups() {
|
|
94
|
+
if (groups !== null) {
|
|
95
|
+
return groups;
|
|
96
|
+
}
|
|
97
|
+
const n = labels.length;
|
|
98
|
+
const dense = new Uint32Array(n).fill(U32_MAX);
|
|
99
|
+
const sizes = new Uint32Array(count);
|
|
100
|
+
let next = 0;
|
|
101
|
+
for (let v = 0; v < n; v++) {
|
|
102
|
+
let k = dense[labels[v]];
|
|
103
|
+
if (k === U32_MAX) {
|
|
104
|
+
k = next++;
|
|
105
|
+
dense[labels[v]] = k;
|
|
106
|
+
}
|
|
107
|
+
sizes[k]++;
|
|
108
|
+
}
|
|
109
|
+
const built = Array.from(sizes, (size) => new Uint32Array(size));
|
|
110
|
+
const filled = new Uint32Array(count);
|
|
111
|
+
for (let v = 0; v < n; v++) {
|
|
112
|
+
const k = dense[labels[v]];
|
|
113
|
+
built[k][filled[k]++] = v;
|
|
114
|
+
}
|
|
115
|
+
groups = built;
|
|
116
|
+
return built;
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* The mode of the sampled labels (GAP's SampleFrequentElement, counted on the host; PD-12).
|
|
122
|
+
* @param sample - the sampled labels
|
|
123
|
+
* @returns the most frequent label
|
|
124
|
+
*/
|
|
125
|
+
function modeOf(sample) {
|
|
126
|
+
const counts = new Map();
|
|
127
|
+
let best = sample[0];
|
|
128
|
+
let bestCount = 0;
|
|
129
|
+
for (const label of sample) {
|
|
130
|
+
const c = (counts.get(label) ?? 0) + 1;
|
|
131
|
+
counts.set(label, c);
|
|
132
|
+
if (c > bestCount) {
|
|
133
|
+
best = label;
|
|
134
|
+
bestCount = c;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return best;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Verifies every label is a node index (so `renumberPartition` can never see `INVALID_INDEX`, PD-11) and counts the
|
|
141
|
+
* distinct roots.
|
|
142
|
+
* @param raw - the labels the device produced
|
|
143
|
+
* @returns the number of distinct labels
|
|
144
|
+
*/
|
|
145
|
+
function checkLabels(raw) {
|
|
146
|
+
const n = raw.length;
|
|
147
|
+
const seen = new Uint8Array(n);
|
|
148
|
+
let count = 0;
|
|
149
|
+
for (let v = 0; v < n; v++) {
|
|
150
|
+
const label = raw[v];
|
|
151
|
+
if (label >= n) {
|
|
152
|
+
throw new WebGpuGraphError("E_VALIDATION", `${ALGORITHM}: labels[${v}] = ${label} is not a node index`, {
|
|
153
|
+
label: `${ALGORITHM}/labels`,
|
|
154
|
+
message: `the device produced a label outside [0, ${n})`,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
if (seen[label] === 0) {
|
|
158
|
+
seen[label] = 1;
|
|
159
|
+
count++;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return count;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Weakly connected components on the device (spec 3.3, 8.3): Afforest over the resident core and the edge list;
|
|
166
|
+
* labels dense in first-seen order (`renumber: true`, the default) or the raw roots (`renumber: false`).
|
|
167
|
+
* @param ctx - the context whose device runs the kernels
|
|
168
|
+
* @param s - the snapshot (uploaded through ctx.residency, or found there)
|
|
169
|
+
* @param options - renumber (default true), plus dest / signal / onProgress
|
|
170
|
+
* @returns the labels, the component count and groups()
|
|
171
|
+
*/
|
|
172
|
+
export async function connectedComponents(ctx, s, options) {
|
|
173
|
+
ctx.assertReady();
|
|
174
|
+
const n = s.nodeCount;
|
|
175
|
+
const renumber = options?.renumber !== false;
|
|
176
|
+
const dest = checkDest(options?.dest, n);
|
|
177
|
+
if (options?.signal?.aborted) {
|
|
178
|
+
throw new WebGpuGraphError("E_ABORTED", `${ALGORITHM}: the signal was aborted before any work started`, {});
|
|
179
|
+
}
|
|
180
|
+
if (n === 0) {
|
|
181
|
+
options?.onProgress?.(1, 1);
|
|
182
|
+
return labelResult(dest ?? new Uint32Array(0), 0);
|
|
183
|
+
}
|
|
184
|
+
const core = coreOf(ctx, s);
|
|
185
|
+
if (s.arcCount === 0) {
|
|
186
|
+
// every node is its own block, and the identity is already first-seen dense: renumbered and raw agree
|
|
187
|
+
const labels = dest ?? new Uint32Array(n);
|
|
188
|
+
for (let v = 0; v < n; v++) {
|
|
189
|
+
labels[v] = v;
|
|
190
|
+
}
|
|
191
|
+
options?.onProgress?.(1, 1);
|
|
192
|
+
return labelResult(labels, n);
|
|
193
|
+
}
|
|
194
|
+
const edges = ctx.residency.view(s, "edgeList");
|
|
195
|
+
const edgeCount = edges.scalars.edgeCount[0];
|
|
196
|
+
const scope = algorithmScope(ctx, ALGORITHM, RING_SLOTS);
|
|
197
|
+
try {
|
|
198
|
+
const compBytes = 4 * (n + 1);
|
|
199
|
+
const comp = scope.scratch(compBytes, "comp");
|
|
200
|
+
const items = Math.min(SAMPLE_SIZE, n);
|
|
201
|
+
const hist = scope.scratch(4 * items, "hist");
|
|
202
|
+
await ctx.allocator.check();
|
|
203
|
+
const fill = await ctx.pipelines.kernel(kernelSpec("fill", {}));
|
|
204
|
+
const linkSample = await ctx.pipelines.kernel(kernelSpec("wcc-link-sample", graphOverrides(core, null)));
|
|
205
|
+
const linkEdges = await ctx.pipelines.kernel(kernelSpec("wcc-link-edges", {}));
|
|
206
|
+
const compress = await ctx.pipelines.kernel(kernelSpec("wcc-compress", {}));
|
|
207
|
+
const sample = await ctx.pipelines.kernel(kernelSpec("wcc-sample", {}));
|
|
208
|
+
const { queue } = ctx.device;
|
|
209
|
+
const compBinding = bindingOf(comp, compBytes);
|
|
210
|
+
const histBinding = bindingOf(hist, 4 * items);
|
|
211
|
+
const rowPlan = planGridStride(n, ctx.workgroupSize, ctx.caps);
|
|
212
|
+
const edgePlan = planGridStride(edgeCount, ctx.workgroupSize, ctx.caps);
|
|
213
|
+
const flagIndex = n;
|
|
214
|
+
const zero = new Uint32Array(1);
|
|
215
|
+
const wccParams = (fields) => scope.params(WCC_PARAMS, { n, ...fields, flagIndex, maxSteps: MAX_STEPS, pad0: 0 });
|
|
216
|
+
const recordCompress = (pass) => {
|
|
217
|
+
const params = wccParams({ items: n, stride: rowPlan.stride ?? n, r: 0, giant: U32_MAX });
|
|
218
|
+
compress.dispatch(pass, compress.bind({ comp: compBinding, P: params.binding }), rowPlan, [params.offset]);
|
|
219
|
+
};
|
|
220
|
+
const submit = (batch) => {
|
|
221
|
+
scope.flush();
|
|
222
|
+
return batch.submit();
|
|
223
|
+
};
|
|
224
|
+
// batch 1: comp[v] = v, the flag cleared, two sampled link rounds over the r-th out-neighbour, one compress
|
|
225
|
+
queue.writeBuffer(comp, 4 * flagIndex, zero);
|
|
226
|
+
const setup = new CommandBatch(ctx, `${ALGORITHM}/setup`);
|
|
227
|
+
let pass = setup.pass("sample-rounds");
|
|
228
|
+
const fillParams = scope.params(FILL_PARAMS, { count: n, value: 0, mode: 1, pad0: 0 });
|
|
229
|
+
fill.dispatch(pass, fill.bind({ dst: bindingOf(comp, 4 * n), P: fillParams.binding }), plan1d(n, ctx.workgroupSize, ctx.caps), [fillParams.offset]);
|
|
230
|
+
const graph = graphBindings(core, null);
|
|
231
|
+
for (let r = 0; r < 2; r++) {
|
|
232
|
+
const params = wccParams({ items: n, stride: rowPlan.stride ?? n, r, giant: U32_MAX });
|
|
233
|
+
const bound = linkSample.bind({ ...graph, comp: compBinding, P: params.binding });
|
|
234
|
+
linkSample.dispatch(pass, bound, rowPlan, [params.offset]);
|
|
235
|
+
}
|
|
236
|
+
recordCompress(pass);
|
|
237
|
+
setup.endPass();
|
|
238
|
+
await submit(setup).readback;
|
|
239
|
+
ctx.assertReady();
|
|
240
|
+
// batch 2: the label sample, whose mode is the giant component
|
|
241
|
+
const sampler = new CommandBatch(ctx, `${ALGORITHM}/sample`);
|
|
242
|
+
pass = sampler.pass("sample");
|
|
243
|
+
const sampleParams = wccParams({ items, stride: 0, r: 0, giant: U32_MAX });
|
|
244
|
+
sample.dispatch(pass, sample.bind({ comp: compBinding, hist: histBinding, P: sampleParams.binding }), plan1d(items, ctx.workgroupSize, ctx.caps), [sampleParams.offset]);
|
|
245
|
+
sampler.endPass();
|
|
246
|
+
const histRequest = sampler.readback(hist, 0, 4 * items);
|
|
247
|
+
const histBytes = await submit(sampler).readback;
|
|
248
|
+
ctx.assertReady();
|
|
249
|
+
const giant = modeOf(new Uint32Array(histBytes, histRequest.offset, items));
|
|
250
|
+
// the edge rounds: four (link + compress) per batch, one readback of the changed flag per batch
|
|
251
|
+
const edgeBindings = { edgeSrc: edges.bindings.src, edgeDst: edges.bindings.dst, comp: compBinding };
|
|
252
|
+
let rounds = 0;
|
|
253
|
+
for (;;) {
|
|
254
|
+
queue.writeBuffer(comp, 4 * flagIndex, zero);
|
|
255
|
+
const batch = new CommandBatch(ctx, `${ALGORITHM}/rounds`);
|
|
256
|
+
pass = batch.pass("edge-rounds");
|
|
257
|
+
for (let i = 0; i < ROUNDS_PER_BATCH; i++) {
|
|
258
|
+
const params = wccParams({ items: edgeCount, stride: edgePlan.stride ?? edgeCount, r: 0, giant });
|
|
259
|
+
const bound = linkEdges.bind({ ...edgeBindings, P: params.binding });
|
|
260
|
+
linkEdges.dispatch(pass, bound, edgePlan, [params.offset]);
|
|
261
|
+
recordCompress(pass);
|
|
262
|
+
}
|
|
263
|
+
batch.endPass();
|
|
264
|
+
const flagRequest = batch.readback(comp, 4 * flagIndex, 4);
|
|
265
|
+
const submitted = submit(batch);
|
|
266
|
+
const back = await submitted.readback;
|
|
267
|
+
rounds += ROUNDS_PER_BATCH;
|
|
268
|
+
ctx.assertReady();
|
|
269
|
+
if (options?.signal?.aborted) {
|
|
270
|
+
throw new WebGpuGraphError("E_ABORTED", `${ALGORITHM}: the signal was aborted`, { batchId: submitted.id });
|
|
271
|
+
}
|
|
272
|
+
if (new Uint32Array(back, flagRequest.offset, 1)[0] === 0) {
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
if (rounds >= MAX_WCC_ROUNDS) {
|
|
276
|
+
throw new WebGpuGraphError("E_VALIDATION", `${ALGORITHM}: the changed flag never settled in ${MAX_WCC_ROUNDS} rounds`, { label: ALGORITHM, message: `the changed flag never settled in ${MAX_WCC_ROUNDS} rounds` });
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
// the final compress, then the labels
|
|
280
|
+
const final = new CommandBatch(ctx, `${ALGORITHM}/final`);
|
|
281
|
+
recordCompress(final.pass("compress"));
|
|
282
|
+
final.endPass();
|
|
283
|
+
await submit(final).readback;
|
|
284
|
+
ctx.assertReady();
|
|
285
|
+
const raw = !renumber && dest !== null ? dest : new Uint32Array(n);
|
|
286
|
+
await ctx.readback.read(comp, 4 * n, raw);
|
|
287
|
+
ctx.assertReady();
|
|
288
|
+
const distinct = checkLabels(raw);
|
|
289
|
+
options?.onProgress?.(1, 1);
|
|
290
|
+
if (!renumber) {
|
|
291
|
+
return labelResult(raw, distinct);
|
|
292
|
+
}
|
|
293
|
+
const { labels, count } = renumberPartition(raw, dest ?? undefined);
|
|
294
|
+
return labelResult(labels, count);
|
|
295
|
+
}
|
|
296
|
+
finally {
|
|
297
|
+
scope.dispose();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.js","sourceRoot":"","sources":["../../../src/algorithms/components.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PageRank and personalized PageRank on the device (spec 8.2, 3.3): a pull over the reverse adjacency with the
|
|
3
|
+
* out-weight normaliser folded into `xNorm` by `pr-scale`, the dangling mass and the L1 delta folded by
|
|
4
|
+
* `pr-finalize` into the header at `partials[0]`, and `spmv-pull` writing the next iterate. Iterations run in
|
|
5
|
+
* batches of PR_BATCH per submit, ONE readback per batch (the header and the iterate together), and the device
|
|
6
|
+
* records `firstConverged` the first time the delta falls below `tolerance * n`, so the reported `iterations` is the
|
|
7
|
+
* first converged iteration and not the batch boundary (spec 9.7).
|
|
8
|
+
*
|
|
9
|
+
* PLAN DECISION PD-7: the ping-pong is TWO buffers (`rankA`, `rankB`) alternated through two cached bind groups;
|
|
10
|
+
* one buffer of two aliased halves would bind (each kernel sees the halves in one access mode) but saves nothing.
|
|
11
|
+
* PLAN DECISION PD-8: `outWeightSum` is call scratch from the Lease, one `segmentedReduce` pass per call.
|
|
12
|
+
* PLAN DECISION PD-9: `pr-scale` at iteration i reads x(i-1) and x(i-2), so its delta is the error of iteration
|
|
13
|
+
* i - 1 and `pr-finalize` records `P.iteration - 1`; the ping-pong supplies `rankPrev` for free because it is the
|
|
14
|
+
* buffer this iteration overwrites, and `pr-scale` runs before `spmv-pull` in the same pass.
|
|
15
|
+
*/
|
|
16
|
+
import { type F32, type GraphSnapshot } from "@graphty/graph-format";
|
|
17
|
+
import { type GpuContext } from "../context.js";
|
|
18
|
+
import { type GpuPageRankResult, type PageRankOptions } from "../types/algorithms.js";
|
|
19
|
+
import { type GpuRunOptions } from "../types/run.js";
|
|
20
|
+
/**
|
|
21
|
+
* PageRank on the device (spec 3.3, 8.2): NetworkX semantics, f32 scores, `iterations` the first converged
|
|
22
|
+
* iteration (spec 9.7).
|
|
23
|
+
* @param ctx - the context whose device runs the kernels
|
|
24
|
+
* @param s - the snapshot (uploaded through ctx.residency, or found there)
|
|
25
|
+
* @param options - dampingFactor 0.85 / maxIterations 100 / tolerance 1e-6 / weighted true, plus dest / signal / onProgress
|
|
26
|
+
* @returns the scores, iterations, converged, danglingMass and precision
|
|
27
|
+
*/
|
|
28
|
+
export declare function pageRank(ctx: GpuContext, s: GraphSnapshot, options?: PageRankOptions & GpuRunOptions): Promise<GpuPageRankResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Personalized PageRank on the device (spec 3.3, 8.2): the personalization vector replaces the uniform 1 / n in
|
|
31
|
+
* the teleport and the dangling redistribution; it is normalised to sum 1 on the host.
|
|
32
|
+
* @param ctx - the context whose device runs the kernels
|
|
33
|
+
* @param s - the snapshot (uploaded through ctx.residency, or found there)
|
|
34
|
+
* @param personalization - one finite non-negative mass per node, not all zero
|
|
35
|
+
* @param options - dampingFactor 0.85 / maxIterations 100 / tolerance 1e-6 / weighted true, plus dest / signal / onProgress
|
|
36
|
+
* @returns the scores, iterations, converged, danglingMass and precision
|
|
37
|
+
*/
|
|
38
|
+
export declare function personalizedPageRank(ctx: GpuContext, s: GraphSnapshot, personalization: F32, options?: PageRankOptions & GpuRunOptions): Promise<GpuPageRankResult>;
|
|
39
|
+
//# sourceMappingURL=pagerank.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagerank.d.ts","sourceRoot":"","sources":["../../../src/algorithms/pagerank.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGrE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAShD,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEtF,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA+PrD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACpB,GAAG,EAAE,UAAU,EACf,CAAC,EAAE,aAAa,EAChB,OAAO,CAAC,EAAE,eAAe,GAAG,aAAa,GAC1C,OAAO,CAAC,iBAAiB,CAAC,CAE5B;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACtC,GAAG,EAAE,UAAU,EACf,CAAC,EAAE,aAAa,EAChB,eAAe,EAAE,GAAG,EACpB,OAAO,CAAC,EAAE,eAAe,GAAG,aAAa,GAC1C,OAAO,CAAC,iBAAiB,CAAC,CA2B5B"}
|