diff --git a/Cargo.lock b/Cargo.lock
index e37f7d3..2185f0c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -347,12 +347,13 @@ dependencies = [
[[package]]
name = "poulpy-backend"
-version = "0.1.0"
+version = "0.1.2"
dependencies = [
"byteorder",
"cmake",
"criterion",
"itertools 0.14.0",
+ "poulpy-hal 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand",
"rand_chacha",
"rand_core",
@@ -362,9 +363,51 @@ dependencies = [
[[package]]
name = "poulpy-backend"
-version = "0.1.0"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d47fbc27d0c03c2bfffd972795c62a243e4a3a3068acdb95ef55fb335a58d00f"
+checksum = "e0c6c0ad35bd5399e72a7d51b8bad5aa03e54bfd63bf1a09c4a595bd51145ca6"
+dependencies = [
+ "byteorder",
+ "cmake",
+ "criterion",
+ "itertools 0.14.0",
+ "poulpy-hal 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand",
+ "rand_chacha",
+ "rand_core",
+ "rand_distr",
+ "rug",
+]
+
+[[package]]
+name = "poulpy-core"
+version = "0.1.1"
+dependencies = [
+ "byteorder",
+ "criterion",
+ "itertools 0.14.0",
+ "poulpy-backend 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "poulpy-hal 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rug",
+]
+
+[[package]]
+name = "poulpy-core"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34afc307c185e288395d9f298a3261177dc850229e2bd6d53aa4059ae7e98cab"
+dependencies = [
+ "byteorder",
+ "criterion",
+ "itertools 0.14.0",
+ "poulpy-backend 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "poulpy-hal 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rug",
+]
+
+[[package]]
+name = "poulpy-hal"
+version = "0.1.2"
dependencies = [
"byteorder",
"cmake",
@@ -378,26 +421,17 @@ dependencies = [
]
[[package]]
-name = "poulpy-core"
-version = "0.1.0"
-dependencies = [
- "byteorder",
- "criterion",
- "itertools 0.14.0",
- "poulpy-backend 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rug",
-]
-
-[[package]]
-name = "poulpy-core"
-version = "0.1.0"
+name = "poulpy-hal"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ff4e1acd3f4a84e861b07184fd28fe3143a57360bd51e923aeadbc94b8b38d0"
+checksum = "63312a7be7c5fd91e1f5151735d646294a4592d80027d8e90778076b2070a0ec"
dependencies = [
"byteorder",
+ "cmake",
"criterion",
"itertools 0.14.0",
- "poulpy-backend 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand",
+ "rand_chacha",
"rand_core",
"rand_distr",
"rug",
@@ -405,12 +439,13 @@ dependencies = [
[[package]]
name = "poulpy-schemes"
-version = "0.1.0"
+version = "0.1.1"
dependencies = [
"byteorder",
"itertools 0.14.0",
- "poulpy-backend 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "poulpy-core 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "poulpy-backend 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "poulpy-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "poulpy-hal 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index 8774029..2b08242 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,5 +1,5 @@
[workspace]
-members = ["poulpy-backend", "poulpy-core", "poulpy-schemes"]
+members = ["poulpy-hal", "poulpy-core", "poulpy-backend", "poulpy-schemes"]
resolver = "3"
[workspace.dependencies]
diff --git a/README.md b/README.md
index 8d19123..efc2df0 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+
# 🐙 Poulpy
@@ -8,6 +9,19 @@
**Poulpy** is a fast & modular FHE library that implements Ring-Learning-With-Errors based homomorphic encryption. It adopts the bivariate polynomial representation proposed in [Revisiting Key Decomposition Techniques for FHE: Simpler, Faster and More Generic](https://eprint.iacr.org/2023/771). In addition to simpler and more efficient arithmetic than the residue number system (RNS), this representation provides a common plaintext space for all schemes and allows easy switching between any two schemes. Poulpy also decouples the schemes implementations from the polynomial arithmetic backend by being built around a hardware abstraction layer (HAL). This enables user to easily provide or use a custom backend.
+## Library Overview
+
+- **`poulpy-hal`**: a crate providing layouts and a trait-based hardware acceleration layer with open extension points, matching the API and types of spqlios-arithmetic.
+ - **`api`**: fixed public low-level polynomial level arithmetic API closely matching spqlios-arithmetic.
+ - **`delegates`**: link between the user facing API and implementation OEP. Each trait of `api` is implemented by calling its corresponding trait on the `oep`.
+ - **`layouts`**: layouts of the front-end algebraic structs matching spqlios-arithmetic types, such as `ScalarZnx`, `VecZnx` or opaque backend prepared struct such as `SvpPPol` and `VmpPMat`.
+ - **`oep`**: open extension points, which can be (re-)implemented by the user to provide a concrete backend.
+ - **`tests`**: backend agnostic & generic tests for the OEP/layouts.
+- **`poulpy-backend`**: a crate providing concrete implementations of **`poulpy-hal`**.
+ - **`cpu_spqlios`**: cpu implementation of **`poulpy-hal`** through the `oep` using bindings on spqlios-arithmetic. This implementation currently supports the `FFT64` backend and will be extended to support the `NTT120` backend once it is available in spqlios-arithmetic.
+- **`poulpy-core`**: a backend agnostic crate implementing scheme agnostic RLWE arithmetic for LWE, GLWE, GGLWE and GGSW ciphertexts using **`poulpy-hal`**.
+- **`poulpy-schemes`**: a backend agnostic crate implementing mainstream FHE schemes using **`poulpy-core`** and **`poulpy-hal`**.
+
### Bivariate Polynomial Representation
Existing FHE implementations (such as [Lattigo](https://github.com/tuneinsight/lattigo) or [OpenFHE](https://github.com/openfheorg/openfhe-development)) use the [residue-number-system](https://en.wikipedia.org/wiki/Residue_number_system) (RNS) to represent large integers. Although the parallelism and carry-less arithmetic provided by the RNS representation provides a very efficient modular arithmetic over large-integers, it suffers from various drawbacks when used in the context of FHE. The main idea behind the bivariate representation is to decouple the cyclotomic arithmetic from the large number arithmetic. Instead of using the RNS representation for large integer, integers are decomposed in base $2^{-K}$ over the Torus $\mathbb{T}_{N}[X]$.
@@ -30,114 +44,13 @@ This provides the following benefits:
In addition to providing a general purpose FHE library over a unified plaintext space, Poulpy is also designed from the ground up around a **hardware abstraction layer** that closely matches the API of [spqlios-arithmetic](https://github.com/tfhe/spqlios-arithmetic). The bivariate representation is by itself hardware friendly as it uses flat, aligned & vectorized memory layout. Finally, generic opaque write only structs (prepared versions) are provided, making it easy for developers to provide hardware focused/optimized operations. This makes possible for anyone to provide or use a custom backend.
-## Library Overview
-
-- **`backend/hal`**: hardware abstraction layer. This layer targets users that want to provide their own backend or use a third party backend.
-
- - **`api`**: fixed public low-level polynomial level arithmetic API closely matching spqlios-arithmetic. The goal is to eventually freeze this API, in order to decouple it from the OEP traits, ensuring that changes to implementations do not affect the front end API.
-
- ```rust
- pub trait SvpPrepare {
- fn svp_prepare(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
- where
- R: SvpPPolToMut,
- A: ScalarZnxToRef;
- }
- ````
-
- - **`delegates`**: link between the user facing API and implementation OEP. Each trait of `api` is implemented by calling its corresponding trait on the `oep`.
-
- ```rust
- impl SvpPrepare for Module
- where
- B: Backend + SvpPrepareImpl,
- {
- fn svp_prepare(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
- where
- R: SvpPPolToMut,
- A: ScalarZnxToRef,
- {
- B::svp_prepare_impl(self, res, res_col, a, a_col);
- }
- }
- ```
-
- - **`layouts`**: defines the layouts of the front-end algebraic structs matching spqlios-arithmetic definitions, such as `ScalarZnx`, `VecZnx` or opaque backend prepared struct such as `SvpPPol` and `VmpPMat`.
-
- ```rust
- pub struct SvpPPol {
- data: D,
- n: usize,
- cols: usize,
- _phantom: PhantomData,
- }
- ```
-
- - **`oep`**: open extension points, which can be implemented by the user to provide a custom backend.
-
- ```rust
- pub unsafe trait SvpPrepareImpl {
- fn svp_prepare_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize)
- where
- R: SvpPPolToMut,
- A: ScalarZnxToRef;
- }
- ```
-
- - **`tests`**: exported generic tests for the OEP/structs. Their goal is to enable a user to automatically be able to test its backend implementation, without having to re-implement any tests.
-
-- **`backend/implementation`**:
- - **`cpu_spqlios`**: concrete cpu implementation of the hal through the oep using bindings on spqlios-arithmetic. This implementation currently supports the `FFT64` backend and will be extended to support the `NTT120` backend once it is available in spqlios-arithmetic.
-
- ```rust
- unsafe impl SvpPrepareImpl for FFT64 {
- fn svp_prepare_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize)
- where
- R: SvpPPolToMut,
- A: ScalarZnxToRef,
- {
- unsafe {
- svp::svp_prepare(
- module.ptr(),
- res.to_mut().at_mut_ptr(res_col, 0) as *mut svp::svp_ppol_t,
- a.to_ref().at_ptr(a_col, 0),
- )
- }
- }
- }
- ```
-
-- **`core`**: core of the FHE library, implementing scheme agnostic RLWE arithmetic for LWE, GLWE, GGLWE and GGSW ciphertexts. It notably includes all possible cross-ciphertext operations, for example applying an external product on a GGLWE or an automorphism on a GGSW, as well as blind rotation. This crate is entirely implemented using the hardware abstraction layer API, and is thus solely defined over generic and traits (including tests). As such it will work over any backend, as long as it implements the necessary traits defined in the OEP.
-
- ```rust
- pub struct GLWESecret {
- pub(crate) data: ScalarZnx,
- pub(crate) dist: Distribution,
- }
-
- pub struct GLWESecrecPrepared {
- pub(crate) data: SvpPPol,
- pub(crate) dist: Distribution,
- }
-
- impl GLWESecretPrepared {
- pub fn prepare(&mut self, module: &Module, sk: &GLWESecret)
- where
- O: DataRef,
- Module: SvpPrepare,
- {
- (0..self.rank()).for_each(|i| {
- module.svp_prepare(&mut self.data, i, &sk.data, i);
- });
- self.dist = sk.dist
- }
- }
- ```
-
## Installation
-TBD — currently not published on crates.io. Clone the repository and use via path-based dependencies.
-
+- **`poulpy-hal`**: https://crates.io/crates/poulpy-hal/0.1.0
+- **`poulpy-backend`**: https://crates.io/crates/poulpy-backend/0.1.0
+- **`poulpy-core`**: https://crates.io/crates/poulpy-core/0.1.0
+- **`poulpy-schemes`**: https://crates.io/crates/poulpy-schemes/0.1.0
+-
## Documentation
* Full `cargo doc` documentation is coming soon.
diff --git a/poulpy-backend/Cargo.toml b/poulpy-backend/Cargo.toml
index e23ee54..62c5906 100644
--- a/poulpy-backend/Cargo.toml
+++ b/poulpy-backend/Cargo.toml
@@ -1,27 +1,28 @@
-[package]
-name = "poulpy-backend"
-version = "0.1.0"
-edition = "2024"
-license = "Apache-2.0"
-readme = "README.md"
-description = "A crate implementing bivariate polynomial arithmetic"
-repository = "https://github.com/phantomzone-org/poulpy"
-homepage = "https://github.com/phantomzone-org/poulpy"
-documentation = "https://docs.rs/poulpy"
-
-[dependencies]
-rug = {workspace = true}
-criterion = {workspace = true}
-itertools = {workspace = true}
-rand = {workspace = true}
-rand_distr = {workspace = true}
-rand_core = {workspace = true}
-byteorder = {workspace = true}
-rand_chacha = "0.9.0"
-
-[build-dependencies]
-cmake = "0.1.54"
-
-[package.metadata.docs.rs]
-all-features = true
+[package]
+name = "poulpy-backend"
+version = "0.1.2"
+edition = "2024"
+license = "Apache-2.0"
+readme = "README.md"
+description = "A crate providing concrete implementations of poulpy-hal through its open extension points"
+repository = "https://github.com/phantomzone-org/poulpy"
+homepage = "https://github.com/phantomzone-org/poulpy"
+documentation = "https://docs.rs/poulpy"
+
+[dependencies]
+poulpy-hal = "0.1.2"
+rug = {workspace = true}
+criterion = {workspace = true}
+itertools = {workspace = true}
+rand = {workspace = true}
+rand_distr = {workspace = true}
+rand_core = {workspace = true}
+byteorder = {workspace = true}
+rand_chacha = "0.9.0"
+
+[build-dependencies]
+cmake = "0.1.54"
+
+[package.metadata.docs.rs]
+all-features = true
rustdoc-args = ["--cfg", "docsrs"]
\ No newline at end of file
diff --git a/poulpy-backend/README.md b/poulpy-backend/README.md
index 86c8c65..23c72b0 100644
--- a/poulpy-backend/README.md
+++ b/poulpy-backend/README.md
@@ -1,12 +1,15 @@
-
-## WSL/Ubuntu
-To use this crate you need to build spqlios-arithmetic, which is provided a as a git submodule:
-1) Initialize the sub-module
-2) $ cd backend/spqlios-arithmetic
-3) mdkir build
-4) cd build
-5) cmake ..
-6) make
-
-## Others
+
+
+## spqlios-arithmetic
+
+### WSL/Ubuntu
+To use this crate you need to build spqlios-arithmetic, which is provided a as a git submodule:
+1) Initialize the sub-module
+2) $ cd backend/spqlios-arithmetic
+3) mdkir build
+4) cd build
+5) cmake ..
+6) make
+
+### Others
Steps 3 to 6 might change depending of your platform. See [spqlios-arithmetic/wiki/build](https://github.com/tfhe/spqlios-arithmetic/wiki/build) for additional information and build options.
\ No newline at end of file
diff --git a/poulpy-backend/builds/cpu_spqlios.rs b/poulpy-backend/builds/cpu_spqlios.rs
index 0f6c07c..8abb07a 100644
--- a/poulpy-backend/builds/cpu_spqlios.rs
+++ b/poulpy-backend/builds/cpu_spqlios.rs
@@ -1,7 +1,7 @@
use std::path::PathBuf;
pub fn build() {
- let dst: PathBuf = cmake::Config::new("src/implementation/cpu_spqlios/spqlios-arithmetic")
+ let dst: PathBuf = cmake::Config::new("src/cpu_spqlios/spqlios-arithmetic")
.define("ENABLE_TESTING", "FALSE")
.build();
diff --git a/poulpy-backend/examples/rlwe_encrypt.rs b/poulpy-backend/examples/rlwe_encrypt.rs
index 392b673..2e970dc 100644
--- a/poulpy-backend/examples/rlwe_encrypt.rs
+++ b/poulpy-backend/examples/rlwe_encrypt.rs
@@ -1,15 +1,13 @@
use itertools::izip;
-use poulpy_backend::{
- hal::{
- api::{
- ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyInplace, SvpPPolAlloc, SvpPrepare, VecZnxAddNormal,
- VecZnxBigAddSmallInplace, VecZnxBigAlloc, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxBigSubSmallBInplace,
- VecZnxDftAlloc, VecZnxDftFromVecZnx, VecZnxDftToVecZnxBigTmpA, VecZnxFillUniform, VecZnxNormalizeInplace, ZnxInfos,
- },
- layouts::{Module, ScalarZnx, ScratchOwned, SvpPPol, VecZnx, VecZnxBig, VecZnxDft},
- source::Source,
+use poulpy_backend::cpu_spqlios::FFT64;
+use poulpy_hal::{
+ api::{
+ ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyInplace, SvpPPolAlloc, SvpPrepare, VecZnxAddNormal,
+ VecZnxBigAddSmallInplace, VecZnxBigAlloc, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxBigSubSmallBInplace,
+ VecZnxDftAlloc, VecZnxDftFromVecZnx, VecZnxDftToVecZnxBigTmpA, VecZnxFillUniform, VecZnxNormalizeInplace, ZnxInfos,
},
- implementation::cpu_spqlios::FFT64,
+ layouts::{Module, ScalarZnx, ScratchOwned, SvpPPol, VecZnx, VecZnxBig, VecZnxDft},
+ source::Source,
};
fn main() {
diff --git a/poulpy-backend/src/implementation/cpu_spqlios/ffi/cnv.rs b/poulpy-backend/src/cpu_spqlios/ffi/cnv.rs
similarity index 100%
rename from poulpy-backend/src/implementation/cpu_spqlios/ffi/cnv.rs
rename to poulpy-backend/src/cpu_spqlios/ffi/cnv.rs
diff --git a/poulpy-backend/src/cpu_spqlios/ffi/mod.rs b/poulpy-backend/src/cpu_spqlios/ffi/mod.rs
new file mode 100644
index 0000000..6d40a1e
--- /dev/null
+++ b/poulpy-backend/src/cpu_spqlios/ffi/mod.rs
@@ -0,0 +1,15 @@
+#[allow(non_camel_case_types)]
+pub mod module;
+#[allow(non_camel_case_types)]
+pub mod svp;
+#[allow(non_camel_case_types)]
+pub mod vec_znx;
+#[allow(dead_code)]
+#[allow(non_camel_case_types)]
+pub mod vec_znx_big;
+#[allow(non_camel_case_types)]
+pub mod vec_znx_dft;
+#[allow(non_camel_case_types)]
+pub mod vmp;
+#[allow(non_camel_case_types)]
+pub mod znx;
diff --git a/poulpy-backend/src/implementation/cpu_spqlios/ffi/module.rs b/poulpy-backend/src/cpu_spqlios/ffi/module.rs
similarity index 79%
rename from poulpy-backend/src/implementation/cpu_spqlios/ffi/module.rs
rename to poulpy-backend/src/cpu_spqlios/ffi/module.rs
index b593448..9e67c30 100644
--- a/poulpy-backend/src/implementation/cpu_spqlios/ffi/module.rs
+++ b/poulpy-backend/src/cpu_spqlios/ffi/module.rs
@@ -1,19 +1,17 @@
-pub struct module_info_t {
- _unused: [u8; 0],
-}
-
-pub type module_type_t = ::std::os::raw::c_uint;
-pub use self::module_type_t as MODULE_TYPE;
-
-#[allow(clippy::upper_case_acronyms)]
-pub type MODULE = module_info_t;
-
-unsafe extern "C" {
- pub unsafe fn new_module_info(N: u64, mode: MODULE_TYPE) -> *mut MODULE;
-}
-unsafe extern "C" {
- pub unsafe fn delete_module_info(module_info: *mut MODULE);
-}
-unsafe extern "C" {
- pub unsafe fn module_get_n(module: *const MODULE) -> u64;
-}
+#[repr(C)]
+pub struct module_info_t {
+ _unused: [u8; 0],
+}
+
+pub type module_type_t = ::std::os::raw::c_uint;
+pub use self::module_type_t as MODULE_TYPE;
+
+#[allow(clippy::upper_case_acronyms)]
+pub type MODULE = module_info_t;
+
+unsafe extern "C" {
+ pub unsafe fn new_module_info(N: u64, mode: MODULE_TYPE) -> *mut MODULE;
+}
+unsafe extern "C" {
+ pub unsafe fn delete_module_info(module_info: *mut MODULE);
+}
diff --git a/poulpy-backend/src/implementation/cpu_spqlios/ffi/svp.rs b/poulpy-backend/src/cpu_spqlios/ffi/svp.rs
similarity index 68%
rename from poulpy-backend/src/implementation/cpu_spqlios/ffi/svp.rs
rename to poulpy-backend/src/cpu_spqlios/ffi/svp.rs
index f9db97f..1b72fb3 100644
--- a/poulpy-backend/src/implementation/cpu_spqlios/ffi/svp.rs
+++ b/poulpy-backend/src/cpu_spqlios/ffi/svp.rs
@@ -1,4 +1,4 @@
-use crate::implementation::cpu_spqlios::ffi::{module::MODULE, vec_znx_dft::VEC_ZNX_DFT};
+use crate::cpu_spqlios::ffi::{module::MODULE, vec_znx_dft::VEC_ZNX_DFT};
#[repr(C)]
#[derive(Debug, Copy, Clone)]
@@ -7,20 +7,11 @@ pub struct svp_ppol_t {
}
pub type SVP_PPOL = svp_ppol_t;
-unsafe extern "C" {
- pub unsafe fn bytes_of_svp_ppol(module: *const MODULE) -> u64;
-}
-unsafe extern "C" {
- pub unsafe fn new_svp_ppol(module: *const MODULE) -> *mut SVP_PPOL;
-}
-unsafe extern "C" {
- pub unsafe fn delete_svp_ppol(res: *mut SVP_PPOL);
-}
-
unsafe extern "C" {
pub unsafe fn svp_prepare(module: *const MODULE, ppol: *mut SVP_PPOL, pol: *const i64);
}
+#[allow(dead_code)]
unsafe extern "C" {
pub unsafe fn svp_apply_dft(
module: *const MODULE,
diff --git a/poulpy-backend/src/implementation/cpu_spqlios/ffi/vec_znx.rs b/poulpy-backend/src/cpu_spqlios/ffi/vec_znx.rs
similarity index 91%
rename from poulpy-backend/src/implementation/cpu_spqlios/ffi/vec_znx.rs
rename to poulpy-backend/src/cpu_spqlios/ffi/vec_znx.rs
index f4ea531..020fb9e 100644
--- a/poulpy-backend/src/implementation/cpu_spqlios/ffi/vec_znx.rs
+++ b/poulpy-backend/src/cpu_spqlios/ffi/vec_znx.rs
@@ -1,4 +1,4 @@
-use crate::implementation::cpu_spqlios::ffi::module::MODULE;
+use crate::cpu_spqlios::ffi::module::MODULE;
unsafe extern "C" {
pub unsafe fn vec_znx_add(
@@ -53,6 +53,7 @@ unsafe extern "C" {
);
}
+#[allow(dead_code)]
unsafe extern "C" {
pub unsafe fn vec_znx_rotate(
module: *const MODULE,
@@ -81,9 +82,12 @@ unsafe extern "C" {
);
}
+#[allow(dead_code)]
unsafe extern "C" {
pub unsafe fn vec_znx_zero(module: *const MODULE, res: *mut i64, res_size: u64, res_sl: u64);
}
+
+#[allow(dead_code)]
unsafe extern "C" {
pub unsafe fn vec_znx_copy(
module: *const MODULE,
diff --git a/poulpy-backend/src/implementation/cpu_spqlios/ffi/vec_znx_big.rs b/poulpy-backend/src/cpu_spqlios/ffi/vec_znx_big.rs
similarity index 86%
rename from poulpy-backend/src/implementation/cpu_spqlios/ffi/vec_znx_big.rs
rename to poulpy-backend/src/cpu_spqlios/ffi/vec_znx_big.rs
index 16d5647..55b9ea7 100644
--- a/poulpy-backend/src/implementation/cpu_spqlios/ffi/vec_znx_big.rs
+++ b/poulpy-backend/src/cpu_spqlios/ffi/vec_znx_big.rs
@@ -1,163 +1,153 @@
-use crate::implementation::cpu_spqlios::ffi::module::MODULE;
-
-#[repr(C)]
-#[derive(Debug, Copy, Clone)]
-pub struct vec_znx_big_t {
- _unused: [u8; 0],
-}
-pub type VEC_ZNX_BIG = vec_znx_big_t;
-
-unsafe extern "C" {
- pub unsafe fn bytes_of_vec_znx_big(module: *const MODULE, size: u64) -> u64;
-}
-unsafe extern "C" {
- pub unsafe fn new_vec_znx_big(module: *const MODULE, size: u64) -> *mut VEC_ZNX_BIG;
-}
-unsafe extern "C" {
- pub unsafe fn delete_vec_znx_big(res: *mut VEC_ZNX_BIG);
-}
-
-unsafe extern "C" {
- pub unsafe fn vec_znx_big_add(
- module: *const MODULE,
- res: *mut VEC_ZNX_BIG,
- res_size: u64,
- a: *const VEC_ZNX_BIG,
- a_size: u64,
- b: *const VEC_ZNX_BIG,
- b_size: u64,
- );
-}
-unsafe extern "C" {
- pub unsafe fn vec_znx_big_add_small(
- module: *const MODULE,
- res: *mut VEC_ZNX_BIG,
- res_size: u64,
- a: *const VEC_ZNX_BIG,
- a_size: u64,
- b: *const i64,
- b_size: u64,
- b_sl: u64,
- );
-}
-unsafe extern "C" {
- pub unsafe fn vec_znx_big_add_small2(
- module: *const MODULE,
- res: *mut VEC_ZNX_BIG,
- res_size: u64,
- a: *const i64,
- a_size: u64,
- a_sl: u64,
- b: *const i64,
- b_size: u64,
- b_sl: u64,
- );
-}
-unsafe extern "C" {
- pub unsafe fn vec_znx_big_sub(
- module: *const MODULE,
- res: *mut VEC_ZNX_BIG,
- res_size: u64,
- a: *const VEC_ZNX_BIG,
- a_size: u64,
- b: *const VEC_ZNX_BIG,
- b_size: u64,
- );
-}
-unsafe extern "C" {
- pub unsafe fn vec_znx_big_sub_small_b(
- module: *const MODULE,
- res: *mut VEC_ZNX_BIG,
- res_size: u64,
- a: *const VEC_ZNX_BIG,
- a_size: u64,
- b: *const i64,
- b_size: u64,
- b_sl: u64,
- );
-}
-unsafe extern "C" {
- pub unsafe fn vec_znx_big_sub_small_a(
- module: *const MODULE,
- res: *mut VEC_ZNX_BIG,
- res_size: u64,
- a: *const i64,
- a_size: u64,
- a_sl: u64,
- b: *const VEC_ZNX_BIG,
- b_size: u64,
- );
-}
-unsafe extern "C" {
- pub unsafe fn vec_znx_big_sub_small2(
- module: *const MODULE,
- res: *mut VEC_ZNX_BIG,
- res_size: u64,
- a: *const i64,
- a_size: u64,
- a_sl: u64,
- b: *const i64,
- b_size: u64,
- b_sl: u64,
- );
-}
-
-unsafe extern "C" {
- pub unsafe fn vec_znx_big_normalize_base2k_tmp_bytes(module: *const MODULE, n: u64) -> u64;
-}
-
-unsafe extern "C" {
- pub unsafe fn vec_znx_big_normalize_base2k(
- module: *const MODULE,
- n: u64,
- log2_base2k: u64,
- res: *mut i64,
- res_size: u64,
- res_sl: u64,
- a: *const VEC_ZNX_BIG,
- a_size: u64,
- tmp_space: *mut u8,
- );
-}
-
-unsafe extern "C" {
- pub unsafe fn vec_znx_big_range_normalize_base2k(
- module: *const MODULE,
- n: u64,
- log2_base2k: u64,
- res: *mut i64,
- res_size: u64,
- res_sl: u64,
- a: *const VEC_ZNX_BIG,
- a_range_begin: u64,
- a_range_xend: u64,
- a_range_step: u64,
- tmp_space: *mut u8,
- );
-}
-
-unsafe extern "C" {
- pub unsafe fn vec_znx_big_range_normalize_base2k_tmp_bytes(module: *const MODULE, n: u64) -> u64;
-}
-
-unsafe extern "C" {
- pub unsafe fn vec_znx_big_automorphism(
- module: *const MODULE,
- p: i64,
- res: *mut VEC_ZNX_BIG,
- res_size: u64,
- a: *const VEC_ZNX_BIG,
- a_size: u64,
- );
-}
-
-unsafe extern "C" {
- pub unsafe fn vec_znx_big_rotate(
- module: *const MODULE,
- p: i64,
- res: *mut VEC_ZNX_BIG,
- res_size: u64,
- a: *const VEC_ZNX_BIG,
- a_size: u64,
- );
-}
+use crate::cpu_spqlios::ffi::module::MODULE;
+
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct vec_znx_big_t {
+ _unused: [u8; 0],
+}
+pub type VEC_ZNX_BIG = vec_znx_big_t;
+
+unsafe extern "C" {
+ pub unsafe fn vec_znx_big_add(
+ module: *const MODULE,
+ res: *mut VEC_ZNX_BIG,
+ res_size: u64,
+ a: *const VEC_ZNX_BIG,
+ a_size: u64,
+ b: *const VEC_ZNX_BIG,
+ b_size: u64,
+ );
+}
+unsafe extern "C" {
+ pub unsafe fn vec_znx_big_add_small(
+ module: *const MODULE,
+ res: *mut VEC_ZNX_BIG,
+ res_size: u64,
+ a: *const VEC_ZNX_BIG,
+ a_size: u64,
+ b: *const i64,
+ b_size: u64,
+ b_sl: u64,
+ );
+}
+unsafe extern "C" {
+ pub unsafe fn vec_znx_big_add_small2(
+ module: *const MODULE,
+ res: *mut VEC_ZNX_BIG,
+ res_size: u64,
+ a: *const i64,
+ a_size: u64,
+ a_sl: u64,
+ b: *const i64,
+ b_size: u64,
+ b_sl: u64,
+ );
+}
+unsafe extern "C" {
+ pub unsafe fn vec_znx_big_sub(
+ module: *const MODULE,
+ res: *mut VEC_ZNX_BIG,
+ res_size: u64,
+ a: *const VEC_ZNX_BIG,
+ a_size: u64,
+ b: *const VEC_ZNX_BIG,
+ b_size: u64,
+ );
+}
+unsafe extern "C" {
+ pub unsafe fn vec_znx_big_sub_small_b(
+ module: *const MODULE,
+ res: *mut VEC_ZNX_BIG,
+ res_size: u64,
+ a: *const VEC_ZNX_BIG,
+ a_size: u64,
+ b: *const i64,
+ b_size: u64,
+ b_sl: u64,
+ );
+}
+unsafe extern "C" {
+ pub unsafe fn vec_znx_big_sub_small_a(
+ module: *const MODULE,
+ res: *mut VEC_ZNX_BIG,
+ res_size: u64,
+ a: *const i64,
+ a_size: u64,
+ a_sl: u64,
+ b: *const VEC_ZNX_BIG,
+ b_size: u64,
+ );
+}
+unsafe extern "C" {
+ pub unsafe fn vec_znx_big_sub_small2(
+ module: *const MODULE,
+ res: *mut VEC_ZNX_BIG,
+ res_size: u64,
+ a: *const i64,
+ a_size: u64,
+ a_sl: u64,
+ b: *const i64,
+ b_size: u64,
+ b_sl: u64,
+ );
+}
+
+unsafe extern "C" {
+ pub unsafe fn vec_znx_big_normalize_base2k_tmp_bytes(module: *const MODULE, n: u64) -> u64;
+}
+
+unsafe extern "C" {
+ pub unsafe fn vec_znx_big_normalize_base2k(
+ module: *const MODULE,
+ n: u64,
+ log2_base2k: u64,
+ res: *mut i64,
+ res_size: u64,
+ res_sl: u64,
+ a: *const VEC_ZNX_BIG,
+ a_size: u64,
+ tmp_space: *mut u8,
+ );
+}
+
+unsafe extern "C" {
+ pub unsafe fn vec_znx_big_range_normalize_base2k(
+ module: *const MODULE,
+ n: u64,
+ log2_base2k: u64,
+ res: *mut i64,
+ res_size: u64,
+ res_sl: u64,
+ a: *const VEC_ZNX_BIG,
+ a_range_begin: u64,
+ a_range_xend: u64,
+ a_range_step: u64,
+ tmp_space: *mut u8,
+ );
+}
+
+unsafe extern "C" {
+ pub unsafe fn vec_znx_big_range_normalize_base2k_tmp_bytes(module: *const MODULE, n: u64) -> u64;
+}
+
+unsafe extern "C" {
+ pub unsafe fn vec_znx_big_automorphism(
+ module: *const MODULE,
+ p: i64,
+ res: *mut VEC_ZNX_BIG,
+ res_size: u64,
+ a: *const VEC_ZNX_BIG,
+ a_size: u64,
+ );
+}
+
+unsafe extern "C" {
+ pub unsafe fn vec_znx_big_rotate(
+ module: *const MODULE,
+ p: i64,
+ res: *mut VEC_ZNX_BIG,
+ res_size: u64,
+ a: *const VEC_ZNX_BIG,
+ a_size: u64,
+ );
+}
diff --git a/poulpy-backend/src/implementation/cpu_spqlios/ffi/vec_znx_dft.rs b/poulpy-backend/src/cpu_spqlios/ffi/vec_znx_dft.rs
similarity index 72%
rename from poulpy-backend/src/implementation/cpu_spqlios/ffi/vec_znx_dft.rs
rename to poulpy-backend/src/cpu_spqlios/ffi/vec_znx_dft.rs
index fbf1e49..9612f37 100644
--- a/poulpy-backend/src/implementation/cpu_spqlios/ffi/vec_znx_dft.rs
+++ b/poulpy-backend/src/cpu_spqlios/ffi/vec_znx_dft.rs
@@ -1,4 +1,4 @@
-use crate::implementation::cpu_spqlios::ffi::{module::MODULE, vec_znx_big::VEC_ZNX_BIG};
+use crate::cpu_spqlios::ffi::{module::MODULE, vec_znx_big::VEC_ZNX_BIG};
#[repr(C)]
#[derive(Debug, Copy, Clone)]
@@ -7,19 +7,6 @@ pub struct vec_znx_dft_t {
}
pub type VEC_ZNX_DFT = vec_znx_dft_t;
-unsafe extern "C" {
- pub unsafe fn bytes_of_vec_znx_dft(module: *const MODULE, size: u64) -> u64;
-}
-unsafe extern "C" {
- pub unsafe fn new_vec_znx_dft(module: *const MODULE, size: u64) -> *mut VEC_ZNX_DFT;
-}
-unsafe extern "C" {
- pub unsafe fn delete_vec_znx_dft(res: *mut VEC_ZNX_DFT);
-}
-
-unsafe extern "C" {
- pub unsafe fn vec_dft_zero(module: *const MODULE, res: *mut VEC_ZNX_DFT, res_size: u64);
-}
unsafe extern "C" {
pub unsafe fn vec_dft_add(
module: *const MODULE,
diff --git a/poulpy-backend/src/implementation/cpu_spqlios/ffi/vmp.rs b/poulpy-backend/src/cpu_spqlios/ffi/vmp.rs
similarity index 79%
rename from poulpy-backend/src/implementation/cpu_spqlios/ffi/vmp.rs
rename to poulpy-backend/src/cpu_spqlios/ffi/vmp.rs
index b9ae29a..48c3a84 100644
--- a/poulpy-backend/src/implementation/cpu_spqlios/ffi/vmp.rs
+++ b/poulpy-backend/src/cpu_spqlios/ffi/vmp.rs
@@ -1,4 +1,4 @@
-use crate::implementation::cpu_spqlios::ffi::{module::MODULE, vec_znx_dft::VEC_ZNX_DFT};
+use crate::cpu_spqlios::ffi::{module::MODULE, vec_znx_dft::VEC_ZNX_DFT};
#[repr(C)]
#[derive(Debug, Copy, Clone)]
@@ -9,16 +9,7 @@ pub struct vmp_pmat_t {
// [rows][cols] = [#Decomposition][#Limbs]
pub type VMP_PMAT = vmp_pmat_t;
-unsafe extern "C" {
- pub unsafe fn bytes_of_vmp_pmat(module: *const MODULE, nrows: u64, ncols: u64) -> u64;
-}
-unsafe extern "C" {
- pub unsafe fn new_vmp_pmat(module: *const MODULE, nrows: u64, ncols: u64) -> *mut VMP_PMAT;
-}
-unsafe extern "C" {
- pub unsafe fn delete_vmp_pmat(res: *mut VMP_PMAT);
-}
-
+#[allow(dead_code)]
unsafe extern "C" {
pub unsafe fn vmp_apply_dft(
module: *const MODULE,
@@ -34,6 +25,7 @@ unsafe extern "C" {
);
}
+#[allow(dead_code)]
unsafe extern "C" {
pub unsafe fn vmp_apply_dft_add(
module: *const MODULE,
@@ -50,6 +42,7 @@ unsafe extern "C" {
);
}
+#[allow(dead_code)]
unsafe extern "C" {
pub unsafe fn vmp_apply_dft_tmp_bytes(module: *const MODULE, res_size: u64, a_size: u64, nrows: u64, ncols: u64) -> u64;
}
@@ -105,10 +98,6 @@ unsafe extern "C" {
);
}
-unsafe extern "C" {
- pub unsafe fn vmp_prepare_contiguous_dft(module: *const MODULE, pmat: *mut VMP_PMAT, mat: *const f64, nrows: u64, ncols: u64);
-}
-
unsafe extern "C" {
pub unsafe fn vmp_prepare_tmp_bytes(module: *const MODULE, nn: u64, nrows: u64, ncols: u64) -> u64;
}
diff --git a/poulpy-backend/src/cpu_spqlios/ffi/znx.rs b/poulpy-backend/src/cpu_spqlios/ffi/znx.rs
new file mode 100644
index 0000000..e669c35
--- /dev/null
+++ b/poulpy-backend/src/cpu_spqlios/ffi/znx.rs
@@ -0,0 +1,7 @@
+unsafe extern "C" {
+ pub unsafe fn znx_rotate_i64(nn: u64, p: i64, res: *mut i64, in_: *const i64);
+}
+
+unsafe extern "C" {
+ pub unsafe fn znx_rotate_inplace_i64(nn: u64, p: i64, res: *mut i64);
+}
diff --git a/poulpy-backend/src/cpu_spqlios/fft64/mod.rs b/poulpy-backend/src/cpu_spqlios/fft64/mod.rs
new file mode 100644
index 0000000..b81e73d
--- /dev/null
+++ b/poulpy-backend/src/cpu_spqlios/fft64/mod.rs
@@ -0,0 +1,15 @@
+mod module;
+mod scratch;
+mod svp_ppol;
+mod vec_znx;
+mod vec_znx_big;
+mod vec_znx_dft;
+mod vmp_pmat;
+
+pub use module::FFT64;
+
+/// For external documentation
+pub use vec_znx::{
+ vec_znx_copy_ref, vec_znx_lsh_inplace_ref, vec_znx_merge_ref, vec_znx_rsh_inplace_ref, vec_znx_split_ref,
+ vec_znx_switch_degree_ref,
+};
diff --git a/poulpy-backend/src/implementation/cpu_spqlios/module_fft64.rs b/poulpy-backend/src/cpu_spqlios/fft64/module.rs
similarity index 53%
rename from poulpy-backend/src/implementation/cpu_spqlios/module_fft64.rs
rename to poulpy-backend/src/cpu_spqlios/fft64/module.rs
index 3f86c6c..7bd4ff6 100644
--- a/poulpy-backend/src/implementation/cpu_spqlios/module_fft64.rs
+++ b/poulpy-backend/src/cpu_spqlios/fft64/module.rs
@@ -1,25 +1,29 @@
use std::ptr::NonNull;
-use crate::{
- hal::{
- layouts::{Backend, Module},
- oep::ModuleNewImpl,
- },
- implementation::cpu_spqlios::{
- CPUAVX,
- ffi::module::{MODULE, delete_module_info, new_module_info},
- },
+use poulpy_hal::{
+ layouts::{Backend, Module},
+ oep::ModuleNewImpl,
};
+use crate::cpu_spqlios::ffi::module::{MODULE, delete_module_info, new_module_info};
+
pub struct FFT64;
-impl CPUAVX for FFT64 {}
-
impl Backend for FFT64 {
+ type ScalarPrep = f64;
+ type ScalarBig = i64;
type Handle = MODULE;
unsafe fn destroy(handle: NonNull) {
unsafe { delete_module_info(handle.as_ptr()) }
}
+
+ fn layout_big_word_count() -> usize {
+ 1
+ }
+
+ fn layout_prep_word_count() -> usize {
+ 1
+ }
}
unsafe impl ModuleNewImpl for FFT64 {
diff --git a/poulpy-backend/src/implementation/cpu_spqlios/scratch.rs b/poulpy-backend/src/cpu_spqlios/fft64/scratch.rs
similarity index 77%
rename from poulpy-backend/src/implementation/cpu_spqlios/scratch.rs
rename to poulpy-backend/src/cpu_spqlios/fft64/scratch.rs
index 3ebb6d2..43ff74e 100644
--- a/poulpy-backend/src/implementation/cpu_spqlios/scratch.rs
+++ b/poulpy-backend/src/cpu_spqlios/fft64/scratch.rs
@@ -1,24 +1,20 @@
use std::marker::PhantomData;
-use crate::{
+use poulpy_hal::{
DEFAULTALIGN, alloc_aligned,
- hal::{
- api::ScratchFromBytes,
- layouts::{Backend, MatZnx, ScalarZnx, Scratch, ScratchOwned, SvpPPol, VecZnx, VecZnxBig, VecZnxDft, VmpPMat},
- oep::{
- ScratchAvailableImpl, ScratchFromBytesImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, SvpPPolAllocBytesImpl,
- TakeMatZnxImpl, TakeScalarZnxImpl, TakeSliceImpl, TakeSvpPPolImpl, TakeVecZnxBigImpl, TakeVecZnxDftImpl,
- TakeVecZnxDftSliceImpl, TakeVecZnxImpl, TakeVecZnxSliceImpl, TakeVmpPMatImpl, VecZnxBigAllocBytesImpl,
- VecZnxDftAllocBytesImpl, VmpPMatAllocBytesImpl,
- },
+ api::ScratchFromBytes,
+ layouts::{Backend, MatZnx, ScalarZnx, Scratch, ScratchOwned, SvpPPol, VecZnx, VecZnxBig, VecZnxDft, VmpPMat},
+ oep::{
+ ScratchAvailableImpl, ScratchFromBytesImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, SvpPPolAllocBytesImpl,
+ TakeMatZnxImpl, TakeScalarZnxImpl, TakeSliceImpl, TakeSvpPPolImpl, TakeVecZnxBigImpl, TakeVecZnxDftImpl,
+ TakeVecZnxDftSliceImpl, TakeVecZnxImpl, TakeVecZnxSliceImpl, TakeVmpPMatImpl, VecZnxBigAllocBytesImpl,
+ VecZnxDftAllocBytesImpl, VmpPMatAllocBytesImpl,
},
- implementation::cpu_spqlios::CPUAVX,
};
-unsafe impl ScratchOwnedAllocImpl for B
-where
- B: CPUAVX,
-{
+use crate::cpu_spqlios::FFT64;
+
+unsafe impl ScratchOwnedAllocImpl for FFT64 {
fn scratch_owned_alloc_impl(size: usize) -> ScratchOwned {
let data: Vec = alloc_aligned(size);
ScratchOwned {
@@ -28,28 +24,22 @@ where
}
}
-unsafe impl ScratchOwnedBorrowImpl for B
+unsafe impl ScratchOwnedBorrowImpl for FFT64
where
- B: CPUAVX,
+ B: ScratchFromBytesImpl,
{
fn scratch_owned_borrow_impl(scratch: &mut ScratchOwned) -> &mut Scratch {
Scratch::from_bytes(&mut scratch.data)
}
}
-unsafe impl ScratchFromBytesImpl for B
-where
- B: CPUAVX,
-{
+unsafe impl ScratchFromBytesImpl for FFT64 {
fn scratch_from_bytes_impl(data: &mut [u8]) -> &mut Scratch {
unsafe { &mut *(data as *mut [u8] as *mut Scratch) }
}
}
-unsafe impl ScratchAvailableImpl for B
-where
- B: CPUAVX,
-{
+unsafe impl ScratchAvailableImpl for FFT64 {
fn scratch_available_impl(scratch: &Scratch) -> usize {
let ptr: *const u8 = scratch.data.as_ptr();
let self_len: usize = scratch.data.len();
@@ -58,9 +48,9 @@ where
}
}
-unsafe impl TakeSliceImpl for B
+unsafe impl TakeSliceImpl for FFT64
where
- B: CPUAVX,
+ B: ScratchFromBytesImpl,
{
fn take_slice_impl(scratch: &mut Scratch, len: usize) -> (&mut [T], &mut Scratch) {
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, len * std::mem::size_of::());
@@ -74,9 +64,9 @@ where
}
}
-unsafe impl TakeScalarZnxImpl for B
+unsafe impl TakeScalarZnxImpl for FFT64
where
- B: CPUAVX,
+ B: ScratchFromBytesImpl,
{
fn take_scalar_znx_impl(scratch: &mut Scratch, n: usize, cols: usize) -> (ScalarZnx<&mut [u8]>, &mut Scratch) {
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, ScalarZnx::alloc_bytes(n, cols));
@@ -87,9 +77,9 @@ where
}
}
-unsafe impl TakeSvpPPolImpl for B
+unsafe impl TakeSvpPPolImpl for FFT64
where
- B: CPUAVX + SvpPPolAllocBytesImpl,
+ B: SvpPPolAllocBytesImpl + ScratchFromBytesImpl,
{
fn take_svp_ppol_impl(scratch: &mut Scratch, n: usize, cols: usize) -> (SvpPPol<&mut [u8], B>, &mut Scratch) {
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, B::svp_ppol_alloc_bytes_impl(n, cols));
@@ -100,9 +90,9 @@ where
}
}
-unsafe impl TakeVecZnxImpl for B
+unsafe impl TakeVecZnxImpl for FFT64
where
- B: CPUAVX,
+ B: ScratchFromBytesImpl,
{
fn take_vec_znx_impl(scratch: &mut Scratch, n: usize, cols: usize, size: usize) -> (VecZnx<&mut [u8]>, &mut Scratch) {
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, VecZnx::alloc_bytes(n, cols, size));
@@ -113,9 +103,9 @@ where
}
}
-unsafe impl TakeVecZnxBigImpl for B
+unsafe impl TakeVecZnxBigImpl for FFT64
where
- B: CPUAVX + VecZnxBigAllocBytesImpl,
+ B: VecZnxBigAllocBytesImpl + ScratchFromBytesImpl,
{
fn take_vec_znx_big_impl(
scratch: &mut Scratch,
@@ -134,9 +124,9 @@ where
}
}
-unsafe impl TakeVecZnxDftImpl for B
+unsafe impl TakeVecZnxDftImpl for FFT64
where
- B: CPUAVX + VecZnxDftAllocBytesImpl,
+ B: VecZnxDftAllocBytesImpl + ScratchFromBytesImpl,
{
fn take_vec_znx_dft_impl(
scratch: &mut Scratch,
@@ -156,9 +146,9 @@ where
}
}
-unsafe impl TakeVecZnxDftSliceImpl for B
+unsafe impl TakeVecZnxDftSliceImpl for FFT64
where
- B: CPUAVX + VecZnxDftAllocBytesImpl,
+ B: VecZnxDftAllocBytesImpl + ScratchFromBytesImpl + TakeVecZnxDftImpl,
{
fn take_vec_znx_dft_slice_impl(
scratch: &mut Scratch,
@@ -178,9 +168,9 @@ where
}
}
-unsafe impl TakeVecZnxSliceImpl for B
+unsafe impl TakeVecZnxSliceImpl for FFT64
where
- B: CPUAVX,
+ B: ScratchFromBytesImpl + TakeVecZnxImpl,
{
fn take_vec_znx_slice_impl(
scratch: &mut Scratch,
@@ -200,9 +190,9 @@ where
}
}
-unsafe impl TakeVmpPMatImpl for B
+unsafe impl TakeVmpPMatImpl for FFT64
where
- B: CPUAVX + VmpPMatAllocBytesImpl,
+ B: VmpPMatAllocBytesImpl + ScratchFromBytesImpl,
{
fn take_vmp_pmat_impl(
scratch: &mut Scratch,
@@ -223,9 +213,9 @@ where
}
}
-unsafe impl TakeMatZnxImpl for B
+unsafe impl TakeMatZnxImpl for FFT64
where
- B: CPUAVX,
+ B: ScratchFromBytesImpl,
{
fn take_mat_znx_impl(
scratch: &mut Scratch,
diff --git a/poulpy-backend/src/implementation/cpu_spqlios/svp_ppol_fft64.rs b/poulpy-backend/src/cpu_spqlios/fft64/svp_ppol.rs
similarity index 72%
rename from poulpy-backend/src/implementation/cpu_spqlios/svp_ppol_fft64.rs
rename to poulpy-backend/src/cpu_spqlios/fft64/svp_ppol.rs
index 265840a..6a82dc6 100644
--- a/poulpy-backend/src/implementation/cpu_spqlios/svp_ppol_fft64.rs
+++ b/poulpy-backend/src/cpu_spqlios/fft64/svp_ppol.rs
@@ -1,35 +1,16 @@
-use crate::{
- hal::{
- api::{ZnxInfos, ZnxSliceSize, ZnxView, ZnxViewMut},
- layouts::{
- Data, DataRef, Module, ScalarZnxToRef, SvpPPol, SvpPPolBytesOf, SvpPPolOwned, SvpPPolToMut, SvpPPolToRef, VecZnxDft,
- VecZnxDftToMut, VecZnxDftToRef,
- },
- oep::{SvpApplyImpl, SvpApplyInplaceImpl, SvpPPolAllocBytesImpl, SvpPPolAllocImpl, SvpPPolFromBytesImpl, SvpPrepareImpl},
- },
- implementation::cpu_spqlios::{
- ffi::{svp, vec_znx_dft::vec_znx_dft_t},
- module_fft64::FFT64,
+use poulpy_hal::{
+ api::{ZnxInfos, ZnxView, ZnxViewMut},
+ layouts::{
+ Backend, Module, ScalarZnxToRef, SvpPPol, SvpPPolOwned, SvpPPolToMut, SvpPPolToRef, VecZnxDft, VecZnxDftToMut,
+ VecZnxDftToRef,
},
+ oep::{SvpApplyImpl, SvpApplyInplaceImpl, SvpPPolAllocBytesImpl, SvpPPolAllocImpl, SvpPPolFromBytesImpl, SvpPrepareImpl},
};
-const SVP_PPOL_FFT64_WORD_SIZE: usize = 1;
-
-impl SvpPPolBytesOf for SvpPPol {
- fn bytes_of(n: usize, cols: usize) -> usize {
- SVP_PPOL_FFT64_WORD_SIZE * n * cols * size_of::()
- }
-}
-
-impl ZnxSliceSize for SvpPPol {
- fn sl(&self) -> usize {
- SVP_PPOL_FFT64_WORD_SIZE * self.n()
- }
-}
-
-impl ZnxView for SvpPPol {
- type Scalar = f64;
-}
+use crate::cpu_spqlios::{
+ FFT64,
+ ffi::{svp, vec_znx_dft::vec_znx_dft_t},
+};
unsafe impl SvpPPolFromBytesImpl for FFT64 {
fn svp_ppol_from_bytes_impl(n: usize, cols: usize, bytes: Vec) -> SvpPPolOwned {
@@ -45,7 +26,7 @@ unsafe impl SvpPPolAllocImpl for FFT64 {
unsafe impl SvpPPolAllocBytesImpl for FFT64 {
fn svp_ppol_alloc_bytes_impl(n: usize, cols: usize) -> usize {
- SvpPPol::, Self>::bytes_of(n, cols)
+ FFT64::layout_prep_word_count() * n * cols * size_of::()
}
}
diff --git a/poulpy-backend/src/implementation/cpu_spqlios/vec_znx.rs b/poulpy-backend/src/cpu_spqlios/fft64/vec_znx.rs
similarity index 77%
rename from poulpy-backend/src/implementation/cpu_spqlios/vec_znx.rs
rename to poulpy-backend/src/cpu_spqlios/fft64/vec_znx.rs
index b928b9c..c5271cc 100644
--- a/poulpy-backend/src/implementation/cpu_spqlios/vec_znx.rs
+++ b/poulpy-backend/src/cpu_spqlios/fft64/vec_znx.rs
@@ -1,48 +1,47 @@
use itertools::izip;
use rand_distr::Normal;
-use crate::{
- hal::{
- api::{
- TakeSlice, TakeVecZnx, VecZnxAddDistF64, VecZnxCopy, VecZnxFillDistF64, VecZnxNormalizeTmpBytes, VecZnxRotate,
- VecZnxRotateInplace, VecZnxSwithcDegree, ZnxInfos, ZnxSliceSize, ZnxView, ZnxViewMut, ZnxZero,
- },
- layouts::{Backend, Module, ScalarZnx, ScalarZnxToRef, Scratch, VecZnx, VecZnxToMut, VecZnxToRef},
- oep::{
- VecZnxAddDistF64Impl, VecZnxAddImpl, VecZnxAddInplaceImpl, VecZnxAddNormalImpl, VecZnxAddScalarInplaceImpl,
- VecZnxAutomorphismImpl, VecZnxAutomorphismInplaceImpl, VecZnxCopyImpl, VecZnxFillDistF64Impl, VecZnxFillNormalImpl,
- VecZnxFillUniformImpl, VecZnxLshInplaceImpl, VecZnxMergeImpl, VecZnxMulXpMinusOneImpl,
- VecZnxMulXpMinusOneInplaceImpl, VecZnxNegateImpl, VecZnxNegateInplaceImpl, VecZnxNormalizeImpl,
- VecZnxNormalizeInplaceImpl, VecZnxNormalizeTmpBytesImpl, VecZnxRotateImpl, VecZnxRotateInplaceImpl,
- VecZnxRshInplaceImpl, VecZnxSplitImpl, VecZnxSubABInplaceImpl, VecZnxSubBAInplaceImpl, VecZnxSubImpl,
- VecZnxSubScalarInplaceImpl, VecZnxSwithcDegreeImpl,
- },
- source::Source,
+use poulpy_hal::{
+ api::{
+ TakeSlice, TakeVecZnx, VecZnxAddDistF64, VecZnxCopy, VecZnxFillDistF64, VecZnxNormalizeTmpBytes, VecZnxRotate,
+ VecZnxRotateInplace, VecZnxSwithcDegree, ZnxInfos, ZnxSliceSize, ZnxView, ZnxViewMut, ZnxZero,
},
- implementation::cpu_spqlios::{
- CPUAVX,
- ffi::{module::module_info_t, vec_znx, znx},
+ layouts::{Backend, Module, ScalarZnx, ScalarZnxToRef, Scratch, VecZnx, VecZnxToMut, VecZnxToRef},
+ oep::{
+ TakeSliceImpl, TakeVecZnxImpl, VecZnxAddDistF64Impl, VecZnxAddImpl, VecZnxAddInplaceImpl, VecZnxAddNormalImpl,
+ VecZnxAddScalarInplaceImpl, VecZnxAutomorphismImpl, VecZnxAutomorphismInplaceImpl, VecZnxCopyImpl, VecZnxFillDistF64Impl,
+ VecZnxFillNormalImpl, VecZnxFillUniformImpl, VecZnxLshInplaceImpl, VecZnxMergeImpl, VecZnxMulXpMinusOneImpl,
+ VecZnxMulXpMinusOneInplaceImpl, VecZnxNegateImpl, VecZnxNegateInplaceImpl, VecZnxNormalizeImpl,
+ VecZnxNormalizeInplaceImpl, VecZnxNormalizeTmpBytesImpl, VecZnxRotateImpl, VecZnxRotateInplaceImpl, VecZnxRshInplaceImpl,
+ VecZnxSplitImpl, VecZnxSubABInplaceImpl, VecZnxSubBAInplaceImpl, VecZnxSubImpl, VecZnxSubScalarInplaceImpl,
+ VecZnxSwithcDegreeImpl,
},
+ source::Source,
};
-unsafe impl VecZnxNormalizeTmpBytesImpl for B
-where
- B: CPUAVX,
-{
- fn vec_znx_normalize_tmp_bytes_impl(module: &Module, n: usize) -> usize {
+use crate::cpu_spqlios::{
+ FFT64,
+ ffi::{module::module_info_t, vec_znx, znx},
+};
+
+unsafe impl VecZnxNormalizeTmpBytesImpl for FFT64 {
+ fn vec_znx_normalize_tmp_bytes_impl(module: &Module, n: usize) -> usize {
unsafe { vec_znx::vec_znx_normalize_base2k_tmp_bytes(module.ptr() as *const module_info_t, n as u64) as usize }
}
}
-unsafe impl VecZnxNormalizeImpl for B {
+unsafe impl VecZnxNormalizeImpl for FFT64
+where
+ Self: TakeSliceImpl + VecZnxNormalizeTmpBytesImpl,
+{
fn vec_znx_normalize_impl(
- module: &Module,
+ module: &Module,
basek: usize,
res: &mut R,
res_col: usize,
a: &A,
a_col: usize,
- scratch: &mut Scratch,
+ scratch: &mut Scratch,
) where
R: VecZnxToMut,
A: VecZnxToRef,
@@ -74,9 +73,17 @@ unsafe impl VecZnxNormalizeImpl for B {
}
}
-unsafe impl VecZnxNormalizeInplaceImpl for B {
- fn vec_znx_normalize_inplace_impl(module: &Module, basek: usize, a: &mut A, a_col: usize, scratch: &mut Scratch)
- where
+unsafe impl VecZnxNormalizeInplaceImpl for FFT64
+where
+ Self: TakeSliceImpl + VecZnxNormalizeTmpBytesImpl,
+{
+ fn vec_znx_normalize_inplace_impl(
+ module: &Module,
+ basek: usize,
+ a: &mut A,
+ a_col: usize,
+ scratch: &mut Scratch,
+ ) where
A: VecZnxToMut,
{
let mut a: VecZnx<&mut [u8]> = a.to_mut();
@@ -100,8 +107,8 @@ unsafe impl VecZnxNormalizeInplaceImpl for B {
}
}
-unsafe impl VecZnxAddImpl for B {
- fn vec_znx_add_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &C, b_col: usize)
+unsafe impl VecZnxAddImpl for FFT64 {
+ fn vec_znx_add_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &C, b_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
@@ -134,8 +141,8 @@ unsafe impl VecZnxAddImpl for B {
}
}
-unsafe impl VecZnxAddInplaceImpl for B {
- fn vec_znx_add_inplace_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize)
+unsafe impl VecZnxAddInplaceImpl for FFT64 {
+ fn vec_znx_add_inplace_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
@@ -164,9 +171,9 @@ unsafe impl VecZnxAddInplaceImpl for B {
}
}
-unsafe impl VecZnxAddScalarInplaceImpl for B {
+unsafe impl VecZnxAddScalarInplaceImpl for FFT64 {
fn vec_znx_add_scalar_inplace_impl(
- module: &Module,
+ module: &Module,
res: &mut R,
res_col: usize,
res_limb: usize,
@@ -201,8 +208,8 @@ unsafe impl VecZnxAddScalarInplaceImpl for B {
}
}
-unsafe impl VecZnxSubImpl for B {
- fn vec_znx_sub_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &C, b_col: usize)
+unsafe impl VecZnxSubImpl for FFT64 {
+ fn vec_znx_sub_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &C, b_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
@@ -235,8 +242,8 @@ unsafe impl VecZnxSubImpl for B {
}
}
-unsafe impl VecZnxSubABInplaceImpl for B {
- fn vec_znx_sub_ab_inplace_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize)
+unsafe impl VecZnxSubABInplaceImpl for FFT64 {
+ fn vec_znx_sub_ab_inplace_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
@@ -264,8 +271,8 @@ unsafe impl VecZnxSubABInplaceImpl for B {
}
}
-unsafe impl VecZnxSubBAInplaceImpl for B {
- fn vec_znx_sub_ba_inplace_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize)
+unsafe impl VecZnxSubBAInplaceImpl for FFT64 {
+ fn vec_znx_sub_ba_inplace_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
@@ -293,9 +300,9 @@ unsafe impl VecZnxSubBAInplaceImpl for B {
}
}
-unsafe impl VecZnxSubScalarInplaceImpl for B {
+unsafe impl VecZnxSubScalarInplaceImpl for FFT64 {
fn vec_znx_sub_scalar_inplace_impl(
- module: &Module,
+ module: &Module,
res: &mut R,
res_col: usize,
res_limb: usize,
@@ -330,8 +337,8 @@ unsafe impl VecZnxSubScalarInplaceImpl for B {
}
}
-unsafe impl VecZnxNegateImpl for B {
- fn vec_znx_negate_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize)
+unsafe impl VecZnxNegateImpl for FFT64 {
+ fn vec_znx_negate_impl(module: &Module, res: &mut R, res_col: usize, a: &A, a_col: usize)
where
R: VecZnxToMut,
A: VecZnxToRef,
@@ -356,8 +363,8 @@ unsafe impl VecZnxNegateImpl for B {
}
}
-unsafe impl VecZnxNegateInplaceImpl for B {
- fn vec_znx_negate_inplace_impl(module: &Module, a: &mut A, a_col: usize)
+unsafe impl VecZnxNegateInplaceImpl