binius_compute/cpu/
memory.rs1use std::{collections::Bound, ops::RangeBounds};
4
5use crate::memory::ComputeMemory;
6
7#[derive(Debug)]
8pub struct CpuMemory;
9
10impl<F: 'static + Sync> ComputeMemory<F> for CpuMemory {
11 const ALIGNMENT: usize = 1;
12
13 type FSlice<'a> = &'a [F];
14 type FSliceMut<'a> = &'a mut [F];
15
16 fn narrow<'a>(data: &'a &[F]) -> &'a [F] {
17 data
18 }
19
20 fn narrow_mut<'a, 'b: 'a>(data: Self::FSliceMut<'b>) -> Self::FSliceMut<'a> {
21 data
22 }
23
24 fn as_const<'a>(data: &'a &mut [F]) -> &'a [F] {
25 data
26 }
27
28 fn slice(data: Self::FSlice<'_>, range: impl RangeBounds<usize>) -> Self::FSlice<'_> {
29 let start = match range.start_bound() {
30 Bound::Included(&start) => start,
31 Bound::Excluded(&start) => start + 1,
32 Bound::Unbounded => 0,
33 };
34 let end = match range.end_bound() {
35 Bound::Included(&end) => end + 1,
36 Bound::Excluded(&end) => end,
37 Bound::Unbounded => data.len(),
38 };
39 &data[start..end]
40 }
41
42 fn slice_mut<'a>(data: &'a mut &mut [F], range: impl RangeBounds<usize>) -> &'a mut [F] {
43 let start = match range.start_bound() {
44 Bound::Included(&start) => start,
45 Bound::Excluded(&start) => start + 1,
46 Bound::Unbounded => 0,
47 };
48 let end = match range.end_bound() {
49 Bound::Included(&end) => end + 1,
50 Bound::Excluded(&end) => end,
51 Bound::Unbounded => data.len(),
52 };
53 &mut data[start..end]
54 }
55
56 fn split_at_mut(
57 data: Self::FSliceMut<'_>,
58 mid: usize,
59 ) -> (Self::FSliceMut<'_>, Self::FSliceMut<'_>) {
60 data.split_at_mut(mid)
61 }
62
63 fn to_owned_mut<'a>(data: &'a mut &mut [F]) -> &'a mut [F] {
64 data
65 }
66
67 fn slice_chunks_mut<'a>(
68 data: Self::FSliceMut<'a>,
69 chunk_len: usize,
70 ) -> impl Iterator<Item = Self::FSliceMut<'a>> {
71 assert_eq!(data.len() % chunk_len, 0, "slice length must be a multiple of chunk_len",);
72
73 data.chunks_exact_mut(chunk_len)
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_try_slice_on_mem_slice() {
83 let data = [4, 5, 6];
84 assert_eq!(CpuMemory::slice(&data, 0..2), &data[0..2]);
85 assert_eq!(CpuMemory::slice(&data, ..2), &data[..2]);
86 assert_eq!(CpuMemory::slice(&data, 1..), &data[1..]);
87 assert_eq!(CpuMemory::slice(&data, ..), &data[..]);
88 }
89
90 #[test]
91 fn test_convert_mut_mem_slice_to_const() {
92 let mut data = [4, 5, 6];
93 let data_clone = data;
94 let data = &mut data[..];
95 let data = CpuMemory::as_const(&data);
96 assert_eq!(data, &data_clone);
97 }
98
99 #[test]
100 fn test_try_slice_on_mut_mem_slice() {
101 let mut data = [4, 5, 6];
102 let mut data_clone = data;
103 let mut data = &mut data[..];
104 assert_eq!(CpuMemory::slice_mut(&mut data, 0..2), &mut data_clone[0..2]);
105 assert_eq!(CpuMemory::slice_mut(&mut data, ..2), &mut data_clone[..2]);
106 assert_eq!(CpuMemory::slice_mut(&mut data, 1..), &mut data_clone[1..]);
107 assert_eq!(CpuMemory::slice_mut(&mut data, ..), &mut data_clone[..]);
108 }
109}