Skip to content

feat(new-execution): rv32im tracegen and e1 execution #1607

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Draft
wants to merge 22 commits into
base: feat/new-execution
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions benchmarks/execute/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ license.workspace = true

[dependencies]
openvm-benchmarks-utils.workspace = true
cargo-openvm.workspace = true
openvm-circuit.workspace = true
openvm-sdk.workspace = true
openvm-stark-sdk.workspace = true
openvm-transpiler.workspace = true
openvm-rv32im-circuit.workspace = true
Expand All @@ -31,7 +29,6 @@ criterion = { version = "0.5", features = ["html_reports"] }

[features]
default = ["mimalloc"]
profiling = ["openvm-sdk/profiling"]
aggregation = []
mimalloc = ["openvm-circuit/mimalloc"]
jemalloc = ["openvm-circuit/jemalloc"]
Expand Down
44 changes: 29 additions & 15 deletions benchmarks/execute/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
use cargo_openvm::{default::DEFAULT_APP_CONFIG_PATH, util::read_config_toml_or_default};
// TODO(ayush): avoid cargo-openvm
use clap::{Parser, ValueEnum};
use eyre::Result;
use openvm_benchmarks_utils::{get_elf_path, get_programs_dir, read_elf_file};
use openvm_circuit::arch::{instructions::exe::VmExe, VmExecutor};
use openvm_sdk::StdIn;
use openvm_stark_sdk::bench::run_with_metric_collection;
use openvm_transpiler::FromElf;
use openvm_rv32im_circuit::Rv32ImConfig;
use openvm_rv32im_transpiler::{
Rv32ITranspilerExtension, Rv32IoTranspilerExtension, Rv32MTranspilerExtension,
};
use openvm_stark_sdk::{bench::run_with_metric_collection, p3_baby_bear::BabyBear};
use openvm_transpiler::{transpiler::Transpiler, FromElf};

#[derive(Debug, Clone, ValueEnum)]
enum BuildProfile {
Debug,
Release,
}

// const DEFAULT_APP_CONFIG_PATH: &str = "./openvm.toml";

static AVAILABLE_PROGRAMS: &[&str] = &[
"fibonacci_recursive",
"fibonacci_iterative",
"quicksort",
"bubblesort",
"pairing",
"keccak256",
"keccak256_iter",
"sha256",
"sha256_iter",
"revm_transfer",
"revm_snailtracer",
// "pairing",
// "keccak256",
// "keccak256_iter",
// "sha256",
// "sha256_iter",
// "revm_transfer",
// "revm_snailtracer",
];

#[derive(Parser)]
Expand Down Expand Up @@ -106,13 +111,22 @@ fn main() -> Result<()> {
let elf_path = get_elf_path(&program_dir);
let elf = read_elf_file(&elf_path)?;

let config_path = program_dir.join(DEFAULT_APP_CONFIG_PATH);
let vm_config = read_config_toml_or_default(&config_path)?.app_vm_config;
// let config_path = program_dir.join(DEFAULT_APP_CONFIG_PATH);
// let vm_config = read_config_toml_or_default(&config_path)?.app_vm_config;
// let transpiler = vm_config.transpiler;
let vm_config = Rv32ImConfig::default();

let transpiler = Transpiler::<BabyBear>::default()
.with_extension(Rv32ITranspilerExtension)
.with_extension(Rv32IoTranspilerExtension)
.with_extension(Rv32MTranspilerExtension);

let exe = VmExe::from_elf(elf, vm_config.transpiler())?;
let exe = VmExe::from_elf(elf, transpiler)?;

let executor = VmExecutor::new(vm_config);
executor.execute(exe, StdIn::default())?;
executor
.execute(exe, vec![])
.expect("Failed to execute program");
tracing::info!("Completed program: {}", program);
}
tracing::info!("All programs executed successfully");
Expand Down
23 changes: 3 additions & 20 deletions crates/circuits/mod-builder/src/core_chip.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
use itertools::Itertools;
use num_bigint::BigUint;
use num_traits::Zero;
use openvm_circuit::{
arch::{
AdapterAirContext, AdapterRuntimeContext, DynAdapterInterface, DynArray, InsExecutorE1,
MinimalInstruction, Result, VmAdapterInterface, VmCoreAir, VmCoreChip, VmExecutionState,
},
system::memory::online::GuestMemory,
use openvm_circuit::arch::{
AdapterAirContext, AdapterRuntimeContext, DynAdapterInterface, DynArray, MinimalInstruction,
Result, VmAdapterInterface, VmCoreAir, VmCoreChip,
};
use openvm_circuit_primitives::{
var_range::SharedVariableRangeCheckerChip, SubAir, TraceSubRowGenerator,
Expand Down Expand Up @@ -314,20 +311,6 @@ where
}
}

impl<Mem, Ctx, F> InsExecutorE1<Mem, Ctx, F> for FieldExpressionCoreChip
where
Mem: GuestMemory,
F: PrimeField32,
{
fn execute_e1(
&mut self,
_state: &mut VmExecutionState<Mem, Ctx>,
_instruction: &Instruction<F>,
) -> Result<()> {
todo!("Implement execute_e1")
}
}

impl FieldExpressionCoreChip {
// We will be setting is_valid = 0. That forces all flags be 0 (otherwise setup will be -1).
// We generate a dummy row with all flags set to 0, then we set is_valid = 0.
Expand Down
5 changes: 3 additions & 2 deletions crates/vm/src/arch/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use openvm_stark_backend::{
use serde::{Deserialize, Serialize};
use thiserror::Error;

use super::{Streams, VmExecutionState};
use super::Streams;
use crate::system::{
memory::{
online::{GuestMemory, TracingMemory},
Expand Down Expand Up @@ -79,6 +79,7 @@ pub enum ExecutionError {
/// Global VM state accessible during instruction execution.
/// The state is generic in guest memory `MEM` and additional host state `CTX`.
/// The host state is execution context specific.
#[derive(derive_new::new)]
pub struct VmStateMut<'a, MEM, CTX> {
pub pc: &'a mut u32,
pub memory: &'a mut MEM,
Expand Down Expand Up @@ -118,7 +119,7 @@ where
{
fn execute_e1(
&mut self,
state: &mut VmExecutionState<Mem, Ctx>,
state: VmStateMut<Mem, Ctx>,
instruction: &Instruction<F>,
) -> Result<()>;
}
Expand Down
57 changes: 35 additions & 22 deletions crates/vm/src/arch/execution_control.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use openvm_instructions::instruction::Instruction;
use openvm_stark_backend::p3_field::PrimeField32;

use super::{segment::VmExecutionState, ExecutionError, TracegenCtx, VmChipComplex, VmConfig};
use super::{ExecutionError, ExecutionSegmentState, TracegenCtx, VmChipComplex, VmConfig};
use crate::{
arch::{ExecutionState, InstructionExecutor},
system::memory::{online::GuestMemory, AddressMap, MemoryImage, PAGE_SIZE},
Expand All @@ -24,31 +24,36 @@ where
fn new(chip_complex: &VmChipComplex<F, VC::Executor, VC::Periphery>) -> Self;

/// Determines if execution should stop
fn should_stop(
&mut self,
state: &VmExecutionState<Self::Mem, Self::Ctx>,
chip_complex: &VmChipComplex<F, VC::Executor, VC::Periphery>,
) -> bool;
fn should_stop(&mut self, chip_complex: &VmChipComplex<F, VC::Executor, VC::Periphery>)
-> bool;

/// Called before segment execution begins
fn on_segment_start(
&mut self,
vm_state: &VmExecutionState<Self::Mem, Self::Ctx>,
pc: u32,
chip_complex: &mut VmChipComplex<F, VC::Executor, VC::Periphery>,
);

/// Called after segment execution completes
fn on_segment_end(
&mut self,
vm_state: &VmExecutionState<Self::Mem, Self::Ctx>,
pc: u32,
chip_complex: &mut VmChipComplex<F, VC::Executor, VC::Periphery>,
);

/// Called after program termination
fn on_terminate(
&mut self,
pc: u32,
chip_complex: &mut VmChipComplex<F, VC::Executor, VC::Periphery>,
exit_code: u32,
);

/// Execute a single instruction
// TODO(ayush): change instruction to Instruction<u32> / PInstruction
fn execute_instruction(
&mut self,
vm_state: &mut VmExecutionState<Self::Mem, Self::Ctx>,
vm_state: &mut ExecutionSegmentState,
// instruction: &Instruction<F>,
chip_complex: &mut VmChipComplex<F, VC::Executor, VC::Periphery>,
) -> Result<(), ExecutionError>
Expand Down Expand Up @@ -91,7 +96,6 @@ where

fn should_stop(
&mut self,
_state: &VmExecutionState<Self::Mem, Self::Ctx>,
chip_complex: &VmChipComplex<F, VC::Executor, VC::Periphery>,
) -> bool {
// Avoid checking segment too often.
Expand All @@ -109,43 +113,52 @@ where

fn on_segment_start(
&mut self,
vm_state: &VmExecutionState<Self::Mem, Self::Ctx>,
pc: u32,
chip_complex: &mut VmChipComplex<F, VC::Executor, VC::Periphery>,
) {
let timestamp = chip_complex.memory_controller().timestamp();
chip_complex
.connector_chip_mut()
.begin(ExecutionState::new(vm_state.pc, timestamp));
.begin(ExecutionState::new(pc, timestamp));
}

fn on_segment_end(
&mut self,
vm_state: &VmExecutionState<Self::Mem, Self::Ctx>,
pc: u32,
chip_complex: &mut VmChipComplex<F, VC::Executor, VC::Periphery>,
) {
let timestamp = chip_complex.memory_controller().timestamp();
// End the current segment with connector chip
chip_complex
.connector_chip_mut()
.end(ExecutionState::new(vm_state.pc, timestamp), None);
.end(ExecutionState::new(pc, timestamp), None);
self.final_memory = Some(chip_complex.base.memory_controller.memory_image().clone());
}

fn on_terminate(
&mut self,
pc: u32,
chip_complex: &mut VmChipComplex<F, VC::Executor, VC::Periphery>,
exit_code: u32,
) {
let timestamp = chip_complex.memory_controller().timestamp();
chip_complex
.connector_chip_mut()
.end(ExecutionState::new(pc, timestamp), Some(exit_code));
}

/// Execute a single instruction
fn execute_instruction(
&mut self,
vm_state: &mut VmExecutionState<Self::Mem, Self::Ctx>,
state: &mut ExecutionSegmentState,
// instruction: &Instruction<F>,
chip_complex: &mut VmChipComplex<F, VC::Executor, VC::Periphery>,
) -> Result<(), ExecutionError>
where
F: PrimeField32,
{
let timestamp = chip_complex.memory_controller().timestamp();
let (instruction, _) = chip_complex
.base
.program_chip
.get_instruction(vm_state.pc)?;
let (instruction, _) = chip_complex.base.program_chip.get_instruction(state.pc)?;

let &Instruction { opcode, .. } = instruction;

Expand All @@ -154,12 +167,12 @@ where
let new_state = executor.execute(
memory_controller,
instruction,
ExecutionState::new(vm_state.pc, timestamp),
ExecutionState::new(state.pc, timestamp),
)?;
vm_state.pc = new_state.pc;
state.pc = new_state.pc;
} else {
return Err(ExecutionError::DisabledOperation {
pc: vm_state.pc,
pc: state.pc,
opcode,
});
};
Expand Down
Loading
Loading