alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
ThreadSpace.hpp
Go to the documentation of this file.
1/* Copyright 2024 Andrea Bocci, René Widera
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
7#include "alpaka/CVec.hpp"
8#include "alpaka/Vec.hpp"
10
11#include <cstdint>
12
13namespace alpaka
14{
15 template<concepts::Vector T_ThreadIdx, concepts::Vector T_ThreadCount>
17 {
18 constexpr ThreadSpace(T_ThreadIdx const& threadIdx, T_ThreadCount const& threadCount)
19 : m_threadIdx(threadIdx)
20 , m_threadCount(threadCount)
21 {
22 }
23
24 std::string toString(std::string const separator = ",", std::string const enclosings = "{}") const
25 {
26 std::string locale_enclosing_begin;
27 std::string locale_enclosing_end;
28 size_t enclosing_dim = enclosings.size();
29
30 if(enclosing_dim > 0)
31 {
32 /* % avoid out of memory access */
33 locale_enclosing_begin = enclosings[0 % enclosing_dim];
34 locale_enclosing_end = enclosings[1 % enclosing_dim];
35 }
36
37 std::stringstream stream;
38 stream << locale_enclosing_begin;
39 stream << m_threadIdx << separator << m_threadCount;
40 stream << locale_enclosing_end;
41 return stream.str();
42 }
43
44 constexpr auto size() const
45 {
46 return m_threadCount;
47 }
48
49 constexpr auto idx() const
50 {
51 return m_threadIdx;
52 }
53
54 template<concepts::CVector T_CSelect>
55 constexpr ThreadSpace mapTo(T_CSelect selection) const requires(T_ThreadIdx::dim() <= T_CSelect::dim())
56 {
57 alpaka::unused(selection);
58 static_assert(T_ThreadIdx::dim() == T_CSelect::dim(), "can not map to a larger dimension");
59 return *this;
60 }
61
62 template<concepts::CVector T_CSelect>
63 constexpr auto mapTo(T_CSelect selection) const requires(T_ThreadIdx::dim() > T_CSelect::dim())
64 {
65 alpaka::unused(selection);
66
67 using IdxType = typename T_ThreadIdx::type;
68 constexpr uint32_t dim = T_ThreadIdx::dim();
69
70 auto allElements = iotaCVec<IdxType, dim>();
71 constexpr auto notSelectedDims = filter(allElements, T_CSelect{});
72
73 // Transform into a universal vector because the input could be a CVec which is read only.
74 auto threadIndex = typename ALPAKA_TYPEOF(m_threadIdx)::UniVec{m_threadIdx};
75 auto numThreads = typename ALPAKA_TYPEOF(m_threadCount)::UniVec{m_threadCount};
76
77 // map not selected dimensions to the slowest selected dimension
78 for(uint32_t x = 0u; x < notSelectedDims.dim(); ++x)
79 {
80 auto d = notSelectedDims[x];
81 auto old = threadIndex[d];
82 threadIndex[d] = 0u;
83 threadIndex[T_CSelect{}[0]] += old * numThreads[T_CSelect{}[0]];
84 }
85
86 for(uint32_t x = 0u; x < notSelectedDims.dim(); ++x)
87 {
88 auto d = notSelectedDims[x];
89 auto old = numThreads[d];
90 numThreads[d] = 1u;
91 numThreads[T_CSelect{}[0]] *= old;
92 }
93
94 return ThreadSpace<ALPAKA_TYPEOF(threadIndex), ALPAKA_TYPEOF(numThreads)>{threadIndex, numThreads};
95 }
96
97 T_ThreadIdx m_threadIdx;
98 T_ThreadCount m_threadCount;
99
100 using type = typename T_ThreadIdx::type;
101 };
102
103 namespace internal
104 {
105 template<typename T_To, typename T_ThreadIdx, typename T_ThreadCount>
106 struct PCast::Op<T_To, ThreadSpace<T_ThreadIdx, T_ThreadCount>>
107 {
108 constexpr auto operator()(auto&& input) const
109 requires std::convertible_to<typename T_ThreadIdx::type, T_To>
110 && (!std::same_as<T_To, typename T_ThreadIdx::type>)
111 {
112 return ThreadSpace{pCast<T_To>(input.m_threadIdx), pCast<T_To>(input.m_threadCount)};
113 }
114
115 constexpr decltype(auto) operator()(auto&& input) const
116 requires std::same_as<T_To, typename T_ThreadIdx::type>
117 {
118 return std::forward<decltype(input)>(input);
119 }
120 };
121 } // namespace internal
122
123 template<std::size_t I, typename T_ThreadIdx, typename T_ThreadCount>
124 constexpr auto get(alpaka::ThreadSpace<T_ThreadIdx, T_ThreadCount> const& v) requires(I == 0u)
125 {
126 return v.m_threadIdx;
127 }
128
129 template<std::size_t I, typename T_ThreadIdx, typename T_ThreadCount>
130 constexpr auto& get(alpaka::ThreadSpace<T_ThreadIdx, T_ThreadCount>& v) requires(I == 0u)
131 {
132 return v.m_threadIdx;
133 }
134
135 template<std::size_t I, typename T_ThreadIdx, typename T_ThreadCount>
136 constexpr auto get(alpaka::ThreadSpace<T_ThreadIdx, T_ThreadCount> const& v) requires(I == 1u)
137 {
138 return v.m_threadCount;
139 }
140
141 template<std::size_t I, typename T_ThreadIdx, typename T_ThreadCount>
142 constexpr auto& get(alpaka::ThreadSpace<T_ThreadIdx, T_ThreadCount>& v) requires(I == 1u)
143 {
144 return v.m_threadCount;
145 }
146
147} // namespace alpaka
148
149namespace std
150{
151 template<typename T_ThreadIdx, typename T_ThreadCount>
152 struct tuple_size<alpaka::ThreadSpace<T_ThreadIdx, T_ThreadCount>>
153 {
154 static constexpr std::size_t value = 2u;
155 };
156
157 template<std::size_t I, typename T_ThreadIdx, typename T_ThreadCount>
158 struct tuple_element<I, alpaka::ThreadSpace<T_ThreadIdx, T_ThreadCount>>
159 {
160 using type = std::conditional_t<I == 0u, T_ThreadIdx, T_ThreadCount>;
161 };
162} // namespace std
#define ALPAKA_TYPEOF(...)
Get the type of instance.
Definition common.hpp:154
alpaka internal implementations.
Definition generic.hpp:19
main alpaka namespace.
Definition alpaka.hpp:76
consteval auto iotaCVec()
Create and return a CVector of the given length with values 1, 2, ...
Definition CVec.hpp:135
constexpr decltype(auto) get(concepts::SpecializationOf< Dict > auto &t) noexcept
Definition Dict.hpp:156
constexpr auto filter(concepts::CVector auto left, concepts::CVector auto right)
Filter the left vector with the right vector's values.
Definition CVec.hpp:169
constexpr decltype(auto) pCast(auto &&input)
Performs a static_cast on the storage type of combined data type.
Definition cast.hpp:48
STL namespace.
constexpr ThreadSpace mapTo(T_CSelect selection) const
typename T_ThreadIdx::type type
constexpr auto size() const
constexpr auto mapTo(T_CSelect selection) const
T_ThreadIdx m_threadIdx
constexpr ThreadSpace(T_ThreadIdx const &threadIdx, T_ThreadCount const &threadCount)
std::string toString(std::string const separator=",", std::string const enclosings="{}") const
constexpr auto idx() const
T_ThreadCount m_threadCount
std::conditional_t< I==0u, T_ThreadIdx, T_ThreadCount > type