pub enum RngMethod {
IndexedSplitMix64,
Pcg64,
Pcg64Mcg,
SmallRng,
ChaCha8,
ChaCha12,
ChaCha20,
}Expand description
Random methods implemented by PiP stochastic components.
Variants§
Implementations§
Source§impl RngMethod
impl RngMethod
Sourcepub const fn name(self) -> &'static str
pub const fn name(self) -> &'static str
Stable method identifier for scientific provenance.
Examples found in repository?
examples/tensor_rand_large_benchmark.rs (line 37)
19fn main() {
20 let len = parse_arg(1).unwrap_or(DEFAULT_LEN);
21 let repeats = parse_arg(2).unwrap_or(DEFAULT_REPEATS);
22 let rng_kinds = parse_rng_kinds(3).unwrap_or_else(|| DEFAULT_RNG_KINDS.to_vec());
23 let kind = RandType::Uniform {
24 low: -1.0,
25 high: 1.0,
26 };
27
28 println!("tensor random fill benchmark");
29 println!("elements: {len}");
30 println!("bytes per array: {}", bytes_human(len * size_of::<f64>()));
31 println!("repeats: {repeats}");
32 println!("rayon threads available: {}", rayon::current_num_threads());
33 println!(
34 "rng kinds: {}",
35 rng_kinds
36 .iter()
37 .map(|kind| kind.name())
38 .collect::<Vec<_>>()
39 .join(", ")
40 );
41 println!();
42
43 println!(
44 "{:<12} {:>14} {:>14} {:>14} {:>14} {:>12} {:>12}",
45 "rng", "tensor best", "tensor avg", "seq best", "seq avg", "best x", "avg x"
46 );
47 println!("{}", "-".repeat(100));
48
49 for rng_kind in rng_kinds {
50 let tensor = benchmark_tensor_fill(len, repeats, kind, rng_kind);
51 let sequential = benchmark_sequential_vec_fill(len, repeats, rng_kind);
52 report(rng_kind, &tensor, &sequential);
53 }
54}
55
56#[derive(Debug, Clone, Copy)]
57struct Timing {
58 best: Duration,
59 average: Duration,
60 checksum: f64,
61}
62
63fn benchmark_tensor_fill(
64 len: usize,
65 repeats: usize,
66 kind: RandType,
67 rng_kind: RngMethod,
68) -> Timing {
69 let mut tensor = Tensor::<f64>::empty(&[len]);
70 let mut filler = TensorRandFiller::new(kind, RngConfig::new(Some(SEED), Some(rng_kind)));
71
72 filler.refresh(&mut tensor);
73
74 let timings = (0..repeats)
75 .map(|_| {
76 let start = Instant::now();
77 filler.refresh(&mut tensor);
78 start.elapsed()
79 })
80 .collect::<Vec<_>>();
81
82 Timing {
83 best: *timings.iter().min().expect("at least one repeat"),
84 average: average(&timings),
85 checksum: black_box(tensor.sum()),
86 }
87}
88
89fn benchmark_sequential_vec_fill(len: usize, repeats: usize, rng_kind: RngMethod) -> Timing {
90 match rng_kind {
91 RngMethod::SmallRng => {
92 benchmark_sequential_vec_fill_with_rng(len, repeats, SmallRng::seed_from_u64(SEED))
93 }
94 RngMethod::Pcg64Mcg => {
95 benchmark_sequential_vec_fill_with_rng(len, repeats, Pcg64Mcg::seed_from_u64(SEED))
96 }
97 RngMethod::Pcg64 => {
98 benchmark_sequential_vec_fill_with_rng(len, repeats, Pcg64::seed_from_u64(SEED))
99 }
100 RngMethod::ChaCha8 => {
101 benchmark_sequential_vec_fill_with_rng(len, repeats, ChaCha8Rng::seed_from_u64(SEED))
102 }
103 RngMethod::ChaCha12 => {
104 benchmark_sequential_vec_fill_with_rng(len, repeats, ChaCha12Rng::seed_from_u64(SEED))
105 }
106 RngMethod::ChaCha20 => {
107 benchmark_sequential_vec_fill_with_rng(len, repeats, ChaCha20Rng::seed_from_u64(SEED))
108 }
109 RngMethod::IndexedSplitMix64 => panic!("indexed randomness is not a tensor stream"),
110 }
111}
112
113fn benchmark_sequential_vec_fill_with_rng<R>(len: usize, repeats: usize, mut rng: R) -> Timing
114where
115 R: rand::Rng,
116{
117 let dist = Uniform::new(-1.0, 1.0).expect("valid uniform bounds");
118 let mut data = vec![0.0; len];
119
120 fill_sequential_with_rng(&mut data, &dist, &mut rng);
121
122 let timings = (0..repeats)
123 .map(|_| {
124 let start = Instant::now();
125 fill_sequential_with_rng(&mut data, &dist, &mut rng);
126 start.elapsed()
127 })
128 .collect::<Vec<_>>();
129
130 Timing {
131 best: *timings.iter().min().expect("at least one repeat"),
132 average: average(&timings),
133 checksum: checksum(&data),
134 }
135}
136
137fn fill_sequential_with_rng<R>(data: &mut [f64], dist: &Uniform<f64>, rng: &mut R)
138where
139 R: rand::Rng + ?Sized,
140{
141 for x in data {
142 *x = dist.sample(rng);
143 }
144}
145
146fn checksum(data: &[f64]) -> f64 {
147 data.iter().copied().sum::<f64>().pipe(black_box)
148}
149
150fn average(times: &[Duration]) -> Duration {
151 let total = times.iter().map(Duration::as_secs_f64).sum::<f64>();
152 Duration::from_secs_f64(total / times.len() as f64)
153}
154
155fn report(rng_kind: RngMethod, tensor: &Timing, sequential: &Timing) {
156 println!(
157 "{:<12} {:>14} {:>14} {:>14} {:>14} {:>12.3} {:>12.3}",
158 rng_kind.name(),
159 millis(tensor.best),
160 millis(tensor.average),
161 millis(sequential.best),
162 millis(sequential.average),
163 sequential.best.as_secs_f64() / tensor.best.as_secs_f64(),
164 sequential.average.as_secs_f64() / tensor.average.as_secs_f64()
165 );
166 println!(
167 "{:<12} tensor checksum {:>16.6}, sequential checksum {:>16.6}",
168 "", tensor.checksum, sequential.checksum
169 );
170}Sourcepub const fn seed_encoding(self) -> &'static str
pub const fn seed_encoding(self) -> &'static str
Stable encoding used for the root seed.
Sourcepub fn from_name(name: &str) -> Option<Self>
pub fn from_name(name: &str) -> Option<Self>
Parses a user-facing method name.
Examples found in repository?
examples/tensor_rand_large_benchmark.rs (line 195)
180fn parse_rng_kinds(position: usize) -> Option<Vec<RngMethod>> {
181 let arg = std::env::args().nth(position)?;
182 if arg.eq_ignore_ascii_case("all") {
183 return Some(vec![
184 RngMethod::Pcg64,
185 RngMethod::Pcg64Mcg,
186 RngMethod::SmallRng,
187 RngMethod::ChaCha8,
188 RngMethod::ChaCha12,
189 RngMethod::ChaCha20,
190 ]);
191 }
192
193 let kinds = arg
194 .split(',')
195 .filter_map(|name| RngMethod::from_name(name.trim()))
196 .collect::<Vec<_>>();
197
198 if kinds.is_empty() { None } else { Some(kinds) }
199}Trait Implementations§
impl Copy for RngMethod
Source§impl<'de> Deserialize<'de> for RngMethod
impl<'de> Deserialize<'de> for RngMethod
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
impl Eq for RngMethod
impl StructuralPartialEq for RngMethod
Auto Trait Implementations§
impl Freeze for RngMethod
impl RefUnwindSafe for RngMethod
impl Send for RngMethod
impl Sync for RngMethod
impl Unpin for RngMethod
impl UnsafeUnpin for RngMethod
impl UnwindSafe for RngMethod
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
Converts
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
Converts
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more