From 6df251e14412295b2463462f3f9bf5c220105713 Mon Sep 17 00:00:00 2001 From: Jakub Nabaglo Date: Thu, 2 Dec 2021 00:01:24 -0800 Subject: [PATCH] Remove `Singleton` type and make every `Field` a `PackedField` (#379) * Remove `Singleton` type and make every `Field` a `PackedField` * Minor: Clippy --- src/field/fft.rs | 4 +- src/field/packable.rs | 6 +- src/field/packed_field.rs | 137 ++++---------------------------------- 3 files changed, 19 insertions(+), 128 deletions(-) diff --git a/src/field/fft.rs b/src/field/fft.rs index 6f5155a4..09672278 100644 --- a/src/field/fft.rs +++ b/src/field/fft.rs @@ -5,7 +5,7 @@ use unroll::unroll_for_loops; use crate::field::field_types::Field; use crate::field::packable::Packable; -use crate::field::packed_field::{PackedField, Singleton}; +use crate::field::packed_field::PackedField; use crate::polynomial::{PolynomialCoeffs, PolynomialValues}; use crate::util::{log2_strict, reverse_index_bits}; @@ -201,7 +201,7 @@ pub(crate) fn fft_classic(input: &[F], r: usize, root_table: &FftRootT if lg_n <= lg_packed_width { // Need the slice to be at least the width of two packed vectors for the vectorized version // to work. Do this tiny problem in scalar. - fft_classic_simd::>(&mut values[..], r, lg_n, root_table); + fft_classic_simd::(&mut values[..], r, lg_n, root_table); } else { fft_classic_simd::<::PackedType>(&mut values[..], r, lg_n, root_table); } diff --git a/src/field/packable.rs b/src/field/packable.rs index 94a9c056..e5fc2ac5 100644 --- a/src/field/packable.rs +++ b/src/field/packable.rs @@ -1,15 +1,15 @@ use crate::field::field_types::Field; -use crate::field::packed_field::{PackedField, Singleton}; +use crate::field::packed_field::PackedField; /// Points us to the default packing for a particular field. There may me multiple choices of -/// PackedField for a particular Field (e.g. Singleton works for all fields), but this is the +/// PackedField for a particular Field (e.g. every Field is also a PackedField), but this is the /// recommended one. The recommended packing varies by target_arch and target_feature. pub trait Packable: Field { type PackedType: PackedField; } impl Packable for F { - default type PackedType = Singleton; + default type PackedType = Self; } #[cfg(target_feature = "avx2")] diff --git a/src/field/packed_field.rs b/src/field/packed_field.rs index a4b1945a..69733bca 100644 --- a/src/field/packed_field.rs +++ b/src/field/packed_field.rs @@ -1,5 +1,4 @@ -use std::fmt; -use std::fmt::{Debug, Formatter}; +use std::fmt::Debug; use std::iter::{Product, Sum}; use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign}; @@ -95,143 +94,35 @@ pub trait PackedField: } } -#[derive(Copy, Clone)] -#[repr(transparent)] -pub struct Singleton(pub F); +impl PackedField for F { + type FieldType = Self; -impl Add for Singleton { - type Output = Self; - fn add(self, rhs: Self) -> Self { - Self(self.0 + rhs.0) - } -} -impl Add for Singleton { - type Output = Self; - fn add(self, rhs: F) -> Self { - self + Self::broadcast(rhs) - } -} -impl AddAssign for Singleton { - fn add_assign(&mut self, rhs: Self) { - *self = *self + rhs; - } -} -impl AddAssign for Singleton { - fn add_assign(&mut self, rhs: F) { - *self = *self + rhs; - } -} - -impl Debug for Singleton { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "({:?})", self.0) - } -} - -impl Default for Singleton { - fn default() -> Self { - Self::zero() - } -} - -impl Mul for Singleton { - type Output = Self; - fn mul(self, rhs: Self) -> Self { - Self(self.0 * rhs.0) - } -} -impl Mul for Singleton { - type Output = Self; - fn mul(self, rhs: F) -> Self { - self * Self::broadcast(rhs) - } -} -impl MulAssign for Singleton { - fn mul_assign(&mut self, rhs: Self) { - *self = *self * rhs; - } -} -impl MulAssign for Singleton { - fn mul_assign(&mut self, rhs: F) { - *self = *self * rhs; - } -} - -impl Neg for Singleton { - type Output = Self; - fn neg(self) -> Self { - Self(-self.0) - } -} - -impl Product for Singleton { - fn product>(iter: I) -> Self { - Self(iter.map(|x| x.0).product()) - } -} - -impl PackedField for Singleton { const LOG2_WIDTH: usize = 0; - type FieldType = F; - fn broadcast(x: F) -> Self { - Self(x) + fn broadcast(x: Self::FieldType) -> Self { + x } fn from_arr(arr: [Self::FieldType; Self::WIDTH]) -> Self { - Self(arr[0]) + arr[0] } - fn to_arr(&self) -> [Self::FieldType; Self::WIDTH] { - [self.0] + [*self] } fn from_slice(slice: &[Self::FieldType]) -> Self { - assert!(slice.len() == 1); - Self(slice[0]) + assert_eq!(slice.len(), 1); + slice[0] } - fn to_vec(&self) -> Vec { - vec![self.0] + vec![*self] } fn interleave(&self, other: Self, r: usize) -> (Self, Self) { - match r { - 0 => (*self, other), // This is a no-op whenever r == LOG2_WIDTH. - _ => panic!("r cannot be more than LOG2_WIDTH"), + if r == 0 { + (*self, other) + } else { + panic!("r > LOG2_WIDTH"); } } - - fn square(&self) -> Self { - Self(self.0.square()) - } -} - -impl Sub for Singleton { - type Output = Self; - fn sub(self, rhs: Self) -> Self { - Self(self.0 - rhs.0) - } -} -impl Sub for Singleton { - type Output = Self; - fn sub(self, rhs: F) -> Self { - self - Self::broadcast(rhs) - } -} -impl SubAssign for Singleton { - fn sub_assign(&mut self, rhs: Self) { - *self = *self - rhs; - } -} -impl SubAssign for Singleton { - fn sub_assign(&mut self, rhs: F) { - *self = *self - rhs; - } -} - -impl Sum for Singleton { - fn sum>(iter: I) -> Self { - Self(iter.map(|x| x.0).sum()) - } }