Expand description
GPU-compute force-directed layout — the elite engine’s must-land core.
A wgpu compute-shader n-body layout: per-node weights + CSR adjacency are
streamed from an Arrow edge batch straight into GPU storage buffers, and the
node positions then iterate in VRAM (ping-pong src→dst, no readback per
step) until they settle. The host reads the converged positions back as plain
[f32; 2] DATA — exactly the contract a headless test asserts on.
This is the answer to the layout-perf-at-scale curse: the all-pairs repulsion
is the same O(n²) compute pattern as the boids in
[facett_core::render::gpu::particles] (reused verbatim — storage ping-pong, a
@workgroup_size(64) kernel, the headless request_adapter device probe), so a
10k–100k-node re-layout runs in real time on the GPU instead of the CPU.
§Force model (Fruchterman-Reingold, velocity-integrated)
For node i with mass wᵢ (its streamed weight):
- repulsion from every other node
j: a Fruchterman-Reingoldk/dpush,rep · wᵢ · wⱼ · (pᵢ − pⱼ) / dist²— the(pᵢ−pⱼ)numerator carries onedist, so the magnitude isrep·wᵢ·wⱼ / dist(heavier nodes shove harder → important nodes claim space), - attraction along each CSR neighbour
t: a Hooke springattr · (dist − ideal) · (pₜ − pᵢ)/dist(pulls connected nodes toideal_len), - gravity
−grav · pᵢkeeps the component centred, - integrate
v ← (v + F/wᵢ·dt)·damp,p ← p + v·dt(heavy nodes move slower).
It is a pure, deterministic function of the seed + params + step count (FC-7):
no RNG (the seed is a golden-angle spiral), fixed loop order. The CPU
step_cpu is the no-GPU fallback and the parity reference the GPU
readback proof checks against — the WGSL cs_layout mirrors it line-for-line.
§Roadmap (see .nornir/elite-graph-engine.md)
The O(n²) repulsion is the foundation; a GPU Barnes-Hut quadtree (or a Morton / grid binning) drops it to O(n log n) for the 100k case — documented there, not built here, because the foundation must land + test clean first.
Structs§
- Graph
Csr - CSR (compressed-sparse-row) adjacency + per-node weight — the GPU-streamable
graph.
offsets[i]..offsets[i+1]indexes intotargetsfor nodei’s neighbours;weights[i]is nodei’s mass. The threeVecs map 1:1 onto the three GPU storage buffers (offsets/targetsread-only,weightspacked into the node buffer), so this is the upload format — no repack at the seam. - Layout
Params - Force-layout tuning.
Defaultis a calm, convergent spring system. - Layout
State - The mutable layout state: one position + velocity per node (the ping-pong the GPU iterates in VRAM; here, the CPU mirror). Positions are the DATA a test reads.
Functions§
- relax_
cpu - Run the CPU fallback to convergence: seed, then
itersstep_cpus. Returns the settled state (positions = DATA). Deterministic in(g, p, iters). - step_
cpu - One CPU force step — the no-GPU fallback and the parity reference the WGSL
cs_layoutmirrors exactly. Pure:step_cpu(s)depends only ons,g,p.