VecZnx: added ring degree switching

This commit is contained in:
Jean-Philippe Bossuat
2025-01-31 12:01:28 +01:00
parent e10de441c6
commit 7704e14d45
6 changed files with 75 additions and 52 deletions

View File

@@ -1,55 +1,6 @@
//use bindgen;
//use std::env;
//use std::fs;
use std::path::absolute;
//use std::path::PathBuf;
//use std::time::SystemTime;
fn main() {
/*
[build-dependencies]
bindgen ="0.71.1"
// Path to the C header file
let header_paths: [&str; 2] = [
"spqlios-arithmetic/spqlios/coeffs/coeffs_arithmetic.h",
"spqlios-arithmetic/spqlios/arithmetic/vec_znx_arithmetic.h",
];
let out_path: PathBuf = PathBuf::from(env::var("OUT_DIR").unwrap());
let bindings_file = out_path.join("bindings.rs");
let regenerate: bool = header_paths.iter().any(|header| {
let header_metadata: SystemTime = fs::metadata(header)
.and_then(|m| m.modified())
.unwrap_or(SystemTime::UNIX_EPOCH);
let bindings_metadata: SystemTime = fs::metadata(&bindings_file)
.and_then(|m| m.modified())
.unwrap_or(SystemTime::UNIX_EPOCH);
header_metadata > bindings_metadata
});
if regenerate {
// Generate the Rust bindings
let mut builder: bindgen::Builder = bindgen::Builder::default();
for header in header_paths {
builder = builder.header(header);
}
let bindings = builder
.generate_comments(false) // Optional: includes comments in bindings
.generate_inline_functions(true) // Optional: includes inline functions
.generate()
.expect("Unable to generate bindings");
// Write the bindings to the OUT_DIR
bindings
.write_to_file(&bindings_file)
.expect("Couldn't write bindings!");
}
*/
println!(
"cargo:rustc-link-search=native={}",
absolute("./spqlios-arithmetic/build/spqlios")

36
base2k/src/bindgen.rs Normal file
View File

@@ -0,0 +1,36 @@
/*
[build-dependencies]
bindgen ="0.71.1"
//use bindgen;
//use std::env;
//use std::fs;
//use std::path::PathBuf;
//use std::time::SystemTime;
// Path to the C header file
let header_paths: [&str; 2] = [
"spqlios-arithmetic/spqlios/coeffs/coeffs_arithmetic.h",
"spqlios-arithmetic/spqlios/arithmetic/vec_znx_arithmetic.h",
];
let out_path: PathBuf = PathBuf::from(env::var("OUT_DIR").unwrap());
let bindings_file = out_path.join("bindings.rs");
let mut builder: bindgen::Builder = bindgen::Builder::default();
for header in header_paths {
builder = builder.header(header);
}
let bindings = builder
.generate_comments(false) // Optional: includes comments in bindings
.generate_inline_functions(true) // Optional: includes inline functions
.generate()
.expect("Unable to generate bindings");
// Write the bindings to the OUT_DIR
bindings
.write_to_file(&bindings_file)
.expect("Couldn't write bindings!");
*/

View File

@@ -1,3 +1,4 @@
use crate::Module;
use rand::seq::SliceRandom;
use rand_core::RngCore;
use rand_distr::{Distribution, WeightedIndex};
@@ -5,6 +6,12 @@ use sampling::source::Source;
pub struct Scalar(pub Vec<i64>);
impl Module {
pub fn new_scalar(&self) -> Scalar {
Scalar::new(self.n())
}
}
impl Scalar {
pub fn new(n: usize) -> Self {
Self(vec![i64::default(); Self::buffer_size(n)])

View File

@@ -2,9 +2,13 @@ use crate::ffi::svp::{delete_svp_ppol, new_svp_ppol, svp_apply_dft, svp_ppol_t,
use crate::scalar::Scalar;
use crate::{Module, VecZnx, VecZnxDft};
pub struct SvpPPol(pub *mut svp_ppol_t);
pub struct SvpPPol(pub *mut svp_ppol_t, pub usize);
impl SvpPPol {
pub fn n(&self) -> usize {
self.1
}
pub fn delete(self) {
unsafe { delete_svp_ppol(self.0) };
let _ = drop(self);
@@ -20,7 +24,7 @@ impl Module {
// Allocates a scalar-vector-product prepared-poly (VecZnxBig).
pub fn svp_new_ppol(&self) -> SvpPPol {
unsafe { SvpPPol(new_svp_ppol(self.0)) }
unsafe { SvpPPol(new_svp_ppol(self.0), self.n()) }
}
// Applies a scalar x vector product: res <- a (ppol) x b

View File

@@ -98,6 +98,10 @@ impl VecZnx {
&mut self.data[i * self.n..(i + 1) * self.n]
}
pub fn zero(&mut self) {
unsafe { znx_zero_i64_ref(self.data.len() as u64, self.data.as_mut_ptr()) }
}
pub fn from_i64(&mut self, data: &[i64], log_max: usize) {
let size: usize = min(data.len(), self.n());
let k_rem: usize = self.log_base2k - (self.log_q % self.log_base2k);
@@ -362,6 +366,28 @@ impl VecZnx {
})
}
}
pub fn switch_degree(&self, a: &mut VecZnx) {
let (n_in, n_out) = (self.n(), a.n());
let (gap_in, gap_out): (usize, usize);
if n_in > n_out {
(gap_in, gap_out) = (n_in / n_out, 1)
} else {
(gap_in, gap_out) = (1, n_out / n_in);
a.zero();
}
let limbs = min(self.limbs(), a.limbs());
(0..limbs).for_each(|i| {
izip!(
self.at(i).iter().step_by(gap_in),
a.at_mut(i).iter_mut().step_by(gap_out)
)
.for_each(|(x_in, x_out)| *x_out = *x_in);
});
}
}
#[cfg(test)]