Skip to content

Commit

Permalink
Integrate user_benchmarker instance into runtime to avoid UB from sta…
Browse files Browse the repository at this point in the history
…tic destruction order
  • Loading branch information
fknorr committed Jan 3, 2022
1 parent 2ab0c46 commit d1c9e51
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 31 deletions.
8 changes: 8 additions & 0 deletions include/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
#include "types.h"

namespace celerity {

namespace experimental::bench::detail {
class user_benchmarker;
} // namespace experimental::bench::detail

namespace detail {

class buffer_manager;
Expand Down Expand Up @@ -57,6 +62,8 @@ namespace detail {

task_manager& get_task_manager() const;

experimental::bench::detail::user_benchmarker& get_user_benchmarker() const { return *user_bench; }

host_queue& get_host_queue() const { return *h_queue; }

device_queue& get_device_queue() const { return *d_queue; }
Expand Down Expand Up @@ -84,6 +91,7 @@ namespace detail {
bool is_shutting_down = false;

std::unique_ptr<config> cfg;
std::unique_ptr<experimental::bench::detail::user_benchmarker> user_bench;
std::unique_ptr<host_queue> h_queue;
std::unique_ptr<device_queue> d_queue;
size_t num_nodes;
Expand Down
21 changes: 8 additions & 13 deletions include/user_bench.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,11 @@ namespace experimental {

class user_benchmarker {
public:
static void initialize(config& cfg, node_id this_nid);
static void destroy();

user_benchmarker(config& cfg, node_id this_nid);
user_benchmarker(const user_benchmarker&) = delete;
user_benchmarker(user_benchmarker&&) = delete;
~user_benchmarker();

static user_benchmarker& get_instance();

void log_user_config(logger_map lm) const;

template <typename... Args>
Expand Down Expand Up @@ -59,25 +55,24 @@ namespace experimental {
bench_clock::time_point start;
};

static std::unique_ptr<user_benchmarker> instance;
std::shared_ptr<logger> bench_logger;
node_id this_nid;
section_id next_section_id = 0;
std::stack<section> sections;

user_benchmarker(config& cfg, node_id this_nid);

void begin_section(std::string name);
void end_section(std::string name);
void log_event(const std::string& message) const;
void log_event(logger_map lm) const;
};

user_benchmarker& get_user_benchmarker();
} // namespace detail

/**
* @brief Logs structured user configuration data. Only logged once (on the master node).
*/
inline void log_user_config(const detail::logger_map& lm) { detail::user_benchmarker::get_instance().log_user_config(lm); }
inline void log_user_config(const detail::logger_map& lm) { detail::get_user_benchmarker().log_user_config(lm); }

/**
* @brief Begins a new benchmarking section.
Expand All @@ -86,26 +81,26 @@ namespace experimental {
*/
template <typename... Args>
void begin(const char* bench_section_fmt, Args... args) {
detail::user_benchmarker::get_instance().begin(bench_section_fmt, std::forward<Args>(args)...);
detail::get_user_benchmarker().begin(bench_section_fmt, std::forward<Args>(args)...);
}

/**
* @brief Ends an existing benchmarking section.
*/
template <typename... Args>
void end(const char* bench_section_fmt, Args... args) {
detail::user_benchmarker::get_instance().end(bench_section_fmt, std::forward<Args>(args)...);
detail::get_user_benchmarker().end(bench_section_fmt, std::forward<Args>(args)...);
}

/**
* @brief Logs a benchmarking event.
*/
template <typename... Args>
void event(const char* event_fmt, Args... args) {
detail::user_benchmarker::get_instance().event(event_fmt, std::forward<Args>(args)...);
detail::get_user_benchmarker().event(event_fmt, std::forward<Args>(args)...);
}

inline void event(const detail::logger_map& lm) { detail::user_benchmarker::get_instance().event(lm); }
inline void event(const detail::logger_map& lm) { detail::get_user_benchmarker().event(lm); }

} // namespace bench
} // namespace experimental
Expand Down
5 changes: 2 additions & 3 deletions src/runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ namespace detail {
cfg = std::make_unique<config>(argc, argv, *default_logger);
graph_logger->set_level(cfg->get_log_level());

experimental::bench::detail::user_benchmarker::initialize(*cfg, static_cast<node_id>(world_rank));
user_bench = std::make_unique<experimental::bench::detail::user_benchmarker>(*cfg, static_cast<node_id>(world_rank));

h_queue = std::make_unique<host_queue>(*default_logger);
d_queue = std::make_unique<device_queue>(*default_logger);
Expand Down Expand Up @@ -149,8 +149,7 @@ namespace detail {
buffer_mngr.reset();
d_queue.reset();
h_queue.reset();

experimental::bench::detail::user_benchmarker::destroy();
user_bench.reset();

// Make sure we free all of our MPI transfers before we finalize
while(!active_flushes.empty()) {
Expand Down
17 changes: 2 additions & 15 deletions src/user_bench.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,13 @@ namespace celerity {
namespace experimental {
namespace bench {
namespace detail {
std::unique_ptr<user_benchmarker> user_benchmarker::instance = nullptr;

void user_benchmarker::initialize(config& cfg, node_id this_nid) {
assert(instance == nullptr && "User benchmarking has already been initialized");
instance = std::unique_ptr<user_benchmarker>(new user_benchmarker(cfg, this_nid));
}

void user_benchmarker::destroy() { instance.reset(); }

user_benchmarker::~user_benchmarker() {
while(!sections.empty()) {
const auto sec = sections.top();
end_section(sec.name);
}
}

user_benchmarker& user_benchmarker::get_instance() {
if(!celerity::detail::runtime::is_initialized()) { throw std::runtime_error("Cannot use benchmarking before runtime has been initialized"); }
assert(instance != nullptr && "User benchmarking was not properly initialized");
return *instance;
}

void user_benchmarker::log_user_config(logger_map lm) const {
assert(lm.count("event") == 0 && "Key 'event' not allowed in user config");
if(this_nid == 0) {
Expand All @@ -46,6 +31,8 @@ namespace experimental {
}
}

user_benchmarker& get_user_benchmarker() { return celerity::detail::runtime::get_instance().get_user_benchmarker(); }

void user_benchmarker::begin_section(std::string name) {
const section sec = {next_section_id++, name, bench_clock::now()};
sections.push(sec);
Expand Down

0 comments on commit d1c9e51

Please sign in to comment.