binius_field/
packed_extension.rs1use crate::{
4 as_packed_field::PackScalar,
5 underlier::{Divisible, WithUnderlier},
6 ExtensionField, Field, PackedField,
7};
8
9pub unsafe trait PackedFieldIndexable: PackedField {
21 fn unpack_scalars(packed: &[Self]) -> &[Self::Scalar];
22 fn unpack_scalars_mut(packed: &mut [Self]) -> &mut [Self::Scalar];
23}
24
25unsafe impl<S, P> PackedFieldIndexable for P
26where
27 S: Field,
28 P: PackedDivisible<S, Scalar = S>,
29{
30 fn unpack_scalars(packed: &[Self]) -> &[Self::Scalar] {
31 P::divide(packed)
32 }
33
34 fn unpack_scalars_mut(packed: &mut [Self]) -> &mut [Self::Scalar] {
35 P::divide_mut(packed)
36 }
37}
38
39pub trait PackedExtension<FS: Field>: PackedField<Scalar: ExtensionField<FS>> {
75 type PackedSubfield: PackedField<Scalar = FS>;
76
77 fn cast_bases(packed: &[Self]) -> &[Self::PackedSubfield];
78 fn cast_bases_mut(packed: &mut [Self]) -> &mut [Self::PackedSubfield];
79
80 fn cast_exts(packed: &[Self::PackedSubfield]) -> &[Self];
81 fn cast_exts_mut(packed: &mut [Self::PackedSubfield]) -> &mut [Self];
82
83 fn cast_base(self) -> Self::PackedSubfield;
84 fn cast_base_ref(&self) -> &Self::PackedSubfield;
85 fn cast_base_mut(&mut self) -> &mut Self::PackedSubfield;
86
87 fn cast_ext(base: Self::PackedSubfield) -> Self;
88 fn cast_ext_ref(base: &Self::PackedSubfield) -> &Self;
89 fn cast_ext_mut(base: &mut Self::PackedSubfield) -> &mut Self;
90
91 #[inline(always)]
92 fn cast_base_arr<const N: usize>(packed: [Self; N]) -> [Self::PackedSubfield; N] {
93 packed.map(Self::cast_base)
94 }
95
96 #[inline(always)]
97 fn cast_base_arr_ref<const N: usize>(packed: &[Self; N]) -> &[Self::PackedSubfield; N] {
98 Self::cast_bases(packed)
99 .try_into()
100 .expect("array has size N")
101 }
102
103 #[inline(always)]
104 fn cast_base_arr_mut<const N: usize>(packed: &mut [Self; N]) -> &mut [Self::PackedSubfield; N] {
105 Self::cast_bases_mut(packed)
106 .try_into()
107 .expect("array has size N")
108 }
109
110 #[inline(always)]
111 fn cast_ext_arr<const N: usize>(packed: [Self::PackedSubfield; N]) -> [Self; N] {
112 packed.map(Self::cast_ext)
113 }
114
115 #[inline(always)]
116 fn cast_ext_arr_ref<const N: usize>(packed: &[Self::PackedSubfield; N]) -> &[Self; N] {
117 Self::cast_exts(packed)
118 .try_into()
119 .expect("array has size N")
120 }
121
122 #[inline(always)]
123 fn cast_ext_arr_mut<const N: usize>(packed: &mut [Self::PackedSubfield; N]) -> &mut [Self; N] {
124 Self::cast_exts_mut(packed)
125 .try_into()
126 .expect("array has size N")
127 }
128}
129
130impl<PT, FS> PackedExtension<FS> for PT
131where
132 FS: Field,
133 PT: PackedField<Scalar: ExtensionField<FS>> + WithUnderlier<Underlier: PackScalar<FS>>,
134{
135 type PackedSubfield = <PT::Underlier as PackScalar<FS>>::Packed;
136
137 fn cast_bases(packed: &[Self]) -> &[Self::PackedSubfield] {
138 Self::PackedSubfield::from_underliers_ref(Self::to_underliers_ref(packed))
139 }
140
141 fn cast_bases_mut(packed: &mut [Self]) -> &mut [Self::PackedSubfield] {
142 Self::PackedSubfield::from_underliers_ref_mut(Self::to_underliers_ref_mut(packed))
143 }
144
145 fn cast_exts(base: &[Self::PackedSubfield]) -> &[Self] {
146 Self::from_underliers_ref(Self::PackedSubfield::to_underliers_ref(base))
147 }
148
149 fn cast_exts_mut(base: &mut [Self::PackedSubfield]) -> &mut [Self] {
150 Self::from_underliers_ref_mut(Self::PackedSubfield::to_underliers_ref_mut(base))
151 }
152
153 fn cast_base(self) -> Self::PackedSubfield {
154 Self::PackedSubfield::from_underlier(self.to_underlier())
155 }
156
157 fn cast_base_ref(&self) -> &Self::PackedSubfield {
158 Self::PackedSubfield::from_underlier_ref(self.to_underlier_ref())
159 }
160
161 fn cast_base_mut(&mut self) -> &mut Self::PackedSubfield {
162 Self::PackedSubfield::from_underlier_ref_mut(self.to_underlier_ref_mut())
163 }
164
165 fn cast_ext(base: Self::PackedSubfield) -> Self {
166 Self::from_underlier(base.to_underlier())
167 }
168
169 fn cast_ext_ref(base: &Self::PackedSubfield) -> &Self {
170 Self::from_underlier_ref(base.to_underlier_ref())
171 }
172
173 fn cast_ext_mut(base: &mut Self::PackedSubfield) -> &mut Self {
174 Self::from_underlier_ref_mut(base.to_underlier_ref_mut())
175 }
176}
177
178pub type PackedSubfield<P, F> = <P as PackedExtension<F>>::PackedSubfield;
181
182pub fn recast_packed<P, FSub1, FSub2>(elem: PackedSubfield<P, FSub1>) -> PackedSubfield<P, FSub2>
184where
185 P: PackedField + PackedExtension<FSub1> + PackedExtension<FSub2>,
186 P::Scalar: ExtensionField<FSub1> + ExtensionField<FSub2>,
187 FSub1: Field,
188 FSub2: Field,
189{
190 <P as PackedExtension<FSub2>>::cast_base(<P as PackedExtension<FSub1>>::cast_ext(elem))
191}
192
193pub fn recast_packed_slice<P, FSub1, FSub2>(
195 elems: &[PackedSubfield<P, FSub1>],
196) -> &[PackedSubfield<P, FSub2>]
197where
198 P: PackedField + PackedExtension<FSub1> + PackedExtension<FSub2>,
199 P::Scalar: ExtensionField<FSub1> + ExtensionField<FSub2>,
200 FSub1: Field,
201 FSub2: Field,
202{
203 <P as PackedExtension<FSub2>>::cast_bases(<P as PackedExtension<FSub1>>::cast_exts(elems))
204}
205
206pub fn recast_packed_mut<P, FSub1, FSub2>(
209 elems: &mut [PackedSubfield<P, FSub1>],
210) -> &mut [PackedSubfield<P, FSub2>]
211where
212 P: PackedField + PackedExtension<FSub1> + PackedExtension<FSub2>,
213 P::Scalar: ExtensionField<FSub1> + ExtensionField<FSub2>,
214 FSub1: Field,
215 FSub2: Field,
216{
217 <P as PackedExtension<FSub2>>::cast_bases_mut(<P as PackedExtension<FSub1>>::cast_exts_mut(
218 elems,
219 ))
220}
221
222pub trait RepackedExtension<P: PackedField>:
225 PackedField<Scalar: ExtensionField<P::Scalar>> + PackedExtension<P::Scalar, PackedSubfield = P>
226{
227}
228
229impl<PT1, PT2> RepackedExtension<PT1> for PT2
230where
231 PT1: PackedField,
232 PT2: PackedExtension<PT1::Scalar, PackedSubfield = PT1, Scalar: ExtensionField<PT1::Scalar>>,
233{
234}
235
236pub trait PackedExtensionIndexable<F: Field>:
239 PackedExtension<F, PackedSubfield: PackedFieldIndexable> + PackedField<Scalar: ExtensionField<F>>
240{
241 fn unpack_base_scalars(packed: &[Self]) -> &[F] {
242 Self::PackedSubfield::unpack_scalars(Self::cast_bases(packed))
243 }
244
245 fn unpack_base_scalars_mut(packed: &mut [Self]) -> &mut [F] {
246 Self::PackedSubfield::unpack_scalars_mut(Self::cast_bases_mut(packed))
247 }
248}
249
250impl<F, PT> PackedExtensionIndexable<F> for PT
251where
252 F: Field,
253 PT: PackedExtension<F, PackedSubfield: PackedFieldIndexable>,
254{
255}
256
257pub unsafe trait PackedDivisible<P>: PackedField
268where
269 P: PackedField<Scalar = Self::Scalar>,
270{
271 fn divide(packed: &[Self]) -> &[P];
272 fn divide_mut(packed: &mut [Self]) -> &mut [P];
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 fn divide(packed: &[Self]) -> &[PT2] {
281 let underliers = PT1::to_underliers_ref(packed);
282 let underliers: &[PT2::Underlier] = PT1::Underlier::split_slice(underliers);
283 PT2::from_underliers_ref(underliers)
284 }
285
286 fn divide_mut(packed: &mut [Self]) -> &mut [PT2] {
287 let underliers = PT1::to_underliers_ref_mut(packed);
288 let underliers: &mut [PT2::Underlier] = PT1::Underlier::split_slice_mut(underliers);
289 PT2::from_underliers_ref_mut(underliers)
290 }
291}