Ginkgo  Generated from tags/v1.0.0^0 branch based on master. Ginkgo version 1.0.0
A numerical linear algebra library targeting many-core architectures
papi.hpp
1 /*******************************<GINKGO LICENSE>******************************
2 Copyright (c) 2017-2019, 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_CORE_LOG_PAPI_HPP_
34 #define GKO_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 
48 
49 #include <ginkgo/core/base/polymorphic_object.hpp>
50 #include <ginkgo/core/log/logger.hpp>
51 #include "third_party/papi_sde/papi_sde_interface.h"
52 
53 
54 #include <papi.h>
55 
56 
57 namespace gko {
58 namespace log {
59 
60 
85 template <typename ValueType = default_precision>
86 class Papi : public Logger {
87 public:
88  /* Executor events */
89  void on_allocation_started(const Executor *exec,
90  const size_type &num_bytes) const override;
91 
92  void on_allocation_completed(const Executor *exec,
93  const size_type &num_bytes,
94  const uintptr &location) const override;
95 
96  void on_free_started(const Executor *exec,
97  const uintptr &location) const override;
98 
99  void on_free_completed(const Executor *exec,
100  const uintptr &location) const override;
101 
102  void on_copy_started(const Executor *from, const Executor *to,
103  const uintptr &location_from,
104  const uintptr &location_to,
105  const size_type &num_bytes) const override;
106 
107  void on_copy_completed(const Executor *from, const Executor *to,
108  const uintptr &location_from,
109  const uintptr &location_to,
110  const size_type &num_bytes) const override;
111 
112  /* Operation events */
113  void on_operation_launched(const Executor *exec,
114  const Operation *operation) const override;
115 
116  void on_operation_completed(const Executor *exec,
117  const Operation *operation) const override;
118 
119  /* PolymorphicObject events */
120  void on_polymorphic_object_create_started(
121  const Executor *, const PolymorphicObject *po) const override;
122 
123  void on_polymorphic_object_create_completed(
124  const Executor *exec, const PolymorphicObject *input,
125  const PolymorphicObject *output) const override;
126 
127  void on_polymorphic_object_copy_started(
128  const Executor *exec, const PolymorphicObject *from,
129  const PolymorphicObject *to) const override;
130 
131  void on_polymorphic_object_copy_completed(
132  const Executor *exec, const PolymorphicObject *from,
133  const PolymorphicObject *to) const override;
134 
135  void on_polymorphic_object_deleted(
136  const Executor *exec, const PolymorphicObject *po) const override;
137 
138  /* LinOp events */
139  void on_linop_apply_started(const LinOp *A, const LinOp *b,
140  const LinOp *x) const override;
141 
142  void on_linop_apply_completed(const LinOp *A, const LinOp *b,
143  const LinOp *x) const override;
144 
145  void on_linop_advanced_apply_started(const LinOp *A, const LinOp *alpha,
146  const LinOp *b, const LinOp *beta,
147  const LinOp *x) const override;
148 
149  void on_linop_advanced_apply_completed(const LinOp *A, const LinOp *alpha,
150  const LinOp *b, const LinOp *beta,
151  const LinOp *x) const override;
152 
153  /* LinOpFactory events */
154  void on_linop_factory_generate_started(const LinOpFactory *factory,
155  const LinOp *input) const override;
156 
157  void on_linop_factory_generate_completed(
158  const LinOpFactory *factory, const LinOp *input,
159  const LinOp *output) const override;
160 
161  void on_criterion_check_completed(
162  const stop::Criterion *criterion, const size_type &num_iterations,
163  const LinOp *residual, const LinOp *residual_norm,
164  const LinOp *solutino, const uint8 &stopping_id,
165  const bool &set_finalized, const Array<stopping_status> *status,
166  const bool &one_changed, const bool &all_converged) const override;
167 
168  /* Internal solver events */
169  void on_iteration_complete(
170  const LinOp *solver, const size_type &num_iterations,
171  const LinOp *residual, const LinOp *solution = nullptr,
172  const LinOp *residual_norm = nullptr) const override;
173 
180  static std::shared_ptr<Papi> create(
181  std::shared_ptr<const gko::Executor> exec,
182  const Logger::mask_type &enabled_events)
183  {
184  return std::shared_ptr<Papi>(new Papi(exec, enabled_events));
185  }
186 
193  const std::string get_handle_name() const { return name; }
194 
195 protected:
196  explicit Papi(
197  std::shared_ptr<const gko::Executor> exec,
198  const Logger::mask_type &enabled_events = Logger::all_events_mask)
199  : Logger(exec, enabled_events)
200  {
201  std::ostringstream os;
202 
203  std::lock_guard<std::mutex> guard(count_mutex);
204  os << "ginkgo" << logger_count;
205  name = os.str();
206  papi_handle = papi_sde_init(name.c_str());
207  logger_count++;
208  }
209 
210 private:
211  template <typename PointerType>
212  class papi_queue {
213  public:
214  papi_queue(papi_handle_t *handle, const char *counter_name)
215  : handle{handle}, counter_name{counter_name}
216  {}
217 
218  ~papi_queue()
219  {
220  if (PAPI_is_initialized()) {
221  for (auto e : data) {
222  std::ostringstream oss;
223  oss << counter_name << "::" << e.first;
224  papi_sde_unregister_counter(*handle, oss.str().c_str());
225  }
226  }
227  data.clear();
228  }
229 
230  size_type &get_counter(const PointerType *ptr)
231  {
232  const auto tmp = reinterpret_cast<uintptr>(ptr);
233  if (data.find(tmp) == data.end()) {
234  data[tmp] = 0;
235  }
236  auto &value = data[tmp];
237  if (!value) {
238  std::ostringstream oss;
239  oss << counter_name << "::" << tmp;
240  papi_sde_register_counter(*handle, oss.str().c_str(),
241  PAPI_SDE_RO | PAPI_SDE_INSTANT,
242  PAPI_SDE_long_long, &value);
243  }
244  return data[tmp];
245  }
246 
247  private:
248  papi_handle_t *handle;
249  const char *counter_name;
250  std::map<std::uintptr_t, size_type> data;
251  };
252 
253 
254  mutable papi_queue<Executor> allocation_started{&papi_handle,
255  "allocation_started"};
256  mutable papi_queue<Executor> allocation_completed{&papi_handle,
257  "allocation_completed"};
258  mutable papi_queue<Executor> free_started{&papi_handle, "free_started"};
259  mutable papi_queue<Executor> free_completed{&papi_handle, "free_completed"};
260  mutable papi_queue<Executor> copy_started_from{&papi_handle,
261  "copy_started_from"};
262  mutable papi_queue<Executor> copy_started_to{&papi_handle,
263  "copy_started_to"};
264  mutable papi_queue<Executor> copy_completed_from{&papi_handle,
265  "copy_completed_from"};
266  mutable papi_queue<Executor> copy_completed_to{&papi_handle,
267  "copy_completed_to"};
268 
269  mutable papi_queue<Executor> operation_launched{&papi_handle,
270  "operation_launched"};
271  mutable papi_queue<Executor> operation_completed{&papi_handle,
272  "operation_completed"};
273 
274  mutable papi_queue<Executor> polymorphic_object_create_started{
275  &papi_handle, "polymorphic_object_create_started"};
276  mutable papi_queue<Executor> polymorphic_object_create_completed{
277  &papi_handle, "polymorphic_object_create_completed"};
278  mutable papi_queue<Executor> polymorphic_object_copy_started{
279  &papi_handle, "polymorphic_object_copy_started"};
280  mutable papi_queue<Executor> polymorphic_object_copy_completed{
281  &papi_handle, "polymorphic_object_copy_completed"};
282  mutable papi_queue<Executor> polymorphic_object_deleted{
283  &papi_handle, "polymorphic_object_deleted"};
284 
285  mutable papi_queue<LinOpFactory> linop_factory_generate_started{
286  &papi_handle, "linop_factory_generate_started"};
287  mutable papi_queue<LinOpFactory> linop_factory_generate_completed{
288  &papi_handle, "linop_factory_generate_completed"};
289 
290  mutable papi_queue<LinOp> linop_apply_started{&papi_handle,
291  "linop_apply_started"};
292  mutable papi_queue<LinOp> linop_apply_completed{&papi_handle,
293  "linop_apply_completed"};
294  mutable papi_queue<LinOp> linop_advanced_apply_started{
295  &papi_handle, "linop_advanced_apply_started"};
296  mutable papi_queue<LinOp> linop_advanced_apply_completed{
297  &papi_handle, "linop_advanced_apply_completed"};
298 
299  mutable std::map<std::uintptr_t, void *> criterion_check_completed;
300 
301  mutable papi_queue<LinOp> iteration_complete{&papi_handle,
302  "iteration_complete"};
303 
304  static size_type logger_count;
305  std::mutex count_mutex;
306 
307  std::string name{"ginkgo"};
308  papi_handle_t papi_handle;
309 };
310 
311 
312 } // namespace log
313 } // namespace gko
314 
315 
316 #endif // GKO_HAVE_PAPI_SDE
317 #endif // GKO_CORE_LOG_OSTREAM_HPP_
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:94
The Ginkgo namespace.
Definition: abstract_factory.hpp:45
std::uint8_t uint8
8-bit unsigned integral type.
Definition: types.hpp:123
static constexpr mask_type all_events_mask
Bitset Mask which activates all events.
Definition: logger.hpp:103