VCTR
Loading...
Searching...
No Matches
SIMDHelpers.h
1/*
2 ==============================================================================
3 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
5 Copyright 2022- by sonible GmbH.
6
7 This file is part of VCTR - Versatile Container Templates Reconceptualized.
8
9 VCTR is free software: you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License version 3
11 only, as published by the Free Software Foundation.
12
13 VCTR is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License version 3 for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 version 3 along with VCTR. If not, see <https://www.gnu.org/licenses/>.
20 ==============================================================================
21*/
22
23namespace vctr::detail
24{
25template <size_t value>
26requires (is::powerOfTwoInt<value>)
27constexpr size_t previousMultipleOf (size_t numElements)
28{
29 constexpr auto numMaskBits = std::bit_width (value) - 1;
30 constexpr auto allBitsOne = size_t (-1);
31 constexpr auto mask = allBitsOne << numMaskBits;
32
33 return numElements & mask;
34}
35
36template <size_t value>
37requires (is::powerOfTwoInt<value>)
38constexpr size_t nextMultipleOf (size_t numElements)
39{
40 return size_t ((int64_t (numElements) + int64_t (value) - 1) & -int64_t (value));
41}
42
43template <uintptr_t requiredAlignment = Config::maxSIMDRegisterSize>
44inline constexpr bool isPtrAligned (const void* ptr)
45{
46 // SIMD alignment is not meaningful in case of constant evaluation
47 if (std::is_constant_evaluated())
48 return false;
49
50 return reinterpret_cast<std::uintptr_t> (ptr) % requiredAlignment == 0;
51}
52} // namespace vctr::detail
53
54namespace vctr
55{
56
72template <class StorageType>
74{
75 // The default implementation is empty and should never be used
76};
77
78template <has::sizeAndData StorageType>
79struct StorageInfo<StorageType>
80{
81 constexpr StorageInfo()
82 : dataIsSIMDAligned (false),
83 hasSIMDExtendedStorage (false)
84 {}
85
86 template <is::storageInfo OtherStorageInfoType>
87 constexpr StorageInfo (const OtherStorageInfoType& other)
88 : dataIsSIMDAligned (other.dataIsSIMDAligned),
89 hasSIMDExtendedStorage (other.hasSIMDExtendedStorage)
90 {}
91
92 template <class T>
93 constexpr StorageInfo init (const T* ptr, size_t s)
94 {
95 dataIsSIMDAligned = detail::isPtrAligned (ptr);
96 hasSIMDExtendedStorage = (s * sizeof (T)) % Config::maxSIMDRegisterSize == 0;
97 return *this;
98 }
99
100 static constexpr size_t memberAlignment = alignof (StorageType);
101
102 bool dataIsSIMDAligned;
103
104 bool hasSIMDExtendedStorage;
105};
106
107template <class ElementType, size_t alignmentInBytes>
108struct StorageInfo<std::vector<ElementType, AlignedAllocator<ElementType, alignmentInBytes>>>
109{
110 constexpr StorageInfo init (const void*, size_t) { return *this; }
111
112 static constexpr size_t memberAlignment = alignof (std::vector<ElementType, AlignedAllocator<ElementType, alignmentInBytes>>);
113
114 static constexpr bool dataIsSIMDAligned = alignmentInBytes == Config::maxSIMDRegisterSize;
115
117 static constexpr bool hasSIMDExtendedStorage = true;
118};
119
120template <class ElementType, size_t size>
121struct StorageInfo<std::array<ElementType, size>>
122{
123 constexpr StorageInfo init (const void*, size_t) { return *this; }
124
125 static constexpr size_t memberAlignment = Config::alignedArray ? Config::maxSIMDRegisterSize : alignof (std::array<ElementType, size>);
126
128 static constexpr bool dataIsSIMDAligned = Config::alignedArray;
129
130 static constexpr bool hasSIMDExtendedStorage = (size * sizeof (ElementType)) % Config::maxSIMDRegisterSize == 0;
131};
132
133template <class Allocator>
134struct StorageInfo<detail::VectorBoolWorkaround<Allocator>>
135{
136 constexpr StorageInfo init (const void*, size_t) { return *this; }
137
138 static constexpr size_t memberAlignment = alignof (detail::VectorBoolWorkaround<Allocator>);
139
140 static constexpr bool dataIsSIMDAligned = false;
141
142 static constexpr bool hasSIMDExtendedStorage = false;
143};
144
148template <bool isDataSIMDAligned, bool isStorageSIMDExtended, size_t customMemberAlignment>
150{
151 static constexpr bool dataIsSIMDAligned = isDataSIMDAligned;
152 static constexpr bool hasSIMDExtendedStorage = isStorageSIMDExtended;
153 static constexpr size_t memberAlignment = customMemberAlignment;
154};
155
162template <size_t alignment, class WrappedInfo>
164{
166
167 StorageInfoWithMemberAlignment (const WrappedInfo& i) : WrappedInfo (i) {}
168
169 static constexpr size_t memberAlignment = alignment;
170};
171
172namespace detail
173{
174
175template <bool, bool>
176struct ConstexprStorageInfoChecker
177{
178};
179} // namespace detail
180
181namespace is
182{
183template <class T>
184concept constexprStorageInfo = requires (const T&) { detail::ConstexprStorageInfoChecker<T::dataIsSIMDAligned, T::hasSIMDExtendedStorage>(); };
185}
186
187template <class InfoA, class InfoB>
189{
190 CombinedStorageInfo (const InfoA& a, const InfoB& b)
191 : dataIsSIMDAligned (a.dataIsSIMDAligned && b.dataIsSIMDAligned),
192 hasSIMDExtendedStorage (a.hasSIMDExtendedStorage && b.hasSIMDExtendedStorage)
193 {}
194
195 bool dataIsSIMDAligned;
196
197 bool hasSIMDExtendedStorage;
198};
199
200template <is::constexprStorageInfo InfoA, is::constexprStorageInfo InfoB>
201struct CombinedStorageInfo<InfoA, InfoB>
202{
203 constexpr CombinedStorageInfo (const InfoA&, const InfoB&) {}
204
205 static constexpr bool dataIsSIMDAligned = InfoA::dataIsSIMDAligned && InfoB::dataIsSIMDAligned;
206
207 static constexpr bool hasSIMDExtendedStorage = InfoA::hasSIMDExtendedStorage && InfoB::hasSIMDExtendedStorage;
208};
209
210} // namespace vctr
Definition: SIMDHelpers.h:184
The main namespace of the VCTR project.
Definition: Array.h:24
Definition: SIMDHelpers.h:189
A storage info type especially used to pass compile time constant traits when viewing externally owne...
Definition: SIMDHelpers.h:150
A storage info type especially used for vctr::Span.
Definition: SIMDHelpers.h:164
A helper class to describe some properties regarding the storage class wrapped in a VctrBase instance...
Definition: SIMDHelpers.h:74