lumbda/www/bend.html
russell@unturf.com a4613b685e
bend.html: rewrite back to focused doc shape
Page had accreted session debugging (Form D structural finding,
opt 1/opt 3 narrative, Day-4 v4 regression notes, robustness fix
narrative, first measured sweep paragraphs). Stripped all of it.

What stays:
  - what bend is
  - start a worker
  - call it
  - wire protocol (S-exp vs binary modes + measured table)
  - fleet (2-host cluster table + brief coexistence note + cluster
    aggregate numbers)
  - catalog: live forms (5) + Wave 1 (A-G detailed) + Wave 2 + 3
    (compact tables) + why-a-form-earns-its-slot criteria
  - source pointers

What goes (back to CATALOG.md / plan docs where they belong):
  - Form D structural finding paragraph
  - Form D opt 1 + opt 3 RESULTS narrative
  - Day-4 v4 regression detail in the secp row
  - First measured ECDSA-mission sweep paragraphs
  - Robustness gap fix paragraph

Page length: 371 → ~226 lines. Reads as a reference doc again
instead of a session log.
2026-06-05 21:26:20 -04:00

256 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>bend — Lumbda's GPU dispatch primitive</title>
<meta name="description" content="bend is Lumbda's GPU dispatch primitive: cost-routed local-vs-remote execution over a wire protocol, with a catalog of CUDA forms each backed by published speedup benchmarks.">
<link rel="stylesheet" href="style.css">
<script src="https://uncloseai.com/uncloseai.js" type="module"></script>
</head>
<body>
<header>
<h1 aria-label="lumbda."><a href="index.html" style="color:inherit;text-decoration:none">lumbda<span class="period" aria-hidden="true">.</span></a></h1>
<img class="lambda-mark" src="lumbda-logo-green.png?v=2" alt="" aria-hidden="true">
<p class="tagline">bend &mdash; dispatch to a GPU without rewriting your code</p>
</header>
<main>
<section id="what">
<p class="lead">
<code>bend</code> is a Lumbda primitive that decides per call whether to evaluate locally or ship to a CUDA worker over our wire protocol. Tiny inputs stay local; heavy inputs bend to a worker that holds a warm CUDA context across requests. The decision uses a cost estimator on the argument shape, not the operation name.
</p>
</section>
<section id="start">
<h2>Start a GPU worker</h2>
<pre><code># On any host with nvcc + a CUDA-capable GPU:
make gpu-worker
# → builds examples/cuda-fanout/shake256-fanout
# → builds the C tier (~10× faster wire orchestration than Python)
# → launches gpu-worker.lsp on port 9091
# Override tier or port:
make gpu-worker LUMBDA=python PORT=9001 # easier debugging
make gpu-worker LUMBDA=asm # smallest footprint</code></pre>
</section>
<section id="call">
<h2>Call it from any tier</h2>
<pre><code>;; bend works on every tier — Python, C, asm — through the same
;; tcp-* + portal primitives lumbda already ships.
(load "examples/cuda-fanout/wire.lsp")
(load "examples/cuda-fanout/bend.lsp")
(load "examples/cuda-fanout/bend-macros.lsp") ; Python/C only — asm uses bend-call
;; Tiny — cost below threshold, evaluates locally
(bend (cuda-shake-fanout '("00" "01" "deadbeef") 32))
;; Heavy — cost above threshold, ships to the GPU worker
(bend (cuda-shake-fanout one-million-inputs 32))</code></pre>
</section>
<section id="protocol">
<h2>Wire protocol</h2>
<p>Two modes: <strong>S-expression text</strong> (the default) and <strong>binary</strong> (magic <code>BSHK</code> header + raw bytes). Binary mode bypasses S-expression parsing entirely.</p>
<table>
<thead><tr><th>workload</th><th>Py S-exp</th><th>Py binary</th><th>C S-exp</th><th>C binary</th></tr></thead>
<tbody>
<tr><td>100 × 16 B</td><td>3.43 ms</td><td>0.74 ms</td><td>0.40 ms</td><td><strong>0.15 ms</strong></td></tr>
<tr><td>1k × 16 B</td><td>23.24 ms</td><td>0.76 ms</td><td>2.77 ms</td><td><strong>0.22 ms</strong></td></tr>
<tr><td>10k × 16 B</td><td>218.82 ms</td><td>1.27 ms</td><td>CLIFF</td><td><strong>0.88 ms</strong></td></tr>
<tr><td>100k × 16 B</td><td>2,219 ms</td><td>10.18 ms</td><td>CLIFF</td><td><strong>10.35 ms</strong></td></tr>
<tr><td>1M × 16 B</td><td>23,811 ms</td><td>159 ms</td><td>CLIFF</td><td><strong>157 ms</strong></td></tr>
</tbody>
</table>
<p>Binary mode wins by 30&ndash;200&times; over S-expression mode at scale. At 1 M × 16 B inputs, C tier binary is 157 ms end-to-end versus 23,811 ms for the S-exp path. At that scale bend beats host hashlib by ~12&times;.</p>
<p>The CUDA toolchain stays isolated to the leaf binary the worker spawns. No tier links libcudart; no tier requires nvcc at build time. Asm tier hosts workers through hand-written <code>pipe2 + fork + execve</code> syscalls.</p>
</section>
<section id="fleet">
<h2>Fleet</h2>
<p>bend runs on a 2-host LAN cluster. Round-robin selection lives in <code>bend.lsp</code> via <code>*bend-workers*</code> &amp; the <code>BEND_WORKERS</code> environment variable.</p>
<table>
<thead><tr><th>host</th><th>GPU</th><th>arch</th><th>port</th><th>coexists with</th></tr></thead>
<tbody>
<tr><td><code>3090-ai.foxhop.net</code></td><td>RTX 3090 (24 GB)</td><td>sm_86</td><td>9091</td><td>idle</td></tr>
<tr><td><code>ai.foxhop.net</code></td><td>RTX 4090 (24 GB)</td><td>sm_89</td><td>9092</td><td>qwen LLM (llama.cpp) on GPU</td></tr>
</tbody>
</table>
<p>The 4090 box shares its GPU with a qwen LLM. Bend kernels fit alongside because secp256k1 / CGBN workloads burn SMs for milliseconds at a time then release; qwen keeps its weights resident, bend allocates transient VRAM per call. 24 GB VRAM holds both.</p>
<p>Cluster aggregate (round-robin fan-out, sequential dispatcher): 1.6&times; at 200 × <code>n=1k</code> CGBN mod-mul, 1.2&times; at 6 × <code>n=100k</code>. Cap is client-side serialization; an async dispatcher unlocks the remaining 2&times; headroom. Workers themselves never block each other.</p>
</section>
<section id="catalog">
<h2>Form catalog</h2>
<p>A form earns a slot here only after we have published a benchmark or measured one on our hardware. "I think this would be fast" does not earn a slot &mdash; the form-status column says <code>planned</code> until numbers exist.</p>
<h3>Status legend</h3>
<ul>
<li><code>live</code> &mdash; binary built, worker dispatches it, numbers recorded on our hardware</li>
<li><code>surveyed</code> &mdash; published benchmark cited, prototype binary not yet wrapped</li>
</ul>
<h3>Live forms</h3>
<table>
<thead><tr><th>form</th><th>hardware</th><th>throughput</th><th>wire shape</th></tr></thead>
<tbody>
<tr>
<td><code>cuda-shake-fanout</code></td>
<td>RTX 3090</td>
<td>12&times; host hashlib at 1 M × 16 B inputs</td>
<td><code>(cuda-shake-fanout '(hex ...) out-bytes)</code> + <code>BSHK</code> binary</td>
</tr>
<tr>
<td><code>cuda-sim-ops-bin</code></td>
<td>RTX 3090</td>
<td>1.07&times; at 128 batches; crossover ~115 batches</td>
<td><code>(cuda-sim-ops-bin "path/to/ops.bin" n-batches)</code></td>
</tr>
<tr>
<td><code>cuda-sim-axis-flip</code></td>
<td>RTX 3090</td>
<td>217 Mops/s @ K=32 M=4 (many-candidates × few-shots)</td>
<td><code>(cuda-sim-axis (variant-paths ...) n-shots)</code></td>
</tr>
<tr>
<td><code>cuda-bignum-cgbn</code></td>
<td>RTX 3090</td>
<td>1.28 Gops/s kernel mod-mul @ n=1M (256-bit, ~256&times; GMP CPU); 9 ops</td>
<td><code>BCGB</code> binary: op_id + bitwidth + n + modulus + a + b</td>
</tr>
<tr>
<td><code>cuda-secp256k1-batched-mul</code></td>
<td>RTX 3090</td>
<td>13.83 Mkeys/s @ n=1M (~309&times; coincurve CPU; windowed-G ladder w=4)</td>
<td><code>BSCP</code> binary: scalars + base-point &rarr; <code>BSCR</code> points</td>
</tr>
</tbody>
</table>
<h3>Surveyed forms (Wave 1)</h3>
<h4>A. <code>cuda-secp256k1-batched-mul</code> &mdash; batched secp256k1 scalar / point ops</h4>
<p><strong>Reference numbers:</strong> gECC 4.94&times; on unknown-point mul, 5.56&times; on ECDSA verify vs CPU. VanitySearch forks hit 6.5 Gkeys/s on RTX 4090, 8.6 Gkeys/s on RTX 5090, 2.65 Gkeys/s on RTX 3080.</p>
<p><strong>Wire:</strong> <code>(secp-mul-batch (scalars . blob&lt;N×32B&gt;) (base-point . blob&lt;64B&gt;))</code> &rarr; <code>(points . blob&lt;N×64B&gt;)</code></p>
<p><strong>Refs:</strong> <a href="https://arxiv.org/pdf/2501.03245">gECC paper</a> &middot; <a href="https://github.com/JeanLucPons/VanitySearch">VanitySearch</a> &middot; <a href="https://github.com/FixedPaul/VanitySearch-Bitcrack">VanitySearch-Bitcrack</a></p>
<h4>B. <code>cuda-bignum-cgbn</code> &mdash; 256-bit modular arithmetic primitives</h4>
<p><strong>Reference numbers:</strong> 100&times;+ on dense mul vs Xeon-20c + GMP + OpenMP on V100.</p>
<p><strong>Wire:</strong> <code>(cgbn-batch (op . mod-mul|mod-inv|mod-add) (modulus . blob&lt;32B&gt;) (a . blob&lt;N×32B&gt;) (b . blob&lt;N×32B&gt;))</code> &rarr; <code>blob&lt;N×32B&gt;</code></p>
<p><strong>Refs:</strong> <a href="https://github.com/NVlabs/CGBN">NVlabs CGBN</a> &middot; <a href="https://arxiv.org/pdf/2405.14642">midsize-int benchmarks</a></p>
<h4>C. <code>cuda-rho-pollard-walk</code> &mdash; Pollard rho / kangaroo walks</h4>
<p><strong>Reference numbers:</strong> 87.7 M ops/sec on RTX 2070 Super for ECCp79. Original CUDA Pollard paper reports &gt; 7.2 M points/sec at 256 threads on older hardware.</p>
<p><strong>Wire:</strong> <code>(rho-walk-batch (start-points . blob&lt;W×64B&gt;) (steps . N) (distinguished-mask . blob&lt;32B&gt;))</code> &rarr; <code>(distinguished . blob&lt;K×96B&gt;)</code></p>
<p><strong>Refs:</strong> <a href="https://github.com/atlomak/CUDA-rho-pollard">atlomak/CUDA-rho-pollard</a> &middot; <a href="https://github.com/oritwoen/kangaroo">oritwoen/kangaroo</a></p>
<h4>D. <code>cuda-clifford-stabilizer</code> &mdash; tableau stabilizer simulator (Stim-on-GPU)</h4>
<p><strong>Reference numbers:</strong> 186&times; over Stim (CPU SOTA) on equivalence-checking.</p>
<p><strong>Wire:</strong> <code>(stab-sim-batch (n-qubits . k) (circuit . blob) (n-shots . S))</code> &rarr; <code>(samples . blob&lt;S×ceil(k/8)&gt;)</code></p>
<p><strong>Refs:</strong> <a href="https://arxiv.org/abs/2507.03092">STABSim</a> &middot; <a href="https://arxiv.org/abs/2505.03307">Qimax</a> &middot; <a href="https://arxiv.org/pdf/2603.14641">equivalence-checking</a></p>
<h4>E. <code>cuda-bernstein-yang-inv</code> &mdash; batched modular inverse (safegcd)</h4>
<p><strong>Reference numbers:</strong> 3&ndash;10&times; per inversion over Fermat on CPU. No published dedicated CUDA implementation; Standalone Bernstein-Yang-on-CUDA holds novel territory.</p>
<p><strong>Wire:</strong> <code>(modinv-batch (modulus . blob&lt;32B&gt;) (xs . blob&lt;N×32B&gt;))</code> &rarr; <code>blob&lt;N×32B&gt;</code></p>
<p><strong>Refs:</strong> <a href="https://eprint.iacr.org/2019/266">safegcd</a> &middot; <a href="https://eprint.iacr.org/2024/644">Jumping for Bernstein-Yang</a></p>
<h4>F. <code>cuda-ntt-poly</code> &mdash; Number Theoretic Transform</h4>
<p><strong>Reference numbers:</strong> Up to 123&times; over CPU; 21&times; on RTX 3070; cuFFT-comparable kernel structure.</p>
<p><strong>Wire:</strong> <code>(ntt (mod . p) (omega . root) (xs . blob&lt;N×8B&gt;))</code> &rarr; <code>blob&lt;N×8B&gt;</code></p>
<p><strong>Refs:</strong> <a href="https://arxiv.org/pdf/2405.11353">NTTSuite</a> &middot; <a href="https://eprint.iacr.org/2021/124.pdf">FHE NTT</a></p>
<h4>G. <code>cuda-radix-sort</code> / <code>cuda-prefix-scan</code> &mdash; reduction primitives</h4>
<p><strong>Reference numbers:</strong> 1.4 G keys/sec on Titan; 20&ndash;50&times; over CPU merge sort; 257&times; over Intel Xeon Phi for scan.</p>
<p><strong>Wire:</strong> <code>(sort-u64 (xs . blob&lt;N×8B&gt;))</code> &rarr; <code>blob&lt;N×8B&gt;</code></p>
<p><strong>Refs:</strong> <a href="https://github.com/NVIDIA/cub">NVIDIA CUB</a> &middot; <a href="https://gpuopen.com/learn/boosting_gpu_radix_sort/">Onesweep</a></p>
<h3>Surveyed forms (Wave 2)</h3>
<p>Sorted by reported speedup descending.</p>
<table>
<thead><tr><th>form</th><th>throughput</th><th>hardware</th><th>ref</th></tr></thead>
<tbody>
<tr><td><code>cuda-minhash-weighted</code></td><td>600&ndash;1000&times; vs numpy+MKL</td><td>Titan X vs Xeon E5-1650</td><td><a href="https://github.com/src-d/minhashcuda">src-d/minhashcuda</a></td></tr>
<tr><td><code>cuda-cuckoo-filter</code></td><td>378&times; insert, 258&times; delete</td><td>A100</td><td><a href="https://arxiv.org/pdf/2603.15486">arXiv:2603.15486</a></td></tr>
<tr><td><code>cuda-aes-ctr-chacha20</code></td><td>211&ndash;400 GB/s</td><td>single GPU</td><td><a href="https://dl.acm.org/doi/fullHtml/10.1145/3605573.3605620">AsyncGBP</a></td></tr>
<tr><td><code>cuda-suffix-array-skew</code></td><td>30&ndash;242&times; vs CPU SA-IS</td><td>Tesla K20</td><td><a href="https://escholarship.org/content/qt83r7w305/qt83r7w305_noSplash_842edf05a7f4e9ecfb1a477bdf9318d3.pdf">Liu/Luo</a></td></tr>
<tr><td><code>cuda-kdtree-build</code></td><td>30&ndash;242&times; build, 1.6&ndash;200&times; kNN</td><td>RTX (RT cores)</td><td><a href="http://www.kunzhou.net/2008/kdtree.pdf">Zhou et al.</a></td></tr>
<tr><td><code>cuda-sat-paraFROST-elim</code></td><td>93&times; peak, 48&times; avg variable elim</td><td>NVIDIA + Kissat baseline</td><td><a href="https://github.com/muhos/ParaFROST">ParaFROST</a></td></tr>
<tr><td><code>cuda-aho-corasick-pfac</code></td><td>~50&ndash;100&times; IDS pkt-inspect</td><td>GTX-class</td><td><a href="https://www.cise.ufl.edu/~sahni/papers/multipatternGPU.pdf">PFAC</a></td></tr>
<tr><td><code>cuda-dilithium-pqsig</code></td><td>57.7&times; keygen+sign+verify vs single CPU thread</td><td>RTX 3090 Ti</td><td><a href="https://eprint.iacr.org/2024/1365.pdf">IACR 2024/1365</a></td></tr>
<tr><td><code>cuda-mc-options-pricing</code></td><td>25&ndash;152&times;</td><td>Tesla C1060 / modern</td><td><a href="https://developer.nvidia.com/gpugems/gpugems2/part-vi-simulation-and-numerical-algorithms/chapter-45-options-pricing-gpu">GPU Gems Ch.45</a></td></tr>
<tr><td><code>cuda-cuFFT-batched-1D</code></td><td>8&ndash;32&times; vs MKL; tcFFT 1.1&ndash;3.2&times; vs cuFFT</td><td>V100 / A100</td><td><a href="https://arxiv.org/pdf/2104.11471">tcFFT</a></td></tr>
<tr><td><code>cuda-blake3-tree</code></td><td>~5&ndash;20&times; tree mode</td><td>Blaze-3 CUDA</td><td><a href="https://github.com/Blaze-3/BLAKE3-gpu">Blaze-3</a></td></tr>
<tr><td><code>cuda-bloom-filter-modern</code></td><td>~6&times; CPU; 3.4 B inserts/s</td><td>B200 / Perlmutter</td><td><a href="https://arxiv.org/pdf/2512.15595">arXiv:2512.15595</a></td></tr>
<tr><td><code>cuda-gemm-batched-FP8</code></td><td>4.8&times; FP8 vs A100; 716 TFLOPS H100</td><td>H100 SXM</td><td><a href="https://developer.nvidia.com/blog/new-cublas-12-0-features-and-matrix-multiplication-performance-on-nvidia-hopper-gpus/">cuBLAS 12.0</a></td></tr>
<tr><td><code>cuda-batched-matrix-inverse</code></td><td>4.3&ndash;16.8&times; vs MAGMA</td><td>P100</td><td><a href="https://www.superfri.org/index.php/superfri/article/download/178/598">Superfri 2018</a></td></tr>
<tr><td><code>cuda-hash-join-radix</code></td><td>4 B tuples/s single; 1.8 T tuples/s on 1024 A100</td><td>A100 cluster</td><td><a href="https://adms-conf.org/2021-camera-ready/gao_adms21.pdf">ADMS-21</a></td></tr>
<tr><td><code>cuda-kmer-count</code></td><td>4&ndash;6&times; vs KMC2</td><td>RapidGKC, Gerbil</td><td><a href="https://www.researchgate.net/publication/382499333_RapidGKC_GPU-Accelerated_K-Mer_Counting">RapidGKC</a></td></tr>
<tr><td><code>cuda-cgraph-traversal</code></td><td>38 B TEPS</td><td>DGX2</td><td><a href="https://medium.com/rapids-ai/rapids-cugraph-multi-gpu-pagerank-363aed1a2503">cuGraph</a></td></tr>
<tr><td><code>cuda-triangle-count-TRUST</code></td><td>~1 T TEPS</td><td>multi-A100</td><td><a href="https://arxiv.org/pdf/2103.08053">TRUST</a></td></tr>
<tr><td><code>cuda-ldpc-bp-decoder</code></td><td>10 Gbps with early-termination</td><td>GPGPU</td><td><a href="https://www.mdpi.com/2079-9292/11/21/3447">MDPI Electronics 2022</a></td></tr>
<tr><td><code>cuda-nvcomp-zstd</code></td><td>2.2&times; zstd; 1.4&times; LZ4; 1.9&times; snappy</td><td>H100 / A100</td><td><a href="https://docs.nvidia.com/cuda/nvcomp/">nvCOMP</a></td></tr>
</tbody>
</table>
<h3>Surveyed forms (Wave 3)</h3>
<table>
<thead><tr><th>form</th><th>throughput</th><th>hardware</th><th>ref</th></tr></thead>
<tbody>
<tr><td><code>cuda-fluidx3d-lbm</code></td><td>100&ndash;200&times; vs ANSYS Fluent; 8,799 MLUPS single A100</td><td>A100</td><td><a href="https://github.com/ProjectPhysX/FluidX3D">FluidX3D</a></td></tr>
<tr><td><code>cuda-mfcc-spectral</code></td><td>~97&times; CPU MFCC; STFT ~75&times; via cuSignal</td><td>GTX 580 / RTX 30-series</td><td><a href="https://developer.nvidia.com/blog/accelerated-signal-processing-with-cusignal/">cuSignal</a></td></tr>
<tr><td><code>cuda-batched-lp-simplex</code></td><td>95&times; over CPLEX; 5&times; over GLPK</td><td>GTX 980-class</td><td><a href="https://arxiv.org/pdf/1802.08557">arXiv 1802.08557</a></td></tr>
<tr><td><code>cuda-betweenness-centrality-weighted</code></td><td>30&ndash;150&times; warp-centric weighted BC</td><td>GTX onwards</td><td><a href="https://arxiv.org/pdf/1701.05975">arXiv 1701.05975</a></td></tr>
<tr><td><code>cuda-cudasift-orb-ransac</code></td><td>~60&times; SIFT CPU&rarr;GPU; ORB 11.3&times;</td><td>GTX 1060+</td><td><a href="https://github.com/Celebrandil/CudaSift">CudaSift</a></td></tr>
<tr><td><code>cuda-cudasw-gasal2</code></td><td>CUDASW++4.0 16.2&times;; 5.71 TCUPS on H100</td><td>H100</td><td><a href="https://bmcbioinformatics.biomedcentral.com/articles/10.1186/s12859-024-05965-6">CUDASW++4.0</a></td></tr>
<tr><td><code>cuda-loopy-bp-mrf</code></td><td>45&times; over CPU LBP for stereo MRF</td><td>GTX 280+</td><td><a href="https://arxiv.org/pdf/2509.22337">arXiv 2509.22337</a></td></tr>
<tr><td><code>cuda-sgm-stereo</code></td><td>42 fps @ 640×480, 128 disparities</td><td>Tegra X1 / discrete</td><td><a href="https://arxiv.org/abs/1610.04121">arXiv 1610.04121</a></td></tr>
<tr><td><code>cuda-hungarian-lap</code></td><td>10&ndash;50&times;; 400 M-variable LAP in ~13 s</td><td>NVIDIA GPU</td><td><a href="https://www.sciencedirect.com/science/article/abs/pii/S016781911630045X">ScienceDirect</a></td></tr>
<tr><td><code>cuda-msm-bls12-381</code></td><td>27.86&times; over Pippenger AVX baseline</td><td>A100 / RTX 4090</td><td><a href="https://tches.iacr.org/index.php/TCHES/article/download/12061/11906/13930">SimdMSM TCHES</a></td></tr>
<tr><td><code>cuda-pdwt-lifting</code></td><td>15.9&times; over best optimized CPU DWT</td><td>GTX / Tesla</td><td><a href="https://github.com/pierrepaleo/PDWT">PDWT</a></td></tr>
<tr><td><code>cuda-tensornet-contract</code></td><td>8&ndash;20&times; vs CuPy; tensor QR ~100&times; vs Xeon</td><td>A100</td><td><a href="https://docs.nvidia.com/cuda/cuquantum/latest/cutensornet/index.html">cuTensorNet</a></td></tr>
<tr><td><code>cuda-ega-gpu-aggregation</code></td><td>6.45&ndash;29.12&times; multi-pass; group-by 19.4&times;</td><td>NVIDIA GPU</td><td><a href="https://www.vldb.org/pvldb/vol17/p644-siddiqui.pdf">VLDB Top-k EGA</a></td></tr>
<tr><td><code>cuda-bicgstab-ilu-spmv</code></td><td>SpTRSV 10.7&times;; BiCGSTAB 3.2&times; vs cuSPARSE</td><td>V100 / MI210</td><td><a href="https://arxiv.org/pdf/2508.04917">arXiv 2508.04917</a></td></tr>
<tr><td><code>cuda-icicle-snark-groth16</code></td><td>fastest Groth16 today; NTT 91% of prover</td><td>RTX 4090 / A100</td><td><a href="https://www.ingonyama.com/post/icicle-snark-the-fastest-groth16-implementation-in-the-world">ICICLE-Snark</a></td></tr>
</tbody>
</table>
<h3>Why a form earns its slot</h3>
<p>A form is GPU-worth-it when at least one of:</p>
<ol>
<li><strong>Embarrassingly parallel.</strong> N independent items, no cross-item dependency.</li>
<li><strong>Dense, branch-free inner loop.</strong> Same operation on every element.</li>
<li><strong>Reduction-friendly.</strong> Tree-reduce / prefix-sum / parallel-scan patterns.</li>
<li><strong>Big batch amortizes fixed kernel overhead.</strong></li>
</ol>
<p>When none of these hold, find a different decomposition: parallelize on a different axis, or stay on CPU &amp; fan out across fleet hosts.</p>
</section>
<section id="source">
<h2>Source &amp; specs</h2>
<p>
<a href="https://git.unturf.com/engineering/unturf/lumbda/-/blob/master/examples/cuda-fanout/">examples/cuda-fanout/</a> &mdash; wire contract, daemon protocol, bench data, per-tier integration.<br>
<a href="https://git.unturf.com/engineering/unturf/lumbda/-/blob/master/examples/cuda-fanout/CATALOG.md">CATALOG.md</a> &mdash; canonical source for form metadata.
</p>
</section>
</main>
<footer>
<p>
<a href="index.html">lumbda.com</a>
&middot;
<a href="https://git.unturf.com/engineering/unturf/lumbda">source</a>
&middot;
<a href="lumbda-whitepaper.html">whitepaper (HTML)</a>
&middot;
<a href="lumbda-whitepaper.pdf">whitepaper (PDF)</a>
&middot;
<a href="https://unturf.com">unturf.com</a>
</p>
</footer>
</body>
</html>