Skip to content

Commit

Permalink
feat: prover metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
alexghr committed Apr 29, 2024
1 parent 271fd17 commit 36ea47e
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 112 deletions.
20 changes: 19 additions & 1 deletion yarn-project/circuit-types/src/stats/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,13 @@ export const Metrics = [
{
name: 'circuit_simulation_time_in_ms',
groupBy: 'circuit-name',
description: 'Time to run a circuit simulation.',
description: 'Time to run a circuit simulation using WASM.',
events: ['circuit-simulation'],
},
{
name: 'circuit_partial_witness_generation_time_in_ms',
groupBy: 'circuit-name',
description: 'Time to generate the partial witness for a circuit',
events: ['circuit-simulation'],
},
{
Expand All @@ -128,6 +134,18 @@ export const Metrics = [
description: 'Size of the outputs (ie public inputs) from a circuit simulation.',
events: ['circuit-simulation'],
},
{
name: 'circuit_proving_time_in_ms',
groupBy: 'circuit-name',
description: 'Time to prove circuit execution.',
events: ['circuit-proving'],
},
{
name: 'circuit_proof_size_in_bytes',
groupBy: 'circuit-name',
description: 'Size of the proof produced by a circuit.',
events: ['circuit-proving'],
},
{
name: 'tx_size_in_bytes',
groupBy: 'classes-registered',
Expand Down
44 changes: 31 additions & 13 deletions yarn-project/circuit-types/src/stats/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,30 +48,47 @@ export type NodeSyncedChainHistoryStats = {
dbSize: number;
};

export type CircuitName =
| 'base-parity'
| 'root-parity'
| 'base-rollup'
| 'private-kernel-init'
| 'private-kernel-ordering'
| 'root-rollup'
| 'merge-rollup'
| 'private-kernel-inner'
| 'public-kernel-setup'
| 'public-kernel-app-logic'
| 'public-kernel-teardown'
| 'public-kernel-tail';

/** Stats for circuit simulation. */
export type CircuitSimulationStats = {
/** name of the event. */
eventName: 'circuit-simulation';
/** Name of the circuit. */
circuitName:
| 'base-parity'
| 'root-parity'
| 'base-rollup'
| 'private-kernel-init'
| 'private-kernel-ordering'
| 'root-rollup'
| 'merge-rollup'
| 'private-kernel-inner'
| 'public-kernel-setup'
| 'public-kernel-app-logic'
| 'public-kernel-teardown'
| 'public-kernel-tail';
circuitName: CircuitName;
/** Duration in ms. */
duration: number;
/** Size in bytes of circuit inputs. */
inputSize: number;
/** Size in bytes of circuit outputs (aka public inputs). */
outputSize: number;
};

export type CircuitProvingStats = {
/** Name of the event. */
eventName: 'circuit-proving';
/** Name of the circuit. */
circuitName: CircuitName;
/** Duration in ms. */
duration: number;
/** Size in bytes of circuit inputs. */
inputSize: number;
/** Size in bytes of circuit outputs (aka public inputs). */
outputSize: number;
/** Size in bytes of the proof. */
proofSize: number;
};

/** Stats for an L2 block built by a sequencer. */
Expand Down Expand Up @@ -206,6 +223,7 @@ export type Stats =
| L1PublishStats
| NodeSyncedChainHistoryStats
| CircuitSimulationStats
| CircuitProvingStats
| L2BlockBuiltStats
| L2BlockHandledStats
| NoteProcessorCaughtUpStats
Expand Down
94 changes: 8 additions & 86 deletions yarn-project/prover-client/src/orchestrator/orchestrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
L2Block,
MerkleTreeId,
type ProcessedTx,
type PublicKernelRequest,
PublicKernelType,
type TxEffect,
toTxEffect,
Expand All @@ -15,7 +14,6 @@ import {
type ProvingTicket,
type PublicInputsAndProof,
} from '@aztec/circuit-types/interfaces';
import { type CircuitSimulationStats } from '@aztec/circuit-types/stats';
import {
type BaseOrMergeRollupPublicInputs,
BaseParityInputs,
Expand All @@ -41,7 +39,6 @@ import { createDebugLogger } from '@aztec/foundation/log';
import { promiseWithResolvers } from '@aztec/foundation/promise';
import { type Tuple } from '@aztec/foundation/serialize';
import { sleep } from '@aztec/foundation/sleep';
import { Timer } from '@aztec/foundation/timer';
import { type MerkleTreeOperations } from '@aztec/world-state';

import { inspect } from 'util';
Expand Down Expand Up @@ -311,7 +308,7 @@ export class ProvingOrchestrator {
private deferredProving<T>(
provingState: ProvingState | undefined,
request: (signal: AbortSignal) => Promise<T>,
callback: (result: T, durationMs: number) => void | Promise<void>,
callback: (result: T) => void | Promise<void>,
) {
if (!provingState?.verifyState()) {
logger.debug(`Not enqueuing job, state no longer valid`);
Expand All @@ -330,10 +327,7 @@ export class ProvingOrchestrator {
return;
}

const timer = new Timer();
const result = await request(controller.signal);
const duration = timer.ms();

if (!provingState?.verifyState()) {
logger.debug(`State no longer valid, discarding result`);
return;
Expand All @@ -345,7 +339,7 @@ export class ProvingOrchestrator {
return;
}

await callback(result, duration);
await callback(result);
} catch (err) {
if (err instanceof AbortedError) {
// operation was cancelled, probably because the block was cancelled
Expand All @@ -367,39 +361,6 @@ export class ProvingOrchestrator {
setImmediate(safeJob);
}

private emitCircuitSimulationStats(
circuitName: CircuitSimulationStats['circuitName'] | null,
inputSize: number,
outputSize: number,
duration: number,
) {
const stats: CircuitSimulationStats | undefined = circuitName
? {
eventName: 'circuit-simulation',
circuitName,
duration,
inputSize,
outputSize,
}
: undefined;
logger.debug(`Simulated ${circuitName} circuit duration=${duration}ms`, stats);
}

private getPublicKernelCircuitName(request: PublicKernelRequest) {
switch (request.type) {
case PublicKernelType.SETUP:
return 'public-kernel-setup';
case PublicKernelType.APP_LOGIC:
return 'public-kernel-app-logic';
case PublicKernelType.TEARDOWN:
return 'public-kernel-teardown';
case PublicKernelType.TAIL:
return 'public-kernel-tail';
default:
return null;
}
}

// Updates the merkle trees for a transaction. The first enqueued job for a transaction
private async prepareBaseRollupInputs(
provingState: ProvingState | undefined,
Expand Down Expand Up @@ -475,14 +436,7 @@ export class ProvingOrchestrator {
this.deferredProving(
provingState,
signal => this.prover.getBaseRollupProof(tx.baseRollupInputs, signal),
(result, duration) => {
this.emitCircuitSimulationStats(
'base-rollup',
tx.baseRollupInputs.toBuffer().length,
result.inputs.toBuffer().length,
duration,
);

result => {
validatePartialState(result.inputs.end, tx.treeSnapshots);
const currentLevel = provingState.numMergeLevels + 1n;
this.storeAndExecuteNextMergeLevel(provingState, currentLevel, index, [result.inputs, result.proof]);
Expand All @@ -506,13 +460,7 @@ export class ProvingOrchestrator {
this.deferredProving(
provingState,
signal => this.prover.getMergeRollupProof(inputs, signal),
(result, duration) => {
this.emitCircuitSimulationStats(
'merge-rollup',
inputs.toBuffer().length,
result.inputs.toBuffer().length,
duration,
);
result => {
this.storeAndExecuteNextMergeLevel(provingState, level, index, [result.inputs, result.proof]);
},
);
Expand Down Expand Up @@ -542,14 +490,7 @@ export class ProvingOrchestrator {
this.deferredProving(
provingState,
signal => this.prover.getRootRollupProof(inputs, signal),
(result, duration) => {
this.emitCircuitSimulationStats(
'root-rollup',
inputs.toBuffer().length,
result.inputs.toBuffer().length,
duration,
);

result => {
provingState.rootRollupPublicInputs = result.inputs;
provingState.finalProof = result.proof;

Expand All @@ -567,13 +508,7 @@ export class ProvingOrchestrator {
this.deferredProving(
provingState,
signal => this.prover.getBaseParityProof(inputs, signal),
(rootInput, duration) => {
this.emitCircuitSimulationStats(
'base-parity',
inputs.toBuffer().length,
rootInput.publicInputs.toBuffer().length,
duration,
);
rootInput => {
provingState.setRootParityInputs(rootInput, index);
if (provingState.areRootParityInputsReady()) {
const rootParityInputs = new RootParityInputs(
Expand All @@ -594,13 +529,7 @@ export class ProvingOrchestrator {
this.deferredProving(
provingState,
signal => this.prover.getRootParityProof(inputs, signal),
async (rootInput, duration) => {
this.emitCircuitSimulationStats(
'root-parity',
inputs.toBuffer().length,
rootInput.publicInputs.toBuffer().length,
duration,
);
async rootInput => {
provingState!.finalRootParityInput = rootInput;
await this.checkAndEnqueueRootRollup(provingState);
},
Expand Down Expand Up @@ -714,14 +643,7 @@ export class ProvingOrchestrator {
return this.prover.getPublicKernelProof(request, signal);
}
},
(result, duration) => {
this.emitCircuitSimulationStats(
this.getPublicKernelCircuitName(request),
request.inputs.toBuffer().length,
0,
duration,
);

result => {
const nextKernelRequest = txProvingState.getNextPublicKernelFromKernelProof(functionIndex, result.proof);
// What's the status of the next kernel?
if (nextKernelRequest.code === TX_PROVING_CODE.NOT_READY) {
Expand Down
20 changes: 20 additions & 0 deletions yarn-project/prover-client/src/prover/bb_prover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
import { randomBytes } from '@aztec/foundation/crypto';
import { createDebugLogger } from '@aztec/foundation/log';
import { type Tuple } from '@aztec/foundation/serialize';
import { Timer } from '@aztec/foundation/timer';
import {
ServerCircuitArtifacts,
type ServerProtocolArtifact,
Expand Down Expand Up @@ -62,6 +63,7 @@ import {
generateProof,
verifyProof,
} from '../bb/execute.js';
import { circuitTypeToCircuitName, emitCircuitProvingStats, emitCircuitSimulationStats } from '../util.js';
import { type CircuitProver, KernelArtifactMapping } from './interface.js';

const logger = createDebugLogger('aztec:bb-prover');
Expand Down Expand Up @@ -268,7 +270,15 @@ export class BBNativeRollupProver implements CircuitProver {

logger.debug(`Generating witness data for ${circuitType}`);

const simTimer = new Timer();
const outputWitness = await simulator.simulateCircuit(witnessMap, artifact);
emitCircuitSimulationStats(
circuitTypeToCircuitName(circuitType),
simTimer.ms(),
witnessMap.size * Fr.SIZE_IN_BYTES,
outputWitness.size * Fr.SIZE_IN_BYTES,
logger,
);

// Now prove the circuit from the generated witness
logger.debug(`Proving ${circuitType}...`);
Expand All @@ -293,6 +303,16 @@ export class BBNativeRollupProver implements CircuitProver {
// Read the proof and then cleanup up our temporary directory
const proof = await fs.readFile(`${provingResult.proofPath!}/${PROOF_FILENAME}`);

// does not include reading the proof from disk above because duration comes from the bb wrapper
emitCircuitProvingStats(
circuitTypeToCircuitName(circuitType),
provingResult.duration,
witnessMap.size * Fr.SIZE_IN_BYTES,
outputWitness.size * Fr.SIZE_IN_BYTES,
proof.length,
logger,
);

await fs.rm(bbWorkingDirectory, { recursive: true, force: true });

logger.info(`Generated proof for ${circuitType} in ${provingResult.duration} ms, size: ${proof.length} fields`);
Expand Down
Loading

0 comments on commit 36ea47e

Please sign in to comment.