alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
scan.hpp
Go to the documentation of this file.
1/* Copyright 2025 Anton Reinhard
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
8#include "alpaka/concepts.hpp"
10
11// TODO: add assertion function for whether a device/api is compatible with a number of buffers
12// (`onHost::isDataAccessible`)
13
14namespace alpaka::onHost
15{
16 /** @brief For a scan of some size, this function returns the necessary buffer size in bytes.
17 *
18 * When multiple scans of the same extents are needed (for example in a loop), this function can be used to only
19 * allocate an intermediate buffer once, removing alloc/free overhead. For unique scan calls, the buffer can be
20 * omitted in the scan call, in which case it will be allocated and freed on the fly.
21 *
22 * @tparam T_Data The type of the data to be scanned.
23 * @param extents The extents of the scan.
24 * @return The size of the buffer to allocate in **number of bytes**.
25 */
26 template<typename T_Data>
28 {
30 }
31
32 /** @brief Perform an inclusive scan on the input data and write the result to the output data.
33 *
34 * @param queue The queue to enqueue to.
35 * @param exec The executor to run with.
36 * @param buffer (optional) The internally used buffer. Use the scanBufferSize() function to check how big the
37 * buffer needs to be. If omitted, it will be allocated and destructed on the fly. If you call this method
38 * repeatedly, it is recommended to reuse the buffer whenever possible, or to provide a buffer allocated with
39 * onHost::allocDeferred() to reduce the overhead of allocating and deallocating the buffer on each call.
40 * @param outputVec The output data. To perform an in-place scan, use the overload with only one data object.
41 * @param inputVec The input data. Can be const.
42 *
43 * @{
44 */
46 auto const& queue,
48 alpaka::concepts::IMdSpan auto& buffer,
49 alpaka::concepts::IMdSpan auto& outputVec,
50 alpaka::concepts::IDataSource auto const& inputVec)
51 {
52 auto devAcc = queue.getDevice();
53 if constexpr(exec == alpaka::exec::anyExecutor)
54 {
56 queue,
57 devAcc,
58 defaultExecutor(devAcc),
59 buffer,
60 outputVec,
61 inputVec);
62 }
63 else
64 internal::scan<internal::INCLUSIVE_SCAN>(queue, devAcc, exec, buffer, outputVec, inputVec);
65 }
66
68 auto const& queue,
70 alpaka::concepts::IMdSpan auto& outputVec,
71 alpaka::concepts::IDataSource auto const& inputVec)
72 {
73 auto devAcc = queue.getDevice();
74 if constexpr(exec == alpaka::exec::anyExecutor)
75 {
76 internal::scan<internal::INCLUSIVE_SCAN>(queue, devAcc, defaultExecutor(devAcc), outputVec, inputVec);
77 }
78 else
79 internal::scan<internal::INCLUSIVE_SCAN>(queue, devAcc, exec, outputVec, inputVec);
80 }
81
82 /** @} */
83
84 /** @brief Perform an inclusive scan on data in-place.
85 *
86 * @param queue The queue to enqueue to.
87 * @param exec The executor to run with.
88 * @param buffer (optional) The internally used buffer. Use the scanBufferSize() function to check how big the
89 * buffer needs to be. If omitted, it will be allocated and destructed on the fly. If you call this method
90 * repeatedly, it is recommended to reuse the buffer whenever possible, or to provide a buffer allocated with
91 * onHost::allocDeferred() to reduce the overhead of allocating and deallocating the buffer on each call.
92 * @param dataVec The vector to scan, will be overwritten with the result.
93 *
94 * @{
95 */
97 auto const& queue,
99 alpaka::concepts::IMdSpan auto& buffer,
100 alpaka::concepts::IMdSpan auto& dataVec)
101 {
102 auto devAcc = queue.getDevice();
103 if constexpr(exec == alpaka::exec::anyExecutor)
104 {
105 internal::scan<internal::INCLUSIVE_SCAN>(queue, devAcc, defaultExecutor(devAcc), buffer, dataVec, dataVec);
106 }
107 else
108 internal::scan<internal::INCLUSIVE_SCAN>(queue, devAcc, exec, buffer, dataVec, dataVec);
109 }
110
112 auto const& queue,
114 alpaka::concepts::IMdSpan auto& dataVec)
115 {
116 auto devAcc = queue.getDevice();
117 if constexpr(exec == alpaka::exec::anyExecutor)
118 {
119 internal::scan<internal::INCLUSIVE_SCAN>(queue, devAcc, defaultExecutor(devAcc), dataVec, dataVec);
120 }
121 else
122 internal::scan<internal::INCLUSIVE_SCAN>(queue, devAcc, exec, dataVec, dataVec);
123 }
124
125 /** @} */
126
127 /** @brief Perform an exclusive scan on the input data and write the result to the output data.
128 *
129 * @param queue The queue to enqueue to.
130 * @param exec The executor to run with.
131 * @param buffer (optional) The internally used buffer. Use the scanBufferSize() function to check how big the
132 * buffer needs to be. If omitted, it will be allocated and destructed on the fly. If you call this method
133 * repeatedly, it is recommended to reuse the buffer whenever possible, or to provide a buffer allocated with
134 * onHost::allocDeferred() to reduce the overhead of allocating and deallocating the buffer on each call.
135 * @param outputVec The output data. To perform an in-place scan, use the overload with only one data object.
136 * @param inputVec The input data. Can be const.
137 *
138 * @{
139 */
141 auto const& queue,
143 alpaka::concepts::IMdSpan auto& buffer,
144 alpaka::concepts::IMdSpan auto& outputVec,
145 alpaka::concepts::IDataSource auto const& inputVec)
146 {
147 auto devAcc = queue.getDevice();
148 if constexpr(exec == alpaka::exec::anyExecutor)
149 {
151 queue,
152 devAcc,
153 defaultExecutor(devAcc),
154 buffer,
155 outputVec,
156 inputVec);
157 }
158 else
159 internal::scan<internal::EXCLUSIVE_SCAN>(queue, devAcc, exec, buffer, outputVec, inputVec);
160 }
161
163 auto const& queue,
165 alpaka::concepts::IMdSpan auto& outputVec,
166 alpaka::concepts::IDataSource auto const& inputVec)
167 {
168 auto devAcc = queue.getDevice();
169 if constexpr(exec == alpaka::exec::anyExecutor)
170 {
171 internal::scan<internal::EXCLUSIVE_SCAN>(queue, devAcc, defaultExecutor(devAcc), outputVec, inputVec);
172 }
173 else
174 internal::scan<internal::EXCLUSIVE_SCAN>(queue, devAcc, exec, outputVec, inputVec);
175 }
176
177 /** @} */
178
179 /** @brief Perform an exclusive scan on data in-place.
180 *
181 * @param queue The queue to enqueue to.
182 * @param exec The executor to run with.
183 * @param buffer (optional) The internally used buffer. Use the scanBufferSize() function to check how big the
184 * buffer needs to be. If omitted, it will be allocated and destructed on the fly. If you call this method
185 * repeatedly, it is recommended to reuse the buffer whenever possible, or to provide a buffer allocated with
186 * onHost::allocDeferred() to reduce the overhead of allocating and deallocating the buffer on each call.
187 * @param dataVec The vector to scan, will be overwritten with the result.
188 *
189 * @{
190 */
192 auto const& queue,
194 alpaka::concepts::IMdSpan auto& buffer,
195 alpaka::concepts::IMdSpan auto& dataVec)
196 {
197 auto devAcc = queue.getDevice();
198 if constexpr(exec == alpaka::exec::anyExecutor)
199 {
200 internal::scan<internal::EXCLUSIVE_SCAN>(queue, devAcc, defaultExecutor(devAcc), buffer, dataVec, dataVec);
201 }
202 else
203 internal::scan<internal::EXCLUSIVE_SCAN>(queue, devAcc, exec, buffer, dataVec, dataVec);
204 }
205
207 auto const& queue,
209 alpaka::concepts::IMdSpan auto& dataVec)
210 {
211 auto devAcc = queue.getDevice();
212 if constexpr(exec == alpaka::exec::anyExecutor)
213 {
214 internal::scan<internal::EXCLUSIVE_SCAN>(queue, devAcc, defaultExecutor(devAcc), dataVec, dataVec);
215 }
216 else
217 internal::scan<internal::EXCLUSIVE_SCAN>(queue, devAcc, exec, dataVec, dataVec);
218 }
219
220 /** @} */
221} // namespace alpaka::onHost
Concept to check for an executor.
Definition trait.hpp:133
Interface concept for objects describing multidimensional memory access.
Definition IMdSpan.hpp:91
Concept to check if a type is a vector or scalar variable.
Definition Vec.hpp:65
constexpr AnyExecutor anyExecutor
Automatic executor selection.
Definition executor.hpp:33
void scan(auto &queue, alpaka::onHost::concepts::Device auto &devAcc, alpaka::concepts::Executor auto &exec, alpaka::concepts::IMdSpan auto &buffer, alpaka::concepts::IMdSpan auto &outputVec, alpaka::concepts::IDataSource auto &inputVec)
Definition scan.hpp:380
auto scanBufferSize(std::integral auto const &extent)
Definition scan.hpp:357
Functionality which is usable on the host CPU controller thread.
Definition api.hpp:40
constexpr auto defaultExecutor(internal::concepts::DeviceHandle auto deviceHandle)
Select a default executor for the given device.
Definition trait.hpp:169
void exclusiveScan(auto const &queue, alpaka::concepts::Executor auto exec, alpaka::concepts::IMdSpan auto &buffer, alpaka::concepts::IMdSpan auto &outputVec, alpaka::concepts::IDataSource auto const &inputVec)
Perform an exclusive scan on the input data and write the result to the output data.
Definition scan.hpp:140
void inclusiveScanInPlace(auto const &queue, alpaka::concepts::Executor auto exec, alpaka::concepts::IMdSpan auto &buffer, alpaka::concepts::IMdSpan auto &dataVec)
Perform an inclusive scan on data in-place.
Definition scan.hpp:96
void exclusiveScanInPlace(auto const &queue, alpaka::concepts::Executor auto exec, alpaka::concepts::IMdSpan auto &buffer, alpaka::concepts::IMdSpan auto &dataVec)
Perform an exclusive scan on data in-place.
Definition scan.hpp:191
auto getScanBufferSize(alpaka::concepts::VectorOrScalar auto const &extents)
For a scan of some size, this function returns the necessary buffer size in bytes.
Definition scan.hpp:27
void inclusiveScan(auto const &queue, alpaka::concepts::Executor auto exec, alpaka::concepts::IMdSpan auto &buffer, alpaka::concepts::IMdSpan auto &outputVec, alpaka::concepts::IDataSource auto const &inputVec)
Perform an inclusive scan on the input data and write the result to the output data.
Definition scan.hpp:45