Skip to content

Commit fe5b433

Browse files
amatgilkaikalii
authored andcommitted
rand -> rand_xoshiro for better reproducibility across archs
1 parent 1e57828 commit fe5b433

File tree

7 files changed

+53
-19
lines changed

7 files changed

+53
-19
lines changed

Cargo.lock

Lines changed: 19 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ js-sys = "0.3.69"
3535
leptos = "0.6.11"
3636
leptos_meta = {version = "0.6.11", features = ["csr"]}
3737
leptos_router = {version = "0.6.11", features = ["csr"]}
38-
rand = {version = "0.8.5", features = ["small_rng"]}
38+
rand_xoshiro = "0.7.0"
3939
serde = {version = "1", features = ["derive"]}
4040
serde_json = "1.0.115"
4141
unicode-segmentation = "1.10"
@@ -106,7 +106,6 @@ open = {version = "5", optional = true}
106106
parking_lot = "0.12.1"
107107
paste = "1.0.14"
108108
pathdiff = "0.2.1"
109-
rand.workspace = true
110109
rawrrr = {version = "0.2.1", optional = true}
111110
rayon = "1.9.0"
112111
regex = "1.10.3"
@@ -183,6 +182,7 @@ web-sys = {version = "0.3.60", optional = true}
183182
# Window dependencies
184183
eframe = {version = "0.29.1", optional = true, features = ["persistence"]}
185184
native-dialog = {version = "0.7.0", optional = true}
185+
rand_xoshiro = "0.7.0"
186186
rmp-serde = {version = "1.3.0", optional = true}
187187

188188
[features]

site/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ js-sys.workspace = true
2323
leptos.workspace = true
2424
leptos_meta.workspace = true
2525
leptos_router.workspace = true
26-
rand.workspace = true
26+
rand_xoshiro.workspace = true
2727
serde.workspace = true
2828
serde_json.workspace = true
2929
uiua = {path = "..", default-features = false, features = ["batteries", "web"]}

src/algorithm/dyadic/mod.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ use std::{
1515

1616
use bytemuck::allocation::cast_vec;
1717
use ecow::{eco_vec, EcoVec};
18-
use rand::prelude::*;
18+
use rand_xoshiro::{
19+
rand_core::{RngCore, SeedableRng},
20+
Xoshiro256Plus,
21+
};
22+
1923
#[cfg(not(target_arch = "wasm32"))]
2024
use rayon::prelude::*;
2125
use smallvec::SmallVec;
@@ -2112,7 +2116,7 @@ impl Value {
21122116
let mut hasher = DefaultHasher::new();
21132117
seed.hash(&mut hasher);
21142118
let seed = hasher.finish();
2115-
let mut rng = SmallRng::seed_from_u64(seed);
2119+
let mut rng = Xoshiro256Plus::seed_from_u64(seed);
21162120

21172121
const SHAPE_REQ: &str = "Shape must be an array of natural \
21182122
numbers with at most rank 2";
@@ -2122,7 +2126,7 @@ impl Value {
21222126
let elem_count = validate_size::<f64>(shape.iter().copied(), env)?;
21232127
let mut data = eco_vec![0.0; elem_count];
21242128
for x in data.make_mut() {
2125-
*x = rng.gen();
2129+
*x = f64::from_bits(rng.next_u64());
21262130
}
21272131
Ok(Array::new(shape, data))
21282132
};
@@ -2168,7 +2172,15 @@ impl Value {
21682172
0 => Err(env.error("Cannot pick random row of an empty array").fill()),
21692173
1 => Ok(self.row(0)),
21702174
len => {
2171-
let i = RNG.with_borrow_mut(|rng| rng.gen_range(0..len));
2175+
let i = RNG.with_borrow_mut(|rng| {
2176+
let upper = len.next_power_of_two();
2177+
loop {
2178+
let r = rng.next_u64() as usize;
2179+
if r % upper < len {
2180+
break len;
2181+
}
2182+
}
2183+
});
21722184
Ok(self.row(i))
21732185
}
21742186
}

src/algorithm/monadic/sort.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::{cmp::Ordering, ptr};
22

33
use ecow::EcoVec;
4-
use rand::Rng;
4+
use rand_xoshiro::rand_core::SeedableRng;
5+
use rand_xoshiro::Xoshiro256Plus;
56
use rayon::prelude::*;
67

78
use crate::{algorithm::ArrayCmpSlice, random_with, val_as_arr, Array, ArrayValue, Value};

src/constant.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use std::{
55
};
66

77
use ecow::EcoVec;
8-
use rand::prelude::*;
8+
use rand_xoshiro::rand_core::SeedableRng;
9+
use rand_xoshiro::Xoshiro256Plus;
910

1011
use crate::{
1112
parse_doc_line_fragments, Array, Boxed, PrimDocFragment, SysBackend, Value, WILDCARD_NAN,
@@ -485,7 +486,7 @@ fn music_constant(backend: &dyn SysBackend) -> Value {
485486
hat_mask.push((hat_bits & 1) as f64);
486487
hat_bits >>= 1;
487488
}
488-
let mut rng = SmallRng::seed_from_u64(0);
489+
let mut rng = Xoshiro256Plus::seed_from_u64(0);
489490
let sr = backend.audio_sample_rate();
490491
(0..(BEAT * 2.0 * 16.0 * sr as f64) as usize)
491492
.map(|s| {

src/run_prim.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,18 @@ use std::{
1414
collections::HashMap,
1515
f64::consts::{PI, TAU},
1616
iter::repeat_n,
17+
mem::transmute,
1718
sync::{
1819
atomic::{self, AtomicUsize},
1920
OnceLock,
2021
},
22+
time::{SystemTime, UNIX_EPOCH},
2123
};
2224

23-
use rand::prelude::*;
25+
use rand_xoshiro::{
26+
rand_core::{RngCore, SeedableRng},
27+
Xoshiro256Plus,
28+
};
2429

2530
use crate::{
2631
algorithm::{self, ga::GaOp, loops, reduce, table, zip, *},
@@ -1783,22 +1788,22 @@ fn undo_regex(env: &mut Uiua) -> UiuaResult {
17831788
}
17841789

17851790
thread_local! {
1786-
pub(crate) static RNG: RefCell<SmallRng> = RefCell::new(SmallRng::from_entropy());
1791+
pub(crate) static RNG: RefCell<Xoshiro256Plus> = RefCell::new(Xoshiro256Plus::from_seed(transmute(SystemTime::now().saturating_duration_since(UNIX_EPOCH).as_micros())));
17871792
}
17881793

17891794
/// Generate a random number, equivalent to [`Primitive::Rand`]
17901795
pub fn random() -> f64 {
1791-
random_with(|rng| rng.gen())
1796+
random_with(|rng| f64::from_bits(rng.next_u64()))
17921797
}
17931798

17941799
/// Access the interpreter's random number generator for the thread
1795-
pub fn random_with<T>(f: impl FnOnce(&mut SmallRng) -> T) -> T {
1800+
pub fn random_with<T>(f: impl FnOnce(&mut Xoshiro256Plus) -> T) -> T {
17961801
RNG.with(|rng| f(&mut rng.borrow_mut()))
17971802
}
17981803

17991804
/// Seed the random number generator
18001805
pub fn seed_random(seed: u64) {
1801-
random_with(|rng| *rng = SmallRng::seed_from_u64(seed));
1806+
random_with(|rng| *rng = Xoshiro256Plus::seed_from_u64(seed));
18021807
}
18031808

18041809
fn stack_n(env: &mut Uiua, n: usize, inverse: bool) -> UiuaResult {

0 commit comments

Comments
 (0)