mirror of
https://github.com/arnaucube/poulpy.git
synced 2026-02-10 05:06:44 +01:00
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:
committed by
GitHub
parent
84598e42fe
commit
9e007c988f
31
poulpy-cpu-ref/Cargo.toml
Normal file
31
poulpy-cpu-ref/Cargo.toml
Normal file
@@ -0,0 +1,31 @@
|
||||
[package]
|
||||
name = "poulpy-cpu-ref"
|
||||
version = "0.3.2"
|
||||
edition = "2024"
|
||||
license = "Apache-2.0"
|
||||
readme = "README.md"
|
||||
description = "The providing concrete implementations of poulpy-hal through its open extension points and reference cpu code"
|
||||
repository = "https://github.com/phantomzone-org/poulpy"
|
||||
homepage = "https://github.com/phantomzone-org/poulpy"
|
||||
documentation = "https://docs.rs/poulpy"
|
||||
|
||||
[dependencies]
|
||||
poulpy-hal = {workspace = true}
|
||||
rug = {workspace = true}
|
||||
criterion = {workspace = true}
|
||||
itertools = {workspace = true}
|
||||
rand = {workspace = true}
|
||||
rand_distr = {workspace = true}
|
||||
rand_core = {workspace = true}
|
||||
byteorder = {workspace = true}
|
||||
once_cell = {workspace = true}
|
||||
rand_chacha = {workspace = true}
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
|
||||
[[bench]]
|
||||
name = "vmp"
|
||||
harness = false
|
||||
38
poulpy-cpu-ref/README.md
Normal file
38
poulpy-cpu-ref/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# 🐙 Poulpy-Backend
|
||||
|
||||
**Poulpy-Backend** is a Rust crate that provides concrete implementations of **`poulpy-hal`**. This crate is used to instantiate projects implemented with **`poulpy-hal`**, **`poulpy-core`** and/or **`poulpy-schemes`**.
|
||||
|
||||
## Backends
|
||||
|
||||
### cpu-spqlios
|
||||
|
||||
This module provides a CPU AVX2 accelerated backend through C bindings over [**spqlios-arithmetic**](https://github.com/tfhe/spqlios-arithmetic).
|
||||
|
||||
- Currently supported: `FFT64` backend
|
||||
- Planned: `NTT120` backend
|
||||
|
||||
### Build Notes
|
||||
|
||||
This backend is built and compiled automatically and has been tested on wsl/ubuntu.
|
||||
|
||||
- `cmake` is invoked automatically by the build script (`build.rs`) when compiling the crate.
|
||||
- No manual setup is required beyond having a standard Rust toolchain.
|
||||
- Build options can be changed in `/build/cpu_spqlios.rs`
|
||||
- Automatic build of cpu-spqlios/spqlios-arithmetic can be disabled in `build.rs`.
|
||||
|
||||
Spqlios-arithmetic is windows/mac compatible but building for those platforms is slightly different (see [spqlios-arithmetic/wiki/build](https://github.com/tfhe/spqlios-arithmetic/wiki/build)) and has not been tested in Poulpy.
|
||||
|
||||
### Example
|
||||
|
||||
```rust
|
||||
use poulpy_backend::cpu_spqlios::FFT64;
|
||||
use poulpy_hal::{api::ModuleNew, layouts::Module};
|
||||
|
||||
let log_n: usize = 10;
|
||||
let module = Module<FFT64> = Module<FFT64>::new(1<<log_n);
|
||||
```
|
||||
|
||||
## Contributors
|
||||
|
||||
To add a backend, implement the open extension traits from **`poulpy-hal/oep`** for a struct that implements the `Backend` trait.
|
||||
This will automatically make your backend compatible with the API of **`poulpy-hal`**, **`poulpy-core`** and **`poulpy-schemes`**.
|
||||
64
poulpy-cpu-ref/benches/fft.rs
Normal file
64
poulpy-cpu-ref/benches/fft.rs
Normal file
@@ -0,0 +1,64 @@
|
||||
use std::hint::black_box;
|
||||
|
||||
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
|
||||
use poulpy_hal::reference::fft64::reim::{ReimDFTExecute, ReimFFTRef, ReimFFTTable, ReimIFFTRef, ReimIFFTTable};
|
||||
|
||||
pub fn bench_fft_ref(c: &mut Criterion) {
|
||||
let group_name: String = "fft_ref".to_string();
|
||||
|
||||
let mut group = c.benchmark_group(group_name);
|
||||
|
||||
fn runner(m: usize) -> impl FnMut() {
|
||||
let mut values: Vec<f64> = vec![0f64; m << 1];
|
||||
let scale: f64 = 1.0f64 / (2 * m) as f64;
|
||||
values
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.for_each(|(i, x)| *x = (i + 1) as f64 * scale);
|
||||
let table: ReimFFTTable<f64> = ReimFFTTable::<f64>::new(m);
|
||||
move || {
|
||||
ReimFFTRef::reim_dft_execute(&table, &mut values);
|
||||
black_box(());
|
||||
}
|
||||
}
|
||||
|
||||
for log_m in [9, 10, 11, 12, 13, 14, 15] {
|
||||
let id: BenchmarkId = BenchmarkId::from_parameter(format!("n: {}", 2 << log_m));
|
||||
let mut runner = runner(1 << log_m);
|
||||
group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
pub fn bench_ifft_ref(c: &mut Criterion) {
|
||||
let group_name: String = "ifft_ref".to_string();
|
||||
|
||||
let mut group = c.benchmark_group(group_name);
|
||||
|
||||
fn runner(m: usize) -> impl FnMut() {
|
||||
let mut values: Vec<f64> = vec![0f64; m << 1];
|
||||
let scale: f64 = 1.0f64 / (2 * m) as f64;
|
||||
values
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.for_each(|(i, x)| *x = (i + 1) as f64 * scale);
|
||||
let table: ReimIFFTTable<f64> = ReimIFFTTable::<f64>::new(m);
|
||||
move || {
|
||||
ReimIFFTRef::reim_dft_execute(&table, &mut values);
|
||||
black_box(());
|
||||
}
|
||||
}
|
||||
|
||||
for log_m in [9, 10, 11, 12, 13, 14, 15] {
|
||||
let id: BenchmarkId = BenchmarkId::from_parameter(format!("n: {}", 2 << log_m));
|
||||
let mut runner = runner(1 << log_m);
|
||||
group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench_fft_ref, bench_ifft_ref,);
|
||||
|
||||
criterion_main!(benches);
|
||||
28
poulpy-cpu-ref/benches/vec_znx.rs
Normal file
28
poulpy-cpu-ref/benches/vec_znx.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
// poulpy-backend/benches/vec_znx_add.rs
|
||||
use criterion::{Criterion, criterion_group, criterion_main};
|
||||
use poulpy_cpu_ref::FFT64Ref;
|
||||
use poulpy_hal::reference::vec_znx::{bench_vec_znx_add, bench_vec_znx_automorphism, bench_vec_znx_normalize_inplace};
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn bench_vec_znx_add_cpu_ref_fft64(c: &mut Criterion) {
|
||||
bench_vec_znx_add::<FFT64Ref>(c, "cpu_spqlios::fft64");
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn bench_vec_znx_normalize_inplace_cpu_ref_fft64(c: &mut Criterion) {
|
||||
bench_vec_znx_normalize_inplace::<FFT64Ref>(c, "cpu_ref::fft64");
|
||||
}
|
||||
|
||||
fn bench_vec_znx_automorphism_cpu_ref_fft64(c: &mut Criterion) {
|
||||
bench_vec_znx_automorphism::<FFT64Ref>(c, "cpu_ref::fft64");
|
||||
}
|
||||
|
||||
criterion_group!(
|
||||
benches,
|
||||
// bench_vec_znx_add_cpu_spqlios_fft64,
|
||||
// bench_vec_znx_add_cpu_ref_fft64,
|
||||
// bench_vec_znx_normalize_inplace_cpu_ref_fft64,
|
||||
// bench_vec_znx_normalize_inplace_cpu_spqlios_fft64,
|
||||
bench_vec_znx_automorphism_cpu_ref_fft64,
|
||||
);
|
||||
criterion_main!(benches);
|
||||
11
poulpy-cpu-ref/benches/vmp.rs
Normal file
11
poulpy-cpu-ref/benches/vmp.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
// poulpy-backend/benches/vec_znx_add.rs
|
||||
use criterion::{Criterion, criterion_group, criterion_main};
|
||||
use poulpy_cpu_ref::FFT64Ref;
|
||||
use poulpy_hal::bench_suite::vmp::bench_vmp_apply_dft_to_dft;
|
||||
|
||||
fn bench_vmp_apply_dft_to_dft_cpu_ref_fft64(c: &mut Criterion) {
|
||||
bench_vmp_apply_dft_to_dft::<FFT64Ref>(c, "cpu_ref::fft64");
|
||||
}
|
||||
|
||||
criterion_group!(benches, bench_vmp_apply_dft_to_dft_cpu_ref_fft64,);
|
||||
criterion_main!(benches);
|
||||
14
poulpy-cpu-ref/src/lib.rs
Normal file
14
poulpy-cpu-ref/src/lib.rs
Normal 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 {}
|
||||
3
poulpy-cpu-ref/src/main.rs
Normal file
3
poulpy-cpu-ref/src/main.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
62
poulpy-cpu-ref/src/module.rs
Normal file
62
poulpy-cpu-ref/src/module.rs
Normal 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
176
poulpy-cpu-ref/src/reim.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
81
poulpy-cpu-ref/src/scratch.rs
Normal file
81
poulpy-cpu-ref/src/scratch.rs
Normal 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
66
poulpy-cpu-ref/src/svp.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
9
poulpy-cpu-ref/src/tests.rs
Normal file
9
poulpy-cpu-ref/src/tests.rs
Normal 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);
|
||||
}
|
||||
549
poulpy-cpu-ref/src/vec_znx.rs
Normal file
549
poulpy-cpu-ref/src/vec_znx.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
333
poulpy-cpu-ref/src/vec_znx_big.rs
Normal file
333
poulpy-cpu-ref/src/vec_znx_big.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
203
poulpy-cpu-ref/src/vec_znx_dft.rs
Normal file
203
poulpy-cpu-ref/src/vec_znx_dft.rs
Normal 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
153
poulpy-cpu-ref/src/vmp.rs
Normal 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
189
poulpy-cpu-ref/src/znx.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user