Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Kokkos_ErrorReporter.hpp
1 //@HEADER
2 // ************************************************************************
3 //
4 // Kokkos v. 4.0
5 // Copyright (2022) National Technology & Engineering
6 // Solutions of Sandia, LLC (NTESS).
7 //
8 // Under the terms of Contract DE-NA0003525 with NTESS,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
12 // See https://kokkos.org/LICENSE for license information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //@HEADER
16 
17 #ifndef KOKKOS_EXPERIMENTAL_ERROR_REPORTER_HPP
18 #define KOKKOS_EXPERIMENTAL_ERROR_REPORTER_HPP
19 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
20 #define KOKKOS_IMPL_PUBLIC_INCLUDE
21 #define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ERRORREPORTER
22 #endif
23 
24 #include <vector>
25 #include <Kokkos_Core.hpp>
26 #include <Kokkos_View.hpp>
27 #include <Kokkos_DualView.hpp>
28 
29 namespace Kokkos {
30 namespace Experimental {
31 
32 template <typename ReportType, typename DeviceType>
33 class ErrorReporter {
34  public:
35  using report_type = ReportType;
36  using device_type = DeviceType;
37  using execution_space = typename device_type::execution_space;
38 
39  ErrorReporter(int max_results)
40  : m_numReportsAttempted(""),
41  m_reports("", max_results),
42  m_reporters("", max_results) {
43  clear();
44  }
45 
46  int getCapacity() const { return m_reports.view_host().extent(0); }
47 
48  int getNumReports();
49 
50  int getNumReportAttempts();
51 
52  void getReports(std::vector<int> &reporters_out,
53  std::vector<report_type> &reports_out);
54  void getReports(
55  typename Kokkos::View<int *,
56  typename DeviceType::execution_space>::HostMirror
57  &reporters_out,
58  typename Kokkos::View<report_type *,
59  typename DeviceType::execution_space>::HostMirror
60  &reports_out);
61 
62  void clear();
63 
64  void resize(const size_t new_size);
65 
66  bool full() { return (getNumReportAttempts() >= getCapacity()); }
67 
68  KOKKOS_INLINE_FUNCTION
69  bool add_report(int reporter_id, report_type report) const {
70  int idx = Kokkos::atomic_fetch_add(&m_numReportsAttempted(), 1);
71 
72  if (idx >= 0 &&
73  (idx < static_cast<int>(m_reports.view_device().extent(0)))) {
74  m_reporters.view_device()(idx) = reporter_id;
75  m_reports.view_device()(idx) = report;
76  return true;
77  } else {
78  return false;
79  }
80  }
81 
82  private:
83  using reports_view_t = Kokkos::View<report_type *, device_type>;
84  using reports_dualview_t = Kokkos::DualView<report_type *, device_type>;
85 
86  using host_mirror_space = typename reports_dualview_t::host_mirror_space;
87  Kokkos::View<int, device_type> m_numReportsAttempted;
88  reports_dualview_t m_reports;
89  Kokkos::DualView<int *, device_type> m_reporters;
90 };
91 
92 template <typename ReportType, typename DeviceType>
93 inline int ErrorReporter<ReportType, DeviceType>::getNumReports() {
94  int num_reports = 0;
95  Kokkos::deep_copy(num_reports, m_numReportsAttempted);
96  if (num_reports > static_cast<int>(m_reports.view_host().extent(0))) {
97  num_reports = m_reports.view_host().extent(0);
98  }
99  return num_reports;
100 }
101 
102 template <typename ReportType, typename DeviceType>
103 inline int ErrorReporter<ReportType, DeviceType>::getNumReportAttempts() {
104  int num_reports = 0;
105  Kokkos::deep_copy(num_reports, m_numReportsAttempted);
106  return num_reports;
107 }
108 
109 template <typename ReportType, typename DeviceType>
110 void ErrorReporter<ReportType, DeviceType>::getReports(
111  std::vector<int> &reporters_out, std::vector<report_type> &reports_out) {
112  int num_reports = getNumReports();
113  reporters_out.clear();
114  reporters_out.reserve(num_reports);
115  reports_out.clear();
116  reports_out.reserve(num_reports);
117 
118  if (num_reports > 0) {
119  m_reports.template sync<host_mirror_space>();
120  m_reporters.template sync<host_mirror_space>();
121 
122  for (int i = 0; i < num_reports; ++i) {
123  reporters_out.push_back(m_reporters.view_host()(i));
124  reports_out.push_back(m_reports.view_host()(i));
125  }
126  }
127 }
128 
129 template <typename ReportType, typename DeviceType>
130 void ErrorReporter<ReportType, DeviceType>::getReports(
131  typename Kokkos::View<
132  int *, typename DeviceType::execution_space>::HostMirror &reporters_out,
133  typename Kokkos::View<report_type *,
134  typename DeviceType::execution_space>::HostMirror
135  &reports_out) {
136  int num_reports = getNumReports();
137  reporters_out = typename Kokkos::View<int *, DeviceType>::HostMirror(
138  "ErrorReport::reporters_out", num_reports);
139  reports_out = typename Kokkos::View<report_type *, DeviceType>::HostMirror(
140  "ErrorReport::reports_out", num_reports);
141 
142  if (num_reports > 0) {
143  m_reports.template sync<host_mirror_space>();
144  m_reporters.template sync<host_mirror_space>();
145 
146  for (int i = 0; i < num_reports; ++i) {
147  reporters_out(i) = m_reporters.view_host()(i);
148  reports_out(i) = m_reports.view_host()(i);
149  }
150  }
151 }
152 
153 template <typename ReportType, typename DeviceType>
154 void ErrorReporter<ReportType, DeviceType>::clear() {
155  int num_reports = 0;
156  Kokkos::deep_copy(m_numReportsAttempted, num_reports);
157  m_reports.template modify<execution_space>();
158  m_reporters.template modify<execution_space>();
159 }
160 
161 template <typename ReportType, typename DeviceType>
162 void ErrorReporter<ReportType, DeviceType>::resize(const size_t new_size) {
163  m_reports.resize(new_size);
164  m_reporters.resize(new_size);
165  typename DeviceType::execution_space().fence(
166  "Kokkos::Experimental::ErrorReporter::resize: fence after resizing");
167 }
168 
169 } // namespace Experimental
170 } // namespace Kokkos
171 
172 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ERRORREPORTER
173 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
174 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ERRORREPORTER
175 #endif
176 #endif