graphwise 1.11.0 → 1.12.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.
Files changed (50) hide show
  1. package/README.md +1 -1
  2. package/dist/gpu/index.cjs +1 -1
  3. package/dist/gpu/index.js +1 -1
  4. package/dist/index/index.cjs +7 -3
  5. package/dist/index/index.js +4 -4
  6. package/dist/{kernel-CigCjrts.js → kernel-BLwhyVSV.js} +1 -1
  7. package/dist/{kernel-CigCjrts.js.map → kernel-BLwhyVSV.js.map} +1 -1
  8. package/dist/{kernel-2oH4Cn32.cjs → kernel-BffKjhZS.cjs} +1 -1
  9. package/dist/{kernel-2oH4Cn32.cjs.map → kernel-BffKjhZS.cjs.map} +1 -1
  10. package/dist/{kernel-CXeGBH3s.cjs → kernel-CbP715Sq.cjs} +1 -1
  11. package/dist/{kernel-CXeGBH3s.cjs.map → kernel-CbP715Sq.cjs.map} +1 -1
  12. package/dist/{kernel-CvnRsF7E.js → kernel-DolEKSSx.js} +1 -1
  13. package/dist/{kernel-CvnRsF7E.js.map → kernel-DolEKSSx.js.map} +1 -1
  14. package/dist/{kernel-DukrXtVb.cjs → kernel-E_h47HjZ.cjs} +1 -1
  15. package/dist/{kernel-DukrXtVb.cjs.map → kernel-E_h47HjZ.cjs.map} +1 -1
  16. package/dist/{kernel-6deK9fh1.js → kernel-lYa4TYth.js} +1 -1
  17. package/dist/{kernel-6deK9fh1.js.map → kernel-lYa4TYth.js.map} +1 -1
  18. package/dist/{operations-D-RB67WP.cjs → operations-CSU0yFPr.cjs} +4 -4
  19. package/dist/{operations-D-RB67WP.cjs.map → operations-CSU0yFPr.cjs.map} +1 -1
  20. package/dist/{operations-D9otVlIH.js → operations-CdrA87Au.js} +4 -4
  21. package/dist/{operations-D9otVlIH.js.map → operations-CdrA87Au.js.map} +1 -1
  22. package/dist/ranking/index.cjs +1 -1
  23. package/dist/ranking/index.js +1 -1
  24. package/dist/{ranking-pe5UaxKg.cjs → ranking-BQqrH26-.cjs} +2 -2
  25. package/dist/{ranking-pe5UaxKg.cjs.map → ranking-BQqrH26-.cjs.map} +1 -1
  26. package/dist/{ranking-DOKDBcIR.js → ranking-B_KdM8Wq.js} +2 -2
  27. package/dist/{ranking-DOKDBcIR.js.map → ranking-B_KdM8Wq.js.map} +1 -1
  28. package/dist/seeds/basil.d.ts +12 -0
  29. package/dist/seeds/basil.d.ts.map +1 -0
  30. package/dist/seeds/brisk.d.ts +18 -0
  31. package/dist/seeds/brisk.d.ts.map +1 -0
  32. package/dist/seeds/hybrid-core.d.ts +32 -0
  33. package/dist/seeds/hybrid-core.d.ts.map +1 -0
  34. package/dist/seeds/hybrid-ensembles.unit.test.d.ts +2 -0
  35. package/dist/seeds/hybrid-ensembles.unit.test.d.ts.map +1 -0
  36. package/dist/seeds/index.cjs +11 -1108
  37. package/dist/seeds/index.d.ts +4 -0
  38. package/dist/seeds/index.d.ts.map +1 -1
  39. package/dist/seeds/index.js +2 -1103
  40. package/dist/seeds/omnia.d.ts +12 -0
  41. package/dist/seeds/omnia.d.ts.map +1 -0
  42. package/dist/seeds/prism.d.ts +12 -0
  43. package/dist/seeds/prism.d.ts.map +1 -0
  44. package/dist/seeds--fLhoBaG.cjs +1762 -0
  45. package/dist/seeds--fLhoBaG.cjs.map +1 -0
  46. package/dist/seeds-ihozTw4J.js +1703 -0
  47. package/dist/seeds-ihozTw4J.js.map +1 -0
  48. package/package.json +1 -1
  49. package/dist/seeds/index.cjs.map +0 -1
  50. package/dist/seeds/index.js.map +0 -1
package/README.md CHANGED
@@ -11,7 +11,7 @@ Low-dependency TypeScript graph algorithms for citation network analysis: novel
11
11
  - **Expansion algorithms**: BASE, DOME, EDGE, HAE, PIPE, SAGE, REACH, MAZE + 6 variants (TIDE, LACE, WARP, FUSE, SIFT, FLUX) + baselines
12
12
  - **MI variants**: Jaccard, Adamic-Adar, SCALE, SKEW, SPAN, ETCH, NOTCH, Unified Adaptive
13
13
  - **Path ranking**: PARSE + baselines (Katz, Communicability, PageRank, etc.)
14
- - **Seed selection**: GRASP, Stratified
14
+ - **Seed selection**: GRASP, STRIDE, CREST, SPINE, CRISP, BRISK, BASIL, PRISM, OMNIA, Stratified
15
15
  - **Subgraph extraction**: ego-network, k-core, k-truss, motif, induced, filter
16
16
  - **Optional WebGPU acceleration**
17
17
  - **Async support**: Generator coroutine protocol, sync/async runners, all algorithms available as `*Async` variants
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_typegpu = require("../typegpu-Dq5FfUB8.cjs");
3
3
  const require_logic = require("../logic-Dbyfb_-7.cjs");
4
- const require_operations = require("../operations-D-RB67WP.cjs");
4
+ const require_operations = require("../operations-CSU0yFPr.cjs");
5
5
  //#region src/gpu/csr-graph.ts
6
6
  /**
7
7
  * A ReadableGraph implementation backed by CSR arrays.
package/dist/gpu/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { r as tgpu_exports } from "../typegpu-DwnJf28i.js";
2
2
  import { c as graphToCSR, s as csrToTypedBuffers } from "../logic-DyBzRg1A.js";
3
- import { a as gpuMIBatch, c as withBackend, d as detectWebGPU, f as isWebGPUAvailable, i as gpuKMeansAssign, l as GPUNotAvailableError, n as gpuDegreeHistogram, o as gpuPageRank, r as gpuJaccardBatch, s as gpuSpmv, t as gpuBfsLevels, u as assertWebGPUAvailable } from "../operations-D9otVlIH.js";
3
+ import { a as gpuMIBatch, c as withBackend, d as detectWebGPU, f as isWebGPUAvailable, i as gpuKMeansAssign, l as GPUNotAvailableError, n as gpuDegreeHistogram, o as gpuPageRank, r as gpuJaccardBatch, s as gpuSpmv, t as gpuBfsLevels, u as assertWebGPUAvailable } from "../operations-CdrA87Au.js";
4
4
  //#region src/gpu/csr-graph.ts
5
5
  /**
6
6
  * A ReadableGraph implementation backed by CSR arrays.
@@ -11,10 +11,10 @@ const require_logic = require("../logic-Dbyfb_-7.cjs");
11
11
  const require_kmeans = require("../kmeans-CZ7tJFYw.cjs");
12
12
  const require_utils$1 = require("../utils/index.cjs");
13
13
  const require_jaccard = require("../jaccard-Bdw4B0i4.cjs");
14
- const require_ranking = require("../ranking-pe5UaxKg.cjs");
14
+ const require_ranking = require("../ranking-BQqrH26-.cjs");
15
15
  const require_ranking_mi = require("../ranking/mi/index.cjs");
16
- const require_operations = require("../operations-D-RB67WP.cjs");
17
- const require_seeds = require("../seeds/index.cjs");
16
+ const require_operations = require("../operations-CSU0yFPr.cjs");
17
+ const require_seeds = require("../seeds--fLhoBaG.cjs");
18
18
  const require_extraction = require("../extraction/index.cjs");
19
19
  const require_gpu = require("../gpu/index.cjs");
20
20
  const require_async = require("../async/index.cjs");
@@ -31,10 +31,12 @@ exports.approximateClusteringCoefficient = require_utils$1.approximateClustering
31
31
  exports.assertWebGPUAvailable = require_operations.assertWebGPUAvailable;
32
32
  exports.base = require_expansion.base;
33
33
  exports.baseAsync = require_expansion.baseAsync;
34
+ exports.basil = require_seeds.basil;
34
35
  exports.batchClusteringCoefficients = require_utils$1.batchClusteringCoefficients;
35
36
  exports.betweenness = require_ranking.betweenness;
36
37
  exports.bfs = require_traversal.bfs;
37
38
  exports.bfsWithPath = require_traversal.bfsWithPath;
39
+ exports.brisk = require_seeds.brisk;
38
40
  exports.collectAsyncIterable = require_utils.collectAsyncIterable;
39
41
  exports.communicability = require_ranking.communicability;
40
42
  exports.communicabilityAsync = require_ranking.communicabilityAsync;
@@ -122,6 +124,7 @@ exports.zScoreNormalise = require_kmeans.normaliseFeatures;
122
124
  exports.normalisedEntropy = require_utils$1.normalisedEntropy;
123
125
  exports.notch = require_ranking_mi.notch;
124
126
  exports.notchAsync = require_ranking_mi.notchAsync;
127
+ exports.omnia = require_seeds.omnia;
125
128
  exports.opBatchDegree = require_ops.opBatchDegree;
126
129
  exports.opBatchNeighbours = require_ops.opBatchNeighbours;
127
130
  exports.opDegree = require_ops.opDegree;
@@ -139,6 +142,7 @@ exports.parse = require_ranking.parse;
139
142
  exports.parseAsync = require_ranking.parseAsync;
140
143
  exports.pipe = require_expansion.pipe;
141
144
  exports.pipeAsync = require_expansion.pipeAsync;
145
+ exports.prism = require_seeds.prism;
142
146
  exports.randomPriority = require_expansion.randomPriority;
143
147
  exports.randomPriorityAsync = require_expansion.randomPriorityAsync;
144
148
  exports.randomRanking = require_ranking.randomRanking;
@@ -10,11 +10,11 @@ import { c as graphToCSR, s as csrToTypedBuffers } from "../logic-DyBzRg1A.js";
10
10
  import { n as miniBatchKMeans, r as normaliseFeatures, t as _computeMean } from "../kmeans-DLrlrp6i.js";
11
11
  import { approximateClusteringCoefficient, batchClusteringCoefficients, computeJaccard, countEdgesOfType, countNodesOfType, entropyFromCounts, localClusteringCoefficient, localTypeEntropy, neighbourIntersection, neighbourOverlap, neighbourSet, normalisedEntropy, shannonEntropy } from "../utils/index.js";
12
12
  import { n as jaccardAsync, t as jaccard } from "../jaccard-BwC_NuQu.js";
13
- import { a as communicabilityAsync, c as betweenness, d as jaccardArithmetic, f as widestPath, g as parseAsync, h as parse, i as communicability, l as pagerank, m as shortest, n as randomRanking, o as katz, p as degreeSum, r as resistanceDistance, s as katzAsync, t as hittingTime, u as pagerankAsync } from "../ranking-DOKDBcIR.js";
13
+ import { a as communicabilityAsync, c as betweenness, d as jaccardArithmetic, f as widestPath, g as parseAsync, h as parse, i as communicability, l as pagerank, m as shortest, n as randomRanking, o as katz, p as degreeSum, r as resistanceDistance, s as katzAsync, t as hittingTime, u as pagerankAsync } from "../ranking-B_KdM8Wq.js";
14
14
  import { adamicAdar, adamicAdarAsync, adaptive, adaptiveAsync, cosine, cosineAsync, etch, etchAsync, hubPromoted, hubPromotedAsync, notch, notchAsync, overlapCoefficient, overlapCoefficientAsync, resourceAllocation, resourceAllocationAsync, scale, scaleAsync, skew, skewAsync, sorensen, sorensenAsync, span, spanAsync } from "../ranking/mi/index.js";
15
- import { a as gpuMIBatch, c as withBackend, d as detectWebGPU, f as isWebGPUAvailable, i as gpuKMeansAssign, l as GPUNotAvailableError, n as gpuDegreeHistogram, o as gpuPageRank, r as gpuJaccardBatch, s as gpuSpmv, t as gpuBfsLevels, u as assertWebGPUAvailable } from "../operations-D9otVlIH.js";
16
- import { crest, crisp, grasp, spine, stratified, stride } from "../seeds/index.js";
15
+ import { a as gpuMIBatch, c as withBackend, d as detectWebGPU, f as isWebGPUAvailable, i as gpuKMeansAssign, l as GPUNotAvailableError, n as gpuDegreeHistogram, o as gpuPageRank, r as gpuJaccardBatch, s as gpuSpmv, t as gpuBfsLevels, u as assertWebGPUAvailable } from "../operations-CdrA87Au.js";
16
+ import { a as basil, c as grasp, i as brisk, l as crisp, n as prism, o as stride, r as omnia, s as spine, t as stratified, u as crest } from "../seeds-ihozTw4J.js";
17
17
  import { computeTrussNumbers, enumerateMotifs, enumerateMotifsWithInstances, extractEgoNetwork, extractInducedSubgraph, extractKCore, extractKTruss, filterSubgraph, getMotifName } from "../extraction/index.js";
18
18
  import { CSRReadableGraph, initGPU, initGPUFromDevice } from "../gpu/index.js";
19
19
  import { runBatched } from "../async/index.js";
20
- export { AdjacencyMapGraph, CSRReadableGraph, GPUNotAvailableError, PriorityQueue, _computeMean, adamicAdar, adamicAdarAsync, adaptive, adaptiveAsync, approximateClusteringCoefficient, assertWebGPUAvailable, base, baseAsync, batchClusteringCoefficients, betweenness, bfs, bfsWithPath, collectAsyncIterable, communicability, communicabilityAsync, computeJaccard, computeTrussNumbers, cosine, cosineAsync, countEdgesOfType, countNodesOfType, createFuseBatchPriority, createSiftBatchPriority, crest, crisp, csrToTypedBuffers, defaultYieldStrategy, degreeSum, detectWebGPU, dfs, dfsPriority, dfsPriorityAsync, dfsPriorityFn, dfsWithPath, dome, domeAsync, domeHighDegree, domeHighDegreeAsync, edge, edgeAsync, entropyFromCounts, enumerateMotifs, enumerateMotifsWithInstances, etch, etchAsync, extractEgoNetwork, extractInducedSubgraph, extractKCore, extractKTruss, filterSubgraph, flux, fluxAsync, frontierBalanced, frontierBalancedAsync, fuse, fuseAsync, fuseBatchPriority, fuseWithBatchPriority, getMotifName, gpuBfsLevels, gpuDegreeHistogram, gpuJaccardBatch, gpuKMeansAssign, gpuMIBatch, gpuPageRank, gpuSpmv, graphToCSR, grasp, hae, haeAsync, hittingTime, hubPromoted, hubPromotedAsync, initGPU, initGPUFromDevice, isWebGPUAvailable, jaccard, jaccardArithmetic, jaccardAsync, kHop, katz, katzAsync, lace, laceAsync, laceBatchPriority, laceWithBatchPriority, localClusteringCoefficient, localTypeEntropy, maze, mazeAsync, miniBatchKMeans, neighbourIntersection, neighbourOverlap, neighbourSet, normaliseFeatures, normaliseFeatures as zScoreNormalise, normalisedEntropy, notch, notchAsync, opBatchDegree, opBatchNeighbours, opDegree, opGetEdge, opGetNode, opHasNode, opNeighbours, opProgress, opYield, overlapCoefficient, overlapCoefficientAsync, pagerank, pagerankAsync, parse, parseAsync, pipe, pipeAsync, randomPriority, randomPriorityAsync, randomRanking, randomWalk, reach, reachAsync, resistanceDistance, resolveAsyncOp, resolveSyncOp, resourceAllocation, resourceAllocationAsync, runAsync, runBatched, runSync, sage, sageAsync, scale, scaleAsync, shannonEntropy, shortest, sift, siftAsync, siftBatchPriority, siftWithBatchPriority, skew, skewAsync, sorensen, sorensenAsync, span, spanAsync, spine, standardBfs, standardBfsAsync, stratified, stride, tide, tideAsync, warp, warpAsync, widestPath, withBackend };
20
+ export { AdjacencyMapGraph, CSRReadableGraph, GPUNotAvailableError, PriorityQueue, _computeMean, adamicAdar, adamicAdarAsync, adaptive, adaptiveAsync, approximateClusteringCoefficient, assertWebGPUAvailable, base, baseAsync, basil, batchClusteringCoefficients, betweenness, bfs, bfsWithPath, brisk, collectAsyncIterable, communicability, communicabilityAsync, computeJaccard, computeTrussNumbers, cosine, cosineAsync, countEdgesOfType, countNodesOfType, createFuseBatchPriority, createSiftBatchPriority, crest, crisp, csrToTypedBuffers, defaultYieldStrategy, degreeSum, detectWebGPU, dfs, dfsPriority, dfsPriorityAsync, dfsPriorityFn, dfsWithPath, dome, domeAsync, domeHighDegree, domeHighDegreeAsync, edge, edgeAsync, entropyFromCounts, enumerateMotifs, enumerateMotifsWithInstances, etch, etchAsync, extractEgoNetwork, extractInducedSubgraph, extractKCore, extractKTruss, filterSubgraph, flux, fluxAsync, frontierBalanced, frontierBalancedAsync, fuse, fuseAsync, fuseBatchPriority, fuseWithBatchPriority, getMotifName, gpuBfsLevels, gpuDegreeHistogram, gpuJaccardBatch, gpuKMeansAssign, gpuMIBatch, gpuPageRank, gpuSpmv, graphToCSR, grasp, hae, haeAsync, hittingTime, hubPromoted, hubPromotedAsync, initGPU, initGPUFromDevice, isWebGPUAvailable, jaccard, jaccardArithmetic, jaccardAsync, kHop, katz, katzAsync, lace, laceAsync, laceBatchPriority, laceWithBatchPriority, localClusteringCoefficient, localTypeEntropy, maze, mazeAsync, miniBatchKMeans, neighbourIntersection, neighbourOverlap, neighbourSet, normaliseFeatures, normaliseFeatures as zScoreNormalise, normalisedEntropy, notch, notchAsync, omnia, opBatchDegree, opBatchNeighbours, opDegree, opGetEdge, opGetNode, opHasNode, opNeighbours, opProgress, opYield, overlapCoefficient, overlapCoefficientAsync, pagerank, pagerankAsync, parse, parseAsync, pipe, pipeAsync, prism, randomPriority, randomPriorityAsync, randomRanking, randomWalk, reach, reachAsync, resistanceDistance, resolveAsyncOp, resolveSyncOp, resourceAllocation, resourceAllocationAsync, runAsync, runBatched, runSync, sage, sageAsync, scale, scaleAsync, shannonEntropy, shortest, sift, siftAsync, siftBatchPriority, siftWithBatchPriority, skew, skewAsync, sorensen, sorensenAsync, span, spanAsync, spine, standardBfs, standardBfsAsync, stratified, stride, tide, tideAsync, warp, warpAsync, widestPath, withBackend };
@@ -464,4 +464,4 @@ function dispatchKMeansAssign(root, pointsBuffer, centroidsBuffer, assignmentsBu
464
464
  //#endregion
465
465
  export { dispatchKMeansAssign };
466
466
 
467
- //# sourceMappingURL=kernel-CigCjrts.js.map
467
+ //# sourceMappingURL=kernel-BLwhyVSV.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"kernel-CigCjrts.js","names":[],"sources":["../src/gpu/kernels/kmeans/kernel.ts"],"sourcesContent":["/**\n * TypeGPU compute kernel for K-means assignment step.\n *\n * Assigns each point to its nearest centroid in parallel.\n * This is the most parallelizable operation in K-means clustering.\n *\n * @module gpu/kernels/kmeans/kernel\n */\n\nimport tgpu, { d } from \"typegpu\";\nimport type { GraphwiseGPURoot } from \"../../root\";\n\n/**\n * K-means assignment kernel buffers.\n *\n * Buffer types are complex TypeGPU types that are difficult to express in TypeScript.\n * Using `any` here is intentional to avoid verbose generic constraints.\n */\nexport interface KMeansAssignBuffers {\n\t/** Points buffer (3D vectors) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly pointsBuffer: any;\n\t/** Centroids buffer (3D vectors) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly centroidsBuffer: any;\n\t/** Assignments output buffer (cluster indices) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly assignmentsBuffer: any;\n\t/** Distances output buffer (distances to assigned centroid) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly distancesBuffer: any;\n}\n\n/**\n * Bind group layout for K-means assignment kernel.\n */\nconst KMeansAssignLayout = tgpu.bindGroupLayout({\n\tpoints: { storage: d.arrayOf(d.arrayOf(d.f32, 3)) }, // 3D points for GRASP\n\tcentroids: { storage: d.arrayOf(d.arrayOf(d.f32, 3)) },\n\tassignments: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tdistances: { storage: d.arrayOf(d.f32), access: \"mutable\" },\n\tpointCount: { uniform: d.u32 },\n\tk: { uniform: d.u32 },\n});\n\n/**\n * K-means assignment compute pipeline: one thread per point.\n *\n * For each point:\n * - Compute distance to all centroids\n * - Assign to nearest centroid\n * - Store squared distance\n */\nconst kmeansAssignPipeline = (pointIdx: number): void => {\n\t\"use gpu\";\n\n\tif (pointIdx >= KMeansAssignLayout.$.pointCount) return;\n\n\t// Load point coordinates\n\tconst point = KMeansAssignLayout.$.points[pointIdx];\n\tif (point === undefined) {\n\t\tKMeansAssignLayout.$.assignments[pointIdx] = 0;\n\t\tKMeansAssignLayout.$.distances[pointIdx] = 0;\n\t\treturn;\n\t}\n\n\tconst px = point[0] ?? 0;\n\tconst py = point[1] ?? 0;\n\tconst pz = point[2] ?? 0;\n\n\t// Find nearest centroid\n\tlet minDist = 1000000000;\n\tlet minIdx = 0;\n\n\tfor (let c = 0; c < KMeansAssignLayout.$.k; c = c + 1) {\n\t\tconst centroid = KMeansAssignLayout.$.centroids[c];\n\t\tif (centroid === undefined) continue;\n\n\t\tconst cx = centroid[0] ?? 0;\n\t\tconst cy = centroid[1] ?? 0;\n\t\tconst cz = centroid[2] ?? 0;\n\n\t\tconst dx = px - cx;\n\t\tconst dy = py - cy;\n\t\tconst dz = pz - cz;\n\t\tconst distSq = dx * dx + dy * dy + dz * dz;\n\n\t\tif (distSq < minDist) {\n\t\t\tminDist = distSq;\n\t\t\tminIdx = c;\n\t\t}\n\t}\n\n\tKMeansAssignLayout.$.assignments[pointIdx] = minIdx;\n\tKMeansAssignLayout.$.distances[pointIdx] = minDist;\n};\n\n/**\n * Dispatch K-means assignment on GPU.\n *\n * @param root - TypeGPU root\n * @param pointsBuffer - Buffer of 3D points\n * @param centroidsBuffer - Buffer of centroids\n * @param assignmentsBuffer - Output buffer for assignments\n * @param distancesBuffer - Output buffer for distances\n * @param pointCount - Number of points\n * @param k - Number of centroids\n */\nexport function dispatchKMeansAssign(\n\troot: GraphwiseGPURoot,\n\t// TypeGPU buffer types are complex and not easily expressible in TypeScript\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpointsBuffer: any,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tcentroidsBuffer: any,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tassignmentsBuffer: any,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tdistancesBuffer: any,\n\tpointCount: number,\n\tk: number,\n): void {\n\t// TypeGPU kernel function with \"use gpu\" directive\n\n\tconst pipeline = root.createGuardedComputePipeline(\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any\n\t\tkmeansAssignPipeline as any,\n\t);\n\n\tconst pairCountBuffer = root\n\t\t.createBuffer(d.u32, pointCount)\n\t\t.$usage(\"uniform\");\n\tconst kBuffer = root.createBuffer(d.u32, k).$usage(\"uniform\");\n\n\tconst bindGroup = root.createBindGroup(KMeansAssignLayout, {\n\t\tpoints: pointsBuffer,\n\t\tcentroids: centroidsBuffer,\n\t\tassignments: assignmentsBuffer,\n\t\tdistances: distancesBuffer,\n\t\tpointCount: pairCountBuffer,\n\t\tk: kBuffer,\n\t});\n\n\tpipeline.with(bindGroup).dispatchThreads(pointCount);\n}\n\n/**\n * Create buffers for K-means assignment.\n */\nexport function createKMeansAssignBuffers(\n\troot: GraphwiseGPURoot,\n\tpoints: readonly (readonly [number, number, number])[],\n\tcentroids: readonly (readonly [number, number, number])[],\n): KMeansAssignBuffers {\n\tconst pointCount = points.length;\n\tconst k = centroids.length;\n\n\t// Convert readonly arrays to mutable for TypeGPU buffer creation\n\n\tconst pointsBuffer = root\n\t\t.createBuffer(\n\t\t\td.arrayOf(d.vec3f, pointCount),\n\t\t\t// TypeGPU type constraints are complex; TypedArrays are compatible with buffer initialization\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any\n\t\t\tArray.from(points) as any,\n\t\t)\n\t\t.$usage(\"storage\");\n\n\tconst centroidsBuffer = root\n\t\t.createBuffer(\n\t\t\td.arrayOf(d.vec3f, k),\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any\n\t\t\tArray.from(centroids) as any,\n\t\t)\n\t\t.$usage(\"storage\");\n\n\tconst assignmentsBuffer = root\n\t\t.createBuffer(d.arrayOf(d.u32, pointCount))\n\t\t.$usage(\"storage\");\n\n\tconst distancesBuffer = root\n\t\t.createBuffer(d.arrayOf(d.f32, pointCount))\n\t\t.$usage(\"storage\");\n\n\treturn {\n\t\tpointsBuffer,\n\t\tcentroidsBuffer,\n\t\tassignmentsBuffer,\n\t\tdistancesBuffer,\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"kernel-BLwhyVSV.js","names":[],"sources":["../src/gpu/kernels/kmeans/kernel.ts"],"sourcesContent":["/**\n * TypeGPU compute kernel for K-means assignment step.\n *\n * Assigns each point to its nearest centroid in parallel.\n * This is the most parallelizable operation in K-means clustering.\n *\n * @module gpu/kernels/kmeans/kernel\n */\n\nimport tgpu, { d } from \"typegpu\";\nimport type { GraphwiseGPURoot } from \"../../root\";\n\n/**\n * K-means assignment kernel buffers.\n *\n * Buffer types are complex TypeGPU types that are difficult to express in TypeScript.\n * Using `any` here is intentional to avoid verbose generic constraints.\n */\nexport interface KMeansAssignBuffers {\n\t/** Points buffer (3D vectors) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly pointsBuffer: any;\n\t/** Centroids buffer (3D vectors) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly centroidsBuffer: any;\n\t/** Assignments output buffer (cluster indices) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly assignmentsBuffer: any;\n\t/** Distances output buffer (distances to assigned centroid) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly distancesBuffer: any;\n}\n\n/**\n * Bind group layout for K-means assignment kernel.\n */\nconst KMeansAssignLayout = tgpu.bindGroupLayout({\n\tpoints: { storage: d.arrayOf(d.arrayOf(d.f32, 3)) }, // 3D points for GRASP\n\tcentroids: { storage: d.arrayOf(d.arrayOf(d.f32, 3)) },\n\tassignments: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tdistances: { storage: d.arrayOf(d.f32), access: \"mutable\" },\n\tpointCount: { uniform: d.u32 },\n\tk: { uniform: d.u32 },\n});\n\n/**\n * K-means assignment compute pipeline: one thread per point.\n *\n * For each point:\n * - Compute distance to all centroids\n * - Assign to nearest centroid\n * - Store squared distance\n */\nconst kmeansAssignPipeline = (pointIdx: number): void => {\n\t\"use gpu\";\n\n\tif (pointIdx >= KMeansAssignLayout.$.pointCount) return;\n\n\t// Load point coordinates\n\tconst point = KMeansAssignLayout.$.points[pointIdx];\n\tif (point === undefined) {\n\t\tKMeansAssignLayout.$.assignments[pointIdx] = 0;\n\t\tKMeansAssignLayout.$.distances[pointIdx] = 0;\n\t\treturn;\n\t}\n\n\tconst px = point[0] ?? 0;\n\tconst py = point[1] ?? 0;\n\tconst pz = point[2] ?? 0;\n\n\t// Find nearest centroid\n\tlet minDist = 1000000000;\n\tlet minIdx = 0;\n\n\tfor (let c = 0; c < KMeansAssignLayout.$.k; c = c + 1) {\n\t\tconst centroid = KMeansAssignLayout.$.centroids[c];\n\t\tif (centroid === undefined) continue;\n\n\t\tconst cx = centroid[0] ?? 0;\n\t\tconst cy = centroid[1] ?? 0;\n\t\tconst cz = centroid[2] ?? 0;\n\n\t\tconst dx = px - cx;\n\t\tconst dy = py - cy;\n\t\tconst dz = pz - cz;\n\t\tconst distSq = dx * dx + dy * dy + dz * dz;\n\n\t\tif (distSq < minDist) {\n\t\t\tminDist = distSq;\n\t\t\tminIdx = c;\n\t\t}\n\t}\n\n\tKMeansAssignLayout.$.assignments[pointIdx] = minIdx;\n\tKMeansAssignLayout.$.distances[pointIdx] = minDist;\n};\n\n/**\n * Dispatch K-means assignment on GPU.\n *\n * @param root - TypeGPU root\n * @param pointsBuffer - Buffer of 3D points\n * @param centroidsBuffer - Buffer of centroids\n * @param assignmentsBuffer - Output buffer for assignments\n * @param distancesBuffer - Output buffer for distances\n * @param pointCount - Number of points\n * @param k - Number of centroids\n */\nexport function dispatchKMeansAssign(\n\troot: GraphwiseGPURoot,\n\t// TypeGPU buffer types are complex and not easily expressible in TypeScript\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpointsBuffer: any,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tcentroidsBuffer: any,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tassignmentsBuffer: any,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tdistancesBuffer: any,\n\tpointCount: number,\n\tk: number,\n): void {\n\t// TypeGPU kernel function with \"use gpu\" directive\n\n\tconst pipeline = root.createGuardedComputePipeline(\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any\n\t\tkmeansAssignPipeline as any,\n\t);\n\n\tconst pairCountBuffer = root\n\t\t.createBuffer(d.u32, pointCount)\n\t\t.$usage(\"uniform\");\n\tconst kBuffer = root.createBuffer(d.u32, k).$usage(\"uniform\");\n\n\tconst bindGroup = root.createBindGroup(KMeansAssignLayout, {\n\t\tpoints: pointsBuffer,\n\t\tcentroids: centroidsBuffer,\n\t\tassignments: assignmentsBuffer,\n\t\tdistances: distancesBuffer,\n\t\tpointCount: pairCountBuffer,\n\t\tk: kBuffer,\n\t});\n\n\tpipeline.with(bindGroup).dispatchThreads(pointCount);\n}\n\n/**\n * Create buffers for K-means assignment.\n */\nexport function createKMeansAssignBuffers(\n\troot: GraphwiseGPURoot,\n\tpoints: readonly (readonly [number, number, number])[],\n\tcentroids: readonly (readonly [number, number, number])[],\n): KMeansAssignBuffers {\n\tconst pointCount = points.length;\n\tconst k = centroids.length;\n\n\t// Convert readonly arrays to mutable for TypeGPU buffer creation\n\n\tconst pointsBuffer = root\n\t\t.createBuffer(\n\t\t\td.arrayOf(d.vec3f, pointCount),\n\t\t\t// TypeGPU type constraints are complex; TypedArrays are compatible with buffer initialization\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any\n\t\t\tArray.from(points) as any,\n\t\t)\n\t\t.$usage(\"storage\");\n\n\tconst centroidsBuffer = root\n\t\t.createBuffer(\n\t\t\td.arrayOf(d.vec3f, k),\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any\n\t\t\tArray.from(centroids) as any,\n\t\t)\n\t\t.$usage(\"storage\");\n\n\tconst assignmentsBuffer = root\n\t\t.createBuffer(d.arrayOf(d.u32, pointCount))\n\t\t.$usage(\"storage\");\n\n\tconst distancesBuffer = root\n\t\t.createBuffer(d.arrayOf(d.f32, pointCount))\n\t\t.$usage(\"storage\");\n\n\treturn {\n\t\tpointsBuffer,\n\t\tcentroidsBuffer,\n\t\tassignmentsBuffer,\n\t\tdistancesBuffer,\n\t};\n}\n"],"mappings":"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"}
@@ -998,4 +998,4 @@ function dispatchAdamicAdar(root, csrBuffers, pairsU, pairsV, results, intersect
998
998
  //#endregion
999
999
  exports.dispatchAdamicAdar = dispatchAdamicAdar;
1000
1000
 
1001
- //# sourceMappingURL=kernel-2oH4Cn32.cjs.map
1001
+ //# sourceMappingURL=kernel-BffKjhZS.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"kernel-2oH4Cn32.cjs","names":[],"sources":["../src/gpu/kernels/adamic-adar/kernel.ts"],"sourcesContent":["/**\n * TypeGPU compute kernel for Adamic-Adar index (batch).\n *\n * For each pair (u, v): iterate smaller neighbourhood, detect common neighbours\n * by binary search in the other neighbourhood, sum 1 / log(deg(w) + 1) and\n * normalise by log(2)/count to match CPU normalisation.\n */\n\nimport tgpu, { d, type StorageFlag, type TgpuBuffer } from \"typegpu\";\nimport type { TypedBufferGroup } from \"../../csr\";\nimport type { GraphwiseGPURoot } from \"../../root\";\n\nconst LOG2 = 0.6931471805599453;\n\nconst AdamicLayout = tgpu.bindGroupLayout({\n\trowOffsets: { storage: d.arrayOf(d.u32) },\n\tcolIndices: { storage: d.arrayOf(d.u32) },\n\tpairsU: { storage: d.arrayOf(d.u32) },\n\tpairsV: { storage: d.arrayOf(d.u32) },\n\tintersections: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeUs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeVs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tresults: { storage: d.arrayOf(d.f32), access: \"mutable\" },\n\tpairCount: { uniform: d.u32 },\n});\n\nconst adamicPipeline = (pairIdx: number): void => {\n\t\"use gpu\";\n\tconst u = AdamicLayout.$.pairsU[pairIdx] ?? 0;\n\tconst v = AdamicLayout.$.pairsV[pairIdx] ?? 0;\n\n\tconst uStart = AdamicLayout.$.rowOffsets[u] ?? 0;\n\tconst uEnd = AdamicLayout.$.rowOffsets[u + 1] ?? 0;\n\tconst vStart = AdamicLayout.$.rowOffsets[v] ?? 0;\n\tconst vEnd = AdamicLayout.$.rowOffsets[v + 1] ?? 0;\n\n\tconst degU = uEnd - uStart;\n\tconst degV = vEnd - vStart;\n\n\tAdamicLayout.$.sizeUs[pairIdx] = degU;\n\tAdamicLayout.$.sizeVs[pairIdx] = degV;\n\n\tif (degU === 0 || degV === 0) {\n\t\tAdamicLayout.$.intersections[pairIdx] = 0;\n\t\tAdamicLayout.$.results[pairIdx] = 0.0;\n\t\treturn;\n\t}\n\n\tlet commonCount = 0;\n\tlet sum = 0.0;\n\n\tif (degU <= degV) {\n\t\tfor (let i = uStart; i < uEnd; i = i + 1) {\n\t\t\tconst neighbour = AdamicLayout.$.colIndices[i] ?? 0;\n\t\t\tlet lo = vStart;\n\t\t\tlet hi = vEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = AdamicLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tcommonCount = commonCount + 1;\n\t\t\t\t\tconst wStart = AdamicLayout.$.rowOffsets[neighbour] ?? 0;\n\t\t\t\t\tconst wEnd = AdamicLayout.$.rowOffsets[neighbour + 1] ?? 0;\n\t\t\t\t\tconst degW = wEnd - wStart;\n\t\t\t\t\tconst invLog = 1.0 / Math.log(degW + 1.0);\n\t\t\t\t\tsum = sum + invLog;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor (let i = vStart; i < vEnd; i = i + 1) {\n\t\t\tconst neighbour = AdamicLayout.$.colIndices[i] ?? 0;\n\t\t\tlet lo = uStart;\n\t\t\tlet hi = uEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = AdamicLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tcommonCount = commonCount + 1;\n\t\t\t\t\tconst wStart = AdamicLayout.$.rowOffsets[neighbour] ?? 0;\n\t\t\t\t\tconst wEnd = AdamicLayout.$.rowOffsets[neighbour + 1] ?? 0;\n\t\t\t\t\tconst degW = wEnd - wStart;\n\t\t\t\t\tconst invLog = 1.0 / Math.log(degW + 1.0);\n\t\t\t\t\tsum = sum + invLog;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tAdamicLayout.$.intersections[pairIdx] = commonCount;\n\tif (commonCount === 0) {\n\t\tAdamicLayout.$.results[pairIdx] = 0.0;\n\t} else {\n\t\tAdamicLayout.$.results[pairIdx] = (sum * LOG2) / commonCount;\n\t}\n};\n\nexport function dispatchAdamicAdar(\n\troot: GraphwiseGPURoot,\n\tcsrBuffers: TypedBufferGroup,\n\tpairsU: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairsV: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tresults: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.f32>>> & StorageFlag,\n\tintersections: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> &\n\t\tStorageFlag,\n\tsizeUs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tsizeVs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairCount: number,\n): void {\n\tconst pipeline = root.createGuardedComputePipeline(adamicPipeline);\n\tconst pairCountBuffer = root.createBuffer(d.u32, pairCount).$usage(\"uniform\");\n\tconst bindGroup = root.createBindGroup(AdamicLayout, {\n\t\trowOffsets: csrBuffers.rowOffsets,\n\t\tcolIndices: csrBuffers.colIndices,\n\t\tpairsU,\n\t\tpairsV,\n\t\tintersections,\n\t\tsizeUs,\n\t\tsizeVs,\n\t\tresults,\n\t\tpairCount: pairCountBuffer,\n\t});\n\tpipeline.with(bindGroup).dispatchThreads(pairCount);\n}\n\nexport { AdamicLayout };\n"],"mappings":"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"}
1
+ {"version":3,"file":"kernel-BffKjhZS.cjs","names":[],"sources":["../src/gpu/kernels/adamic-adar/kernel.ts"],"sourcesContent":["/**\n * TypeGPU compute kernel for Adamic-Adar index (batch).\n *\n * For each pair (u, v): iterate smaller neighbourhood, detect common neighbours\n * by binary search in the other neighbourhood, sum 1 / log(deg(w) + 1) and\n * normalise by log(2)/count to match CPU normalisation.\n */\n\nimport tgpu, { d, type StorageFlag, type TgpuBuffer } from \"typegpu\";\nimport type { TypedBufferGroup } from \"../../csr\";\nimport type { GraphwiseGPURoot } from \"../../root\";\n\nconst LOG2 = 0.6931471805599453;\n\nconst AdamicLayout = tgpu.bindGroupLayout({\n\trowOffsets: { storage: d.arrayOf(d.u32) },\n\tcolIndices: { storage: d.arrayOf(d.u32) },\n\tpairsU: { storage: d.arrayOf(d.u32) },\n\tpairsV: { storage: d.arrayOf(d.u32) },\n\tintersections: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeUs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeVs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tresults: { storage: d.arrayOf(d.f32), access: \"mutable\" },\n\tpairCount: { uniform: d.u32 },\n});\n\nconst adamicPipeline = (pairIdx: number): void => {\n\t\"use gpu\";\n\tconst u = AdamicLayout.$.pairsU[pairIdx] ?? 0;\n\tconst v = AdamicLayout.$.pairsV[pairIdx] ?? 0;\n\n\tconst uStart = AdamicLayout.$.rowOffsets[u] ?? 0;\n\tconst uEnd = AdamicLayout.$.rowOffsets[u + 1] ?? 0;\n\tconst vStart = AdamicLayout.$.rowOffsets[v] ?? 0;\n\tconst vEnd = AdamicLayout.$.rowOffsets[v + 1] ?? 0;\n\n\tconst degU = uEnd - uStart;\n\tconst degV = vEnd - vStart;\n\n\tAdamicLayout.$.sizeUs[pairIdx] = degU;\n\tAdamicLayout.$.sizeVs[pairIdx] = degV;\n\n\tif (degU === 0 || degV === 0) {\n\t\tAdamicLayout.$.intersections[pairIdx] = 0;\n\t\tAdamicLayout.$.results[pairIdx] = 0.0;\n\t\treturn;\n\t}\n\n\tlet commonCount = 0;\n\tlet sum = 0.0;\n\n\tif (degU <= degV) {\n\t\tfor (let i = uStart; i < uEnd; i = i + 1) {\n\t\t\tconst neighbour = AdamicLayout.$.colIndices[i] ?? 0;\n\t\t\tlet lo = vStart;\n\t\t\tlet hi = vEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = AdamicLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tcommonCount = commonCount + 1;\n\t\t\t\t\tconst wStart = AdamicLayout.$.rowOffsets[neighbour] ?? 0;\n\t\t\t\t\tconst wEnd = AdamicLayout.$.rowOffsets[neighbour + 1] ?? 0;\n\t\t\t\t\tconst degW = wEnd - wStart;\n\t\t\t\t\tconst invLog = 1.0 / Math.log(degW + 1.0);\n\t\t\t\t\tsum = sum + invLog;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor (let i = vStart; i < vEnd; i = i + 1) {\n\t\t\tconst neighbour = AdamicLayout.$.colIndices[i] ?? 0;\n\t\t\tlet lo = uStart;\n\t\t\tlet hi = uEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = AdamicLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tcommonCount = commonCount + 1;\n\t\t\t\t\tconst wStart = AdamicLayout.$.rowOffsets[neighbour] ?? 0;\n\t\t\t\t\tconst wEnd = AdamicLayout.$.rowOffsets[neighbour + 1] ?? 0;\n\t\t\t\t\tconst degW = wEnd - wStart;\n\t\t\t\t\tconst invLog = 1.0 / Math.log(degW + 1.0);\n\t\t\t\t\tsum = sum + invLog;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tAdamicLayout.$.intersections[pairIdx] = commonCount;\n\tif (commonCount === 0) {\n\t\tAdamicLayout.$.results[pairIdx] = 0.0;\n\t} else {\n\t\tAdamicLayout.$.results[pairIdx] = (sum * LOG2) / commonCount;\n\t}\n};\n\nexport function dispatchAdamicAdar(\n\troot: GraphwiseGPURoot,\n\tcsrBuffers: TypedBufferGroup,\n\tpairsU: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairsV: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tresults: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.f32>>> & StorageFlag,\n\tintersections: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> &\n\t\tStorageFlag,\n\tsizeUs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tsizeVs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairCount: number,\n): void {\n\tconst pipeline = root.createGuardedComputePipeline(adamicPipeline);\n\tconst pairCountBuffer = root.createBuffer(d.u32, pairCount).$usage(\"uniform\");\n\tconst bindGroup = root.createBindGroup(AdamicLayout, {\n\t\trowOffsets: csrBuffers.rowOffsets,\n\t\tcolIndices: csrBuffers.colIndices,\n\t\tpairsU,\n\t\tpairsV,\n\t\tintersections,\n\t\tsizeUs,\n\t\tsizeVs,\n\t\tresults,\n\t\tpairCount: pairCountBuffer,\n\t});\n\tpipeline.with(bindGroup).dispatchThreads(pairCount);\n}\n\nexport { AdamicLayout };\n"],"mappings":";;;;;;;;;AAYA,IAAM,OAAO;AAEb,IAAM,gBAAA,WAAA,0BAAA,MAAA,IAAe,gBAAA,YAAK,gBAAgB;CACzC,YAAY,EAAE,SAAS,gBAAA,aAAE,QAAQ,gBAAA,aAAE,IAAI,EAAE;CACzC,YAAY,EAAE,SAAS,gBAAA,aAAE,QAAQ,gBAAA,aAAE,IAAI,EAAE;CACzC,QAAQ,EAAE,SAAS,gBAAA,aAAE,QAAQ,gBAAA,aAAE,IAAI,EAAE;CACrC,QAAQ,EAAE,SAAS,gBAAA,aAAE,QAAQ,gBAAA,aAAE,IAAI,EAAE;CACrC,eAAe;EAAE,SAAS,gBAAA,aAAE,QAAQ,gBAAA,aAAE,IAAI;EAAE,QAAQ;EAAW;CAC/D,QAAQ;EAAE,SAAS,gBAAA,aAAE,QAAQ,gBAAA,aAAE,IAAI;EAAE,QAAQ;EAAW;CACxD,QAAQ;EAAE,SAAS,gBAAA,aAAE,QAAQ,gBAAA,aAAE,IAAI;EAAE,QAAQ;EAAW;CACxD,SAAS;EAAE,SAAS,gBAAA,aAAE,QAAQ,gBAAA,aAAE,IAAI;EAAE,QAAQ;EAAW;CACzD,WAAW,EAAE,SAAS,gBAAA,aAAE,KAAA;CACxB,CAAA,EAAA,eAAA;AAED,IAAM,mBAAA,OAAA,WAAA,qCAAA,IAAA,SAAA,EAAA,IAAA,EAAA,MAAkB,YAA0B;AACjD;CACA,MAAM,IAAI,aAAa,EAAE,OAAO,YAAY;CAC5C,MAAM,IAAI,aAAa,EAAE,OAAO,YAAY;CAE5C,MAAM,SAAS,aAAa,EAAE,WAAW,MAAM;CAC/C,MAAM,OAAO,aAAa,EAAE,WAAW,aAAA,GAAA,EAAI,KAAM;CACjD,MAAM,SAAS,aAAa,EAAE,WAAW,MAAM;CAC/C,MAAM,OAAO,aAAa,EAAE,WAAW,aAAA,GAAA,EAAI,KAAM;CAEjD,MAAM,OAAO,aAAA,MAAA,OAAO;CACpB,MAAM,OAAO,aAAA,MAAA,OAAO;AAEpB,cAAa,EAAE,OAAO,WAAW;AACjC,cAAa,EAAE,OAAO,WAAW;AAEjC,KAAI,SAAS,KAAK,SAAS,GAAG;AAC7B,eAAa,EAAE,cAAc,WAAW;AACxC,eAAa,EAAE,QAAQ,WAAW;AAClC;;CAGD,IAAI,cAAc;CAClB,IAAI,MAAM;AAEV,KAAI,QAAQ,KACX,MAAK,IAAI,IAAI,QAAQ,IAAI,MAAM,IAAI,aAAA,GAAA,EAAI,EAAG;EACzC,MAAM,YAAY,aAAa,EAAE,WAAW,MAAM;EAClD,IAAI,KAAK;EACT,IAAI,KAAK;AACT,SAAO,KAAK,IAAI;GACf,MAAM,MAAM,aAAA,IAAA,aAAA,aAAA,IAAA,GAAA,EAAA,EAAA,CAAiB;GAC7B,MAAM,SAAS,aAAa,EAAE,WAAW,QAAQ;AACjD,OAAI,WAAW,WAAW;AACzB,kBAAc,aAAA,aAAA,EAAc;IAC5B,MAAM,SAAS,aAAa,EAAE,WAAW,cAAc;IACvD,MAAM,OAAO,aAAa,EAAE,WAAW,aAAA,WAAA,EAAY,KAAM;IACzD,MAAM,OAAO,aAAA,MAAA,OAAO;IACpB,MAAM,SAAS,aAAA,GAAA,KAAA,IAAA,aAAA,MAAA,EAAA,CAAA,CAA0B;AACzC,UAAM,aAAA,KAAA,OAAM;AACZ,SAAK;cACK,SAAS,UACnB,MAAK,aAAA,KAAA,EAAM;OAEX,MAAK;;;KAKR,MAAK,IAAI,IAAI,QAAQ,IAAI,MAAM,IAAI,aAAA,GAAA,EAAI,EAAG;EACzC,MAAM,YAAY,aAAa,EAAE,WAAW,MAAM;EAClD,IAAI,KAAK;EACT,IAAI,KAAK;AACT,SAAO,KAAK,IAAI;GACf,MAAM,MAAM,aAAA,IAAA,aAAA,aAAA,IAAA,GAAA,EAAA,EAAA,CAAiB;GAC7B,MAAM,SAAS,aAAa,EAAE,WAAW,QAAQ;AACjD,OAAI,WAAW,WAAW;AACzB,kBAAc,aAAA,aAAA,EAAc;IAC5B,MAAM,SAAS,aAAa,EAAE,WAAW,cAAc;IACvD,MAAM,OAAO,aAAa,EAAE,WAAW,aAAA,WAAA,EAAY,KAAM;IACzD,MAAM,OAAO,aAAA,MAAA,OAAO;IACpB,MAAM,SAAS,aAAA,GAAA,KAAA,IAAA,aAAA,MAAA,EAAA,CAAA,CAA0B;AACzC,UAAM,aAAA,KAAA,OAAM;AACZ,SAAK;cACK,SAAS,UACnB,MAAK,aAAA,KAAA,EAAM;OAEX,MAAK;;;AAMT,cAAa,EAAE,cAAc,WAAW;AACxC,KAAI,gBAAgB,EACnB,cAAa,EAAE,QAAQ,WAAW;KAElC,cAAa,EAAE,QAAQ,WAAY,aAAA,aAAA,KAAA,KAAA,EAAA,YAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAInD,SAAgB,mBACf,MACA,YACA,QACA,QACA,SACA,eAEA,QACA,QACA,WACO;CACP,MAAM,YAAA,WAAA,0BAAA,MAAA,IAAW,KAAK,6BAA6B,eAAA,EAAA,WAAA;CACnD,MAAM,mBAAA,WAAA,0BAAA,MAAA,IAAkB,KAAK,aAAa,gBAAA,aAAE,KAAK,UAAU,CAAC,OAAO,UAAA,EAAA,kBAAA;CACnE,MAAM,YAAY,KAAK,gBAAgB,cAAc;EACpD,YAAY,WAAW;EACvB,YAAY,WAAW;EACvB;EACA;EACA;EACA;EACA;EACA;EACA,WAAW;EACX,CAAC;AACF,UAAS,KAAK,UAAU,CAAC,gBAAgB,UAAU"}
@@ -464,4 +464,4 @@ function dispatchKMeansAssign(root, pointsBuffer, centroidsBuffer, assignmentsBu
464
464
  //#endregion
465
465
  exports.dispatchKMeansAssign = dispatchKMeansAssign;
466
466
 
467
- //# sourceMappingURL=kernel-CXeGBH3s.cjs.map
467
+ //# sourceMappingURL=kernel-CbP715Sq.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"kernel-CXeGBH3s.cjs","names":[],"sources":["../src/gpu/kernels/kmeans/kernel.ts"],"sourcesContent":["/**\n * TypeGPU compute kernel for K-means assignment step.\n *\n * Assigns each point to its nearest centroid in parallel.\n * This is the most parallelizable operation in K-means clustering.\n *\n * @module gpu/kernels/kmeans/kernel\n */\n\nimport tgpu, { d } from \"typegpu\";\nimport type { GraphwiseGPURoot } from \"../../root\";\n\n/**\n * K-means assignment kernel buffers.\n *\n * Buffer types are complex TypeGPU types that are difficult to express in TypeScript.\n * Using `any` here is intentional to avoid verbose generic constraints.\n */\nexport interface KMeansAssignBuffers {\n\t/** Points buffer (3D vectors) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly pointsBuffer: any;\n\t/** Centroids buffer (3D vectors) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly centroidsBuffer: any;\n\t/** Assignments output buffer (cluster indices) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly assignmentsBuffer: any;\n\t/** Distances output buffer (distances to assigned centroid) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly distancesBuffer: any;\n}\n\n/**\n * Bind group layout for K-means assignment kernel.\n */\nconst KMeansAssignLayout = tgpu.bindGroupLayout({\n\tpoints: { storage: d.arrayOf(d.arrayOf(d.f32, 3)) }, // 3D points for GRASP\n\tcentroids: { storage: d.arrayOf(d.arrayOf(d.f32, 3)) },\n\tassignments: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tdistances: { storage: d.arrayOf(d.f32), access: \"mutable\" },\n\tpointCount: { uniform: d.u32 },\n\tk: { uniform: d.u32 },\n});\n\n/**\n * K-means assignment compute pipeline: one thread per point.\n *\n * For each point:\n * - Compute distance to all centroids\n * - Assign to nearest centroid\n * - Store squared distance\n */\nconst kmeansAssignPipeline = (pointIdx: number): void => {\n\t\"use gpu\";\n\n\tif (pointIdx >= KMeansAssignLayout.$.pointCount) return;\n\n\t// Load point coordinates\n\tconst point = KMeansAssignLayout.$.points[pointIdx];\n\tif (point === undefined) {\n\t\tKMeansAssignLayout.$.assignments[pointIdx] = 0;\n\t\tKMeansAssignLayout.$.distances[pointIdx] = 0;\n\t\treturn;\n\t}\n\n\tconst px = point[0] ?? 0;\n\tconst py = point[1] ?? 0;\n\tconst pz = point[2] ?? 0;\n\n\t// Find nearest centroid\n\tlet minDist = 1000000000;\n\tlet minIdx = 0;\n\n\tfor (let c = 0; c < KMeansAssignLayout.$.k; c = c + 1) {\n\t\tconst centroid = KMeansAssignLayout.$.centroids[c];\n\t\tif (centroid === undefined) continue;\n\n\t\tconst cx = centroid[0] ?? 0;\n\t\tconst cy = centroid[1] ?? 0;\n\t\tconst cz = centroid[2] ?? 0;\n\n\t\tconst dx = px - cx;\n\t\tconst dy = py - cy;\n\t\tconst dz = pz - cz;\n\t\tconst distSq = dx * dx + dy * dy + dz * dz;\n\n\t\tif (distSq < minDist) {\n\t\t\tminDist = distSq;\n\t\t\tminIdx = c;\n\t\t}\n\t}\n\n\tKMeansAssignLayout.$.assignments[pointIdx] = minIdx;\n\tKMeansAssignLayout.$.distances[pointIdx] = minDist;\n};\n\n/**\n * Dispatch K-means assignment on GPU.\n *\n * @param root - TypeGPU root\n * @param pointsBuffer - Buffer of 3D points\n * @param centroidsBuffer - Buffer of centroids\n * @param assignmentsBuffer - Output buffer for assignments\n * @param distancesBuffer - Output buffer for distances\n * @param pointCount - Number of points\n * @param k - Number of centroids\n */\nexport function dispatchKMeansAssign(\n\troot: GraphwiseGPURoot,\n\t// TypeGPU buffer types are complex and not easily expressible in TypeScript\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpointsBuffer: any,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tcentroidsBuffer: any,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tassignmentsBuffer: any,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tdistancesBuffer: any,\n\tpointCount: number,\n\tk: number,\n): void {\n\t// TypeGPU kernel function with \"use gpu\" directive\n\n\tconst pipeline = root.createGuardedComputePipeline(\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any\n\t\tkmeansAssignPipeline as any,\n\t);\n\n\tconst pairCountBuffer = root\n\t\t.createBuffer(d.u32, pointCount)\n\t\t.$usage(\"uniform\");\n\tconst kBuffer = root.createBuffer(d.u32, k).$usage(\"uniform\");\n\n\tconst bindGroup = root.createBindGroup(KMeansAssignLayout, {\n\t\tpoints: pointsBuffer,\n\t\tcentroids: centroidsBuffer,\n\t\tassignments: assignmentsBuffer,\n\t\tdistances: distancesBuffer,\n\t\tpointCount: pairCountBuffer,\n\t\tk: kBuffer,\n\t});\n\n\tpipeline.with(bindGroup).dispatchThreads(pointCount);\n}\n\n/**\n * Create buffers for K-means assignment.\n */\nexport function createKMeansAssignBuffers(\n\troot: GraphwiseGPURoot,\n\tpoints: readonly (readonly [number, number, number])[],\n\tcentroids: readonly (readonly [number, number, number])[],\n): KMeansAssignBuffers {\n\tconst pointCount = points.length;\n\tconst k = centroids.length;\n\n\t// Convert readonly arrays to mutable for TypeGPU buffer creation\n\n\tconst pointsBuffer = root\n\t\t.createBuffer(\n\t\t\td.arrayOf(d.vec3f, pointCount),\n\t\t\t// TypeGPU type constraints are complex; TypedArrays are compatible with buffer initialization\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any\n\t\t\tArray.from(points) as any,\n\t\t)\n\t\t.$usage(\"storage\");\n\n\tconst centroidsBuffer = root\n\t\t.createBuffer(\n\t\t\td.arrayOf(d.vec3f, k),\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any\n\t\t\tArray.from(centroids) as any,\n\t\t)\n\t\t.$usage(\"storage\");\n\n\tconst assignmentsBuffer = root\n\t\t.createBuffer(d.arrayOf(d.u32, pointCount))\n\t\t.$usage(\"storage\");\n\n\tconst distancesBuffer = root\n\t\t.createBuffer(d.arrayOf(d.f32, pointCount))\n\t\t.$usage(\"storage\");\n\n\treturn {\n\t\tpointsBuffer,\n\t\tcentroidsBuffer,\n\t\tassignmentsBuffer,\n\t\tdistancesBuffer,\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"kernel-CbP715Sq.cjs","names":[],"sources":["../src/gpu/kernels/kmeans/kernel.ts"],"sourcesContent":["/**\n * TypeGPU compute kernel for K-means assignment step.\n *\n * Assigns each point to its nearest centroid in parallel.\n * This is the most parallelizable operation in K-means clustering.\n *\n * @module gpu/kernels/kmeans/kernel\n */\n\nimport tgpu, { d } from \"typegpu\";\nimport type { GraphwiseGPURoot } from \"../../root\";\n\n/**\n * K-means assignment kernel buffers.\n *\n * Buffer types are complex TypeGPU types that are difficult to express in TypeScript.\n * Using `any` here is intentional to avoid verbose generic constraints.\n */\nexport interface KMeansAssignBuffers {\n\t/** Points buffer (3D vectors) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly pointsBuffer: any;\n\t/** Centroids buffer (3D vectors) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly centroidsBuffer: any;\n\t/** Assignments output buffer (cluster indices) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly assignmentsBuffer: any;\n\t/** Distances output buffer (distances to assigned centroid) */\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\treadonly distancesBuffer: any;\n}\n\n/**\n * Bind group layout for K-means assignment kernel.\n */\nconst KMeansAssignLayout = tgpu.bindGroupLayout({\n\tpoints: { storage: d.arrayOf(d.arrayOf(d.f32, 3)) }, // 3D points for GRASP\n\tcentroids: { storage: d.arrayOf(d.arrayOf(d.f32, 3)) },\n\tassignments: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tdistances: { storage: d.arrayOf(d.f32), access: \"mutable\" },\n\tpointCount: { uniform: d.u32 },\n\tk: { uniform: d.u32 },\n});\n\n/**\n * K-means assignment compute pipeline: one thread per point.\n *\n * For each point:\n * - Compute distance to all centroids\n * - Assign to nearest centroid\n * - Store squared distance\n */\nconst kmeansAssignPipeline = (pointIdx: number): void => {\n\t\"use gpu\";\n\n\tif (pointIdx >= KMeansAssignLayout.$.pointCount) return;\n\n\t// Load point coordinates\n\tconst point = KMeansAssignLayout.$.points[pointIdx];\n\tif (point === undefined) {\n\t\tKMeansAssignLayout.$.assignments[pointIdx] = 0;\n\t\tKMeansAssignLayout.$.distances[pointIdx] = 0;\n\t\treturn;\n\t}\n\n\tconst px = point[0] ?? 0;\n\tconst py = point[1] ?? 0;\n\tconst pz = point[2] ?? 0;\n\n\t// Find nearest centroid\n\tlet minDist = 1000000000;\n\tlet minIdx = 0;\n\n\tfor (let c = 0; c < KMeansAssignLayout.$.k; c = c + 1) {\n\t\tconst centroid = KMeansAssignLayout.$.centroids[c];\n\t\tif (centroid === undefined) continue;\n\n\t\tconst cx = centroid[0] ?? 0;\n\t\tconst cy = centroid[1] ?? 0;\n\t\tconst cz = centroid[2] ?? 0;\n\n\t\tconst dx = px - cx;\n\t\tconst dy = py - cy;\n\t\tconst dz = pz - cz;\n\t\tconst distSq = dx * dx + dy * dy + dz * dz;\n\n\t\tif (distSq < minDist) {\n\t\t\tminDist = distSq;\n\t\t\tminIdx = c;\n\t\t}\n\t}\n\n\tKMeansAssignLayout.$.assignments[pointIdx] = minIdx;\n\tKMeansAssignLayout.$.distances[pointIdx] = minDist;\n};\n\n/**\n * Dispatch K-means assignment on GPU.\n *\n * @param root - TypeGPU root\n * @param pointsBuffer - Buffer of 3D points\n * @param centroidsBuffer - Buffer of centroids\n * @param assignmentsBuffer - Output buffer for assignments\n * @param distancesBuffer - Output buffer for distances\n * @param pointCount - Number of points\n * @param k - Number of centroids\n */\nexport function dispatchKMeansAssign(\n\troot: GraphwiseGPURoot,\n\t// TypeGPU buffer types are complex and not easily expressible in TypeScript\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tpointsBuffer: any,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tcentroidsBuffer: any,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tassignmentsBuffer: any,\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tdistancesBuffer: any,\n\tpointCount: number,\n\tk: number,\n): void {\n\t// TypeGPU kernel function with \"use gpu\" directive\n\n\tconst pipeline = root.createGuardedComputePipeline(\n\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any\n\t\tkmeansAssignPipeline as any,\n\t);\n\n\tconst pairCountBuffer = root\n\t\t.createBuffer(d.u32, pointCount)\n\t\t.$usage(\"uniform\");\n\tconst kBuffer = root.createBuffer(d.u32, k).$usage(\"uniform\");\n\n\tconst bindGroup = root.createBindGroup(KMeansAssignLayout, {\n\t\tpoints: pointsBuffer,\n\t\tcentroids: centroidsBuffer,\n\t\tassignments: assignmentsBuffer,\n\t\tdistances: distancesBuffer,\n\t\tpointCount: pairCountBuffer,\n\t\tk: kBuffer,\n\t});\n\n\tpipeline.with(bindGroup).dispatchThreads(pointCount);\n}\n\n/**\n * Create buffers for K-means assignment.\n */\nexport function createKMeansAssignBuffers(\n\troot: GraphwiseGPURoot,\n\tpoints: readonly (readonly [number, number, number])[],\n\tcentroids: readonly (readonly [number, number, number])[],\n): KMeansAssignBuffers {\n\tconst pointCount = points.length;\n\tconst k = centroids.length;\n\n\t// Convert readonly arrays to mutable for TypeGPU buffer creation\n\n\tconst pointsBuffer = root\n\t\t.createBuffer(\n\t\t\td.arrayOf(d.vec3f, pointCount),\n\t\t\t// TypeGPU type constraints are complex; TypedArrays are compatible with buffer initialization\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any\n\t\t\tArray.from(points) as any,\n\t\t)\n\t\t.$usage(\"storage\");\n\n\tconst centroidsBuffer = root\n\t\t.createBuffer(\n\t\t\td.arrayOf(d.vec3f, k),\n\t\t\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any\n\t\t\tArray.from(centroids) as any,\n\t\t)\n\t\t.$usage(\"storage\");\n\n\tconst assignmentsBuffer = root\n\t\t.createBuffer(d.arrayOf(d.u32, pointCount))\n\t\t.$usage(\"storage\");\n\n\tconst distancesBuffer = root\n\t\t.createBuffer(d.arrayOf(d.f32, pointCount))\n\t\t.$usage(\"storage\");\n\n\treturn {\n\t\tpointsBuffer,\n\t\tcentroidsBuffer,\n\t\tassignmentsBuffer,\n\t\tdistancesBuffer,\n\t};\n}\n"],"mappings":"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"}
@@ -998,4 +998,4 @@ function dispatchAdamicAdar(root, csrBuffers, pairsU, pairsV, results, intersect
998
998
  //#endregion
999
999
  export { dispatchAdamicAdar };
1000
1000
 
1001
- //# sourceMappingURL=kernel-CvnRsF7E.js.map
1001
+ //# sourceMappingURL=kernel-DolEKSSx.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"kernel-CvnRsF7E.js","names":[],"sources":["../src/gpu/kernels/adamic-adar/kernel.ts"],"sourcesContent":["/**\n * TypeGPU compute kernel for Adamic-Adar index (batch).\n *\n * For each pair (u, v): iterate smaller neighbourhood, detect common neighbours\n * by binary search in the other neighbourhood, sum 1 / log(deg(w) + 1) and\n * normalise by log(2)/count to match CPU normalisation.\n */\n\nimport tgpu, { d, type StorageFlag, type TgpuBuffer } from \"typegpu\";\nimport type { TypedBufferGroup } from \"../../csr\";\nimport type { GraphwiseGPURoot } from \"../../root\";\n\nconst LOG2 = 0.6931471805599453;\n\nconst AdamicLayout = tgpu.bindGroupLayout({\n\trowOffsets: { storage: d.arrayOf(d.u32) },\n\tcolIndices: { storage: d.arrayOf(d.u32) },\n\tpairsU: { storage: d.arrayOf(d.u32) },\n\tpairsV: { storage: d.arrayOf(d.u32) },\n\tintersections: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeUs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeVs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tresults: { storage: d.arrayOf(d.f32), access: \"mutable\" },\n\tpairCount: { uniform: d.u32 },\n});\n\nconst adamicPipeline = (pairIdx: number): void => {\n\t\"use gpu\";\n\tconst u = AdamicLayout.$.pairsU[pairIdx] ?? 0;\n\tconst v = AdamicLayout.$.pairsV[pairIdx] ?? 0;\n\n\tconst uStart = AdamicLayout.$.rowOffsets[u] ?? 0;\n\tconst uEnd = AdamicLayout.$.rowOffsets[u + 1] ?? 0;\n\tconst vStart = AdamicLayout.$.rowOffsets[v] ?? 0;\n\tconst vEnd = AdamicLayout.$.rowOffsets[v + 1] ?? 0;\n\n\tconst degU = uEnd - uStart;\n\tconst degV = vEnd - vStart;\n\n\tAdamicLayout.$.sizeUs[pairIdx] = degU;\n\tAdamicLayout.$.sizeVs[pairIdx] = degV;\n\n\tif (degU === 0 || degV === 0) {\n\t\tAdamicLayout.$.intersections[pairIdx] = 0;\n\t\tAdamicLayout.$.results[pairIdx] = 0.0;\n\t\treturn;\n\t}\n\n\tlet commonCount = 0;\n\tlet sum = 0.0;\n\n\tif (degU <= degV) {\n\t\tfor (let i = uStart; i < uEnd; i = i + 1) {\n\t\t\tconst neighbour = AdamicLayout.$.colIndices[i] ?? 0;\n\t\t\tlet lo = vStart;\n\t\t\tlet hi = vEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = AdamicLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tcommonCount = commonCount + 1;\n\t\t\t\t\tconst wStart = AdamicLayout.$.rowOffsets[neighbour] ?? 0;\n\t\t\t\t\tconst wEnd = AdamicLayout.$.rowOffsets[neighbour + 1] ?? 0;\n\t\t\t\t\tconst degW = wEnd - wStart;\n\t\t\t\t\tconst invLog = 1.0 / Math.log(degW + 1.0);\n\t\t\t\t\tsum = sum + invLog;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor (let i = vStart; i < vEnd; i = i + 1) {\n\t\t\tconst neighbour = AdamicLayout.$.colIndices[i] ?? 0;\n\t\t\tlet lo = uStart;\n\t\t\tlet hi = uEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = AdamicLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tcommonCount = commonCount + 1;\n\t\t\t\t\tconst wStart = AdamicLayout.$.rowOffsets[neighbour] ?? 0;\n\t\t\t\t\tconst wEnd = AdamicLayout.$.rowOffsets[neighbour + 1] ?? 0;\n\t\t\t\t\tconst degW = wEnd - wStart;\n\t\t\t\t\tconst invLog = 1.0 / Math.log(degW + 1.0);\n\t\t\t\t\tsum = sum + invLog;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tAdamicLayout.$.intersections[pairIdx] = commonCount;\n\tif (commonCount === 0) {\n\t\tAdamicLayout.$.results[pairIdx] = 0.0;\n\t} else {\n\t\tAdamicLayout.$.results[pairIdx] = (sum * LOG2) / commonCount;\n\t}\n};\n\nexport function dispatchAdamicAdar(\n\troot: GraphwiseGPURoot,\n\tcsrBuffers: TypedBufferGroup,\n\tpairsU: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairsV: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tresults: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.f32>>> & StorageFlag,\n\tintersections: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> &\n\t\tStorageFlag,\n\tsizeUs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tsizeVs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairCount: number,\n): void {\n\tconst pipeline = root.createGuardedComputePipeline(adamicPipeline);\n\tconst pairCountBuffer = root.createBuffer(d.u32, pairCount).$usage(\"uniform\");\n\tconst bindGroup = root.createBindGroup(AdamicLayout, {\n\t\trowOffsets: csrBuffers.rowOffsets,\n\t\tcolIndices: csrBuffers.colIndices,\n\t\tpairsU,\n\t\tpairsV,\n\t\tintersections,\n\t\tsizeUs,\n\t\tsizeVs,\n\t\tresults,\n\t\tpairCount: pairCountBuffer,\n\t});\n\tpipeline.with(bindGroup).dispatchThreads(pairCount);\n}\n\nexport { AdamicLayout };\n"],"mappings":"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"}
1
+ {"version":3,"file":"kernel-DolEKSSx.js","names":[],"sources":["../src/gpu/kernels/adamic-adar/kernel.ts"],"sourcesContent":["/**\n * TypeGPU compute kernel for Adamic-Adar index (batch).\n *\n * For each pair (u, v): iterate smaller neighbourhood, detect common neighbours\n * by binary search in the other neighbourhood, sum 1 / log(deg(w) + 1) and\n * normalise by log(2)/count to match CPU normalisation.\n */\n\nimport tgpu, { d, type StorageFlag, type TgpuBuffer } from \"typegpu\";\nimport type { TypedBufferGroup } from \"../../csr\";\nimport type { GraphwiseGPURoot } from \"../../root\";\n\nconst LOG2 = 0.6931471805599453;\n\nconst AdamicLayout = tgpu.bindGroupLayout({\n\trowOffsets: { storage: d.arrayOf(d.u32) },\n\tcolIndices: { storage: d.arrayOf(d.u32) },\n\tpairsU: { storage: d.arrayOf(d.u32) },\n\tpairsV: { storage: d.arrayOf(d.u32) },\n\tintersections: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeUs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeVs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tresults: { storage: d.arrayOf(d.f32), access: \"mutable\" },\n\tpairCount: { uniform: d.u32 },\n});\n\nconst adamicPipeline = (pairIdx: number): void => {\n\t\"use gpu\";\n\tconst u = AdamicLayout.$.pairsU[pairIdx] ?? 0;\n\tconst v = AdamicLayout.$.pairsV[pairIdx] ?? 0;\n\n\tconst uStart = AdamicLayout.$.rowOffsets[u] ?? 0;\n\tconst uEnd = AdamicLayout.$.rowOffsets[u + 1] ?? 0;\n\tconst vStart = AdamicLayout.$.rowOffsets[v] ?? 0;\n\tconst vEnd = AdamicLayout.$.rowOffsets[v + 1] ?? 0;\n\n\tconst degU = uEnd - uStart;\n\tconst degV = vEnd - vStart;\n\n\tAdamicLayout.$.sizeUs[pairIdx] = degU;\n\tAdamicLayout.$.sizeVs[pairIdx] = degV;\n\n\tif (degU === 0 || degV === 0) {\n\t\tAdamicLayout.$.intersections[pairIdx] = 0;\n\t\tAdamicLayout.$.results[pairIdx] = 0.0;\n\t\treturn;\n\t}\n\n\tlet commonCount = 0;\n\tlet sum = 0.0;\n\n\tif (degU <= degV) {\n\t\tfor (let i = uStart; i < uEnd; i = i + 1) {\n\t\t\tconst neighbour = AdamicLayout.$.colIndices[i] ?? 0;\n\t\t\tlet lo = vStart;\n\t\t\tlet hi = vEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = AdamicLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tcommonCount = commonCount + 1;\n\t\t\t\t\tconst wStart = AdamicLayout.$.rowOffsets[neighbour] ?? 0;\n\t\t\t\t\tconst wEnd = AdamicLayout.$.rowOffsets[neighbour + 1] ?? 0;\n\t\t\t\t\tconst degW = wEnd - wStart;\n\t\t\t\t\tconst invLog = 1.0 / Math.log(degW + 1.0);\n\t\t\t\t\tsum = sum + invLog;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor (let i = vStart; i < vEnd; i = i + 1) {\n\t\t\tconst neighbour = AdamicLayout.$.colIndices[i] ?? 0;\n\t\t\tlet lo = uStart;\n\t\t\tlet hi = uEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = AdamicLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tcommonCount = commonCount + 1;\n\t\t\t\t\tconst wStart = AdamicLayout.$.rowOffsets[neighbour] ?? 0;\n\t\t\t\t\tconst wEnd = AdamicLayout.$.rowOffsets[neighbour + 1] ?? 0;\n\t\t\t\t\tconst degW = wEnd - wStart;\n\t\t\t\t\tconst invLog = 1.0 / Math.log(degW + 1.0);\n\t\t\t\t\tsum = sum + invLog;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tAdamicLayout.$.intersections[pairIdx] = commonCount;\n\tif (commonCount === 0) {\n\t\tAdamicLayout.$.results[pairIdx] = 0.0;\n\t} else {\n\t\tAdamicLayout.$.results[pairIdx] = (sum * LOG2) / commonCount;\n\t}\n};\n\nexport function dispatchAdamicAdar(\n\troot: GraphwiseGPURoot,\n\tcsrBuffers: TypedBufferGroup,\n\tpairsU: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairsV: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tresults: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.f32>>> & StorageFlag,\n\tintersections: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> &\n\t\tStorageFlag,\n\tsizeUs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tsizeVs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairCount: number,\n): void {\n\tconst pipeline = root.createGuardedComputePipeline(adamicPipeline);\n\tconst pairCountBuffer = root.createBuffer(d.u32, pairCount).$usage(\"uniform\");\n\tconst bindGroup = root.createBindGroup(AdamicLayout, {\n\t\trowOffsets: csrBuffers.rowOffsets,\n\t\tcolIndices: csrBuffers.colIndices,\n\t\tpairsU,\n\t\tpairsV,\n\t\tintersections,\n\t\tsizeUs,\n\t\tsizeVs,\n\t\tresults,\n\t\tpairCount: pairCountBuffer,\n\t});\n\tpipeline.with(bindGroup).dispatchThreads(pairCount);\n}\n\nexport { AdamicLayout };\n"],"mappings":"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"}
@@ -721,4 +721,4 @@ function dispatchIntersection(root, csrBuffers, pairsU, pairsV, intersections, s
721
721
  //#endregion
722
722
  exports.dispatchIntersection = dispatchIntersection;
723
723
 
724
- //# sourceMappingURL=kernel-DukrXtVb.cjs.map
724
+ //# sourceMappingURL=kernel-E_h47HjZ.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"kernel-DukrXtVb.cjs","names":[],"sources":["../src/gpu/kernels/intersection/kernel.ts"],"sourcesContent":["/**\n * TypeGPU compute kernel for batch neighbourhood intersection.\n *\n * Computes intersection size and neighbourhood sizes for multiple node pairs.\n * One thread per pair: iterates the smaller neighbourhood and binary-searches the other.\n *\n * @module gpu/kernels/intersection/kernel\n */\n\nimport tgpu, { d, type StorageFlag, type TgpuBuffer } from \"typegpu\";\nimport type { TypedBufferGroup } from \"../../csr\";\nimport type { GraphwiseGPURoot } from \"../../root\";\n\n/**\n * Bind group layout for Intersection kernel.\n */\nconst IntersectionLayout = tgpu.bindGroupLayout({\n\trowOffsets: { storage: d.arrayOf(d.u32) },\n\tcolIndices: { storage: d.arrayOf(d.u32) },\n\tpairsU: { storage: d.arrayOf(d.u32) },\n\tpairsV: { storage: d.arrayOf(d.u32) },\n\tintersections: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeUs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeVs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tpairCount: { uniform: d.u32 },\n});\n\n/**\n * Intersection compute pipeline: one thread per pair.\n *\n * For each pair (u, v):\n * - Count intersection by iterating smaller neighbourhood\n * - Binary search in larger neighbourhood\n * - Write intersection, sizeU, sizeV to output buffers\n */\nconst intersectionPipeline = (pairIdx: number): void => {\n\t\"use gpu\";\n\tconst u = IntersectionLayout.$.pairsU[pairIdx] ?? 0;\n\tconst v = IntersectionLayout.$.pairsV[pairIdx] ?? 0;\n\n\tconst uStart = IntersectionLayout.$.rowOffsets[u] ?? 0;\n\tconst uEnd = IntersectionLayout.$.rowOffsets[u + 1] ?? 0;\n\tconst vStart = IntersectionLayout.$.rowOffsets[v] ?? 0;\n\tconst vEnd = IntersectionLayout.$.rowOffsets[v + 1] ?? 0;\n\n\tconst degU = uEnd - uStart;\n\tconst degV = vEnd - vStart;\n\n\t// Write sizes first\n\tIntersectionLayout.$.sizeUs[pairIdx] = degU;\n\tIntersectionLayout.$.sizeVs[pairIdx] = degV;\n\n\t// Empty neighbourhoods → intersection = 0\n\tif (degU === 0 || degV === 0) {\n\t\tIntersectionLayout.$.intersections[pairIdx] = 0;\n\t\treturn;\n\t}\n\n\tlet intersection = 0;\n\n\tif (degU <= degV) {\n\t\t// Iterate u's neighbours, search in v's\n\t\tfor (let i = uStart; i < uEnd; i = i + 1) {\n\t\t\tconst neighbour = IntersectionLayout.$.colIndices[i] ?? 0;\n\t\t\t// Binary search in v's neighbourhood\n\t\t\tlet lo = vStart;\n\t\t\tlet hi = vEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = IntersectionLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tintersection = intersection + 1;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// Iterate v's neighbours, search in u's\n\t\tfor (let i = vStart; i < vEnd; i = i + 1) {\n\t\t\tconst neighbour = IntersectionLayout.$.colIndices[i] ?? 0;\n\t\t\t// Binary search in u's neighbourhood\n\t\t\tlet lo = uStart;\n\t\t\tlet hi = uEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = IntersectionLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tintersection = intersection + 1;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tIntersectionLayout.$.intersections[pairIdx] = intersection;\n};\n\n/**\n * Dispatch batch intersection on GPU.\n *\n * @param root - TypeGPU root instance\n * @param csrBuffers - CSR matrix as typed buffers\n * @param pairsU - First node of each pair (u32 array)\n * @param pairsV - Second node of each pair (u32 array)\n * @param intersections - Output intersections (u32 array, mutable)\n * @param sizeUs - Output sizeU per pair (u32 array, mutable)\n * @param sizeVs - Output sizeV per pair (u32 array, mutable)\n * @param pairCount - Number of pairs to compute\n */\nexport function dispatchIntersection(\n\troot: GraphwiseGPURoot,\n\tcsrBuffers: TypedBufferGroup,\n\tpairsU: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairsV: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tintersections: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> &\n\t\tStorageFlag,\n\tsizeUs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tsizeVs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairCount: number,\n): void {\n\tconst pipeline = root.createGuardedComputePipeline(intersectionPipeline);\n\n\tconst pairCountBuffer = root.createBuffer(d.u32, pairCount).$usage(\"uniform\");\n\n\tconst bindGroup = root.createBindGroup(IntersectionLayout, {\n\t\trowOffsets: csrBuffers.rowOffsets,\n\t\tcolIndices: csrBuffers.colIndices,\n\t\tpairsU,\n\t\tpairsV,\n\t\tintersections,\n\t\tsizeUs,\n\t\tsizeVs,\n\t\tpairCount: pairCountBuffer,\n\t});\n\n\tpipeline.with(bindGroup).dispatchThreads(pairCount);\n}\n\nexport { IntersectionLayout };\n"],"mappings":"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"}
1
+ {"version":3,"file":"kernel-E_h47HjZ.cjs","names":[],"sources":["../src/gpu/kernels/intersection/kernel.ts"],"sourcesContent":["/**\n * TypeGPU compute kernel for batch neighbourhood intersection.\n *\n * Computes intersection size and neighbourhood sizes for multiple node pairs.\n * One thread per pair: iterates the smaller neighbourhood and binary-searches the other.\n *\n * @module gpu/kernels/intersection/kernel\n */\n\nimport tgpu, { d, type StorageFlag, type TgpuBuffer } from \"typegpu\";\nimport type { TypedBufferGroup } from \"../../csr\";\nimport type { GraphwiseGPURoot } from \"../../root\";\n\n/**\n * Bind group layout for Intersection kernel.\n */\nconst IntersectionLayout = tgpu.bindGroupLayout({\n\trowOffsets: { storage: d.arrayOf(d.u32) },\n\tcolIndices: { storage: d.arrayOf(d.u32) },\n\tpairsU: { storage: d.arrayOf(d.u32) },\n\tpairsV: { storage: d.arrayOf(d.u32) },\n\tintersections: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeUs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeVs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tpairCount: { uniform: d.u32 },\n});\n\n/**\n * Intersection compute pipeline: one thread per pair.\n *\n * For each pair (u, v):\n * - Count intersection by iterating smaller neighbourhood\n * - Binary search in larger neighbourhood\n * - Write intersection, sizeU, sizeV to output buffers\n */\nconst intersectionPipeline = (pairIdx: number): void => {\n\t\"use gpu\";\n\tconst u = IntersectionLayout.$.pairsU[pairIdx] ?? 0;\n\tconst v = IntersectionLayout.$.pairsV[pairIdx] ?? 0;\n\n\tconst uStart = IntersectionLayout.$.rowOffsets[u] ?? 0;\n\tconst uEnd = IntersectionLayout.$.rowOffsets[u + 1] ?? 0;\n\tconst vStart = IntersectionLayout.$.rowOffsets[v] ?? 0;\n\tconst vEnd = IntersectionLayout.$.rowOffsets[v + 1] ?? 0;\n\n\tconst degU = uEnd - uStart;\n\tconst degV = vEnd - vStart;\n\n\t// Write sizes first\n\tIntersectionLayout.$.sizeUs[pairIdx] = degU;\n\tIntersectionLayout.$.sizeVs[pairIdx] = degV;\n\n\t// Empty neighbourhoods → intersection = 0\n\tif (degU === 0 || degV === 0) {\n\t\tIntersectionLayout.$.intersections[pairIdx] = 0;\n\t\treturn;\n\t}\n\n\tlet intersection = 0;\n\n\tif (degU <= degV) {\n\t\t// Iterate u's neighbours, search in v's\n\t\tfor (let i = uStart; i < uEnd; i = i + 1) {\n\t\t\tconst neighbour = IntersectionLayout.$.colIndices[i] ?? 0;\n\t\t\t// Binary search in v's neighbourhood\n\t\t\tlet lo = vStart;\n\t\t\tlet hi = vEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = IntersectionLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tintersection = intersection + 1;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// Iterate v's neighbours, search in u's\n\t\tfor (let i = vStart; i < vEnd; i = i + 1) {\n\t\t\tconst neighbour = IntersectionLayout.$.colIndices[i] ?? 0;\n\t\t\t// Binary search in u's neighbourhood\n\t\t\tlet lo = uStart;\n\t\t\tlet hi = uEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = IntersectionLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tintersection = intersection + 1;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tIntersectionLayout.$.intersections[pairIdx] = intersection;\n};\n\n/**\n * Dispatch batch intersection on GPU.\n *\n * @param root - TypeGPU root instance\n * @param csrBuffers - CSR matrix as typed buffers\n * @param pairsU - First node of each pair (u32 array)\n * @param pairsV - Second node of each pair (u32 array)\n * @param intersections - Output intersections (u32 array, mutable)\n * @param sizeUs - Output sizeU per pair (u32 array, mutable)\n * @param sizeVs - Output sizeV per pair (u32 array, mutable)\n * @param pairCount - Number of pairs to compute\n */\nexport function dispatchIntersection(\n\troot: GraphwiseGPURoot,\n\tcsrBuffers: TypedBufferGroup,\n\tpairsU: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairsV: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tintersections: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> &\n\t\tStorageFlag,\n\tsizeUs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tsizeVs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairCount: number,\n): void {\n\tconst pipeline = root.createGuardedComputePipeline(intersectionPipeline);\n\n\tconst pairCountBuffer = root.createBuffer(d.u32, pairCount).$usage(\"uniform\");\n\n\tconst bindGroup = root.createBindGroup(IntersectionLayout, {\n\t\trowOffsets: csrBuffers.rowOffsets,\n\t\tcolIndices: csrBuffers.colIndices,\n\t\tpairsU,\n\t\tpairsV,\n\t\tintersections,\n\t\tsizeUs,\n\t\tsizeVs,\n\t\tpairCount: pairCountBuffer,\n\t});\n\n\tpipeline.with(bindGroup).dispatchThreads(pairCount);\n}\n\nexport { IntersectionLayout };\n"],"mappings":"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"}
@@ -721,4 +721,4 @@ function dispatchIntersection(root, csrBuffers, pairsU, pairsV, intersections, s
721
721
  //#endregion
722
722
  export { dispatchIntersection };
723
723
 
724
- //# sourceMappingURL=kernel-6deK9fh1.js.map
724
+ //# sourceMappingURL=kernel-lYa4TYth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"kernel-6deK9fh1.js","names":[],"sources":["../src/gpu/kernels/intersection/kernel.ts"],"sourcesContent":["/**\n * TypeGPU compute kernel for batch neighbourhood intersection.\n *\n * Computes intersection size and neighbourhood sizes for multiple node pairs.\n * One thread per pair: iterates the smaller neighbourhood and binary-searches the other.\n *\n * @module gpu/kernels/intersection/kernel\n */\n\nimport tgpu, { d, type StorageFlag, type TgpuBuffer } from \"typegpu\";\nimport type { TypedBufferGroup } from \"../../csr\";\nimport type { GraphwiseGPURoot } from \"../../root\";\n\n/**\n * Bind group layout for Intersection kernel.\n */\nconst IntersectionLayout = tgpu.bindGroupLayout({\n\trowOffsets: { storage: d.arrayOf(d.u32) },\n\tcolIndices: { storage: d.arrayOf(d.u32) },\n\tpairsU: { storage: d.arrayOf(d.u32) },\n\tpairsV: { storage: d.arrayOf(d.u32) },\n\tintersections: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeUs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeVs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tpairCount: { uniform: d.u32 },\n});\n\n/**\n * Intersection compute pipeline: one thread per pair.\n *\n * For each pair (u, v):\n * - Count intersection by iterating smaller neighbourhood\n * - Binary search in larger neighbourhood\n * - Write intersection, sizeU, sizeV to output buffers\n */\nconst intersectionPipeline = (pairIdx: number): void => {\n\t\"use gpu\";\n\tconst u = IntersectionLayout.$.pairsU[pairIdx] ?? 0;\n\tconst v = IntersectionLayout.$.pairsV[pairIdx] ?? 0;\n\n\tconst uStart = IntersectionLayout.$.rowOffsets[u] ?? 0;\n\tconst uEnd = IntersectionLayout.$.rowOffsets[u + 1] ?? 0;\n\tconst vStart = IntersectionLayout.$.rowOffsets[v] ?? 0;\n\tconst vEnd = IntersectionLayout.$.rowOffsets[v + 1] ?? 0;\n\n\tconst degU = uEnd - uStart;\n\tconst degV = vEnd - vStart;\n\n\t// Write sizes first\n\tIntersectionLayout.$.sizeUs[pairIdx] = degU;\n\tIntersectionLayout.$.sizeVs[pairIdx] = degV;\n\n\t// Empty neighbourhoods → intersection = 0\n\tif (degU === 0 || degV === 0) {\n\t\tIntersectionLayout.$.intersections[pairIdx] = 0;\n\t\treturn;\n\t}\n\n\tlet intersection = 0;\n\n\tif (degU <= degV) {\n\t\t// Iterate u's neighbours, search in v's\n\t\tfor (let i = uStart; i < uEnd; i = i + 1) {\n\t\t\tconst neighbour = IntersectionLayout.$.colIndices[i] ?? 0;\n\t\t\t// Binary search in v's neighbourhood\n\t\t\tlet lo = vStart;\n\t\t\tlet hi = vEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = IntersectionLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tintersection = intersection + 1;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// Iterate v's neighbours, search in u's\n\t\tfor (let i = vStart; i < vEnd; i = i + 1) {\n\t\t\tconst neighbour = IntersectionLayout.$.colIndices[i] ?? 0;\n\t\t\t// Binary search in u's neighbourhood\n\t\t\tlet lo = uStart;\n\t\t\tlet hi = uEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = IntersectionLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tintersection = intersection + 1;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tIntersectionLayout.$.intersections[pairIdx] = intersection;\n};\n\n/**\n * Dispatch batch intersection on GPU.\n *\n * @param root - TypeGPU root instance\n * @param csrBuffers - CSR matrix as typed buffers\n * @param pairsU - First node of each pair (u32 array)\n * @param pairsV - Second node of each pair (u32 array)\n * @param intersections - Output intersections (u32 array, mutable)\n * @param sizeUs - Output sizeU per pair (u32 array, mutable)\n * @param sizeVs - Output sizeV per pair (u32 array, mutable)\n * @param pairCount - Number of pairs to compute\n */\nexport function dispatchIntersection(\n\troot: GraphwiseGPURoot,\n\tcsrBuffers: TypedBufferGroup,\n\tpairsU: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairsV: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tintersections: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> &\n\t\tStorageFlag,\n\tsizeUs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tsizeVs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairCount: number,\n): void {\n\tconst pipeline = root.createGuardedComputePipeline(intersectionPipeline);\n\n\tconst pairCountBuffer = root.createBuffer(d.u32, pairCount).$usage(\"uniform\");\n\n\tconst bindGroup = root.createBindGroup(IntersectionLayout, {\n\t\trowOffsets: csrBuffers.rowOffsets,\n\t\tcolIndices: csrBuffers.colIndices,\n\t\tpairsU,\n\t\tpairsV,\n\t\tintersections,\n\t\tsizeUs,\n\t\tsizeVs,\n\t\tpairCount: pairCountBuffer,\n\t});\n\n\tpipeline.with(bindGroup).dispatchThreads(pairCount);\n}\n\nexport { IntersectionLayout };\n"],"mappings":"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"}
1
+ {"version":3,"file":"kernel-lYa4TYth.js","names":[],"sources":["../src/gpu/kernels/intersection/kernel.ts"],"sourcesContent":["/**\n * TypeGPU compute kernel for batch neighbourhood intersection.\n *\n * Computes intersection size and neighbourhood sizes for multiple node pairs.\n * One thread per pair: iterates the smaller neighbourhood and binary-searches the other.\n *\n * @module gpu/kernels/intersection/kernel\n */\n\nimport tgpu, { d, type StorageFlag, type TgpuBuffer } from \"typegpu\";\nimport type { TypedBufferGroup } from \"../../csr\";\nimport type { GraphwiseGPURoot } from \"../../root\";\n\n/**\n * Bind group layout for Intersection kernel.\n */\nconst IntersectionLayout = tgpu.bindGroupLayout({\n\trowOffsets: { storage: d.arrayOf(d.u32) },\n\tcolIndices: { storage: d.arrayOf(d.u32) },\n\tpairsU: { storage: d.arrayOf(d.u32) },\n\tpairsV: { storage: d.arrayOf(d.u32) },\n\tintersections: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeUs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tsizeVs: { storage: d.arrayOf(d.u32), access: \"mutable\" },\n\tpairCount: { uniform: d.u32 },\n});\n\n/**\n * Intersection compute pipeline: one thread per pair.\n *\n * For each pair (u, v):\n * - Count intersection by iterating smaller neighbourhood\n * - Binary search in larger neighbourhood\n * - Write intersection, sizeU, sizeV to output buffers\n */\nconst intersectionPipeline = (pairIdx: number): void => {\n\t\"use gpu\";\n\tconst u = IntersectionLayout.$.pairsU[pairIdx] ?? 0;\n\tconst v = IntersectionLayout.$.pairsV[pairIdx] ?? 0;\n\n\tconst uStart = IntersectionLayout.$.rowOffsets[u] ?? 0;\n\tconst uEnd = IntersectionLayout.$.rowOffsets[u + 1] ?? 0;\n\tconst vStart = IntersectionLayout.$.rowOffsets[v] ?? 0;\n\tconst vEnd = IntersectionLayout.$.rowOffsets[v + 1] ?? 0;\n\n\tconst degU = uEnd - uStart;\n\tconst degV = vEnd - vStart;\n\n\t// Write sizes first\n\tIntersectionLayout.$.sizeUs[pairIdx] = degU;\n\tIntersectionLayout.$.sizeVs[pairIdx] = degV;\n\n\t// Empty neighbourhoods → intersection = 0\n\tif (degU === 0 || degV === 0) {\n\t\tIntersectionLayout.$.intersections[pairIdx] = 0;\n\t\treturn;\n\t}\n\n\tlet intersection = 0;\n\n\tif (degU <= degV) {\n\t\t// Iterate u's neighbours, search in v's\n\t\tfor (let i = uStart; i < uEnd; i = i + 1) {\n\t\t\tconst neighbour = IntersectionLayout.$.colIndices[i] ?? 0;\n\t\t\t// Binary search in v's neighbourhood\n\t\t\tlet lo = vStart;\n\t\t\tlet hi = vEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = IntersectionLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tintersection = intersection + 1;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// Iterate v's neighbours, search in u's\n\t\tfor (let i = vStart; i < vEnd; i = i + 1) {\n\t\t\tconst neighbour = IntersectionLayout.$.colIndices[i] ?? 0;\n\t\t\t// Binary search in u's neighbourhood\n\t\t\tlet lo = uStart;\n\t\t\tlet hi = uEnd;\n\t\t\twhile (lo < hi) {\n\t\t\t\tconst mid = lo + (hi - lo) / 2;\n\t\t\t\tconst midVal = IntersectionLayout.$.colIndices[mid] ?? 0;\n\t\t\t\tif (midVal === neighbour) {\n\t\t\t\t\tintersection = intersection + 1;\n\t\t\t\t\tlo = hi; // break\n\t\t\t\t} else if (midVal < neighbour) {\n\t\t\t\t\tlo = mid + 1;\n\t\t\t\t} else {\n\t\t\t\t\thi = mid;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tIntersectionLayout.$.intersections[pairIdx] = intersection;\n};\n\n/**\n * Dispatch batch intersection on GPU.\n *\n * @param root - TypeGPU root instance\n * @param csrBuffers - CSR matrix as typed buffers\n * @param pairsU - First node of each pair (u32 array)\n * @param pairsV - Second node of each pair (u32 array)\n * @param intersections - Output intersections (u32 array, mutable)\n * @param sizeUs - Output sizeU per pair (u32 array, mutable)\n * @param sizeVs - Output sizeV per pair (u32 array, mutable)\n * @param pairCount - Number of pairs to compute\n */\nexport function dispatchIntersection(\n\troot: GraphwiseGPURoot,\n\tcsrBuffers: TypedBufferGroup,\n\tpairsU: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairsV: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tintersections: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> &\n\t\tStorageFlag,\n\tsizeUs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tsizeVs: TgpuBuffer<ReturnType<typeof d.arrayOf<typeof d.u32>>> & StorageFlag,\n\tpairCount: number,\n): void {\n\tconst pipeline = root.createGuardedComputePipeline(intersectionPipeline);\n\n\tconst pairCountBuffer = root.createBuffer(d.u32, pairCount).$usage(\"uniform\");\n\n\tconst bindGroup = root.createBindGroup(IntersectionLayout, {\n\t\trowOffsets: csrBuffers.rowOffsets,\n\t\tcolIndices: csrBuffers.colIndices,\n\t\tpairsU,\n\t\tpairsV,\n\t\tintersections,\n\t\tsizeUs,\n\t\tsizeVs,\n\t\tpairCount: pairCountBuffer,\n\t});\n\n\tpipeline.with(bindGroup).dispatchThreads(pairCount);\n}\n\nexport { IntersectionLayout };\n"],"mappings":"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"}
@@ -1976,7 +1976,7 @@ async function gpuMIBatch(graph, pairs, variant = "jaccard", options) {
1976
1976
  const sizeVsBuffer = (globalThis.__TYPEGPU_AUTONAME__ ?? ((a) => a))(root.createBuffer(require_typegpu.data_exports.arrayOf(require_typegpu.data_exports.u32, pairCount)).$usage("storage"), "sizeVsBuffer");
1977
1977
  if (variant === "adamic-adar") {
1978
1978
  const resultsBuffer = (globalThis.__TYPEGPU_AUTONAME__ ?? ((a) => a))(root.createBuffer(require_typegpu.data_exports.arrayOf(require_typegpu.data_exports.f32, pairCount)).$usage("storage"), "resultsBuffer");
1979
- const { dispatchAdamicAdar } = await Promise.resolve().then(() => require("./kernel-2oH4Cn32.cjs"));
1979
+ const { dispatchAdamicAdar } = await Promise.resolve().then(() => require("./kernel-BffKjhZS.cjs"));
1980
1980
  dispatchAdamicAdar(root, csrBuffers, pairsUBuffer, pairsVBuffer, resultsBuffer, intersectionsBuffer, sizeUsBuffer, sizeVsBuffer, pairCount);
1981
1981
  const scoresRaw = await resultsBuffer.read();
1982
1982
  const intersectionsRaw = await intersectionsBuffer.read();
@@ -1999,7 +1999,7 @@ async function gpuMIBatch(graph, pairs, variant = "jaccard", options) {
1999
1999
  sizeVs
2000
2000
  };
2001
2001
  } else {
2002
- const { dispatchIntersection } = await Promise.resolve().then(() => require("./kernel-DukrXtVb.cjs"));
2002
+ const { dispatchIntersection } = await Promise.resolve().then(() => require("./kernel-E_h47HjZ.cjs"));
2003
2003
  dispatchIntersection(root, csrBuffers, pairsUBuffer, pairsVBuffer, intersectionsBuffer, sizeUsBuffer, sizeVsBuffer, pairCount);
2004
2004
  const intersectionsRaw = await intersectionsBuffer.read();
2005
2005
  const sizeUsRaw = await sizeUsBuffer.read();
@@ -2177,7 +2177,7 @@ async function gpuKMeansAssign(points, centroids, options) {
2177
2177
  const centroidsBuffer = (globalThis.__TYPEGPU_AUTONAME__ ?? ((a) => a))(root.createBuffer(require_typegpu.data_exports.arrayOf(require_typegpu.data_exports.vec3f, k), Array.from(centroids)).$usage("storage"), "centroidsBuffer");
2178
2178
  const assignmentsBuffer = (globalThis.__TYPEGPU_AUTONAME__ ?? ((a) => a))(root.createBuffer(require_typegpu.data_exports.arrayOf(require_typegpu.data_exports.u32, pointCount)).$usage("storage"), "assignmentsBuffer");
2179
2179
  const distancesBuffer = (globalThis.__TYPEGPU_AUTONAME__ ?? ((a) => a))(root.createBuffer(require_typegpu.data_exports.arrayOf(require_typegpu.data_exports.f32, pointCount)).$usage("storage"), "distancesBuffer");
2180
- const { dispatchKMeansAssign: dispatch } = await Promise.resolve().then(() => require("./kernel-CXeGBH3s.cjs"));
2180
+ const { dispatchKMeansAssign: dispatch } = await Promise.resolve().then(() => require("./kernel-CbP715Sq.cjs"));
2181
2181
  dispatch(root, pointsBuffer, centroidsBuffer, assignmentsBuffer, distancesBuffer, pointCount, k);
2182
2182
  const assignments = await assignmentsBuffer.read();
2183
2183
  const distances = await distancesBuffer.read();
@@ -2266,4 +2266,4 @@ Object.defineProperty(exports, "withBackend", {
2266
2266
  }
2267
2267
  });
2268
2268
 
2269
- //# sourceMappingURL=operations-D-RB67WP.cjs.map
2269
+ //# sourceMappingURL=operations-CSU0yFPr.cjs.map