Ginkgo  Generated from pipelines/1556235455 branch based on develop. Ginkgo version 1.9.0
A numerical linear algebra library targeting many-core architectures
papi.hpp
1 // SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 #ifndef GKO_PUBLIC_CORE_LOG_PAPI_HPP_
6 #define GKO_PUBLIC_CORE_LOG_PAPI_HPP_
7 
8 
9 #include <ginkgo/config.hpp>
10 
11 
12 #if GKO_HAVE_PAPI_SDE
13 
14 
15 #include <cstddef>
16 #include <iostream>
17 #include <map>
18 #include <mutex>
19 
20 #include <sde_lib.h>
21 
22 #include <ginkgo/core/base/polymorphic_object.hpp>
23 #include <ginkgo/core/log/logger.hpp>
24 
25 
26 namespace gko {
27 namespace log {
28 
29 
30 static size_type papi_logger_count = 0;
31 static std::mutex papi_count_mutex;
32 
33 
58 template <typename ValueType = default_precision>
59 class Papi : public Logger {
60 public:
61  /* Executor events */
62  void on_allocation_started(const Executor* exec,
63  const size_type& num_bytes) const override;
64 
65  void on_allocation_completed(const Executor* exec,
66  const size_type& num_bytes,
67  const uintptr& location) const override;
68 
69  void on_free_started(const Executor* exec,
70  const uintptr& location) const override;
71 
72  void on_free_completed(const Executor* exec,
73  const uintptr& location) const override;
74 
75  void on_copy_started(const Executor* from, const Executor* to,
76  const uintptr& location_from,
77  const uintptr& location_to,
78  const size_type& num_bytes) const override;
79 
80  void on_copy_completed(const Executor* from, const Executor* to,
81  const uintptr& location_from,
82  const uintptr& location_to,
83  const size_type& num_bytes) const override;
84 
85  /* Operation events */
86  void on_operation_launched(const Executor* exec,
87  const Operation* operation) const override;
88 
89  void on_operation_completed(const Executor* exec,
90  const Operation* operation) const override;
91 
92  /* PolymorphicObject events */
94  const Executor*, const PolymorphicObject* po) const override;
95 
97  const Executor* exec, const PolymorphicObject* input,
98  const PolymorphicObject* output) 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 
109  const Executor* exec, const PolymorphicObject* from,
110  const PolymorphicObject* to) const override;
111 
113  const Executor* exec, const PolymorphicObject* from,
114  const PolymorphicObject* to) const override;
115 
117  const Executor* exec, const PolymorphicObject* po) const override;
118 
119  /* LinOp events */
120  void on_linop_apply_started(const LinOp* A, const LinOp* b,
121  const LinOp* x) const override;
122 
123  void on_linop_apply_completed(const LinOp* A, const LinOp* b,
124  const LinOp* x) const override;
125 
126  void on_linop_advanced_apply_started(const LinOp* A, const LinOp* alpha,
127  const LinOp* b, const LinOp* beta,
128  const LinOp* x) const override;
129 
130  void on_linop_advanced_apply_completed(const LinOp* A, const LinOp* alpha,
131  const LinOp* b, const LinOp* beta,
132  const LinOp* x) const override;
133 
134  /* LinOpFactory events */
136  const LinOp* input) const override;
137 
139  const LinOpFactory* factory, const LinOp* input,
140  const LinOp* output) const override;
141 
143  const stop::Criterion* criterion, const size_type& num_iterations,
144  const LinOp* residual, const LinOp* residual_norm,
145  const LinOp* solution, const uint8& stopping_id,
146  const bool& set_finalized, const array<stopping_status>* status,
147  const bool& one_changed, const bool& all_converged) const override;
148 
149  /* Internal solver events */
150  void on_iteration_complete(const LinOp* solver, const LinOp* b,
151  const LinOp* x, const size_type& num_iterations,
152  const LinOp* residual,
153  const LinOp* residual_norm,
154  const LinOp* implicit_resnorm_sq,
155  const array<stopping_status>* status,
156  bool stopped) const override;
157 
158  GKO_DEPRECATED(
159  "Please use the version with the additional stopping "
160  "information.")
161  void on_iteration_complete(const LinOp* solver,
162  const size_type& num_iterations,
163  const LinOp* residual, const LinOp* solution,
164  const LinOp* residual_norm) const override;
165 
166  GKO_DEPRECATED(
167  "Please use the version with the additional stopping "
168  "information.")
170  const LinOp* solver, const size_type& num_iterations,
171  const LinOp* residual, const LinOp* solution,
172  const LinOp* residual_norm,
173  const LinOp* implicit_sq_residual_norm) const override;
174 
180  GKO_DEPRECATED("use single-parameter create")
181  static std::shared_ptr<Papi> create(
182  std::shared_ptr<const gko::Executor>,
183  const Logger::mask_type& enabled_events = Logger::all_events_mask)
184  {
185  return Papi::create(enabled_events);
186  }
187 
193  static std::shared_ptr<Papi> create(
194  const Logger::mask_type& enabled_events = Logger::all_events_mask)
195  {
196  return std::shared_ptr<Papi>(new Papi(enabled_events), [](auto logger) {
197  auto handle = logger->get_handle();
198  delete logger;
199  papi_sde_shutdown(handle);
200  });
201  }
202 
209  const std::string get_handle_name() const { return name; }
210 
216  const papi_handle_t get_handle() const { return papi_handle; }
217 
218 protected:
219  GKO_DEPRECATED("use single-parameter constructor")
220  explicit Papi(
221  std::shared_ptr<const gko::Executor> exec,
222  const Logger::mask_type& enabled_events = Logger::all_events_mask)
223  : Papi(enabled_events)
224  {}
225 
226  explicit Papi(
227  const Logger::mask_type& enabled_events = Logger::all_events_mask)
228  : Logger(enabled_events)
229  {
230  std::ostringstream os;
231 
232  std::lock_guard<std::mutex> guard(papi_count_mutex);
233  os << "ginkgo" << papi_logger_count;
234  name = os.str();
235  papi_handle = papi_sde_init(name.c_str());
236  papi_logger_count++;
237  }
238 
239 private:
240  template <typename PointerType>
241  class papi_queue {
242  public:
243  papi_queue(papi_handle_t* handle, const char* counter_name)
244  : handle{handle}, counter_name{counter_name}
245  {}
246 
247  ~papi_queue()
248  {
249  for (auto e : data) {
250  std::ostringstream oss;
251  oss << counter_name << "::" << e.first;
252  papi_sde_unregister_counter(*handle, oss.str().c_str());
253  }
254  data.clear();
255  }
256 
257  size_type& get_counter(const PointerType* ptr)
258  {
259  const auto tmp = reinterpret_cast<uintptr>(ptr);
260  if (data.find(tmp) == data.end()) {
261  data[tmp] = 0;
262  }
263  auto& value = data[tmp];
264  if (!value) {
265  std::ostringstream oss;
266  oss << counter_name << "::" << tmp;
267  papi_sde_register_counter(*handle, oss.str().c_str(),
268  PAPI_SDE_RO | PAPI_SDE_INSTANT,
269  PAPI_SDE_long_long, &value);
270  }
271  return data[tmp];
272  }
273 
274  private:
275  papi_handle_t* handle;
276  const char* counter_name;
277  std::map<std::uintptr_t, size_type> data;
278  };
279 
280 
281  mutable papi_queue<Executor> allocation_started{&papi_handle,
282  "allocation_started"};
283  mutable papi_queue<Executor> allocation_completed{&papi_handle,
284  "allocation_completed"};
285  mutable papi_queue<Executor> free_started{&papi_handle, "free_started"};
286  mutable papi_queue<Executor> free_completed{&papi_handle, "free_completed"};
287  mutable papi_queue<Executor> copy_started_from{&papi_handle,
288  "copy_started_from"};
289  mutable papi_queue<Executor> copy_started_to{&papi_handle,
290  "copy_started_to"};
291  mutable papi_queue<Executor> copy_completed_from{&papi_handle,
292  "copy_completed_from"};
293  mutable papi_queue<Executor> copy_completed_to{&papi_handle,
294  "copy_completed_to"};
295 
296  mutable papi_queue<Executor> operation_launched{&papi_handle,
297  "operation_launched"};
298  mutable papi_queue<Executor> operation_completed{&papi_handle,
299  "operation_completed"};
300 
301  mutable papi_queue<Executor> polymorphic_object_create_started{
302  &papi_handle, "polymorphic_object_create_started"};
303  mutable papi_queue<Executor> polymorphic_object_create_completed{
304  &papi_handle, "polymorphic_object_create_completed"};
305  mutable papi_queue<Executor> polymorphic_object_copy_started{
306  &papi_handle, "polymorphic_object_copy_started"};
307  mutable papi_queue<Executor> polymorphic_object_copy_completed{
308  &papi_handle, "polymorphic_object_copy_completed"};
309  mutable papi_queue<Executor> polymorphic_object_move_started{
310  &papi_handle, "polymorphic_object_move_started"};
311  mutable papi_queue<Executor> polymorphic_object_move_completed{
312  &papi_handle, "polymorphic_object_move_completed"};
313  mutable papi_queue<Executor> polymorphic_object_deleted{
314  &papi_handle, "polymorphic_object_deleted"};
315 
316  mutable papi_queue<LinOpFactory> linop_factory_generate_started{
317  &papi_handle, "linop_factory_generate_started"};
318  mutable papi_queue<LinOpFactory> linop_factory_generate_completed{
319  &papi_handle, "linop_factory_generate_completed"};
320 
321  mutable papi_queue<LinOp> linop_apply_started{&papi_handle,
322  "linop_apply_started"};
323  mutable papi_queue<LinOp> linop_apply_completed{&papi_handle,
324  "linop_apply_completed"};
325  mutable papi_queue<LinOp> linop_advanced_apply_started{
326  &papi_handle, "linop_advanced_apply_started"};
327  mutable papi_queue<LinOp> linop_advanced_apply_completed{
328  &papi_handle, "linop_advanced_apply_completed"};
329 
330  mutable std::map<std::uintptr_t, void*> criterion_check_completed;
331 
332  mutable papi_queue<LinOp> iteration_complete{&papi_handle,
333  "iteration_complete"};
334 
335 
336  std::string name{"ginkgo"};
337  papi_handle_t papi_handle;
338 };
339 
340 
341 } // namespace log
342 } // namespace gko
343 
344 
345 #endif // GKO_HAVE_PAPI_SDE
346 #endif // GKO_PUBLIC_CORE_LOG_PAPI_HPP_
gko::log::Papi::on_iteration_complete
void on_iteration_complete(const LinOp *solver, const LinOp *b, const LinOp *x, const size_type &num_iterations, const LinOp *residual, const LinOp *residual_norm, const LinOp *implicit_resnorm_sq, const array< stopping_status > *status, bool stopped) const override
Register the iteration_complete event which logs every completed iterations.
gko::uint8
std::uint8_t uint8
8-bit unsigned integral type.
Definition: types.hpp:115
gko::log::Papi::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::log::profile_event_category::solver
Solver events.
gko::LinOp
Definition: lin_op.hpp:117
gko::log::Papi::on_operation_completed
void on_operation_completed(const Executor *exec, const Operation *operation) const override
Executor's operation completed event (method run).
gko::log::Papi::on_operation_launched
void on_operation_launched(const Executor *exec, const Operation *operation) const override
Executor's operation launched event (method run).
gko::PolymorphicObject
A PolymorphicObject is the abstract base for all "heavy" objects in Ginkgo that behave polymorphicall...
Definition: polymorphic_object.hpp:43
gko::log::Papi::on_polymorphic_object_create_started
void on_polymorphic_object_create_started(const Executor *, const PolymorphicObject *po) const override
PolymorphicObject's create started event.
gko::log::profile_event_category::factory
LinOpFactory events.
gko::log::Papi::on_allocation_completed
void on_allocation_completed(const Executor *exec, const size_type &num_bytes, const uintptr &location) const override
Executor's allocation completed event.
gko::log::Papi::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::criterion
Stopping criterion events.
gko::uintptr
std::uintptr_t uintptr
Unsigned integer type capable of holding a pointer to void.
Definition: types.hpp:138
gko::log::Papi::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::size_type
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:86
gko::log::Papi::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::Papi::create
static std::shared_ptr< Papi > create(std::shared_ptr< const gko::Executor >, const Logger::mask_type &enabled_events=Logger::all_events_mask)
Creates a Papi Logger.
Definition: papi.hpp:181
gko::log::Papi::on_copy_completed
void on_copy_completed(const Executor *from, const Executor *to, const uintptr &location_from, const uintptr &location_to, const size_type &num_bytes) const override
Executor's copy completed event.
gko
The Ginkgo namespace.
Definition: abstract_factory.hpp:20
gko::log::Papi::get_handle_name
const std::string get_handle_name() const
Returns the unique name of this logger, which can be used in the PAPI_read() call.
Definition: papi.hpp:209
gko::log::Papi::create
static std::shared_ptr< Papi > create(const Logger::mask_type &enabled_events=Logger::all_events_mask)
Creates a Papi Logger.
Definition: papi.hpp:193
gko::array
An array is a container which encapsulates fixed-sized arrays, stored on the Executor tied to the arr...
Definition: array.hpp:26
gko::log::Papi::on_copy_started
void on_copy_started(const Executor *from, const Executor *to, const uintptr &location_from, const uintptr &location_to, const size_type &num_bytes) const override
Executor's copy started event.
gko::log::Logger::all_events_mask
static constexpr mask_type all_events_mask
Bitset Mask which activates all events.
Definition: logger.hpp:88
gko::log::Papi::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::log::Papi::get_handle
const papi_handle_t get_handle() const
Returns the corresponding papi_handle_t for this logger.
Definition: papi.hpp:216
gko::log::Papi::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::Logger
Definition: logger.hpp:75
gko::log::Papi::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::Papi
Papi is a Logger which logs every event to the PAPI software.
Definition: papi.hpp:59
gko::log::Papi::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::stop::Criterion
The Criterion class is a base class for all stopping criteria.
Definition: criterion.hpp:36
gko::log::Papi::on_polymorphic_object_deleted
void on_polymorphic_object_deleted(const Executor *exec, const PolymorphicObject *po) const override
PolymorphicObject's deleted event.
gko::log::Papi::on_allocation_started
void on_allocation_started(const Executor *exec, const size_type &num_bytes) const override
Executor's allocation started event.
gko::log::Papi::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_converged) const override
stop::Criterion's check completed event.
gko::log::Papi::on_polymorphic_object_create_completed
void on_polymorphic_object_create_completed(const Executor *exec, const PolymorphicObject *input, const PolymorphicObject *output) const override
PolymorphicObject's create completed event.
gko::log::profile_event_category::operation
Kernel execution and data movement.
gko::Executor
The first step in using the Ginkgo library consists of creating an executor.
Definition: executor.hpp:615
gko::log::Papi::on_free_started
void on_free_started(const Executor *exec, const uintptr &location) const override
Executor's free started event.
gko::log::Papi::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::LinOpFactory
A LinOpFactory represents a higher order mapping which transforms one linear operator into another.
Definition: lin_op.hpp:384
gko::log::Papi::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::Operation
Operations can be used to define functionalities whose implementations differ among devices.
Definition: executor.hpp:258
gko::log::Papi::on_free_completed
void on_free_completed(const Executor *exec, const uintptr &location) const override
Executor's free completed event.