Kokkos Core Kernels Package Version of the Day
Loading...
Searching...
No Matches
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
29namespace Kokkos {
30namespace Experimental {
31
32template <typename ReportType, typename DeviceType>
33class 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;
90};
91
92template <typename ReportType, typename DeviceType>
93inline 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
102template <typename ReportType, typename DeviceType>
103inline int ErrorReporter<ReportType, DeviceType>::getNumReportAttempts() {
104 int num_reports = 0;
105 Kokkos::deep_copy(num_reports, m_numReportsAttempted);
106 return num_reports;
107}
108
109template <typename ReportType, typename DeviceType>
110void 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
129template <typename ReportType, typename DeviceType>
130void 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);
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
153template <typename ReportType, typename DeviceType>
154void 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
161template <typename ReportType, typename DeviceType>
162void 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
Declaration and definition of Kokkos::DualView.
A thread safe view to a bitset.