@graphty/webgpu-graph-algorithms 0.5.0 → 0.5.1

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 (88) hide show
  1. package/README.md +27 -21
  2. package/dist/browser.js +1 -1
  3. package/dist/chunks/{context-CRbw2Wyo.js → context-BR7fx3vR.js} +47 -5
  4. package/dist/chunks/context-BR7fx3vR.js.map +1 -0
  5. package/dist/node.js +1 -1
  6. package/dist/src/accelerator.d.ts +12 -10
  7. package/dist/src/accelerator.d.ts.map +1 -1
  8. package/dist/src/accelerator.js +32 -10
  9. package/dist/src/accelerator.js.map +1 -1
  10. package/dist/src/constants.d.ts +47 -0
  11. package/dist/src/constants.d.ts.map +1 -1
  12. package/dist/src/constants.js +47 -0
  13. package/dist/src/constants.js.map +1 -1
  14. package/dist/src/index.d.ts +7 -4
  15. package/dist/src/index.d.ts.map +1 -1
  16. package/dist/src/index.js +9 -5
  17. package/dist/src/index.js.map +1 -1
  18. package/dist/src/kernel/prelude.d.ts.map +1 -1
  19. package/dist/src/kernel/prelude.js +4 -1
  20. package/dist/src/kernel/prelude.js.map +1 -1
  21. package/dist/src/kernels.d.ts +3 -3
  22. package/dist/src/kernels.d.ts.map +1 -1
  23. package/dist/src/kernels.js +27 -11
  24. package/dist/src/kernels.js.map +1 -1
  25. package/dist/src/layouts/force-simulation.d.ts +3 -1
  26. package/dist/src/layouts/force-simulation.d.ts.map +1 -1
  27. package/dist/src/layouts/force-simulation.js +13 -3
  28. package/dist/src/layouts/force-simulation.js.map +1 -1
  29. package/dist/src/layouts/forceatlas2.d.ts +1 -3
  30. package/dist/src/layouts/forceatlas2.d.ts.map +1 -1
  31. package/dist/src/layouts/forceatlas2.js +2 -191
  32. package/dist/src/layouts/forceatlas2.js.map +1 -1
  33. package/dist/src/layouts/fruchterman-reingold.d.ts +195 -0
  34. package/dist/src/layouts/fruchterman-reingold.d.ts.map +1 -0
  35. package/dist/src/layouts/fruchterman-reingold.js +579 -0
  36. package/dist/src/layouts/fruchterman-reingold.js.map +1 -0
  37. package/dist/src/layouts/model-common.d.ts +102 -0
  38. package/dist/src/layouts/model-common.d.ts.map +1 -0
  39. package/dist/src/layouts/model-common.js +198 -0
  40. package/dist/src/layouts/model-common.js.map +1 -0
  41. package/dist/src/layouts/spring-electrical.d.ts +179 -0
  42. package/dist/src/layouts/spring-electrical.d.ts.map +1 -0
  43. package/dist/src/layouts/spring-electrical.js +508 -0
  44. package/dist/src/layouts/spring-electrical.js.map +1 -0
  45. package/dist/src/types/accelerator.d.ts +7 -3
  46. package/dist/src/types/accelerator.d.ts.map +1 -1
  47. package/dist/src/types/layout.d.ts +32 -0
  48. package/dist/src/types/layout.d.ts.map +1 -1
  49. package/dist/src/types/options.d.ts +43 -1
  50. package/dist/src/types/options.d.ts.map +1 -1
  51. package/dist/src/wgsl/fa2-attraction.wgsl.d.ts +5 -2
  52. package/dist/src/wgsl/fa2-attraction.wgsl.d.ts.map +1 -1
  53. package/dist/src/wgsl/fa2-attraction.wgsl.js +6 -1
  54. package/dist/src/wgsl/fa2-attraction.wgsl.js.map +1 -1
  55. package/dist/src/wgsl/fa2-integrate.wgsl.d.ts +7 -2
  56. package/dist/src/wgsl/fa2-integrate.wgsl.d.ts.map +1 -1
  57. package/dist/src/wgsl/fa2-integrate.wgsl.js +28 -2
  58. package/dist/src/wgsl/fa2-integrate.wgsl.js.map +1 -1
  59. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.d.ts +4 -2
  60. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.d.ts.map +1 -1
  61. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.js +14 -5
  62. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.js.map +1 -1
  63. package/dist/src/wgsl/fa2-stats-finalize.wgsl.d.ts +8 -1
  64. package/dist/src/wgsl/fa2-stats-finalize.wgsl.d.ts.map +1 -1
  65. package/dist/src/wgsl/fa2-stats-finalize.wgsl.js +33 -0
  66. package/dist/src/wgsl/fa2-stats-finalize.wgsl.js.map +1 -1
  67. package/dist/tsconfig.build.tsbuildinfo +1 -1
  68. package/dist/webgpu-graph-algorithms.js +1358 -284
  69. package/dist/webgpu-graph-algorithms.js.map +1 -1
  70. package/package.json +6 -4
  71. package/src/accelerator.ts +46 -12
  72. package/src/constants.ts +70 -0
  73. package/src/index.ts +15 -5
  74. package/src/kernel/prelude.ts +6 -0
  75. package/src/kernels.ts +27 -11
  76. package/src/layouts/force-simulation.ts +20 -3
  77. package/src/layouts/forceatlas2.ts +17 -220
  78. package/src/layouts/fruchterman-reingold.ts +737 -0
  79. package/src/layouts/model-common.ts +228 -0
  80. package/src/layouts/spring-electrical.ts +666 -0
  81. package/src/types/accelerator.ts +15 -3
  82. package/src/types/layout.ts +36 -0
  83. package/src/types/options.ts +45 -1
  84. package/src/wgsl/fa2-attraction.wgsl.ts +6 -1
  85. package/src/wgsl/fa2-integrate.wgsl.ts +28 -2
  86. package/src/wgsl/fa2-repulsion-exact.wgsl.ts +14 -5
  87. package/src/wgsl/fa2-stats-finalize.wgsl.ts +33 -0
  88. package/dist/chunks/context-CRbw2Wyo.js.map +0 -1
package/README.md CHANGED
@@ -274,8 +274,10 @@ lane's own artifact; `bench:compare` skips when the card was not quiet during th
274
274
  `roundtrip` (T-2, T-3), `layout-exact` (T-4 and the Node side of T-5: `step(1)` on the exact ladder 1k / 4k / 8k / 16k /
275
275
  32k / 65k and at 10k, two rows per rung -- the wall time of one iteration with its readback, and the GPU time per iteration
276
276
  the profiler reports; every rung starts with an untimed clock warm-up burst, because NVIDIA's power management leaves the
277
- SM clock at its idle 210 MHz under sparse sub-millisecond dispatches and the kernels then measure 4-15x slower). The
278
- Chromium number of T-5 comes from the `bench`-tagged browser test (`GRAPHTY_BROWSER_GPU=nvidia node
277
+ SM clock at its idle 210 MHz under sparse sub-millisecond dispatches and the kernels then measure 4-15x slower),
278
+ `pagerank` (T-8), `wcc` (T-9), `layout-fr` (T-14: `step(1)` of `createFruchtermanReingold` and `createSpringElectrical`
279
+ at 10k and at 100k with `repulsion: "exact"`, the same two rows per model and rung as `layout-exact`, tagged `fr` /
280
+ `se`). The Chromium number of T-5 comes from the `bench`-tagged browser test (`GRAPHTY_BROWSER_GPU=nvidia node
279
281
  scripts/run-browser-project.js`), which appends its session through the Vitest commands bridge. `exactMaxNodes` is
280
282
  re-fixed from the ladder by the rule of plan section 7.8 (the largest rung under 4 ms per iteration, rounded down to a
281
283
  power of two; `benchmarks/layout-exact.bench.ts` `exactMaxNodesFromLadder`).
@@ -291,15 +293,16 @@ are the T-table of plan section 10.4. A missed target is re-fixed by a recorded
291
293
 
292
294
  Measured on nvidia-lovelace-driver580 (NVIDIA: 580.173.02 580.173.2.0), session 2026-09-20T01:06:48.656Z, medians of 5 runs; Chromium: nvidia / lovelace (nvidia-lovelace-driver0, the description is redacted by Chromium), session 2026-09-16T02:18:11.896Z.
293
295
 
294
- | Id | What | Target | Measured |
295
- | --- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ---------------------- |
296
- | T-1 | Upload of the 100k / 1M weighted hot prefix (16.4 MB); 1M / 10M (164 MB) | <= 10 ms; <= 100 ms | 5.980 ms; 125.738 ms |
297
- | T-2 | `degree` + 400 KB readback at 100k (core resident), Node | <= 2 ms | 0.870 ms |
298
- | T-3 | Empty submit + 4-byte `readU32` round trip, Dawn | <= 0.1 ms | 0.181 ms |
299
- | T-4 | ForceAtlas2 exact tier, GPU time per iteration (profiler) at 10k; at 16k | <= 1 ms; <= 2 ms | 0.586 ms; 1.053 ms |
300
- | T-5 | ForceAtlas2 per-frame cost, `step(1)` + the 12n readback at 10k, Chromium (Node in brackets) | <= 6 ms | 2.400 ms (0.726 ms) |
301
- | T-8 | PageRank, 100 iterations, wall end to end including the upload, at 100k / 1M; at 1M / 10M | <= 150 ms; <= 1.5 s | 17.204 ms; 198.645 ms |
302
- | T-9 | Weakly connected components (Afforest), wall end to end including the upload and the label readback, at 1M / 10M (100k / 1M in brackets) | <= 100 ms | 145.970 ms (12.613 ms) |
296
+ | Id | What | Target | Measured |
297
+ | ---- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ---------------------- |
298
+ | T-1 | Upload of the 100k / 1M weighted hot prefix (16.4 MB); 1M / 10M (164 MB) | <= 10 ms; <= 100 ms | 5.980 ms; 125.738 ms |
299
+ | T-2 | `degree` + 400 KB readback at 100k (core resident), Node | <= 2 ms | 0.870 ms |
300
+ | T-3 | Empty submit + 4-byte `readU32` round trip, Dawn | <= 0.1 ms | 0.181 ms |
301
+ | T-4 | ForceAtlas2 exact tier, GPU time per iteration (profiler) at 10k; at 16k | <= 1 ms; <= 2 ms | 0.586 ms; 1.053 ms |
302
+ | T-5 | ForceAtlas2 per-frame cost, `step(1)` + the 12n readback at 10k, Chromium (Node in brackets) | <= 6 ms | 2.400 ms (0.726 ms) |
303
+ | T-8 | PageRank, 100 iterations, wall end to end including the upload, at 100k / 1M; at 1M / 10M | <= 150 ms; <= 1.5 s | 17.204 ms; 198.645 ms |
304
+ | T-9 | Weakly connected components (Afforest), wall end to end including the upload and the label readback, at 1M / 10M (100k / 1M in brackets) | <= 100 ms | 145.970 ms (12.613 ms) |
305
+ | T-14 | Fruchterman-Reingold exact tier, GPU time per iteration (profiler) at 10k; at 100k (`repulsion: "exact"`) | recorded | 0.617 ms; 16.367 ms |
303
306
 
304
307
  Three rows miss their target in this session: the 1M / 10M upload (125.7 ms against 100 ms, the open owner decision of
305
308
  `docs/decisions/G1.md` section 7), the empty-submit round trip (0.181 ms against 0.1 ms: the row is measured after the
@@ -309,7 +312,9 @@ the working clock -- finding G3-F2 of `docs/decisions/G3.md` section 10), and WC
309
312
  with the core resident the same call takes 11-16 ms). The T-9 target is therefore below
310
313
  the T-1 upload it includes, an owner decision for `docs/decisions/G7.md`. The `pagerank` rows run all 100 iterations
311
314
  (`tolerance: 0`): at the NetworkX tolerance of 1e-6 the seeded G(n, m) input converges from the uniform start in one to
312
- four iterations, which would time one pull and call it a hundred.
315
+ four iterations, which would time one pull and call it a hundred. The T-14 row is the `layout-fr` group of the later
316
+ session 2026-09-20T19:25:37.311Z (the file's last session, the current baseline), whose other rows are within 1.08x of
317
+ this table's; the spring-electrical preset measures 0.648 ms at 10k and 18.154 ms at 100k in the same session.
313
318
 
314
319
  The exact curve (the `layout-exact` group: 2D, E = 10n, seeded G(n, m), one simulation per rung; ms / iteration from the profiler):
315
320
 
@@ -338,15 +343,16 @@ RTX 4070 SUPER's at 10k and 3.0x at 65k.
338
343
 
339
344
  Measured on gpu-linux-t4 (NVIDIA: 580.126.20 580.126.20.0), session 2026-09-20T02:29:33.210Z (run 35483512705), medians of 5 runs; Chromium: nvidia / turing (nvidia-turing-driver0, the description is redacted by Chromium), session 2026-09-20T02:28:10.676Z.
340
345
 
341
- | Id | What | Target | Measured |
342
- | --- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ---------------------- |
343
- | T-1 | Upload of the 100k / 1M weighted hot prefix (16.4 MB); 1M / 10M (164 MB) | <= 10 ms; <= 100 ms | 14.338 ms; 256.418 ms |
344
- | T-2 | `degree` + 400 KB readback at 100k (core resident), Node | <= 2 ms | 2.957 ms |
345
- | T-3 | Empty submit + 4-byte `readU32` round trip, Dawn | <= 0.1 ms | 1.296 ms |
346
- | T-4 | ForceAtlas2 exact tier, GPU time per iteration (profiler) at 10k; at 16k | <= 1 ms; <= 2 ms | 0.972 ms; 1.953 ms |
347
- | T-5 | ForceAtlas2 per-frame cost, `step(1)` + the 12n readback at 10k, Chromium (Node in brackets) | <= 6 ms | 2.600 ms (1.359 ms) |
348
- | T-8 | PageRank, 100 iterations, wall end to end including the upload, at 100k / 1M; at 1M / 10M | <= 150 ms; <= 1.5 s | 45.461 ms; 1092.799 ms |
349
- | T-9 | Weakly connected components (Afforest), wall end to end including the upload and the label readback, at 1M / 10M (100k / 1M in brackets) | <= 100 ms | 293.079 ms (28.544 ms) |
346
+ | Id | What | Target | Measured |
347
+ | ---- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
348
+ | T-1 | Upload of the 100k / 1M weighted hot prefix (16.4 MB); 1M / 10M (164 MB) | <= 10 ms; <= 100 ms | 14.338 ms; 256.418 ms |
349
+ | T-2 | `degree` + 400 KB readback at 100k (core resident), Node | <= 2 ms | 2.957 ms |
350
+ | T-3 | Empty submit + 4-byte `readU32` round trip, Dawn | <= 0.1 ms | 1.296 ms |
351
+ | T-4 | ForceAtlas2 exact tier, GPU time per iteration (profiler) at 10k; at 16k | <= 1 ms; <= 2 ms | 0.972 ms; 1.953 ms |
352
+ | T-5 | ForceAtlas2 per-frame cost, `step(1)` + the 12n readback at 10k, Chromium (Node in brackets) | <= 6 ms | 2.600 ms (1.359 ms) |
353
+ | T-8 | PageRank, 100 iterations, wall end to end including the upload, at 100k / 1M; at 1M / 10M | <= 150 ms; <= 1.5 s | 45.461 ms; 1092.799 ms |
354
+ | T-9 | Weakly connected components (Afforest), wall end to end including the upload and the label readback, at 1M / 10M (100k / 1M in brackets) | <= 100 ms | 293.079 ms (28.544 ms) |
355
+ | T-14 | Fruchterman-Reingold exact tier, GPU time per iteration (profiler) at 10k; at 100k (`repulsion: "exact"`) | recorded | 0.942 ms; 54.232 ms (the spring preset 1.051 ms; 60.706 ms) |
350
356
 
351
357
  The exact curve (the `layout-exact` group: 2D, E = 10n, seeded G(n, m), one simulation per rung; ms / iteration from the profiler):
352
358
 
package/dist/browser.js CHANGED
@@ -1,4 +1,4 @@
1
- import { G as GpuContext, W as WebGpuGraphError } from "./chunks/context-CRbw2Wyo.js";
1
+ import { G as GpuContext, W as WebGpuGraphError } from "./chunks/context-BR7fx3vR.js";
2
2
  function navigatorGpu() {
3
3
  if (typeof navigator === "undefined") {
4
4
  return void 0;
@@ -49,6 +49,38 @@ const FA2_DISTANCE_FLOOR = 0.01;
49
49
  const FA2_DISTANCE_FLOOR_SQ = 1e-4;
50
50
  const FA2_COINCIDENT_SQ = 1e-8;
51
51
  const FA2_FLAG_FIRST = 1;
52
+ const FA2_FLAG_ADAPTIVE = 2;
53
+ const FR_START_TEMPERATURE = 0.1;
54
+ const FR_REHEAT_FRACTION = 0.7;
55
+ const FR_COOLING_STEP = 0.9;
56
+ const FR_COOLING_PATIENCE = 5;
57
+ const FR_ADAPTIVE_MAX_ITERATIONS = 1e4;
58
+ const FR_DEFAULTS = Object.freeze({
59
+ k: null,
60
+ iterations: 50,
61
+ fixed: null,
62
+ dim: 2,
63
+ scale: 1,
64
+ settleThreshold: 1e-3,
65
+ settleWindow: 10,
66
+ iterationsPerStep: 1,
67
+ maxInFlight: 2,
68
+ cooling: "linear"
69
+ });
70
+ const SE_SCALE_REFERENCE_NODES = 300;
71
+ const SE_DEFAULTS = Object.freeze({
72
+ springLength: 10,
73
+ springCoefficient: 0.8,
74
+ gravity: -12,
75
+ dragCoefficient: 0.9,
76
+ timeStep: 0.5,
77
+ dim: 2,
78
+ scale: 1,
79
+ settleThreshold: 1e-3,
80
+ settleWindow: 10,
81
+ iterationsPerStep: 1,
82
+ maxInFlight: 2
83
+ });
52
84
  const PASSTHROUGH_FORMAT_CODES = Object.freeze(["E_GPU_INELIGIBLE", "E_UNKNOWN_NODE", "E_UNKNOWN_COLUMN", "E_COLUMN_LENGTH"]);
53
85
  const EMPTY_DETAILS = Object.freeze({});
54
86
  class WebGpuGraphError extends Error {
@@ -807,6 +839,9 @@ const FA2_DIST_FLOOR: f32 = ${wgslF32Literal(FA2_DISTANCE_FLOOR)};
807
839
  const FA2_DIST_FLOOR_SQ: f32 = ${wgslF32Literal(FA2_DISTANCE_FLOOR_SQ)};
808
840
  const FA2_COINCIDENT_SQ: f32 = ${wgslF32Literal(FA2_COINCIDENT_SQ)};
809
841
  const FA2_FLAG_FIRST: u32 = ${FA2_FLAG_FIRST}u;
842
+ const FA2_FLAG_ADAPTIVE: u32 = ${FA2_FLAG_ADAPTIVE}u;
843
+ const FR_COOLING_STEP: f32 = ${wgslF32Literal(FR_COOLING_STEP)};
844
+ const FR_COOLING_PATIENCE: u32 = ${FR_COOLING_PATIENCE}u;
810
845
  const F32_MAX: f32 = 0x1.fffffep+127;
811
846
  override WG: u32 = ${WORKGROUP_SIZE}u;
812
847
  override USE_PERM: bool = false;
@@ -3285,11 +3320,18 @@ export {
3285
3320
  deviceLostError as d,
3286
3321
  MAX_1D_ITEMS as e,
3287
3322
  FA2_FLAG_FIRST as f,
3288
- PASSTHROUGH_FORMAT_CODES as g,
3323
+ FR_ADAPTIVE_MAX_ITERATIONS as g,
3289
3324
  hasErrorCode as h,
3290
3325
  isWebGpuGraphError as i,
3291
- STORAGE_ALIGN as j,
3292
- WORKGROUP_SIZE as k,
3293
- isSoftwareAdapter as l
3326
+ FR_START_TEMPERATURE as j,
3327
+ FA2_FLAG_ADAPTIVE as k,
3328
+ FR_REHEAT_FRACTION as l,
3329
+ FR_DEFAULTS as m,
3330
+ SE_DEFAULTS as n,
3331
+ SE_SCALE_REFERENCE_NODES as o,
3332
+ PASSTHROUGH_FORMAT_CODES as p,
3333
+ STORAGE_ALIGN as q,
3334
+ WORKGROUP_SIZE as r,
3335
+ isSoftwareAdapter as s
3294
3336
  };
3295
- //# sourceMappingURL=context-CRbw2Wyo.js.map
3337
+ //# sourceMappingURL=context-BR7fx3vR.js.map