Skip to content

Commit b25646f

Browse files
authored
Merge pull request #82 from rust-random/push-vnovnmokrvzs
Update reproducibility guarantees
2 parents 5bb5e73 + 41ac8a2 commit b25646f

File tree

1 file changed

+40
-30
lines changed

1 file changed

+40
-30
lines changed

src/crate-reprod.md

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,54 @@
11
# Reproducibility
22

3-
## Definitions
3+
The `rust-random` libraries make limited commitments to reproducibility of seedable PRNGs and stochastic algorithms.
44

5-
Given fixed inputs, all items (should) fall into one of three categories:
5+
This chapter concerns value-stability of deterministic processes using the `rust-random` libraries.
66

7-
- Output is non-deterministic, thus never reproducible (example: `rand::rng`)
8-
- Output is deterministic, but not considered portable (`SmallRng`, `StdRng`; limitations below)
9-
- Output is deterministic and portable (named RNGs; most distributions, sampling and shuffling algorithms)
7+
## API-breaking, value-breaking and SemVer
108

11-
In general, functionality is considered deterministic and portable *unless*
12-
it is clearly non-deterministic (e.g. `getrandom`, `ThreadRng`) *or* it is
13-
documented as being nonportable (e.g. `StdRng`, `SmallRng`).
9+
A change (to a library) is considered **API-breaking** if it may cause a compilation failure of code which was compatible with a prior version of the API, or is otherwise an incompatible change.
1410

15-
## Crate versions
11+
We aim to follow [SemVer rules](https://semver.org/) regarding API-breaking changes and `MAJOR.MINOR.PATCH` versions. That is, post 1.0, new minor versions should not introduce API-breaking changes.
1612

17-
We try to follow [semver rules](https://semver.org/) regarding
18-
API-breaking changes and `MAJOR.MINOR.PATCH` versions:
13+
A change is considered **value-breaking** if it is not API-breaking yet would result in changed output values of a deterministic stochastic process using only unchanged parts of the `rust-random` API.
1914

20-
- New *patch* versions should not include API-breaking changes or major new
21-
features
22-
- Before 1.0, *minor* versions may include API breaking changes. After 1.0
23-
they should not.
15+
Value-breaking changes are permitted in minor versions.
2416

25-
Additionally, we must also consider *value-breaking changes* and *portability*.
26-
When given fixed inputs,
17+
## Non-portable deterministic items
2718

28-
- For non-deterministic items, implementations may change in any release
29-
- For deterministic nonportable items, output should be preserved in patch
30-
releases, but may change in any minor release (including after 1.0)
31-
- For portable items, output should be preserved by patch releases.
32-
Minor releases (including after 1.0) may include such value-breaking
33-
changes, though these must be documented in the CHANGELOG.
19+
An item in a `rust-random` API (such as a struct or function) may be declared to be **non-portable**, meaning that it opts out of all reproducibility guarantees. Non-portable items may be deterministic, yet yield different results on different platforms and library versions (they may make value-breaking changes in any release).
20+
21+
This is a change in policy affecting `rand` from version `0.10` or `1.0` (whichever release is next); up to version `0.9` non-portable items were not permitted to make value-breaking changes in patch releases.
22+
23+
This non-portable declaration must be clearly mentioned in documentation. The following items make such a declaration:
24+
25+
- [`rand::rngs::SmallRng`](https://docs.rs/rand/latest/rand/rngs/struct.SmallRng.html)
26+
- [`rand::rngs::StdRng`](https://docs.rs/rand/latest/rand/rngs/struct.StdRng.html)
27+
28+
## Portable items
29+
30+
Some items are clearly non-deterministic (e.g. [`rand::rng`]). Some items are deterministic but non-portable (above). All other parts of the public API of `rust-random` crates (including PRNGs, distributions and other stochastic algorithms) are expected to be portable:
31+
32+
- Results should be reproducible across platforms
33+
- Results should be reproducible across patch releases
34+
- Minor releases, including after 1.0, may make value-breaking changes to portable items. Such changes must be well motivated and should be clearly mentioned in the CHANGELOG.
3435

3536
### Testing
3637

37-
We expect all pseudo-random algorithms to test the value-stability of their
38-
output, where possible:
38+
We expect all portable stochastic algorithms to test the value-stability of their output with some form of test vector.
3939

40-
- PRNGs should be compared with a reference vector ([example](https://github.com/rust-random/rngs/blob/master/rand_xoshiro/src/xoshiro256starstar.rs#L124))
40+
- PRNGs should test against a reference vector where available ([example](https://github.com/rust-random/rngs/blob/master/rand_xoshiro/src/xoshiro256starstar.rs#L122))
4141
- Other algorithms should include their own test vectors within a
4242
`value_stability` test or similar ([example](https://github.com/rust-random/rand/blob/master/src/distr/bernoulli.rs#L226))
4343

44+
## Support for prior versions
45+
46+
We aim to support users of `rust-random` crates using a prior `MAJOR.MINOR` version for the purposes of reproducibility by:
47+
48+
- Providing security fixes as patch versions where appropriate
49+
- Facilitating the back-porting of compatible additions from future crate versions *on request*
50+
- Other fixes may be considered for back-porting, but are often not possible without API-breaking or value-breaking changes
51+
4452
## Limitations
4553

4654
### Portability of usize
@@ -54,10 +62,7 @@ it does matter.
5462
A simple rule follows: if portability is required, *never* sample a `usize` or
5563
`isize` value directly.
5664

57-
Within Rand we adhere to this rule whenever possible. All sequence-related
58-
code requiring a bounded `usize` value will sample a `u32` value unless the
59-
upper bound exceeds `u32::MAX`.
60-
(Note that this actually improves benchmark performance in many cases.)
65+
From `rand v0.9`, `isize` and `usize` types are no longer supported in many parts of the public API, including [`StandardUniform`]. `usize` is supported by [`SampleUniform`] and thus [`Rng::random_range`], using `u32` sampling whenever possible to maximise portability.
6166

6267
### Portability of floats
6368

@@ -66,3 +71,8 @@ implementation details. In particular, the results of transcendental functions v
6671
from platform to platform. Due to this, results of distributions in `rand_distr` using `f32` or `f64` may not be portable.
6772

6873
To alleviate (or further complicate) this concern, we prefer to use `libm` over `std` implementations of these transcendental functions. See [rand_distr features](crate-features.html#rand_distr-features).
74+
75+
[`rand::rng`]: https://docs.rs/rand/latest/rand/fn.rng.html
76+
[`StandardUniform`]: https://docs.rs/rand/latest/rand/distr/struct.StandardUniform.html
77+
[`SampleUniform`]: https://docs.rs/rand/latest/rand/distr/uniform/trait.SampleUniform.html
78+
[`Rng::random_range`]: https://docs.rs/rand/latest/rand/trait.Rng.html#method.random_range

0 commit comments

Comments
 (0)