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