Skip to content

Commit

Permalink
feat: pasta gpu support
Browse files Browse the repository at this point in the history
  • Loading branch information
DrPeterVanNostrand committed Mar 16, 2022
1 parent 6c28dd0 commit 7edf855
Show file tree
Hide file tree
Showing 39 changed files with 692 additions and 709 deletions.
2 changes: 1 addition & 1 deletion fil-proofs-param/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ indicatif = "0.15.0"
group = "0.11.0"
dialoguer = "0.8.0"
clap = "2.33.3"
blstrs = "0.4.0"
blstrs = { version = "0.4.0", features = ["gpu"] }

[dependencies.reqwest]
version = "0.10"
Expand Down
2 changes: 1 addition & 1 deletion fil-proofs-tooling/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ fdlimit = "0.2.0"
dialoguer = "0.8.0"
structopt = "0.3.12"
humansize = "1.1.0"
blstrs = "0.4.0"
blstrs = { version = "0.4.0", features = ["gpu"] }

[features]
default = ["opencl", "measurements"]
Expand Down
10 changes: 6 additions & 4 deletions filecoin-hashers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@ readme = "README.md"

[dependencies]
bellperson = "0.18.0"
blstrs = "0.4.0"
blstrs = { version = "0.4.0", features = ["gpu"] }
generic-array = "0.14.4"
merkletree = "0.21.0"
ec-gpu = "0.1.0"
ff = "0.11.0"
anyhow = "1.0.34"
serde = "1.0.117"
rand = "0.8.0"

neptune = { version = "5.1.0", optional = true, features = ["arity2", "arity4", "arity8", "arity11", "arity16", "arity24", "arity36"] }
pasta_curves = "0.3.0"
# neptune = { version = "5.1.0", optional = true, features = ["arity2", "arity4", "arity8", "arity11", "arity16", "arity24", "arity36"] }
# pasta_curves = "0.3.0"
neptune = { git = "https://github.com/filecoin-project/neptune", branch = "fr-as-trait", optional = true, features = ["bls", "pasta", "arity2", "arity4", "arity8", "arity11", "arity16", "arity24", "arity36"] }
pasta_curves = { git = "https://github.com/vmx/pasta_curves", branch = "ec-gpu", features = ["gpu"] }
lazy_static = { version = "1.4.0", optional = true }
blake2s_simd = { version = "0.5.11", optional = true }
sha2 = { version = "0.9.2", optional = true }
Expand Down
25 changes: 0 additions & 25 deletions filecoin-hashers/src/blake2s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,31 +80,6 @@ impl Into<Fq> for Blake2sDomain<Fq> {
}
}

// Currently, these panics serve as a stopgap to prevent accidental conversions of a Pasta field
// domains to/from a BLS12-381 scalar field domain.
impl From<Fr> for Blake2sDomain<Fp> {
fn from(_f: Fr) -> Self {
panic!("cannot convert BLS12-381 scalar into Blake2sDomain<Fp>")
}
}
#[allow(clippy::from_over_into)]
impl Into<Fr> for Blake2sDomain<Fq> {
fn into(self) -> Fr {
panic!("cannot convert Blake2sDomain<Fq> into BLS12-381 scalar");
}
}
impl From<Fr> for Blake2sDomain<Fq> {
fn from(_f: Fr) -> Self {
panic!("cannot convert BLS12-381 scalar into Blake2sDomain<Fq>")
}
}
#[allow(clippy::from_over_into)]
impl Into<Fr> for Blake2sDomain<Fp> {
fn into(self) -> Fr {
panic!("cannot convert Blake2sDomain<Fp> into BLS12-381 scalar");
}
}

impl<F> From<[u8; 32]> for Blake2sDomain<F> {
fn from(bytes: [u8; 32]) -> Self {
Blake2sDomain {
Expand Down
31 changes: 3 additions & 28 deletions filecoin-hashers/src/poseidon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,31 +76,6 @@ impl Into<Fq> for PoseidonDomain<Fq> {
}
}

// Currently, these panics serve as a stopgap to prevent accidental conversions of a Pasta field
// domains to/from a BLS12-381 scalar field domain.
impl From<Fr> for PoseidonDomain<Fp> {
fn from(_f: Fr) -> Self {
panic!("cannot convert BLS12-381 scalar into PoseidonDomain<Fp>")
}
}
#[allow(clippy::from_over_into)]
impl Into<Fr> for PoseidonDomain<Fp> {
fn into(self) -> Fr {
panic!("cannot convert PoseidonDomain<Fp> into BLS12-381 scalar");
}
}
impl From<Fr> for PoseidonDomain<Fq> {
fn from(_f: Fr) -> Self {
panic!("cannot convert BLS12-381 scalar into PoseidonDomain<Fq>")
}
}
#[allow(clippy::from_over_into)]
impl Into<Fr> for PoseidonDomain<Fq> {
fn into(self) -> Fr {
panic!("cannot convert PoseidonDomain<Fq> into BLS12-381 scalar");
}
}

impl<F> From<[u8; 32]> for PoseidonDomain<F> {
fn from(bytes: [u8; 32]) -> Self {
PoseidonDomain {
Expand Down Expand Up @@ -377,7 +352,7 @@ impl HashFunction<PoseidonDomain<Fr>> for PoseidonFunction<Fr> {
Self::hash2_circuit(cs, left, right)
}

fn hash_multi_leaf_circuit<Arity: 'static + PoseidonArity, CS: ConstraintSystem<Fr>>(
fn hash_multi_leaf_circuit<Arity: PoseidonArity<Fr>, CS: ConstraintSystem<Fr>>(
cs: CS,
leaves: &[AllocatedNum<Fr>],
_height: usize,
Expand Down Expand Up @@ -497,7 +472,7 @@ impl HashFunction<PoseidonDomain<Fp>> for PoseidonFunction<Fp> {
unimplemented!("PoseidonFunction<Fp> cannot be used within Groth16 circuits")
}

fn hash_multi_leaf_circuit<Arity: 'static + PoseidonArity, CS: ConstraintSystem<Fr>>(
fn hash_multi_leaf_circuit<Arity: PoseidonArity<Fr>, CS: ConstraintSystem<Fr>>(
_cs: CS,
_leaves: &[AllocatedNum<Fr>],
_height: usize,
Expand Down Expand Up @@ -584,7 +559,7 @@ impl HashFunction<PoseidonDomain<Fq>> for PoseidonFunction<Fq> {
unimplemented!("PoseidonFunction<Fq> cannot be used within Groth16 circuits")
}

fn hash_multi_leaf_circuit<Arity: 'static + PoseidonArity, CS: ConstraintSystem<Fr>>(
fn hash_multi_leaf_circuit<Arity: PoseidonArity<Fr>, CS: ConstraintSystem<Fr>>(
_cs: CS,
_leaves: &[AllocatedNum<Fr>],
_height: usize,
Expand Down
66 changes: 14 additions & 52 deletions filecoin-hashers/src/poseidon_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,63 +76,25 @@ lazy_static! {
pub struct FieldArity<F, A>(PhantomData<(F, A)>)
where
F: PrimeField,
A: Arity<F>;
A: PoseidonArity<F>;

impl<F, A> typemap::Key for FieldArity<F, A>
where
F: PrimeField,
A: Arity<F>,
A: PoseidonArity<F>,
{
type Value = &'static PoseidonConstants<F, A>;
}

pub trait PoseidonArity: Arity<Fr> + Send + Sync + Clone + Debug {
#[allow(non_snake_case)]
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self>;
}

impl PoseidonArity for U0 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
unreachable!("dummy implementation, do not ever call me")
}
}

impl PoseidonArity for U2 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_2
}
}

impl PoseidonArity for U4 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_4
}
}

impl PoseidonArity for U8 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_8
}
}

impl PoseidonArity for U11 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_11
}
}

impl PoseidonArity for U16 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_16
}
}
impl PoseidonArity for U24 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_24
}
}
impl PoseidonArity for U36 {
fn PARAMETERS() -> &'static PoseidonConstants<Fr, Self> {
&*POSEIDON_CONSTANTS_36
}
}
// A marker trait for arities which are in `POSEIDON_CONSTANTS`; we require that 'PoseidonArity<F>`
// implements `Send + Sync` because those traits are required by `lazy_static`.
pub trait PoseidonArity<F: PrimeField>: Arity<F> + Send + Sync + Clone + Debug {}

// We must implement `PoseidonArity<F> for U0` because the `U0` arity is used in compound trees
// (each compound tree arity must implement `PoseidonArity`).
impl<F: PrimeField> PoseidonArity<F> for U0 {}
impl<F: PrimeField> PoseidonArity<F> for U2 {}
impl<F: PrimeField> PoseidonArity<F> for U4 {}
impl<F: PrimeField> PoseidonArity<F> for U8 {}
impl<F: PrimeField> PoseidonArity<F> for U11 {}
impl<F: PrimeField> PoseidonArity<F> for PoseidonMDArity {}
25 changes: 0 additions & 25 deletions filecoin-hashers/src/sha256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,31 +78,6 @@ impl Into<Fq> for Sha256Domain<Fq> {
}
}

// Currently, these panics serve as a stopgap to prevent accidental conversions of a Pasta field
// domains to/from a BLS12-381 scalar field domain.
impl From<Fr> for Sha256Domain<Fp> {
fn from(_f: Fr) -> Self {
panic!("cannot convert BLS12-381 scalar into Sha256Domain<Fp>")
}
}
#[allow(clippy::from_over_into)]
impl Into<Fr> for Sha256Domain<Fp> {
fn into(self) -> Fr {
panic!("cannot convert Sha256Domain<Fp> into BLS12-381 scalar");
}
}
impl From<Fr> for Sha256Domain<Fq> {
fn from(_f: Fr) -> Self {
panic!("cannot convert BLS12-381 scalar into Sha256Domain<Fq>")
}
}
#[allow(clippy::from_over_into)]
impl Into<Fr> for Sha256Domain<Fq> {
fn into(self) -> Fr {
panic!("cannot convert Sha256Domain<Fq> into BLS12-381 scalar");
}
}

impl<F> From<[u8; 32]> for Sha256Domain<F> {
fn from(bytes: [u8; 32]) -> Self {
Sha256Domain {
Expand Down
14 changes: 3 additions & 11 deletions filecoin-hashers/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use bellperson::{
ConstraintSystem, SynthesisError,
};
use blstrs::Scalar as Fr;
use ec_gpu::GpuField;
use ff::{Field, PrimeField};
use merkletree::{
hash::{Algorithm as LightAlgorithm, Hashable as LightHashable},
Expand All @@ -28,15 +29,6 @@ pub trait Domain:
+ Eq
+ Send
+ Sync
// TODO (halo): remove once we have Pasta GPU support.
// Currently the `From<Fr> + Into<Fr>` trait bounds are used as a stopgap to prevent
// Pasta field domains from being used in GPU code, e.g. currently converting a
// `Sha256Domain<Fp>` into an `Fr` panics. Remove theses trait bounds once Pasta fields are
// fully supported in `rust-fil-proofs`, e.g. GPU code.
+ From<Fr>
+ Into<Fr>
// Note that `Self::Field` may be `Fr`, in which case the trait bounds
// `From<Self::Field> + Into<Self::Field>` are redundant.
+ From<Self::Field>
+ Into<Self::Field>
+ From<[u8; 32]>
Expand All @@ -45,7 +37,7 @@ pub trait Domain:
+ Element
+ StdHash
{
type Field: PrimeField;
type Field: PrimeField + GpuField;

#[allow(clippy::wrong_self_convention)]
fn into_bytes(&self) -> Vec<u8> {
Expand Down Expand Up @@ -110,7 +102,7 @@ pub trait HashFunction<T: Domain>: Clone + Debug + Send + Sync + LightAlgorithm<
Self::hash_leaf_bits_circuit(cs, &left_bits, &right_bits, height)
}

fn hash_multi_leaf_circuit<Arity: 'static + PoseidonArity, CS: ConstraintSystem<Fr>>(
fn hash_multi_leaf_circuit<Arity: PoseidonArity<Fr>, CS: ConstraintSystem<Fr>>(
cs: CS,
leaves: &[AllocatedNum<Fr>],
height: usize,
Expand Down
2 changes: 1 addition & 1 deletion filecoin-proofs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ group = "0.11.0"
byte-slice-cast = "1.0.0"
fr32 = { path = "../fr32", version = "^4.0.0", default-features = false }
once_cell = "1.8.0"
blstrs = "0.4.0"
blstrs = { version = "0.4.0", features = ["gpu"] }

[dev-dependencies]
criterion = "0.3"
Expand Down
17 changes: 8 additions & 9 deletions filecoin-proofs/src/api/util.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
use std::mem::size_of;

use anyhow::{Context, Result};
use blstrs::Scalar as Fr;
use ff::PrimeField;
use filecoin_hashers::{Domain, Hasher};
use fr32::{bytes_into_fr, fr_into_bytes};
use merkletree::merkle::{get_merkle_tree_leafs, get_merkle_tree_len};
use storage_proofs_core::merkle::{get_base_tree_count, MerkleTreeTrait};
use typenum::Unsigned;

use crate::types::{Commitment, SectorSize};

pub fn as_safe_commitment<H: Domain, T: AsRef<str>>(
pub fn as_safe_commitment<D: Domain, T: AsRef<str>>(
comm: &[u8; 32],
commitment_name: T,
) -> Result<H> {
bytes_into_fr(comm)
) -> Result<D> {
let mut repr = <D::Field as PrimeField>::Repr::default();
repr.as_mut().copy_from_slice(comm);
D::Field::from_repr_vartime(repr)
.map(Into::into)
.with_context(|| format!("Invalid commitment ({})", commitment_name.as_ref(),))
}

pub fn commitment_from_fr(fr: Fr) -> Commitment {
pub fn commitment_from_fr<F: PrimeField>(fr: F) -> Commitment {
let mut commitment = [0; 32];
for (i, b) in fr_into_bytes(&fr).iter().enumerate() {
commitment[i] = *b;
}
commitment.copy_from_slice(fr.to_repr().as_ref());
commitment
}

Expand Down
5 changes: 3 additions & 2 deletions fr32/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ byte-slice-cast = "1.0.0"
byteorder = "1"
ff = "0.11.0"
thiserror = "1.0.6"
blstrs = "0.4.0"
blstrs = { version = "0.4.0", features = ["gpu"] }

[dev-dependencies]
bitvec = "0.17"
criterion = "0.3"
itertools = "0.9"
pasta_curves = "0.3.0"
# pasta_curves = "0.3.0"
pasta_curves = { git = "https://github.com/vmx/pasta_curves", branch = "ec-gpu", features = ["gpu"] }
pretty_assertions = "0.6.1"
rand = "0.8"
rand_xorshift = "0.3"
Expand Down
8 changes: 5 additions & 3 deletions storage-proofs-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,15 @@ hex = "0.4.0"
generic-array = "0.14.4"
anyhow = "1.0.23"
thiserror = "1.0.6"
neptune = { version = "5.1.0", features = ["arity2", "arity4", "arity8", "arity11", "arity16", "arity24", "arity36"] }
# neptune = { version = "5.1.0", features = ["arity2", "arity4", "arity8", "arity11", "arity16", "arity24", "arity36"] }
neptune = { git = "https://github.com/filecoin-project/neptune", branch = "wip-fr-as-trait", features = ["bls", "pasta", "arity2", "arity4", "arity8", "arity11", "arity16", "arity24", "arity36"] }
cpu-time = { version = "1.0", optional = true }
gperftools = { version = "0.2", optional = true }
num_cpus = "1.10.1"
semver = "0.11.0"
fr32 = { path = "../fr32", version = "^4.0.0"}
pairing = "0.21"
blstrs = "0.4.0"
blstrs = { version = "0.4.0", features = ["gpu"] }

[dev-dependencies]
proptest = "0.10"
Expand All @@ -56,7 +57,8 @@ rand_xorshift = "0.3.0"
pretty_assertions = "0.6.1"
sha2raw = { path = "../sha2raw", version = "^6.0.0"}
filecoin-hashers = { path = "../filecoin-hashers", version = "^6.0.0", default-features = false, features = ["blake2s", "sha256", "poseidon"] }
pasta_curves = "0.3.0"
# pasta_curves = "0.3.0"
pasta_curves = { git = "https://github.com/vmx/pasta_curves", branch = "ec-gpu", features = ["gpu"] }

[features]
default = ["opencl"]
Expand Down
Loading

0 comments on commit 7edf855

Please sign in to comment.