alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
FrameSpec.hpp
Go to the documentation of this file.
1/* Copyright 2024 René Widera
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
7#include "alpaka/Vec.hpp"
9#include "alpaka/concepts.hpp"
12
13#include <cstdint>
14#include <ostream>
15
16namespace alpaka::onHost
17{
18 /** @brief Device/Api-agnostic description of the logical parallelism exposed to a kernel.
19 *
20 * A frame specification describes how a multidimensional index range [0; K) is divided into fixed-size chunks,
21 * called frames (NF), each with a frame extent (FE), where `K = NF * FE`.
22 * K does not need to match the problem size (P), e.g., the number of elements in a buffer you want to process in a
23 * kernel. Often, the best performance of a kernel can be achieved if `K <= P`, and if the
24 * kernel uses SIMD operations, `K <= P/(SIMD width)`.
25 * alpaka derives the onHost::ThreadSpec to launch the kernel, based on a heuristic and additional launch
26 * information from the `FrameSpec`. Therefore a kernel enqueued with a frame specification should always be
27 * written to be executable with any onHost::ThreadSpec and should not depend on hard-coded thread numbers, to
28 * ensure portability between devices.
29 *
30 * A `FrameSpec` is therefore not equivalent to a CUDA-style grid description. It specifies only the maximum
31 * parallelism made available to the kernel. It does not guarantee the number of physical thread blocks, nor the
32 * number of physical threads per block used by the backend. If exact control over blocks and threads is required,
33 * use onHost::ThreadSpec.
34 *
35 * @tparam T_NumFrames The n-dimensional number of frames.
36 * @tparam T_FrameExtents The n-dimensional size of one logical frame.
37 * @tparam T_Executor The executor used to translate the onHost::ThreadSpec into a thread block hierarchy.
38 * If the executor is exec::AnyExecutor alpaka will select a good fitting executor for the action where the
39 * ThreadSpec is used.
40 */
41 template<
42 alpaka::concepts::Vector T_NumFrames,
43 alpaka::concepts::Vector<typename T_NumFrames::type, T_NumFrames::dim()> T_FrameExtents,
44 alpaka::concepts::Executor T_Executor = alpaka::exec::AnyExecutor>
45 struct FrameSpec
46 {
47 using index_type = typename T_NumFrames::type;
48
49 using NumFramesVecType = T_NumFrames;
50 using FrameExtentsVecType = T_FrameExtents;
51
52 private:
55
56 public:
57 constexpr FrameSpec(
58 T_NumFrames const& numFrames,
59 T_FrameExtents const& frameExtent,
60 T_Executor executor = T_Executor{})
61 : m_numFrames(numFrames)
62 , m_frameExtents(frameExtent)
63 {
64 alpaka::unused(executor);
65 }
66
67 [[nodiscard]] static constexpr T_Executor getExecutor() noexcept
68 {
69 return T_Executor{};
70 }
71
72 [[nodiscard]] constexpr NumFramesVecType const& getNumFrames() const noexcept
73 {
74 return m_numFrames;
75 }
76
77 [[nodiscard]] constexpr FrameExtentsVecType const& getFrameExtents() const noexcept
78 {
79 return m_frameExtents;
80 }
81
82 [[nodiscard]] static consteval uint32_t dim()
83 {
84 return T_FrameExtents::dim();
85 }
86 };
87
88 template<alpaka::concepts::VectorOrScalar T_NumFrames, alpaka::concepts::VectorOrScalar T_FrameExtents>
89 FrameSpec(T_NumFrames const&, T_FrameExtents const&) -> FrameSpec<
93
94 template<
98 FrameSpec(T_NumFrames const&, T_FrameExtents const&, T_Executor)
100
101 namespace trait
102 {
103 template<typename T>
104 struct IsFrameSpec : std::false_type
105 {
106 };
107
108 template<
109 alpaka::concepts::Vector T_NumFrames,
110 alpaka::concepts::Vector T_FrameExtents,
112 struct IsFrameSpec<onHost::FrameSpec<T_NumFrames, T_FrameExtents, T_Executor>> : std::true_type
113 {
114 };
115 } // namespace trait
116
117 template<typename T>
119
120 namespace concepts
121 {
122 /** Concept to check if a type is a FrameSpec
123 *
124 * @tparam T Type to check
125 * @tparam T_IndexType enforce a index type of the frame specification, if not provided the type is not checked
126 * @tparam T_dim enforce a dimensionality of the frame specification, if not provided the value is not
127 * checked
128 */
129 template<typename T, typename T_IndexType = alpaka::NotRequired, uint32_t T_dim = alpaka::notRequiredDim>
130 concept FrameSpec
132 && (std::same_as<T_IndexType, alpaka::NotRequired> || std::same_as<typename T::index_type, T_IndexType>)
133 && ((T_dim == alpaka::notRequiredDim) || (T::dim() == T_dim));
134
135 /** Concept to check if a type is a ThreadSpec or a FrameSpec
136 *
137 * @tparam T Type to check
138 */
139 template<typename T>
141 } // namespace concepts
142
143 std::ostream& operator<<(std::ostream& s, concepts::FrameSpec auto const& d)
144 {
145 return s << "FrameSpec{ frames=" << d.getNumFrames() << ", frameExtent=" << d.getFrameExtents() << " }";
146 }
147
148} // namespace alpaka::onHost
Concept to check for an executor.
Definition trait.hpp:133
Concept to check if a type is a vector or scalar variable.
Definition Vec.hpp:65
Concept to check if a type is a vector.
Definition Vec.hpp:54
Concept to check if a type is a FrameSpec.
Concept to check if a type is a ThreadSpec or a FrameSpec.
Functionality which is usable on the host CPU controller thread.
Definition api.hpp:40
std::ostream & operator<<(std::ostream &s, DeviceProperties const &p)
FrameSpec(T_NumFrames const &, T_FrameExtents const &) -> FrameSpec< alpaka::trait::getVec_t< T_NumFrames >, alpaka::trait::getVec_t< T_FrameExtents >, alpaka::exec::AnyExecutor >
constexpr bool isThreadSpec_v
constexpr bool isFrameSpec_v
typename GetVec< T >::type getVec_t
Definition Vec.hpp:948
constexpr uint32_t notRequiredDim
Definition trait.hpp:23
Automatic executor selection.
Definition executor.hpp:25
Device/Api-agnostic description of the logical parallelism exposed to a kernel.
Definition FrameSpec.hpp:46
constexpr FrameExtentsVecType const & getFrameExtents() const noexcept
Definition FrameSpec.hpp:77
static consteval uint32_t dim()
Definition FrameSpec.hpp:82
static constexpr T_Executor getExecutor() noexcept
Definition FrameSpec.hpp:67
constexpr FrameSpec(T_NumFrames const &numFrames, T_FrameExtents const &frameExtent, T_Executor executor=T_Executor{})
Definition FrameSpec.hpp:57
constexpr NumFramesVecType const & getNumFrames() const noexcept
Definition FrameSpec.hpp:72