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.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
91template <typename ReportType, typename DeviceType>
92inline 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
101template <typename ReportType, typename DeviceType>
102inline int ErrorReporter<ReportType, DeviceType>::getNumReportAttempts() {
103 int num_reports = 0;
104 Kokkos::deep_copy(num_reports, m_numReportsAttempted);
105 return num_reports;
106}
107
108template <typename ReportType, typename DeviceType>
109void 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
128template <typename ReportType, typename DeviceType>
129void 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);
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
152template <typename ReportType, typename DeviceType>
153void 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
160template <typename ReportType, typename DeviceType>
161void 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.
View to an array of data.
View< typename traits::non_const_data_type, typename traits::array_layout, Device< DefaultHostExecutionSpace, typename traits::host_mirror_space::memory_space >, typename traits::hooks_policy > HostMirror
Compatible HostMirror view.