From 870939ab03e0450ea18e4098bd7ffa2ddfa023e4 Mon Sep 17 00:00:00 2001 From: Volker Mische Date: Wed, 2 Mar 2022 14:37:44 +0100 Subject: [PATCH 1/4] Implement ec_gpu:GpuField for Fp/Fq This commit introduces a new feature called "gpu", which enables an `ec_gpu:GpuField` implementation of `Fp` and `Fq`. This enables the field arithmetics to be run on a GPU. The code to convert from a u64 to a u32 vector was taken from https://github.com/filecoin-project/blstrs/blob/07a84f9727d2fb7387efb2df0f17ddc5d35571d3/src/lib.rs#L102-L108 --- Cargo.toml | 4 ++++ src/fields.rs | 8 ++++++++ src/fields/fp.rs | 15 +++++++++++++++ src/fields/fq.rs | 15 +++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 6b1429f..620104f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,8 +53,12 @@ blake2b_simd = { version = "1", optional = true, default-features = false } # sqrt-table dependencies lazy_static = { version = "1.4.0", optional = true } +# gpu dependencies +ec-gpu = { version = "0.1.0", optional = true } + [features] default = ["bits", "sqrt-table"] alloc = ["group/alloc", "blake2b_simd"] bits = ["ff/bits"] +gpu = ["alloc", "ec-gpu"] sqrt-table = ["alloc", "lazy_static"] diff --git a/src/fields.rs b/src/fields.rs index e19389e..70ce865 100644 --- a/src/fields.rs +++ b/src/fields.rs @@ -6,3 +6,11 @@ mod fq; pub use fp::*; pub use fq::*; + +#[cfg(feature = "gpu")] +fn u64_to_u32(limbs: &[u64]) -> alloc::vec::Vec { + limbs + .iter() + .flat_map(|limb| alloc::vec![(limb & 0xFFFF_FFFF) as u32, (limb >> 32) as u32]) + .collect() +} diff --git a/src/fields/fp.rs b/src/fields/fp.rs index 17be5d6..50dba17 100644 --- a/src/fields/fp.rs +++ b/src/fields/fp.rs @@ -770,6 +770,21 @@ impl FieldExt for Fp { } } +#[cfg(feature = "gpu")] +impl ec_gpu::GpuField for Fp { + fn one() -> alloc::vec::Vec { + crate::fields::u64_to_u32(&R.0[..]) + } + + fn r2() -> alloc::vec::Vec { + crate::fields::u64_to_u32(&R2.0[..]) + } + + fn modulus() -> alloc::vec::Vec { + crate::fields::u64_to_u32(&MODULUS.0[..]) + } +} + #[cfg(test)] use ff::Field; diff --git a/src/fields/fq.rs b/src/fields/fq.rs index 618bf54..d01a609 100644 --- a/src/fields/fq.rs +++ b/src/fields/fq.rs @@ -769,6 +769,21 @@ impl FieldExt for Fq { } } +#[cfg(feature = "gpu")] +impl ec_gpu::GpuField for Fq { + fn one() -> alloc::vec::Vec { + crate::fields::u64_to_u32(&R.0[..]) + } + + fn r2() -> alloc::vec::Vec { + crate::fields::u64_to_u32(&R2.0[..]) + } + + fn modulus() -> alloc::vec::Vec { + crate::fields::u64_to_u32(&MODULUS.0[..]) + } +} + #[cfg(test)] use ff::Field; From cc51340dc539c664ce2e37e12b19a833786a173b Mon Sep 17 00:00:00 2001 From: Volker Mische Date: Fri, 11 Mar 2022 17:37:47 +0100 Subject: [PATCH 2/4] fix: less allocations Co-authored-by: str4d --- src/fields.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fields.rs b/src/fields.rs index 70ce865..9e01217 100644 --- a/src/fields.rs +++ b/src/fields.rs @@ -11,6 +11,6 @@ pub use fq::*; fn u64_to_u32(limbs: &[u64]) -> alloc::vec::Vec { limbs .iter() - .flat_map(|limb| alloc::vec![(limb & 0xFFFF_FFFF) as u32, (limb >> 32) as u32]) + .flat_map(|limb| Some((limb & 0xFFFF_FFFF) as u32).into_iter().chain(Some((limb >> 32) as u32))) .collect() } From b1f03fbc9c3701afcc2005412f34c3c672720e64 Mon Sep 17 00:00:00 2001 From: Volker Mische Date: Fri, 11 Mar 2022 17:47:17 +0100 Subject: [PATCH 3/4] Document helper function --- src/fields.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fields.rs b/src/fields.rs index 9e01217..8e11528 100644 --- a/src/fields.rs +++ b/src/fields.rs @@ -7,6 +7,7 @@ mod fq; pub use fp::*; pub use fq::*; +/// Converts 64-bit little-endian limbs to 32-bit little endian limbs. #[cfg(feature = "gpu")] fn u64_to_u32(limbs: &[u64]) -> alloc::vec::Vec { limbs From 678cd40419d537eca51541d113601cfce232d727 Mon Sep 17 00:00:00 2001 From: Volker Mische Date: Tue, 15 Mar 2022 16:25:18 +0100 Subject: [PATCH 4/4] chore: fix source formatting --- src/fields.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/fields.rs b/src/fields.rs index 8e11528..ccad57a 100644 --- a/src/fields.rs +++ b/src/fields.rs @@ -12,6 +12,10 @@ pub use fq::*; fn u64_to_u32(limbs: &[u64]) -> alloc::vec::Vec { limbs .iter() - .flat_map(|limb| Some((limb & 0xFFFF_FFFF) as u32).into_iter().chain(Some((limb >> 32) as u32))) + .flat_map(|limb| { + Some((limb & 0xFFFF_FFFF) as u32) + .into_iter() + .chain(Some((limb >> 32) as u32)) + }) .collect() }