Ginkgo  Generated from pipelines/1330831941 branch based on master. Ginkgo version 1.8.0
A numerical linear algebra library targeting many-core architectures
profiler_hook.hpp
1 // SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 #ifndef GKO_PUBLIC_CORE_LOG_PROFILER_HOOK_HPP_
6 #define GKO_PUBLIC_CORE_LOG_PROFILER_HOOK_HPP_
7 
8 
9 #include <iostream>
10 #include <unordered_map>
11 
12 
13 #include <ginkgo/config.hpp>
14 #include <ginkgo/core/base/timer.hpp>
15 #include <ginkgo/core/log/logger.hpp>
16 
17 
18 namespace gko {
19 namespace log {
20 
21 
25  memory,
27  operation,
29  object,
31  linop,
33  factory,
35  solver,
37  criterion,
39  user,
41  internal,
42 };
43 
44 
45 class profiling_scope_guard;
46 
47 
58 class ProfilerHook : public Logger {
59 public:
60  using hook_function =
61  std::function<void(const char*, profile_event_category)>;
62 
63  void on_allocation_started(const gko::Executor* exec,
64  const gko::size_type&) const override;
65 
66  void on_allocation_completed(const gko::Executor* exec,
67  const gko::size_type&,
68  const gko::uintptr&) const override;
69 
70  void on_free_started(const gko::Executor* exec,
71  const gko::uintptr&) const override;
72 
73  void on_free_completed(const gko::Executor* exec,
74  const gko::uintptr&) const override;
75 
76  void on_copy_started(const gko::Executor* from, const gko::Executor* to,
77  const gko::uintptr&, const gko::uintptr&,
78  const gko::size_type&) const override;
79 
80  void on_copy_completed(const gko::Executor* from, const gko::Executor* to,
81  const gko::uintptr&, const gko::uintptr&,
82  const gko::size_type&) const override;
83 
84  /* Operation events */
85  void on_operation_launched(const Executor* exec,
86  const Operation* operation) const override;
87 
88  void on_operation_completed(const Executor* exec,
89  const Operation* operation) const override;
90 
91  /* PolymorphicObject events */
93  const Executor* exec, const PolymorphicObject* from,
94  const PolymorphicObject* to) const override;
95 
97  const Executor* exec, const PolymorphicObject* from,
98  const PolymorphicObject* to) const override;
99 
101  const Executor* exec, const PolymorphicObject* from,
102  const PolymorphicObject* to) const override;
103 
105  const Executor* exec, const PolymorphicObject* from,
106  const PolymorphicObject* to) const override;
107 
108  /* LinOp events */
109  void on_linop_apply_started(const LinOp* A, const LinOp* b,
110  const LinOp* x) const override;
111 
112  void on_linop_apply_completed(const LinOp* A, const LinOp* b,
113  const LinOp* x) const override;
114 
115  void on_linop_advanced_apply_started(const LinOp* A, const LinOp* alpha,
116  const LinOp* b, const LinOp* beta,
117  const LinOp* x) const override;
118 
119  void on_linop_advanced_apply_completed(const LinOp* A, const LinOp* alpha,
120  const LinOp* b, const LinOp* beta,
121  const LinOp* x) const override;
122 
123  /* LinOpFactory events */
125  const LinOp* input) const override;
126 
128  const LinOpFactory* factory, const LinOp* input,
129  const LinOp* output) const override;
130 
131  /* Criterion events */
133  const size_type& num_iterations,
134  const LinOp* residual,
135  const LinOp* residual_norm,
136  const LinOp* solution,
137  const uint8& stopping_id,
138  const bool& set_finalized) const override;
139 
141  const stop::Criterion* criterion, const size_type& num_iterations,
142  const LinOp* residual, const LinOp* residual_norm,
143  const LinOp* solution, const uint8& stopping_id,
144  const bool& set_finalized, const array<stopping_status>* status,
145  const bool& one_changed, const bool& all_stopped) const override;
146 
148  const stop::Criterion* criterion, const size_type& num_iterations,
149  const LinOp* residual, const LinOp* residual_norm,
150  const LinOp* implicit_sq_resnorm, const LinOp* solution,
151  const uint8& stopping_id, const bool& set_finalized,
152  const array<stopping_status>* status, const bool& one_changed,
153  const bool& all_stopped) const override;
154 
155  /* Internal solver events */
157  const LinOp* solver, const LinOp* right_hand_side,
158  const LinOp* solution, const size_type& num_iterations,
159  const LinOp* residual, const LinOp* residual_norm,
160  const LinOp* implicit_sq_residual_norm,
161  const array<stopping_status>* status, bool stopped) const override;
162 
163  GKO_DEPRECATED(
164  "Please use the version with the additional stopping "
165  "information.")
166  void on_iteration_complete(const LinOp* solver,
167  const size_type& num_iterations,
168  const LinOp* residual, const LinOp* solution,
169  const LinOp* residual_norm) const override;
170 
171  GKO_DEPRECATED(
172  "Please use the version with the additional stopping "
173  "information.")
175  const LinOp* solver, const size_type& num_iterations,
176  const LinOp* residual, const LinOp* solution,
177  const LinOp* residual_norm,
178  const LinOp* implicit_sq_residual_norm) const override;
179 
180  bool needs_propagation() const override;
181 
190  std::string name);
191 
197  void set_synchronization(bool synchronize);
198 
208  profiling_scope_guard user_range(const char* name) const;
209 
211  constexpr static uint32 color_yellow_argb = 0xFFFFCB05U;
212 
221  static std::shared_ptr<ProfilerHook> create_tau(bool initialize = true);
222 
226  static std::shared_ptr<ProfilerHook> create_vtune();
227 
233  static std::shared_ptr<ProfilerHook> create_nvtx(
234  uint32 color_argb = color_yellow_argb);
235 
239  static std::shared_ptr<ProfilerHook> create_roctx();
240 
246  static std::shared_ptr<ProfilerHook> create_for_executor(
247  std::shared_ptr<const Executor> exec);
248 
249  struct summary_entry {
251  std::string name;
253  std::chrono::nanoseconds inclusive{0};
258  std::chrono::nanoseconds exclusive{0};
261  };
262 
265  std::string name;
267  std::chrono::nanoseconds elapsed{0};
271  std::vector<nested_summary_entry> children{};
272  };
273 
276  public:
277  virtual ~SummaryWriter() = default;
278 
285  virtual void write(const std::vector<summary_entry>& entries,
286  std::chrono::nanoseconds overhead) = 0;
287  };
288 
291  public:
292  virtual ~NestedSummaryWriter() = default;
293 
300  virtual void write_nested(const nested_summary_entry& root,
301  std::chrono::nanoseconds overhead) = 0;
302  };
303 
310  public NestedSummaryWriter {
311  public:
318  TableSummaryWriter(std::ostream& output = std::cerr,
319  std::string header = "Runtime summary");
320 
321  void write(const std::vector<summary_entry>& entries,
322  std::chrono::nanoseconds overhead) override;
323 
324  void write_nested(const nested_summary_entry& root,
325  std::chrono::nanoseconds overhead) override;
326 
327  private:
328  std::ostream* output_;
329  std::string header_;
330  };
331 
348  static std::shared_ptr<ProfilerHook> create_summary(
349  std::shared_ptr<Timer> timer = std::make_shared<CpuTimer>(),
350  std::unique_ptr<SummaryWriter> writer =
351  std::make_unique<TableSummaryWriter>(),
352  bool debug_check_nesting = false);
353 
371  static std::shared_ptr<ProfilerHook> create_nested_summary(
372  std::shared_ptr<Timer> timer = std::make_shared<CpuTimer>(),
373  std::unique_ptr<NestedSummaryWriter> writer =
374  std::make_unique<TableSummaryWriter>(),
375  bool debug_check_nesting = false);
376 
381  static std::shared_ptr<ProfilerHook> create_custom(hook_function begin,
382  hook_function end);
383 
384 private:
385  ProfilerHook(hook_function begin, hook_function end);
386 
387  void maybe_synchronize(const Executor* exec) const;
388 
389  std::string stringify_object(const PolymorphicObject* obj) const;
390 
391  std::unordered_map<const PolymorphicObject*, std::string> name_map_;
392  bool synchronize_;
393  hook_function begin_hook_;
394  hook_function end_hook_;
395 };
396 
397 
402 public:
405 
414  profiling_scope_guard(const char* name, profile_event_category category,
415  ProfilerHook::hook_function begin,
416  ProfilerHook::hook_function end);
417 
420 
422 
423  // TODO17: unnecessary with guaranteed RVO
426 
427  profiling_scope_guard& operator=(const profiling_scope_guard&) = delete;
428 
429  profiling_scope_guard& operator=(profiling_scope_guard&&) = delete;
430 
431 private:
432  bool empty_;
433  const char* name_;
434  profile_event_category category_;
435  ProfilerHook::hook_function end_;
436 };
437 
438 
439 } // namespace log
440 } // namespace gko
441 
442 
443 #endif // GKO_PUBLIC_CORE_LOG_PROFILER_HOOK_HPP_
gko::log::ProfilerHook::on_allocation_started
void on_allocation_started(const gko::Executor *exec, const gko::size_type &) const override
Executor's allocation started event.
gko::log::ProfilerHook::create_vtune
static std::shared_ptr< ProfilerHook > create_vtune()
Creates a logger annotating Ginkgo events with VTune ITT ranges.
gko::uint8
std::uint8_t uint8
8-bit unsigned integral type.
Definition: types.hpp:137
gko::log::ProfilerHook::set_object_name
void set_object_name(ptr_param< const PolymorphicObject > obj, std::string name)
Sets the name for an object to be profiled.
gko::log::ProfilerHook::create_tau
static std::shared_ptr< ProfilerHook > create_tau(bool initialize=true)
Creates a logger annotating Ginkgo events with TAU ranges via PerfStubs.
gko::log::ProfilerHook::on_criterion_check_started
void on_criterion_check_started(const stop::Criterion *criterion, const size_type &num_iterations, const LinOp *residual, const LinOp *residual_norm, const LinOp *solution, const uint8 &stopping_id, const bool &set_finalized) const override
stop::Criterion's check started event.
gko::log::profile_event_category::solver
Solver events.
gko::log::ProfilerHook::create_roctx
static std::shared_ptr< ProfilerHook > create_roctx()
Creates a logger annotating Ginkgo events with ROCTX ranges for HIP.
gko::log::ProfilerHook::create_nested_summary
static std::shared_ptr< ProfilerHook > create_nested_summary(std::shared_ptr< Timer > timer=std::make_shared< CpuTimer >(), std::unique_ptr< NestedSummaryWriter > writer=std::make_unique< TableSummaryWriter >(), bool debug_check_nesting=false)
Creates a logger measuring the runtime of Ginkgo events in a nested fashion and printing a summary wh...
gko::log::ProfilerHook::nested_summary_entry::elapsed
std::chrono::nanoseconds elapsed
The total runtime of all invocations of the range in nanoseconds.
Definition: profiler_hook.hpp:267
gko::log::ProfilerHook::color_yellow_argb
constexpr static uint32 color_yellow_argb
The Ginkgo yellow background color as packed 32 bit ARGB value.
Definition: profiler_hook.hpp:211
gko::LinOp
Definition: lin_op.hpp:118
gko::log::profiling_scope_guard
Scope guard that annotates its scope with the provided profiler hooks.
Definition: profiler_hook.hpp:401
gko::log::ProfilerHook::on_operation_launched
void on_operation_launched(const Executor *exec, const Operation *operation) const override
Executor's operation launched event (method run).
gko::log::ProfilerHook::on_linop_advanced_apply_completed
void on_linop_advanced_apply_completed(const LinOp *A, const LinOp *alpha, const LinOp *b, const LinOp *beta, const LinOp *x) const override
LinOp's advanced apply completed event.
gko::PolymorphicObject
A PolymorphicObject is the abstract base for all "heavy" objects in Ginkgo that behave polymorphicall...
Definition: polymorphic_object.hpp:44
gko::log::profile_event_category::factory
LinOpFactory events.
gko::log::ProfilerHook::SummaryWriter
Receives the results from ProfilerHook::create_summary().
Definition: profiler_hook.hpp:275
gko::log::profile_event_category::criterion
Stopping criterion events.
gko::log::ProfilerHook::summary_entry::name
std::string name
The name of the range.
Definition: profiler_hook.hpp:251
gko::uintptr
std::uintptr_t uintptr
Unsigned integer type capable of holding a pointer to void.
Definition: types.hpp:160
gko::log::ProfilerHook::on_linop_advanced_apply_started
void on_linop_advanced_apply_started(const LinOp *A, const LinOp *alpha, const LinOp *b, const LinOp *beta, const LinOp *x) const override
LinOp's advanced apply started event.
gko::log::ProfilerHook::summary_entry::exclusive
std::chrono::nanoseconds exclusive
The total runtime of all invocations of the range in nanoseconds, excluding the runtime of all nested...
Definition: profiler_hook.hpp:258
gko::size_type
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:108
gko::log::ProfilerHook::needs_propagation
bool needs_propagation() const override
Returns true if this logger, when attached to an Executor, needs to be forwarded all events from obje...
gko::log::ProfilerHook::NestedSummaryWriter
Receives the results from ProfilerHook::create_nested_summary().
Definition: profiler_hook.hpp:290
gko::log::ProfilerHook::on_copy_completed
void on_copy_completed(const gko::Executor *from, const gko::Executor *to, const gko::uintptr &, const gko::uintptr &, const gko::size_type &) const override
Executor's copy completed event.
gko::initialize
std::unique_ptr< Matrix > initialize(size_type stride, std::initializer_list< typename Matrix::value_type > vals, std::shared_ptr< const Executor > exec, TArgs &&... create_args)
Creates and initializes a column-vector.
Definition: dense.hpp:1540
gko::log::ProfilerHook::nested_summary_entry::count
int64 count
The total number of invocations of the range.
Definition: profiler_hook.hpp:269
gko::log::profile_event_category::memory
Memory allocation.
gko::log::ProfilerHook::nested_summary_entry
Definition: profiler_hook.hpp:263
gko::log::ProfilerHook::on_iteration_complete
void on_iteration_complete(const LinOp *solver, const LinOp *right_hand_side, const LinOp *solution, const size_type &num_iterations, const LinOp *residual, const LinOp *residual_norm, const LinOp *implicit_sq_residual_norm, const array< stopping_status > *status, bool stopped) const override
Register the iteration_complete event which logs every completed iterations.
gko::log::ProfilerHook::summary_entry
Definition: profiler_hook.hpp:249
gko::log::ProfilerHook::on_allocation_completed
void on_allocation_completed(const gko::Executor *exec, const gko::size_type &, const gko::uintptr &) const override
Executor's allocation completed event.
gko
The Ginkgo namespace.
Definition: abstract_factory.hpp:20
gko::log::ProfilerHook::set_synchronization
void set_synchronization(bool synchronize)
Should the events call executor->synchronize on operations and copy/allocation? This leads to a certa...
gko::array
An array is a container which encapsulates fixed-sized arrays, stored on the Executor tied to the arr...
Definition: array.hpp:27
gko::log::ProfilerHook::user_range
profiling_scope_guard user_range(const char *name) const
Creates a scope guard for a user-defined range to be included in the profile.
gko::log::profile_event_category::object
PolymorphicObject events.
gko::log::ProfilerHook::nested_summary_entry::name
std::string name
The name of the range.
Definition: profiler_hook.hpp:265
gko::log::profile_event_category::user
User-defined events.
gko::log::ProfilerHook::on_polymorphic_object_move_started
void on_polymorphic_object_move_started(const Executor *exec, const PolymorphicObject *from, const PolymorphicObject *to) const override
PolymorphicObject's move started event.
gko::uint32
std::uint32_t uint32
32-bit unsigned integral type.
Definition: types.hpp:148
gko::log::ProfilerHook
This Logger can be used to annotate the execution of Ginkgo functionality with profiler-specific rang...
Definition: profiler_hook.hpp:58
gko::log::ProfilerHook::on_linop_factory_generate_started
void on_linop_factory_generate_started(const LinOpFactory *factory, const LinOp *input) const override
LinOp Factory's generate started event.
gko::log::profile_event_category
profile_event_category
Categorization of logger events.
Definition: profiler_hook.hpp:23
gko::log::ProfilerHook::on_linop_apply_completed
void on_linop_apply_completed(const LinOp *A, const LinOp *b, const LinOp *x) const override
LinOp's apply completed event.
gko::log::ProfilerHook::create_summary
static std::shared_ptr< ProfilerHook > create_summary(std::shared_ptr< Timer > timer=std::make_shared< CpuTimer >(), std::unique_ptr< SummaryWriter > writer=std::make_unique< TableSummaryWriter >(), bool debug_check_nesting=false)
Creates a logger measuring the runtime of Ginkgo events and printing a summary when it is destroyed.
gko::ptr_param
This class is used for function parameters in the place of raw pointers.
Definition: utils_helper.hpp:43
gko::log::ProfilerHook::TableSummaryWriter::TableSummaryWriter
TableSummaryWriter(std::ostream &output=std::cerr, std::string header="Runtime summary")
Constructs a writer on an output stream.
gko::log::Logger
Definition: logger.hpp:76
gko::log::ProfilerHook::on_operation_completed
void on_operation_completed(const Executor *exec, const Operation *operation) const override
Executor's operation completed event (method run).
gko::log::ProfilerHook::on_free_started
void on_free_started(const gko::Executor *exec, const gko::uintptr &) const override
Executor's free started event.
gko::stop::Criterion
The Criterion class is a base class for all stopping criteria.
Definition: criterion.hpp:36
gko::log::ProfilerHook::create_nvtx
static std::shared_ptr< ProfilerHook > create_nvtx(uint32 color_argb=color_yellow_argb)
Creates a logger annotating Ginkgo events with NVTX ranges for CUDA.
gko::log::ProfilerHook::create_for_executor
static std::shared_ptr< ProfilerHook > create_for_executor(std::shared_ptr< const Executor > exec)
Creates a logger annotating Ginkgo events with the most suitable backend for the given executor: NVTX...
gko::log::ProfilerHook::on_linop_factory_generate_completed
void on_linop_factory_generate_completed(const LinOpFactory *factory, const LinOp *input, const LinOp *output) const override
LinOp Factory's generate completed event.
gko::log::ProfilerHook::on_free_completed
void on_free_completed(const gko::Executor *exec, const gko::uintptr &) const override
Executor's free completed event.
gko::log::ProfilerHook::on_copy_started
void on_copy_started(const gko::Executor *from, const gko::Executor *to, const gko::uintptr &, const gko::uintptr &, const gko::size_type &) const override
Executor's copy started event.
gko::log::ProfilerHook::on_criterion_check_completed
void on_criterion_check_completed(const stop::Criterion *criterion, const size_type &num_iterations, const LinOp *residual, const LinOp *residual_norm, const LinOp *solution, const uint8 &stopping_id, const bool &set_finalized, const array< stopping_status > *status, const bool &one_changed, const bool &all_stopped) const override
stop::Criterion's check completed event.
gko::log::ProfilerHook::TableSummaryWriter
Writes the results from ProfilerHook::create_summary() and ProfilerHook::create_nested_summary() to a...
Definition: profiler_hook.hpp:309
gko::log::profile_event_category::linop
LinOp events.
gko::log::ProfilerHook::create_custom
static std::shared_ptr< ProfilerHook > create_custom(hook_function begin, hook_function end)
Creates a logger annotating Ginkgo events with a custom set of functions for range begin and end.
gko::int64
std::int64_t int64
64-bit signed integral type.
Definition: types.hpp:131
gko::log::ProfilerHook::summary_entry::inclusive
std::chrono::nanoseconds inclusive
The total runtime of all invocations of the range in nanoseconds.
Definition: profiler_hook.hpp:253
gko::log::profile_event_category::operation
Kernel execution and data movement.
gko::log::ProfilerHook::TableSummaryWriter::write
void write(const std::vector< summary_entry > &entries, std::chrono::nanoseconds overhead) override
Callback to write out the summary results.
gko::log::ProfilerHook::NestedSummaryWriter::write_nested
virtual void write_nested(const nested_summary_entry &root, std::chrono::nanoseconds overhead)=0
Callback to write out the summary results.
gko::Executor
The first step in using the Ginkgo library consists of creating an executor.
Definition: executor.hpp:616
gko::log::ProfilerHook::TableSummaryWriter::write_nested
void write_nested(const nested_summary_entry &root, std::chrono::nanoseconds overhead) override
Callback to write out the summary results.
gko::log::profiling_scope_guard::~profiling_scope_guard
~profiling_scope_guard()
Calls the range end function if the scope guard was not moved from.
gko::log::ProfilerHook::SummaryWriter::write
virtual void write(const std::vector< summary_entry > &entries, std::chrono::nanoseconds overhead)=0
Callback to write out the summary results.
gko::LinOpFactory
A LinOpFactory represents a higher order mapping which transforms one linear operator into another.
Definition: lin_op.hpp:385
gko::log::profiling_scope_guard::profiling_scope_guard
profiling_scope_guard()
Creates an empty (moved-from) scope guard.
gko::log::ProfilerHook::on_linop_apply_started
void on_linop_apply_started(const LinOp *A, const LinOp *b, const LinOp *x) const override
LinOp's apply started event.
gko::log::ProfilerHook::nested_summary_entry::children
std::vector< nested_summary_entry > children
The nested ranges inside this range.
Definition: profiler_hook.hpp:271
gko::log::ProfilerHook::on_polymorphic_object_copy_started
void on_polymorphic_object_copy_started(const Executor *exec, const PolymorphicObject *from, const PolymorphicObject *to) const override
PolymorphicObject's copy started event.
gko::log::ProfilerHook::on_polymorphic_object_move_completed
void on_polymorphic_object_move_completed(const Executor *exec, const PolymorphicObject *from, const PolymorphicObject *to) const override
PolymorphicObject's move completed event.
gko::log::ProfilerHook::summary_entry::count
int64 count
The total number of invocations of the range.
Definition: profiler_hook.hpp:260
gko::log::ProfilerHook::on_polymorphic_object_copy_completed
void on_polymorphic_object_copy_completed(const Executor *exec, const PolymorphicObject *from, const PolymorphicObject *to) const override
PolymorphicObject's copy completed event.
gko::Operation
Operations can be used to define functionalities whose implementations differ among devices.
Definition: executor.hpp:259