I would like to share an open-source native Goldilocks/G64 GPU NTT implementation and ask for feedback on benchmark methodology for STARK-LDE workloads.
I am the author of qingming-g64-ntt, an original AMD HIP / ROCm implementation of native Goldilocks-field NTT for a STARK-style LDE workload. The goal of this post is not to claim a universal “fastest NTT”, but to make native G64 GPU NTT results more reproducible, better specified, and easier to compare across open implementations.
Related external baseline work: [https://github.com/Alisah-Ozcan/GPU-NTT/pull/6\]
Motivation
Goldilocks/G64 is still relevant for Plonky2-style STARK/FRI systems and related prover pipelines. However, public GPU NTT benchmark results are often hard to compare.
Some common ambiguity I have seen:
-
Is the field truly native Goldilocks/G64, or only generic 64-bit arithmetic?
-
What exact transform size is being measured?
-
Does the timing include layout / transpose / wrapper work, or only a core kernel?
-
What is the output order / layout contract?
-
Is correctness checked against an independent CPU reference or only against a weak sanity test?
-
Which transform sizes are actually supported, and which are unsupported?
I am trying to make these assumptions explicit.
Workload
The current main workload in qingming-g64-ntt is:
-
Field: Goldilocks / G64
-
Modulus:
p = 2^64 - 2^32 + 1 -
Generator:
7 -
Original logical size:
2^24 -
LDE expansion: exact
8x -
Transform domain:
2^27 -
Backend: AMD HIP / ROCm
-
Validation GPU: AMD Radeon RX 7900 XTX
The repository also provides scaling targets from logn = 20 to logn = 27.
Correctness checks
The implementation includes several correctness gates:
-
field arithmetic randomized self-test
-
primitive
2^27root contract -
explicit base-512 layout bijection
-
delta-vector check
-
sampled direct evaluation
-
standard/fast layout mapping checks
-
full CPU radix-2 reference check for the
2^27target
I think this part is important: a delta-vector check alone is not enough, because many wrong layouts or twiddle schedules can still pass the all-ones output check. Sampled direct evaluation and CPU reference checks are more useful for catching real mapping or decomposition errors.
Current RX 7900 XTX results
Measured on AMD Radeon RX 7900 XTX with ROCm/HIP.
Fast interface scaling:
| logn | N | logical size | median ms | p95 ms |
|---|---|---|---|---|
| 24 | 16,777,216 | 2,097,152 | 2.8914 | 2.9595 |
| 25 | 33,554,432 | 4,194,304 | 4.8422 | 5.4525 |
| 26 | 67,108,864 | 8,388,608 | 9.9209 | 10.2368 |
| 27 | 134,217,728 | 16,777,216 | 19.1927 | 19.4936 |
At logn = 27, this corresponds to the main STARK-LDE point I care about:
logical size = 2^24
LDE factor = 8
domain size = 2^27
This is still a primitive-level benchmark.
Cross-check against GPU-NTT
Separately, I opened GPU-NTT PR #6 to add a standalone validated native Goldilocks/G64 benchmark path for the paper_version 4-step implementation.
Current observation from that PR/testing:
-
logn = 24works and validates on RTX 4090. -
logn >= 25currently reports unsupported in that path. -
This is a support/coverage observation, not a performance claim against GPU-NTT.
My reason for doing this PR is to avoid comparing qingming-g64-ntt only against my own implementation. I want a clearer external baseline under the same field and validation assumptions.
Planned follow-up work
I am planning three next steps.
1. qingming-g64-ntt on RTX 4090
The current public implementation is AMD HIP / ROCm. I would like to provide an RTX 4090 / CUDA-side comparison as well, so that the same G64/STARK-LDE workload can be evaluated on both consumer AMD and consumer NVIDIA hardware.
2. ntt-g64-benchmark
I plan to create a separate ntt-g64-benchmark repository.
The goal is not to rank every NTT implementation by one number. The goal is to build a reproducible fact matrix for native Goldilocks/G64 GPU NTT implementations.
The matrix should record:
-
implementation
-
source / commit / PR
-
field and modulus
-
transform size
-
logical size and LDE factor
-
device and software stack
-
timing region
-
output layout
-
correctness method
-
raw logs
-
reproduction command
-
supported / unsupported sizes
I think unsupported sizes should also be recorded. For example, “supports 2^24 but not 2^25” is useful information for STARK-LDE engineering.
3. qingming-zkp
I also have qingming-zkp, which is intended to move from primitive-level NTT acceleration toward a fuller G64/STARK prover pipeline including NTT, Merkle, FRI, openings, and verification.
The current qingming-g64-ntt result should be understood as the NTT/LDE primitive layer. A complete prover benchmark needs stricter definitions: AIR, transcript, security parameters, Merkle/FRI details, verifier, proof size, and end-to-end wall-clock time.
Questions for the community
I would appreciate feedback on the benchmark methodology.
-
Is
logical_size = 2^24with exact8xLDE to2^27a representative Goldilocks/STARK-LDE benchmark point? -
Which transform sizes should a native G64 GPU NTT benchmark include by default? My current proposal is
2^20through2^27, with focus on2^24..2^27. -
What timing regions should be mandatory?
-
core kernel only
-
wrapper including layout/transpose
-
full prover-stage timing
-
-
What correctness checks should be required for a public benchmark?
-
sampled direct evaluation
-
full CPU reference
-
inverse check
-
fixed-seed test vectors
-
output digest
-
-
Are there other open-source native Goldilocks/G64 GPU NTT implementations that should be included in
ntt-g64-benchmark? -
For Plonky2/Plonky3-style systems, are there better workload definitions than “logical size + LDE factor + transform domain”?
Any feedback on methodology, representative workloads, correctness requirements, or fair baselines would be very helpful.