From 37d93bf33afb5aa30ea4624995092adbe1d75d4f Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 5 Sep 2024 10:04:40 -0400 Subject: [PATCH 01/15] macros crate skeleton --- Cargo.lock | 21 +++++++++++++++------ Cargo.toml | 2 ++ macros/Cargo.toml | 12 ++++++++++++ macros/src/lib.rs | 1 + 4 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 macros/Cargo.toml create mode 100644 macros/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index a8d5b032..7018d72f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,9 +62,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" [[package]] name = "autocfg" @@ -648,6 +648,15 @@ dependencies = [ "proofman-starks-lib-c", ] +[[package]] +name = "proofman-macros" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "proofman-starks-lib-c" version = "0.1.0" @@ -825,18 +834,18 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 17a9ff62..f235098a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "hints", "pilout", "proofman", + "macros", "provers/stark", "provers/starks-lib-c", "transcript", @@ -23,3 +24,4 @@ log = { version = "0.4", default-features = false } env_logger = "0.11" p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3.git", rev = "c3d754ef77b9fce585b46b972af751fe6e7a9803" } p3-field = { git = "https://github.com/Plonky3/Plonky3.git", rev = "c3d754ef77b9fce585b46b972af751fe6e7a9803" } +macros = { path = "macros", version = "0.1.0" } diff --git a/macros/Cargo.toml b/macros/Cargo.toml new file mode 100644 index 00000000..dbc57525 --- /dev/null +++ b/macros/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "proofman-macros" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +syn = { version = "2", features = ["full"] } +quote = "1" +proc-macro2 = "1" diff --git a/macros/src/lib.rs b/macros/src/lib.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/macros/src/lib.rs @@ -0,0 +1 @@ + From 7a0dcbe426e1b2fa9a78920d754ae52fc6d384a4 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Thu, 5 Sep 2024 12:41:57 -0400 Subject: [PATCH 02/15] almost --- Cargo.lock | 1 + Cargo.toml | 2 +- common/Cargo.toml | 5 +- macros/src/lib.rs | 222 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 227 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7018d72f..767076f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -631,6 +631,7 @@ dependencies = [ "log", "p3-field", "pilout", + "proofman-macros", "proofman-starks-lib-c", "proofman-util", "serde", diff --git a/Cargo.toml b/Cargo.toml index f235098a..1fe8a80a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,4 +24,4 @@ log = { version = "0.4", default-features = false } env_logger = "0.11" p3-goldilocks = { git = "https://github.com/Plonky3/Plonky3.git", rev = "c3d754ef77b9fce585b46b972af751fe6e7a9803" } p3-field = { git = "https://github.com/Plonky3/Plonky3.git", rev = "c3d754ef77b9fce585b46b972af751fe6e7a9803" } -macros = { path = "macros", version = "0.1.0" } +proofman-macros = { path = "macros", version = "0.1.0" } diff --git a/common/Cargo.toml b/common/Cargo.toml index ee13a6c7..66e77389 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -8,8 +8,9 @@ serde = { version = "1.0.130", features = ["derive"] } serde_json = "1.0.68" serde_derive = "1.0.196" pilout = { path = "../pilout" } -log = { workspace = true } +log.workspace = true transcript = { path = "../transcript" } -p3-field = { workspace = true } +p3-field.workspace = true +proofman-macros.workspace = true proofman-util = { path = "../util" } proofman-starks-lib-c = { path = "../provers/starks-lib-c" } diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 8b137891..74d5487b 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1 +1,223 @@ +use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, format_ident, ToTokens}; +use syn::{parse2, DeriveInput, FieldsNamed, Ident, Type, Result, Field}; +#[proc_macro] +pub fn trace(input: TokenStream) -> TokenStream { + match trace_impl(input.into()) { + Ok(tokens) => tokens.into(), + Err(e) => e.to_compile_error().into(), + } +} + +fn trace_impl(input: TokenStream2) -> Result { + let derive_input = parse2::(input)?; + + // Extract the struct name and generic parameters + let row_struct_name = &derive_input.ident; + let trace_struct_name = format_ident!("{}Trace", row_struct_name); + + let generic_param = &derive_input.generics.params.first().unwrap(); // Assuming there's one generic param (like ) + + // Extract fields from the struct + let fields_def = match &derive_input.data { + syn::Data::Struct(data_struct) => match &data_struct.fields { + syn::Fields::Named(FieldsNamed { named, .. }) => named, + _ => return Err(syn::Error::new_spanned(derive_input, "Expected named fields")), + }, + _ => return Err(syn::Error::new_spanned(derive_input, "Expected struct data")), + }; + + // Build up the integer literal for ROW_SIZE + let row_size = fields_def.iter().map(|field| calculate_field_size_literal(&field.ty)).sum::(); + + // Generate the row struct + let field_definitions = fields_def.iter().map(|field| { + let Field { ident, ty, .. } = field; + quote! { pub #ident: #ty, } + }); + + let row_struct = quote! { + #[derive(Debug, Clone, Copy, Default)] + pub struct #row_struct_name<#generic_param> { + #(#field_definitions)* + } + }; + + // Generate the trace struct + let trace_struct = quote! { + pub struct #trace_struct_name<'a, #generic_param> { + pub buffer: Option>, + pub slice_trace: &'a mut [#row_struct_name<#generic_param>], + num_rows: usize, + } + }; + + let impl_block = quote! { + impl<#generic_param: Default + Clone + Copy> #trace_struct_name<'_, #generic_param> { + pub const ROW_SIZE: usize = #row_size; + + pub fn new(num_rows: usize) -> Self { + assert!(num_rows >= 2); + assert!(num_rows & (num_rows - 1) == 0); + let buffer = vec![#generic_param::default(); num_rows * Self::ROW_SIZE]; + let slice_trace = unsafe { + std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut #row_struct_name<#generic_param>, num_rows) + }; + Self { buffer: Some(buffer), slice_trace, num_rows } + } + + pub fn num_rows(&self) -> usize { + self.num_rows + } + } + + impl<'a, #generic_param> std::ops::Index for #trace_struct_name<'a, #generic_param> { + type Output = #row_struct_name<#generic_param>; + + fn index(&self, index: usize) -> &Self::Output { + &self.slice_trace[index] + } + } + + impl<'a, #generic_param> std::ops::IndexMut for #trace_struct_name<'a, #generic_param> { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + &mut self.slice_trace[index] + } + } + }; + + Ok(quote! { + #row_struct + #trace_struct + #impl_block + }) +} + +// Calculate the size of a field based on its type and return it as a usize literal +fn calculate_field_size_literal(field_type: &Type) -> usize { + match field_type { + // Handle arrays with multiple dimensions + Type::Array(type_array) => { + let len = type_array.len.to_token_stream().to_string().parse::().unwrap(); + let elem_size = calculate_field_size_literal(&type_array.elem); + len * elem_size + } + // For simple types, the size is 1 + _ => 1, + } +} + +// Tests + +#[test] +fn test_simple_struct() { + let input = quote! { + struct TraceRow1 { a: F, b: F, c: F } + }; + + let expected = quote! { + pub struct TraceRow1 { + pub a: F, + pub b: F, + pub c: F, + } + pub struct TraceRow1Trace<'a, F> { + pub buffer: Option>, + pub slice_trace: &'a mut [TraceRow1], + num_rows: usize, + } + impl TraceRow1Trace<'_, F> { + pub const ROW_SIZE: usize = 3usize; + + pub fn new(num_rows: usize) -> Self { + assert!(num_rows >= 2); + assert!(num_rows & (num_rows - 1) == 0); + let buffer = vec![F::default(); num_rows * Self::ROW_SIZE]; + let slice_trace = unsafe { + std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut TraceRow1, num_rows) + }; + Self { buffer: Some(buffer), slice_trace, num_rows } + } + + pub fn num_rows(&self) -> usize { + self.num_rows + } + } + + impl<'a, F> std::ops::Index for TraceRow1Trace<'a, F> { + type Output = TraceRow1; + + fn index(&self, index: usize) -> &Self::Output { + &self.slice_trace[index] + } + } + + impl<'a, F> std::ops::IndexMut for TraceRow1Trace<'a, F> { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + &mut self.slice_trace[index] + } + } + }; + + let parsed_input = parse2::(input).unwrap(); + let generated = trace_impl(parsed_input.into_token_stream()).unwrap(); + + assert_eq!(generated.to_string(), expected.to_string()); +} + +#[test] +fn test_three_dimensional_array() { + let input = quote! { + struct TraceRow3 { a: [[F; 3]; 2], b: F } + }; + + let expected = quote! { + pub struct TraceRow3 { + pub a: [[F; 3]; 2], + pub b: F, + } + pub struct TraceRow3Trace<'a, F> { + pub buffer: Option>, + pub slice_trace: &'a mut [TraceRow3], + num_rows: usize, + } + impl TraceRow3Trace<'_, F> { + pub const ROW_SIZE: usize = 7usize; + + pub fn new(num_rows: usize) -> Self { + assert!(num_rows >= 2); + assert!(num_rows & (num_rows - 1) == 0); + let buffer = vec![F::default(); num_rows * Self::ROW_SIZE]; + let slice_trace = unsafe { + std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut TraceRow3, num_rows) + }; + Self { buffer: Some(buffer), slice_trace, num_rows } + } + + pub fn num_rows(&self) -> usize { + self.num_rows + } + } + + impl<'a, F> std::ops::Index for TraceRow3Trace<'a, F> { + type Output = TraceRow3; + + fn index(&self, index: usize) -> &Self::Output { + &self.slice_trace[index] + } + } + + impl<'a, F> std::ops::IndexMut for TraceRow3Trace<'a, F> { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + &mut self.slice_trace[index] + } + } + }; + + let parsed_input = parse2::(input).unwrap(); + let generated = trace_impl(parsed_input.into_token_stream()).unwrap(); + + assert_eq!(generated.to_string(), expected.to_string()); +} From fe8a9e5aaee7bac73587a91ec50a285534285d55 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 6 Sep 2024 05:13:31 -0400 Subject: [PATCH 03/15] test_simple_struct() passing! --- macros/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 74d5487b..4b12dbba 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -109,8 +109,6 @@ fn calculate_field_size_literal(field_type: &Type) -> usize { } } -// Tests - #[test] fn test_simple_struct() { let input = quote! { @@ -118,6 +116,7 @@ fn test_simple_struct() { }; let expected = quote! { + #[derive(Debug, Clone, Copy, Default)] pub struct TraceRow1 { pub a: F, pub b: F, @@ -164,7 +163,8 @@ fn test_simple_struct() { let parsed_input = parse2::(input).unwrap(); let generated = trace_impl(parsed_input.into_token_stream()).unwrap(); - assert_eq!(generated.to_string(), expected.to_string()); + // Compare ignoring spaces + assert_eq!(generated.to_string().replace(" ", ""), expected.into_token_stream().to_string().replace(" ", "")); } #[test] From 16b64cb834837aac714a7406f8ab9d1368bd7a6b Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 6 Sep 2024 05:14:41 -0400 Subject: [PATCH 04/15] both passing! :tada: --- macros/src/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 4b12dbba..14e78339 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,7 +1,7 @@ use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::{quote, format_ident, ToTokens}; -use syn::{parse2, DeriveInput, FieldsNamed, Ident, Type, Result, Field}; +use syn::{parse2, DeriveInput, FieldsNamed, Type, Result, Field}; #[proc_macro] pub fn trace(input: TokenStream) -> TokenStream { @@ -174,6 +174,7 @@ fn test_three_dimensional_array() { }; let expected = quote! { + #[derive(Debug, Clone, Copy, Default)] pub struct TraceRow3 { pub a: [[F; 3]; 2], pub b: F, @@ -219,5 +220,6 @@ fn test_three_dimensional_array() { let parsed_input = parse2::(input).unwrap(); let generated = trace_impl(parsed_input.into_token_stream()).unwrap(); - assert_eq!(generated.to_string(), expected.to_string()); + // Compare ignoring spaces + assert_eq!(generated.to_string().replace(" ", ""), expected.into_token_stream().to_string().replace(" ", "")); } From b74b090a09f80fb61c84bd6eb69be9caa6473528 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 6 Sep 2024 05:21:23 -0400 Subject: [PATCH 05/15] add another test case --- macros/src/lib.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 14e78339..21274ce6 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -168,7 +168,7 @@ fn test_simple_struct() { } #[test] -fn test_three_dimensional_array() { +fn test_two_dimensional_array_01() { let input = quote! { struct TraceRow3 { a: [[F; 3]; 2], b: F } }; @@ -223,3 +223,59 @@ fn test_three_dimensional_array() { // Compare ignoring spaces assert_eq!(generated.to_string().replace(" ", ""), expected.into_token_stream().to_string().replace(" ", "")); } + +#[test] +fn test_two_dimensional_array_02() { + let input = quote! { + struct TraceRow2 { a: [[F; 3]; 2] } + }; + + let expected = quote! { + #[derive(Debug, Clone, Copy, Default)] + pub struct TraceRow2 { + pub a: [[F; 3]; 2], + } + pub struct TraceRow2Trace<'a, F> { + pub buffer: Option>, + pub slice_trace: &'a mut [TraceRow2], + num_rows: usize, + } + impl TraceRow2Trace<'_, F> { + pub const ROW_SIZE: usize = 6usize; // 2 * (3 * 1) + + pub fn new(num_rows: usize) -> Self { + assert!(num_rows >= 2); + assert!(num_rows & (num_rows - 1) == 0); + let buffer = vec![F::default(); num_rows * Self::ROW_SIZE]; + let slice_trace = unsafe { + std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut TraceRow2, num_rows) + }; + Self { buffer: Some(buffer), slice_trace, num_rows } + } + + pub fn num_rows(&self) -> usize { + self.num_rows + } + } + + impl<'a, F> std::ops::Index for TraceRow2Trace<'a, F> { + type Output = TraceRow2; + + fn index(&self, index: usize) -> &Self::Output { + &self.slice_trace[index] + } + } + + impl<'a, F> std::ops::IndexMut for TraceRow2Trace<'a, F> { + fn index_mut(&mut self, index: usize) -> &mut Self::Output { + &mut self.slice_trace[index] + } + } + }; + + let parsed_input = parse2::(input).unwrap(); + let generated = trace_impl(parsed_input.into_token_stream()).unwrap(); + + // Compare ignoring spaces + assert_eq!(generated.to_string().replace(" ", ""), expected.into_token_stream().to_string().replace(" ", "")); +} From 20fa0c39020e850ae7f94eabacaede942b571be0 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 6 Sep 2024 07:37:30 -0400 Subject: [PATCH 06/15] checkpoint --- common/src/trace.rs | 266 ++++++++------------------------------------ macros/src/lib.rs | 185 +++++++++++++----------------- 2 files changed, 119 insertions(+), 332 deletions(-) diff --git a/common/src/trace.rs b/common/src/trace.rs index b5db8839..32546b4d 100644 --- a/common/src/trace.rs +++ b/common/src/trace.rs @@ -3,236 +3,58 @@ pub trait Trace: Send { fn get_buffer_ptr(&mut self) -> *mut u8; } -#[macro_export] -macro_rules! trace { - ($row_struct_name:ident, $trace_struct_name:ident<$generic:ident> { - $( $field_name:ident : $field_type:ty ),* $(,)? - }) => { - // Define the row structure (Main0RowTrace) - #[allow(dead_code)] - #[derive(Debug, Clone, Copy, Default)] - pub struct $row_struct_name<$generic> { - $( pub $field_name: $field_type ),* - } +pub use proofman_macros::trace; +#[test] +fn check() { + const OFFSET: usize = 1; + let num_rows = 8; - impl<$generic: Copy> $row_struct_name<$generic> { - // The size of each row in terms of the number of fields - pub const ROW_SIZE: usize = 0 $(+ trace!(@count_elements $field_type))*; - } + trace!(TraceRow, MyTrace { a: F, b: F }); - // Define the trace structure (Main0Trace) that manages the row structure - pub struct $trace_struct_name<'a, $generic> { - pub buffer: Option>, - pub slice_trace: &'a mut [$row_struct_name<$generic>], - num_rows: usize, - } + let mut buffer = vec![0usize; num_rows * TraceRow::::ROW_SIZE + OFFSET]; + let trace = MyTrace::map_buffer(&mut buffer, num_rows, OFFSET); + let mut trace = trace.unwrap(); - impl<'a, $generic: Default + Clone + Copy> $trace_struct_name<'a, $generic> { - // Constructor for creating a new buffer - pub fn new(num_rows: usize) -> Self { - // PRECONDITIONS - // num_rows must be greater than or equal to 2 - assert!(num_rows >= 2); - // num_rows must be a power of 2 - assert!(num_rows & (num_rows - 1) == 0); - - let buffer = vec![$generic::default(); num_rows * $row_struct_name::<$generic>::ROW_SIZE]; - - let slice_trace = unsafe { - std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut $row_struct_name<$generic>, num_rows) - }; - - $trace_struct_name { buffer: Some(buffer), slice_trace, num_rows } - } - - // Constructor to map over an external buffer - pub fn map_buffer(external_buffer: &'a mut [$generic], num_rows: usize, offset: usize) -> Result> { - // PRECONDITIONS - // num_rows must be greater than or equal to 2 - assert!(num_rows >= 2); - // num_rows must be a power of 2 - assert!(num_rows & (num_rows - 1) == 0); - - let start = offset; - let end = start + num_rows * $row_struct_name::<$generic>::ROW_SIZE; - - if end > external_buffer.len() { - return Err("Buffer is too small to fit the trace".into()); - } - - let slice_trace = unsafe { - std::slice::from_raw_parts_mut( - external_buffer[start..end].as_ptr() as *mut $row_struct_name<$generic>, - num_rows, - ) - }; - - Ok($trace_struct_name { - buffer: None, - slice_trace, - num_rows, - }) - } - - // Constructor to map over an external buffer - pub fn map_row_vec(external_buffer: Vec<$row_struct_name<$generic>>) -> Result> { - let num_rows = external_buffer.len().next_power_of_two(); - - // PRECONDITIONS - // num_rows must be greater than or equal to 2 - assert!(num_rows >= 2); - // num_rows must be a power of 2 - assert!(num_rows & (num_rows - 1) == 0); - - let slice_trace = unsafe { - let ptr = external_buffer.as_ptr() as *mut $row_struct_name<$generic>; - std::slice::from_raw_parts_mut(ptr, - num_rows, - ) - }; - - let buffer_f = unsafe { - Vec::from_raw_parts(external_buffer.as_ptr() as *mut $generic, num_rows * $row_struct_name::<$generic>::ROW_SIZE, num_rows * $row_struct_name::<$generic>::ROW_SIZE) - }; - - std::mem::forget(external_buffer); - - Ok($trace_struct_name { - buffer: Some(buffer_f), - slice_trace, - num_rows, - }) - } - - pub fn num_rows(&self) -> usize { - self.num_rows - } - } - - // Implement Index trait for immutable access - impl<'a, $generic> std::ops::Index for $trace_struct_name<'a, $generic> { - type Output = $row_struct_name<$generic>; - - fn index(&self, index: usize) -> &Self::Output { - &self.slice_trace[index] - } - } - - // Implement IndexMut trait for mutable access - impl<'a, $generic> std::ops::IndexMut for $trace_struct_name<'a, $generic> { - fn index_mut(&mut self, index: usize) -> &mut Self::Output { - &mut self.slice_trace[index] - } - } - - // Implement the Trace trait - impl<'a, $generic: Send > $crate::trace::Trace for $trace_struct_name<'a, $generic> { - fn num_rows(&self) -> usize { - self.num_rows - } - - fn get_buffer_ptr(&mut self) -> *mut u8 { - let buffer = self.buffer.as_mut().expect("Buffer is not available"); - buffer.as_mut_ptr() as *mut u8 - } - } - }; - - (@count_elements $elem_type:ty) => { - if std::mem::size_of::<$elem_type>() == 8 { - 1 - } else if std::mem::size_of::<$elem_type>() == std::mem::size_of::<&str>() { - trace!(@parse_string $elem_type) - } else { - 0 - } - }; - - (@parse_string $elem_type:ty) => { - // Check if the element type is a string array - if true { - let field_str = stringify!($elem_type); - let a_bytes = "[F; 2]".as_bytes(); - let b_bytes = field_str.as_bytes(); - let mut result = 0; - let mut i = 0; - let mut c = 0; - if a_bytes.len() == b_bytes.len() { - while i < b_bytes.len() { - if a_bytes[i] != b_bytes[i] { - c+=1; - } - i+=1; - } - if c == 0 { - result = 2; - } - } - result - - } else { - 0 - } - }; -} -#[cfg(test)] -mod tests { - // use rand::Rng; - - #[test] - fn check() { - const OFFSET: usize = 1; - let num_rows = 8; - - trace!(TraceRow, MyTrace { a: F, b:F}); - - assert_eq!(TraceRow::::ROW_SIZE, 2); - - let mut buffer = vec![0usize; num_rows * TraceRow::::ROW_SIZE + OFFSET]; - let trace = MyTrace::map_buffer(&mut buffer, num_rows, OFFSET); - let mut trace = trace.unwrap(); - - // Set values - for i in 0..num_rows { - trace[i].a = i; - trace[i].b = i * 10; - } - - // Check values - for i in 0..num_rows { - assert_eq!(trace[i].a, i); - assert_eq!(trace[i].b, i * 10); - } + // Set values + for i in 0..num_rows { + trace[i].a = i; + trace[i].b = i * 10; } - #[test] - #[should_panic] - fn test_errors_are_launched_when_num_rows_is_invalid_1() { - let mut buffer = vec![0u8; 3]; - trace!(SimpleRow, Simple { a: F }); - let _ = Simple::map_buffer(&mut buffer, 1, 0); + // Check values + for i in 0..num_rows { + assert_eq!(trace[i].a, i); + assert_eq!(trace[i].b, i * 10); } +} - #[test] - #[should_panic] - fn test_errors_are_launched_when_num_rows_is_invalid_2() { - let mut buffer = vec![0u8; 3]; - trace!(SimpleRow, Simple { a: F }); - let _ = Simple::map_buffer(&mut buffer, 3, 0); - } +#[test] +#[should_panic] +fn test_errors_are_launched_when_num_rows_is_invalid_1() { + let mut buffer = vec![0u8; 3]; + trace!(SimpleRow, Simple { a: F }); + let _ = Simple::map_buffer(&mut buffer, 1, 0); +} - #[test] - #[should_panic] - fn test_errors_are_launched_when_num_rows_is_invalid_3() { - trace!(SimpleRow, Simple { a: F }); - let _ = Simple::::new(1); - } +#[test] +#[should_panic] +fn test_errors_are_launched_when_num_rows_is_invalid_2() { + let mut buffer = vec![0u8; 3]; + trace!(SimpleRow, Simple { a: F }); + let _ = Simple::map_buffer(&mut buffer, 3, 0); +} - #[test] - #[should_panic] - fn test_errors_are_launched_when_num_rows_is_invalid_4() { - trace!(SimpleRow, Simple { a: F }); - let _ = Simple::::new(3); - } +#[test] +#[should_panic] +fn test_errors_are_launched_when_num_rows_is_invalid_3() { + trace!(SimpleRow, Simple { a: F }); + let _ = Simple::::new(1); +} + +#[test] +#[should_panic] +fn test_errors_are_launched_when_num_rows_is_invalid_4() { + trace!(SimpleRow, Simple { a: F }); + let _ = Simple::::new(3); } diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 21274ce6..50876c8c 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -1,7 +1,11 @@ use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::{quote, format_ident, ToTokens}; -use syn::{parse2, DeriveInput, FieldsNamed, Type, Result, Field}; +use syn::{ + parse2, + parse::{Parse, ParseStream}, + Ident, Generics, FieldsNamed, Result, Field, Token, +}; #[proc_macro] pub fn trace(input: TokenStream) -> TokenStream { @@ -12,40 +16,30 @@ pub fn trace(input: TokenStream) -> TokenStream { } fn trace_impl(input: TokenStream2) -> Result { - let derive_input = parse2::(input)?; + let parsed_input: ParsedTraceInput = parse2(input)?; - // Extract the struct name and generic parameters - let row_struct_name = &derive_input.ident; - let trace_struct_name = format_ident!("{}Trace", row_struct_name); + let row_struct_name = parsed_input.row_struct_name; + let trace_struct_name = parsed_input.struct_name; + let generic_param = parsed_input.generics; + let fields = parsed_input.fields; - let generic_param = &derive_input.generics.params.first().unwrap(); // Assuming there's one generic param (like ) + // Calculate ROW_SIZE + let row_size = fields.named.iter().map(|field| calculate_field_size_literal(&field.ty)).sum::(); - // Extract fields from the struct - let fields_def = match &derive_input.data { - syn::Data::Struct(data_struct) => match &data_struct.fields { - syn::Fields::Named(FieldsNamed { named, .. }) => named, - _ => return Err(syn::Error::new_spanned(derive_input, "Expected named fields")), - }, - _ => return Err(syn::Error::new_spanned(derive_input, "Expected struct data")), - }; - - // Build up the integer literal for ROW_SIZE - let row_size = fields_def.iter().map(|field| calculate_field_size_literal(&field.ty)).sum::(); - - // Generate the row struct - let field_definitions = fields_def.iter().map(|field| { + // Generate row struct + let field_definitions = fields.named.iter().map(|field| { let Field { ident, ty, .. } = field; quote! { pub #ident: #ty, } }); let row_struct = quote! { #[derive(Debug, Clone, Copy, Default)] - pub struct #row_struct_name<#generic_param> { + pub struct #row_struct_name #generic_param { #(#field_definitions)* } }; - // Generate the trace struct + // Generate trace struct let trace_struct = quote! { pub struct #trace_struct_name<'a, #generic_param> { pub buffer: Option>, @@ -95,11 +89,42 @@ fn trace_impl(input: TokenStream2) -> Result { }) } +// A struct to handle parsing the input and all the syntactic variations +struct ParsedTraceInput { + row_struct_name: Ident, + struct_name: Ident, + generics: Generics, + fields: FieldsNamed, +} + +impl Parse for ParsedTraceInput { + fn parse(input: ParseStream) -> Result { + let lookahead = input.lookahead1(); + let row_struct_name; + + // Handle explicit or implicit row struct names + if lookahead.peek(Ident) && input.peek2(Token![,]) { + row_struct_name = Some(input.parse::()?); + input.parse::()?; // Skip comma after explicit row name + } else { + row_struct_name = None; + } + + let struct_name = input.parse::()?; + let row_struct_name = row_struct_name.unwrap_or_else(|| format_ident!("{}Row", struct_name)); + + let generics: Generics = input.parse()?; + let fields: FieldsNamed = input.parse()?; + + Ok(ParsedTraceInput { row_struct_name, struct_name, generics, fields }) + } +} + // Calculate the size of a field based on its type and return it as a usize literal -fn calculate_field_size_literal(field_type: &Type) -> usize { +fn calculate_field_size_literal(field_type: &syn::Type) -> usize { match field_type { // Handle arrays with multiple dimensions - Type::Array(type_array) => { + syn::Type::Array(type_array) => { let len = type_array.len.to_token_stream().to_string().parse::().unwrap(); let elem_size = calculate_field_size_literal(&type_array.elem); len * elem_size @@ -109,25 +134,27 @@ fn calculate_field_size_literal(field_type: &Type) -> usize { } } +// Tests + #[test] -fn test_simple_struct() { +fn test_simple_struct_without_struct_keyword() { let input = quote! { - struct TraceRow1 { a: F, b: F, c: F } + Simple { a: F, b: F, c: F } }; let expected = quote! { #[derive(Debug, Clone, Copy, Default)] - pub struct TraceRow1 { + pub struct Simple { pub a: F, pub b: F, pub c: F, } - pub struct TraceRow1Trace<'a, F> { + pub struct SimpleRow<'a, F> { pub buffer: Option>, - pub slice_trace: &'a mut [TraceRow1], + pub slice_trace: &'a mut [SimpleRow], num_rows: usize, } - impl TraceRow1Trace<'_, F> { + impl SimpleRow<'_, F> { pub const ROW_SIZE: usize = 3usize; pub fn new(num_rows: usize) -> Self { @@ -135,7 +162,7 @@ fn test_simple_struct() { assert!(num_rows & (num_rows - 1) == 0); let buffer = vec![F::default(); num_rows * Self::ROW_SIZE]; let slice_trace = unsafe { - std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut TraceRow1, num_rows) + std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut SimpleRow, num_rows) }; Self { buffer: Some(buffer), slice_trace, num_rows } } @@ -145,110 +172,51 @@ fn test_simple_struct() { } } - impl<'a, F> std::ops::Index for TraceRow1Trace<'a, F> { - type Output = TraceRow1; + impl<'a, F> std::ops::Index for SimpleRow<'a, F> { + type Output = SimpleRow; fn index(&self, index: usize) -> &Self::Output { &self.slice_trace[index] } } - impl<'a, F> std::ops::IndexMut for TraceRow1Trace<'a, F> { + impl<'a, F> std::ops::IndexMut for SimpleRow<'a, F> { fn index_mut(&mut self, index: usize) -> &mut Self::Output { &mut self.slice_trace[index] } } }; - let parsed_input = parse2::(input).unwrap(); - let generated = trace_impl(parsed_input.into_token_stream()).unwrap(); - - // Compare ignoring spaces + let generated = trace_impl(input.into()).unwrap(); assert_eq!(generated.to_string().replace(" ", ""), expected.into_token_stream().to_string().replace(" ", "")); } #[test] -fn test_two_dimensional_array_01() { +fn test_explicit_row_and_trace_struct() { let input = quote! { - struct TraceRow3 { a: [[F; 3]; 2], b: F } + SimpleRow, Simple { a: F, b: F } }; let expected = quote! { #[derive(Debug, Clone, Copy, Default)] - pub struct TraceRow3 { - pub a: [[F; 3]; 2], + pub struct SimpleRow { + pub a: F, pub b: F, } - pub struct TraceRow3Trace<'a, F> { - pub buffer: Option>, - pub slice_trace: &'a mut [TraceRow3], - num_rows: usize, - } - impl TraceRow3Trace<'_, F> { - pub const ROW_SIZE: usize = 7usize; - - pub fn new(num_rows: usize) -> Self { - assert!(num_rows >= 2); - assert!(num_rows & (num_rows - 1) == 0); - let buffer = vec![F::default(); num_rows * Self::ROW_SIZE]; - let slice_trace = unsafe { - std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut TraceRow3, num_rows) - }; - Self { buffer: Some(buffer), slice_trace, num_rows } - } - - pub fn num_rows(&self) -> usize { - self.num_rows - } - } - - impl<'a, F> std::ops::Index for TraceRow3Trace<'a, F> { - type Output = TraceRow3; - - fn index(&self, index: usize) -> &Self::Output { - &self.slice_trace[index] - } - } - - impl<'a, F> std::ops::IndexMut for TraceRow3Trace<'a, F> { - fn index_mut(&mut self, index: usize) -> &mut Self::Output { - &mut self.slice_trace[index] - } - } - }; - - let parsed_input = parse2::(input).unwrap(); - let generated = trace_impl(parsed_input.into_token_stream()).unwrap(); - - // Compare ignoring spaces - assert_eq!(generated.to_string().replace(" ", ""), expected.into_token_stream().to_string().replace(" ", "")); -} - -#[test] -fn test_two_dimensional_array_02() { - let input = quote! { - struct TraceRow2 { a: [[F; 3]; 2] } - }; - - let expected = quote! { - #[derive(Debug, Clone, Copy, Default)] - pub struct TraceRow2 { - pub a: [[F; 3]; 2], - } - pub struct TraceRow2Trace<'a, F> { + pub struct Simple<'a, F> { pub buffer: Option>, - pub slice_trace: &'a mut [TraceRow2], + pub slice_trace: &'a mut [SimpleRow], num_rows: usize, } - impl TraceRow2Trace<'_, F> { - pub const ROW_SIZE: usize = 6usize; // 2 * (3 * 1) + impl Simple<'_, F> { + pub const ROW_SIZE: usize = 2usize; pub fn new(num_rows: usize) -> Self { assert!(num_rows >= 2); assert!(num_rows & (num_rows - 1) == 0); let buffer = vec![F::default(); num_rows * Self::ROW_SIZE]; let slice_trace = unsafe { - std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut TraceRow2, num_rows) + std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut SimpleRow, num_rows) }; Self { buffer: Some(buffer), slice_trace, num_rows } } @@ -258,24 +226,21 @@ fn test_two_dimensional_array_02() { } } - impl<'a, F> std::ops::Index for TraceRow2Trace<'a, F> { - type Output = TraceRow2; + impl<'a, F> std::ops::Index for Simple<'a, F> { + type Output = Simple; fn index(&self, index: usize) -> &Self::Output { &self.slice_trace[index] } } - impl<'a, F> std::ops::IndexMut for TraceRow2Trace<'a, F> { + impl<'a, F> std::ops::IndexMut for Simple<'a, F> { fn index_mut(&mut self, index: usize) -> &mut Self::Output { &mut self.slice_trace[index] } } }; - let parsed_input = parse2::(input).unwrap(); - let generated = trace_impl(parsed_input.into_token_stream()).unwrap(); - - // Compare ignoring spaces + let generated = trace_impl(input.into()).unwrap(); assert_eq!(generated.to_string().replace(" ", ""), expected.into_token_stream().to_string().replace(" ", "")); } From c0cf9c8f45c87243c613a06a26c2e79d3909ff78 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 6 Sep 2024 07:48:05 -0400 Subject: [PATCH 07/15] add parsing tests --- macros/src/lib.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 50876c8c..9b7a2792 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -244,3 +244,33 @@ fn test_explicit_row_and_trace_struct() { let generated = trace_impl(input.into()).unwrap(); assert_eq!(generated.to_string().replace(" ", ""), expected.into_token_stream().to_string().replace(" ", "")); } + +#[test] +fn test_parsing_01() { + let input = quote! { + TraceRow, MyTrace { a: F, b: F } + }; + let parsed: ParsedTraceInput = parse2(input).unwrap(); + assert_eq!(parsed.row_struct_name, "TraceRow"); + assert_eq!(parsed.struct_name, "MyTrace"); +} + +#[test] +fn test_parsing_02() { + let input = quote! { + SimpleRow, Simple { a: F } + }; + let parsed: ParsedTraceInput = parse2(input).unwrap(); + assert_eq!(parsed.row_struct_name, "SimpleRow"); + assert_eq!(parsed.struct_name, "Simple"); +} + +#[test] +fn test_parsing_03() { + let input = quote! { + Simple { a: F } + }; + let parsed: ParsedTraceInput = parse2(input).unwrap(); + assert_eq!(parsed.row_struct_name, "SimpleRow"); + assert_eq!(parsed.struct_name, "Simple"); +} From 5f593bbde58b6abbcb0aebdc397d7f8b4488b8e0 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 6 Sep 2024 08:26:20 -0400 Subject: [PATCH 08/15] fix generics issue --- macros/src/lib.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 9b7a2792..a9ac8050 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -20,7 +20,7 @@ fn trace_impl(input: TokenStream2) -> Result { let row_struct_name = parsed_input.row_struct_name; let trace_struct_name = parsed_input.struct_name; - let generic_param = parsed_input.generics; + let generics = parsed_input.generics.params; let fields = parsed_input.fields; // Calculate ROW_SIZE @@ -34,30 +34,30 @@ fn trace_impl(input: TokenStream2) -> Result { let row_struct = quote! { #[derive(Debug, Clone, Copy, Default)] - pub struct #row_struct_name #generic_param { + pub struct #row_struct_name<#generics> { #(#field_definitions)* } }; - // Generate trace struct + // Generate trace struct with lifetime let trace_struct = quote! { - pub struct #trace_struct_name<'a, #generic_param> { - pub buffer: Option>, - pub slice_trace: &'a mut [#row_struct_name<#generic_param>], + pub struct #trace_struct_name<'a, #generics> { + pub buffer: Option>, + pub slice_trace: &'a mut [#row_struct_name<#generics>], num_rows: usize, } }; let impl_block = quote! { - impl<#generic_param: Default + Clone + Copy> #trace_struct_name<'_, #generic_param> { + impl<#generics: Default + Clone + Copy> #trace_struct_name<'_, #generics> { pub const ROW_SIZE: usize = #row_size; pub fn new(num_rows: usize) -> Self { assert!(num_rows >= 2); assert!(num_rows & (num_rows - 1) == 0); - let buffer = vec![#generic_param::default(); num_rows * Self::ROW_SIZE]; + let buffer = vec![#generics::default(); num_rows * Self::ROW_SIZE]; let slice_trace = unsafe { - std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut #row_struct_name<#generic_param>, num_rows) + std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut #row_struct_name<#generics>, num_rows) }; Self { buffer: Some(buffer), slice_trace, num_rows } } @@ -67,15 +67,15 @@ fn trace_impl(input: TokenStream2) -> Result { } } - impl<'a, #generic_param> std::ops::Index for #trace_struct_name<'a, #generic_param> { - type Output = #row_struct_name<#generic_param>; + impl<'a, #generics> std::ops::Index for #trace_struct_name<'a, #generics> { + type Output = #row_struct_name<#generics>; fn index(&self, index: usize) -> &Self::Output { &self.slice_trace[index] } } - impl<'a, #generic_param> std::ops::IndexMut for #trace_struct_name<'a, #generic_param> { + impl<'a, #generics> std::ops::IndexMut for #trace_struct_name<'a, #generics> { fn index_mut(&mut self, index: usize) -> &mut Self::Output { &mut self.slice_trace[index] } From 6cb767fd32374f303986f203ecf27ce0c777a83f Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 6 Sep 2024 08:36:57 -0400 Subject: [PATCH 09/15] tests passing, still some subtle downstream compile-time issues --- macros/src/lib.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index a9ac8050..851dd57c 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -134,8 +134,6 @@ fn calculate_field_size_literal(field_type: &syn::Type) -> usize { } } -// Tests - #[test] fn test_simple_struct_without_struct_keyword() { let input = quote! { @@ -144,17 +142,17 @@ fn test_simple_struct_without_struct_keyword() { let expected = quote! { #[derive(Debug, Clone, Copy, Default)] - pub struct Simple { + pub struct SimpleRow { pub a: F, pub b: F, pub c: F, } - pub struct SimpleRow<'a, F> { + pub struct Simple<'a, F> { pub buffer: Option>, pub slice_trace: &'a mut [SimpleRow], num_rows: usize, } - impl SimpleRow<'_, F> { + impl Simple<'_, F> { pub const ROW_SIZE: usize = 3usize; pub fn new(num_rows: usize) -> Self { @@ -172,7 +170,7 @@ fn test_simple_struct_without_struct_keyword() { } } - impl<'a, F> std::ops::Index for SimpleRow<'a, F> { + impl<'a, F> std::ops::Index for Simple<'a, F> { type Output = SimpleRow; fn index(&self, index: usize) -> &Self::Output { @@ -180,7 +178,7 @@ fn test_simple_struct_without_struct_keyword() { } } - impl<'a, F> std::ops::IndexMut for SimpleRow<'a, F> { + impl<'a, F> std::ops::IndexMut for Simple<'a, F> { fn index_mut(&mut self, index: usize) -> &mut Self::Output { &mut self.slice_trace[index] } @@ -188,7 +186,7 @@ fn test_simple_struct_without_struct_keyword() { }; let generated = trace_impl(input.into()).unwrap(); - assert_eq!(generated.to_string().replace(" ", ""), expected.into_token_stream().to_string().replace(" ", "")); + assert_eq!(generated.to_string(), expected.into_token_stream().to_string()); } #[test] @@ -227,7 +225,7 @@ fn test_explicit_row_and_trace_struct() { } impl<'a, F> std::ops::Index for Simple<'a, F> { - type Output = Simple; + type Output = SimpleRow; fn index(&self, index: usize) -> &Self::Output { &self.slice_trace[index] @@ -242,7 +240,7 @@ fn test_explicit_row_and_trace_struct() { }; let generated = trace_impl(input.into()).unwrap(); - assert_eq!(generated.to_string().replace(" ", ""), expected.into_token_stream().to_string().replace(" ", "")); + assert_eq!(generated.to_string(), expected.into_token_stream().to_string()); } #[test] From eee4fc27d9d99e08eaaffac9902ae11a530d34bf Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 6 Sep 2024 09:26:22 -0400 Subject: [PATCH 10/15] downstream tests passing! --- common/src/trace.rs | 3 ++ macros/src/lib.rs | 78 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 72 insertions(+), 9 deletions(-) diff --git a/common/src/trace.rs b/common/src/trace.rs index 32546b4d..451797a8 100644 --- a/common/src/trace.rs +++ b/common/src/trace.rs @@ -5,6 +5,9 @@ pub trait Trace: Send { pub use proofman_macros::trace; +#[cfg(test)] +use crate as common; + #[test] fn check() { const OFFSET: usize = 1; diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 851dd57c..952e793d 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -37,29 +37,79 @@ fn trace_impl(input: TokenStream2) -> Result { pub struct #row_struct_name<#generics> { #(#field_definitions)* } + + impl<#generics: Copy> #row_struct_name<#generics> { + pub const ROW_SIZE: usize = #row_size; + } }; - // Generate trace struct with lifetime + // Generate trace struct let trace_struct = quote! { pub struct #trace_struct_name<'a, #generics> { pub buffer: Option>, pub slice_trace: &'a mut [#row_struct_name<#generics>], num_rows: usize, } - }; - - let impl_block = quote! { - impl<#generics: Default + Clone + Copy> #trace_struct_name<'_, #generics> { - pub const ROW_SIZE: usize = #row_size; + impl<'a, #generics: Default + Clone + Copy> #trace_struct_name<'a, #generics> { pub fn new(num_rows: usize) -> Self { assert!(num_rows >= 2); assert!(num_rows & (num_rows - 1) == 0); - let buffer = vec![#generics::default(); num_rows * Self::ROW_SIZE]; + + let buffer = vec![#generics::default(); num_rows * #row_struct_name::<#generics>::ROW_SIZE]; let slice_trace = unsafe { std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut #row_struct_name<#generics>, num_rows) }; - Self { buffer: Some(buffer), slice_trace, num_rows } + + #trace_struct_name { buffer: Some(buffer), slice_trace, num_rows } + } + + pub fn map_buffer(external_buffer: &'a mut [#generics], num_rows: usize, offset: usize) -> Result> { + assert!(num_rows >= 2); + assert!(num_rows & (num_rows - 1) == 0); + + let start = offset; + let end = start + num_rows * #row_struct_name::<#generics>::ROW_SIZE; + + if end > external_buffer.len() { + return Err("Buffer is too small to fit the trace".into()); + } + + let slice_trace = unsafe { + std::slice::from_raw_parts_mut( + external_buffer[start..end].as_ptr() as *mut #row_struct_name<#generics>, + num_rows, + ) + }; + + Ok(#trace_struct_name { + buffer: None, + slice_trace, + num_rows, + }) + } + + pub fn map_row_vec(external_buffer: Vec<#row_struct_name<#generics>>) -> Result> { + let num_rows = external_buffer.len().next_power_of_two(); + assert!(num_rows >= 2); + assert!(num_rows & (num_rows - 1) == 0); + + let slice_trace = unsafe { + let ptr = external_buffer.as_ptr() as *mut #row_struct_name<#generics>; + std::slice::from_raw_parts_mut(ptr, num_rows) + }; + + let buffer_f = unsafe { + Vec::from_raw_parts(external_buffer.as_ptr() as *mut #generics, num_rows * #row_struct_name::<#generics>::ROW_SIZE, num_rows * #row_struct_name::<#generics>::ROW_SIZE) + }; + + std::mem::forget(external_buffer); + + Ok(#trace_struct_name { + buffer: Some(buffer_f), + slice_trace, + num_rows, + }) } pub fn num_rows(&self) -> usize { @@ -80,12 +130,22 @@ fn trace_impl(input: TokenStream2) -> Result { &mut self.slice_trace[index] } } + + impl<'a, #generics: Send> common::trace::Trace for #trace_struct_name<'a, #generics> { + fn num_rows(&self) -> usize { + self.num_rows + } + + fn get_buffer_ptr(&mut self) -> *mut u8 { + let buffer = self.buffer.as_mut().expect("Buffer is not available"); + buffer.as_mut_ptr() as *mut u8 + } + } }; Ok(quote! { #row_struct #trace_struct - #impl_block }) } From a985f85afc56c0d9bbb515d6ec7fcabe8556b797 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 6 Sep 2024 10:29:11 -0400 Subject: [PATCH 11/15] closer --- macros/src/lib.rs | 167 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 148 insertions(+), 19 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 952e793d..4fc37a84 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -23,8 +23,14 @@ fn trace_impl(input: TokenStream2) -> Result { let generics = parsed_input.generics.params; let fields = parsed_input.fields; - // Calculate ROW_SIZE - let row_size = fields.named.iter().map(|field| calculate_field_size_literal(&field.ty)).sum::(); + // Calculate ROW_SIZE based on the field types + let row_size = fields + .named + .iter() + .map(|field| calculate_field_size_literal(&field.ty)) + .collect::>>()? + .into_iter() + .sum::(); // Generate row struct let field_definitions = fields.named.iter().map(|field| { @@ -58,10 +64,17 @@ fn trace_impl(input: TokenStream2) -> Result { let buffer = vec![#generics::default(); num_rows * #row_struct_name::<#generics>::ROW_SIZE]; let slice_trace = unsafe { - std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut #row_struct_name<#generics>, num_rows) + std::slice::from_raw_parts_mut( + buffer.as_ptr() as *mut #row_struct_name<#generics>, + num_rows, + ) }; - #trace_struct_name { buffer: Some(buffer), slice_trace, num_rows } + #trace_struct_name { + buffer: Some(buffer), + slice_trace, + num_rows, + } } pub fn map_buffer(external_buffer: &'a mut [#generics], num_rows: usize, offset: usize) -> Result> { @@ -96,11 +109,18 @@ fn trace_impl(input: TokenStream2) -> Result { let slice_trace = unsafe { let ptr = external_buffer.as_ptr() as *mut #row_struct_name<#generics>; - std::slice::from_raw_parts_mut(ptr, num_rows) + std::slice::from_raw_parts_mut( + ptr, + num_rows, + ) }; let buffer_f = unsafe { - Vec::from_raw_parts(external_buffer.as_ptr() as *mut #generics, num_rows * #row_struct_name::<#generics>::ROW_SIZE, num_rows * #row_struct_name::<#generics>::ROW_SIZE) + Vec::from_raw_parts( + external_buffer.as_ptr() as *mut #generics, + num_rows * #row_struct_name::<#generics>::ROW_SIZE, + num_rows * #row_struct_name::<#generics>::ROW_SIZE, + ) }; std::mem::forget(external_buffer); @@ -180,22 +200,24 @@ impl Parse for ParsedTraceInput { } } -// Calculate the size of a field based on its type and return it as a usize literal -fn calculate_field_size_literal(field_type: &syn::Type) -> usize { +// Calculate the size of a field based on its type and return it as a Result +fn calculate_field_size_literal(field_type: &syn::Type) -> Result { match field_type { // Handle arrays with multiple dimensions syn::Type::Array(type_array) => { - let len = type_array.len.to_token_stream().to_string().parse::().unwrap(); - let elem_size = calculate_field_size_literal(&type_array.elem); - len * elem_size + let len = type_array.len.to_token_stream().to_string().parse::().map_err(|e| { + syn::Error::new_spanned(&type_array.len, format!("Failed to parse array length: {}", e)) + })?; + let elem_size = calculate_field_size_literal(&type_array.elem)?; + Ok(len * elem_size) } // For simple types, the size is 1 - _ => 1, + _ => Ok(1), } } #[test] -fn test_simple_struct_without_struct_keyword() { +fn test_trace_macro_generates_default_row_struct() { let input = quote! { Simple { a: F, b: F, c: F } }; @@ -250,7 +272,7 @@ fn test_simple_struct_without_struct_keyword() { } #[test] -fn test_explicit_row_and_trace_struct() { +fn test_trace_macro_with_explicit_row_struct_name() { let input = quote! { SimpleRow, Simple { a: F, b: F } }; @@ -261,22 +283,78 @@ fn test_explicit_row_and_trace_struct() { pub a: F, pub b: F, } + + impl SimpleRow { + pub const ROW_SIZE: usize = 2usize; + } + pub struct Simple<'a, F> { pub buffer: Option>, pub slice_trace: &'a mut [SimpleRow], num_rows: usize, } - impl Simple<'_, F> { - pub const ROW_SIZE: usize = 2usize; + impl<'a, F: Default + Clone + Copy> Simple<'a, F> { pub fn new(num_rows: usize) -> Self { assert!(num_rows >= 2); assert!(num_rows & (num_rows - 1) == 0); - let buffer = vec![F::default(); num_rows * Self::ROW_SIZE]; + let buffer = vec![F::default(); num_rows * SimpleRow::::ROW_SIZE]; let slice_trace = unsafe { - std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut SimpleRow, num_rows) + std::slice::from_raw_parts_mut( + buffer.as_ptr() as *mut SimpleRow, + num_rows, + ) }; - Self { buffer: Some(buffer), slice_trace, num_rows } + Simple { + buffer: Some(buffer), + slice_trace, + num_rows, + } + } + + pub fn map_buffer(external_buffer: &'a mut [F], num_rows: usize, offset: usize) -> Result> { + assert!(num_rows >= 2); + assert!(num_rows & (num_rows - 1) == 0); + let start = offset; + let end = start + num_rows * SimpleRow::::ROW_SIZE; + if end > external_buffer.len() { + return Err("Buffer is too small to fit the trace".into()); + } + let slice_trace = unsafe { + std::slice::from_raw_parts_mut( + external_buffer[start..end].as_ptr() as *mut SimpleRow, + num_rows, + ) + }; + Ok(Simple { + buffer: None, + slice_trace, + num_rows, + }) + } + + pub fn map_row_vec(external_buffer: Vec>) -> Result> { + let num_rows = external_buffer.len().next_power_of_two(); + assert!(num_rows >= 2); + assert!(num_rows & (num_rows - 1) == 0); + let slice_trace = unsafe { + let ptr = external_buffer.as_ptr() as *mut SimpleRow; + std::slice::from_raw_parts_mut( + ptr, + num_rows, + ) + }; + let buffer_f = unsafe { + Vec::from_raw_parts( + external_buffer.as_ptr() as *mut F, + num_rows * SimpleRow::::ROW_SIZE, num_rows * SimpleRow::::ROW_SIZE, + ) + }; + std::mem::forget(external_buffer); + Ok(Simple { + buffer: Some(buffer_f), + slice_trace, num_rows, + }) } pub fn num_rows(&self) -> usize { @@ -297,6 +375,17 @@ fn test_explicit_row_and_trace_struct() { &mut self.slice_trace[index] } } + + impl<'a, F: Send> common::trace::Trace for Simple<'a, F> { + fn num_rows(&self) -> usize { + self.num_rows + } + + fn get_buffer_ptr(&mut self) -> *mut u8 { + let buffer = self.buffer.as_mut().expect("Buffer is not available"); + buffer.as_mut_ptr() as *mut u8 + } + } }; let generated = trace_impl(input.into()).unwrap(); @@ -332,3 +421,43 @@ fn test_parsing_03() { assert_eq!(parsed.row_struct_name, "SimpleRow"); assert_eq!(parsed.struct_name, "Simple"); } + +#[test] +fn test_simple_type_size() { + // A simple type like `F` should return size 1 + let ty: syn::Type = syn::parse_quote! { F }; + let size = calculate_field_size_literal(&ty).unwrap(); + assert_eq!(size, 1); +} + +#[test] +fn test_array_type_size_single_dimension() { + // An array like `[F; 3]` should return size 3 + let ty: syn::Type = syn::parse_quote! { [F; 3] }; + let size = calculate_field_size_literal(&ty).unwrap(); + assert_eq!(size, 3); +} + +#[test] +fn test_array_type_size_multi_dimension() { + // A multi-dimensional array like `[[F; 3]; 2]` should return size 6 (2 * 3) + let ty: syn::Type = syn::parse_quote! { [[F; 3]; 2] }; + let size = calculate_field_size_literal(&ty).unwrap(); + assert_eq!(size, 6); +} + +#[test] +fn test_nested_array_type_size() { + // A more deeply nested array like `[[[F; 2]; 3]; 4]` should return size 24 (4 * 3 * 2) + let ty: syn::Type = syn::parse_quote! { [[[F; 2]; 3]; 4] }; + let size = calculate_field_size_literal(&ty).unwrap(); + assert_eq!(size, 24); +} + +#[test] +fn test_empty_array() { + // An empty array should return size 0 + let ty: syn::Type = syn::parse_quote! { [F; 0] }; + let size = calculate_field_size_literal(&ty).unwrap(); + assert_eq!(size, 0); +} From 7a09e036fe119fdedc90865023de9a48a4313c52 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 6 Sep 2024 16:24:53 -0400 Subject: [PATCH 12/15] passing! --- macros/src/lib.rs | 110 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 17 deletions(-) diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 4fc37a84..0cc5d203 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -77,7 +77,11 @@ fn trace_impl(input: TokenStream2) -> Result { } } - pub fn map_buffer(external_buffer: &'a mut [#generics], num_rows: usize, offset: usize) -> Result> { + pub fn map_buffer( + external_buffer: &'a mut [#generics], + num_rows: usize, + offset: usize, + ) -> Result> { assert!(num_rows >= 2); assert!(num_rows & (num_rows - 1) == 0); @@ -102,7 +106,9 @@ fn trace_impl(input: TokenStream2) -> Result { }) } - pub fn map_row_vec(external_buffer: Vec<#row_struct_name<#generics>>) -> Result> { + pub fn map_row_vec( + external_buffer: Vec<#row_struct_name<#generics>>, + ) -> Result> { let num_rows = external_buffer.len().next_power_of_two(); assert!(num_rows >= 2); assert!(num_rows & (num_rows - 1) == 0); @@ -219,7 +225,7 @@ fn calculate_field_size_literal(field_type: &syn::Type) -> Result { #[test] fn test_trace_macro_generates_default_row_struct() { let input = quote! { - Simple { a: F, b: F, c: F } + Simple { a: F, b: F } }; let expected = quote! { @@ -227,46 +233,110 @@ fn test_trace_macro_generates_default_row_struct() { pub struct SimpleRow { pub a: F, pub b: F, - pub c: F, + } + impl SimpleRow { + pub const ROW_SIZE: usize = 2usize; } pub struct Simple<'a, F> { pub buffer: Option>, pub slice_trace: &'a mut [SimpleRow], num_rows: usize, } - impl Simple<'_, F> { - pub const ROW_SIZE: usize = 3usize; - + impl<'a, F: Default + Clone + Copy> Simple<'a, F> { pub fn new(num_rows: usize) -> Self { assert!(num_rows >= 2); assert!(num_rows & (num_rows - 1) == 0); - let buffer = vec![F::default(); num_rows * Self::ROW_SIZE]; + let buffer = vec![F::default(); num_rows * SimpleRow::::ROW_SIZE]; let slice_trace = unsafe { - std::slice::from_raw_parts_mut(buffer.as_ptr() as *mut SimpleRow, num_rows) + std::slice::from_raw_parts_mut( + buffer.as_ptr() as *mut SimpleRow, + num_rows, + ) }; - Self { buffer: Some(buffer), slice_trace, num_rows } + Simple { + buffer: Some(buffer), + slice_trace, + num_rows, + } + } + pub fn map_buffer( + external_buffer: &'a mut [F], + num_rows: usize, + offset: usize, + ) -> Result> { + assert!(num_rows >= 2); + assert!(num_rows & (num_rows - 1) == 0); + let start = offset; + let end = start + num_rows * SimpleRow::::ROW_SIZE; + if end > external_buffer.len() { + return Err("Buffer is too small to fit the trace".into()); + } + let slice_trace = unsafe { + std::slice::from_raw_parts_mut( + external_buffer[start..end].as_ptr() as *mut SimpleRow, + num_rows, + ) + }; + Ok(Simple { + buffer: None, + slice_trace, + num_rows, + }) + } + pub fn map_row_vec( + external_buffer: Vec>, + ) -> Result> { + let num_rows = external_buffer.len().next_power_of_two(); + assert!(num_rows >= 2); + assert!(num_rows & (num_rows - 1) == 0); + let slice_trace = unsafe { + let ptr = external_buffer.as_ptr() as *mut SimpleRow; + std::slice::from_raw_parts_mut( + ptr, + num_rows, + ) + }; + let buffer_f = unsafe { + Vec::from_raw_parts( + external_buffer.as_ptr() as *mut F, + num_rows * SimpleRow::::ROW_SIZE, + num_rows * SimpleRow::::ROW_SIZE, + ) + }; + std::mem::forget(external_buffer); + Ok(Simple { + buffer: Some(buffer_f), + slice_trace, + num_rows, + }) } - pub fn num_rows(&self) -> usize { self.num_rows } } - impl<'a, F> std::ops::Index for Simple<'a, F> { type Output = SimpleRow; - fn index(&self, index: usize) -> &Self::Output { &self.slice_trace[index] } } - impl<'a, F> std::ops::IndexMut for Simple<'a, F> { fn index_mut(&mut self, index: usize) -> &mut Self::Output { &mut self.slice_trace[index] } } - }; + impl<'a, F: Send> common::trace::Trace for Simple<'a, F> { + fn num_rows(&self) -> usize { + self.num_rows + } + fn get_buffer_ptr(&mut self) -> *mut u8 { + let buffer = self.buffer.as_mut().expect("Buffer is not available"); + buffer.as_mut_ptr() as *mut u8 + } + } + + }; let generated = trace_impl(input.into()).unwrap(); assert_eq!(generated.to_string(), expected.into_token_stream().to_string()); } @@ -312,7 +382,11 @@ fn test_trace_macro_with_explicit_row_struct_name() { } } - pub fn map_buffer(external_buffer: &'a mut [F], num_rows: usize, offset: usize) -> Result> { + pub fn map_buffer( + external_buffer: &'a mut [F], + num_rows: usize, + offset: usize, + ) -> Result> { assert!(num_rows >= 2); assert!(num_rows & (num_rows - 1) == 0); let start = offset; @@ -333,7 +407,9 @@ fn test_trace_macro_with_explicit_row_struct_name() { }) } - pub fn map_row_vec(external_buffer: Vec>) -> Result> { + pub fn map_row_vec( + external_buffer: Vec>, + ) -> Result> { let num_rows = external_buffer.len().next_power_of_two(); assert!(num_rows >= 2); assert!(num_rows & (num_rows - 1) == 0); From 6bb4a4cbc3c4a0c6b01cceed4bd2935ff607ce7d Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 6 Sep 2024 16:48:14 -0400 Subject: [PATCH 13/15] add tests, one example failing --- common/src/trace.rs | 104 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/common/src/trace.rs b/common/src/trace.rs index 451797a8..44eb1966 100644 --- a/common/src/trace.rs +++ b/common/src/trace.rs @@ -61,3 +61,107 @@ fn test_errors_are_launched_when_num_rows_is_invalid_4() { trace!(SimpleRow, Simple { a: F }); let _ = Simple::::new(3); } + +#[test] +fn check_array() { + let num_rows = 8; + + trace!(TraceRow, MyTrace { a: F, b: [F; 3], c: F }); + + assert_eq!(TraceRow::::ROW_SIZE, 5); + let mut buffer = vec![0usize; num_rows * TraceRow::::ROW_SIZE]; + let trace = MyTrace::map_buffer(&mut buffer, num_rows, 0); + let mut trace = trace.unwrap(); + + // Set values + for i in 0..num_rows { + trace[i].a = i; + trace[i].b[0] = i * 10; + trace[i].b[1] = i * 20; + trace[i].b[2] = i * 30; + trace[i].c = i * 40; + } + + // Check values + for i in 0..num_rows { + assert_eq!(buffer[i * TraceRow::::ROW_SIZE], i); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 1], i * 10); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 2], i * 20); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 3], i * 30); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 4], i * 40); + } +} + +#[test] +fn check_multi_array() { + let num_rows = 8; + + trace!(TraceRow, MyTrace { a: [[F;3]; 2], b: F }); + + assert_eq!(TraceRow::::ROW_SIZE, 7); + let mut buffer = vec![0usize; num_rows * TraceRow::::ROW_SIZE]; + let trace = MyTrace::map_buffer(&mut buffer, num_rows, 0); + let mut trace = trace.unwrap(); + + // Set values + for i in 0..num_rows { + trace[i].a[0][0] = i; + trace[i].a[0][1] = i * 10; + trace[i].a[0][2] = i * 20; + trace[i].a[1][0] = i * 30; + trace[i].a[1][1] = i * 40; + trace[i].a[1][2] = i * 50; + trace[i].b = i + 3; + } + + // Check values + for i in 0..num_rows { + assert_eq!(buffer[i * TraceRow::::ROW_SIZE], i); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 1], i * 10); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 2], i * 20); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 3], i * 30); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 4], i * 40); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 5], i * 50); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 6], i + 3); + } +} + +#[test] +fn check_multi_array_2() { + let num_rows = 8; + + trace!(TraceRow, MyTrace { a: [[F;3]; 2], b: F, c: [F; 2] }); + + assert_eq!(TraceRow::::ROW_SIZE, 9); + let mut buffer = vec![0usize; num_rows * TraceRow::::ROW_SIZE]; + let trace = MyTrace::map_buffer(&mut buffer, num_rows, 0); + let mut trace = trace.unwrap(); + + // Set values + for i in 0..num_rows { + trace[i].a[0][0] = i; + trace[i].a[0][1] = i * 10; + trace[i].a[0][2] = i * 20; + trace[i].a[1][0] = i * 30; + trace[i].a[1][1] = i * 40; + trace[i].a[1][2] = i * 50; + trace[i].b = i + 3; + trace[i].c[0] = i + 9; + trace[i].c[1] = i + 2; + } + + println!("{:?}", buffer); + + // Check values + for i in 0..num_rows { + assert_eq!(buffer[i * TraceRow::::ROW_SIZE], i); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 1], i * 10); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 2], i * 20); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 3], i * 30); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 4], i * 40); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 5], i * 50); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 6], i + 3); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 7], i + 9); + assert_eq!(buffer[i * TraceRow::::ROW_SIZE + 8], i + 2); + } +} From 5a262607ab0c576aa5458cda1f70ce056b742781 Mon Sep 17 00:00:00 2001 From: RogerTaule Date: Mon, 9 Sep 2024 07:15:06 +0000 Subject: [PATCH 14/15] All macros tests passing --- common/src/trace.rs | 52 ++++++++++++++++++++++----------------------- macros/src/lib.rs | 3 +++ 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/common/src/trace.rs b/common/src/trace.rs index 44eb1966..1ca6e89a 100644 --- a/common/src/trace.rs +++ b/common/src/trace.rs @@ -8,30 +8,6 @@ pub use proofman_macros::trace; #[cfg(test)] use crate as common; -#[test] -fn check() { - const OFFSET: usize = 1; - let num_rows = 8; - - trace!(TraceRow, MyTrace { a: F, b: F }); - - let mut buffer = vec![0usize; num_rows * TraceRow::::ROW_SIZE + OFFSET]; - let trace = MyTrace::map_buffer(&mut buffer, num_rows, OFFSET); - let mut trace = trace.unwrap(); - - // Set values - for i in 0..num_rows { - trace[i].a = i; - trace[i].b = i * 10; - } - - // Check values - for i in 0..num_rows { - assert_eq!(trace[i].a, i); - assert_eq!(trace[i].b, i * 10); - } -} - #[test] #[should_panic] fn test_errors_are_launched_when_num_rows_is_invalid_1() { @@ -62,6 +38,32 @@ fn test_errors_are_launched_when_num_rows_is_invalid_4() { let _ = Simple::::new(3); } +#[test] +fn check() { + const OFFSET: usize = 1; + let num_rows = 8; + + trace!(TraceRow, MyTrace { a: F, b:F}); + + assert_eq!(TraceRow::::ROW_SIZE, 2); + + let mut buffer = vec![0usize; num_rows * TraceRow::::ROW_SIZE + OFFSET]; + let trace = MyTrace::map_buffer(&mut buffer, num_rows, OFFSET); + let mut trace = trace.unwrap(); + + // Set values + for i in 0..num_rows { + trace[i].a = i; + trace[i].b = i * 10; + } + + // Check values + for i in 0..num_rows { + assert_eq!(trace[i].a, i); + assert_eq!(trace[i].b, i * 10); + } +} + #[test] fn check_array() { let num_rows = 8; @@ -150,8 +152,6 @@ fn check_multi_array_2() { trace[i].c[1] = i + 2; } - println!("{:?}", buffer); - // Check values for i in 0..num_rows { assert_eq!(buffer[i * TraceRow::::ROW_SIZE], i); diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 0cc5d203..da12b836 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -39,6 +39,7 @@ fn trace_impl(input: TokenStream2) -> Result { }); let row_struct = quote! { + #[repr(C)] #[derive(Debug, Clone, Copy, Default)] pub struct #row_struct_name<#generics> { #(#field_definitions)* @@ -229,6 +230,7 @@ fn test_trace_macro_generates_default_row_struct() { }; let expected = quote! { + #[repr(C)] #[derive(Debug, Clone, Copy, Default)] pub struct SimpleRow { pub a: F, @@ -348,6 +350,7 @@ fn test_trace_macro_with_explicit_row_struct_name() { }; let expected = quote! { + #[repr(C)] #[derive(Debug, Clone, Copy, Default)] pub struct SimpleRow { pub a: F, From c776f0c6809be57a295726e1981a43d9c12060ad Mon Sep 17 00:00:00 2001 From: RogerTaule Date: Mon, 9 Sep 2024 07:57:02 +0000 Subject: [PATCH 15/15] Modifying pil_helpers_trace to work with new macro --- cli/assets/templates/pil_helpers_trace.rs.tt | 3 ++- examples/fibonacci-square/Cargo.toml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cli/assets/templates/pil_helpers_trace.rs.tt b/cli/assets/templates/pil_helpers_trace.rs.tt index f06e5a4e..b0df01e2 100644 --- a/cli/assets/templates/pil_helpers_trace.rs.tt +++ b/cli/assets/templates/pil_helpers_trace.rs.tt @@ -1,6 +1,7 @@ // WARNING: This file has been autogenerated from the PILOUT file. // Manual modifications are not recommended and may be overwritten. -use proofman_common::trace; +pub use proofman_macros::trace; +use proofman_common as common; {{ for air_group in air_groups }} {{ for air in air_group.airs }} diff --git a/examples/fibonacci-square/Cargo.toml b/examples/fibonacci-square/Cargo.toml index b4d39399..d30116fa 100644 --- a/examples/fibonacci-square/Cargo.toml +++ b/examples/fibonacci-square/Cargo.toml @@ -8,6 +8,7 @@ crate-type = ["dylib"] [dependencies] proofman-common = { path = "../../common" } +proofman-macros.workspace = true proofman = { path = "../../proofman" } # pil-std-lib = { git = "https://github.com/0xPolygonHermez/pil2-components.git", branch ="std_rust" }