From 54f04f7b350bc684d2fd2ea48240d912f3a8b635 Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Wed, 24 Nov 2021 17:22:36 +0100 Subject: [PATCH 1/4] Include GPU source kernels in Stmt and StmtHtml file. --- src/IRPrinter.cpp | 13 ++++++++++++- src/StmtToHtml.cpp | 22 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/IRPrinter.cpp b/src/IRPrinter.cpp index 4ecbbbbbb080..0b546f3a62fa 100644 --- a/src/IRPrinter.cpp +++ b/src/IRPrinter.cpp @@ -8,6 +8,7 @@ #include "IROperator.h" #include "Module.h" #include "Target.h" +#include "Util.h" namespace Halide { @@ -58,7 +59,17 @@ ostream &operator<<(ostream &stream, const Expr &ir) { } ostream &operator<<(ostream &stream, const Buffer<> &buffer) { - return stream << "buffer " << buffer.name() << " = {...}\n"; + bool include_data = Internal::ends_with(buffer.name(), "_gpu_source_kernels"); + stream << "buffer " << buffer.name() << " = {"; + if (include_data) { + std::string str((const char *)buffer.data(), buffer.size_in_bytes()); + stream << "\n" + << str << "\n"; + } else { + stream << "..."; + } + stream << "}\n"; + return stream; } ostream &operator<<(ostream &stream, const Module &m) { diff --git a/src/StmtToHtml.cpp b/src/StmtToHtml.cpp index 93763d7683ff..4f007601f195 100644 --- a/src/StmtToHtml.cpp +++ b/src/StmtToHtml.cpp @@ -3,6 +3,7 @@ #include "IRVisitor.h" #include "Module.h" #include "Scope.h" +#include "Util.h" #include #include @@ -762,8 +763,29 @@ class StmtToHtml : public IRVisitor { } void print(const Buffer<> &op) { + bool include_data = ends_with(op.name(), "_gpu_source_kernels"); + int id = 0; + if (include_data) { + id = unique_id(); + stream << open_expand_button(id); + stream << open_span("Matched"); + } stream << open_div("Buffer<>"); stream << keyword("buffer ") << var(op.name()); + if (include_data) { + stream << " = "; + stream << matched("{"); + stream << close_expand_button(); + + stream << open_div("BufferData", id); + stream << "
\n";
+            std::string str((const char *)op.data(), op.size_in_bytes());
+            stream << str;
+            stream << "
\n"; + stream << close_div(); + + stream << " " << matched("}"); + } stream << close_div(); } From 10a95ea74c2551729e94e4a0366514773b2d70c9 Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Thu, 25 Nov 2021 16:08:15 +0100 Subject: [PATCH 2/4] Syntax highlighting for embedded PTX code. --- src/StmtToHtml.cpp | 196 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 189 insertions(+), 7 deletions(-) diff --git a/src/StmtToHtml.cpp b/src/StmtToHtml.cpp index 4f007601f195..76fac4760698 100644 --- a/src/StmtToHtml.cpp +++ b/src/StmtToHtml.cpp @@ -762,13 +762,177 @@ class StmtToHtml : public IRVisitor { scope.pop(op.name); } + void print_cuda_gpu_source_kernels(const std::string &str) { + std::istringstream ss(str); + int current_id = -1; + stream << ""; + bool in_braces = false; + bool in_func_signature = false; + std::string current_kernel; + for (std::string line; std::getline(ss, line);) { + if (line.empty()) { + stream << "\n"; + continue; + } + line = replace_all(line, "&", "&"); + line = replace_all(line, "<", "<"); + line = replace_all(line, ">", ">"); + line = replace_all(line, "\"", """); + line = replace_all(line, "/", "/"); + line = replace_all(line, "'", "'"); + + if (starts_with(line, ".visible .entry")) { + std::vector parts = split_string(line, " "); + if (parts.size() == 3) { + in_func_signature = true; + current_id = unique_id(); + stream << open_expand_button(current_id); + + std::string kernel_name = parts[2].substr(0, parts[2].length() - 1); + line = keyword(".visible") + " " + keyword(".entry") + " "; + line += var(kernel_name) + " " + matched("("); + current_kernel = kernel_name; + } + } else if (starts_with(line, ")") && in_func_signature) { + stream << close_expand_button(); + in_func_signature = false; + line = matched(")") + line.substr(1); + } else if (starts_with(line, "{") && !in_braces) { + in_braces = true; + stream << matched("{"); + stream << close_expand_button(); + internal_assert(current_id != -1); + stream << open_div("Indent", current_id); + current_id = -1; + line = line.substr(1); + scope.push(current_kernel, unique_id()); + } else if (starts_with(line, "}") && in_braces) { + stream << close_div(); + line = matched("}") + line.substr(1); + in_braces = false; + scope.pop(current_kernel); + } + + bool indent = false; + + if (line[0] == '\t') { + // Replace first tab with four spaces. + line = line.substr(1); + indent = true; + } + + line = replace_all(line, ".f32", ".f32"); + line = replace_all(line, ".f64", ".f64"); + + line = replace_all(line, ".s8", ".s8"); + line = replace_all(line, ".s16", ".s16"); + line = replace_all(line, ".s32", ".s32"); + line = replace_all(line, ".s64", ".s64"); + + line = replace_all(line, ".u8", ".u8"); + line = replace_all(line, ".u16", ".u16"); + line = replace_all(line, ".u32", ".u32"); + line = replace_all(line, ".u64", ".u64"); + + line = replace_all(line, ".b8", ".b8"); + line = replace_all(line, ".b16", ".b16"); + line = replace_all(line, ".b32", ".b32"); + line = replace_all(line, ".b64", ".b64"); + + line = replace_all(line, ".v2", ".v2"); + line = replace_all(line, ".v4", ".v4"); + + line = replace_all(line, "ld.", "ld."); + line = replace_all(line, "st.", "st."); + + size_t idx; + if ((idx = line.find("//")) != std::string::npos) { + line.insert(idx, ""); + line += ""; + } + + // Predicated instructions + if (line.front() == '@' && indent) { + idx = line.find(" "); + std::string pred = line.substr(1, idx - 1); + line = "@" + var(pred) + "" + line.substr(idx); + } + + // Labels + if (line.front() == 'L' && !indent && (idx = line.find(":")) != std::string::npos) { + std::string label = line.substr(0, idx); + line = "" + var(label) + ":" + line.substr(idx + 1); + } + + // Highlight operands + if ((idx = line.find(" \t")) != std::string::npos && line.back() == ';') { + std::string operands_str = line.substr(idx + 2); + operands_str = operands_str.substr(0, operands_str.length() - 1); + std::vector operands = split_string(operands_str, ", "); + operands_str = ""; + for (size_t opidx = 0; opidx < operands.size(); ++opidx) { + std::string op = operands[opidx]; + internal_assert(op.size() > 0); + if (opidx != 0) { + operands_str += ", "; + } + if (op.back() == '}') { + std::string reg = op.substr(0, op.size() - 1); + operands_str += var(reg) + '}'; + } else if (op.front() == '%') { + operands_str += var(op); + } else if (op.find_first_not_of("-0123456789") == string::npos) { + operands_str += open_span("IntImm Imm"); + operands_str += op; + operands_str += close_span(); + } else if (starts_with(op, "0f") && + op.find_first_not_of("0123456789ABCDEF", 2) == string::npos) { + operands_str += open_span("FloatImm Imm"); + operands_str += op; + operands_str += close_span(); + } else if (op.front() == '[' && op.back() == ']') { + size_t idx = op.find("+"); + if (idx == std::string::npos) { + std::string reg = op.substr(1, op.size() - 2); + operands_str += '[' + var(reg) + ']'; + } else { + std::string reg = op.substr(1, idx - 2); + std::string offset = op.substr(idx + 1); + offset = offset.substr(0, offset.size() - 1); + operands_str += '[' + var(reg) + "+"; + operands_str += open_span("IntImm Imm"); + operands_str += offset; + operands_str += close_span(); + operands_str += ']'; + } + } else if (op.front() == '{') { + std::string reg = op.substr(1); + operands_str += '{' + var(reg); + } else if (op.front() == 'L') { + // Labels + operands_str += "" + var(op) + ""; + } else { + operands_str += op; + } + } + operands_str += ";"; + line = line.substr(0, idx + 2) + operands_str; + } + + if (indent) { + stream << " "; + } + stream << line << "\n"; + } + stream << ""; + } + void print(const Buffer<> &op) { bool include_data = ends_with(op.name(), "_gpu_source_kernels"); int id = 0; if (include_data) { id = unique_id(); stream << open_expand_button(id); - stream << open_span("Matched"); } stream << open_div("Buffer<>"); stream << keyword("buffer ") << var(op.name()); @@ -777,11 +941,15 @@ class StmtToHtml : public IRVisitor { stream << matched("{"); stream << close_expand_button(); - stream << open_div("BufferData", id); - stream << "
\n";
+            stream << open_div("BufferData Indent", id);
             std::string str((const char *)op.data(), op.size_in_bytes());
-            stream << str;
-            stream << "
\n"; + if (starts_with(op.name(), "cuda_")) { + print_cuda_gpu_source_kernels(str); + } else { + stream << "
\n";
+                stream << str;
+                stream << "
\n"; + } stream << close_div(); stream << " " << matched("}"); @@ -825,8 +993,6 @@ class StmtToHtml : public IRVisitor { stream << ""; stream << "\n"; stream << "\n"; - stream << "\n"; - stream << "\n"; stream << "\n"; stream << "\n"; stream << "\n \n"; @@ -861,6 +1027,22 @@ span.IntImm { color: #099; }\n \ span.FloatImm { color: #099; }\n \ b.Highlight { font-weight: bold; background-color: #DDD; }\n \ span.Highlight { font-weight: bold; background-color: #FF0; }\n \ +span.OpF32 { color: hsl(106deg 100% 40%); font-weight: bold; }\n \ +span.OpF64 { color: hsl(106deg 100% 30%); font-weight: bold; }\n \ +span.OpB8 { color: hsl(208deg 100% 80%); font-weight: bold; }\n \ +span.OpB16 { color: hsl(208deg 100% 70%); font-weight: bold; }\n \ +span.OpB32 { color: hsl(208deg 100% 60%); font-weight: bold; }\n \ +span.OpB64 { color: hsl(208deg 100% 50%); font-weight: bold; }\n \ +span.OpI8 { color: hsl( 46deg 100% 45%); font-weight: bold; }\n \ +span.OpI16 { color: hsl( 46deg 100% 40%); font-weight: bold; }\n \ +span.OpI32 { color: hsl( 46deg 100% 34%); font-weight: bold; }\n \ +span.OpI64 { color: hsl( 46deg 100% 27%); font-weight: bold; }\n \ +span.OpVec2 { background-color: hsl(100deg 100% 90%); font-weight: bold; }\n \ +span.OpVec4 { background-color: hsl(100deg 100% 80%); font-weight: bold; }\n \ +span.Memory { color: #d22; font-weight: bold; }\n \ +span.Pred { background-color: #ffe8bd; font-weight: bold; }\n \ +span.Label { background-color: #bde4ff; font-weight: bold; }\n \ +code.ptx { tab-size: 26; white-space: pre; }\n \ "; const std::string StmtToHtml::js = "\n \ From 04f99730a4cc9b470cd5c70a4f00b07935229098 Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Thu, 25 Nov 2021 16:25:49 +0100 Subject: [PATCH 3/4] Bugfix the register name extraction of offseted addressing. --- src/StmtToHtml.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StmtToHtml.cpp b/src/StmtToHtml.cpp index 937fc11691a2..4056a20c8956 100644 --- a/src/StmtToHtml.cpp +++ b/src/StmtToHtml.cpp @@ -896,7 +896,7 @@ class StmtToHtml : public IRVisitor { std::string reg = op.substr(1, op.size() - 2); operands_str += '[' + var(reg) + ']'; } else { - std::string reg = op.substr(1, idx - 2); + std::string reg = op.substr(1, idx - 1); std::string offset = op.substr(idx + 1); offset = offset.substr(0, offset.size() - 1); operands_str += '[' + var(reg) + "+"; From c89f188c7893f92d27b1b369f96ee6692ae486f2 Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Thu, 25 Nov 2021 16:45:32 +0100 Subject: [PATCH 4/4] Fix clang-tidy; --- src/StmtToHtml.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/StmtToHtml.cpp b/src/StmtToHtml.cpp index 4056a20c8956..a77183e31d11 100644 --- a/src/StmtToHtml.cpp +++ b/src/StmtToHtml.cpp @@ -853,13 +853,13 @@ class StmtToHtml : public IRVisitor { // Predicated instructions if (line.front() == '@' && indent) { - idx = line.find(" "); + idx = line.find(' '); std::string pred = line.substr(1, idx - 1); line = "@" + var(pred) + "" + line.substr(idx); } // Labels - if (line.front() == 'L' && !indent && (idx = line.find(":")) != std::string::npos) { + if (line.front() == 'L' && !indent && (idx = line.find(':')) != std::string::npos) { std::string label = line.substr(0, idx); line = "" + var(label) + ":" + line.substr(idx + 1); } @@ -872,7 +872,7 @@ class StmtToHtml : public IRVisitor { operands_str = ""; for (size_t opidx = 0; opidx < operands.size(); ++opidx) { std::string op = operands[opidx]; - internal_assert(op.size() > 0); + internal_assert(!op.empty()); if (opidx != 0) { operands_str += ", "; } @@ -891,7 +891,7 @@ class StmtToHtml : public IRVisitor { operands_str += op; operands_str += close_span(); } else if (op.front() == '[' && op.back() == ']') { - size_t idx = op.find("+"); + size_t idx = op.find('+'); if (idx == std::string::npos) { std::string reg = op.substr(1, op.size() - 2); operands_str += '[' + var(reg) + ']';