alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
CVec.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
10#include <array>
11#include <concepts>
12#include <cstdint>
13#include <functional>
14#include <type_traits>
15#include <utility>
16
17namespace alpaka
18{
19 /** @brief A vector with compile-time known values
20 *
21 * @details
22 * A CVec is guaranteed to be constexpr, because all of its values are stored in the type. A CVec instance
23 * satisfies the alpaka::concept::Vector. Some ways to create common types of vectors are fillCVec() and
24 * iotaCVec().
25 *
26 * @tparam T The type of the vector's stored values
27 * @tparam T_values List of values of type T that the vector stores; the length of the vector is inferred from the
28 * length of this list
29 */
30 template<typename T, T... T_values>
31 using CVec = Vec<T, sizeof...(T_values), detail::CVec<T, T_values...>>;
32
33 namespace detail
34 {
35 template<typename T, T... T_values>
36 [[nodiscard]] constexpr auto integerSequenceToCVec(std::integer_sequence<T, T_values...>)
37 {
38 return alpaka::CVec<T, T_values...>{};
39 }
40
41 template<typename T, T... T_values>
42 [[nodiscard]] constexpr auto toIntegerSequence(alpaka::CVec<T, T_values...>)
43 {
44 return std::integer_sequence<T, T_values...>{};
45 }
46
47 template<typename Int, Int... Is1, Int... Is2>
48 [[nodiscard]] constexpr auto combine(std::integer_sequence<Int, Is1...>, std::integer_sequence<Int, Is2...>)
49 {
50 return std::integer_sequence<Int, Is1..., Is2...>{};
51 }
52
53 template<typename Last>
54 [[nodiscard]] constexpr auto concatenate(Last last)
55 {
56 return last;
57 }
58
59 template<typename First, typename... Rest>
60 [[nodiscard]] constexpr auto concatenate(First first, Rest... rest)
61 {
62 return combine(first, concatenate(rest...));
63 }
64
65 template<bool pred, typename T, T T_v>
66 using selectValue = std::conditional_t<pred, std::integer_sequence<T>, std::integer_sequence<T, T_v>>;
67
68 /** @brief Return all values of an integer sequence for which a filter returns true
69 *
70 * @tparam T_UnaryOp The type of the function or functor to filter with. Must take one argument and return a
71 * boolean.
72 * @tparam T The type of the given values.
73 * @tparam T_values The values to filter.
74 * @param op The filter function/functor.
75 * @param _ An integer sequence of values to filter
76 * @return The filtered integer sequence
77 */
78 template<typename T_UnaryOp, typename T, T... T_values>
79 [[nodiscard]] constexpr auto filterValues(T_UnaryOp const op, std::integer_sequence<T, T_values...> _)
80 {
81 alpaka::unused(_);
82 return concatenate(selectValue<op(T_values), T, T_values>{}...);
83 }
84
85 /** A functor that can check for any of the contained values
86 *
87 * @details
88 * The functor contains the given sequence of values and implements an `operator()(T value)`, which returns
89 * true if the `value` is part of the sequence.
90 *
91 * @tparam T_Seq The sequence to check against
92 */
93 template<typename T_Seq>
94 struct Contains;
95
96 template<typename T, template<typename, T...> typename T_Seq, T... T_values>
97 struct Contains<T_Seq<T, T_values...>>
98 {
99 using argument_type = T;
100
101 constexpr bool operator()(T value) const
102 {
103 return ((value == T_values) || ...);
104 }
105 };
106
107 /* this specialization is required for clang20 but in principle the specialization above should cover it
108 * compile error: CVec.hpp:92:51: error: implicit instantiation of undefined template
109 * 'alpaka::detail::Contains<std::integer_sequence<unsigned int, 0>>' 92 | return
110 * integerSequenceToCVec(filterValues(Contains<ALPAKA_TYPEOF(rightSeq)>{}, toIntegerSequence(left)));
111 */
112 template<typename T, T... T_values>
113 struct Contains<std::integer_sequence<T, T_values...>>
114 {
115 using argument_type = T;
116
117 constexpr bool operator()(T value) const
118 {
119 return ((value == T_values) || ...);
120 }
121 };
122 } // namespace detail
123
124 /** Create and return a CVector of the given length with values 1, 2, ...
125 *
126 * @details
127 * The function is defined consteval, so the result can and should always be constexpr.
128 *
129 * @tparam T Type of the stored values
130 * @tparam T_dim Length of the vector
131 *
132 * @return The vector containing the iota sequence
133 */
134 template<typename T, uint32_t T_dim>
135 [[nodiscard]] consteval auto iotaCVec()
136 {
137 using IotaSeq = std::make_integer_sequence<T, T_dim>;
138 return detail::integerSequenceToCVec(IotaSeq{});
139 }
140
141 /** Create and return a CVector of some length, filled with the given value
142 *
143 * @details
144 * The function is defined consteval, so the result can and should always be constexpr.
145 *
146 * @tparam T Type of the stored values
147 * @tparam T_dim Length of the vector
148 * @tparam T_val Values to fill the vector with
149 *
150 * @return The filled vector
151 */
152 template<typename T, uint32_t T_dim, T T_val>
153 [[nodiscard]] consteval auto fillCVec()
154 {
155 auto concatCVec = []<T... T_values>(CVec<T, T_values...>) -> auto { return CVec<T, T_values..., T_val>{}; };
156
157 static_assert(T_dim > 0);
158 if constexpr(T_dim == 1)
159 return CVec<T, T_val>{};
160 else
161 return concatCVec(fillCVec<T, T_dim - 1, T_val>());
162 }
163
164 /** Filter the left vector with the right vector's values
165 *
166 * @return A CVec that contains all values of the left vector that don't exist in the right vector. Preserves
167 * original order.
168 */
169 [[nodiscard]] constexpr auto filter(concepts::CVector auto left, concepts::CVector auto right)
170 {
171 using namespace detail;
172 constexpr auto rightSeq = toIntegerSequence(right);
173
174 return integerSequenceToCVec(
175 filterValues(detail::Contains<ALPAKA_TYPEOF(rightSeq)>{}, toIntegerSequence(left)));
176 }
177
178} // namespace alpaka
#define ALPAKA_TYPEOF(...)
Get the type of instance.
Definition common.hpp:154
Concept to check if a type is a CVector.
Definition Vec.hpp:75
main alpaka namespace.
Definition alpaka.hpp:76
Vec< T, sizeof...(T_values), detail::CVec< T, T_values... > > CVec
A vector with compile-time known values.
Definition CVec.hpp:31
consteval auto fillCVec()
Create and return a CVector of some length, filled with the given value.
Definition CVec.hpp:153
consteval auto iotaCVec()
Create and return a CVector of the given length with values 1, 2, ...
Definition CVec.hpp:135
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
STL namespace.