@graphty/webgpu-graph-algorithms 0.6.13 → 0.6.15

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 (95) hide show
  1. package/README.md +52 -52
  2. package/dist/browser.js +1 -1
  3. package/dist/chunks/{context-Bi6AhScG.js → context-oXphO3yj.js} +36 -28
  4. package/dist/chunks/context-oXphO3yj.js.map +1 -0
  5. package/dist/node.js +1 -1
  6. package/dist/src/accelerator.d.ts +3 -2
  7. package/dist/src/accelerator.d.ts.map +1 -1
  8. package/dist/src/accelerator.js +48 -4
  9. package/dist/src/accelerator.js.map +1 -1
  10. package/dist/src/algorithms/betweenness.d.ts +70 -0
  11. package/dist/src/algorithms/betweenness.d.ts.map +1 -0
  12. package/dist/src/algorithms/betweenness.js +538 -0
  13. package/dist/src/algorithms/betweenness.js.map +1 -0
  14. package/dist/src/algorithms/closeness.d.ts +15 -5
  15. package/dist/src/algorithms/closeness.d.ts.map +1 -1
  16. package/dist/src/algorithms/closeness.js +112 -26
  17. package/dist/src/algorithms/closeness.js.map +1 -1
  18. package/dist/src/constants.d.ts +8 -0
  19. package/dist/src/constants.d.ts.map +1 -1
  20. package/dist/src/constants.js +8 -0
  21. package/dist/src/constants.js.map +1 -1
  22. package/dist/src/index.d.ts +4 -2
  23. package/dist/src/index.d.ts.map +1 -1
  24. package/dist/src/index.js +1 -0
  25. package/dist/src/index.js.map +1 -1
  26. package/dist/src/kernels.d.ts +12 -6
  27. package/dist/src/kernels.d.ts.map +1 -1
  28. package/dist/src/kernels.js +153 -7
  29. package/dist/src/kernels.js.map +1 -1
  30. package/dist/src/primitives/frontier.d.ts +2 -0
  31. package/dist/src/primitives/frontier.d.ts.map +1 -1
  32. package/dist/src/primitives/frontier.js +2 -0
  33. package/dist/src/primitives/frontier.js.map +1 -1
  34. package/dist/src/types/accelerator.d.ts +11 -7
  35. package/dist/src/types/accelerator.d.ts.map +1 -1
  36. package/dist/src/types/algorithms.d.ts +4 -0
  37. package/dist/src/types/algorithms.d.ts.map +1 -1
  38. package/dist/src/types/betweenness.d.ts +35 -0
  39. package/dist/src/types/betweenness.d.ts.map +1 -0
  40. package/dist/src/types/betweenness.js +7 -0
  41. package/dist/src/types/betweenness.js.map +1 -0
  42. package/dist/src/wgsl/bc-backward.wgsl.d.ts +15 -0
  43. package/dist/src/wgsl/bc-backward.wgsl.d.ts.map +1 -0
  44. package/dist/src/wgsl/bc-backward.wgsl.js +34 -0
  45. package/dist/src/wgsl/bc-backward.wgsl.js.map +1 -0
  46. package/dist/src/wgsl/bc-edge-gather.wgsl.d.ts +12 -0
  47. package/dist/src/wgsl/bc-edge-gather.wgsl.d.ts.map +1 -0
  48. package/dist/src/wgsl/bc-edge-gather.wgsl.js +36 -0
  49. package/dist/src/wgsl/bc-edge-gather.wgsl.js.map +1 -0
  50. package/dist/src/wgsl/bc-finalize.wgsl.d.ts +21 -0
  51. package/dist/src/wgsl/bc-finalize.wgsl.d.ts.map +1 -0
  52. package/dist/src/wgsl/bc-finalize.wgsl.js +47 -0
  53. package/dist/src/wgsl/bc-finalize.wgsl.js.map +1 -0
  54. package/dist/src/wgsl/bc-forward-edge.wgsl.d.ts +15 -0
  55. package/dist/src/wgsl/bc-forward-edge.wgsl.d.ts.map +1 -0
  56. package/dist/src/wgsl/bc-forward-edge.wgsl.js +76 -0
  57. package/dist/src/wgsl/bc-forward-edge.wgsl.js.map +1 -0
  58. package/dist/src/wgsl/bc-forward.wgsl.d.ts +23 -0
  59. package/dist/src/wgsl/bc-forward.wgsl.d.ts.map +1 -0
  60. package/dist/src/wgsl/bc-forward.wgsl.js +106 -0
  61. package/dist/src/wgsl/bc-forward.wgsl.js.map +1 -0
  62. package/dist/src/wgsl/bc-gather.wgsl.d.ts +9 -0
  63. package/dist/src/wgsl/bc-gather.wgsl.d.ts.map +1 -0
  64. package/dist/src/wgsl/bc-gather.wgsl.js +20 -0
  65. package/dist/src/wgsl/bc-gather.wgsl.js.map +1 -0
  66. package/dist/src/wgsl/closeness-reduce.wgsl.d.ts +4 -1
  67. package/dist/src/wgsl/closeness-reduce.wgsl.d.ts.map +1 -1
  68. package/dist/src/wgsl/closeness-reduce.wgsl.js +8 -4
  69. package/dist/src/wgsl/closeness-reduce.wgsl.js.map +1 -1
  70. package/dist/src/wgsl/closeness-sweep.wgsl.d.ts +4 -2
  71. package/dist/src/wgsl/closeness-sweep.wgsl.d.ts.map +1 -1
  72. package/dist/src/wgsl/closeness-sweep.wgsl.js +12 -2
  73. package/dist/src/wgsl/closeness-sweep.wgsl.js.map +1 -1
  74. package/dist/webgpu-graph-algorithms.js +1037 -168
  75. package/dist/webgpu-graph-algorithms.js.map +1 -1
  76. package/package.json +5 -5
  77. package/src/accelerator.ts +75 -7
  78. package/src/algorithms/betweenness.ts +739 -0
  79. package/src/algorithms/closeness.ts +124 -32
  80. package/src/constants.ts +8 -0
  81. package/src/index.ts +8 -0
  82. package/src/kernels.ts +169 -10
  83. package/src/primitives/frontier.ts +4 -0
  84. package/src/types/accelerator.ts +18 -6
  85. package/src/types/algorithms.ts +5 -0
  86. package/src/types/betweenness.ts +38 -0
  87. package/src/wgsl/bc-backward.wgsl.ts +33 -0
  88. package/src/wgsl/bc-edge-gather.wgsl.ts +35 -0
  89. package/src/wgsl/bc-finalize.wgsl.ts +46 -0
  90. package/src/wgsl/bc-forward-edge.wgsl.ts +75 -0
  91. package/src/wgsl/bc-forward.wgsl.ts +105 -0
  92. package/src/wgsl/bc-gather.wgsl.ts +19 -0
  93. package/src/wgsl/closeness-reduce.wgsl.ts +8 -4
  94. package/src/wgsl/closeness-sweep.wgsl.ts +12 -2
  95. package/dist/chunks/context-Bi6AhScG.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphty/webgpu-graph-algorithms",
3
- "version": "0.6.13",
3
+ "version": "0.6.15",
4
4
  "description": "WebGPU-accelerated graph algorithms and layouts over the @graphty/graph-format snapshot, for Node (Dawn) and browsers",
5
5
  "author": "Adam Powers <apowers@ato.ms>",
6
6
  "type": "module",
@@ -61,10 +61,10 @@
61
61
  "homepage": "https://github.com/graphty-org/graphty-monorepo/tree/master/webgpu-graph-algorithms#readme",
62
62
  "dependencies": {
63
63
  "@webgpu/types": "^0.1.72",
64
- "@graphty/graph-format": "^1.2.0"
64
+ "@graphty/graph-format": "^1.2.2"
65
65
  },
66
66
  "peerDependencies": {
67
- "@graphty/algorithms": "^1.0.0 || ^2.0.0",
67
+ "@graphty/algorithms": "^1.0.0 || ^2.0.0 || ^3.0.0",
68
68
  "@graphty/graph-format": "^1.0.0",
69
69
  "@graphty/layout": "^1.7.0 || ^2.0.0",
70
70
  "webgpu": ">=0.4.0 <1.0.0"
@@ -95,8 +95,8 @@
95
95
  "vite": "^7.0.5",
96
96
  "vitest": "4.1.11",
97
97
  "webgpu": "0.4.0",
98
- "@graphty/algorithms": "^2.2.0",
99
- "@graphty/layout": "^2.0.0"
98
+ "@graphty/layout": "^2.0.2",
99
+ "@graphty/algorithms": "^3.0.0"
100
100
  },
101
101
  "scripts": {
102
102
  "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json",
@@ -17,6 +17,7 @@
17
17
  import { type F32, type F64, type GraphSnapshot } from "@graphty/graph-format";
18
18
 
19
19
  import { bellmanFord } from "./algorithms/bellman-ford.js";
20
+ import { betweennessCentrality, edgeBetweennessCentrality } from "./algorithms/betweenness.js";
20
21
  import { breadthFirstSearch } from "./algorithms/bfs.js";
21
22
  import { closenessCentrality } from "./algorithms/closeness.js";
22
23
  import { connectedComponents } from "./algorithms/components.js";
@@ -29,14 +30,16 @@ import { createFruchtermanReingold } from "./layouts/fruchterman-reingold.js";
29
30
  import { createSpringElectrical } from "./layouts/spring-electrical.js";
30
31
  import {
31
32
  type AcceleratorOptions,
33
+ type BetweennessAcceleratorOptions,
32
34
  type BfsOptions,
35
+ type ClosenessAcceleratorOptions,
33
36
  type GpuAccelerator,
34
- type HitsOptionsLike,
35
37
  type SsspOptions,
36
38
  } from "./types/accelerator.js";
37
39
  import {
38
40
  type ComponentsOptions,
39
41
  type EigenvectorOptions,
42
+ type GpuClosenessResult,
40
43
  type GpuHitsResult,
41
44
  type GpuLabelResult,
42
45
  type GpuPageRankResult,
@@ -45,6 +48,7 @@ import {
45
48
  type KatzOptions,
46
49
  type PageRankOptions,
47
50
  } from "./types/algorithms.js";
51
+ import { type GpuBetweennessResult, type GpuEdgeScoresResult } from "./types/betweenness.js";
48
52
  import {
49
53
  type ForceAtlas2Stats,
50
54
  type FruchtermanReingoldStats,
@@ -79,6 +83,30 @@ function copyBetweenness(defaults: BetweennessDefaults): BetweennessDefaults {
79
83
  return Object.freeze(copy);
80
84
  }
81
85
 
86
+ /**
87
+ * A betweenness call's options with the accelerator's `algorithms.betweenness` defaults applied: the defaults supply
88
+ * `sources` / `k` only when the call names neither, so a call's own sampling always wins whole. The defaults serve
89
+ * graphs of every size, so they are fitted to this one: a default `sources` list keeps only the indices below
90
+ * `nodeCount` (and then wins over a default `k`), and a default `k` of `nodeCount` or more runs every vertex.
91
+ * @param defaults - the frozen defaults, if any
92
+ * @param options - the call's options
93
+ * @param nodeCount - the snapshot's vertex count
94
+ * @returns the options the driver runs with
95
+ */
96
+ function withBetweennessDefaults(
97
+ defaults: BetweennessDefaults | undefined,
98
+ options: BetweennessAcceleratorOptions | undefined,
99
+ nodeCount: number,
100
+ ): BetweennessAcceleratorOptions | undefined {
101
+ if (defaults === undefined || options?.sources !== undefined || options?.k !== undefined) {
102
+ return options;
103
+ }
104
+ if (defaults.sources !== undefined) {
105
+ return { ...options, sources: defaults.sources.filter((v) => v < nodeCount) };
106
+ }
107
+ return { ...options, k: defaults.k !== undefined && defaults.k < nodeCount ? defaults.k : undefined };
108
+ }
109
+
82
110
  /**
83
111
  * Frozen copy of the algorithms record, one level deeper for `betweenness`.
84
112
  * @param algorithms - the caller's record
@@ -118,8 +146,9 @@ function freezeOptions(options: AcceleratorOptions | undefined): Readonly<Accele
118
146
  * Spec 3.3 createAccelerator, verbatim: the object implementing AlgorithmAccelerator & LayoutAccelerator
119
147
  * structurally; P3's forceAtlas2, release and dispose, P5's fruchtermanReingold and springElectrical (the same
120
148
  * `{ ...o, ...options.layout }` shape as forceAtlas2) plus P7's seven algorithm members and P8's four traversal
121
- * members, each a delegation to its algorithm with `ctx.assertReady()` first. The accelerator's algorithm defaults are not consulted by any of
122
- * them: only `betweenness` has any, and it belongs to P9. One per call (the app creates one and injects
149
+ * members and the two betweenness members, each a delegation to its algorithm with `ctx.assertReady()` first. Only
150
+ * the betweenness members consult the accelerator's algorithm defaults (`algorithms.betweenness` supplies `sources` /
151
+ * `k` when a call names neither). One per call (the app creates one and injects
123
152
  * it, spec 2.4); `kind` is "webgpu"; `options` is a frozen deep copy; `forceAtlas2(o)` is
124
153
  * `createForceAtlas2(ctx, { ...o, ...options.layout })`, so the GPU tuning given here wins over anything the
125
154
  * CPU-typed option object carries (spec 3.3: tuning never comes from the caller of the accelerator method);
@@ -163,7 +192,9 @@ export function createAccelerator(ctx: GpuContext, options?: AcceleratorOptions)
163
192
  * @param o - the CPU option type (spec 9.3 SpringElectricalOptions, ngraph's names)
164
193
  * @returns a fresh simulation in state "created"
165
194
  */
166
- springElectrical(o?: SpringElectricalOptions): GpuLayoutSimulation<SpringElectricalOptions, SpringElectricalStats> {
195
+ springElectrical(
196
+ o?: SpringElectricalOptions,
197
+ ): GpuLayoutSimulation<SpringElectricalOptions, SpringElectricalStats> {
167
198
  ctx.assertReady();
168
199
  return createSpringElectrical(ctx, { ...o, ...frozen.layout });
169
200
  },
@@ -278,14 +309,51 @@ export function createAccelerator(ctx: GpuContext, options?: AcceleratorOptions)
278
309
  ctx.assertReady();
279
310
  return await bellmanFord(ctx, gs, source, o);
280
311
  },
312
+ /**
313
+ * Betweenness centrality on the device (spec 8.4): exact, or sampled through `sources` / `k` (the call's own,
314
+ * else the accelerator's `algorithms.betweenness` defaults), the unscaled sum over the sources run.
315
+ * `endpoints: true` is refused.
316
+ * @param gs - the snapshot
317
+ * @param o - the seam's `BetweennessAcceleratorOptions`
318
+ * @returns the f32 scores with `sourcesUsed` and `sigmaOverflow`
319
+ */
320
+ async betweennessCentrality(
321
+ gs: GraphSnapshot,
322
+ o?: BetweennessAcceleratorOptions,
323
+ ): Promise<GpuBetweennessResult> {
324
+ ctx.assertReady();
325
+ return await betweennessCentrality(
326
+ ctx,
327
+ gs,
328
+ withBetweennessDefaults(frozen.algorithms?.betweenness, o, gs.nodeCount),
329
+ );
330
+ },
331
+ /**
332
+ * Edge betweenness on the device (spec 8.4): one score per edge, arcs summed and halved when undirected; sampling
333
+ * and defaults as `betweennessCentrality`.
334
+ * @param gs - the snapshot
335
+ * @param o - the seam's `BetweennessAcceleratorOptions`
336
+ * @returns the f32 per-edge scores with `sourcesUsed` and `sigmaOverflow`
337
+ */
338
+ async edgeBetweennessCentrality(
339
+ gs: GraphSnapshot,
340
+ o?: BetweennessAcceleratorOptions,
341
+ ): Promise<GpuEdgeScoresResult> {
342
+ ctx.assertReady();
343
+ return await edgeBetweennessCentrality(
344
+ ctx,
345
+ gs,
346
+ withBetweennessDefaults(frozen.algorithms?.betweenness, o, gs.nodeCount),
347
+ );
348
+ },
281
349
  /**
282
350
  * Closeness centrality on the device (spec 8.4; P8-T13): the bit-parallel multi-source sweep, or one `sssp`
283
351
  * per source when `weighted`. `maxIterations` / `tolerance` are refused when defined (P8 PD-25).
284
352
  * @param gs - the snapshot
285
- * @param o - the seam's placeholder `HitsOptionsLike` (`weighted`)
286
- * @returns the f32 scores with `precision: "f32"` (spec 9.7)
353
+ * @param o - `weighted`, and a sampled run's `sources` (undirected snapshots only)
354
+ * @returns the f32 scores with `precision: "f32"` (spec 9.7) and `sourcesUsed`
287
355
  */
288
- async closenessCentrality(gs: GraphSnapshot, o?: HitsOptionsLike): Promise<GpuScoresResult> {
356
+ async closenessCentrality(gs: GraphSnapshot, o?: ClosenessAcceleratorOptions): Promise<GpuClosenessResult> {
289
357
  ctx.assertReady();
290
358
  return await closenessCentrality(ctx, gs, o);
291
359
  },