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::{emulated_fp::EmulatedFpVar, 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<TargetF: PrimeField, BaseField: PrimeField, R: RngCore>(
 30    cs: ConstraintSystemRef<BaseField>,
 31    rng: &mut R,
 32) -> (usize, usize) {
 33    let a_native = TargetF::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 _ = EmulatedFpVar::<TargetF, BaseField>::new_witness(ns!(cs, "alloc a"), || Ok(a_native))
 40        .unwrap();
 41
 42    let constraints_after = cs.num_constraints();
 43    let nonzeros_after = get_density(&cs);
 44
 45    return (
 46        constraints_after - constraints_before,
 47        nonzeros_after - nonzeros_before,
 48    );
 49}
 50
 51fn addition<TargetF: PrimeField, BaseField: PrimeField, R: RngCore>(
 52    cs: ConstraintSystemRef<BaseField>,
 53    rng: &mut R,
 54) -> (usize, usize) {
 55    let a_native = TargetF::rand(rng);
 56    let a = EmulatedFpVar::<TargetF, BaseField>::new_witness(ns!(cs, "alloc a"), || Ok(a_native))
 57        .unwrap();
 58
 59    let b_native = TargetF::rand(rng);
 60    let b = EmulatedFpVar::<TargetF, BaseField>::new_witness(ns!(cs, "alloc b"), || Ok(b_native))
 61        .unwrap();
 62
 63    let constraints_before = cs.num_constraints();
 64    let nonzeros_before = get_density(&cs);
 65
 66    let _ = &a + &b;
 67
 68    let constraints_after = cs.num_constraints();
 69    let nonzeros_after = get_density(&cs);
 70
 71    return (
 72        constraints_after - constraints_before,
 73        nonzeros_after - nonzeros_before,
 74    );
 75}
 76
 77fn equality<TargetF: PrimeField, BaseField: PrimeField, R: RngCore>(
 78    cs: ConstraintSystemRef<BaseField>,
 79    rng: &mut R,
 80) -> (usize, usize) {
 81    let a_native = TargetF::rand(rng);
 82    let a1 = EmulatedFpVar::<TargetF, BaseField>::new_witness(ns!(cs, "alloc a1"), || Ok(a_native))
 83        .unwrap();
 84    let a2 = EmulatedFpVar::<TargetF, BaseField>::new_witness(ns!(cs, "alloc a2"), || Ok(a_native))
 85        .unwrap();
 86
 87    let constraints_before = cs.num_constraints();
 88    let nonzeros_before = get_density(&cs);
 89
 90    a1.enforce_equal(&a2).unwrap();
 91
 92    let constraints_after = cs.num_constraints();
 93    let nonzeros_after = get_density(&cs);
 94
 95    return (
 96        constraints_after - constraints_before,
 97        nonzeros_after - nonzeros_before,
 98    );
 99}
100
101fn multiplication<TargetF: PrimeField, BaseField: PrimeField, R: RngCore>(
102    cs: ConstraintSystemRef<BaseField>,
103    rng: &mut R,
104) -> (usize, usize) {
105    let a_native = TargetF::rand(rng);
106    let a = EmulatedFpVar::<TargetF, BaseField>::new_witness(ns!(cs, "initial a"), || Ok(a_native))
107        .unwrap();
108
109    let b_native = TargetF::rand(rng);
110    let b = EmulatedFpVar::<TargetF, BaseField>::new_witness(ns!(cs, "initial b"), || Ok(b_native))
111        .unwrap();
112
113    let constraints_before = cs.num_constraints();
114    let nonzeros_before = get_density(&cs);
115
116    let _ = &a * &b;
117
118    let constraints_after = cs.num_constraints();
119    let nonzeros_after = get_density(&cs);
120
121    return (
122        constraints_after - constraints_before,
123        nonzeros_after - nonzeros_before,
124    );
125}
126
127fn inverse<TargetF: PrimeField, BaseField: PrimeField, R: RngCore>(
128    cs: ConstraintSystemRef<BaseField>,
129    rng: &mut R,
130) -> (usize, usize) {
131    let num_native = TargetF::rand(rng);
132    let num = EmulatedFpVar::<TargetF, BaseField>::new_witness(ns!(cs, "alloc"), || Ok(num_native))
133        .unwrap();
134
135    let constraints_before = cs.num_constraints();
136    let nonzeros_before = get_density(&cs);
137
138    let _ = num.inverse().unwrap();
139
140    let constraints_after = cs.num_constraints();
141    let nonzeros_after = get_density(&cs);
142
143    return (
144        constraints_after - constraints_before,
145        nonzeros_after - nonzeros_before,
146    );
147}
148
149macro_rules! nonnative_bench_individual {
150    ($bench_method:ident, $bench_name:ident, $bench_target_field:ty, $bench_base_field:ty) => {
151        let rng = &mut ark_std::test_rng();
152        let mut num_constraints = 0;
153        let mut num_nonzeros = 0;
154        for _ in 0..NUM_REPETITIONS {
155            let cs_sys = ConstraintSystem::<$bench_base_field>::new();
156            let cs = ConstraintSystemRef::new(cs_sys);
157            cs.set_optimization_goal(OptimizationGoal::Constraints);
158
159            let (cur_constraints, cur_nonzeros) =
160                $bench_method::<$bench_target_field, $bench_base_field, _>(cs.clone(), rng);
161
162            num_constraints += cur_constraints;
163            num_nonzeros += cur_nonzeros;
164
165            assert!(cs.is_satisfied().unwrap());
166        }
167        let average_constraints = num_constraints / NUM_REPETITIONS;
168        let average_nonzeros = num_nonzeros / NUM_REPETITIONS;
169        println!(
170            "{} takes: {} constraints, {} non-zeros",
171            stringify!($bench_method),
172            average_constraints,
173            average_nonzeros,
174        );
175    };
176}
177
178macro_rules! nonnative_bench {
179    ($bench_name:ident, $bench_target_field:ty, $bench_base_field:ty) => {
180        println!(
181            "For {} to simulate {}",
182            stringify!($bench_base_field),
183            stringify!($bench_target_field),
184        );
185        nonnative_bench_individual!(
186            allocation,
187            $bench_name,
188            $bench_target_field,
189            $bench_base_field
190        );
191        nonnative_bench_individual!(
192            addition,
193            $bench_name,
194            $bench_target_field,
195            $bench_base_field
196        );
197        nonnative_bench_individual!(
198            multiplication,
199            $bench_name,
200            $bench_target_field,
201            $bench_base_field
202        );
203        nonnative_bench_individual!(
204            equality,
205            $bench_name,
206            $bench_target_field,
207            $bench_base_field
208        );
209        nonnative_bench_individual!(inverse, $bench_name, $bench_target_field, $bench_base_field);
210        println!("----------------------")
211    };
212}
213
214fn main() {
215    nonnative_bench!(MNT46Small, ark_mnt4_298::Fr, ark_mnt6_298::Fr);
216    nonnative_bench!(MNT64Small, ark_mnt6_298::Fr, ark_mnt4_298::Fr);
217    nonnative_bench!(MNT46Big, ark_mnt4_753::Fr, ark_mnt6_753::Fr);
218    nonnative_bench!(MNT64Big, ark_mnt6_753::Fr, ark_mnt4_753::Fr);
219    nonnative_bench!(BLS12MNT4Small, ark_bls12_381::Fr, ark_mnt4_298::Fr);
220    nonnative_bench!(BLS12, ark_bls12_381::Fq, ark_bls12_381::Fr);
221    nonnative_bench!(MNT6BigMNT4Small, ark_mnt6_753::Fr, ark_mnt4_298::Fr);
222}