Skip to content

Commit

Permalink
Adaptive Dark colorscheme for Stmt HTML. Ability to programmatically …
Browse files Browse the repository at this point in the history
…export conceptual stmt files. (#8327)

* A few color tweaks for a darker colorscheme.

* Dark color scheme for Stmt HTML. Ability to programatically export the conceptual stmt files.

* Toolbar for HTML Stmt viewer with various settings.

* Cleanup.
  • Loading branch information
mcourteaux authored Jul 16, 2024
1 parent a05f459 commit b741d9c
Show file tree
Hide file tree
Showing 11 changed files with 700 additions and 311 deletions.
5 changes: 5 additions & 0 deletions python_bindings/src/halide/halide_/PyFunc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ void define_func(py::module &m) {
f.compile_to_lowered_stmt(filename, args, fmt, to_aot_target(target));
},
py::arg("filename"), py::arg("arguments"), py::arg("fmt") = Text, py::arg("target") = Target())
.def(
"compile_to_conceptual_stmt", [](Func &f, const std::string &filename, const std::vector<Argument> &args, StmtOutputFormat fmt, const Target &target) {
f.compile_to_conceptual_stmt(filename, args, fmt, to_aot_target(target));
},
py::arg("filename"), py::arg("arguments"), py::arg("fmt") = Text, py::arg("target") = Target())
.def(
"compile_to_file", [](Func &f, const std::string &filename_prefix, const std::vector<Argument> &args, const std::string &fn_name, const Target &target) {
f.compile_to_file(filename_prefix, args, fn_name, to_aot_target(target));
Expand Down
5 changes: 5 additions & 0 deletions python_bindings/src/halide/halide_/PyPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ void define_pipeline(py::module &m) {
p.compile_to_lowered_stmt(filename, args, fmt, to_aot_target(target));
},
py::arg("filename"), py::arg("arguments"), py::arg("fmt") = Text, py::arg("target") = Target())
.def(
"compile_to_conceptual_stmt", [](Pipeline &p, const std::string &filename, const std::vector<Argument> &args, StmtOutputFormat fmt, const Target &target) {
p.compile_to_conceptual_stmt(filename, args, fmt, to_aot_target(target));
},
py::arg("filename"), py::arg("arguments"), py::arg("fmt") = Text, py::arg("target") = Target())
.def(
"compile_to_file", [](Pipeline &p, const std::string &filename_prefix, const std::vector<Argument> &args, const std::string &fn_name, const Target &target) {
p.compile_to_file(filename_prefix, args, fn_name, to_aot_target(target));
Expand Down
7 changes: 7 additions & 0 deletions src/Func.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3542,6 +3542,13 @@ void Func::compile_to_lowered_stmt(const string &filename,
pipeline().compile_to_lowered_stmt(filename, args, fmt, target);
}

void Func::compile_to_conceptual_stmt(const string &filename,
const vector<Argument> &args,
StmtOutputFormat fmt,
const Target &target) {
pipeline().compile_to_conceptual_stmt(filename, args, fmt, target);
}

void Func::print_loop_nest() {
pipeline().print_loop_nest();
}
Expand Down
8 changes: 8 additions & 0 deletions src/Func.h
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,14 @@ class Func {
StmtOutputFormat fmt = Text,
const Target &target = get_target_from_environment());

/** Write out a conceptual representation of lowered code, before any parallel loop
* get factored out into separate functions, or GPU loops are offloaded to kernel code.r
* Useful for analyzing and debugging scheduling. Can emit html or plain text. */
void compile_to_conceptual_stmt(const std::string &filename,
const std::vector<Argument> &args,
StmtOutputFormat fmt = Text,
const Target &target = get_target_from_environment());

/** Write out the loop nests specified by the schedule for this
* Function. Helpful for understanding what a schedule is
* doing. */
Expand Down
8 changes: 8 additions & 0 deletions src/Pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,14 @@ void Pipeline::compile_to_lowered_stmt(const string &filename,
m.compile(single_output(filename, m, fmt == HTML ? OutputFileType::stmt_html : OutputFileType::stmt));
}

void Pipeline::compile_to_conceptual_stmt(const string &filename,
const vector<Argument> &args,
StmtOutputFormat fmt,
const Target &target) {
Module m = compile_to_module(args, "", target);
m.compile(single_output(filename, m, fmt == HTML ? OutputFileType::conceptual_stmt_html : OutputFileType::conceptual_stmt));
}

void Pipeline::compile_to_static_library(const string &filename_prefix,
const vector<Argument> &args,
const std::string &fn_name,
Expand Down
8 changes: 8 additions & 0 deletions src/Pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,14 @@ class Pipeline {
StmtOutputFormat fmt = Text,
const Target &target = get_target_from_environment());

/** Write out a conceptual representation of lowered code, before any parallel loop
* get factored out into separate functions, or GPU loops are offloaded to kernel code.r
* Useful for analyzing and debugging scheduling. Can emit html or plain text. */
void compile_to_conceptual_stmt(const std::string &filename,
const std::vector<Argument> &args,
StmtOutputFormat fmt = Text,
const Target &target = get_target_from_environment());

/** Write out the loop nests specified by the schedule for this
* Pipeline's Funcs. Helpful for understanding what a schedule is
* doing. */
Expand Down
34 changes: 34 additions & 0 deletions src/StmtToHTML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2378,7 +2378,10 @@ class PipelineHTMLInspector {
void generate_body(const Module &m) {
stream << "<body>\n";
stream << " <div id='page-container'>\n";
generate_toolbar(m);
stream << " <div id='content'>\n";
generate_visualization_panes(m);
stream << " </div>\n";
stream << " </div>\n";
#if INLINE_TEMPLATES
stream << "<script>\n"
Expand All @@ -2393,6 +2396,37 @@ class PipelineHTMLInspector {
stream << "</body>";
}

void generate_toolbar(const Module &m) {
stream << "<div id='toolbar'>\n";

// IR settings
stream << "<form id='form-ir-settings' name='form-ir-settings'>IR:\n";
stream << " <label><input type='checkbox' name='checkbox-show-ir-wrap' checked />Wrap</label>\n";
stream << " <label><input type='checkbox' name='checkbox-show-ir-line-nums' checked />Line numbers</label>\n";
stream << " <label><input type='checkbox' name='checkbox-show-ir-costs' checked />Costs</label>\n";
stream << "</form>\n";

// Which panes to show
stream << "<form id='form-panes' name='form-panes'>Panes:\n";
stream << " <label><input type='checkbox' name='checkbox-show-ir' checked />Show IR</label>\n";
stream << " <label><input type='checkbox' name='checkbox-show-assembly' checked />Show Assembly</label>\n";
Buffer<> device_code_buf = m.get_device_code_buffer();
if (device_code_buf.defined()) {
stream << " <label><input type='checkbox' name='checkbox-show-device-code' checked />Show Device Code</label>\n";
}
stream << "</form>\n";

// Color theme
stream << "<form id='form-theme' name='form-theme'>Theme:\n";
stream << " <label><input type='radio' name='theme' value='auto' checked />Auto</label>\n";
stream << " <label><input type='radio' name='theme' value='classic-light' />Classic Light</label>\n";
stream << " <label><input type='radio' name='theme' value='gruvbox-dark' />Gruvbox Dark</label>\n";
stream << "<label><input type='radio' name='theme' value='gruvbox-light' />Gruvbox Light</label>\n";

stream << "</form>\n";
stream << "</div>\n";
}

// Generate the three visualization panes
void generate_visualization_panes(const Module &m) {
int pane_count = 0;
Expand Down
42 changes: 41 additions & 1 deletion src/irvisualizer/generate_palettes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,47 @@ def make_oklch(l, c, h):


STEPS = 20
for color_theme, fL in [("light", 1.0), ("dark", 0.7)]:
print()
print("[data-theme=\"" + color_theme + "\"] {")

for i in range(STEPS):
f = i / (STEPS - 1)
col = make_oklch((0.9 - f * 0.5) * fL, 0.05 + 0.1 * f, 140)
print(" .block-CostColor%d:first-child { border-left: 8px solid %s; }" % (i, col))
print(" .block-CostColorNone:first-child { border-left: transparent; }")
print()

for i in range(STEPS):
f = i / (STEPS - 1)
col = make_oklch((0.9 - f * 0.5) * fL, 0.05 + 0.1 * f, 140)
print(" .line-CostColor%d:first-child { border-right: 8px solid %s; }" % (i, col))
print(" .line-CostColorNone:first-child { border-right: transparent; }")
print()


for i in range(STEPS):
f = i / (STEPS - 1)
col = make_oklch((0.9 - f * 0.5) * fL, 0.05 + 0.1 * f, 300)
print(" .block-CostColor%d:last-child { border-left: 8px solid %s; }" % (i, col))
print(" .block-CostColorNone:last-child { border-left: transparent; }")
print()

for i in range(STEPS):
f = i / (STEPS - 1)
col = make_oklch((0.9 - f * 0.5) * fL, 0.05 + 0.1 * f, 300)
print(" .line-CostColor%d:last-child { border-right: 8px solid %s; }" % (i, col))
print(" .line-CostColorNone:last-child { border-right: transparent; }")

print("} /* End of", color_theme, "theme. */")

print()
print("Theme agnostic")
print()

def make_oklch(l, c, h):
return ("oklch(calc(%.1f%% * var(--cost-Lf)) %.2f %.0f)" % (l * 100, c, h))


for i in range(STEPS):
f = i / (STEPS - 1)
Expand Down Expand Up @@ -31,4 +72,3 @@ def make_oklch(l, c, h):
col = make_oklch(0.9 - f * 0.5, 0.05 + 0.1 * f, 300)
print(".line-CostColor%d:last-child { border-right: 8px solid %s; }" % (i, col))
print(".line-CostColorNone:last-child { border-right: transparent; }")
print()
Loading

0 comments on commit b741d9c

Please sign in to comment.