treams_core/numerics/
memory.rs1use nalgebra::DMatrix;
12
13use crate::{Complex, Error, Result};
14
15pub(crate) fn zeros(rows: usize, cols: usize) -> Result<DMatrix<Complex>> {
17 let len = rows
18 .checked_mul(cols)
19 .ok_or_else(|| Error::out_of_memory(usize::MAX, size_of::<Complex>()))?;
20 Ok(DMatrix::from_vec(
21 rows,
22 cols,
23 filled(len, Complex::default())?,
24 ))
25}
26
27pub(crate) fn filled<T: Clone>(len: usize, value: T) -> Result<Vec<T>> {
29 let mut values = Vec::new();
30 reserve(&mut values, len)?;
31 values.resize(len, value);
32 Ok(values)
33}
34
35pub(crate) fn reserve<T>(values: &mut Vec<T>, additional: usize) -> Result<()> {
37 values
38 .try_reserve_exact(additional)
39 .map_err(|_| Error::out_of_memory(values.len().saturating_add(additional), size_of::<T>()))
40}
41
42#[cfg(test)]
44mod tests {
45 use super::{filled, reserve, zeros};
46 use crate::Error;
47
48 #[test]
49 fn requests_beyond_the_address_space_return_out_of_memory() {
50 let error = zeros(1 << 24, 1 << 24).unwrap_err();
53 assert!(
54 matches!(&error, Error::OutOfMemory(message) if message == "cannot allocate 4503599627370496 bytes"),
55 "{error:?}"
56 );
57 assert!(!error.is_numerical());
58 let mut values = vec![0_u8; 3];
59 assert!(matches!(
60 reserve(&mut values, 1 << 52),
61 Err(Error::OutOfMemory(_))
62 ));
63 assert_eq!(values, [0, 0, 0]);
64 }
65
66 #[test]
67 fn overflowing_requests_return_out_of_memory_without_panicking() {
68 let more = format!("cannot allocate more than {} bytes", usize::MAX);
69 for (rows, cols) in [(usize::MAX, 1), (usize::MAX, 2), (1 << 33, 1 << 33)] {
70 let error = zeros(rows, cols).unwrap_err();
71 assert!(
72 matches!(&error, Error::OutOfMemory(message) if *message == more),
73 "{rows} x {cols}: {error:?}"
74 );
75 }
76 assert!(matches!(
77 filled(usize::MAX, 0.0_f64),
78 Err(Error::OutOfMemory(message)) if message == more
79 ));
80 let mut values = vec![0_u64; 2];
81 assert!(matches!(
82 reserve(&mut values, usize::MAX),
83 Err(Error::OutOfMemory(message)) if message == more
84 ));
85 }
86
87 #[test]
88 fn granted_requests_hold_the_requested_values() {
89 let matrix = zeros(3, 2).unwrap();
90 assert_eq!(matrix.shape(), (3, 2));
91 assert!(matrix.iter().all(|&z| z == crate::Complex::default()));
92 assert_eq!(zeros(0, 7).unwrap().shape(), (0, 7));
93 assert_eq!(filled(4, 1.5).unwrap(), [1.5; 4]);
94 let mut values = vec![1];
95 reserve(&mut values, 5).unwrap();
96 assert!(values.capacity() >= 6);
97 }
98}