A proper random-number library: a normal distribution, native f16, buffer fills
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 14
- Forks
- 2
- Avg merge
- 12h 42m
- Merged PRs (30d)
- 61
Description
45473f23 added a SplitMix64 in stdlib/rust_core/src/ffi/rt.rs reachable as extern "C":
vx_rand_seed, vx_rand_u64, vx_rand_i32, vx_rand_f32, vx_rand_f64, vx_rand_range_f32.
It was written to stop tests being filled with zeros, and it does that. It is not a random-number
library, and the gaps below are the ones that will be felt first.
Why it exists at all
Zero-filled inputs hide bugs, and three separate defects in the ANE work were invisible until the
inputs varied: a dropped scale (Vx#437), and an operand transposition and row-indexing error that
the closed-form cases could not distinguish from correct. A matrix of zeros gives the right answer
under all three.
What is missing
A normal distribution. Uniform is the wrong default for anything resembling model data. Weights,
activations and KV entries are approximately Gaussian, and a uniform fill exercises a range of
magnitudes real data never has -- which matters for f16, where the interesting failures are overflow
and underflow at the tails. Box-Muller over the existing uniform is a few lines and would probably
be the most-used entry point.
Native f16. Today it is vx_rand_f32() as f16, because Rust's f16 is unstable as of 1.95 and
the runtime cannot return one across the C ABI. Options are to wait for stabilisation, to take the
half crate, or to build the bits directly and hand back a u16 the compiler bitcasts. The cast
works and loses nothing for a random value, but it is a workaround and should be labelled one.
Buffer fills. Every value currently costs an FFI call. 49k calls to fill the attention operands
is fine; the 2M a full 256x8192 tensor needs would not be. vx_rand_fill_f32(ptr, n) and friends
would make filling a real tensor practical, and would let the generator vectorise.
The rest of the width table. i64, u32, i8/u8, and bf16 all have element types in the
language and no generator. bf16 matters for the same reason f16 does.
Per-stream state. One global atomic counter means two threads filling two tensors interleave
draws, so a parallel fill is reproducible in aggregate but not per tensor. A seeded stream per
caller would fix that. Nothing today needs it; a parallel differential would.
What to keep if this is replaced
Determinism, and specifically the ability to replay a sequence exactly. A differential test compares
two execution paths on the same inputs, so a generator that cannot be pinned is unusable for the
job this one was written for. rand with an explicitly seeded StdRng keeps that;
thread_rng-style ambient entropy does not.
Also worth keeping: no dependency in the default build path. If rand comes in, it should not make
stdlib/rust_core harder to build on a machine that is only running tests.
Not urgent
The current one is adequate for what it was written for, and a test that pins exact values
(tests/backend/pass/rand_primitives.vx) will make a replacement's behaviour change obvious rather
than silent.
Related: Vx#437 (the differential that motivated it).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with stdlib/rust_core/src/ffi/rt.rs and tests/backend/pass/rand_primitives.vx to understand the existing deterministic entry points and their exact-value coverage. The issue spans distributions, element widths, buffer fills, and stream state; done should preserve replayable seeded behavior while covering the selected additions with tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend, testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100