From 25c2914c235e3f24a06228b4375b69254ee34563 Mon Sep 17 00:00:00 2001 From: James Wu Date: Tue, 2 Apr 2024 11:38:53 -0400 Subject: [PATCH 1/4] Generalize parsers using trait and enum --- src/lib.rs | 47 ++++++++++--------------- src/parsers.rs | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/types.rs | 11 ++++++ 3 files changed, 122 insertions(+), 29 deletions(-) create mode 100644 src/parsers.rs diff --git a/src/lib.rs b/src/lib.rs index cb0e04f..b1f0d2d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,13 +15,12 @@ use std::time::Instant; use crate::types::*; use crate::templates::*; - +use crate::parsers::all_parsers; +mod parsers; mod templates; mod types; -pub type ParseOutput = Vec<(PathBuf, String)>; - pub struct ParseConfig { pub strict: bool, } @@ -86,6 +85,8 @@ pub fn parse_path(path: &PathBuf, config: ParseConfig) -> anyhow::Result anyhow::Result anyhow::Result anyhow::Result| -> anyhow::Result<()> { - if sentinel.is_some() { - let f = subdir.join(filename); - output.push((f, payload.clone())); - compile_directory.push(compile_id_dir.join(filename)); - } - Ok(()) - }; - - output_dump("optimize_ddp_split_graph.txt", e.optimize_ddp_split_graph)?; - output_dump("compiled_autograd_graph.txt", e.compiled_autograd_graph)?; - output_dump("aot_forward_graph.txt", e.aot_forward_graph)?; - output_dump("aot_backward_graph.txt", e.aot_backward_graph)?; - output_dump("aot_joint_graph.txt", e.aot_joint_graph)?; - output_dump("inductor_post_grad_graph.txt", e.inductor_post_grad_graph)?; - - if e.dynamo_output_graph.is_some() { - // TODO: dump sizes - let filename = "dynamo_output_graph.txt"; - let f = subdir.join(filename); - output.push((f, payload.clone())); - compile_directory.push(compile_id_dir.join(filename)); - } - if e.dynamo_guards.is_some() { let filename = "dynamo_guards.html"; let f = subdir.join(filename); diff --git a/src/parsers.rs b/src/parsers.rs new file mode 100644 index 0000000..dcde60b --- /dev/null +++ b/src/parsers.rs @@ -0,0 +1,93 @@ +use crate::types::*; +use std::path::PathBuf; + +pub trait StructuredLogParser { + // If this returns Some value, the parser will be run on that metadata. + // Otherwise, it will be skipped + + // 'e is the lifetime of the envelope + fn get_metadata<'e>(&self, e: &'e Envelope) -> Option>; + fn parse<'e>(&self, + lineno: usize, + metadata: Metadata<'e>, + rank: Option, + compile_id: &Option, + payload: &str + ) -> anyhow::Result; +} + +// Takes a filename and a payload and writes that payload into a the file +fn simple_file_output( + filename: &str, + lineno: usize, + compile_id: &Option, + payload: &str +) -> anyhow::Result { + let compile_id_dir: PathBuf = compile_id + .as_ref() + .map_or( + format!("unknown_{lineno}"), + |CompileId { + frame_id, + frame_compile_id, + attempt, + }| { format!("{frame_id}_{frame_compile_id}_{attempt}") }, + ) + .into(); + let subdir = PathBuf::from(compile_id_dir); + let f = subdir.join(filename); + Ok(Vec::from([(f, String::from(payload))])) +} + +pub struct SentinelFileParser { + filename: &'static str, + get_sentinel: fn (&Envelope) -> Option<&EmptyMetadata>, +} impl SentinelFileParser { + pub fn new(filename: &'static str, get_sentinel: fn (&Envelope) -> Option<&EmptyMetadata>) -> Self { + Self { filename, get_sentinel } + } +} +impl StructuredLogParser for SentinelFileParser { + fn get_metadata<'e>(&self, e: &'e Envelope) -> Option> { + (self.get_sentinel)(e).map(|m| Metadata::Empty(m)) + } + fn parse<'e>(&self, + lineno: usize, + _metadata: Metadata<'e>, + _rank: Option, + compile_id: &Option, + payload: &str + ) -> anyhow::Result { + simple_file_output(self.filename, lineno, compile_id, payload) + } +} +// Same as above, but can log the size of the graph +pub struct DynamoOutputGraphParser; +impl StructuredLogParser for DynamoOutputGraphParser { + fn get_metadata<'e>(&self, e: &'e Envelope) -> Option> { + e.dynamo_output_graph.as_ref().map(|m| Metadata::DynamoOutputGraph(m)) + } + fn parse<'e>(&self, + lineno: usize, + _metadata: Metadata<'e>, // TODO: log size of graph + _rank: Option, + compile_id: &Option, + payload: &str + ) -> anyhow::Result { + simple_file_output("dynamo_output_graph.txt", lineno, compile_id, payload) + } +} + +// Register your parser here +pub fn all_parsers() -> Vec> { + let result : Vec> = vec![ + Box::new(SentinelFileParser::new("optimize_ddp_split_graph.txt", |e| e.optimize_ddp_split_graph.as_ref())), + Box::new(SentinelFileParser::new("compiled_autograd_graph.txt", |e| e.compiled_autograd_graph.as_ref())), + Box::new(SentinelFileParser::new("aot_forward_graph.txt", |e| e.aot_forward_graph.as_ref())), + Box::new(SentinelFileParser::new("aot_backward_graph.txt", |e| e.aot_backward_graph.as_ref())), + Box::new(SentinelFileParser::new("aot_joint_graph.txt", |e| e.aot_joint_graph.as_ref())), + Box::new(SentinelFileParser::new("inductor_post_grad_graph.txt", |e| e.inductor_post_grad_graph.as_ref())), + Box::new(DynamoOutputGraphParser {}), + ]; + result +} diff --git a/src/types.rs b/src/types.rs index eedd218..3b6ccc3 100644 --- a/src/types.rs +++ b/src/types.rs @@ -10,6 +10,8 @@ use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; use std::sync::Mutex; +pub type ParseOutput = Vec<(PathBuf, String)>; + pub type FxIndexMap = IndexMap>; pub static INTERN_TABLE: Lazy>> = @@ -169,6 +171,15 @@ pub struct InductorOutputCodeMetadata { pub filename: Option, } +pub enum Metadata<'e> { + Empty(&'e EmptyMetadata), + DynamoOutputGraph(&'e DynamoOutputGraphMetadata), + #[allow(dead_code)] + DynamoStart(&'e DynamoStartMetadata), + #[allow(dead_code)] + InductorOutputCode(&'e InductorOutputCodeMetadata), +} + #[derive(Debug, Deserialize)] pub struct Envelope { pub rank: Option, From d6fce4856d004e8316a1d6ea8db3cb38c575cb8a Mon Sep 17 00:00:00 2001 From: James Wu Date: Tue, 2 Apr 2024 12:08:00 -0400 Subject: [PATCH 2/4] Add comments --- src/parsers.rs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/parsers.rs b/src/parsers.rs index dcde60b..b7826fe 100644 --- a/src/parsers.rs +++ b/src/parsers.rs @@ -1,18 +1,21 @@ use crate::types::*; use std::path::PathBuf; +/** + * StructuredLogParser + * Parses a structured log and returns a vec of file outputs. + * Implement this trait to add your own analyses. + */ pub trait StructuredLogParser { // If this returns Some value, the parser will be run on that metadata. - // Otherwise, it will be skipped - - // 'e is the lifetime of the envelope + // Otherwise, it will be skipped. 'e is the lifetime of the envelope. fn get_metadata<'e>(&self, e: &'e Envelope) -> Option>; fn parse<'e>(&self, - lineno: usize, - metadata: Metadata<'e>, - rank: Option, - compile_id: &Option, - payload: &str + lineno: usize, // Line number from log + metadata: Metadata<'e>, // Metadata from get_metadata + rank: Option, // Rank of the log + compile_id: &Option, // Compile ID of the envelope + payload: &str // Payload from the log (empty string when None) ) -> anyhow::Result; } @@ -39,6 +42,9 @@ fn simple_file_output( Ok(Vec::from([(f, String::from(payload))])) } +/** + * Parser for simple output dumps where the metadata is a sentinel {} + */ pub struct SentinelFileParser { filename: &'static str, get_sentinel: fn (&Envelope) -> Option<&EmptyMetadata>, @@ -61,7 +67,8 @@ impl StructuredLogParser for SentinelFileParser { simple_file_output(self.filename, lineno, compile_id, payload) } } -// Same as above, but can log the size of the graph + +// Same as SentinelFileParser, but can log the size of the graph pub struct DynamoOutputGraphParser; impl StructuredLogParser for DynamoOutputGraphParser { fn get_metadata<'e>(&self, e: &'e Envelope) -> Option> { @@ -80,6 +87,7 @@ impl StructuredLogParser for DynamoOutputGraphParser { // Register your parser here pub fn all_parsers() -> Vec> { + // We need to use Box wrappers here because vecs in Rust need to have known size let result : Vec> = vec![ Box::new(SentinelFileParser::new("optimize_ddp_split_graph.txt", |e| e.optimize_ddp_split_graph.as_ref())), Box::new(SentinelFileParser::new("compiled_autograd_graph.txt", |e| e.compiled_autograd_graph.as_ref())), From 65ec2a99ecbd7ef2c0967133c70b32effc504906 Mon Sep 17 00:00:00 2001 From: James Wu Date: Tue, 2 Apr 2024 13:37:42 -0400 Subject: [PATCH 3/4] Rewrite some more parsers in new type --- src/lib.rs | 65 +++-------------------------------- src/parsers.rs | 92 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/types.rs | 12 +++---- 3 files changed, 99 insertions(+), 70 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index b1f0d2d..8261c30 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,10 @@ use anyhow::anyhow; use fxhash::FxHashMap; use md5::{Digest, Md5}; -use std::ffi::{OsStr, OsString}; use regex::Regex; use std::fs::File; use std::io::{self, BufRead}; -use std::path::Path; use std::path::PathBuf; use tinytemplate::TinyTemplate; use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; @@ -85,7 +83,7 @@ pub fn parse_path(path: &PathBuf, config: ParseConfig) -> anyhow::Result anyhow::Result anyhow::Result anyhow::Result>(payload.as_str()) { - Ok(guards) => { - let guards_context = DynamoGuardsContext { guards }; - output.push((f, tt.render("dynamo_guards.html", &guards_context)?)); - compile_directory.push(compile_id_dir.join(filename)); - } - Err(err) => { - eprintln!("Failed to parse guards json: {}", err); - stats.fail_dynamo_guards_json += 1; - } - } - } - - if let Some(metadata) = e.inductor_output_code { - let filename = metadata - .filename - .as_ref() - .and_then(|p| Path::file_stem(p)) - .map_or_else( - || PathBuf::from("inductor_output_code.txt"), - |stem| { - let mut r = OsString::from("inductor_output_code_"); - r.push(stem); - r.push(OsStr::new(".txt")); - r.into() - }, - ); - let f = subdir.join(&filename); - output.push((f, payload.clone())); - compile_directory.push(compile_id_dir.join(filename)); - } - - if let Some(metadata) = e.optimize_ddp_split_child { - let filename = format!("optimize_ddp_split_child_{}.txt", metadata.name); - let f = subdir.join(&filename); - output.push((f, payload.clone())); - compile_directory.push(compile_id_dir.join(filename)); - } } pb.finish_with_message("done"); spinner.finish(); diff --git a/src/parsers.rs b/src/parsers.rs index b7826fe..5095ba6 100644 --- a/src/parsers.rs +++ b/src/parsers.rs @@ -1,14 +1,19 @@ use crate::types::*; use std::path::PathBuf; +use std::ffi::{OsStr, OsString}; +use std::path::Path; +use tinytemplate::TinyTemplate; /** * StructuredLogParser * Parses a structured log and returns a vec of file outputs. * Implement this trait to add your own analyses. + * + * 'e is the lifetime of the individual envelope */ pub trait StructuredLogParser { // If this returns Some value, the parser will be run on that metadata. - // Otherwise, it will be skipped. 'e is the lifetime of the envelope. + // Otherwise, it will be skipped. fn get_metadata<'e>(&self, e: &'e Envelope) -> Option>; fn parse<'e>(&self, lineno: usize, // Line number from log @@ -85,8 +90,86 @@ impl StructuredLogParser for DynamoOutputGraphParser { } } +pub struct DynamoGuardParser<'t> { + tt: &'t TinyTemplate<'t>, +} +impl StructuredLogParser for DynamoGuardParser<'_> { + fn get_metadata<'e>(&self, e: &'e Envelope) -> Option> { + e.dynamo_guards.as_ref().map(|m| Metadata::Empty(m)) + } + fn parse<'e>(&self, + lineno: usize, + _metadata: Metadata<'e>, + _rank: Option, + compile_id: &Option, + payload: &str + ) -> anyhow::Result { + let filename = "dynamo_guards.html"; + let guards = serde_json::from_str::>(payload)?; + let guards_context = DynamoGuardsContext { guards }; + let output = self.tt.render(filename, &guards_context)?; + simple_file_output(filename, lineno, compile_id, &output) + } +} + +pub struct InductorOutputCodeParser; +impl StructuredLogParser for InductorOutputCodeParser { + fn get_metadata<'e>(&self, e: &'e Envelope) -> Option> { + e.inductor_output_code.as_ref().map(|m| Metadata::InductorOutputCode(m)) + } + + fn parse<'e>(&self, + lineno: usize, + metadata: Metadata<'e>, + _rank: Option, + compile_id: &Option, + payload: &str + ) -> anyhow::Result { + if let Metadata::InductorOutputCode(metadata) = metadata { + let filename = metadata + .filename + .as_ref() + .and_then(|p| Path::file_stem(p)) + .map_or_else( + || PathBuf::from("inductor_output_code.txt"), + |stem| { + let mut r = OsString::from("inductor_output_code_"); + r.push(stem); + r.push(OsStr::new(".txt")); + r.into() + }, + ); + simple_file_output(&filename.to_string_lossy(), lineno, compile_id, payload) + } else { + Err(anyhow::anyhow!("Expected InductorOutputCode metadata")) + } + } +} + +pub struct OptimizeDdpSplitChildParser; +impl StructuredLogParser for OptimizeDdpSplitChildParser { + fn get_metadata<'e>(&self, e: &'e Envelope) -> Option> { + e.optimize_ddp_split_child.as_ref().map(|m| Metadata::OptimizeDdpSplitChild(m)) + } + + fn parse<'e>(&self, + lineno: usize, + metadata: Metadata<'e>, + _rank: Option, + compile_id: &Option, + payload: &str + ) -> anyhow::Result { + if let Metadata::OptimizeDdpSplitChild(m) = metadata { + let filename = format!("optimize_ddp_split_child_{}.txt", m.name); + simple_file_output(&filename, lineno, compile_id, payload) + } else { + Err(anyhow::anyhow!("Expected OptimizeDdpSplitChild metadata")) + } + } +} + // Register your parser here -pub fn all_parsers() -> Vec> { +pub fn all_parsers<'t>(tt: &'t TinyTemplate<'t>) -> Vec> { // We need to use Box wrappers here because vecs in Rust need to have known size let result : Vec> = vec![ Box::new(SentinelFileParser::new("optimize_ddp_split_graph.txt", |e| e.optimize_ddp_split_graph.as_ref())), @@ -95,7 +178,10 @@ pub fn all_parsers() -> Vec> { Box::new(SentinelFileParser::new("aot_backward_graph.txt", |e| e.aot_backward_graph.as_ref())), Box::new(SentinelFileParser::new("aot_joint_graph.txt", |e| e.aot_joint_graph.as_ref())), Box::new(SentinelFileParser::new("inductor_post_grad_graph.txt", |e| e.inductor_post_grad_graph.as_ref())), - Box::new(DynamoOutputGraphParser {}), + Box::new(DynamoOutputGraphParser), + Box::new(DynamoGuardParser { tt }), + Box::new(InductorOutputCodeParser), + Box::new(OptimizeDdpSplitChildParser), ]; result } diff --git a/src/types.rs b/src/types.rs index 3b6ccc3..c9df30c 100644 --- a/src/types.rs +++ b/src/types.rs @@ -141,11 +141,6 @@ impl fmt::Display for FrameSummary { pub type StackSummary = Vec; -#[derive(Debug, Deserialize)] -pub struct OptimizeDdpSplitChildMetadata { - pub name: String, -} - #[derive(Debug, Deserialize)] #[serde(untagged)] pub enum SymInt { @@ -153,6 +148,11 @@ pub enum SymInt { Symbol(String), } +#[derive(Debug, Deserialize)] +pub struct OptimizeDdpSplitChildMetadata { + pub name: String, +} + #[derive(Debug, Deserialize)] pub struct EmptyMetadata {} @@ -176,8 +176,8 @@ pub enum Metadata<'e> { DynamoOutputGraph(&'e DynamoOutputGraphMetadata), #[allow(dead_code)] DynamoStart(&'e DynamoStartMetadata), - #[allow(dead_code)] InductorOutputCode(&'e InductorOutputCodeMetadata), + OptimizeDdpSplitChild(&'e OptimizeDdpSplitChildMetadata), } #[derive(Debug, Deserialize)] From f5cace07261bbe712cb0135aba86be8bcd99d016 Mon Sep 17 00:00:00 2001 From: James Wu Date: Tue, 2 Apr 2024 14:18:03 -0400 Subject: [PATCH 4/4] Error logging --- src/lib.rs | 26 ++++++++++++++++++++++---- src/parsers.rs | 43 ++++++++++++++++++++++++++++++++----------- src/types.rs | 2 ++ 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8261c30..6c711b9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -174,11 +174,28 @@ pub fn parse_path(path: &PathBuf, config: ParseConfig) -> anyhow::Result { + for (filename, out) in results { + output.push((filename.clone(), out)); + compile_directory.push(filename); + } + } + Err(err) => { + match parser.name() { + "dynamo_guards" => { + eprintln!("Failed to parse guards json: {}", err); + stats.fail_dynamo_guards_json += 1; + } + name => { + eprintln!("Parser {name} failed: {err}"); + stats.fail_parser += 1; + } + } + } } + } } @@ -220,6 +237,7 @@ pub fn parse_path(path: &PathBuf, config: ParseConfig) -> anyhow::Result 0) { // Report something went wrong diff --git a/src/parsers.rs b/src/parsers.rs index 5095ba6..d494c1a 100644 --- a/src/parsers.rs +++ b/src/parsers.rs @@ -9,12 +9,14 @@ use tinytemplate::TinyTemplate; * Parses a structured log and returns a vec of file outputs. * Implement this trait to add your own analyses. * - * 'e is the lifetime of the individual envelope + * 'e is the lifetime of the envelope being parsed */ pub trait StructuredLogParser { // If this returns Some value, the parser will be run on that metadata. // Otherwise, it will be skipped. fn get_metadata<'e>(&self, e: &'e Envelope) -> Option>; + + // Take a log input and the metadata you asked for, return a set of files to write fn parse<'e>(&self, lineno: usize, // Line number from log metadata: Metadata<'e>, // Metadata from get_metadata @@ -22,6 +24,9 @@ pub trait StructuredLogParser { compile_id: &Option, // Compile ID of the envelope payload: &str // Payload from the log (empty string when None) ) -> anyhow::Result; + + // Name of the parser, for error logging + fn name(&self) -> &'static str; } // Takes a filename and a payload and writes that payload into a the file @@ -59,6 +64,9 @@ pub struct SentinelFileParser { } } impl StructuredLogParser for SentinelFileParser { + fn name(&self) -> &'static str { + self.filename + } fn get_metadata<'e>(&self, e: &'e Envelope) -> Option> { (self.get_sentinel)(e).map(|m| Metadata::Empty(m)) } @@ -69,13 +77,16 @@ impl StructuredLogParser for SentinelFileParser { compile_id: &Option, payload: &str ) -> anyhow::Result { - simple_file_output(self.filename, lineno, compile_id, payload) + simple_file_output(&format!("{}.txt",self.filename), lineno, compile_id, payload) } } // Same as SentinelFileParser, but can log the size of the graph pub struct DynamoOutputGraphParser; impl StructuredLogParser for DynamoOutputGraphParser { + fn name(&self) -> &'static str { + "dynamo_output_graph" + } fn get_metadata<'e>(&self, e: &'e Envelope) -> Option> { e.dynamo_output_graph.as_ref().map(|m| Metadata::DynamoOutputGraph(m)) } @@ -94,6 +105,9 @@ pub struct DynamoGuardParser<'t> { tt: &'t TinyTemplate<'t>, } impl StructuredLogParser for DynamoGuardParser<'_> { + fn name(&self) -> &'static str { + "dynamo_guards" + } fn get_metadata<'e>(&self, e: &'e Envelope) -> Option> { e.dynamo_guards.as_ref().map(|m| Metadata::Empty(m)) } @@ -104,16 +118,19 @@ impl StructuredLogParser for DynamoGuardParser<'_> { compile_id: &Option, payload: &str ) -> anyhow::Result { - let filename = "dynamo_guards.html"; + let filename = format!("{}.html", self.name()); let guards = serde_json::from_str::>(payload)?; let guards_context = DynamoGuardsContext { guards }; - let output = self.tt.render(filename, &guards_context)?; - simple_file_output(filename, lineno, compile_id, &output) + let output = self.tt.render(&filename, &guards_context)?; + simple_file_output(&filename, lineno, compile_id, &output) } } pub struct InductorOutputCodeParser; impl StructuredLogParser for InductorOutputCodeParser { + fn name(&self) -> &'static str { + "inductor_output_code" + } fn get_metadata<'e>(&self, e: &'e Envelope) -> Option> { e.inductor_output_code.as_ref().map(|m| Metadata::InductorOutputCode(m)) } @@ -148,6 +165,9 @@ impl StructuredLogParser for InductorOutputCodeParser { pub struct OptimizeDdpSplitChildParser; impl StructuredLogParser for OptimizeDdpSplitChildParser { + fn name(&self) -> &'static str { + "optimize_ddp_split_child" + } fn get_metadata<'e>(&self, e: &'e Envelope) -> Option> { e.optimize_ddp_split_child.as_ref().map(|m| Metadata::OptimizeDdpSplitChild(m)) } @@ -172,16 +192,17 @@ impl StructuredLogParser for OptimizeDdpSplitChildParser { pub fn all_parsers<'t>(tt: &'t TinyTemplate<'t>) -> Vec> { // We need to use Box wrappers here because vecs in Rust need to have known size let result : Vec> = vec![ - Box::new(SentinelFileParser::new("optimize_ddp_split_graph.txt", |e| e.optimize_ddp_split_graph.as_ref())), - Box::new(SentinelFileParser::new("compiled_autograd_graph.txt", |e| e.compiled_autograd_graph.as_ref())), - Box::new(SentinelFileParser::new("aot_forward_graph.txt", |e| e.aot_forward_graph.as_ref())), - Box::new(SentinelFileParser::new("aot_backward_graph.txt", |e| e.aot_backward_graph.as_ref())), - Box::new(SentinelFileParser::new("aot_joint_graph.txt", |e| e.aot_joint_graph.as_ref())), - Box::new(SentinelFileParser::new("inductor_post_grad_graph.txt", |e| e.inductor_post_grad_graph.as_ref())), + Box::new(SentinelFileParser::new("optimize_ddp_split_graph", |e| e.optimize_ddp_split_graph.as_ref())), + Box::new(SentinelFileParser::new("compiled_autograd_graph", |e| e.compiled_autograd_graph.as_ref())), + Box::new(SentinelFileParser::new("aot_forward_graph", |e| e.aot_forward_graph.as_ref())), + Box::new(SentinelFileParser::new("aot_backward_graph", |e| e.aot_backward_graph.as_ref())), + Box::new(SentinelFileParser::new("aot_joint_graph", |e| e.aot_joint_graph.as_ref())), + Box::new(SentinelFileParser::new("inductor_post_grad_graph", |e| e.inductor_post_grad_graph.as_ref())), Box::new(DynamoOutputGraphParser), Box::new(DynamoGuardParser { tt }), Box::new(InductorOutputCodeParser), Box::new(OptimizeDdpSplitChildParser), ]; + result } diff --git a/src/types.rs b/src/types.rs index c9df30c..3536db0 100644 --- a/src/types.rs +++ b/src/types.rs @@ -99,6 +99,7 @@ pub struct Stats { pub fail_json: u64, pub fail_payload_md5: u64, pub fail_dynamo_guards_json: u64, + pub fail_parser: u64, } #[derive(Debug, Hash, Eq, PartialEq, Deserialize, Serialize)] @@ -171,6 +172,7 @@ pub struct InductorOutputCodeMetadata { pub filename: Option, } +#[derive(Debug)] pub enum Metadata<'e> { Empty(&'e EmptyMetadata), DynamoOutputGraph(&'e DynamoOutputGraphMetadata),