Ginkgo  Generated from pipelines/1068515030 branch based on master. Ginkgo version 1.7.0
A numerical linear algebra library targeting many-core architectures
papi.hpp
1 /*******************************<GINKGO LICENSE>******************************
2 Copyright (c) 2017-2023, the Ginkgo authors
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15 
16 3. Neither the name of the copyright holder nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 ******************************<GINKGO LICENSE>*******************************/
32 
33 #ifndef GKO_PUBLIC_CORE_LOG_PAPI_HPP_
34 #define GKO_PUBLIC_CORE_LOG_PAPI_HPP_
35 
36 
37 #include <ginkgo/config.hpp>
38 
39 
40 #if GKO_HAVE_PAPI_SDE
41 
42 
43 #include <cstddef>
44 #include <iostream>
45 #include <map>
46 #include <mutex>
47 #include <sde_lib.h>
48 
49 
50 #include <ginkgo/core/base/polymorphic_object.hpp>
51 #include <ginkgo/core/log/logger.hpp>
52 
53 
54 namespace gko {
55 namespace log {
56 
57 
58 static size_type papi_logger_count = 0;
59 static std::mutex papi_count_mutex;
60 
61 
86 template <typename ValueType = default_precision>
87 class Papi : public Logger {
88 public:
89  /* Executor events */
90  void on_allocation_started(const Executor* exec,
91  const size_type& num_bytes) const override;
92 
93  void on_allocation_completed(const Executor* exec,
94  const size_type& num_bytes,
95  const uintptr& location) const override;
96 
97  void on_free_started(const Executor* exec,
98  const uintptr& location) const override;
99 
100  void on_free_completed(const Executor* exec,
101  const uintptr& location) const override;
102 
103  void on_copy_started(const Executor* from, const Executor* to,
104  const uintptr& location_from,
105  const uintptr& location_to,
106  const size_type& num_bytes) const override;
107 
108  void on_copy_completed(const Executor* from, const Executor* to,
109  const uintptr& location_from,
110  const uintptr& location_to,
111  const size_type& num_bytes) const override;
112 
113  /* Operation events */
114  void on_operation_launched(const Executor* exec,
115  const Operation* operation) const override;
116 
117  void on_operation_completed(const Executor* exec,
118  const Operation* operation) const override;
119 
120  /* PolymorphicObject events */
122  const Executor*, const PolymorphicObject* po) const override;
123 
125  const Executor* exec, const PolymorphicObject* input,
126  const PolymorphicObject* output) const override;
127 
129  const Executor* exec, const PolymorphicObject* from,
130  const PolymorphicObject* to) const override;
131 
133  const Executor* exec, const PolymorphicObject* from,
134  const PolymorphicObject* to) const override;
135 
137  const Executor* exec, const PolymorphicObject* from,
138  const PolymorphicObject* to) const override;
139 
141  const Executor* exec, const PolymorphicObject* from,
142  const PolymorphicObject* to) const override;
143 
145  const Executor* exec, const PolymorphicObject* po) const override;
146 
147  /* LinOp events */
148  void on_linop_apply_started(const LinOp* A, const LinOp* b,
149  const LinOp* x) const override;
150 
151  void on_linop_apply_completed(const LinOp* A, const LinOp* b,
152  const LinOp* x) const override;
153 
154  void on_linop_advanced_apply_started(const LinOp* A, const LinOp* alpha,
155  const LinOp* b, const LinOp* beta,
156  const LinOp* x) const override;
157 
158  void on_linop_advanced_apply_completed(const LinOp* A, const LinOp* alpha,
159  const LinOp* b, const LinOp* beta,
160  const LinOp* x) const override;
161 
162  /* LinOpFactory events */
164  const LinOp* input) const override;
165 
167  const LinOpFactory* factory, const LinOp* input,
168  const LinOp* output) const override;
169 
171  const stop::Criterion* criterion, const size_type& num_iterations,
172  const LinOp* residual, const LinOp* residual_norm,
173  const LinOp* solution, const uint8& stopping_id,
174  const bool& set_finalized, const array<stopping_status>* status,
175  const bool& one_changed, const bool& all_converged) const override;
176 
177  /* Internal solver events */
178  void on_iteration_complete(const LinOp* solver, const LinOp* b,
179  const LinOp* x, const size_type& num_iterations,
180  const LinOp* residual,
181  const LinOp* residual_norm,
182  const LinOp* implicit_resnorm_sq,
183  const array<stopping_status>* status,
184  bool stopped) const override;
185 
186  GKO_DEPRECATED(
187  "Please use the version with the additional stopping "
188  "information.")
189  void on_iteration_complete(const LinOp* solver,
190  const size_type& num_iterations,
191  const LinOp* residual, const LinOp* solution,
192  const LinOp* residual_norm) const override;
193 
194  GKO_DEPRECATED(
195  "Please use the version with the additional stopping "
196  "information.")
198  const LinOp* solver, const size_type& num_iterations,
199  const LinOp* residual, const LinOp* solution,
200  const LinOp* residual_norm,
201  const LinOp* implicit_sq_residual_norm) const override;
202 
208  GKO_DEPRECATED("use single-parameter create")
209  static std::shared_ptr<Papi> create(
210  std::shared_ptr<const gko::Executor>,
211  const Logger::mask_type& enabled_events = Logger::all_events_mask)
212  {
213  return Papi::create(enabled_events);
214  }
215 
221  static std::shared_ptr<Papi> create(
222  const Logger::mask_type& enabled_events = Logger::all_events_mask)
223  {
224  return std::shared_ptr<Papi>(new Papi(enabled_events), [](auto logger) {
225  auto handle = logger->get_handle();
226  delete logger;
227  papi_sde_shutdown(handle);
228  });
229  }
230 
237  const std::string get_handle_name() const { return name; }
238 
244  const papi_handle_t get_handle() const { return papi_handle; }
245 
246 protected:
247  GKO_DEPRECATED("use single-parameter constructor")
248  explicit Papi(
249  std::shared_ptr<const gko::Executor> exec,
250  const Logger::mask_type& enabled_events = Logger::all_events_mask)
251  : Papi(enabled_events)
252  {}
253 
254  explicit Papi(
255  const Logger::mask_type& enabled_events = Logger::all_events_mask)
256  : Logger(enabled_events)
257  {
258  std::ostringstream os;
259 
260  std::lock_guard<std::mutex> guard(papi_count_mutex);
261  os << "ginkgo" << papi_logger_count;
262  name = os.str();
263  papi_handle = papi_sde_init(name.c_str());
264  papi_logger_count++;
265  }
266 
267 private:
268  template <typename PointerType>
269  class papi_queue {
270  public:
271  papi_queue(papi_handle_t* handle, const char* counter_name)
272  : handle{handle}, counter_name{counter_name}
273  {}
274 
275  ~papi_queue()
276  {
277  for (auto e : data) {
278  std::ostringstream oss;
279  oss << counter_name << "::" << e.first;
280  papi_sde_unregister_counter(*handle, oss.str().c_str());
281  }
282  data.clear();
283  }
284 
285  size_type& get_counter(const PointerType* ptr)
286  {
287  const auto tmp = reinterpret_cast<uintptr>(ptr);
288  if (data.find(tmp) == data.end()) {
289  data[tmp] = 0;
290  }
291  auto& value = data[tmp];
292  if (!value) {
293  std::ostringstream oss;
294  oss << counter_name << "::" << tmp;
295  papi_sde_register_counter(*handle, oss.str().c_str(),
296  PAPI_SDE_RO | PAPI_SDE_INSTANT,
297  PAPI_SDE_long_long, &value);
298  }
299  return data[tmp];
300  }
301 
302  private:
303  papi_handle_t* handle;
304  const char* counter_name;
305  std::map<std::uintptr_t, size_type> data;
306  };
307 
308 
309  mutable papi_queue<Executor> allocation_started{&papi_handle,
310  "allocation_started"};
311  mutable papi_queue<Executor> allocation_completed{&papi_handle,
312  "allocation_completed"};
313  mutable papi_queue<Executor> free_started{&papi_handle, "free_started"};
314  mutable papi_queue<Executor> free_completed{&papi_handle, "free_completed"};
315  mutable papi_queue<Executor> copy_started_from{&papi_handle,
316  "copy_started_from"};
317  mutable papi_queue<Executor> copy_started_to{&papi_handle,
318  "copy_started_to"};
319  mutable papi_queue<Executor> copy_completed_from{&papi_handle,
320  "copy_completed_from"};
321  mutable papi_queue<Executor> copy_completed_to{&papi_handle,
322  "copy_completed_to"};
323 
324  mutable papi_queue<Executor> operation_launched{&papi_handle,
325  "operation_launched"};
326  mutable papi_queue<Executor> operation_completed{&papi_handle,
327  "operation_completed"};
328 
329  mutable papi_queue<Executor> polymorphic_object_create_started{
330  &papi_handle, "polymorphic_object_create_started"};
331  mutable papi_queue<Executor> polymorphic_object_create_completed{
332  &papi_handle, "polymorphic_object_create_completed"};
333  mutable papi_queue<Executor> polymorphic_object_copy_started{
334  &papi_handle, "polymorphic_object_copy_started"};
335  mutable papi_queue<Executor> polymorphic_object_copy_completed{
336  &papi_handle, "polymorphic_object_copy_completed"};
337  mutable papi_queue<Executor> polymorphic_object_move_started{
338  &papi_handle, "polymorphic_object_move_started"};
339  mutable papi_queue<Executor> polymorphic_object_move_completed{
340  &papi_handle, "polymorphic_object_move_completed"};
341  mutable papi_queue<Executor> polymorphic_object_deleted{
342  &papi_handle, "polymorphic_object_deleted"};
343 
344  mutable papi_queue<LinOpFactory> linop_factory_generate_started{
345  &papi_handle, "linop_factory_generate_started"};
346  mutable papi_queue<LinOpFactory> linop_factory_generate_completed{
347  &papi_handle, "linop_factory_generate_completed"};
348 
349  mutable papi_queue<LinOp> linop_apply_started{&papi_handle,
350  "linop_apply_started"};
351  mutable papi_queue<LinOp> linop_apply_completed{&papi_handle,
352  "linop_apply_completed"};
353  mutable papi_queue<LinOp> linop_advanced_apply_started{
354  &papi_handle, "linop_advanced_apply_started"};
355  mutable papi_queue<LinOp> linop_advanced_apply_completed{
356  &papi_handle, "linop_advanced_apply_completed"};
357 
358  mutable std::map<std::uintptr_t, void*> criterion_check_completed;
359 
360  mutable papi_queue<LinOp> iteration_complete{&papi_handle,
361  "iteration_complete"};
362 
363 
364  std::string name{"ginkgo"};
365  papi_handle_t papi_handle;
366 };
367 
368 
369 } // namespace log
370 } // namespace gko
371 
372 
373 #endif // GKO_HAVE_PAPI_SDE
374 #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:149
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:146
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:72
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:172
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:120
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:209
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:48
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:237
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:221
gko::array
An array is a container which encapsulates fixed-sized arrays, stored on the Executor tied to the arr...
Definition: array.hpp:55
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:117
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:244
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:104
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:87
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:64
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:644
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:413
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:287
gko::log::Papi::on_free_completed
void on_free_completed(const Executor *exec, const uintptr &location) const override
Executor's free completed event.