diff --git a/include/pareas/compiler/frontend.hpp b/include/pareas/compiler/frontend.hpp index abed9f7..3c71a9b 100644 --- a/include/pareas/compiler/frontend.hpp +++ b/include/pareas/compiler/frontend.hpp @@ -4,7 +4,7 @@ #include "futhark_generated.h" #include "pareas/compiler/ast.hpp" -#include "pareas/compiler/profiler.hpp" +#include "pareas/profiler/profiler.hpp" #include #include @@ -33,7 +33,7 @@ namespace frontend { std::runtime_error(error_name(e)) {} }; - DeviceAst compile(futhark_context* ctx, const std::string& input, Profiler& p); + DeviceAst compile(futhark_context* ctx, const std::string& input, pareas::Profiler& p); } #endif diff --git a/include/pareas/compiler/profiler.hpp b/include/pareas/compiler/profiler.hpp deleted file mode 100644 index 7705672..0000000 --- a/include/pareas/compiler/profiler.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _PAREAS_COMPILER_PROFILER_HPP -#define _PAREAS_COMPILER_PROFILER_HPP - -#include -#include -#include -#include - -struct Profiler { - using SyncCallback = std::function; - - using Clock = std::chrono::high_resolution_clock; - - struct HistoryEntry { - unsigned level; - const char* name; - Clock::duration elapsed; - }; - - unsigned max_level; - unsigned level; - - SyncCallback sync_callback; - std::vector starts; - std::vector history; - - Profiler(unsigned max_level); - - void set_sync_callback(SyncCallback sync_callback = null_callback); - - void begin(); - void end(const char* name); - - void dump(std::ostream& os); - - template - void measure(const char* name, F f) { - this->begin(); - f(); - this->end(name); - } - - static void null_callback() {} -}; - -#endif diff --git a/include/pareas/profiler/profiler.hpp b/include/pareas/profiler/profiler.hpp new file mode 100644 index 0000000..220ad8e --- /dev/null +++ b/include/pareas/profiler/profiler.hpp @@ -0,0 +1,48 @@ +#ifndef _PAREAS_PROFILER_PROFILER_HPP +#define _PAREAS_PROFILER_PROFILER_HPP + +#include +#include +#include +#include + +namespace pareas { + struct Profiler { + using SyncCallback = std::function; + + using Clock = std::chrono::high_resolution_clock; + + struct HistoryEntry { + unsigned level; + const char* name; + Clock::duration elapsed; + }; + + unsigned max_level; + unsigned level; + + SyncCallback sync_callback; + std::vector starts; + std::vector history; + + Profiler(unsigned max_level); + + void set_sync_callback(SyncCallback sync_callback = null_callback); + + void begin(); + void end(const char* name); + + void dump(std::ostream& os); + + template + void measure(const char* name, F f) { + this->begin(); + f(); + this->end(name); + } + + static void null_callback() {} + }; +} + +#endif diff --git a/meson.build b/meson.build index 2353081..f13e335 100644 --- a/meson.build +++ b/meson.build @@ -56,8 +56,15 @@ pareas_lpg_exe = executable( include_directories: inc, ) +# Profiling library +pareas_prof_dep = declare_dependency( + include_directories: inc, + sources: files('src/profiler/profiler.cpp'), + dependencies: fmt_dep, +) + # Compiler -dependencies = [fmt_dep, dependency('threads')] +dependencies = [pareas_prof_dep, fmt_dep, dependency('threads')] # Build futhark library futhark_backend = get_option('futhark-backend') @@ -143,7 +150,6 @@ sources = files( 'src/compiler/main.cpp', 'src/compiler/frontend.cpp', 'src/compiler/ast.cpp', - 'src/compiler/profiler.cpp', ) pareas_exe = executable( diff --git a/src/compiler/frontend.cpp b/src/compiler/frontend.cpp index f091560..798b30e 100644 --- a/src/compiler/frontend.cpp +++ b/src/compiler/frontend.cpp @@ -84,7 +84,7 @@ namespace frontend { } } - DeviceAst compile(futhark_context* ctx, const std::string& input, Profiler& p) { + DeviceAst compile(futhark_context* ctx, const std::string& input, pareas::Profiler& p) { p.begin(); p.begin(); auto lex_table = upload_lex_table(ctx); diff --git a/src/compiler/main.cpp b/src/compiler/main.cpp index 478d422..38213e6 100644 --- a/src/compiler/main.cpp +++ b/src/compiler/main.cpp @@ -4,7 +4,7 @@ #include "pareas/compiler/futhark_interop.hpp" #include "pareas/compiler/ast.hpp" #include "pareas/compiler/frontend.hpp" -#include "pareas/compiler/profiler.hpp" +#include "pareas/profiler/profiler.hpp" #include #include @@ -199,7 +199,7 @@ int main(int argc, char* argv[]) { return EXIT_SUCCESS; } - auto p = Profiler(opts.profile); + auto p = pareas::Profiler(opts.profile); auto in = std::ifstream(opts.input_path, std::ios::binary); if (!in) { diff --git a/src/compiler/profiler.cpp b/src/compiler/profiler.cpp deleted file mode 100644 index 16388ff..0000000 --- a/src/compiler/profiler.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "pareas/compiler/profiler.hpp" - -#include -#include - -#include -#include - -Profiler::Profiler(unsigned max_level): - max_level(max_level), - level(0), - sync_callback(null_callback) { -} - -void Profiler::set_sync_callback(SyncCallback sync_callback) { - this->sync_callback = sync_callback; -} - -void Profiler::begin() { - ++this->level; - if (this->level > this->max_level) - return; - - this->sync_callback(); - - auto start = Clock::now(); - this->starts.push_back(start); -} - -void Profiler::end(const char* name) { - --this->level; - if (this->level >= this->max_level) - return; - - this->sync_callback(); - - auto end = Clock::now(); - auto start = this->starts.back(); - this->starts.pop_back(); - auto diff = end - start; - this->history.push_back(HistoryEntry{this->level, name, diff}); -} - -void Profiler::dump(std::ostream& os) { - assert(this->level == 0); - - auto ordered_history = std::vector(this->history.size()); - auto level_index_stack = std::vector(); - - size_t j = 0; - for (const auto& entry : this->history) { - for (unsigned i = level_index_stack.size(); i <= entry.level; ++i) { - level_index_stack.push_back(j++); - } - - size_t index = level_index_stack.back(); - ordered_history[index] = entry; - level_index_stack.pop_back(); - } - - auto name_stack = std::vector(); - for (auto [level, name, elapsed] : ordered_history) { - name_stack.resize(level); - name_stack.push_back(name); - - auto us = std::chrono::duration_cast(elapsed); - fmt::print("{}: {}\n", fmt::join(name_stack, "."), us); - } -} diff --git a/src/profiler/profiler.cpp b/src/profiler/profiler.cpp new file mode 100644 index 0000000..1bc28c0 --- /dev/null +++ b/src/profiler/profiler.cpp @@ -0,0 +1,71 @@ +#include "pareas/profiler/profiler.hpp" + +#include +#include + +#include +#include + +namespace pareas { + Profiler::Profiler(unsigned max_level): + max_level(max_level), + level(0), + sync_callback(null_callback) { + } + + void Profiler::set_sync_callback(SyncCallback sync_callback) { + this->sync_callback = sync_callback; + } + + void Profiler::begin() { + ++this->level; + if (this->level > this->max_level) + return; + + this->sync_callback(); + + auto start = Clock::now(); + this->starts.push_back(start); + } + + void Profiler::end(const char* name) { + --this->level; + if (this->level >= this->max_level) + return; + + this->sync_callback(); + + auto end = Clock::now(); + auto start = this->starts.back(); + this->starts.pop_back(); + auto diff = end - start; + this->history.push_back(HistoryEntry{this->level, name, diff}); + } + + void Profiler::dump(std::ostream& os) { + assert(this->level == 0); + + auto ordered_history = std::vector(this->history.size()); + auto level_index_stack = std::vector(); + + size_t j = 0; + for (const auto& entry : this->history) { + for (unsigned i = level_index_stack.size(); i <= entry.level; ++i) { + level_index_stack.push_back(j++); + } + + size_t index = level_index_stack.back(); + ordered_history[index] = entry; + level_index_stack.pop_back(); + } + + auto name_stack = std::vector(); + for (auto [level, name, elapsed] : ordered_history) { + name_stack.resize(level); + name_stack.push_back(name); + + auto us = std::chrono::duration_cast(elapsed); + fmt::print("{}: {}\n", fmt::join(name_stack, "."), us); + } + } +}