Skip to content

Commit

Permalink
refactor testing
Browse files Browse the repository at this point in the history
  • Loading branch information
KimiWu123 committed Sep 23, 2024
1 parent 4801231 commit 712d629
Showing 1 changed file with 25 additions and 78 deletions.
103 changes: 25 additions & 78 deletions ceno_zkvm/src/instructions/riscv/divu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl<E: ExtensionField, I: RIVInstruction> Instruction<E> for ArithInstruction<E
let is_zero = divisor.is_zero(circuit_builder)?;
outcome.limbs.iter().for_each(|&limb| {
// conditional_outcome is -1 if divisor is zero
// => is_zero * (-1) + (1 - is_zero) * outcome = outcome - is_zero*outcome - is_zero*(-1)
// => is_zero * (-1) + (1 - is_zero) * outcome = outcome - is_zero * outcome - is_zero * (-1)
let conditional_outcome = limb.expr()
+ is_zero.is_zero.expr() * Expression::from(u16::MAX as usize)
- is_zero.is_zero.expr() * limb.expr();
Expand Down Expand Up @@ -149,23 +149,28 @@ impl<E: ExtensionField, I: RIVInstruction> Instruction<E> for ArithInstruction<E
mod test {

mod divu {
use ceno_emul::{Change, StepRecord};
use std::u32;

use ceno_emul::{Change, StepRecord, Word};
use goldilocks::GoldilocksExt2;
use itertools::Itertools;
use multilinear_extensions::mle::IntoMLEs;
use rand::Rng;

use crate::{
circuit_builder::{CircuitBuilder, ConstraintSystem},
instructions::{riscv::divu::DivUInstruction, Instruction},
scheme::mock_prover::{MockProver, MOCK_PC_DIVU, MOCK_PROGRAM},
};

#[test]
fn test_opcode_divu() {
fn verify(name: &'static str, dividend: Word, divisor: Word, outcome: Word) {
let mut cs = ConstraintSystem::<GoldilocksExt2>::new(|| "riscv");
let mut cb = CircuitBuilder::new(&mut cs);
let config = cb
.namespace(|| "divu", |cb| Ok(DivUInstruction::construct_circuit(cb)))
.namespace(
|| format!("divu_{name}"),
|cb| Ok(DivUInstruction::construct_circuit(cb)),
)
.unwrap()
.unwrap();

Expand All @@ -176,10 +181,10 @@ mod test {
vec![StepRecord::new_r_instruction(
3,
MOCK_PC_DIVU,
MOCK_PROGRAM[3],
10,
2,
Change::new(0, 5),
MOCK_PROGRAM[6],
dividend,
divisor,
Change::new(0, outcome),
0,
)],
)
Expand All @@ -196,79 +201,21 @@ mod test {
None,
);
}

#[test]
fn test_opcode_divu_remainder() {
let mut cs = ConstraintSystem::<GoldilocksExt2>::new(|| "riscv");
let mut cb = CircuitBuilder::new(&mut cs);
let config = cb
.namespace(|| "divu", |cb| Ok(DivUInstruction::construct_circuit(cb)))
.unwrap()
.unwrap();

// values assignment
let (raw_witin, _) = DivUInstruction::assign_instances(
&config,
cb.cs.num_witin as usize,
vec![StepRecord::new_r_instruction(
3,
MOCK_PC_DIVU,
MOCK_PROGRAM[3],
11,
2,
Change::new(0, 5),
0,
)],
)
.unwrap();

MockProver::assert_satisfied(
&mut cb,
&raw_witin
.de_interleaving()
.into_mles()
.into_iter()
.map(|v| v.into())
.collect_vec(),
None,
);
fn test_opcode_divu() {
verify("basic", 10, 2, 5);
verify("dividend > divisor", 10, 11, 0);
verify("remainder", 11, 2, 5);
verify("u32::MAX", u32::MAX, u32::MAX, 1);
verify("div by zero", 10, 0, u32::MAX);
}

#[test]
fn test_opcode_divu_by_zero() {
let mut cs = ConstraintSystem::<GoldilocksExt2>::new(|| "riscv");
let mut cb = CircuitBuilder::new(&mut cs);
let config = cb
.namespace(|| "divu", |cb| Ok(DivUInstruction::construct_circuit(cb)))
.unwrap()
.unwrap();

// values assignment
let (raw_witin, _) = DivUInstruction::assign_instances(
&config,
cb.cs.num_witin as usize,
vec![StepRecord::new_r_instruction(
3,
MOCK_PC_DIVU,
MOCK_PROGRAM[3],
11,
0,
Change::new(0, u32::MAX),
0,
)],
)
.unwrap();

MockProver::assert_satisfied(
&mut cb,
&raw_witin
.de_interleaving()
.into_mles()
.into_iter()
.map(|v| v.into())
.collect_vec(),
None,
);
fn test_opcode_divu_random() {
let mut rng = rand::thread_rng();
let a: u32 = rng.gen();
let b: u32 = rng.gen_range(1..u32::MAX);
verify("random", a, b, a / b);
}
}
}

0 comments on commit 712d629

Please sign in to comment.