binius_core/protocols/gkr_gpa/
packed_field_storage.rs1use std::ops::Deref;
4
5use binius_field::PackedField;
6use binius_math::{Error, MultilinearExtension};
7use binius_utils::checked_arithmetics::checked_log_2;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
12pub enum PackedFieldStorage<'a, P: PackedField> {
13 SliceRef(&'a [P]),
14 Inline { data: P, size: usize },
15}
16
17impl<'a, P: PackedField> PackedFieldStorage<'a, P> {
18 pub fn new_inline(values: impl Iterator<Item = P::Scalar>) -> Result<Self, Error> {
21 let mut data = P::default();
22 let mut size = 0;
23 for (i, val) in values.enumerate() {
24 data.set_checked(i, val)?;
25 size += 1;
26 }
27 Ok(Self::Inline { data, size })
28 }
29
30 pub const fn new_slice(data: &'a [P]) -> Self {
32 Self::SliceRef(data)
33 }
34
35 pub const fn n_scalars(&self) -> usize {
37 match self {
38 PackedFieldStorage::SliceRef(data) => data.len() * P::WIDTH,
39 PackedFieldStorage::Inline { size, .. } => *size,
40 }
41 }
42
43 pub fn log_n_scalars(&self) -> Option<usize> {
46 self.n_scalars()
47 .is_power_of_two()
48 .then(|| checked_log_2(self.n_scalars()))
49 }
50}
51
52impl<'a, P: PackedField> From<&'a [P]> for PackedFieldStorage<'a, P> {
53 fn from(data: &'a [P]) -> Self {
54 PackedFieldStorage::new_slice(data)
55 }
56}
57
58impl<P: PackedField> Deref for PackedFieldStorage<'_, P> {
59 type Target = [P];
60
61 fn deref(&self) -> &Self::Target {
62 match self {
63 PackedFieldStorage::SliceRef(data) => data,
64 PackedFieldStorage::Inline { data, .. } => std::slice::from_ref(data),
65 }
66 }
67}
68
69impl<'a, P: PackedField> TryFrom<PackedFieldStorage<'a, P>>
70 for MultilinearExtension<P, PackedFieldStorage<'a, P>>
71{
72 type Error = Error;
73
74 fn try_from(storage: PackedFieldStorage<'a, P>) -> Result<Self, Error> {
75 Self::new(
76 storage
77 .log_n_scalars()
78 .ok_or(binius_math::Error::PowerOfTwoLengthRequired)?,
79 storage,
80 )
81 }
82}