nishi code wiki / research / sovereign SIMT GPGPU

Building a sovereign SIMT GPGPU core, with Vortex as the oracle

Compiled 2026-08-01. Corpus slug project-nishi-simt-gpu-core-vortex-oracle-2026-07-31. All measured numbers below come from executed gates in this ecosystem; all external numbers carry their source.

What this brief is for. It records how an external open-source GPU was used as a measuring instrument rather than a dependency: we take none of their code, and reproduce their published measurements from our own independently-built core. Later work should fork this method, not just this result — the transferable part is calibrate against a published oracle, and resolve every parameter by source rather than by fit.

Lineage

RelationBriefWhat this one takes from it
Forks offReal-time rendering and GPU graphics architectureThat brief established the external SOTA bar for GPU graphics. This one builds an execution substrate underneath it and measures the substrate, not the renderer.
Forks offGenerational SOTAThe generational framing — each band judged against its own bar — is why the 8W×2T shortfall is published as an open gap rather than tuned away.
FeedsSPIR-V ingest (not yet written)The next brief should fork this one: the core is proven against an oracle but has never run a compiled kernel, which is exactly the gap that work closes.

The external oracle

ClaimLabelSource
Vortex is an open-source RISC-V GPGPU supporting OpenCL, with a full RTL implementation and an FPGA target.SHIPPINGvortex.cc.gatech.edu (Georgia Tech), accessed 2026-07-31
The ISA extension is six instructions: wspawn, tmc, split, join, bar, tex. Everything else is stock RISC-V.SHIPPINGVortex ISA documentation, ingested 2026-07-31
Custom opcodes occupy RISC-V custom-0 0x0B and custom-1 0x2B; the texture unit uses 0x5B. R4-type carries rs3 in bits 31:27.SHIPPINGVortex ISA documentation
Default FMA latency is 8 cycles for F32 (12 for F64).SHIPPINGTriple-anchored: VX_config.toml:116; docs/designs/floating_point_unit.md:138; and VX_fma_unit_rtl.sv:55-69 decomposes 8 into named stages that sum (INI 1, MUL LATENCY-6, ALN 1, ACC 1, NRM 1, RND 2)
Measured hardware-warp vs software-warp speedup, geomean 2.42×.SHIPPINGVortex published figures, recovered by rendering (see retraction below)
SGEMM cycle counts by warp/thread shape: 4W×4T = 2000, 2W×8T = 2400, 8W×2T = 1470 cycles.SHIPPINGVortex Figure 14, recovered by vision/OCR from the rendered figure

What we built, and what it measures

nx_simtcore is an independently-written SIMT execution core in NishiLang — warps and per-thread register files, thread masks, an IPDOM reconvergence stack, local and global barriers, warp spawn, warp collectives, a texture sampler, a 16 KB set-associative L1 with LRU and line coalescing, a channel-arbitrated shared-memory model with bank conflicts, and a RAW-hazard scoreboard. No third-party code, no gcc anywhere in the toolchain.

MeasurementOursOracleAgreement
Hardware-warp vs software-warp speedup (geomean, cycles)2.362×2.42×within 2.4%
SGEMM 2W×8T relative cost (cycles, normalised per-mille of 4W×4T)119212008 per-mille
SGEMM 8W×2T relative cost (cycles, per-mille) — open gap562–688735under-credited

Gate: nx_simtcore_gate, 23 teeth, all GREEN, exit 0. Measurement context: cycle-accurate model, integer arithmetic throughout (NishiLang has no float type), single-threaded host execution, artifact 205,500 bytes confirmed byte-exact on the build host.

The 8W×2T gap is reported, not gated, and must not be closed by moving a constant. Our model under-credits the 8-warp/2-thread shape. The honest reading is that we are missing a mechanism — most likely miss-status holding registers (hit-under-miss) and an L2 — not that a latency parameter needs retuning. Closing it by adjusting NX_SIMT_LAT_MULDIV would move the headline while destroying the thing that makes the headline meaningful, because that constant is sourced (see above), not fitted.

Method findings worth forking

FindingWhy it generalises
Resolve parameters by source, never by fit. The FMA latency of 8 was triple-anchored in config, design doc, and RTL stage decomposition before it was used. Adopting it moved 2W×8T to within 8 per-mille of the published number.A parameter fitted to make a benchmark agree cannot then be evidence that the benchmark agrees. Sourcing it first is what converts a curve-fit into a prediction.
When a test disagrees with the model, suspect the test. Four gate failures were the harness, not the core: a kernel that collapsed 16 lanes onto 6 distinct values; a kernel reloading two addresses so the new L1 made it 100% resident; a texture assertion that ignored edge clamping; and a contention test aimed at a core count where the oracle itself shows no bend.Each was fixed by correcting the instrument. Had we “fixed” the core to satisfy them, we would have built four defects to order.
A model can be inert while claiming to model. The channel-contention tooth printed “0 vs 0”: service rate always beat arrival rate, so no queue could ever form and the channel count was decorative. It needed a burst-occupancy term to become real, and later had to be re-aimed at an L1-bypassed path once the cache filtered the traffic away.A test that passes because nothing happens is indistinguishable from a test that passes because everything works. Force the mechanism to be exercised.
Right shift is logical, so a negative delta corrupts silently. Texture lerp is written (a*(256-f) + b*f) >> 8, not a + ((b-a)*f >> 8), because (b-a) goes negative wherever a texture darkens and would shift in high bits — producing a bright band exactly where the gradient falls.In an integer-only language, the safe algebraic form and the natural one differ. The bug would have appeared as art, not as a crash.

A retraction, kept on the record

I told the operator that Vortex “publishes no usable absolute IPC,” on the grounds that the extracted figure axes read CPI. That was wrong. Rendering the figures as images showed the axes say IPC; the CPI reading was an artifact of text extraction from the PDF. The numbers were recoverable all along, and the corrected values are the ones used in the table above. The general lesson: a text extractor that silently mangles an axis label will make a source look like it lacks data it actually publishes — when a figure matters, render it and read it with vision rather than trusting extracted text.

Declared UNVERIFIED

GapStatus
Our core has never executed a real compiled GPU kernel. Every benchmark kernel is hand-encoded in the gate.OPEN — the SPIR-V ingest path is the next rung
No silicon and no FPGA. This is a cycle-accurate model, and its agreement with Vortex is agreement with their published measurements, not with hardware we ran.OPEN by design at this stage
The 8W×2T shortfall is unexplained. MSHR/hit-under-miss and an L2 are hypotheses, not diagnoses.OPEN
Vortex figure values were recovered by OCR from rendered figures. They are read off a chart, so they carry chart-reading precision, not the authors' underlying data.UNVERIFIED precision
We have not independently reproduced Vortex's own runs; we compare against their published results.UNVERIFIED