vx-lang / vx-lang/Vx

A proper random-number library: a normal distribution, native f16, buffer fills

Open
#438 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement stdlib
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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.