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.h_view.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 && (idx < static_cast<int>(m_reports.d_view.extent(0)))) {
73  m_reporters.d_view(idx) = reporter_id;
74  m_reports.d_view(idx) = report;
75  return true;
76  } else {
77  return false;
78  }
79  }
80 
81  private:
82  using reports_view_t = Kokkos::View<report_type *, device_type>;
83  using reports_dualview_t = Kokkos::DualView<report_type *, device_type>;
84 
85  using host_mirror_space = typename reports_dualview_t::host_mirror_space;
86  Kokkos::View<int, device_type> m_numReportsAttempted;
87  reports_dualview_t m_reports;
88  Kokkos::DualView<int *, device_type> m_reporters;
89 };
90 
91 template <typename ReportType, typename DeviceType>
92 inline int ErrorReporter<ReportType, DeviceType>::getNumReports() {
93  int num_reports = 0;
94  Kokkos::deep_copy(num_reports, m_numReportsAttempted);
95  if (num_reports > static_cast<int>(m_reports.h_view.extent(0))) {
96  num_reports = m_reports.h_view.extent(0);
97  }
98  return num_reports;
99 }
100 
101 template <typename ReportType, typename DeviceType>
102 inline int ErrorReporter<ReportType, DeviceType>::getNumReportAttempts() {
103  int num_reports = 0;
104  Kokkos::deep_copy(num_reports, m_numReportsAttempted);
105  return num_reports;
106 }
107 
108 template <typename ReportType, typename DeviceType>
109 void ErrorReporter<ReportType, DeviceType>::getReports(
110  std::vector<int> &reporters_out, std::vector<report_type> &reports_out) {
111  int num_reports = getNumReports();
112  reporters_out.clear();
113  reporters_out.reserve(num_reports);
114  reports_out.clear();
115  reports_out.reserve(num_reports);
116 
117  if (num_reports > 0) {
118  m_reports.template sync<host_mirror_space>();
119  m_reporters.template sync<host_mirror_space>();
120 
121  for (int i = 0; i < num_reports; ++i) {
122  reporters_out.push_back(m_reporters.h_view(i));
123  reports_out.push_back(m_reports.h_view(i));
124  }
125  }
126 }
127 
128 template <typename ReportType, typename DeviceType>
129 void ErrorReporter<ReportType, DeviceType>::getReports(
130  typename Kokkos::View<
131  int *, typename DeviceType::execution_space>::HostMirror &reporters_out,
132  typename Kokkos::View<report_type *,
133  typename DeviceType::execution_space>::HostMirror
134  &reports_out) {
135  int num_reports = getNumReports();
136  reporters_out = typename Kokkos::View<int *, DeviceType>::HostMirror(
137  "ErrorReport::reporters_out", num_reports);
138  reports_out = typename Kokkos::View<report_type *, DeviceType>::HostMirror(
139  "ErrorReport::reports_out", num_reports);
140 
141  if (num_reports > 0) {
142  m_reports.template sync<host_mirror_space>();
143  m_reporters.template sync<host_mirror_space>();
144 
145  for (int i = 0; i < num_reports; ++i) {
146  reporters_out(i) = m_reporters.h_view(i);
147  reports_out(i) = m_reports.h_view(i);
148  }
149  }
150 }
151 
152 template <typename ReportType, typename DeviceType>
153 void ErrorReporter<ReportType, DeviceType>::clear() {
154  int num_reports = 0;
155  Kokkos::deep_copy(m_numReportsAttempted, num_reports);
156  m_reports.template modify<execution_space>();
157  m_reporters.template modify<execution_space>();
158 }
159 
160 template <typename ReportType, typename DeviceType>
161 void ErrorReporter<ReportType, DeviceType>::resize(const size_t new_size) {
162  m_reports.resize(new_size);
163  m_reporters.resize(new_size);
164  typename DeviceType::execution_space().fence(
165  "Kokkos::Experimental::ErrorReporter::resize: fence after resizing");
166 }
167 
168 } // namespace Experimental
169 } // namespace Kokkos
170 
171 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ERRORREPORTER
172 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
173 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_ERRORREPORTER
174 #endif
175 #endif
Declaration and definition of Kokkos::DualView.