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