alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
StdSimdMask.hpp
Go to the documentation of this file.
1/* Copyright 2026 René Widera
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5/** @file This file provides a basic implementation of a SIMD vector.
6 *
7 * The implementation is based on the class Vec:
8 * - the storge policy should become the native SIMD implementation e.g. std::simd
9 * - load/ store and simd specifis should be implemented in the storage policy
10 * - the name of storage policy should be changed
11 *
12 * The current operator operations relay on compilers auto vectorization.
13 */
14
15#pragma once
16
17#include "alpaka/api/api.hpp"
21#include "alpaka/simd/trait.hpp"
22
23#include <type_traits>
24
25#if ALPAKA_HAS_STD_SIMD
26
27namespace alpaka
28{
29 namespace internal
30 {
31 template<typename T_Type, uint32_t T_width>
32 struct StdSimdMask
33 : protected alpakaStdSimd::
34 rebind_simd_t<T_Type, alpakaStdSimd::simd_mask<T_Type, alpakaStdSimd::simd_abi::fixed_size<T_width>>>
35 {
36 using BaseType = alpakaStdSimd::
37 rebind_simd_t<T_Type, alpakaStdSimd::simd_mask<T_Type, alpakaStdSimd::simd_abi::fixed_size<T_width>>>;
38
39 using value_type = typename BaseType::value_type;
40 using reference = typename BaseType::reference;
41
42 using BaseType::operator[];
43
44 constexpr StdSimdMask() = default;
45 constexpr StdSimdMask(StdSimdMask const&) = default;
46 constexpr StdSimdMask(StdSimdMask&&) = default;
47 constexpr StdSimdMask& operator=(StdSimdMask&& rhs) = default;
48
49 constexpr StdSimdMask& operator=(StdSimdMask const& rhs) = default;
50
51 constexpr StdSimdMask& operator=(T_Type const value)
52 {
53 this->asNativeType() = value;
54 return *this;
55 }
56
57 // constructor is required because exposing the array constructors does not work
58 template<typename... T_Args>
59 requires(sizeof...(T_Args) == T_width && (std::same_as<T_Args, T_Type> && ...))
60 constexpr StdSimdMask(T_Args const&... args) : BaseType{}
61 {
62 std::array<T_Type, T_width> const initArgs{ALPAKA_FORWARD(args)...};
63 for(uint32_t i = 0u; i < T_width; ++i)
64 this->asNativeType()[i] = static_cast<bool>(initArgs[i]);
65 }
66
67 template<typename... T_Args>
68 requires(sizeof...(T_Args) == T_width && (std::same_as<T_Args, bool> && ...))
69 constexpr StdSimdMask(T_Args... args) : BaseType{}
70 {
71 std::array<bool, T_width> const initArgs{args...};
72 for(uint32_t i = 0u; i < T_width; ++i)
73 this->asNativeType()[i] = initArgs[i];
74 }
75
76 constexpr StdSimdMask(BaseType const& nativeSimd) : BaseType{nativeSimd}
77 {
78 }
79
80 /** static cast the instance to the parent std::simd_mask class
81 *
82 * This method is mostly used to get access to native comparison operators.
83 *
84 * @{
85 */
86 constexpr auto& asNativeType()
87 {
88 return static_cast<BaseType&>(*this);
89 }
90
91 constexpr auto const& asNativeType() const
92 {
93 return static_cast<BaseType const&>(*this);
94 }
95
96 /** @} */
97
98 static constexpr auto fill(bool value)
99 {
100 return StdSimdMask{BaseType(value)};
101 }
102
103 constexpr void copyFrom(T_Type const* data, alpaka::concepts::Alignment auto alignment)
104 {
105 if constexpr((alignment.template get<T_Type>() % alpakaStdSimd::memory_alignment_v<BaseType>) == 0u)
106 this->asNativeType().copy_from(data, alpakaStdSimd::vector_aligned);
107 else
108 this->asNativeType().copy_from(data, alpakaStdSimd::element_aligned);
109 }
110
111 constexpr void copyTo(auto* data, alpaka::concepts::Alignment auto alignment) const
112 {
113 if constexpr((alignment.template get<T_Type>() % alpakaStdSimd::memory_alignment_v<BaseType>) == 0u)
114 this->asNativeType().copy_to(data, alpakaStdSimd::vector_aligned);
115 else
116 this->asNativeType().copy_to(data, alpakaStdSimd::element_aligned);
117 }
118
119 /** assign operator
120 */
121# define ALPAKA_VECTOR_ASSIGN_OP(op) \
122 template<typename T_OtherStorage> \
123 constexpr StdSimdMask& operator op(StdSimdMask const& rhs) \
124 { \
125 this->asNativeType() op rhs.asNativeType(); \
126 return *this; \
127 } \
128 constexpr StdSimdMask& operator op(T_Type const value) \
129 { \
130 this->asNativeType() op value; \
131 return *this; \
132 }
133
137
138# undef ALPAKA_VECTOR_ASSIGN_OP
139 };
140
141# define ALPAKA_VECTOR_BINARY_CMP_OP(returnSimdType, argSimdType, typenameOrConcept, op) \
142 template<typenameOrConcept T_Type, uint32_t T_width> \
143 constexpr auto operator op(const argSimdType<T_Type, T_width>& lhs, const argSimdType<T_Type, T_width>& rhs) \
144 { \
145 return returnSimdType<T_Type, T_width>{lhs.asNativeType() op rhs.asNativeType()}; \
146 } \
147 template<typenameOrConcept T_Type, uint32_t T_width> \
148 constexpr auto operator op(const argSimdType<T_Type, T_width>& lhs, T_Type rhs) \
149 { \
150 return returnSimdType<T_Type, T_width>{lhs.asNativeType() op rhs}; \
151 } \
152 template<typenameOrConcept T_Type, uint32_t T_width> \
153 constexpr auto operator op(T_Type lhs, const argSimdType<T_Type, T_width>& rhs) \
154 { \
155 return returnSimdType<T_Type, T_width>{lhs op rhs.asNativeType()}; \
156 }
157
158 ALPAKA_VECTOR_BINARY_CMP_OP(StdSimdMask, StdSimd, typename, >=)
159 ALPAKA_VECTOR_BINARY_CMP_OP(StdSimdMask, StdSimd, typename, >)
160 ALPAKA_VECTOR_BINARY_CMP_OP(StdSimdMask, StdSimd, typename, <=)
161 ALPAKA_VECTOR_BINARY_CMP_OP(StdSimdMask, StdSimd, typename, <)
162 ALPAKA_VECTOR_BINARY_CMP_OP(StdSimdMask, StdSimd, typename, ==)
163 ALPAKA_VECTOR_BINARY_CMP_OP(StdSimdMask, StdSimd, typename, !=)
164
165 ALPAKA_VECTOR_BINARY_CMP_OP(StdSimdMask, StdSimdMask, typename, ==)
166 ALPAKA_VECTOR_BINARY_CMP_OP(StdSimdMask, StdSimdMask, typename, !=)
167 ALPAKA_VECTOR_BINARY_CMP_OP(StdSimdMask, StdSimdMask, typename, &&)
168 ALPAKA_VECTOR_BINARY_CMP_OP(StdSimdMask, StdSimdMask, typename, ||)
169
170# undef ALPAKA_VECTOR_BINARY_CMP_OP
171
172 } // namespace internal
173
174 namespace trait
175 {
176 template<typename T_Type, uint32_t T_width>
177 requires(
178 std::has_single_bit(T_width) && std::has_single_bit(sizeof(T_Type))
179 && alpakaStdSimd::fixed_size_simd_mask<T_Type, T_width>::size() > 0u)
180 struct GetSimdMaskStorageType<alpaka::api::Host, T_Type, T_width>
181 {
182 using type = internal::StdSimdMask<T_Type, T_width>;
183 };
184 } // namespace trait
185} // namespace alpaka
186#endif
#define ALPAKA_VECTOR_BINARY_CMP_OP(typenameOrConcept, op)
binary operators
Definition Simd.hpp:593
#define ALPAKA_VECTOR_ASSIGN_OP(op)
assign operator
Definition Simd.hpp:232
#define ALPAKA_FORWARD(instance)
Perfectly forward an instance as argument.
Definition common.hpp:147
constexpr auto alpaka
Definition fn.hpp:66
main alpaka namespace.
Definition alpaka.hpp:76
Get the storage type for a SIMD mask pack.
internal::EmuSimdMask< T_Type, T_width > type