-
Notifications
You must be signed in to change notification settings - Fork 17
Add inductor provenance tracking higlighter #93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9346ff3
8372841
e98c2f5
8393349
ffaa9be
2179bd3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,7 @@ pub struct ParseConfig { | |
pub verbose: bool, | ||
pub plain_text: bool, | ||
pub export: bool, | ||
pub inductor_provenance: bool, | ||
} | ||
|
||
impl Default for ParseConfig { | ||
|
@@ -41,6 +42,7 @@ impl Default for ParseConfig { | |
verbose: false, | ||
plain_text: false, | ||
export: false, | ||
inductor_provenance: false, | ||
} | ||
} | ||
} | ||
|
@@ -248,6 +250,7 @@ pub fn parse_path(path: &PathBuf, config: ParseConfig) -> anyhow::Result<ParseOu | |
TEMPLATE_AOT_AUTOGRAD_BACKWARD_COMPILATION_METRICS, | ||
)?; | ||
} | ||
tt.add_template("provenance_tracking.html", TEMPLATE_PROVENANCE_TRACKING)?; | ||
|
||
let mut unknown_fields: FxHashSet<String> = FxHashSet::default(); | ||
|
||
|
@@ -668,6 +671,14 @@ pub fn parse_path(path: &PathBuf, config: ParseConfig) -> anyhow::Result<ParseOu | |
|
||
let has_unknown_compile_id = directory.contains_key(&None); | ||
|
||
let directory_names: Vec<String> = directory | ||
.iter() | ||
.map(|(x, _)| { | ||
x.as_ref() | ||
.map_or("(unknown)".to_string(), |e| e.as_directory_name()) | ||
}) | ||
.collect(); | ||
|
||
let index_context = IndexContext { | ||
css: CSS, | ||
javascript: JAVASCRIPT, | ||
|
@@ -686,6 +697,8 @@ pub fn parse_path(path: &PathBuf, config: ParseConfig) -> anyhow::Result<ParseOu | |
num_breaks: breaks.failures.len(), | ||
has_chromium_events: !chromium_events.is_empty(), | ||
qps: TEMPLATE_QUERY_PARAM_SCRIPT, | ||
has_inductor_provenance: config.inductor_provenance, | ||
directory_names: directory_names.clone(), | ||
}; | ||
output.push(( | ||
PathBuf::from("index.html"), | ||
|
@@ -713,5 +726,55 @@ pub fn parse_path(path: &PathBuf, config: ParseConfig) -> anyhow::Result<ParseOu | |
return Err(anyhow!("Some log entries did not have compile id")); | ||
} | ||
|
||
if config.inductor_provenance { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of having this be a config to pass to tlparse, can we have it so this logic turns on if there's at least one There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jamesjwu I added it because it's a new feature and I don't want to break the normal tlparse flow accidentally. I'm thinking we can remove this flag after it has been running smoothly for a while. |
||
// Helper function to get file content for a specific directory name | ||
fn get_file_content( | ||
output: &[(PathBuf, String)], | ||
filename_pattern: &str, | ||
directory_name: &str, | ||
) -> String { | ||
output | ||
.iter() | ||
.find(|(path, _)| { | ||
path.to_string_lossy() | ||
.contains(&format!("{}/{}", directory_name, filename_pattern)) | ||
}) | ||
.map(|(_, content)| content.clone()) | ||
.unwrap_or_default() | ||
} | ||
|
||
// Generate HTML for each directory name | ||
for directory_name in &directory_names { | ||
let pre_grad_graph_content = | ||
get_file_content(&output, "inductor_pre_grad_graph", directory_name); | ||
let post_grad_graph_content = | ||
get_file_content(&output, "inductor_post_grad_graph", directory_name); | ||
let output_code_content = | ||
get_file_content(&output, "inductor_output_code", directory_name); | ||
let aot_code_content = get_file_content(&output, "inductor_aot_code", directory_name); | ||
let node_mappings_content = get_file_content( | ||
&output, | ||
"inductor_provenance_tracking_node_mappings", | ||
directory_name, | ||
); | ||
|
||
output.push(( | ||
PathBuf::from(format!("provenance_tracking_{}.html", directory_name)), | ||
tt.render( | ||
"provenance_tracking.html", | ||
&ProvenanceContext { | ||
css: PROVENANCE_CSS, | ||
js: PROVENANCE_JS, | ||
pre_grad_graph_content, | ||
post_grad_graph_content, | ||
output_code_content, | ||
aot_code_content, | ||
node_mappings_content, | ||
}, | ||
)?, | ||
)); | ||
} | ||
} | ||
|
||
Ok(output) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
body { | ||
display: flex; | ||
flex-direction: column; | ||
font-family: Arial, sans-serif; | ||
margin: 0; | ||
padding: 0; | ||
height: 100vh; | ||
overflow: hidden; | ||
} | ||
|
||
.url-inputs { | ||
display: flex; | ||
padding: 10px; | ||
background-color: #f0f0f0; | ||
} | ||
|
||
.url-input { | ||
flex: 1; | ||
margin-right: 10px; | ||
display: flex; | ||
align-items: center; | ||
gap: 10px; | ||
} | ||
|
||
.url-input input { | ||
width: 100%; | ||
padding: 5px; | ||
} | ||
|
||
.editor-container { | ||
display: flex; | ||
flex: 1; | ||
overflow: hidden; | ||
} | ||
|
||
.editor { | ||
height: 100%; | ||
overflow-y: auto; | ||
border: 1px solid #ddd; | ||
padding: 10px; | ||
box-sizing: border-box; | ||
flex: 1; | ||
font-family: monospace; | ||
} | ||
|
||
.line { | ||
padding: 2px 5px; | ||
cursor: pointer; | ||
white-space: nowrap; | ||
transition: background-color 0.2s ease; | ||
} | ||
|
||
.highlight { | ||
background-color: yellow; | ||
transition: background-color 0.2s ease; | ||
} | ||
|
||
.mapped-line { | ||
font-weight: bold; | ||
} | ||
|
||
.line-number { | ||
color: #888; | ||
display: inline-block; | ||
width: 30px; | ||
text-align: right; | ||
margin-right: 10px; | ||
} | ||
|
||
.divider { | ||
width: 10px; | ||
background-color: #ccc; | ||
cursor: col-resize; | ||
} | ||
|
||
.line-content { | ||
white-space: pre; | ||
display: inline; | ||
} | ||
|
||
.json-popup { | ||
display: none; | ||
position: fixed; | ||
background: white; | ||
border: 1px solid #ccc; | ||
padding: 10px; | ||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); | ||
max-width: 400px; | ||
max-height: 300px; | ||
overflow: auto; | ||
z-index: 1000; | ||
white-space: pre-wrap; | ||
font-family: monospace; | ||
font-size: 12px; | ||
} | ||
|
||
.json-popup .close-button { | ||
position: sticky; | ||
float: right; | ||
top: 0; | ||
right: 0; | ||
cursor: pointer; | ||
font-size: 20px; | ||
background: white; | ||
padding: 0 5px; | ||
margin-left: 10px; | ||
} | ||
|
||
#jsonContent { | ||
margin-top: 10px; | ||
} | ||
|
||
.toggle-container { | ||
margin-left: 20px; | ||
display: inline-flex; | ||
align-items: center; | ||
cursor: pointer; | ||
min-width: 200px; | ||
white-space: nowrap; | ||
} | ||
|
||
.toggle-container input[type="checkbox"] { | ||
margin-right: 5px; | ||
} | ||
|
||
.file-input { | ||
display: none; | ||
} | ||
|
||
.url-input { | ||
flex: 1; | ||
margin-right: 10px; | ||
display: flex; | ||
align-items: center; | ||
gap: 10px; | ||
} | ||
|
||
.file-label { | ||
background-color: #f0f0f0; | ||
padding: 5px 10px; | ||
border: 1px solid #ddd; | ||
border-radius: 4px; | ||
cursor: pointer; | ||
} | ||
|
||
.file-label:hover { | ||
background-color: #e0e0e0; | ||
} | ||
|
||
.has-match { | ||
font-weight: bold; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Inductor Provenance Tracking Highlighter</title> | ||
<style> | ||
{css | format_unescaped} | ||
</style> | ||
</head> | ||
|
||
<body> | ||
<div class="editor-container"> | ||
<div id="preGradGraph" class="editor"> | ||
<pre>{pre_grad_graph_content}</pre> | ||
</div> | ||
<div id="divider" class="divider"></div> | ||
<div id="postGradGraph" class="editor"> | ||
<pre>{post_grad_graph_content}</pre> | ||
</div> | ||
<div id="divider" class="divider"></div> | ||
<div id="generatedCode" class="editor"> | ||
<pre>{output_code_content | format_unescaped}{aot_code_content}</pre> | ||
</div> | ||
</div> | ||
|
||
<script> | ||
// Make node mappings available to JavaScript | ||
const nodeMappings = {node_mappings_content | format_unescaped}; | ||
{js | format_unescaped} | ||
</script> | ||
</body> | ||
|
||
</html> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, similar question for @angelayi , why did we end up needing this again? Shouldn't we be able to tell just from the structured log input whether there are export related logs?