From 3f55c889865e954cecbf795d3186ea6590987c45 Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 17:24:53 +0200 Subject: [PATCH 1/8] rand -> rand_xoshiro for better reproducibility across archs --- Cargo.lock | 40 ++++++++++++----------------------- Cargo.toml | 4 ++-- site/Cargo.toml | 2 +- src/algorithm/dyadic/mod.rs | 36 ++++++++++++++++++++++--------- src/algorithm/monadic/sort.rs | 3 ++- src/constant.rs | 5 +++-- src/run_prim.rs | 22 ++++++++++++++----- src/value.rs | 16 ++++++++++---- 8 files changed, 76 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a7bf66740..bc01c255a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2771,7 +2771,7 @@ dependencies = [ "cpal", "hound", "parking_lot", - "rand 0.8.5", + "rand", "thiserror 1.0.69", ] @@ -5071,20 +5071,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.1", + "rand_chacha", "rand_core 0.6.4", ] -[[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", -] - [[package]] name = "rand_chacha" version = "0.3.1" @@ -5095,16 +5085,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.3", -] - [[package]] name = "rand_core" version = "0.6.4" @@ -5119,8 +5099,14 @@ name = "rand_core" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" + +[[package]] +name = "rand_xoshiro" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" dependencies = [ - "getrandom 0.3.4", + "rand_core 0.9.3", ] [[package]] @@ -5161,8 +5147,8 @@ dependencies = [ "once_cell", "paste", "profiling", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand", + "rand_chacha", "simd_helpers", "system-deps", "thiserror 1.0.69", @@ -5862,7 +5848,7 @@ dependencies = [ "leptos", "leptos_meta", "leptos_router", - "rand 0.9.2", + "rand_xoshiro", "serde", "serde_json", "uiua", @@ -6616,7 +6602,7 @@ dependencies = [ "paste", "pathdiff", "png", - "rand 0.9.2", + "rand_xoshiro", "rawrrr", "rayon", "regex", diff --git a/Cargo.toml b/Cargo.toml index 5548760b8..3fe503155 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ js-sys = "0.3.69" leptos = "0.6.11" leptos_meta = {version = "0.6.11", features = ["csr"]} leptos_router = {version = "0.6.11", features = ["csr"]} -rand = {version = "0.9.2", features = ["small_rng"]} +rand_xoshiro = "0.7.0" serde = {version = "1", features = ["derive"]} serde_json = "1.0.115" unicode-segmentation = "1.10" @@ -107,7 +107,6 @@ open = {version = "5", optional = true} parking_lot = "0.12.1" paste = "1.0.14" pathdiff = "0.2.1" -rand.workspace = true rawrrr = {version = "0.2.1", optional = true} rayon = "1.9.0" regex = "1.10.3" @@ -185,6 +184,7 @@ web-sys = {version = "0.3.60", optional = true} # Window dependencies eframe = {version = "0.33.0", optional = true, features = ["persistence"]} native-dialog = {version = "0.7.0", optional = true} +rand_xoshiro = "0.7.0" rmp-serde = {version = "1.3.0", optional = true} [features] diff --git a/site/Cargo.toml b/site/Cargo.toml index f06dd7172..b8bb618f3 100644 --- a/site/Cargo.toml +++ b/site/Cargo.toml @@ -24,7 +24,7 @@ js-sys.workspace = true leptos.workspace = true leptos_meta.workspace = true leptos_router.workspace = true -rand.workspace = true +rand_xoshiro.workspace = true serde.workspace = true serde_json.workspace = true uiua = {path = "..", default-features = false, features = ["batteries", "web"]} diff --git a/src/algorithm/dyadic/mod.rs b/src/algorithm/dyadic/mod.rs index 27998554d..7dcedc186 100644 --- a/src/algorithm/dyadic/mod.rs +++ b/src/algorithm/dyadic/mod.rs @@ -14,33 +14,41 @@ use std::{ }; use bytemuck::allocation::cast_vec; -use ecow::{EcoVec, eco_vec}; -use rand::prelude::*; +use ecow::{eco_vec, EcoVec}; +use rand_xoshiro::{ + rand_core::{RngCore, SeedableRng}, + Xoshiro256Plus, +}; + #[cfg(not(target_arch = "wasm32"))] use rayon::prelude::*; use smallvec::SmallVec; use crate::{ - Complex, RNG, Shape, Uiua, UiuaResult, - algorithm::pervade::{self, InfalliblePervasiveFn, bin_pervade_recursive}, + algorithm::pervade::{self, bin_pervade_recursive, InfalliblePervasiveFn}, array::*, boxed::Boxed, - cowslice::{CowSlice, cowslice, extend_repeat}, + cowslice::{cowslice, extend_repeat, CowSlice}, fill::FillValue, grid_fmt::GridFmt, val_as_arr, value::Value, + Complex, Shape, Uiua, UiuaResult, RNG, }; use super::{ - ArrayCmpSlice, FillContext, SizeError, shape_prefixes_match, validate_size, validate_size_of, + shape_prefixes_match, validate_size, validate_size_of, ArrayCmpSlice, FillContext, SizeError, }; macro_rules! par_if { ($cond:expr, $if_true:expr, $if_false:expr) => {{ #[cfg(not(target_arch = "wasm32"))] { - if $cond { $if_true } else { $if_false } + if $cond { + $if_true + } else { + $if_false + } } #[cfg(target_arch = "wasm32")] $if_false @@ -2122,7 +2130,7 @@ impl Value { let mut hasher = DefaultHasher::new(); seed.hash(&mut hasher); let seed = hasher.finish(); - let mut rng = SmallRng::seed_from_u64(seed); + let mut rng = Xoshiro256Plus::seed_from_u64(seed); const SHAPE_REQ: &str = "Shape must be an array of natural \ numbers with at most rank 2"; @@ -2132,7 +2140,7 @@ impl Value { let elem_count = validate_size::(shape.iter().copied(), env)?; let mut data = eco_vec![0.0; elem_count]; for x in data.make_mut() { - *x = rng.random(); + *x = f64::from_bits(rng.next_u64()); } Ok(Array::new(shape, data)) }; @@ -2178,7 +2186,15 @@ impl Value { 0 => Err(env.error("Cannot pick random row of an empty array").fill()), 1 => Ok(self.row(0)), len => { - let i = RNG.with_borrow_mut(|rng| rng.random_range(0..len)); + let i = RNG.with_borrow_mut(|rng| { + let upper = len.next_power_of_two(); + loop { + let r = rng.next_u64() as usize; + if r % upper < len { + break len; + } + } + }); Ok(self.row(i)) } } diff --git a/src/algorithm/monadic/sort.rs b/src/algorithm/monadic/sort.rs index 2b59befbd..6efe35206 100644 --- a/src/algorithm/monadic/sort.rs +++ b/src/algorithm/monadic/sort.rs @@ -1,7 +1,8 @@ use std::{cmp::Ordering, ptr}; use ecow::EcoVec; -use rand::Rng; +use rand_xoshiro::rand_core::SeedableRng; +use rand_xoshiro::Xoshiro256Plus; use rayon::prelude::*; use crate::{Array, ArrayValue, Value, algorithm::ArrayCmpSlice, random_with, val_as_arr}; diff --git a/src/constant.rs b/src/constant.rs index 13d75e008..a2725f078 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -7,7 +7,8 @@ use std::{ }; use ecow::EcoVec; -use rand::prelude::*; +use rand_xoshiro::Xoshiro256Plus; +use rand_xoshiro::rand_core::SeedableRng; use crate::{ Array, Boxed, PrimDocFragment, SysBackend, Uiua, Value, WILDCARD_NAN, media, @@ -587,7 +588,7 @@ fn music_constant(backend: &dyn SysBackend) -> Value { hat_mask.push((hat_bits & 1) as f64); hat_bits >>= 1; } - let mut rng = SmallRng::seed_from_u64(0); + let mut rng = Xoshiro256Plus::seed_from_u64(0); let sr = backend.audio_sample_rate(); (0..(BEAT * 2.0 * 16.0 * sr as f64) as usize) .map(|s| { diff --git a/src/run_prim.rs b/src/run_prim.rs index 5124cbd2e..ee13dc572 100644 --- a/src/run_prim.rs +++ b/src/run_prim.rs @@ -14,13 +14,18 @@ use std::{ collections::HashMap, f64::consts::{PI, TAU}, iter::repeat_n, + mem::transmute, sync::{ OnceLock, atomic::{self, AtomicUsize}, }, + time::{Duration, SystemTime, UNIX_EPOCH}, }; -use rand::prelude::*; +use rand_xoshiro::{ + Xoshiro256Plus, + rand_core::{RngCore, SeedableRng}, +}; use crate::{ FunctionId, ImplPrimitive, Ops, Primitive, Shape, SubSide, SysOp, Uiua, UiuaErrorKind, @@ -1868,22 +1873,29 @@ fn undo_regex(env: &mut Uiua) -> UiuaResult { } thread_local! { - pub(crate) static RNG: RefCell = RefCell::new(SmallRng::from_os_rng()); + pub(crate) static RNG: RefCell = RefCell::new(Xoshiro256Plus::from_seed(unsafe { + transmute( + [SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap_or(Duration::ZERO) + .as_micros(); 2], + ) + })); } /// Generate a random number, equivalent to [`Primitive::Rand`] pub fn random() -> f64 { - random_with(|rng| rng.random()) + random_with(|rng| f64::from_bits(rng.next_u64())) } /// Access the interpreter's random number generator for the thread -pub fn random_with(f: impl FnOnce(&mut SmallRng) -> T) -> T { +pub fn random_with(f: impl FnOnce(&mut Xoshiro256Plus) -> T) -> T { RNG.with(|rng| f(&mut rng.borrow_mut())) } /// Seed the random number generator pub fn seed_random(seed: u64) { - random_with(|rng| *rng = SmallRng::seed_from_u64(seed)); + random_with(|rng| *rng = Xoshiro256Plus::seed_from_u64(seed)); } fn stack_n(env: &mut Uiua, n: usize, inverse: bool) -> UiuaResult { diff --git a/src/value.rs b/src/value.rs index 19b57a1ce..dcb0e73b3 100644 --- a/src/value.rs +++ b/src/value.rs @@ -12,11 +12,11 @@ use ecow::EcoVec; use serde::*; use crate::{ - Boxed, Complex, Shape, Uiua, UiuaResult, - algorithm::{ErrorContext, FillContext, pervade::*}, + algorithm::{pervade::*, ErrorContext, FillContext}, array::*, cowslice::CowSlice, grid_fmt::GridFmt, + Boxed, Complex, Shape, Uiua, UiuaResult, }; /// A generic array value @@ -1346,11 +1346,19 @@ impl Value { } /// Remove a single layer of boxing if the condition is met pub fn unboxed_if(self, unbox: bool) -> Self { - if unbox { self.unboxed() } else { self } + if unbox { + self.unboxed() + } else { + self + } } /// Box the value if the condition is met pub fn boxed_if(self, do_box: bool) -> Self { - if do_box { Boxed(self).into() } else { self } + if do_box { + Boxed(self).into() + } else { + self + } } /// Turn the value into a scalar box if it is not one already pub fn box_if_not(&mut self) { From 30572db00fdf21037542b1b3311cb251c28e161b Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 17:34:34 +0200 Subject: [PATCH 2/8] Remember to return the generated value, not the upper bound :P --- src/algorithm/dyadic/mod.rs | 6 +++--- src/algorithm/monadic/sort.rs | 12 ++++++++++-- src/run_prim.rs | 10 ++-------- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/algorithm/dyadic/mod.rs b/src/algorithm/dyadic/mod.rs index 7dcedc186..84ecbf8d3 100644 --- a/src/algorithm/dyadic/mod.rs +++ b/src/algorithm/dyadic/mod.rs @@ -2189,9 +2189,9 @@ impl Value { let i = RNG.with_borrow_mut(|rng| { let upper = len.next_power_of_two(); loop { - let r = rng.next_u64() as usize; - if r % upper < len { - break len; + let r = rng.next_u64() as usize % upper; + if r < len { + break r; } } }); diff --git a/src/algorithm/monadic/sort.rs b/src/algorithm/monadic/sort.rs index 6efe35206..3ba2ecbfb 100644 --- a/src/algorithm/monadic/sort.rs +++ b/src/algorithm/monadic/sort.rs @@ -1,8 +1,8 @@ use std::{cmp::Ordering, ptr}; use ecow::EcoVec; -use rand_xoshiro::rand_core::SeedableRng; use rand_xoshiro::Xoshiro256Plus; +use rand_xoshiro::rand_core::SeedableRng; use rayon::prelude::*; use crate::{Array, ArrayValue, Value, algorithm::ArrayCmpSlice, random_with, val_as_arr}; @@ -237,7 +237,15 @@ impl Array { let row_len = self.row_len(); let slice = self.data.as_mut_slice(); for i in (1..row_count).rev() { - let j = rng.random_range(0..=i); + let j = { + let upper = i.next_power_of_two(); + loop { + let r = rng.next_u64() as usize % upper; + if r <= i { + break r; + } + } + }; if i == j { continue; } diff --git a/src/run_prim.rs b/src/run_prim.rs index ee13dc572..a30393df6 100644 --- a/src/run_prim.rs +++ b/src/run_prim.rs @@ -1873,14 +1873,8 @@ fn undo_regex(env: &mut Uiua) -> UiuaResult { } thread_local! { - pub(crate) static RNG: RefCell = RefCell::new(Xoshiro256Plus::from_seed(unsafe { - transmute( - [SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap_or(Duration::ZERO) - .as_micros(); 2], - ) - })); + pub(crate) static RNG: RefCell = RefCell::new(Xoshiro256Plus::seed_from_u64( + SystemTime::now().duration_since(UNIX_EPOCH).map(|t|t.as_micros()).unwrap_or(42) as u64)); } /// Generate a random number, equivalent to [`Primitive::Rand`] From b6170f964b430f18e07b89b540818cc5a794e32f Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 21:23:25 +0200 Subject: [PATCH 3/8] Implement gen_range(-1..=1), seems to be more uniform than the previous way --- src/algorithm/monadic/sort.rs | 7 +++++-- src/constant.rs | 12 ++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/algorithm/monadic/sort.rs b/src/algorithm/monadic/sort.rs index 3ba2ecbfb..1a36329f3 100644 --- a/src/algorithm/monadic/sort.rs +++ b/src/algorithm/monadic/sort.rs @@ -1,8 +1,10 @@ use std::{cmp::Ordering, ptr}; use ecow::EcoVec; -use rand_xoshiro::Xoshiro256Plus; -use rand_xoshiro::rand_core::SeedableRng; +use rand_xoshiro::{ + Xoshiro256Plus, + rand_core::{RngCore, SeedableRng}, +}; use rayon::prelude::*; use crate::{Array, ArrayValue, Value, algorithm::ArrayCmpSlice, random_with, val_as_arr}; @@ -246,6 +248,7 @@ impl Array { } } }; + if i == j { continue; } diff --git a/src/constant.rs b/src/constant.rs index a2725f078..089852cd2 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -7,8 +7,10 @@ use std::{ }; use ecow::EcoVec; -use rand_xoshiro::Xoshiro256Plus; -use rand_xoshiro::rand_core::SeedableRng; +use rand_xoshiro::{ + Xoshiro256Plus, + rand_core::{RngCore, SeedableRng}, +}; use crate::{ Array, Boxed, PrimDocFragment, SysBackend, Uiua, Value, WILDCARD_NAN, media, @@ -589,6 +591,8 @@ fn music_constant(backend: &dyn SysBackend) -> Value { hat_bits >>= 1; } let mut rng = Xoshiro256Plus::seed_from_u64(0); + let mut rand_wrench = + || 2.0 * f64::from_bits(rng.next_u64() >> 12 | 0x3FF0_0000_0000_0000) - 3.0; // gen_range(-1..=1) let sr = backend.audio_sample_rate(); (0..(BEAT * 2.0 * 16.0 * sr as f64) as usize) .map(|s| { @@ -602,11 +606,11 @@ fn music_constant(backend: &dyn SysBackend) -> Value { let h = if (h * secs % 1.0) < 0.5 { 1.0 } else { -1.0 } / 3.0; // Square wave let kick = ((secs % BEAT).powf(0.4) * 40.0 * TAU).sin(); let hat = 0.3 - * rng.random_range(-1.0..=1.0) + * rand_wrench() * hat_mask[(4.0 * beat) as usize % 32] * (0.0..=0.1).contains(&(secs % (BEAT / 4.0) / (BEAT / 4.0))) as u8 as f64; let snare = 0.5 - * rng.random_range(-1.0..=1.0) + * rand_wrench() * ((0.5..=0.6).contains(&(secs % (2.0 * BEAT) / (2.0 * BEAT))) as u8 as f64); 0.5 * (m + h + kick + hat + snare) From 029bfcf1aa3bfb049f2b89c54c793090c95127b4 Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 22:07:40 +0200 Subject: [PATCH 4/8] Make sure the random numbers are in the correct range --- src/algorithm/dyadic/mod.rs | 2 +- src/algorithm/monadic/sort.rs | 5 +---- src/run_prim.rs | 5 ++--- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/algorithm/dyadic/mod.rs b/src/algorithm/dyadic/mod.rs index 84ecbf8d3..0c79308da 100644 --- a/src/algorithm/dyadic/mod.rs +++ b/src/algorithm/dyadic/mod.rs @@ -2140,7 +2140,7 @@ impl Value { let elem_count = validate_size::(shape.iter().copied(), env)?; let mut data = eco_vec![0.0; elem_count]; for x in data.make_mut() { - *x = f64::from_bits(rng.next_u64()); + *x = f64::from_bits(rng.next_u64() >> 12 | 0x3FF0_0000_0000_0000) - 1.0; } Ok(Array::new(shape, data)) }; diff --git a/src/algorithm/monadic/sort.rs b/src/algorithm/monadic/sort.rs index 1a36329f3..06a8c6aad 100644 --- a/src/algorithm/monadic/sort.rs +++ b/src/algorithm/monadic/sort.rs @@ -1,10 +1,7 @@ use std::{cmp::Ordering, ptr}; use ecow::EcoVec; -use rand_xoshiro::{ - Xoshiro256Plus, - rand_core::{RngCore, SeedableRng}, -}; +use rand_xoshiro::rand_core::RngCore; use rayon::prelude::*; use crate::{Array, ArrayValue, Value, algorithm::ArrayCmpSlice, random_with, val_as_arr}; diff --git a/src/run_prim.rs b/src/run_prim.rs index a30393df6..af18d1ec6 100644 --- a/src/run_prim.rs +++ b/src/run_prim.rs @@ -14,12 +14,11 @@ use std::{ collections::HashMap, f64::consts::{PI, TAU}, iter::repeat_n, - mem::transmute, sync::{ OnceLock, atomic::{self, AtomicUsize}, }, - time::{Duration, SystemTime, UNIX_EPOCH}, + time::{SystemTime, UNIX_EPOCH}, }; use rand_xoshiro::{ @@ -1879,7 +1878,7 @@ thread_local! { /// Generate a random number, equivalent to [`Primitive::Rand`] pub fn random() -> f64 { - random_with(|rng| f64::from_bits(rng.next_u64())) + random_with(|rng| f64::from_bits(rng.next_u64() >> 12 | 0x3FF0_0000_0000_0000) - 1.0) } /// Access the interpreter's random number generator for the thread From ce76e27261c61797688fea126f06363ef92ea8d8 Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 22:07:59 +0200 Subject: [PATCH 5/8] Make site's `shuffle` call functional --- site/src/main.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/site/src/main.rs b/site/src/main.rs index ff6f4f631..de6c2aaa4 100644 --- a/site/src/main.rs +++ b/site/src/main.rs @@ -19,7 +19,10 @@ use js_sys::Date; use leptos::*; use leptos_meta::*; use leptos_router::*; -use rand::prelude::*; +use rand_xoshiro::{ + Xoshiro256Plus, + rand_core::{RngCore, SeedableRng}, +}; use uiua::{ConstantDef, Primitive, SysOp, now}; use uiua_editor::{ EDITOR_SHORTCUTS, Editor, EditorMode, Prim, binding_name_class, lang, @@ -267,9 +270,23 @@ pub fn MainPage() -> impl IntoView { let indices = if visits < 4 { vec![0, rich_prims.len() - 3, rich_prims.len() - 1] } else { - let mut rng = SmallRng::seed_from_u64(visits as u64); let mut indices: Vec = (0..rich_prims.len()).collect(); - indices.shuffle(&mut rng); + { + // Shuffle indices + let l = indices.len(); + let upper = l.next_power_of_two(); + let mut rng = Xoshiro256Plus::seed_from_u64(visits as u64); + + for i in 0..indices.len() { + let index = loop { + let r = rng.next_u64() as usize % upper; + if r < l { + break r; + } + }; + indices.swap(i, index); + } + } indices.truncate(3); indices.sort_unstable(); indices From b156ff0b8d81b2baf8e4152fa903c8cce1ebc642 Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 22:26:16 +0200 Subject: [PATCH 6/8] Seed from time properly --- src/run_prim.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/run_prim.rs b/src/run_prim.rs index af18d1ec6..6682a4a34 100644 --- a/src/run_prim.rs +++ b/src/run_prim.rs @@ -1872,8 +1872,7 @@ fn undo_regex(env: &mut Uiua) -> UiuaResult { } thread_local! { - pub(crate) static RNG: RefCell = RefCell::new(Xoshiro256Plus::seed_from_u64( - SystemTime::now().duration_since(UNIX_EPOCH).map(|t|t.as_micros()).unwrap_or(42) as u64)); + pub(crate) static RNG: RefCell = RefCell::new(Xoshiro256Plus::seed_from_u64(f64::to_bits(crate::now()))) } /// Generate a random number, equivalent to [`Primitive::Rand`] From f386dae2a1a761a6daf82001232548d8d955e608 Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 22:43:09 +0200 Subject: [PATCH 7/8] Add two simple tests --- tests/monadic.ua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/monadic.ua b/tests/monadic.ua index a34d22df3..bf3e6c816 100644 --- a/tests/monadic.ua +++ b/tests/monadic.ua @@ -283,3 +283,7 @@ ReprTest! ←^ ˙$"\"_\" repr _" °□⊢ ⍤⤙≍ ⟜⍜binary∘ ⇡257 ⍤⤙≍ ⟜⍜binary∘ ÷⟜⇡256 ⍤⤙≍ ⟜⍜binary∘ ×π ⇡256 + +# Rand/Gen +/×♭×⊃≥₀≤₁ gen1000_1000 0 +/×♭×⊃≥₀≤₁⍥₁₀₀₀₀⚂ \ No newline at end of file From 158703d943fc0c0addc690755ab4abaaeb297331 Mon Sep 17 00:00:00 2001 From: amatgil Date: Thu, 18 Sep 2025 22:53:45 +0200 Subject: [PATCH 8/8] Tweak tests, use ahasher --- Cargo.lock | 1 + Cargo.toml | 1 + src/algorithm/dyadic/mod.rs | 23 ++++++++++------------- src/run_prim.rs | 1 - tests/monadic.ua | 5 +++-- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bc01c255a..75db63b16 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6565,6 +6565,7 @@ dependencies = [ name = "uiua" version = "0.18.0-dev.3" dependencies = [ + "ahash", "arboard", "bitflags 2.10.0", "bytemuck", diff --git a/Cargo.toml b/Cargo.toml index 3fe503155..7b1de1e1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -182,6 +182,7 @@ wasm-bindgen = {workspace = true, optional = true} web-sys = {version = "0.3.60", optional = true} # Window dependencies +ahash = "0.8.12" eframe = {version = "0.33.0", optional = true, features = ["persistence"]} native-dialog = {version = "0.7.0", optional = true} rand_xoshiro = "0.7.0" diff --git a/src/algorithm/dyadic/mod.rs b/src/algorithm/dyadic/mod.rs index 0c79308da..2b5b7c27c 100644 --- a/src/algorithm/dyadic/mod.rs +++ b/src/algorithm/dyadic/mod.rs @@ -8,16 +8,17 @@ use core::f64; use std::{ borrow::Cow, cmp::Ordering, - hash::{DefaultHasher, Hash, Hasher}, + hash::{Hash, Hasher}, iter::{once, repeat_n}, mem::{replace, swap, take}, }; +use ahash::AHasher; use bytemuck::allocation::cast_vec; -use ecow::{eco_vec, EcoVec}; +use ecow::{EcoVec, eco_vec}; use rand_xoshiro::{ - rand_core::{RngCore, SeedableRng}, Xoshiro256Plus, + rand_core::{RngCore, SeedableRng}, }; #[cfg(not(target_arch = "wasm32"))] @@ -25,30 +26,26 @@ use rayon::prelude::*; use smallvec::SmallVec; use crate::{ - algorithm::pervade::{self, bin_pervade_recursive, InfalliblePervasiveFn}, + Complex, RNG, Shape, Uiua, UiuaResult, + algorithm::pervade::{self, InfalliblePervasiveFn, bin_pervade_recursive}, array::*, boxed::Boxed, - cowslice::{cowslice, extend_repeat, CowSlice}, + cowslice::{CowSlice, cowslice, extend_repeat}, fill::FillValue, grid_fmt::GridFmt, val_as_arr, value::Value, - Complex, Shape, Uiua, UiuaResult, RNG, }; use super::{ - shape_prefixes_match, validate_size, validate_size_of, ArrayCmpSlice, FillContext, SizeError, + ArrayCmpSlice, FillContext, SizeError, shape_prefixes_match, validate_size, validate_size_of, }; macro_rules! par_if { ($cond:expr, $if_true:expr, $if_false:expr) => {{ #[cfg(not(target_arch = "wasm32"))] { - if $cond { - $if_true - } else { - $if_false - } + if $cond { $if_true } else { $if_false } } #[cfg(target_arch = "wasm32")] $if_false @@ -2127,7 +2124,7 @@ impl Value { } /// Generate randomly seeded arrays pub fn seeded_gen(&self, seed: &Self, env: &Uiua) -> UiuaResult { - let mut hasher = DefaultHasher::new(); + let mut hasher = AHasher::default(); seed.hash(&mut hasher); let seed = hasher.finish(); let mut rng = Xoshiro256Plus::seed_from_u64(seed); diff --git a/src/run_prim.rs b/src/run_prim.rs index 6682a4a34..ef2c9246e 100644 --- a/src/run_prim.rs +++ b/src/run_prim.rs @@ -18,7 +18,6 @@ use std::{ OnceLock, atomic::{self, AtomicUsize}, }, - time::{SystemTime, UNIX_EPOCH}, }; use rand_xoshiro::{ diff --git a/tests/monadic.ua b/tests/monadic.ua index bf3e6c816..2d0204e18 100644 --- a/tests/monadic.ua +++ b/tests/monadic.ua @@ -285,5 +285,6 @@ ReprTest! ←^ ˙$"\"_\" repr _" °□⊢ ⍤⤙≍ ⟜⍜binary∘ ×π ⇡256 # Rand/Gen -/×♭×⊃≥₀≤₁ gen1000_1000 0 -/×♭×⊃≥₀≤₁⍥₁₀₀₀₀⚂ \ No newline at end of file +⍤⤙≍1 /×♭×⊃≥₀≤₁ gen1000_1000 0 +⍤⤙≍1 /×♭×⊃≥₀≤₁⍥₁₀₀₀₀⚂ +⍤⤙≍ 1000_1000 △gen1000_1000 0 \ No newline at end of file