Skip to content

Commit

Permalink
better ccc log (#960)
Browse files Browse the repository at this point in the history
* better ccc log

* fix

* fix

* fix
  • Loading branch information
lispc authored Sep 19, 2023
1 parent 2723b82 commit 25f8bde
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 69 deletions.
109 changes: 82 additions & 27 deletions zkevm-circuits/src/evm_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,13 @@ impl<F: Field> EvmCircuit<F> {
}
}

// the diff is from the num of valid opcodes: self-destruct?
#[cfg(not(feature = "scroll"))]
const FIXED_TABLE_ROWS_NO_BITWISE: usize = 3647;
#[cfg(feature = "scroll")]
const FIXED_TABLE_ROWS_NO_BITWISE: usize = 3646;
const FIXED_TABLE_ROWS: usize = FIXED_TABLE_ROWS_NO_BITWISE + 3 * 65536;

impl<F: Field> SubCircuit<F> for EvmCircuit<F> {
type Config = EvmCircuitConfig<F>;

Expand All @@ -300,20 +307,18 @@ impl<F: Field> SubCircuit<F> for EvmCircuit<F> {
fn min_num_rows_block(block: &witness::Block<F>) -> (usize, usize) {
let num_rows_required_for_execution_steps: usize =
Self::get_num_rows_required_no_padding(block);
let num_rows_required_for_fixed_table: usize = detect_fixed_table_tags(block)
.iter()
.map(|tag| tag.build::<F>().count())
.sum();
(
num_rows_required_for_execution_steps,
std::cmp::max(
block.circuits_params.max_evm_rows,
std::cmp::max(
num_rows_required_for_fixed_table,
num_rows_required_for_execution_steps,
),
),
)
let mut total_rows = num_rows_required_for_execution_steps;
total_rows = total_rows.max(block.circuits_params.max_evm_rows);

if total_rows <= FIXED_TABLE_ROWS {
// for many test cases, there is no need for bitwise table.
// So using `detect_fixed_table_tags` can greatly improve CI time.
let num_rows_required_for_fixed_table =
get_fixed_table_row_num(need_bitwise_lookup(block));
total_rows = total_rows.max(num_rows_required_for_fixed_table)
}

(num_rows_required_for_execution_steps, total_rows)
}

/// Make the assignments to the EvmCircuit
Expand All @@ -334,9 +339,16 @@ impl<F: Field> SubCircuit<F> for EvmCircuit<F> {
}
}

/// create fixed_table_tags needed given witness block
pub(crate) fn detect_fixed_table_tags<F: Field>(block: &Block<F>) -> Vec<FixedTableTag> {
let need_bitwise_lookup = block.txs.iter().any(|tx| {
fn get_fixed_table_row_num(need_bitwise_lookup: bool) -> usize {
if need_bitwise_lookup {
FIXED_TABLE_ROWS
} else {
FIXED_TABLE_ROWS_NO_BITWISE
}
}

fn need_bitwise_lookup<F: Field>(block: &Block<F>) -> bool {
block.txs.iter().any(|tx| {
tx.steps.iter().any(|step| {
matches!(
step.opcode,
Expand All @@ -346,15 +358,24 @@ pub(crate) fn detect_fixed_table_tags<F: Field>(block: &Block<F>) -> Vec<FixedTa
| Some(OpcodeId::NOT)
)
})
});
FixedTableTag::iter()
.filter(|t| {
!matches!(
t,
FixedTableTag::BitwiseAnd | FixedTableTag::BitwiseOr | FixedTableTag::BitwiseXor
) || need_bitwise_lookup
})
.collect()
})
}
/// create fixed_table_tags needed given witness block
pub(crate) fn detect_fixed_table_tags<F: Field>(block: &Block<F>) -> Vec<FixedTableTag> {
if need_bitwise_lookup(block) {
FixedTableTag::iter().collect()
} else {
FixedTableTag::iter()
.filter(|t| {
!matches!(
t,
FixedTableTag::BitwiseAnd
| FixedTableTag::BitwiseOr
| FixedTableTag::BitwiseXor
)
})
.collect()
}
}

#[cfg(all(feature = "disabled", test))]
Expand Down Expand Up @@ -532,7 +553,8 @@ mod evm_circuit_stats {
N_PHASE2_COPY_COLUMNS,
},
step::ExecutionState,
EvmCircuit,
table::FixedTableTag,
EvmCircuit, FIXED_TABLE_ROWS, FIXED_TABLE_ROWS_NO_BITWISE,
},
stats::print_circuit_stats_by_states,
test_util::CircuitTestBuilder,
Expand All @@ -555,6 +577,39 @@ mod evm_circuit_stats {
},
MOCK_ACCOUNTS,
};
use strum::IntoEnumIterator;

#[test]
fn test_fixed_table_rows() {
let row_num_by_tags = |tags: Vec<FixedTableTag>| -> usize {
tags.iter()
.map(|tag| {
let count = tag.build::<Fr>().count();
log::debug!("fixed tab {tag:?} needs {count} rows");
count
})
.sum::<usize>()
};
assert_eq!(
FIXED_TABLE_ROWS,
row_num_by_tags(FixedTableTag::iter().collect_vec())
);
assert_eq!(
FIXED_TABLE_ROWS_NO_BITWISE,
row_num_by_tags(
FixedTableTag::iter()
.filter(|t| {
!matches!(
t,
FixedTableTag::BitwiseAnd
| FixedTableTag::BitwiseOr
| FixedTableTag::BitwiseXor
)
})
.collect_vec()
)
);
}

#[test]
fn evm_circuit_unusable_rows() {
Expand Down
68 changes: 26 additions & 42 deletions zkevm-circuits/src/super_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,64 +471,48 @@ impl<
}
/// Return the minimum number of rows required to prove the block
pub fn min_num_rows_block_subcircuits(block: &Block<Fr>) -> Vec<SubcircuitRowUsage> {
log::debug!("start min_num_rows_block_subcircuits");
let mut rows = Vec::new();
let mut push = |name, usage| {
log::debug!("{name} circuit row: {usage:?}");
rows.push((name, usage));
};
let evm = EvmCircuit::min_num_rows_block(block);
push("evm", evm);
let state = StateCircuit::min_num_rows_block(block);
push("state", state);
let bytecode = BytecodeCircuit::min_num_rows_block(block);
push("bytecode", bytecode);
let copy = CopyCircuit::min_num_rows_block(block);
push("copy", copy);
let keccak = KeccakCircuit::min_num_rows_block(block);
push("keccak", keccak);
let tx = TxCircuit::min_num_rows_block(block);
push("tx", tx);
let rlp = RlpCircuit::min_num_rows_block(block);
push("rlp", rlp);
let exp = ExpCircuit::min_num_rows_block(block);
push("exp", exp);
let mod_exp = ModExpCircuit::min_num_rows_block(block);
push("mod_exp", mod_exp);
let pi = PiCircuit::min_num_rows_block(block);
push("pi", pi);
let poseidon = PoseidonCircuit::min_num_rows_block(block);
push("poseidon", poseidon);
let sig = SigCircuit::min_num_rows_block(block);
push("sig", sig);
let ecc = EccCircuit::<Fr, 9>::min_num_rows_block(block);
push("ecc", ecc);
#[cfg(feature = "zktrie")]
let mpt = MptCircuit::<Fr>::min_num_rows_block(block);

let rows: Vec<(usize, usize)> = vec![
evm,
state,
bytecode,
copy,
keccak,
tx,
rlp,
exp,
mod_exp,
pi,
poseidon,
sig,
ecc,
#[cfg(feature = "zktrie")]
mpt,
];
let sub_circuit_names: Vec<String> = [
"evm",
"state",
"bytecode",
"copy",
"keccak",
"tx",
"rlp",
"exp",
"modexp",
"pi",
"poseidon",
"sig",
"ecc",
#[cfg(feature = "zktrie")]
"mpt",
]
.into_iter()
.map(|s| s.to_string())
.collect();
let row_usage_details = sub_circuit_names
{
let mpt = MptCircuit::<Fr>::min_num_rows_block(block);
push("mpt", mpt);
}

let row_usage_details = rows
.into_iter()
.zip_eq(rows.into_iter())
.map(|(name, (row_num_real, row_num_total))| SubcircuitRowUsage {
name,
name: name.to_string(),
row_num_real,
row_num_total,
})
Expand Down

0 comments on commit 25f8bde

Please sign in to comment.