binius_field/
packed_extension.rs1use crate::{
4 ExtensionField, Field, PackedField,
5 as_packed_field::PackScalar,
6 underlier::{Divisible, WithUnderlier},
7};
8
9unsafe trait PackedFieldIndexable: PackedField {}
21
22unsafe impl<S, P> PackedFieldIndexable for P
23where
24 S: Field,
25 P: PackedDivisible<S, Scalar = S>,
26{
27}
28
29#[inline(always)]
33#[allow(clippy::redundant_clone)]
34pub fn is_packed_field_indexable<P: PackedField>() -> bool {
35 struct X<T> {
38 cloned: bool,
39 _pd: std::marker::PhantomData<T>,
40 }
41
42 impl<T> Clone for X<T> {
43 fn clone(&self) -> Self {
44 Self {
45 cloned: true,
46 _pd: std::marker::PhantomData,
47 }
48 }
49 }
50
51 impl<T: PackedFieldIndexable> Copy for X<T> {}
52
53 let arr = [X::<P> {
54 cloned: false,
55 _pd: std::marker::PhantomData,
56 }];
57 let cloned = arr.clone();
58
59 !cloned[0].cloned
60}
61
62pub trait PackedExtension<FS: Field>: PackedField<Scalar: ExtensionField<FS>> {
98 type PackedSubfield: PackedField<Scalar = FS>;
99
100 fn cast_bases(packed: &[Self]) -> &[Self::PackedSubfield];
101 fn cast_bases_mut(packed: &mut [Self]) -> &mut [Self::PackedSubfield];
102
103 fn cast_exts(packed: &[Self::PackedSubfield]) -> &[Self];
104 fn cast_exts_mut(packed: &mut [Self::PackedSubfield]) -> &mut [Self];
105
106 fn cast_base(self) -> Self::PackedSubfield;
107 fn cast_base_ref(&self) -> &Self::PackedSubfield;
108 fn cast_base_mut(&mut self) -> &mut Self::PackedSubfield;
109
110 fn cast_ext(base: Self::PackedSubfield) -> Self;
111 fn cast_ext_ref(base: &Self::PackedSubfield) -> &Self;
112 fn cast_ext_mut(base: &mut Self::PackedSubfield) -> &mut Self;
113
114 #[inline(always)]
115 fn cast_base_arr<const N: usize>(packed: [Self; N]) -> [Self::PackedSubfield; N] {
116 packed.map(Self::cast_base)
117 }
118
119 #[inline(always)]
120 fn cast_base_arr_ref<const N: usize>(packed: &[Self; N]) -> &[Self::PackedSubfield; N] {
121 Self::cast_bases(packed)
122 .try_into()
123 .expect("array has size N")
124 }
125
126 #[inline(always)]
127 fn cast_base_arr_mut<const N: usize>(packed: &mut [Self; N]) -> &mut [Self::PackedSubfield; N] {
128 Self::cast_bases_mut(packed)
129 .try_into()
130 .expect("array has size N")
131 }
132
133 #[inline(always)]
134 fn cast_ext_arr<const N: usize>(packed: [Self::PackedSubfield; N]) -> [Self; N] {
135 packed.map(Self::cast_ext)
136 }
137
138 #[inline(always)]
139 fn cast_ext_arr_ref<const N: usize>(packed: &[Self::PackedSubfield; N]) -> &[Self; N] {
140 Self::cast_exts(packed)
141 .try_into()
142 .expect("array has size N")
143 }
144
145 #[inline(always)]
146 fn cast_ext_arr_mut<const N: usize>(packed: &mut [Self::PackedSubfield; N]) -> &mut [Self; N] {
147 Self::cast_exts_mut(packed)
148 .try_into()
149 .expect("array has size N")
150 }
151}
152
153impl<PT, FS> PackedExtension<FS> for PT
154where
155 FS: Field,
156 PT: PackedField<Scalar: ExtensionField<FS>> + WithUnderlier<Underlier: PackScalar<FS>>,
157{
158 type PackedSubfield = <PT::Underlier as PackScalar<FS>>::Packed;
159
160 fn cast_bases(packed: &[Self]) -> &[Self::PackedSubfield] {
161 Self::PackedSubfield::from_underliers_ref(Self::to_underliers_ref(packed))
162 }
163
164 fn cast_bases_mut(packed: &mut [Self]) -> &mut [Self::PackedSubfield] {
165 Self::PackedSubfield::from_underliers_ref_mut(Self::to_underliers_ref_mut(packed))
166 }
167
168 fn cast_exts(base: &[Self::PackedSubfield]) -> &[Self] {
169 Self::from_underliers_ref(Self::PackedSubfield::to_underliers_ref(base))
170 }
171
172 fn cast_exts_mut(base: &mut [Self::PackedSubfield]) -> &mut [Self] {
173 Self::from_underliers_ref_mut(Self::PackedSubfield::to_underliers_ref_mut(base))
174 }
175
176 fn cast_base(self) -> Self::PackedSubfield {
177 Self::PackedSubfield::from_underlier(self.to_underlier())
178 }
179
180 fn cast_base_ref(&self) -> &Self::PackedSubfield {
181 Self::PackedSubfield::from_underlier_ref(self.to_underlier_ref())
182 }
183
184 fn cast_base_mut(&mut self) -> &mut Self::PackedSubfield {
185 Self::PackedSubfield::from_underlier_ref_mut(self.to_underlier_ref_mut())
186 }
187
188 fn cast_ext(base: Self::PackedSubfield) -> Self {
189 Self::from_underlier(base.to_underlier())
190 }
191
192 fn cast_ext_ref(base: &Self::PackedSubfield) -> &Self {
193 Self::from_underlier_ref(base.to_underlier_ref())
194 }
195
196 fn cast_ext_mut(base: &mut Self::PackedSubfield) -> &mut Self {
197 Self::from_underlier_ref_mut(base.to_underlier_ref_mut())
198 }
199}
200
201pub type PackedSubfield<P, F> = <P as PackedExtension<F>>::PackedSubfield;
204
205pub fn recast_packed<P, FSub1, FSub2>(elem: PackedSubfield<P, FSub1>) -> PackedSubfield<P, FSub2>
207where
208 P: PackedField + PackedExtension<FSub1> + PackedExtension<FSub2>,
209 P::Scalar: ExtensionField<FSub1> + ExtensionField<FSub2>,
210 FSub1: Field,
211 FSub2: Field,
212{
213 <P as PackedExtension<FSub2>>::cast_base(<P as PackedExtension<FSub1>>::cast_ext(elem))
214}
215
216pub fn recast_packed_slice<P, FSub1, FSub2>(
218 elems: &[PackedSubfield<P, FSub1>],
219) -> &[PackedSubfield<P, FSub2>]
220where
221 P: PackedField + PackedExtension<FSub1> + PackedExtension<FSub2>,
222 P::Scalar: ExtensionField<FSub1> + ExtensionField<FSub2>,
223 FSub1: Field,
224 FSub2: Field,
225{
226 <P as PackedExtension<FSub2>>::cast_bases(<P as PackedExtension<FSub1>>::cast_exts(elems))
227}
228
229pub fn recast_packed_mut<P, FSub1, FSub2>(
232 elems: &mut [PackedSubfield<P, FSub1>],
233) -> &mut [PackedSubfield<P, FSub2>]
234where
235 P: PackedField + PackedExtension<FSub1> + PackedExtension<FSub2>,
236 P::Scalar: ExtensionField<FSub1> + ExtensionField<FSub2>,
237 FSub1: Field,
238 FSub2: Field,
239{
240 <P as PackedExtension<FSub2>>::cast_bases_mut(<P as PackedExtension<FSub1>>::cast_exts_mut(
241 elems,
242 ))
243}
244
245pub trait RepackedExtension<P: PackedField>:
248 PackedField<Scalar: ExtensionField<P::Scalar>> + PackedExtension<P::Scalar, PackedSubfield = P>
249{
250}
251
252impl<PT1, PT2> RepackedExtension<PT1> for PT2
253where
254 PT1: PackedField,
255 PT2: PackedExtension<PT1::Scalar, PackedSubfield = PT1, Scalar: ExtensionField<PT1::Scalar>>,
256{
257}
258
259unsafe trait PackedDivisible<P>: PackedField
270where
271 P: PackedField<Scalar = Self::Scalar>,
272{
273}
274
275unsafe impl<PT1, PT2> PackedDivisible<PT2> for PT1
276where
277 PT2: PackedField + WithUnderlier,
278 PT1: PackedField<Scalar = PT2::Scalar> + WithUnderlier<Underlier: Divisible<PT2::Underlier>>,
279{
280}