Skip to content

Commit

Permalink
feat(fflont): device based trace and permutations construction
Browse files Browse the repository at this point in the history
  • Loading branch information
saitima committed Oct 22, 2024
1 parent dbdd7c6 commit 3f6fe51
Show file tree
Hide file tree
Showing 9 changed files with 439 additions and 583 deletions.
18 changes: 2 additions & 16 deletions crates/fflonk/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,7 @@ pub fn init_compact_crs(
) -> Crs<CompactBn256, CrsForMonomialForm> {
assert!(domain_size <= 1 << fflonk::L1_VERIFIER_DOMAIN_SIZE_LOG);
let num_points = MAX_COMBINED_DEGREE_FACTOR * domain_size;
let mon_crs = if let Ok(socket_path) = std::env::var("TEST_SOCK_FILE") {
read_crs_over_socket(&socket_path).unwrap()
} else if let Ok(crs_file_path) = std::env::var("COMPACT_CRS_FILE") {
let mon_crs = if let Ok(crs_file_path) = std::env::var("COMPACT_CRS_FILE") {
println!("using crs file at {crs_file_path}");
let crs_file =
std::fs::File::open(&crs_file_path).expect(&format!("crs file at {}", crs_file_path));
Expand All @@ -303,21 +301,9 @@ pub fn init_compact_crs(

mon_crs
} else {
println!("Using dummy CRS");
Crs::<CompactBn256, CrsForMonomialForm>::non_power_of_two_crs_42(num_points, &worker)
};

mon_crs
}

// This is convenient for faster testing
fn read_crs_over_socket(
socket_path: &str,
) -> std::io::Result<Crs<CompactBn256, CrsForMonomialForm>> {
let mut socket = std::os::unix::net::UnixStream::connect(socket_path)?;
let start = std::time::Instant::now();
std::io::Write::write_all(&mut socket, &[1])?;
let crs = Crs::<CompactBn256, CrsForMonomialForm>::read(&socket)?;
println!("Loading CRS takes {} s", start.elapsed().as_secs());

Ok(crs)
}
34 changes: 12 additions & 22 deletions crates/fflonk/src/convenience.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use bellman::{
},
commitments::transcript::keccak_transcript::RollingKeccakTranscript,
},
worker::Worker,
};
use fflonk::{
FflonkAssembly, FflonkSnarkVerifierCircuit, FflonkSnarkVerifierCircuitProof,
Expand All @@ -20,7 +19,6 @@ use super::*;

pub fn gpu_prove_fflonk_snark_verifier_circuit_single_shot(
circuit: &FflonkSnarkVerifierCircuit,
worker: &Worker,
) -> (
FflonkSnarkVerifierCircuitProof,
FflonkSnarkVerifierCircuitVK,
Expand All @@ -29,20 +27,22 @@ pub fn gpu_prove_fflonk_snark_verifier_circuit_single_shot(
circuit.synthesize(&mut assembly).expect("must work");
assert!(assembly.is_satisfied());
let raw_trace_len = assembly.n();
assembly.finalize();
let domain_size = assembly.n() + 1;
assert!(domain_size.is_power_of_two());
assert!(domain_size <= 1 << L1_VERIFIER_DOMAIN_SIZE_LOG);

let domain_size = (raw_trace_len + 1).next_power_of_two();
let _context = DeviceContextWithSingleDevice::init(domain_size)
.expect("Couldn't create fflonk GPU Context");

let setup =
FflonkDeviceSetup::<_, FflonkSnarkVerifierCircuit, GlobalHost>::create_setup_from_assembly_on_device(
&assembly, raw_trace_len, &worker,
&assembly,
)
.unwrap();
let vk = setup.get_verification_key();

assembly.finalize();
assert_eq!(assembly.n(), vk.n);
assert_eq!(assembly.n() + 1, domain_size);
assert!(domain_size <= 1 << L1_VERIFIER_DOMAIN_SIZE_LOG);

let start = std::time::Instant::now();
let proof = create_proof::<
_,
Expand All @@ -51,7 +51,7 @@ pub fn gpu_prove_fflonk_snark_verifier_circuit_single_shot(
RollingKeccakTranscript<_>,
CombinedMonomialDeviceStorage<Fr>,
_,
>(&assembly, &setup, &worker)
>(&assembly, &setup, raw_trace_len)
.unwrap();
println!("proof generation takes {} ms", start.elapsed().as_millis());

Expand All @@ -65,14 +65,14 @@ pub fn gpu_prove_fflonk_snark_verifier_circuit_with_precomputation(
circuit: &FflonkSnarkVerifierCircuit,
setup: &FflonkSnarkVerifierCircuitDeviceSetup,
vk: &FflonkSnarkVerifierCircuitVK,
worker: &Worker,
) -> FflonkSnarkVerifierCircuitProof {
println!("Synthesizing for fflonk proving");
let mut proving_assembly = FflonkAssembly::<Bn256, SynthesisModeProve, GlobalHost>::new();
circuit
.synthesize(&mut proving_assembly)
.expect("must work");
assert!(proving_assembly.is_satisfied());
let raw_trace_len = proving_assembly.n();
proving_assembly.finalize();
let domain_size = proving_assembly.n() + 1;
assert!(domain_size.is_power_of_two());
Expand All @@ -86,7 +86,7 @@ pub fn gpu_prove_fflonk_snark_verifier_circuit_with_precomputation(
RollingKeccakTranscript<_>,
CombinedMonomialDeviceStorage<Fr>,
_,
>(&proving_assembly, &setup, &worker)
>(&proving_assembly, setup, raw_trace_len)
.unwrap();
println!("proof generation takes {} ms", start.elapsed().as_millis());

Expand All @@ -98,24 +98,14 @@ pub fn gpu_prove_fflonk_snark_verifier_circuit_with_precomputation(

pub fn precompute_and_save_setup_and_vk_for_fflonk_snark_circuit(
circuit: &FflonkSnarkVerifierCircuit,
worker: &Worker,
path: &str,
) {
let compression_wrapper_mode = circuit.wrapper_function.numeric_circuit_type();
println!("Compression mode: {compression_wrapper_mode}");
println!("Synthesizing for fflonk setup");
let mut setup_assembly = FflonkAssembly::<Bn256, SynthesisModeGenerateSetup>::new();
circuit.synthesize(&mut setup_assembly).expect("must work");
assert!(setup_assembly.is_satisfied());
setup_assembly.finalize();

let domain_size = setup_assembly.n() + 1;
assert!(domain_size.is_power_of_two());
assert!(domain_size <= 1 << L1_VERIFIER_DOMAIN_SIZE_LOG);

println!("Generating fflonk setup data on the device");
let device_setup =
FflonkSnarkVerifierCircuitDeviceSetup::create_setup_on_device(&circuit, &worker).unwrap();
FflonkSnarkVerifierCircuitDeviceSetup::create_setup_on_device(&circuit).unwrap();
let setup_file_path = format!("{}/final_snark_device_setup.bin", path);
println!("Saving setup into file {setup_file_path}");
let device_setup_file = std::fs::File::create(&setup_file_path).unwrap();
Expand Down
10 changes: 7 additions & 3 deletions crates/fflonk/src/dbuffer/dslice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,15 @@ impl<T> DSlice<T> {
}

pub fn to_vec(&self, stream: bc_stream) -> CudaResult<Vec<T>> {
self.to_vec_in_on::<std::alloc::Global>(stream)
self.to_vec_in(stream, std::alloc::Global)
}

pub fn to_vec_in_on<A: HostAllocator>(&self, stream: bc_stream) -> CudaResult<Vec<T, A>> {
let mut dst: Vec<_, A> = Vec::with_capacity_in(self.len(), A::default());
pub fn to_vec_in<A: HostAllocator>(
&self,
stream: bc_stream,
alloc: A,
) -> CudaResult<Vec<T, A>> {
let mut dst: Vec<_, A> = Vec::with_capacity_in(self.len(), alloc);
unsafe { dst.set_len(self.len()) };
super::mem::d2h_on(self, &mut dst, stream)?;

Expand Down
Loading

0 comments on commit 3f6fe51

Please sign in to comment.