arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
ark-r1cs-std/benches/bench.rs
benches/bench.rsRaw
  1use ark_ff::PrimeField;
  2use ark_r1cs_std::{
  3    alloc::AllocVar,
  4    eq::EqGadget,
  5    fields::{nonnative::NonNativeFieldVar, FieldVar},
  6};
  7use ark_relations::{
  8    ns,
  9    r1cs::{ConstraintSystem, ConstraintSystemRef, OptimizationGoal},
 10};
 11use ark_std::rand::RngCore;
 12
 13const NUM_REPETITIONS: usize = 1;
 14
 15fn get_density<BaseField: PrimeField>(cs: &ConstraintSystemRef<BaseField>) -> usize {
 16    match cs {
 17        ConstraintSystemRef::None => panic!("Constraint system is none."),
 18        ConstraintSystemRef::CS(r) => {
 19            let mut cs_bak = r.borrow().clone();
 20
 21            cs_bak.finalize();
 22            let matrices = cs_bak.to_matrices().unwrap();
 23
 24            matrices.a_num_non_zero + matrices.b_num_non_zero + matrices.c_num_non_zero
 25        },
 26    }
 27}
 28
 29fn allocation<TargetField: PrimeField, BaseField: PrimeField, R: RngCore>(
 30    cs: ConstraintSystemRef<BaseField>,
 31    rng: &mut R,
 32) -> (usize, usize) {
 33    let a_native = TargetField::rand(rng);
 34
 35    let constraints_before = cs.num_constraints();
 36    let nonzeros_before = get_density(&cs);
 37
 38    // There will be a check that ensures it has the reasonable number of bits
 39    let _ = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "alloc a"), || {
 40        Ok(a_native)
 41    })
 42    .unwrap();
 43
 44    let constraints_after = cs.num_constraints();
 45    let nonzeros_after = get_density(&cs);
 46
 47    return (
 48        constraints_after - constraints_before,
 49        nonzeros_after - nonzeros_before,
 50    );
 51}
 52
 53fn addition<TargetField: PrimeField, BaseField: PrimeField, R: RngCore>(
 54    cs: ConstraintSystemRef<BaseField>,
 55    rng: &mut R,
 56) -> (usize, usize) {
 57    let a_native = TargetField::rand(rng);
 58    let a = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "alloc a"), || {
 59        Ok(a_native)
 60    })
 61    .unwrap();
 62
 63    let b_native = TargetField::rand(rng);
 64    let b = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "alloc b"), || {
 65        Ok(b_native)
 66    })
 67    .unwrap();
 68
 69    let constraints_before = cs.num_constraints();
 70    let nonzeros_before = get_density(&cs);
 71
 72    let _ = &a + &b;
 73
 74    let constraints_after = cs.num_constraints();
 75    let nonzeros_after = get_density(&cs);
 76
 77    return (
 78        constraints_after - constraints_before,
 79        nonzeros_after - nonzeros_before,
 80    );
 81}
 82
 83fn equality<TargetField: PrimeField, BaseField: PrimeField, R: RngCore>(
 84    cs: ConstraintSystemRef<BaseField>,
 85    rng: &mut R,
 86) -> (usize, usize) {
 87    let a_native = TargetField::rand(rng);
 88    let a1 = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "alloc a1"), || {
 89        Ok(a_native)
 90    })
 91    .unwrap();
 92    let a2 = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "alloc a2"), || {
 93        Ok(a_native)
 94    })
 95    .unwrap();
 96
 97    let constraints_before = cs.num_constraints();
 98    let nonzeros_before = get_density(&cs);
 99
100    a1.enforce_equal(&a2).unwrap();
101
102    let constraints_after = cs.num_constraints();
103    let nonzeros_after = get_density(&cs);
104
105    return (
106        constraints_after - constraints_before,
107        nonzeros_after - nonzeros_before,
108    );
109}
110
111fn multiplication<TargetField: PrimeField, BaseField: PrimeField, R: RngCore>(
112    cs: ConstraintSystemRef<BaseField>,
113    rng: &mut R,
114) -> (usize, usize) {
115    let a_native = TargetField::rand(rng);
116    let a = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "initial a"), || {
117        Ok(a_native)
118    })
119    .unwrap();
120
121    let b_native = TargetField::rand(rng);
122    let b = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "initial b"), || {
123        Ok(b_native)
124    })
125    .unwrap();
126
127    let constraints_before = cs.num_constraints();
128    let nonzeros_before = get_density(&cs);
129
130    let _ = &a * &b;
131
132    let constraints_after = cs.num_constraints();
133    let nonzeros_after = get_density(&cs);
134
135    return (
136        constraints_after - constraints_before,
137        nonzeros_after - nonzeros_before,
138    );
139}
140
141fn inverse<TargetField: PrimeField, BaseField: PrimeField, R: RngCore>(
142    cs: ConstraintSystemRef<BaseField>,
143    rng: &mut R,
144) -> (usize, usize) {
145    let num_native = TargetField::rand(rng);
146    let num = NonNativeFieldVar::<TargetField, BaseField>::new_witness(ns!(cs, "alloc"), || {
147        Ok(num_native)
148    })
149    .unwrap();
150
151    let constraints_before = cs.num_constraints();
152    let nonzeros_before = get_density(&cs);
153
154    let _ = num.inverse().unwrap();
155
156    let constraints_after = cs.num_constraints();
157    let nonzeros_after = get_density(&cs);
158
159    return (
160        constraints_after - constraints_before,
161        nonzeros_after - nonzeros_before,
162    );
163}
164
165macro_rules! nonnative_bench_individual {
166    ($bench_method:ident, $bench_name:ident, $bench_target_field:ty, $bench_base_field:ty) => {
167        let rng = &mut ark_std::test_rng();
168        let mut num_constraints = 0;
169        let mut num_nonzeros = 0;
170        for _ in 0..NUM_REPETITIONS {
171            let cs_sys = ConstraintSystem::<$bench_base_field>::new();
172            let cs = ConstraintSystemRef::new(cs_sys);
173            cs.set_optimization_goal(OptimizationGoal::Constraints);
174
175            let (cur_constraints, cur_nonzeros) =
176                $bench_method::<$bench_target_field, $bench_base_field, _>(cs.clone(), rng);
177
178            num_constraints += cur_constraints;
179            num_nonzeros += cur_nonzeros;
180
181            assert!(cs.is_satisfied().unwrap());
182        }
183        let average_constraints = num_constraints / NUM_REPETITIONS;
184        let average_nonzeros = num_nonzeros / NUM_REPETITIONS;
185        println!(
186            "{} takes: {} constraints, {} non-zeros",
187            stringify!($bench_method),
188            average_constraints,
189            average_nonzeros,
190        );
191    };
192}
193
194macro_rules! nonnative_bench {
195    ($bench_name:ident, $bench_target_field:ty, $bench_base_field:ty) => {
196        println!(
197            "For {} to simulate {}",
198            stringify!($bench_base_field),
199            stringify!($bench_target_field),
200        );
201        nonnative_bench_individual!(
202            allocation,
203            $bench_name,
204            $bench_target_field,
205            $bench_base_field
206        );
207        nonnative_bench_individual!(
208            addition,
209            $bench_name,
210            $bench_target_field,
211            $bench_base_field
212        );
213        nonnative_bench_individual!(
214            multiplication,
215            $bench_name,
216            $bench_target_field,
217            $bench_base_field
218        );
219        nonnative_bench_individual!(
220            equality,
221            $bench_name,
222            $bench_target_field,
223            $bench_base_field
224        );
225        nonnative_bench_individual!(inverse, $bench_name, $bench_target_field, $bench_base_field);
226        println!("----------------------")
227    };
228}
229
230fn main() {
231    nonnative_bench!(MNT46Small, ark_mnt4_298::Fr, ark_mnt6_298::Fr);
232    nonnative_bench!(MNT64Small, ark_mnt6_298::Fr, ark_mnt4_298::Fr);
233    nonnative_bench!(MNT46Big, ark_mnt4_753::Fr, ark_mnt6_753::Fr);
234    nonnative_bench!(MNT64Big, ark_mnt6_753::Fr, ark_mnt4_753::Fr);
235    nonnative_bench!(BLS12MNT4Small, ark_bls12_381::Fr, ark_mnt4_298::Fr);
236    nonnative_bench!(BLS12, ark_bls12_381::Fq, ark_bls12_381::Fr);
237    nonnative_bench!(MNT6BigMNT4Small, ark_mnt6_753::Fr, ark_mnt4_298::Fr);
238}