binius_compute/cpu/
memory.rs

1// Copyright 2025 Irreducible Inc.
2
3use 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}