Backend refactor (#120)

* remove spqlios, split cpu_ref and cpu_avx into different crates

* remove spqlios submodule

* update crate naming & add avx tests
This commit is contained in:
Jean-Philippe Bossuat
2025-11-19 15:34:31 +01:00
committed by GitHub
parent 84598e42fe
commit 9e007c988f
182 changed files with 1053 additions and 4483 deletions

14
poulpy-cpu-ref/src/lib.rs Normal file
View File

@@ -0,0 +1,14 @@
mod module;
mod reim;
mod scratch;
mod svp;
mod vec_znx;
mod vec_znx_big;
mod vec_znx_dft;
mod vmp;
mod znx;
#[cfg(test)]
mod tests;
pub struct FFT64Ref {}

View File

@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

View File

@@ -0,0 +1,62 @@
use std::ptr::NonNull;
use poulpy_hal::{
layouts::{Backend, Module},
oep::ModuleNewImpl,
reference::fft64::reim::{ReimFFTTable, ReimIFFTTable},
};
use crate::FFT64Ref;
#[repr(C)]
pub struct FFT64RefHandle {
table_fft: ReimFFTTable<f64>,
table_ifft: ReimIFFTTable<f64>,
}
impl Backend for FFT64Ref {
type ScalarPrep = f64;
type ScalarBig = i64;
type Handle = FFT64RefHandle;
unsafe fn destroy(handle: NonNull<Self::Handle>) {
unsafe {
drop(Box::from_raw(handle.as_ptr()));
}
}
fn layout_big_word_count() -> usize {
1
}
fn layout_prep_word_count() -> usize {
1
}
}
unsafe impl ModuleNewImpl<Self> for FFT64Ref {
fn new_impl(n: u64) -> Module<Self> {
let handle: FFT64RefHandle = FFT64RefHandle {
table_fft: ReimFFTTable::new(n as usize >> 1),
table_ifft: ReimIFFTTable::new(n as usize >> 1),
};
// Leak Box to get a stable NonNull pointer
let ptr: NonNull<FFT64RefHandle> = NonNull::from(Box::leak(Box::new(handle)));
unsafe { Module::from_nonnull(ptr, n) }
}
}
pub trait FFT64ModuleHandle {
fn get_fft_table(&self) -> &ReimFFTTable<f64>;
fn get_ifft_table(&self) -> &ReimIFFTTable<f64>;
}
impl FFT64ModuleHandle for Module<FFT64Ref> {
fn get_fft_table(&self) -> &ReimFFTTable<f64> {
let h: &FFT64RefHandle = unsafe { &*self.ptr() };
&h.table_fft
}
fn get_ifft_table(&self) -> &ReimIFFTTable<f64> {
let h: &FFT64RefHandle = unsafe { &*self.ptr() };
&h.table_ifft
}
}

176
poulpy-cpu-ref/src/reim.rs Normal file
View File

@@ -0,0 +1,176 @@
use poulpy_hal::reference::fft64::{
reim::{
ReimAdd, ReimAddInplace, ReimAddMul, ReimCopy, ReimDFTExecute, ReimFFTTable, ReimFromZnx, ReimIFFTTable, ReimMul,
ReimMulInplace, ReimNegate, ReimNegateInplace, ReimSub, ReimSubInplace, ReimSubNegateInplace, ReimToZnx,
ReimToZnxInplace, ReimZero, fft_ref, ifft_ref, reim_add_inplace_ref, reim_add_ref, reim_addmul_ref, reim_copy_ref,
reim_from_znx_i64_ref, reim_mul_inplace_ref, reim_mul_ref, reim_negate_inplace_ref, reim_negate_ref,
reim_sub_inplace_ref, reim_sub_negate_inplace_ref, reim_sub_ref, reim_to_znx_i64_inplace_ref, reim_to_znx_i64_ref,
reim_zero_ref,
},
reim4::{
Reim4Extract1Blk, Reim4Mat1ColProd, Reim4Mat2Cols2ndColProd, Reim4Mat2ColsProd, Reim4Save1Blk, Reim4Save2Blks,
reim4_extract_1blk_from_reim_ref, reim4_save_1blk_to_reim_ref, reim4_save_2blk_to_reim_ref,
reim4_vec_mat1col_product_ref, reim4_vec_mat2cols_2ndcol_product_ref, reim4_vec_mat2cols_product_ref,
},
};
use crate::FFT64Ref;
impl ReimDFTExecute<ReimFFTTable<f64>, f64> for FFT64Ref {
fn reim_dft_execute(table: &ReimFFTTable<f64>, data: &mut [f64]) {
fft_ref(table.m(), table.omg(), data);
}
}
impl ReimDFTExecute<ReimIFFTTable<f64>, f64> for FFT64Ref {
fn reim_dft_execute(table: &ReimIFFTTable<f64>, data: &mut [f64]) {
ifft_ref(table.m(), table.omg(), data);
}
}
impl ReimFromZnx for FFT64Ref {
#[inline(always)]
fn reim_from_znx(res: &mut [f64], a: &[i64]) {
reim_from_znx_i64_ref(res, a);
}
}
impl ReimToZnx for FFT64Ref {
#[inline(always)]
fn reim_to_znx(res: &mut [i64], divisor: f64, a: &[f64]) {
reim_to_znx_i64_ref(res, divisor, a);
}
}
impl ReimToZnxInplace for FFT64Ref {
#[inline(always)]
fn reim_to_znx_inplace(res: &mut [f64], divisor: f64) {
reim_to_znx_i64_inplace_ref(res, divisor);
}
}
impl ReimAdd for FFT64Ref {
#[inline(always)]
fn reim_add(res: &mut [f64], a: &[f64], b: &[f64]) {
reim_add_ref(res, a, b);
}
}
impl ReimAddInplace for FFT64Ref {
#[inline(always)]
fn reim_add_inplace(res: &mut [f64], a: &[f64]) {
reim_add_inplace_ref(res, a);
}
}
impl ReimSub for FFT64Ref {
#[inline(always)]
fn reim_sub(res: &mut [f64], a: &[f64], b: &[f64]) {
reim_sub_ref(res, a, b);
}
}
impl ReimSubInplace for FFT64Ref {
#[inline(always)]
fn reim_sub_inplace(res: &mut [f64], a: &[f64]) {
reim_sub_inplace_ref(res, a);
}
}
impl ReimSubNegateInplace for FFT64Ref {
#[inline(always)]
fn reim_sub_negate_inplace(res: &mut [f64], a: &[f64]) {
reim_sub_negate_inplace_ref(res, a);
}
}
impl ReimNegate for FFT64Ref {
#[inline(always)]
fn reim_negate(res: &mut [f64], a: &[f64]) {
reim_negate_ref(res, a);
}
}
impl ReimNegateInplace for FFT64Ref {
#[inline(always)]
fn reim_negate_inplace(res: &mut [f64]) {
reim_negate_inplace_ref(res);
}
}
impl ReimMul for FFT64Ref {
#[inline(always)]
fn reim_mul(res: &mut [f64], a: &[f64], b: &[f64]) {
reim_mul_ref(res, a, b);
}
}
impl ReimMulInplace for FFT64Ref {
#[inline(always)]
fn reim_mul_inplace(res: &mut [f64], a: &[f64]) {
reim_mul_inplace_ref(res, a);
}
}
impl ReimAddMul for FFT64Ref {
#[inline(always)]
fn reim_addmul(res: &mut [f64], a: &[f64], b: &[f64]) {
reim_addmul_ref(res, a, b);
}
}
impl ReimCopy for FFT64Ref {
#[inline(always)]
fn reim_copy(res: &mut [f64], a: &[f64]) {
reim_copy_ref(res, a);
}
}
impl ReimZero for FFT64Ref {
#[inline(always)]
fn reim_zero(res: &mut [f64]) {
reim_zero_ref(res);
}
}
impl Reim4Extract1Blk for FFT64Ref {
#[inline(always)]
fn reim4_extract_1blk(m: usize, rows: usize, blk: usize, dst: &mut [f64], src: &[f64]) {
reim4_extract_1blk_from_reim_ref(m, rows, blk, dst, src);
}
}
impl Reim4Save1Blk for FFT64Ref {
#[inline(always)]
fn reim4_save_1blk<const OVERWRITE: bool>(m: usize, blk: usize, dst: &mut [f64], src: &[f64]) {
reim4_save_1blk_to_reim_ref::<OVERWRITE>(m, blk, dst, src);
}
}
impl Reim4Save2Blks for FFT64Ref {
#[inline(always)]
fn reim4_save_2blks<const OVERWRITE: bool>(m: usize, blk: usize, dst: &mut [f64], src: &[f64]) {
reim4_save_2blk_to_reim_ref::<OVERWRITE>(m, blk, dst, src);
}
}
impl Reim4Mat1ColProd for FFT64Ref {
#[inline(always)]
fn reim4_mat1col_prod(nrows: usize, dst: &mut [f64], u: &[f64], v: &[f64]) {
reim4_vec_mat1col_product_ref(nrows, dst, u, v);
}
}
impl Reim4Mat2ColsProd for FFT64Ref {
#[inline(always)]
fn reim4_mat2cols_prod(nrows: usize, dst: &mut [f64], u: &[f64], v: &[f64]) {
reim4_vec_mat2cols_product_ref(nrows, dst, u, v);
}
}
impl Reim4Mat2Cols2ndColProd for FFT64Ref {
#[inline(always)]
fn reim4_mat2cols_2ndcol_prod(nrows: usize, dst: &mut [f64], u: &[f64], v: &[f64]) {
reim4_vec_mat2cols_2ndcol_product_ref(nrows, dst, u, v);
}
}

View File

@@ -0,0 +1,81 @@
use std::marker::PhantomData;
use poulpy_hal::{
DEFAULTALIGN, alloc_aligned,
api::ScratchFromBytes,
layouts::{Backend, Scratch, ScratchOwned},
oep::{ScratchAvailableImpl, ScratchFromBytesImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeSliceImpl},
};
use crate::FFT64Ref;
unsafe impl<B: Backend> ScratchOwnedAllocImpl<B> for FFT64Ref {
fn scratch_owned_alloc_impl(size: usize) -> ScratchOwned<B> {
let data: Vec<u8> = alloc_aligned(size);
ScratchOwned {
data,
_phantom: PhantomData,
}
}
}
unsafe impl<B: Backend> ScratchOwnedBorrowImpl<B> for FFT64Ref
where
B: ScratchFromBytesImpl<B>,
{
fn scratch_owned_borrow_impl(scratch: &mut ScratchOwned<B>) -> &mut Scratch<B> {
Scratch::from_bytes(&mut scratch.data)
}
}
unsafe impl<B: Backend> ScratchFromBytesImpl<B> for FFT64Ref {
fn scratch_from_bytes_impl(data: &mut [u8]) -> &mut Scratch<B> {
unsafe { &mut *(data as *mut [u8] as *mut Scratch<B>) }
}
}
unsafe impl<B: Backend> ScratchAvailableImpl<B> for FFT64Ref {
fn scratch_available_impl(scratch: &Scratch<B>) -> usize {
let ptr: *const u8 = scratch.data.as_ptr();
let self_len: usize = scratch.data.len();
let aligned_offset: usize = ptr.align_offset(DEFAULTALIGN);
self_len.saturating_sub(aligned_offset)
}
}
unsafe impl<B: Backend> TakeSliceImpl<B> for FFT64Ref
where
B: ScratchFromBytesImpl<B>,
{
fn take_slice_impl<T>(scratch: &mut Scratch<B>, len: usize) -> (&mut [T], &mut Scratch<B>) {
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, len * std::mem::size_of::<T>());
unsafe {
(
&mut *(std::ptr::slice_from_raw_parts_mut(take_slice.as_mut_ptr() as *mut T, len)),
Scratch::from_bytes(rem_slice),
)
}
}
}
fn take_slice_aligned(data: &mut [u8], take_len: usize) -> (&mut [u8], &mut [u8]) {
let ptr: *mut u8 = data.as_mut_ptr();
let self_len: usize = data.len();
let aligned_offset: usize = ptr.align_offset(DEFAULTALIGN);
let aligned_len: usize = self_len.saturating_sub(aligned_offset);
if let Some(rem_len) = aligned_len.checked_sub(take_len) {
unsafe {
let rem_ptr: *mut u8 = ptr.add(aligned_offset).add(take_len);
let rem_slice: &mut [u8] = &mut *std::ptr::slice_from_raw_parts_mut(rem_ptr, rem_len);
let take_slice: &mut [u8] = &mut *std::ptr::slice_from_raw_parts_mut(ptr.add(aligned_offset), take_len);
(take_slice, rem_slice)
}
} else {
panic!("Attempted to take {take_len} from scratch with {aligned_len} aligned bytes left");
}
}

66
poulpy-cpu-ref/src/svp.rs Normal file
View File

@@ -0,0 +1,66 @@
use poulpy_hal::{
layouts::{Backend, Module, ScalarZnxToRef, SvpPPolOwned, SvpPPolToMut, SvpPPolToRef, VecZnxDftToMut, VecZnxDftToRef},
oep::{
SvpApplyDftToDftImpl, SvpApplyDftToDftInplaceImpl, SvpPPolAllocBytesImpl, SvpPPolAllocImpl, SvpPPolFromBytesImpl,
SvpPrepareImpl,
},
reference::fft64::svp::{svp_apply_dft_to_dft, svp_apply_dft_to_dft_inplace, svp_prepare},
};
use crate::{FFT64Ref, module::FFT64ModuleHandle};
unsafe impl SvpPPolFromBytesImpl<Self> for FFT64Ref {
fn svp_ppol_from_bytes_impl(n: usize, cols: usize, bytes: Vec<u8>) -> SvpPPolOwned<Self> {
SvpPPolOwned::from_bytes(n, cols, bytes)
}
}
unsafe impl SvpPPolAllocImpl<Self> for FFT64Ref {
fn svp_ppol_alloc_impl(n: usize, cols: usize) -> SvpPPolOwned<Self> {
SvpPPolOwned::alloc(n, cols)
}
}
unsafe impl SvpPPolAllocBytesImpl<Self> for FFT64Ref {
fn svp_ppol_bytes_of_impl(n: usize, cols: usize) -> usize {
Self::layout_prep_word_count() * n * cols * size_of::<f64>()
}
}
unsafe impl SvpPrepareImpl<Self> for FFT64Ref {
fn svp_prepare_impl<R, A>(module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: SvpPPolToMut<Self>,
A: ScalarZnxToRef,
{
svp_prepare(module.get_fft_table(), res, res_col, a, a_col);
}
}
unsafe impl SvpApplyDftToDftImpl<Self> for FFT64Ref {
fn svp_apply_dft_to_dft_impl<R, A, B>(
_module: &Module<Self>,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
b: &B,
b_col: usize,
) where
R: VecZnxDftToMut<Self>,
A: SvpPPolToRef<Self>,
B: VecZnxDftToRef<Self>,
{
svp_apply_dft_to_dft(res, res_col, a, a_col, b, b_col);
}
}
unsafe impl SvpApplyDftToDftInplaceImpl for FFT64Ref {
fn svp_apply_dft_to_dft_inplace_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxDftToMut<Self>,
A: SvpPPolToRef<Self>,
{
svp_apply_dft_to_dft_inplace(res, res_col, a, a_col);
}
}

View File

@@ -0,0 +1,9 @@
use poulpy_hal::{api::ModuleNew, layouts::Module, test_suite::convolution::test_bivariate_tensoring};
use crate::FFT64Ref;
#[test]
fn test_convolution_fft64_ref() {
let module: Module<FFT64Ref> = Module::<FFT64Ref>::new(8);
test_bivariate_tensoring(&module);
}

View File

@@ -0,0 +1,549 @@
use poulpy_hal::{
api::{
TakeSlice, VecZnxAutomorphismInplaceTmpBytes, VecZnxLshTmpBytes, VecZnxMergeRingsTmpBytes,
VecZnxMulXpMinusOneInplaceTmpBytes, VecZnxNormalizeTmpBytes, VecZnxRotateInplaceTmpBytes, VecZnxRshTmpBytes,
VecZnxSplitRingTmpBytes,
},
layouts::{Module, ScalarZnxToRef, Scratch, VecZnxToMut, VecZnxToRef},
oep::{
TakeSliceImpl, VecZnxAddImpl, VecZnxAddInplaceImpl, VecZnxAddNormalImpl, VecZnxAddScalarImpl, VecZnxAddScalarInplaceImpl,
VecZnxAutomorphismImpl, VecZnxAutomorphismInplaceImpl, VecZnxAutomorphismInplaceTmpBytesImpl, VecZnxCopyImpl,
VecZnxFillNormalImpl, VecZnxFillUniformImpl, VecZnxLshImpl, VecZnxLshInplaceImpl, VecZnxLshTmpBytesImpl,
VecZnxMergeRingsImpl, VecZnxMergeRingsTmpBytesImpl, VecZnxMulXpMinusOneImpl, VecZnxMulXpMinusOneInplaceImpl,
VecZnxMulXpMinusOneInplaceTmpBytesImpl, VecZnxNegateImpl, VecZnxNegateInplaceImpl, VecZnxNormalizeImpl,
VecZnxNormalizeInplaceImpl, VecZnxNormalizeTmpBytesImpl, VecZnxRotateImpl, VecZnxRotateInplaceImpl,
VecZnxRotateInplaceTmpBytesImpl, VecZnxRshImpl, VecZnxRshInplaceImpl, VecZnxRshTmpBytesImpl, VecZnxSplitRingImpl,
VecZnxSplitRingTmpBytesImpl, VecZnxSubImpl, VecZnxSubInplaceImpl, VecZnxSubNegateInplaceImpl, VecZnxSubScalarImpl,
VecZnxSubScalarInplaceImpl, VecZnxSwitchRingImpl, VecZnxZeroImpl,
},
reference::vec_znx::{
vec_znx_add, vec_znx_add_inplace, vec_znx_add_normal_ref, vec_znx_add_scalar, vec_znx_add_scalar_inplace,
vec_znx_automorphism, vec_znx_automorphism_inplace, vec_znx_automorphism_inplace_tmp_bytes, vec_znx_copy,
vec_znx_fill_normal_ref, vec_znx_fill_uniform_ref, vec_znx_lsh, vec_znx_lsh_inplace, vec_znx_lsh_tmp_bytes,
vec_znx_merge_rings, vec_znx_merge_rings_tmp_bytes, vec_znx_mul_xp_minus_one, vec_znx_mul_xp_minus_one_inplace,
vec_znx_mul_xp_minus_one_inplace_tmp_bytes, vec_znx_negate, vec_znx_negate_inplace, vec_znx_normalize,
vec_znx_normalize_inplace, vec_znx_normalize_tmp_bytes, vec_znx_rotate, vec_znx_rotate_inplace,
vec_znx_rotate_inplace_tmp_bytes, vec_znx_rsh, vec_znx_rsh_inplace, vec_znx_rsh_tmp_bytes, vec_znx_split_ring,
vec_znx_split_ring_tmp_bytes, vec_znx_sub, vec_znx_sub_inplace, vec_znx_sub_negate_inplace, vec_znx_sub_scalar,
vec_znx_sub_scalar_inplace, vec_znx_switch_ring, vec_znx_zero,
},
source::Source,
};
use crate::FFT64Ref;
unsafe impl VecZnxZeroImpl<Self> for FFT64Ref {
fn vec_znx_zero_impl<R>(_module: &Module<Self>, res: &mut R, res_col: usize)
where
R: VecZnxToMut,
{
vec_znx_zero::<_, FFT64Ref>(res, res_col);
}
}
unsafe impl VecZnxNormalizeTmpBytesImpl<Self> for FFT64Ref {
fn vec_znx_normalize_tmp_bytes_impl(module: &Module<Self>) -> usize {
vec_znx_normalize_tmp_bytes(module.n())
}
}
unsafe impl VecZnxNormalizeImpl<Self> for FFT64Ref
where
Self: TakeSliceImpl<Self> + VecZnxNormalizeTmpBytesImpl<Self>,
{
fn vec_znx_normalize_impl<R, A>(
module: &Module<Self>,
res_basek: usize,
res: &mut R,
res_col: usize,
a_basek: usize,
a: &A,
a_col: usize,
scratch: &mut Scratch<Self>,
) where
R: VecZnxToMut,
A: VecZnxToRef,
{
let (carry, _) = scratch.take_slice(module.vec_znx_normalize_tmp_bytes() / size_of::<i64>());
vec_znx_normalize::<R, A, Self>(res_basek, res, res_col, a_basek, a, a_col, carry);
}
}
unsafe impl VecZnxNormalizeInplaceImpl<Self> for FFT64Ref
where
Self: TakeSliceImpl<Self> + VecZnxNormalizeTmpBytesImpl<Self>,
{
fn vec_znx_normalize_inplace_impl<R>(
module: &Module<Self>,
base2k: usize,
res: &mut R,
res_col: usize,
scratch: &mut Scratch<Self>,
) where
R: VecZnxToMut,
{
let (carry, _) = scratch.take_slice(module.vec_znx_normalize_tmp_bytes() / size_of::<i64>());
vec_znx_normalize_inplace::<R, Self>(base2k, res, res_col, carry);
}
}
unsafe impl VecZnxAddImpl<Self> for FFT64Ref {
fn vec_znx_add_impl<R, A, B>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
B: VecZnxToRef,
{
vec_znx_add::<R, A, B, Self>(res, res_col, a, a_col, b, b_col);
}
}
unsafe impl VecZnxAddInplaceImpl<Self> for FFT64Ref {
fn vec_znx_add_inplace_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
{
vec_znx_add_inplace::<R, A, Self>(res, res_col, a, a_col);
}
}
unsafe impl VecZnxAddScalarInplaceImpl<Self> for FFT64Ref {
fn vec_znx_add_scalar_inplace_impl<R, A>(
_module: &Module<Self>,
res: &mut R,
res_col: usize,
res_limb: usize,
a: &A,
a_col: usize,
) where
R: VecZnxToMut,
A: ScalarZnxToRef,
{
vec_znx_add_scalar_inplace::<R, A, Self>(res, res_col, res_limb, a, a_col);
}
}
unsafe impl VecZnxAddScalarImpl<Self> for FFT64Ref {
fn vec_znx_add_scalar_impl<R, A, B>(
_module: &Module<Self>,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
b: &B,
b_col: usize,
b_limb: usize,
) where
R: VecZnxToMut,
A: ScalarZnxToRef,
B: VecZnxToRef,
{
vec_znx_add_scalar::<R, A, B, Self>(res, res_col, a, a_col, b, b_col, b_limb);
}
}
unsafe impl VecZnxSubImpl<Self> for FFT64Ref {
fn vec_znx_sub_impl<R, A, B>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
B: VecZnxToRef,
{
vec_znx_sub::<R, A, B, Self>(res, res_col, a, a_col, b, b_col);
}
}
unsafe impl VecZnxSubInplaceImpl<Self> for FFT64Ref {
fn vec_znx_sub_inplace_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
{
vec_znx_sub_inplace::<R, A, Self>(res, res_col, a, a_col);
}
}
unsafe impl VecZnxSubNegateInplaceImpl<Self> for FFT64Ref {
fn vec_znx_sub_negate_inplace_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
{
vec_znx_sub_negate_inplace::<R, A, Self>(res, res_col, a, a_col);
}
}
unsafe impl VecZnxSubScalarImpl<Self> for FFT64Ref {
fn vec_znx_sub_scalar_impl<R, A, B>(
_module: &Module<Self>,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
b: &B,
b_col: usize,
b_limb: usize,
) where
R: VecZnxToMut,
A: ScalarZnxToRef,
B: VecZnxToRef,
{
vec_znx_sub_scalar::<R, A, B, Self>(res, res_col, a, a_col, b, b_col, b_limb);
}
}
unsafe impl VecZnxSubScalarInplaceImpl<Self> for FFT64Ref {
fn vec_znx_sub_scalar_inplace_impl<R, A>(
_module: &Module<Self>,
res: &mut R,
res_col: usize,
res_limb: usize,
a: &A,
a_col: usize,
) where
R: VecZnxToMut,
A: ScalarZnxToRef,
{
vec_znx_sub_scalar_inplace::<R, A, Self>(res, res_col, res_limb, a, a_col);
}
}
unsafe impl VecZnxNegateImpl<Self> for FFT64Ref {
fn vec_znx_negate_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
{
vec_znx_negate::<R, A, Self>(res, res_col, a, a_col);
}
}
unsafe impl VecZnxNegateInplaceImpl<Self> for FFT64Ref {
fn vec_znx_negate_inplace_impl<R>(_module: &Module<Self>, res: &mut R, res_col: usize)
where
R: VecZnxToMut,
{
vec_znx_negate_inplace::<R, Self>(res, res_col);
}
}
unsafe impl VecZnxLshTmpBytesImpl<Self> for FFT64Ref {
fn vec_znx_lsh_tmp_bytes_impl(module: &Module<Self>) -> usize {
vec_znx_lsh_tmp_bytes(module.n())
}
}
unsafe impl VecZnxRshTmpBytesImpl<Self> for FFT64Ref {
fn vec_znx_rsh_tmp_bytes_impl(module: &Module<Self>) -> usize {
vec_znx_rsh_tmp_bytes(module.n())
}
}
unsafe impl VecZnxLshImpl<Self> for FFT64Ref
where
Module<Self>: VecZnxNormalizeTmpBytes,
Scratch<Self>: TakeSlice,
{
fn vec_znx_lsh_impl<R, A>(
module: &Module<Self>,
base2k: usize,
k: usize,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
scratch: &mut Scratch<Self>,
) where
R: VecZnxToMut,
A: VecZnxToRef,
{
let (carry, _) = scratch.take_slice(module.vec_znx_lsh_tmp_bytes() / size_of::<i64>());
vec_znx_lsh::<_, _, Self>(base2k, k, res, res_col, a, a_col, carry);
}
}
unsafe impl VecZnxLshInplaceImpl<Self> for FFT64Ref
where
Module<Self>: VecZnxNormalizeTmpBytes,
Scratch<Self>: TakeSlice,
{
fn vec_znx_lsh_inplace_impl<A>(
module: &Module<Self>,
base2k: usize,
k: usize,
a: &mut A,
a_col: usize,
scratch: &mut Scratch<Self>,
) where
A: VecZnxToMut,
{
let (carry, _) = scratch.take_slice(module.vec_znx_lsh_tmp_bytes() / size_of::<i64>());
vec_znx_lsh_inplace::<_, Self>(base2k, k, a, a_col, carry);
}
}
unsafe impl VecZnxRshImpl<Self> for FFT64Ref
where
Module<Self>: VecZnxNormalizeTmpBytes,
Scratch<Self>: TakeSlice,
{
fn vec_znx_rsh_impl<R, A>(
module: &Module<Self>,
base2k: usize,
k: usize,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
scratch: &mut Scratch<Self>,
) where
R: VecZnxToMut,
A: VecZnxToRef,
{
let (carry, _) = scratch.take_slice(module.vec_znx_rsh_tmp_bytes() / size_of::<i64>());
vec_znx_rsh::<_, _, Self>(base2k, k, res, res_col, a, a_col, carry);
}
}
unsafe impl VecZnxRshInplaceImpl<Self> for FFT64Ref
where
Module<Self>: VecZnxNormalizeTmpBytes,
Scratch<Self>: TakeSlice,
{
fn vec_znx_rsh_inplace_impl<A>(
module: &Module<Self>,
base2k: usize,
k: usize,
a: &mut A,
a_col: usize,
scratch: &mut Scratch<Self>,
) where
A: VecZnxToMut,
{
let (carry, _) = scratch.take_slice(module.vec_znx_rsh_tmp_bytes() / size_of::<i64>());
vec_znx_rsh_inplace::<_, Self>(base2k, k, a, a_col, carry);
}
}
unsafe impl VecZnxRotateImpl<Self> for FFT64Ref {
fn vec_znx_rotate_impl<R, A>(_module: &Module<Self>, p: i64, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
{
vec_znx_rotate::<R, A, Self>(p, res, res_col, a, a_col);
}
}
unsafe impl VecZnxRotateInplaceTmpBytesImpl<Self> for FFT64Ref
where
Scratch<Self>: TakeSlice,
{
fn vec_znx_rotate_inplace_tmp_bytes_impl(module: &Module<Self>) -> usize {
vec_znx_rotate_inplace_tmp_bytes(module.n())
}
}
unsafe impl VecZnxRotateInplaceImpl<Self> for FFT64Ref
where
Scratch<Self>: TakeSlice,
Self: VecZnxRotateInplaceTmpBytesImpl<Self>,
{
fn vec_znx_rotate_inplace_impl<R>(module: &Module<Self>, p: i64, res: &mut R, res_col: usize, scratch: &mut Scratch<Self>)
where
R: VecZnxToMut,
{
let (tmp, _) = scratch.take_slice(module.vec_znx_rotate_inplace_tmp_bytes() / size_of::<i64>());
vec_znx_rotate_inplace::<R, Self>(p, res, res_col, tmp);
}
}
unsafe impl VecZnxAutomorphismImpl<Self> for FFT64Ref {
fn vec_znx_automorphism_impl<R, A>(_module: &Module<Self>, p: i64, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
{
vec_znx_automorphism::<R, A, Self>(p, res, res_col, a, a_col);
}
}
unsafe impl VecZnxAutomorphismInplaceTmpBytesImpl<Self> for FFT64Ref {
fn vec_znx_automorphism_inplace_tmp_bytes_impl(module: &Module<Self>) -> usize {
vec_znx_automorphism_inplace_tmp_bytes(module.n())
}
}
unsafe impl VecZnxAutomorphismInplaceImpl<Self> for FFT64Ref
where
Scratch<Self>: TakeSlice,
Self: VecZnxAutomorphismInplaceTmpBytesImpl<Self>,
{
fn vec_znx_automorphism_inplace_impl<R>(
module: &Module<Self>,
p: i64,
res: &mut R,
res_col: usize,
scratch: &mut Scratch<Self>,
) where
R: VecZnxToMut,
{
let (tmp, _) = scratch.take_slice(module.vec_znx_automorphism_inplace_tmp_bytes() / size_of::<i64>());
vec_znx_automorphism_inplace::<R, Self>(p, res, res_col, tmp);
}
}
unsafe impl VecZnxMulXpMinusOneImpl<Self> for FFT64Ref {
fn vec_znx_mul_xp_minus_one_impl<R, A>(_module: &Module<Self>, p: i64, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
{
vec_znx_mul_xp_minus_one::<R, A, Self>(p, res, res_col, a, a_col);
}
}
unsafe impl VecZnxMulXpMinusOneInplaceTmpBytesImpl<Self> for FFT64Ref
where
Scratch<Self>: TakeSlice,
Self: VecZnxMulXpMinusOneImpl<Self>,
{
fn vec_znx_mul_xp_minus_one_inplace_tmp_bytes_impl(module: &Module<Self>) -> usize {
vec_znx_mul_xp_minus_one_inplace_tmp_bytes(module.n())
}
}
unsafe impl VecZnxMulXpMinusOneInplaceImpl<Self> for FFT64Ref {
fn vec_znx_mul_xp_minus_one_inplace_impl<R>(
module: &Module<Self>,
p: i64,
res: &mut R,
res_col: usize,
scratch: &mut Scratch<Self>,
) where
R: VecZnxToMut,
{
let (tmp, _) = scratch.take_slice(module.vec_znx_mul_xp_minus_one_inplace_tmp_bytes() / size_of::<i64>());
vec_znx_mul_xp_minus_one_inplace::<R, Self>(p, res, res_col, tmp);
}
}
unsafe impl VecZnxSplitRingTmpBytesImpl<Self> for FFT64Ref {
fn vec_znx_split_ring_tmp_bytes_impl(module: &Module<Self>) -> usize {
vec_znx_split_ring_tmp_bytes(module.n())
}
}
unsafe impl VecZnxSplitRingImpl<Self> for FFT64Ref
where
Module<Self>: VecZnxSplitRingTmpBytes,
Scratch<Self>: TakeSlice,
{
fn vec_znx_split_ring_impl<R, A>(
module: &Module<Self>,
res: &mut [R],
res_col: usize,
a: &A,
a_col: usize,
scratch: &mut Scratch<Self>,
) where
R: VecZnxToMut,
A: VecZnxToRef,
{
let (tmp, _) = scratch.take_slice(module.vec_znx_split_ring_tmp_bytes() / size_of::<i64>());
vec_znx_split_ring::<R, A, Self>(res, res_col, a, a_col, tmp);
}
}
unsafe impl VecZnxMergeRingsTmpBytesImpl<Self> for FFT64Ref {
fn vec_znx_merge_rings_tmp_bytes_impl(module: &Module<Self>) -> usize {
vec_znx_merge_rings_tmp_bytes(module.n())
}
}
unsafe impl VecZnxMergeRingsImpl<Self> for FFT64Ref
where
Module<Self>: VecZnxMergeRingsTmpBytes,
{
fn vec_znx_merge_rings_impl<R, A>(
module: &Module<Self>,
res: &mut R,
res_col: usize,
a: &[A],
a_col: usize,
scratch: &mut Scratch<Self>,
) where
R: VecZnxToMut,
A: VecZnxToRef,
{
let (tmp, _) = scratch.take_slice(module.vec_znx_merge_rings_tmp_bytes() / size_of::<i64>());
vec_znx_merge_rings::<R, A, Self>(res, res_col, a, a_col, tmp);
}
}
unsafe impl VecZnxSwitchRingImpl<Self> for FFT64Ref
where
Self: VecZnxCopyImpl<Self>,
{
fn vec_znx_switch_ring_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
{
vec_znx_switch_ring::<R, A, Self>(res, res_col, a, a_col);
}
}
unsafe impl VecZnxCopyImpl<Self> for FFT64Ref {
fn vec_znx_copy_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
{
vec_znx_copy::<R, A, Self>(res, res_col, a, a_col)
}
}
unsafe impl VecZnxFillUniformImpl<Self> for FFT64Ref {
fn vec_znx_fill_uniform_impl<R>(_module: &Module<Self>, base2k: usize, res: &mut R, res_col: usize, source: &mut Source)
where
R: VecZnxToMut,
{
vec_znx_fill_uniform_ref(base2k, res, res_col, source)
}
}
unsafe impl VecZnxFillNormalImpl<Self> for FFT64Ref {
fn vec_znx_fill_normal_impl<R>(
_module: &Module<Self>,
base2k: usize,
res: &mut R,
res_col: usize,
k: usize,
source: &mut Source,
sigma: f64,
bound: f64,
) where
R: VecZnxToMut,
{
vec_znx_fill_normal_ref(base2k, res, res_col, k, sigma, bound, source);
}
}
unsafe impl VecZnxAddNormalImpl<Self> for FFT64Ref {
fn vec_znx_add_normal_impl<R>(
_module: &Module<Self>,
base2k: usize,
res: &mut R,
res_col: usize,
k: usize,
source: &mut Source,
sigma: f64,
bound: f64,
) where
R: VecZnxToMut,
{
vec_znx_add_normal_ref(base2k, res, res_col, k, sigma, bound, source);
}
}

View File

@@ -0,0 +1,333 @@
use crate::FFT64Ref;
use poulpy_hal::{
api::{TakeSlice, VecZnxBigAutomorphismInplaceTmpBytes, VecZnxBigNormalizeTmpBytes},
layouts::{
Backend, Module, Scratch, VecZnx, VecZnxBig, VecZnxBigOwned, VecZnxBigToMut, VecZnxBigToRef, VecZnxToMut, VecZnxToRef,
ZnxInfos, ZnxView, ZnxViewMut,
},
oep::{
TakeSliceImpl, VecZnxBigAddImpl, VecZnxBigAddInplaceImpl, VecZnxBigAddNormalImpl, VecZnxBigAddSmallImpl,
VecZnxBigAddSmallInplaceImpl, VecZnxBigAllocBytesImpl, VecZnxBigAllocImpl, VecZnxBigAutomorphismImpl,
VecZnxBigAutomorphismInplaceImpl, VecZnxBigAutomorphismInplaceTmpBytesImpl, VecZnxBigFromBytesImpl,
VecZnxBigFromSmallImpl, VecZnxBigNegateImpl, VecZnxBigNegateInplaceImpl, VecZnxBigNormalizeImpl,
VecZnxBigNormalizeTmpBytesImpl, VecZnxBigSubImpl, VecZnxBigSubInplaceImpl, VecZnxBigSubNegateInplaceImpl,
VecZnxBigSubSmallAImpl, VecZnxBigSubSmallBImpl, VecZnxBigSubSmallInplaceImpl, VecZnxBigSubSmallNegateInplaceImpl,
},
reference::{
fft64::vec_znx_big::{
vec_znx_big_add, vec_znx_big_add_inplace, vec_znx_big_add_normal_ref, vec_znx_big_add_small,
vec_znx_big_add_small_inplace, vec_znx_big_automorphism, vec_znx_big_automorphism_inplace,
vec_znx_big_automorphism_inplace_tmp_bytes, vec_znx_big_negate, vec_znx_big_negate_inplace, vec_znx_big_normalize,
vec_znx_big_normalize_tmp_bytes, vec_znx_big_sub, vec_znx_big_sub_inplace, vec_znx_big_sub_negate_inplace,
vec_znx_big_sub_small_a, vec_znx_big_sub_small_a_inplace, vec_znx_big_sub_small_b, vec_znx_big_sub_small_b_inplace,
},
znx::{znx_copy_ref, znx_zero_ref},
},
source::Source,
};
unsafe impl VecZnxBigAllocBytesImpl<Self> for FFT64Ref {
fn vec_znx_big_bytes_of_impl(n: usize, cols: usize, size: usize) -> usize {
Self::layout_big_word_count() * n * cols * size * size_of::<f64>()
}
}
unsafe impl VecZnxBigAllocImpl<Self> for FFT64Ref {
fn vec_znx_big_alloc_impl(n: usize, cols: usize, size: usize) -> VecZnxBigOwned<Self> {
VecZnxBig::alloc(n, cols, size)
}
}
unsafe impl VecZnxBigFromBytesImpl<Self> for FFT64Ref {
fn vec_znx_big_from_bytes_impl(n: usize, cols: usize, size: usize, bytes: Vec<u8>) -> VecZnxBigOwned<Self> {
VecZnxBig::from_bytes(n, cols, size, bytes)
}
}
unsafe impl VecZnxBigFromSmallImpl<Self> for FFT64Ref {
fn vec_znx_big_from_small_impl<R, A>(res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxBigToMut<Self>,
A: VecZnxToRef,
{
let mut res: VecZnxBig<&mut [u8], FFT64Ref> = res.to_mut();
let a: VecZnx<&[u8]> = a.to_ref();
#[cfg(debug_assertions)]
{
assert_eq!(res.n(), a.n());
}
let res_size: usize = res.size();
let a_size: usize = a.size();
let min_size: usize = res_size.min(a_size);
for j in 0..min_size {
znx_copy_ref(res.at_mut(res_col, j), a.at(a_col, j));
}
for j in min_size..res_size {
znx_zero_ref(res.at_mut(res_col, j));
}
}
}
unsafe impl VecZnxBigAddNormalImpl<Self> for FFT64Ref {
fn add_normal_impl<R: VecZnxBigToMut<Self>>(
_module: &Module<Self>,
base2k: usize,
res: &mut R,
res_col: usize,
k: usize,
source: &mut Source,
sigma: f64,
bound: f64,
) {
vec_znx_big_add_normal_ref(base2k, res, res_col, k, sigma, bound, source);
}
}
unsafe impl VecZnxBigAddImpl<Self> for FFT64Ref {
/// Adds `a` to `b` and stores the result on `c`.
fn vec_znx_big_add_impl<R, A, B>(
_module: &Module<Self>,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
b: &B,
b_col: usize,
) where
R: VecZnxBigToMut<Self>,
A: VecZnxBigToRef<Self>,
B: VecZnxBigToRef<Self>,
{
vec_znx_big_add(res, res_col, a, a_col, b, b_col);
}
}
unsafe impl VecZnxBigAddInplaceImpl<Self> for FFT64Ref {
/// Adds `a` to `b` and stores the result on `b`.
fn vec_znx_big_add_inplace_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxBigToMut<Self>,
A: VecZnxBigToRef<Self>,
{
vec_znx_big_add_inplace(res, res_col, a, a_col);
}
}
unsafe impl VecZnxBigAddSmallImpl<Self> for FFT64Ref {
/// Adds `a` to `b` and stores the result on `c`.
fn vec_znx_big_add_small_impl<R, A, B>(
_module: &Module<Self>,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
b: &B,
b_col: usize,
) where
R: VecZnxBigToMut<Self>,
A: VecZnxBigToRef<Self>,
B: VecZnxToRef,
{
vec_znx_big_add_small(res, res_col, a, a_col, b, b_col);
}
}
unsafe impl VecZnxBigAddSmallInplaceImpl<Self> for FFT64Ref {
/// Adds `a` to `b` and stores the result on `b`.
fn vec_znx_big_add_small_inplace_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxBigToMut<Self>,
A: VecZnxToRef,
{
vec_znx_big_add_small_inplace(res, res_col, a, a_col);
}
}
unsafe impl VecZnxBigSubImpl<Self> for FFT64Ref {
/// Subtracts `a` to `b` and stores the result on `c`.
fn vec_znx_big_sub_impl<R, A, B>(
_module: &Module<Self>,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
b: &B,
b_col: usize,
) where
R: VecZnxBigToMut<Self>,
A: VecZnxBigToRef<Self>,
B: VecZnxBigToRef<Self>,
{
vec_znx_big_sub(res, res_col, a, a_col, b, b_col);
}
}
unsafe impl VecZnxBigSubInplaceImpl<Self> for FFT64Ref {
/// Subtracts `a` from `b` and stores the result on `b`.
fn vec_znx_big_sub_inplace_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxBigToMut<Self>,
A: VecZnxBigToRef<Self>,
{
vec_znx_big_sub_inplace(res, res_col, a, a_col);
}
}
unsafe impl VecZnxBigSubNegateInplaceImpl<Self> for FFT64Ref {
/// Subtracts `b` from `a` and stores the result on `b`.
fn vec_znx_big_sub_negate_inplace_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxBigToMut<Self>,
A: VecZnxBigToRef<Self>,
{
vec_znx_big_sub_negate_inplace(res, res_col, a, a_col);
}
}
unsafe impl VecZnxBigSubSmallAImpl<Self> for FFT64Ref {
/// Subtracts `b` from `a` and stores the result on `c`.
fn vec_znx_big_sub_small_a_impl<R, A, B>(
_module: &Module<Self>,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
b: &B,
b_col: usize,
) where
R: VecZnxBigToMut<Self>,
A: VecZnxToRef,
B: VecZnxBigToRef<Self>,
{
vec_znx_big_sub_small_a(res, res_col, a, a_col, b, b_col);
}
}
unsafe impl VecZnxBigSubSmallInplaceImpl<Self> for FFT64Ref {
/// Subtracts `a` from `res` and stores the result on `res`.
fn vec_znx_big_sub_small_inplace_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxBigToMut<Self>,
A: VecZnxToRef,
{
vec_znx_big_sub_small_a_inplace(res, res_col, a, a_col);
}
}
unsafe impl VecZnxBigSubSmallBImpl<Self> for FFT64Ref {
/// Subtracts `b` from `a` and stores the result on `c`.
fn vec_znx_big_sub_small_b_impl<R, A, B>(
_module: &Module<Self>,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
b: &B,
b_col: usize,
) where
R: VecZnxBigToMut<Self>,
A: VecZnxBigToRef<Self>,
B: VecZnxToRef,
{
vec_znx_big_sub_small_b(res, res_col, a, a_col, b, b_col);
}
}
unsafe impl VecZnxBigSubSmallNegateInplaceImpl<Self> for FFT64Ref {
/// Subtracts `res` from `a` and stores the result on `res`.
fn vec_znx_big_sub_small_negate_inplace_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxBigToMut<Self>,
A: VecZnxToRef,
{
vec_znx_big_sub_small_b_inplace(res, res_col, a, a_col);
}
}
unsafe impl VecZnxBigNegateImpl<Self> for FFT64Ref {
fn vec_znx_big_negate_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxBigToMut<Self>,
A: VecZnxBigToRef<Self>,
{
vec_znx_big_negate(res, res_col, a, a_col);
}
}
unsafe impl VecZnxBigNegateInplaceImpl<Self> for FFT64Ref {
fn vec_znx_big_negate_inplace_impl<R>(_module: &Module<Self>, res: &mut R, res_col: usize)
where
R: VecZnxBigToMut<Self>,
{
vec_znx_big_negate_inplace(res, res_col);
}
}
unsafe impl VecZnxBigNormalizeTmpBytesImpl<Self> for FFT64Ref {
fn vec_znx_big_normalize_tmp_bytes_impl(module: &Module<Self>) -> usize {
vec_znx_big_normalize_tmp_bytes(module.n())
}
}
unsafe impl VecZnxBigNormalizeImpl<Self> for FFT64Ref
where
Self: TakeSliceImpl<Self>,
{
fn vec_znx_big_normalize_impl<R, A>(
module: &Module<Self>,
res_basek: usize,
res: &mut R,
res_col: usize,
a_basek: usize,
a: &A,
a_col: usize,
scratch: &mut Scratch<Self>,
) where
R: VecZnxToMut,
A: VecZnxBigToRef<Self>,
{
let (carry, _) = scratch.take_slice(module.vec_znx_big_normalize_tmp_bytes() / size_of::<i64>());
vec_znx_big_normalize(res_basek, res, res_col, a_basek, a, a_col, carry);
}
}
unsafe impl VecZnxBigAutomorphismImpl<Self> for FFT64Ref {
/// Applies the automorphism X^i -> X^ik on `a` and stores the result on `b`.
fn vec_znx_big_automorphism_impl<R, A>(_module: &Module<Self>, p: i64, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxBigToMut<Self>,
A: VecZnxBigToRef<Self>,
{
vec_znx_big_automorphism(p, res, res_col, a, a_col);
}
}
unsafe impl VecZnxBigAutomorphismInplaceTmpBytesImpl<Self> for FFT64Ref {
fn vec_znx_big_automorphism_inplace_tmp_bytes_impl(module: &Module<Self>) -> usize {
vec_znx_big_automorphism_inplace_tmp_bytes(module.n())
}
}
unsafe impl VecZnxBigAutomorphismInplaceImpl<Self> for FFT64Ref
where
Module<Self>: VecZnxBigAutomorphismInplaceTmpBytes,
{
/// Applies the automorphism X^i -> X^ik on `a` and stores the result on `a`.
fn vec_znx_big_automorphism_inplace_impl<R>(
module: &Module<Self>,
p: i64,
res: &mut R,
res_col: usize,
scratch: &mut Scratch<Self>,
) where
R: VecZnxBigToMut<Self>,
{
let (tmp, _) = scratch.take_slice(module.vec_znx_big_automorphism_inplace_tmp_bytes() / size_of::<i64>());
vec_znx_big_automorphism_inplace(p, res, res_col, tmp);
}
}

View File

@@ -0,0 +1,203 @@
use poulpy_hal::{
layouts::{
Backend, Data, Module, Scratch, VecZnxBig, VecZnxBigToMut, VecZnxDft, VecZnxDftOwned, VecZnxDftToMut, VecZnxDftToRef,
VecZnxToRef,
},
oep::{
VecZnxDftAddImpl, VecZnxDftAddInplaceImpl, VecZnxDftAddScaledInplaceImpl, VecZnxDftAllocBytesImpl, VecZnxDftAllocImpl,
VecZnxDftApplyImpl, VecZnxDftCopyImpl, VecZnxDftFromBytesImpl, VecZnxDftSubImpl, VecZnxDftSubInplaceImpl,
VecZnxDftSubNegateInplaceImpl, VecZnxDftZeroImpl, VecZnxIdftApplyConsumeImpl, VecZnxIdftApplyImpl,
VecZnxIdftApplyTmpAImpl, VecZnxIdftApplyTmpBytesImpl,
},
reference::fft64::vec_znx_dft::{
vec_znx_dft_add, vec_znx_dft_add_inplace, vec_znx_dft_add_scaled_inplace, vec_znx_dft_apply, vec_znx_dft_copy,
vec_znx_dft_sub, vec_znx_dft_sub_inplace, vec_znx_dft_sub_negate_inplace, vec_znx_dft_zero, vec_znx_idft_apply,
vec_znx_idft_apply_consume, vec_znx_idft_apply_tmpa,
},
};
use crate::{FFT64Ref, module::FFT64ModuleHandle};
unsafe impl VecZnxDftFromBytesImpl<Self> for FFT64Ref {
fn vec_znx_dft_from_bytes_impl(n: usize, cols: usize, size: usize, bytes: Vec<u8>) -> VecZnxDftOwned<Self> {
VecZnxDft::<Vec<u8>, Self>::from_bytes(n, cols, size, bytes)
}
}
unsafe impl VecZnxDftAllocBytesImpl<Self> for FFT64Ref {
fn vec_znx_dft_bytes_of_impl(n: usize, cols: usize, size: usize) -> usize {
Self::layout_prep_word_count() * n * cols * size * size_of::<<FFT64Ref as Backend>::ScalarPrep>()
}
}
unsafe impl VecZnxDftAllocImpl<Self> for FFT64Ref {
fn vec_znx_dft_alloc_impl(n: usize, cols: usize, size: usize) -> VecZnxDftOwned<Self> {
VecZnxDftOwned::alloc(n, cols, size)
}
}
unsafe impl VecZnxIdftApplyTmpBytesImpl<Self> for FFT64Ref {
fn vec_znx_idft_apply_tmp_bytes_impl(_module: &Module<Self>) -> usize {
0
}
}
unsafe impl VecZnxIdftApplyImpl<Self> for FFT64Ref {
fn vec_znx_idft_apply_impl<R, A>(
module: &Module<Self>,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
_scratch: &mut Scratch<Self>,
) where
R: VecZnxBigToMut<Self>,
A: VecZnxDftToRef<Self>,
{
vec_znx_idft_apply(module.get_ifft_table(), res, res_col, a, a_col);
}
}
unsafe impl VecZnxIdftApplyTmpAImpl<Self> for FFT64Ref {
fn vec_znx_idft_apply_tmpa_impl<R, A>(module: &Module<Self>, res: &mut R, res_col: usize, a: &mut A, a_col: usize)
where
R: VecZnxBigToMut<Self>,
A: VecZnxDftToMut<Self>,
{
vec_znx_idft_apply_tmpa(module.get_ifft_table(), res, res_col, a, a_col);
}
}
unsafe impl VecZnxIdftApplyConsumeImpl<Self> for FFT64Ref {
fn vec_znx_idft_apply_consume_impl<D: Data>(module: &Module<Self>, res: VecZnxDft<D, FFT64Ref>) -> VecZnxBig<D, FFT64Ref>
where
VecZnxDft<D, FFT64Ref>: VecZnxDftToMut<Self>,
{
vec_znx_idft_apply_consume(module.get_ifft_table(), res)
}
}
unsafe impl VecZnxDftApplyImpl<Self> for FFT64Ref {
fn vec_znx_dft_apply_impl<R, A>(
module: &Module<Self>,
step: usize,
offset: usize,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
) where
R: VecZnxDftToMut<Self>,
A: VecZnxToRef,
{
vec_znx_dft_apply(module.get_fft_table(), step, offset, res, res_col, a, a_col);
}
}
unsafe impl VecZnxDftAddImpl<Self> for FFT64Ref {
fn vec_znx_dft_add_impl<R, A, B>(
_module: &Module<Self>,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
b: &B,
b_col: usize,
) where
R: VecZnxDftToMut<Self>,
A: VecZnxDftToRef<Self>,
B: VecZnxDftToRef<Self>,
{
vec_znx_dft_add(res, res_col, a, a_col, b, b_col);
}
}
unsafe impl VecZnxDftAddScaledInplaceImpl<Self> for FFT64Ref {
fn vec_znx_dft_add_scaled_inplace_impl<R, A>(
_module: &Module<Self>,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
a_scale: i64,
) where
R: VecZnxDftToMut<Self>,
A: VecZnxDftToRef<Self>,
{
vec_znx_dft_add_scaled_inplace(res, res_col, a, a_col, a_scale);
}
}
unsafe impl VecZnxDftAddInplaceImpl<Self> for FFT64Ref {
fn vec_znx_dft_add_inplace_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxDftToMut<Self>,
A: VecZnxDftToRef<Self>,
{
vec_znx_dft_add_inplace(res, res_col, a, a_col);
}
}
unsafe impl VecZnxDftSubImpl<Self> for FFT64Ref {
fn vec_znx_dft_sub_impl<R, A, B>(
_module: &Module<Self>,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
b: &B,
b_col: usize,
) where
R: VecZnxDftToMut<Self>,
A: VecZnxDftToRef<Self>,
B: VecZnxDftToRef<Self>,
{
vec_znx_dft_sub(res, res_col, a, a_col, b, b_col);
}
}
unsafe impl VecZnxDftSubInplaceImpl<Self> for FFT64Ref {
fn vec_znx_dft_sub_inplace_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxDftToMut<Self>,
A: VecZnxDftToRef<Self>,
{
vec_znx_dft_sub_inplace(res, res_col, a, a_col);
}
}
unsafe impl VecZnxDftSubNegateInplaceImpl<Self> for FFT64Ref {
fn vec_znx_dft_sub_negate_inplace_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxDftToMut<Self>,
A: VecZnxDftToRef<Self>,
{
vec_znx_dft_sub_negate_inplace(res, res_col, a, a_col);
}
}
unsafe impl VecZnxDftCopyImpl<Self> for FFT64Ref {
fn vec_znx_dft_copy_impl<R, A>(
_module: &Module<Self>,
step: usize,
offset: usize,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
) where
R: VecZnxDftToMut<Self>,
A: VecZnxDftToRef<Self>,
{
vec_znx_dft_copy(step, offset, res, res_col, a, a_col);
}
}
unsafe impl VecZnxDftZeroImpl<Self> for FFT64Ref {
fn vec_znx_dft_zero_impl<R>(_module: &Module<Self>, res: &mut R, res_col: usize)
where
R: VecZnxDftToMut<Self>,
{
vec_znx_dft_zero(res, res_col);
}
}

153
poulpy-cpu-ref/src/vmp.rs Normal file
View File

@@ -0,0 +1,153 @@
use poulpy_hal::{
api::{TakeSlice, VmpPrepareTmpBytes},
layouts::{
Backend, MatZnx, MatZnxToRef, Module, Scratch, VecZnxDft, VecZnxDftToMut, VecZnxDftToRef, VmpPMat, VmpPMatOwned,
VmpPMatToMut, VmpPMatToRef, ZnxInfos,
},
oep::{
VmpApplyDftToDftAddImpl, VmpApplyDftToDftAddTmpBytesImpl, VmpApplyDftToDftImpl, VmpApplyDftToDftTmpBytesImpl,
VmpPMatAllocBytesImpl, VmpPMatAllocImpl, VmpPrepareImpl, VmpPrepareTmpBytesImpl, VmpZeroImpl,
},
reference::fft64::vmp::{
vmp_apply_dft_to_dft, vmp_apply_dft_to_dft_add, vmp_apply_dft_to_dft_tmp_bytes, vmp_prepare, vmp_prepare_tmp_bytes,
vmp_zero,
},
};
use crate::{FFT64Ref, module::FFT64ModuleHandle};
unsafe impl VmpPMatAllocBytesImpl<Self> for FFT64Ref {
fn vmp_pmat_bytes_of_impl(n: usize, rows: usize, cols_in: usize, cols_out: usize, size: usize) -> usize {
Self::layout_prep_word_count() * n * rows * cols_in * cols_out * size * size_of::<f64>()
}
}
unsafe impl VmpPMatAllocImpl<Self> for FFT64Ref {
fn vmp_pmat_alloc_impl(n: usize, rows: usize, cols_in: usize, cols_out: usize, size: usize) -> VmpPMatOwned<Self> {
VmpPMatOwned::alloc(n, rows, cols_in, cols_out, size)
}
}
unsafe impl VmpApplyDftToDftImpl<Self> for FFT64Ref
where
Scratch<Self>: TakeSlice,
FFT64Ref: VmpApplyDftToDftTmpBytesImpl<Self>,
{
fn vmp_apply_dft_to_dft_impl<R, A, C>(module: &Module<Self>, res: &mut R, a: &A, pmat: &C, scratch: &mut Scratch<Self>)
where
R: VecZnxDftToMut<Self>,
A: VecZnxDftToRef<Self>,
C: VmpPMatToRef<Self>,
{
let mut res: VecZnxDft<&mut [u8], Self> = res.to_mut();
let a: VecZnxDft<&[u8], Self> = a.to_ref();
let pmat: VmpPMat<&[u8], Self> = pmat.to_ref();
let (tmp, _) = scratch.take_slice(
Self::vmp_apply_dft_to_dft_tmp_bytes_impl(
module,
res.size(),
a.size(),
pmat.rows(),
pmat.cols_in(),
pmat.cols_out(),
pmat.size(),
) / size_of::<f64>(),
);
vmp_apply_dft_to_dft(&mut res, &a, &pmat, tmp);
}
}
unsafe impl VmpApplyDftToDftAddImpl<Self> for FFT64Ref
where
Scratch<Self>: TakeSlice,
FFT64Ref: VmpApplyDftToDftTmpBytesImpl<Self>,
{
fn vmp_apply_dft_to_dft_add_impl<R, A, C>(
module: &Module<Self>,
res: &mut R,
a: &A,
pmat: &C,
limb_offset: usize,
scratch: &mut Scratch<Self>,
) where
R: VecZnxDftToMut<Self>,
A: VecZnxDftToRef<Self>,
C: VmpPMatToRef<Self>,
{
let mut res: VecZnxDft<&mut [u8], Self> = res.to_mut();
let a: VecZnxDft<&[u8], Self> = a.to_ref();
let pmat: VmpPMat<&[u8], Self> = pmat.to_ref();
let (tmp, _) = scratch.take_slice(
Self::vmp_apply_dft_to_dft_tmp_bytes_impl(
module,
res.size(),
a.size(),
pmat.rows(),
pmat.cols_in(),
pmat.cols_out(),
pmat.size(),
) / size_of::<f64>(),
);
vmp_apply_dft_to_dft_add(&mut res, &a, &pmat, limb_offset * pmat.cols_out(), tmp);
}
}
unsafe impl VmpPrepareTmpBytesImpl<Self> for FFT64Ref {
fn vmp_prepare_tmp_bytes_impl(module: &Module<Self>, _rows: usize, _cols_in: usize, _cols_out: usize, _size: usize) -> usize {
vmp_prepare_tmp_bytes(module.n())
}
}
unsafe impl VmpPrepareImpl<Self> for FFT64Ref {
fn vmp_prepare_impl<R, A>(module: &Module<Self>, res: &mut R, a: &A, scratch: &mut Scratch<Self>)
where
R: VmpPMatToMut<Self>,
A: MatZnxToRef,
{
{}
let mut res: VmpPMat<&mut [u8], Self> = res.to_mut();
let a: MatZnx<&[u8]> = a.to_ref();
let (tmp, _) =
scratch.take_slice(module.vmp_prepare_tmp_bytes(a.rows(), a.cols_in(), a.cols_out(), a.size()) / size_of::<f64>());
vmp_prepare(module.get_fft_table(), &mut res, &a, tmp);
}
}
unsafe impl VmpApplyDftToDftTmpBytesImpl<Self> for FFT64Ref {
fn vmp_apply_dft_to_dft_tmp_bytes_impl(
_module: &Module<Self>,
_res_size: usize,
a_size: usize,
b_rows: usize,
b_cols_in: usize,
_b_cols_out: usize,
_b_size: usize,
) -> usize {
vmp_apply_dft_to_dft_tmp_bytes(a_size, b_rows, b_cols_in)
}
}
unsafe impl VmpApplyDftToDftAddTmpBytesImpl<Self> for FFT64Ref {
fn vmp_apply_dft_to_dft_add_tmp_bytes_impl(
_module: &Module<Self>,
_res_size: usize,
a_size: usize,
b_rows: usize,
b_cols_in: usize,
_b_cols_out: usize,
_b_size: usize,
) -> usize {
vmp_apply_dft_to_dft_tmp_bytes(a_size, b_rows, b_cols_in)
}
}
unsafe impl VmpZeroImpl<Self> for FFT64Ref {
fn vmp_zero_impl<R>(_module: &Module<Self>, res: &mut R)
where
R: VmpPMatToMut<Self>,
{
vmp_zero(res);
}
}

189
poulpy-cpu-ref/src/znx.rs Normal file
View File

@@ -0,0 +1,189 @@
use poulpy_hal::reference::znx::{
ZnxAdd, ZnxAddInplace, ZnxAutomorphism, ZnxCopy, ZnxExtractDigitAddMul, ZnxMulAddPowerOfTwo, ZnxMulPowerOfTwo,
ZnxMulPowerOfTwoInplace, ZnxNegate, ZnxNegateInplace, ZnxNormalizeDigit, ZnxNormalizeFinalStep, ZnxNormalizeFinalStepInplace,
ZnxNormalizeFirstStep, ZnxNormalizeFirstStepCarryOnly, ZnxNormalizeFirstStepInplace, ZnxNormalizeMiddleStep,
ZnxNormalizeMiddleStepCarryOnly, ZnxNormalizeMiddleStepInplace, ZnxRotate, ZnxSub, ZnxSubInplace, ZnxSubNegateInplace,
ZnxSwitchRing, ZnxZero, znx_add_inplace_ref, znx_add_ref, znx_automorphism_ref, znx_copy_ref, znx_extract_digit_addmul_ref,
znx_mul_add_power_of_two_ref, znx_mul_power_of_two_inplace_ref, znx_mul_power_of_two_ref, znx_negate_inplace_ref,
znx_negate_ref, znx_normalize_digit_ref, znx_normalize_final_step_inplace_ref, znx_normalize_final_step_ref,
znx_normalize_first_step_carry_only_ref, znx_normalize_first_step_inplace_ref, znx_normalize_first_step_ref,
znx_normalize_middle_step_carry_only_ref, znx_normalize_middle_step_inplace_ref, znx_normalize_middle_step_ref, znx_rotate,
znx_sub_inplace_ref, znx_sub_negate_inplace_ref, znx_sub_ref, znx_switch_ring_ref, znx_zero_ref,
};
use crate::FFT64Ref;
impl ZnxAdd for FFT64Ref {
#[inline(always)]
fn znx_add(res: &mut [i64], a: &[i64], b: &[i64]) {
znx_add_ref(res, a, b);
}
}
impl ZnxAddInplace for FFT64Ref {
#[inline(always)]
fn znx_add_inplace(res: &mut [i64], a: &[i64]) {
znx_add_inplace_ref(res, a);
}
}
impl ZnxSub for FFT64Ref {
#[inline(always)]
fn znx_sub(res: &mut [i64], a: &[i64], b: &[i64]) {
znx_sub_ref(res, a, b);
}
}
impl ZnxSubInplace for FFT64Ref {
#[inline(always)]
fn znx_sub_inplace(res: &mut [i64], a: &[i64]) {
znx_sub_inplace_ref(res, a);
}
}
impl ZnxSubNegateInplace for FFT64Ref {
#[inline(always)]
fn znx_sub_negate_inplace(res: &mut [i64], a: &[i64]) {
znx_sub_negate_inplace_ref(res, a);
}
}
impl ZnxMulAddPowerOfTwo for FFT64Ref {
#[inline(always)]
fn znx_muladd_power_of_two(k: i64, res: &mut [i64], a: &[i64]) {
znx_mul_add_power_of_two_ref(k, res, a);
}
}
impl ZnxMulPowerOfTwo for FFT64Ref {
#[inline(always)]
fn znx_mul_power_of_two(k: i64, res: &mut [i64], a: &[i64]) {
znx_mul_power_of_two_ref(k, res, a);
}
}
impl ZnxMulPowerOfTwoInplace for FFT64Ref {
#[inline(always)]
fn znx_mul_power_of_two_inplace(k: i64, res: &mut [i64]) {
znx_mul_power_of_two_inplace_ref(k, res);
}
}
impl ZnxAutomorphism for FFT64Ref {
#[inline(always)]
fn znx_automorphism(p: i64, res: &mut [i64], a: &[i64]) {
znx_automorphism_ref(p, res, a);
}
}
impl ZnxCopy for FFT64Ref {
#[inline(always)]
fn znx_copy(res: &mut [i64], a: &[i64]) {
znx_copy_ref(res, a);
}
}
impl ZnxNegate for FFT64Ref {
#[inline(always)]
fn znx_negate(res: &mut [i64], src: &[i64]) {
znx_negate_ref(res, src);
}
}
impl ZnxNegateInplace for FFT64Ref {
#[inline(always)]
fn znx_negate_inplace(res: &mut [i64]) {
znx_negate_inplace_ref(res);
}
}
impl ZnxRotate for FFT64Ref {
#[inline(always)]
fn znx_rotate(p: i64, res: &mut [i64], src: &[i64]) {
znx_rotate::<Self>(p, res, src);
}
}
impl ZnxZero for FFT64Ref {
#[inline(always)]
fn znx_zero(res: &mut [i64]) {
znx_zero_ref(res);
}
}
impl ZnxSwitchRing for FFT64Ref {
#[inline(always)]
fn znx_switch_ring(res: &mut [i64], a: &[i64]) {
znx_switch_ring_ref(res, a);
}
}
impl ZnxNormalizeFinalStep for FFT64Ref {
#[inline(always)]
fn znx_normalize_final_step(base2k: usize, lsh: usize, x: &mut [i64], a: &[i64], carry: &mut [i64]) {
znx_normalize_final_step_ref(base2k, lsh, x, a, carry);
}
}
impl ZnxNormalizeFinalStepInplace for FFT64Ref {
#[inline(always)]
fn znx_normalize_final_step_inplace(base2k: usize, lsh: usize, x: &mut [i64], carry: &mut [i64]) {
znx_normalize_final_step_inplace_ref(base2k, lsh, x, carry);
}
}
impl ZnxNormalizeFirstStep for FFT64Ref {
#[inline(always)]
fn znx_normalize_first_step(base2k: usize, lsh: usize, x: &mut [i64], a: &[i64], carry: &mut [i64]) {
znx_normalize_first_step_ref(base2k, lsh, x, a, carry);
}
}
impl ZnxNormalizeFirstStepCarryOnly for FFT64Ref {
#[inline(always)]
fn znx_normalize_first_step_carry_only(base2k: usize, lsh: usize, x: &[i64], carry: &mut [i64]) {
znx_normalize_first_step_carry_only_ref(base2k, lsh, x, carry);
}
}
impl ZnxNormalizeFirstStepInplace for FFT64Ref {
#[inline(always)]
fn znx_normalize_first_step_inplace(base2k: usize, lsh: usize, x: &mut [i64], carry: &mut [i64]) {
znx_normalize_first_step_inplace_ref(base2k, lsh, x, carry);
}
}
impl ZnxNormalizeMiddleStep for FFT64Ref {
#[inline(always)]
fn znx_normalize_middle_step(base2k: usize, lsh: usize, x: &mut [i64], a: &[i64], carry: &mut [i64]) {
znx_normalize_middle_step_ref(base2k, lsh, x, a, carry);
}
}
impl ZnxNormalizeMiddleStepCarryOnly for FFT64Ref {
#[inline(always)]
fn znx_normalize_middle_step_carry_only(base2k: usize, lsh: usize, x: &[i64], carry: &mut [i64]) {
znx_normalize_middle_step_carry_only_ref(base2k, lsh, x, carry);
}
}
impl ZnxNormalizeMiddleStepInplace for FFT64Ref {
#[inline(always)]
fn znx_normalize_middle_step_inplace(base2k: usize, lsh: usize, x: &mut [i64], carry: &mut [i64]) {
znx_normalize_middle_step_inplace_ref(base2k, lsh, x, carry);
}
}
impl ZnxExtractDigitAddMul for FFT64Ref {
#[inline(always)]
fn znx_extract_digit_addmul(base2k: usize, lsh: usize, res: &mut [i64], src: &mut [i64]) {
znx_extract_digit_addmul_ref(base2k, lsh, res, src);
}
}
impl ZnxNormalizeDigit for FFT64Ref {
#[inline(always)]
fn znx_normalize_digit(base2k: usize, res: &mut [i64], src: &mut [i64]) {
znx_normalize_digit_ref(base2k, res, src);
}
}