diff --git a/DEVELOPER-GUIDE.md b/DEVELOPER-GUIDE.md index 7c7b21b5e..aeb8918d1 100644 --- a/DEVELOPER-GUIDE.md +++ b/DEVELOPER-GUIDE.md @@ -95,7 +95,7 @@ You can find this functionality under `src/values.rs` and `src/values/{typename} Serialization is done using `Serde`, and each type provides a `deserialize` and `serialize` function. The inner workings of such functions can be a bit complex due to how the JIT runner works. You need to work with pointers and unsafe rust. -In `values.rs` we should also declare whether the type is complex under `is_complex` in the `ValueBuilder` trait implmentation. +In `values.rs` we should also declare whether the type is complex under `is_complex` in the `ValueBuilder` trait implementation. > Complex types are always passed by pointer (both as params and return values) and require a stack allocation. Examples of complex values include structs and enums, but not felts since LLVM considers them integers. @@ -215,7 +215,7 @@ Some commonly used dialects in this project: #### The arith dialect -It contains arithmetic operations, such as `addi`, `subi` for addition and substraction. +It contains arithmetic operations, such as `addi`, `subi` for addition and subtraction. #### The cf dialect diff --git a/README.md b/README.md index 029ec2062..08fab25b5 100644 --- a/README.md +++ b/README.md @@ -291,7 +291,7 @@ cd build cmake -G Ninja ../llvm \ -DLLVM_ENABLE_PROJECTS="mlir;clang;clang-tools-extra;lld;polly" \ -DLLVM_BUILD_EXAMPLES=OFF \ - -DLLVM_TARGETS_TO_BUILD="Native;NVPTX" \ + -DLLVM_TARGETS_TO_BUILD="Native" \ -DCMAKE_INSTALL_PREFIX=/opt/llvm-17 \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ -DLLVM_PARALLEL_LINK_JOBS=4 \ @@ -342,7 +342,7 @@ make deps make build ``` -Or with your native CPU Architecture for even more perfomance (usually): +Or with your native CPU Architecture for even more performance (usually): ```bash make build-native ``` @@ -462,7 +462,7 @@ fn main() { // Compile the cairo program to sierra. let sierra_program = cairo_native::utils::cairo_to_sierra(program_path); - // Instantiate a Cairo Native MLIR contex. This data structure is responsible for the + // Instantiate a Cairo Native MLIR context. This data structure is responsible for the // MLIR initialization and compilation of sierra programs into a MLIR module. let native_context = NativeContext::new(); @@ -486,7 +486,7 @@ fn main() { native_executor .execute(&fn_id, params, returns, required_init_gas).unwrap(); - println!("Cairo program was compiled and executed succesfully."); + println!("Cairo program was compiled and executed successfully."); } ``` @@ -510,8 +510,8 @@ make bench ``` The `bench` target will run the `./scripts/bench-hyperfine.sh` script. -This script runs hyperfine comands to compare the execution time of programs in the `./programs/benches/` folder. -Each program is compiled and executed via the execution engine with the `sierrajit` command and via the cairo-vm with the `cairo-run` command provided by the `cairo` codebase. +This script runs hyperfine commands to compare the execution time of programs in the `./programs/benches/` folder. +Each program is compiled and executed via the execution engine with the `cairo-native-run` command and via the cairo-vm with the `cairo-run` command provided by the `cairo` codebase. The `cairo-run` command should be available in the `$PATH` and ideally compiled with `cargo build --release`. If you want the benchmarks to run using a specific build, or the `cairo-run` commands conflicts with something (e.g. the cairo-svg package binaries in macos) then the command to run `cairo-run` with a full path can be specified with the `$CAIRO_RUN` environment variable. @@ -520,7 +520,7 @@ If you want the benchmarks to run using a specific build, or the `cairo-run` com # to mlir with llvm dialect sierra2mlir program.sierra -o program.mlir -# trranslate all dialects to the llvm dialect +# translate all dialects to the llvm dialect "$MLIR_SYS_170_PREFIX/bin/mlir-opt" \ --canonicalize \ --convert-scf-to-cf \ diff --git a/examples/easy_api.rs b/examples/easy_api.rs index 21616edae..c64a9e105 100644 --- a/examples/easy_api.rs +++ b/examples/easy_api.rs @@ -18,16 +18,16 @@ fn main() { // Compile the cairo program to sierra. let sierra_program = cairo_native::utils::cairo_to_sierra(program_path); - // Instantiate a Cairo Native MLIR contex. This data structure is responsible for the - // MLIR initialization and compilation of sierra programs into a MLIR module. + // Instantiate a Cairo Native MLIR context. This data structure is responsible for the MLIR + // initialization and compilation of sierra programs into a MLIR module. let native_context = NativeContext::new(); // Compile the sierra program into a MLIR module. let native_program = native_context.compile(&sierra_program).unwrap(); // Get necessary information for the execution of the program from a given entrypoint: - // * entrypoint function id - // * required initial gas + // - Entrypoint function id + // - Required initial gas let name = cairo_native::utils::felt252_short_str("user"); let entry_point = "hello::hello::greet"; let params = json!([name]); @@ -38,7 +38,7 @@ fn main() { // Instantiate MLIR executor. let native_executor = NativeExecutor::new(native_program); - // Execute the program + // Execute the program. native_executor .execute(fn_id, params, returns, required_init_gas) .unwrap_or_else(|e| match &e.source { @@ -59,5 +59,5 @@ fn main() { e => panic!("{:?}", e), }); - println!("Cairo program was compiled and executed succesfully."); + println!("Cairo program was compiled and executed successfully."); } diff --git a/examples/erc20.rs b/examples/erc20.rs index db5b4c2af..21c57f261 100644 --- a/examples/erc20.rs +++ b/examples/erc20.rs @@ -423,6 +423,6 @@ fn main() { } */ - println!("Cairo program was compiled and executed succesfully."); + println!("Cairo program was compiled and executed successfully."); println!("{result:#?}"); } diff --git a/examples/starknet.rs b/examples/starknet.rs index f5202edf4..8d0ba2dc2 100644 --- a/examples/starknet.rs +++ b/examples/starknet.rs @@ -401,6 +401,6 @@ fn main() { .expect("failed to serialize starknet execution result"); println!(); - println!("Cairo program was compiled and executed succesfully."); + println!("Cairo program was compiled and executed successfully."); println!("{result:#?}"); } diff --git a/src/cache.rs b/src/cache.rs index da581f310..f65b40b40 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -1,14 +1,13 @@ -use std::{cell::RefCell, collections::HashMap, fmt::Debug, hash::Hash, rc::Rc}; - -use cairo_lang_sierra::program::Program; - use crate::{context::NativeContext, executor::NativeExecutor}; +use cairo_lang_sierra::program::Program; +use std::{cell::RefCell, collections::HashMap, fmt::Debug, hash::Hash, rc::Rc}; /// A Cache for programs with the same context. pub struct ProgramCache<'a, K: PartialEq + Eq + Hash> { context: &'a NativeContext, - // Since we already hold a reference to the Context, it doesn't make sense to use thread-safe refcounting. - // Using a Arc> here is useless because NativeExecutor is not Send and Sync. + // Since we already hold a reference to the Context, it doesn't make sense to use thread-safe + // reference counting. Using a Arc> here is useless because NativeExecutor is neither + // Send nor Sync. cache: HashMap>>>, } @@ -45,11 +44,9 @@ impl<'a, K: Clone + PartialEq + Eq + Hash> ProgramCache<'a, K> { #[cfg(test)] mod test { - use std::time::Instant; - - use crate::utils::test::load_cairo; - use super::*; + use crate::utils::test::load_cairo; + use std::time::Instant; #[test] fn test_cache() { diff --git a/src/compiler.rs b/src/compiler.rs index afe9012a0..e3eb61343 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -139,7 +139,7 @@ where /// The function accepts a `Function` argument, which provides the function's entry point, signature /// and name. Check out [compile](self::compile) for a description of the other arguments. /// -/// The [module docs](self) contain more information about the compiliation process. +/// The [module docs](self) contain more information about the compilation process. fn compile_func( context: &Context, module: &Module, diff --git a/src/error/jit_engine.rs b/src/error/jit_engine.rs index 73b168a45..df0a256ac 100644 --- a/src/error/jit_engine.rs +++ b/src/error/jit_engine.rs @@ -225,7 +225,7 @@ where } } -pub fn make_insuficient_gas_error<'de, TType, TLibfunc, D, S>( +pub fn make_insufficient_gas_error<'de, TType, TLibfunc, D, S>( needed: u128, have: u128, ) -> Error<'de, TType, TLibfunc, D, S> diff --git a/src/jit_runner.rs b/src/jit_runner.rs index 6452d17e7..83560ec59 100644 --- a/src/jit_runner.rs +++ b/src/jit_runner.rs @@ -3,7 +3,7 @@ use crate::{ error::{ jit_engine::{ - make_deserializer_error, make_insuficient_gas_error, make_serializer_error, + make_deserializer_error, make_insufficient_gas_error, make_serializer_error, make_type_builder_error, }, JitRunnerError, @@ -27,8 +27,8 @@ use tracing::debug; /// Execute a function on an engine loaded with a Sierra program. /// /// The JIT execution of a Sierra program requires an [`ExecutionEngine`] already configured with -/// the compiled module. This has been designed this way because it allows engine reusal, as opposed -/// to building a different engine every time a function is called and therefore losing all +/// the compiled module. This has been designed this way because it allows reusing the engine, as +/// opposed to building a different engine every time a function is called and therefore losing all /// potential optimizations that are already present. /// /// The registry is needed to convert the params and return values into and from the JIT ABI. Check @@ -69,15 +69,15 @@ where }) .map_err(make_deserializer_error)?; - // If program has a required initial gas, check if a gas builting exists - // and check if the passed gas was enough, if so, deduct the required gas before execution. + // If program has a required initial gas, check if a gas builtin exists and check if the passed + // gas was enough, if so, deduct the required gas before execution. if let Some(required_initial_gas) = required_initial_gas { for (id, param) in entry_point.signature.param_types.iter().zip(params.iter()) { if id.debug_name.as_deref() == Some("GasBuiltin") { let gas_builtin = unsafe { *param.cast::().as_ptr() }; if gas_builtin < required_initial_gas { - return Err(make_insuficient_gas_error( + return Err(make_insufficient_gas_error( required_initial_gas, gas_builtin, )); diff --git a/src/lib.rs b/src/lib.rs index 0c24ff809..902e1a2af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ //! //! ## Usage //! -//! The API containts two structs, `NativeContext` and `NativeExecutor`. +//! The API contains two structs, `NativeContext` and `NativeExecutor`. //! The main purpose of `NativeContext` is MLIR initialization, compilation and lowering to LLVM. //! `NativeExecutor` in the other hand is responsible of executing MLIR compiled sierra programs //! from an entrypoint. @@ -37,7 +37,7 @@ //! // Compile the cairo program to sierra. //! let sierra_program = cairo_native::utils::cairo_to_sierra(program_path); //! -//! // Instantiate a Cairo Native MLIR contex. This data structure is responsible for the +//! // Instantiate a Cairo Native MLIR context. This data structure is responsible for the //! // MLIR initialization and compilation of sierra programs into a MLIR module. //! let native_context = NativeContext::new(); //! diff --git a/src/libfuncs/array.rs b/src/libfuncs/array.rs index 08ed54b45..9955ce74f 100644 --- a/src/libfuncs/array.rs +++ b/src/libfuncs/array.rs @@ -1,6 +1,7 @@ //! # Array libfuncs -// TODO: A future possible improvement would be to put the array behind a double pointer and a reference counter, to avoid unnecesary clones. +// TODO: A future possible improvement would be to put the array behind a double pointer and a +// reference counter, to avoid unnecessary clones. use super::{LibfuncBuilder, LibfuncHelper}; use crate::{ diff --git a/src/libfuncs/bool.rs b/src/libfuncs/bool.rs index d6d263575..001a7ee12 100644 --- a/src/libfuncs/bool.rs +++ b/src/libfuncs/bool.rs @@ -96,7 +96,7 @@ fn build_bool_binary<'ctx, 'this, TType, TLibfunc>( helper: &LibfuncHelper<'ctx, 'this>, _metadata: &mut MetadataStorage, info: &SignatureOnlyConcreteLibfunc, - binop: BoolOp, + bin_op: BoolOp, ) -> Result<()> where TType: GenericType, @@ -133,7 +133,7 @@ where )); let rhs_tag = op.result(0)?.into(); - let op = match binop { + let op = match bin_op { BoolOp::And => entry.append_operation(arith::andi(lhs_tag, rhs_tag, location)), BoolOp::Xor => entry.append_operation(arith::xori(lhs_tag, rhs_tag, location)), BoolOp::Or => entry.append_operation(arith::ori(lhs_tag, rhs_tag, location)), diff --git a/src/libfuncs/snapshot_take.rs b/src/libfuncs/snapshot_take.rs index f7a96e86d..9fe705000 100644 --- a/src/libfuncs/snapshot_take.rs +++ b/src/libfuncs/snapshot_take.rs @@ -36,9 +36,8 @@ where ::Concrete: TypeBuilder, ::Concrete: LibfuncBuilder, { - // TODO: Should this act like dup like it does now? or are there special requirements. So far it seems to work. - // TODO: Handle non-trivially-copyable types (ex. arrays) and maybe update docs. - + // Handle non-trivially-copyable types (ex. arrays) by invoking their override or just copy the + // original value otherwise. let original_value = entry.argument(0)?.into(); let cloned_value = match metadata .get_mut::>() diff --git a/src/types/enum.rs b/src/types/enum.rs index 442284881..b51aedc87 100644 --- a/src/types/enum.rs +++ b/src/types/enum.rs @@ -470,7 +470,7 @@ where )) } -/// Extract layout for the default enum representation, itsdiscriminant and all its payloads. +/// Extract layout for the default enum representation, its discriminant and all its payloads. pub fn get_layout_for_variants( registry: &ProgramRegistry, variants: &[ConcreteTypeId], diff --git a/src/types/nullable.rs b/src/types/nullable.rs index 723e153f1..8dd089c54 100644 --- a/src/types/nullable.rs +++ b/src/types/nullable.rs @@ -2,8 +2,8 @@ //! //! Nullable is represented as a pointer, usually the null value will point to a alloca in the stack. //! -//! This is so we only check if the ptr is nullptr for nulability, instead of using a enum in this case. -//! TODO +//! A nullable is functionally equivalent to Rust's `Option>`. Since it's always paired with +//! `Box` we can reuse its pointer, just leaving it null when there's no value. use super::{TypeBuilder, WithSelf}; use crate::{ diff --git a/tests/boolean.rs b/tests/boolean.rs index 1384d531c..dfe98e4f3 100644 --- a/tests/boolean.rs +++ b/tests/boolean.rs @@ -111,9 +111,8 @@ lazy_static! { }; } -// because comparing a felt to 1 to create boolean, which uses felt252_is_zero and felt sub,add, has a bug we use u8 on other tests -// until this is fixed. -// the bug may be in felt substraction +// Since comparing a felt to 1 to create boolean (uses felt252_is_zero and felt sub,add) has a bug, +// we'll be using use u8 on other tests until this is fixed. The bug may be in felt subtraction. #[ignore = "TODO: comparing a felt252 == 1 will lead to wrong results"] #[test] fn felt252_to_bool_bug() {