Skip to content

Commit 45cd39b

Browse files
authored
feat: Tighter timing on ACVM (#13743)
This PR alters the metrics capture for acvm execution to more tightly target the acvm.
1 parent 010975a commit 45cd39b

8 files changed

Lines changed: 43 additions & 36 deletions

File tree

yarn-project/bb-prover/src/prover/bb_private_kernel_prover.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { createLogger } from '@aztec/foundation/log';
2-
import { Timer } from '@aztec/foundation/timer';
32
import {
43
convertPrivateKernelInitInputsToWitnessMapWithAbi,
54
convertPrivateKernelInitOutputsFromWitnessMapWithAbi,
@@ -165,7 +164,6 @@ export abstract class BBPrivateKernelProver implements PrivateKernelProver {
165164

166165
const witnessMap = convertInputs(inputs, compiledCircuit.abi);
167166

168-
const timer = new Timer();
169167
const outputWitness = await this.simulationProvider
170168
.executeProtocolCircuit(witnessMap, compiledCircuit, foreignCallHandler)
171169
.catch((err: Error) => {
@@ -175,12 +173,12 @@ export abstract class BBPrivateKernelProver implements PrivateKernelProver {
175173
});
176174
throw err;
177175
});
178-
const output = convertOutputs(outputWitness, compiledCircuit.abi);
176+
const output = convertOutputs(outputWitness.witness, compiledCircuit.abi);
179177

180178
this.log.debug(`Simulated ${circuitType}`, {
181179
eventName: 'circuit-simulation',
182180
circuitName: mapProtocolArtifactNameToCircuitName(circuitType),
183-
duration: timer.ms(),
181+
duration: outputWitness.duration,
184182
inputSize: inputs.toBuffer().length,
185183
outputSize: output.toBuffer().length,
186184
} satisfies CircuitSimulationStats);
@@ -203,18 +201,17 @@ export abstract class BBPrivateKernelProver implements PrivateKernelProver {
203201
);
204202

205203
const witnessMap = convertInputs(inputs, compiledCircuit.abi);
206-
const timer = new Timer();
207204
const outputWitness = await this.simulationProvider.executeProtocolCircuit(
208205
witnessMap,
209206
compiledCircuit,
210207
foreignCallHandler,
211208
);
212-
const output = convertOutputs(outputWitness, compiledCircuit.abi);
209+
const output = convertOutputs(outputWitness.witness, compiledCircuit.abi);
213210

214211
this.log.debug(`Generated witness for ${circuitType}`, {
215212
eventName: 'circuit-witness-generation',
216213
circuitName: mapProtocolArtifactNameToCircuitName(circuitType),
217-
duration: timer.ms(),
214+
duration: outputWitness.duration,
218215
inputSize: inputs.toBuffer().length,
219216
outputSize: output.toBuffer().length,
220217
} satisfies CircuitWitnessGenerationStats);
@@ -225,7 +222,7 @@ export abstract class BBPrivateKernelProver implements PrivateKernelProver {
225222
const kernelOutput: PrivateKernelSimulateOutput<O> = {
226223
publicInputs: output,
227224
verificationKey,
228-
outputWitness,
225+
outputWitness: outputWitness.witness,
229226
bytecode,
230227
};
231228
return kernelOutput;

yarn-project/bb-prover/src/prover/bb_prover.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { Fr } from '@aztec/foundation/fields';
1111
import { runInDirectory } from '@aztec/foundation/fs';
1212
import { createLogger } from '@aztec/foundation/log';
1313
import { BufferReader } from '@aztec/foundation/serialize';
14-
import { Timer } from '@aztec/foundation/timer';
1514
import {
1615
type ServerProtocolArtifact,
1716
convertBaseParityInputsToWitnessMap,
@@ -415,19 +414,18 @@ export class BBNativeRollupProver implements ServerCircuitProver {
415414
logger.debug(`Generating witness data for ${circuitType}`);
416415

417416
const inputWitness = convertInput(input);
418-
const timer = new Timer();
419417
const foreignCallHandler = undefined; // We don't handle foreign calls in the native ACVM simulator
420-
const outputWitness = await simulator.executeProtocolCircuit(inputWitness, artifact, foreignCallHandler);
421-
const output = convertOutput(outputWitness);
418+
const witnessResult = await simulator.executeProtocolCircuit(inputWitness, artifact, foreignCallHandler);
419+
const output = convertOutput(witnessResult.witness);
422420

423421
const circuitName = mapProtocolArtifactNameToCircuitName(circuitType);
424-
this.instrumentation.recordDuration('witGenDuration', circuitName, timer);
422+
this.instrumentation.recordDuration('witGenDuration', circuitName, witnessResult.duration);
425423
this.instrumentation.recordSize('witGenInputSize', circuitName, input.toBuffer().length);
426424
this.instrumentation.recordSize('witGenOutputSize', circuitName, output.toBuffer().length);
427425

428426
logger.info(`Generated witness`, {
429427
circuitName,
430-
duration: timer.ms(),
428+
duration: witnessResult.duration,
431429
inputSize: input.toBuffer().length,
432430
outputSize: output.toBuffer().length,
433431
eventName: 'circuit-witness-generation',

yarn-project/bb-prover/src/test/test_circuit_prover.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -356,17 +356,21 @@ export class TestCircuitProver implements ServerCircuitProver {
356356
// TODO(#10323): Native ACVM simulator does not support foreign call handler so we use the wasm simulator
357357
// when simulating block root rollup and single tx block root rollup circuits or when the native ACVM simulator
358358
// is not provided.
359-
witness = await this.wasmSimulator.executeProtocolCircuit(
360-
witnessMap,
361-
getSimulatedServerCircuitArtifact(artifactName),
362-
foreignCallHandler,
363-
);
359+
witness = (
360+
await this.wasmSimulator.executeProtocolCircuit(
361+
witnessMap,
362+
getSimulatedServerCircuitArtifact(artifactName),
363+
foreignCallHandler,
364+
)
365+
).witness;
364366
} else {
365-
witness = await this.simulationProvider.executeProtocolCircuit(
366-
witnessMap,
367-
getSimulatedServerCircuitArtifact(artifactName),
368-
undefined, // Native ACM simulator does not support foreign call handler
369-
);
367+
witness = (
368+
await this.simulationProvider.executeProtocolCircuit(
369+
witnessMap,
370+
getSimulatedServerCircuitArtifact(artifactName),
371+
undefined, // Native ACM simulator does not support foreign call handler
372+
)
373+
).witness;
370374
}
371375

372376
const result = convertOutput(witness);

yarn-project/simulator/src/private/providers/acvm_native.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,15 @@ export async function executeNativeCircuit(
123123
});
124124
});
125125

126-
const duration = new Timer();
126+
const timer = new Timer();
127127
const output = await processPromise;
128+
const duration = timer.ms();
128129
if (outputFilename) {
129130
const outputWitnessFileName = `${workingDirectory}/output-witness.gz`;
130131
await fs.copyFile(outputWitnessFileName, outputFilename);
131132
}
132133
const witness = parseIntoWitnessMap(output);
133-
return { status: ACVM_RESULT.SUCCESS, witness, duration: duration.ms() };
134+
return { status: ACVM_RESULT.SUCCESS, witness, duration };
134135
} catch (error) {
135136
return { status: ACVM_RESULT.FAILURE, reason: `${error}` };
136137
}
@@ -143,7 +144,7 @@ export class NativeACVMSimulator implements SimulationProvider {
143144
input: ACVMWitness,
144145
artifact: NoirCompiledCircuitWithName,
145146
callback: ForeignCallHandler | undefined,
146-
): Promise<ACVMWitness> {
147+
): Promise<ACVMSuccess> {
147148
// Execute the circuit on those initial witness values
148149

149150
if (callback) {
@@ -166,7 +167,7 @@ export class NativeACVMSimulator implements SimulationProvider {
166167
throw new Error(`Failed to generate witness: ${result.reason}`);
167168
}
168169

169-
return result.witness;
170+
return result;
170171
};
171172

172173
return await runInDirectory(this.workingDirectory, operation, false, logger);

yarn-project/simulator/src/private/providers/acvm_wasm.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { createLogger } from '@aztec/foundation/log';
2+
import { Timer } from '@aztec/foundation/timer';
23
import initACVM, { type ExecutionError, type ForeignCallHandler, executeCircuit } from '@aztec/noir-acvm_js';
34
import initAbi from '@aztec/noir-noirc_abi';
45
import type { FunctionArtifactWithContractName } from '@aztec/stdlib/abi';
56
import type { NoirCompiledCircuitWithName } from '@aztec/stdlib/noir';
67

78
import { type ACIRCallback, type ACIRExecutionResult, acvm } from '../acvm/acvm.js';
89
import type { ACVMWitness } from '../acvm/acvm_types.js';
10+
import type { ACVMSuccess } from './acvm_native.js';
911
import { type SimulationProvider, enrichNoirError } from './simulation_provider.js';
1012

1113
export class WASMSimulator implements SimulationProvider {
@@ -25,7 +27,7 @@ export class WASMSimulator implements SimulationProvider {
2527
input: ACVMWitness,
2628
artifact: NoirCompiledCircuitWithName,
2729
callback: ForeignCallHandler,
28-
): Promise<ACVMWitness> {
30+
): Promise<ACVMSuccess> {
2931
this.log.debug('init', { hash: artifact.hash });
3032
await this.init();
3133

@@ -34,13 +36,14 @@ export class WASMSimulator implements SimulationProvider {
3436
//
3537
// Execute the circuit
3638
try {
39+
const timer = new Timer();
3740
const result = await executeCircuit(
3841
decodedBytecode,
3942
input,
4043
callback, // handle calls to debug_log
4144
);
4245
this.log.debug('execution successful', { hash: artifact.hash });
43-
return result;
46+
return { witness: result, duration: timer.ms() } as ACVMSuccess;
4447
} catch (err) {
4548
// Typescript types caught errors as unknown or any, so we need to narrow its type to check if it has raw
4649
// assertion payload.

yarn-project/simulator/src/private/providers/acvm_wasm_with_blobs.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import { Timer } from '@aztec/foundation/timer';
12
import { type ExecutionError, type ForeignCallHandler, executeCircuit } from '@aztec/noir-acvm_js';
23
import type { WitnessMap } from '@aztec/noir-types';
34
import type { FunctionArtifactWithContractName } from '@aztec/stdlib/abi';
45
import type { NoirCompiledCircuitWithName } from '@aztec/stdlib/noir';
56

67
import type { ACIRCallback, ACIRExecutionResult } from '../acvm/acvm.js';
78
import type { ACVMWitness } from '../acvm/acvm_types.js';
9+
import type { ACVMSuccess } from './acvm_native.js';
810
import { type SimulationProvider, enrichNoirError } from './simulation_provider.js';
911

1012
/**
@@ -19,19 +21,19 @@ export class WASMSimulatorWithBlobs implements SimulationProvider {
1921
input: WitnessMap,
2022
artifact: NoirCompiledCircuitWithName,
2123
callback: ForeignCallHandler,
22-
): Promise<WitnessMap> {
24+
): Promise<ACVMSuccess> {
2325
// Decode the bytecode from base64 since the acvm does not know about base64 encoding
2426
const decodedBytecode = Buffer.from(artifact.bytecode, 'base64');
2527
//
2628
// Execute the circuit
2729
try {
30+
const timer = new Timer();
2831
const _witnessMap = await executeCircuit(
2932
decodedBytecode,
3033
input,
3134
callback, // handle calls to debug_log and evaluate_blobs mock
3235
);
33-
34-
return _witnessMap;
36+
return { witness: _witnessMap, duration: timer.ms() } as ACVMSuccess;
3537
} catch (err) {
3638
// Typescript types caught errors as unknown or any, so we need to narrow its type to check if it has raw
3739
// assertion payload.

yarn-project/simulator/src/private/providers/circuit_recording/simulation_provider_recorder_wrapper.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { NoirCompiledCircuitWithName } from '@aztec/stdlib/noir';
44

55
import type { ACIRCallback, ACIRExecutionResult } from '../../acvm/acvm.js';
66
import type { ACVMWitness } from '../../acvm/acvm_types.js';
7+
import type { ACVMSuccess } from '../acvm_native.js';
78
import type { SimulationProvider } from '../simulation_provider.js';
89
import { CircuitRecorder } from './circuit_recorder.js';
910

@@ -18,10 +19,10 @@ export class SimulationProviderRecorderWrapper implements SimulationProvider {
1819
input: ACVMWitness,
1920
artifact: NoirCompiledCircuitWithName,
2021
callback: ForeignCallHandler | undefined,
21-
): Promise<ACVMWitness> {
22+
): Promise<ACVMSuccess> {
2223
const bytecode = Buffer.from(artifact.bytecode, 'base64');
2324

24-
return this.#simulate<ForeignCallHandler | undefined, ACVMWitness>(
25+
return this.#simulate<ForeignCallHandler | undefined, ACVMSuccess>(
2526
wrappedCallback => this.simulator.executeProtocolCircuit(input, artifact, wrappedCallback),
2627
input,
2728
bytecode,

yarn-project/simulator/src/private/providers/simulation_provider.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { NoirCompiledCircuit, NoirCompiledCircuitWithName } from '@aztec/st
66

77
import { type ACIRCallback, type ACIRExecutionResult, extractCallStack } from '../acvm/acvm.js';
88
import type { ACVMWitness } from '../acvm/acvm_types.js';
9+
import type { ACVMSuccess } from './acvm_native.js';
910

1011
/**
1112
* Low level simulation interface
@@ -23,7 +24,7 @@ export interface SimulationProvider {
2324
input: ACVMWitness,
2425
artifact: NoirCompiledCircuitWithName,
2526
callback: ForeignCallHandler | undefined,
26-
): Promise<ACVMWitness>;
27+
): Promise<ACVMSuccess>;
2728

2829
/**
2930
* Execute a user circuit (smart contract function)/generate a witness

0 commit comments

Comments
 (0)