提交 27d4c4b3 编写于 作者: M Megvii Engine Team

refactor(stats): use static inline variable declaration

GitOrigin-RevId: 7d86e5f2578cfbdf4aace113de56837d3a6b1c48
上级 787a22a9
......@@ -14,7 +14,6 @@
#include <list>
#include "megbrain/imperative/transformations/trace.h"
#include "megbrain/imperative/utils/map.h"
#include "megbrain/imperative/utils/stats.h"
#include "./tensor.h"
......
......@@ -23,9 +23,9 @@
#include "megbrain/imperative/transformations/symbol.h"
#include "megbrain/imperative/transformations/trace.h"
#include "megbrain/imperative/utils/map.h"
#include "megbrain/imperative/utils/stats.h"
#include "megbrain/opr/io.h"
#include "megbrain/plugin/profiler.h"
#include "megbrain/utils/stats.h"
#include "./common.h"
#include "./grad.h"
......@@ -1367,9 +1367,9 @@ void init_tensor(py::module m) {
return reprs;
});
m.def("print_stats", [] { imperative::Stats::print(); });
m.def("print_stats", [] { Stats::print(); });
m.def("reset_stats", [] { imperative::Stats::reset(); });
m.def("reset_stats", [] { Stats::reset(); });
m.def("_get_convert_inputs",
[]() -> bool { return DTypePromoteCfg::convert_input_enabled; });
......
......@@ -21,7 +21,6 @@
#include "megbrain/imperative/transformations/symbol.h"
#include "megbrain/imperative/transformations/trace.h"
#include "megbrain/imperative/utils/map.h"
#include "megbrain/imperative/utils/stats.h"
#include "megbrain/opr/io.h"
#include "megbrain/plugin/profiler.h"
......
......@@ -14,7 +14,6 @@
#include "megbrain/imperative/utils/debug.h"
#include "megbrain/imperative/utils/helper.h"
#include "megbrain/imperative/utils/map.h"
#include "megbrain/imperative/utils/stats.h"
namespace mgb {
namespace imperative {
......
......@@ -19,7 +19,6 @@
#include "megbrain/imperative/ops/backward_graph.h"
#include "megbrain/imperative/ops/opr_attr.h"
#include "megbrain/imperative/ops/utility.h"
#include "megbrain/imperative/utils/stats.h"
#include "megbrain/imperative/utils/to_string.h"
#include "../blob_manager_impl.h"
......
......@@ -11,7 +11,6 @@
#include "megbrain/imperative/opr_utility.h"
#include "megbrain/imperative/ops/autogen.h"
#include "megbrain/imperative/utils/stats.h"
#include "megbrain/opr/basic_arith.h"
#include "megbrain/opr/utility.h"
......
......@@ -11,7 +11,6 @@
#include "megbrain/opr/dnn/pooling.h"
#include "megbrain/imperative/ops/autogen.h"
#include "megbrain/imperative/utils/stats.h"
#include "megbrain/opr/utility.h"
#include "megbrain/opr/internal/megdnn_opr_wrapper.h"
......
#include "megbrain/imperative/transformation.h"
#include "megbrain/imperative/utils/stats.h"
namespace mgb {
namespace imperative {
......
......@@ -10,7 +10,6 @@
*/
#include "megbrain/imperative/transformations/eval.h"
#include "megbrain/imperative/utils/stats.h"
namespace mgb {
namespace imperative {
......
......@@ -15,7 +15,6 @@
#include "megbrain/imperative/graph_cache.h"
#include "megbrain/imperative/resource_manager.h"
#include "megbrain/imperative/utils/stats.h"
#include <range/v3/all.hpp>
......
......@@ -13,7 +13,6 @@
#include "megbrain/imperative/ops/autogen.h"
#include "megbrain/imperative/ops/utility.h"
#include "megbrain/imperative/utils/stats.h"
namespace mgb {
namespace imperative {
......
......@@ -23,7 +23,6 @@
#include "megbrain/imperative/utils/debug.h"
#include "megbrain/imperative/utils/local_ptr.h"
#include "megbrain/imperative/utils/span.h"
#include "megbrain/imperative/utils/stats.h"
namespace mgb {
namespace imperative {
......
#include "megbrain/utils/stats.h"
namespace mgb {
Stats::TimerNode Stats::sm_root;
stats::Timer& Stats::get_timer(std::string name) {
auto full_name = name;
Stats::TimerNode* node = &Stats::sm_root;
while (true) {
auto pos = name.find("_");
if (pos == std::string::npos) {
auto& child = node->children[name];
child = std::make_unique<Stats::TimerNode>();
node = child.get();
auto& timer = node->timer;
if (!timer) {
timer = std::make_unique<stats::Timer>(full_name);
}
return *timer;
} else {
auto& child = node->children[name.substr(0, pos)];
if (!child) {
child = std::make_unique<Stats::TimerNode>();
}
node = child.get();
name = name.substr(pos + 1);
}
}
}
std::pair<long, long> Stats::print_node(
std::string name, TimerNode& node, size_t indent) {
auto print_indent = [&] {
for (size_t i = 0; i < indent; ++i) {
printf(" ");
}
};
long ns = 0, count = 0;
if (auto& timer = node.timer) {
print_indent();
printf("%s costs %'ld ns, hits %'ld times\n", name.c_str(),
(long)timer->get().count(), (long)timer->count());
ns = timer->get().count();
count = timer->count();
}
if (!node.children.empty()) {
bool collect_children = node.timer == nullptr;
if (collect_children) {
print_indent();
printf("%s:\n", name.c_str());
}
long ns = 0, count = 0;
for (auto&& child : node.children) {
auto&& child_res = print_node(child.first, *child.second, indent + 4);
auto&& child_ns = child_res.first;
auto&& child_count = child_res.second;
if (collect_children) {
ns += child_ns;
count += child_count;
}
}
if (collect_children) {
print_indent();
printf("total costs %'ld ns, hits %'ld times\n", ns, count);
}
}
return {ns, count};
}
void Stats::print() {
for (auto&& child : sm_root.children) {
print_node(child.first, *child.second);
}
}
void Stats::reset() {
auto reset_node = [](TimerNode& node, auto&& reset_node) -> void {
if (auto& timer = node.timer) {
timer->reset();
}
for (auto&& child : node.children) {
reset_node(*child.second, reset_node);
}
};
reset_node(sm_root, reset_node);
}
} // namespace mgb
\ No newline at end of file
......@@ -8,11 +8,12 @@
#include <unordered_map>
#include <vector>
#include "megbrain/common.h"
namespace mgb {
namespace imperative {
namespace stats {
#define MGE_ENABLE_STATS 0
#define MGE_ENABLE_STATS 1
class Timer {
public:
......@@ -72,7 +73,8 @@ private:
};
public:
Timer(std::string name, bool default_enabled = true);
Timer(std::string name, bool default_enabled = true)
: m_name(name), m_default_enabled(default_enabled){};
std::string name() { return m_name; }
auto time_scope_recursive() { return TimeScopeRecursive(*this); };
......@@ -89,111 +91,45 @@ public:
} // namespace stats
struct Stats {
private:
struct TimerNode {
std::map<std::string, std::unique_ptr<TimerNode>> children;
stats::Timer* timer = nullptr;
TimerNode() {}
std::unique_ptr<stats::Timer> timer;
};
static inline TimerNode sm_root;
static TimerNode sm_root;
// register your timers here
// for example:
//
// static inline stats::Timer mytimer;
//
// then use MGE_TIMER_SCOPE(mytimer) to collect durations in your code
// don't register your timers here
// use MGE_TIMER_SCOPE(mytimer) to collect durations in your code
public:
MGE_WIN_DECLSPEC_FUC static stats::Timer& get_timer(std::string name);
static std::pair<long, long> print_node(
std::string name, TimerNode& node, size_t indent = 0) {
auto print_indent = [&] {
for (size_t i = 0; i < indent; ++i) {
printf(" ");
}
};
long ns = 0, count = 0;
if (auto* timer = node.timer) {
print_indent();
printf("%s costs %'ld ns, hits %'ld times\n", name.c_str(),
(long)timer->get().count(), (long)timer->count());
ns = timer->get().count();
count = timer->count();
}
if (!node.children.empty()) {
bool collect_children = node.timer == nullptr;
if (collect_children) {
print_indent();
printf("%s:\n", name.c_str());
}
long ns = 0, count = 0;
for (auto&& child : node.children) {
auto [child_ns, child_count] =
print_node(child.first, *child.second, indent + 4);
if (collect_children) {
ns += child_ns;
count += child_count;
}
}
if (collect_children) {
print_indent();
printf("total costs %'ld ns, hits %'ld times\n", ns, count);
}
}
return {ns, count};
}
MGE_WIN_DECLSPEC_FUC static std::pair<long, long> print_node(
std::string name, TimerNode& node, size_t indent = 0);
static void print() {
for (auto&& child : sm_root.children) {
print_node(child.first, *child.second);
}
}
MGE_WIN_DECLSPEC_FUC static void print();
static void reset() {
auto reset_node = [](TimerNode& node, auto&& reset_node) -> void {
if (auto* timer = node.timer) {
timer->reset();
}
for (auto&& child : node.children) {
reset_node(*child.second, reset_node);
}
};
reset_node(sm_root, reset_node);
}
MGE_WIN_DECLSPEC_FUC static void reset();
};
inline stats::Timer::Timer(std::string name, bool default_enabled)
: m_name(name), m_default_enabled(default_enabled) {
std::vector<std::string> terms;
Stats::TimerNode* node = &Stats::sm_root;
while (true) {
auto pos = name.find(".");
if (pos == std::string::npos) {
auto& child = node->children[name];
child = std::make_unique<Stats::TimerNode>();
node = child.get();
node->timer = this;
break;
} else {
auto& child = node->children[name.substr(0, pos)];
if (!child) {
child = std::make_unique<Stats::TimerNode>();
}
node = child.get();
name = name.substr(pos + 1);
}
}
}
#if MGE_ENABLE_STATS
#define MGE_TIMER_SCOPE(name) auto name = Stats::name.time_scope_recursive()
#define MGE_TIMER_SCOPE(name) \
static auto& _timer_##name = mgb::Stats::get_timer(#name); \
auto name = _timer_##name.time_scope_recursive()
#define MGE_TIMER_SCOPE_RELEASE(name) name.release()
#define MGE_TIMER_SCOPE_ENABLE(name) auto name = Stats::name.enable_scope()
#define MGE_TIMER_SCOPE_ENABLE(name) \
static auto& _timer_##name = mgb::Stats::get_timer(#name); \
auto name = _timer_##name.enable_scope()
#else
#define MGE_TIMER_SCOPE(name) (void)0
#define MGE_TIMER_SCOPE_RELEASE(name) (void)0
#define MGE_TIMER_SCOPE_ENABLE(name) (void)0
#endif
} // namespace imperative
} // namespace mgb
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册