Vc  1.4.1
SIMD Vector Classes for C++
types.h
1 /* This file is part of the Vc library. {{{
2 Copyright © 2012-2015 Matthias Kretz <kretz@kde.org>
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6  * Redistributions of source code must retain the above copyright
7  notice, this list of conditions and the following disclaimer.
8  * Redistributions in binary form must reproduce the above copyright
9  notice, this list of conditions and the following disclaimer in the
10  documentation and/or other materials provided with the distribution.
11  * Neither the names of contributing organizations nor the
12  names of its contributors may be used to endorse or promote products
13  derived from this software without specific prior written permission.
14 
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
19 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 }}}*/
27 
28 #ifndef VC_COMMON_TYPES_H_
29 #define VC_COMMON_TYPES_H_
30 
31 #ifdef Vc_CHECK_ALIGNMENT
32 #include <cstdlib>
33 #include <cstdio>
34 #endif
35 
36 #include <ratio>
37 #include "../global.h"
38 #include "../traits/type_traits.h"
39 #include "permutation.h"
40 
41 namespace Vc_VERSIONED_NAMESPACE
42 {
45 
47 using std::size_t;
48 
50 using llong = long long;
52 using ullong = unsigned long long;
54 using ulong = unsigned long;
56 using uint = unsigned int;
58 using ushort = unsigned short;
60 using uchar = unsigned char;
62 using schar = signed char;
63 
67 struct VectorSpecialInitializerZero {};
71 struct VectorSpecialInitializerOne {};
75 struct VectorSpecialInitializerIndexesFromZero {};
76 
81 constexpr VectorSpecialInitializerZero Zero = {};
86 constexpr VectorSpecialInitializerOne One = {};
91 constexpr VectorSpecialInitializerIndexesFromZero IndexesFromZero = {};
93 
94 namespace Detail
95 {
96 template<typename T> struct MayAliasImpl {
97 #ifdef __GNUC__
98 #pragma GCC diagnostic push
99 #pragma GCC diagnostic ignored "-Wattributes"
100 #endif
101  typedef T type Vc_MAY_ALIAS;
102 #ifdef __GNUC__
103 #pragma GCC diagnostic pop
104 #endif
105 };
106 //template<size_t Bytes> struct MayAlias<MaskBool<Bytes>> { typedef MaskBool<Bytes> type; };
107 } // namespace Detail
114 #ifdef Vc_ICC
115 template <typename T> using MayAlias [[gnu::may_alias]] = T;
116 #else
117 template <typename T> using MayAlias = typename Detail::MayAliasImpl<T>::type;
118 #endif
119 
120 template <class To, class From> MayAlias<To> &aliasing_cast(From &x)
121 {
122  return *reinterpret_cast<MayAlias<To> *>(&x);
123 }
124 template <class To, class From> const MayAlias<To> &aliasing_cast(const From &x)
125 {
126  return *reinterpret_cast<const MayAlias<To> *>(&x);
127 }
128 
129 template <class To, class From> MayAlias<To> *aliasing_cast(From *x)
130 {
131  return reinterpret_cast<MayAlias<To> *>(x);
132 }
133 template <class To, class From> const MayAlias<To> *aliasing_cast(const From *x)
134 {
135  return reinterpret_cast<const MayAlias<To> *>(x);
136 }
137 
144 enum class Operator : char {
145  Assign,
146  Multiply,
147  MultiplyAssign,
148  Divide,
149  DivideAssign,
150  Remainder,
151  RemainderAssign,
152  Plus,
153  PlusAssign,
154  Minus,
155  MinusAssign,
156  RightShift,
157  RightShiftAssign,
158  LeftShift,
159  LeftShiftAssign,
160  And,
161  AndAssign,
162  Xor,
163  XorAssign,
164  Or,
165  OrAssign,
166  PreIncrement,
167  PostIncrement,
168  PreDecrement,
169  PostDecrement,
170  LogicalAnd,
171  LogicalOr,
172  Comma,
173  UnaryPlus,
174  UnaryMinus,
175  UnaryNot,
176  UnaryOnesComplement,
177  CompareEqual,
178  CompareNotEqual,
179  CompareLess,
180  CompareGreater,
181  CompareLessEqual,
182  CompareGreaterEqual
183 };
184 
185 // forward declaration for Vc::array in <Vc/array>
186 template <typename T, std::size_t N> struct array;
187 // forward declaration for Vc::span in <Vc/span>
188 namespace Common {
189 template <typename T, std::ptrdiff_t N> class span;
190 }
191 
192 /* TODO: add type for half-float, something along these lines:
193 class half_float
194 {
195  uint16_t data;
196 public:
197  constexpr half_float() : data(0) {}
198  constexpr half_float(const half_float &) = default;
199  constexpr half_float(half_float &&) = default;
200  constexpr half_float &operator=(const half_float &) = default;
201 
202  constexpr explicit half_float(float);
203  constexpr explicit half_float(double);
204  constexpr explicit half_float(int);
205  constexpr explicit half_float(unsigned int);
206 
207  explicit operator float () const;
208  explicit operator double () const;
209  explicit operator int () const;
210  explicit operator unsigned int() const;
211 
212  bool operator==(half_float rhs) const;
213  bool operator!=(half_float rhs) const;
214  bool operator>=(half_float rhs) const;
215  bool operator<=(half_float rhs) const;
216  bool operator> (half_float rhs) const;
217  bool operator< (half_float rhs) const;
218 
219  half_float operator+(half_float rhs) const;
220  half_float operator-(half_float rhs) const;
221  half_float operator*(half_float rhs) const;
222  half_float operator/(half_float rhs) const;
223 };
224 */
225 
226 // TODO: the following doesn't really belong into the toplevel Vc namespace.
227 #ifndef Vc_CHECK_ALIGNMENT
228 template<typename _T> static Vc_ALWAYS_INLINE void assertCorrectAlignment(const _T *){}
229 #else
230 template<typename _T> static Vc_ALWAYS_INLINE void assertCorrectAlignment(const _T *ptr)
231 {
232  const size_t s = alignof(_T);
233  if((reinterpret_cast<size_t>(ptr) & ((s ^ (s & (s - 1))) - 1)) != 0) {
234  fprintf(stderr, "A vector with incorrect alignment has just been created. Look at the stacktrace to find the guilty object.\n");
235  abort();
236  }
237 }
238 #endif
239 
240 namespace Common
241 {
242 // defined in common/simdarrayhelper.h
243 template <typename T, std::size_t Pieces, std::size_t Index> struct Segment;
244 
251 template<size_t StructSize> class SuccessiveEntries
252 {
253 #ifdef Vc_MSVC
254  // scatterinterleavedmemory fails with garbage values in m_first if size_type is a
255  // 64-bit integer type. Using a 32-bit type seems to work around the miscompilation.
256  using size_type = unsigned;
257 #else
258  using size_type = size_t;
259 #endif
260  const size_type m_first;
261 
262 public:
263  typedef SuccessiveEntries AsArg;
264  Vc_INTRINSIC SuccessiveEntries(size_type first) : m_first(first) {}
265  Vc_INTRINSIC Vc_PURE size_type operator[](size_type offset) const
266  {
267  return m_first + offset * StructSize;
268  }
269  Vc_INTRINSIC Vc_PURE size_type data() const { return m_first; }
270  Vc_INTRINSIC Vc_PURE SuccessiveEntries operator+(const SuccessiveEntries &rhs) const
271  {
272  return SuccessiveEntries(m_first + rhs.m_first);
273  }
274  Vc_INTRINSIC Vc_PURE SuccessiveEntries operator*(const SuccessiveEntries &rhs) const
275  {
276  return SuccessiveEntries(m_first * rhs.m_first);
277  }
278  Vc_INTRINSIC Vc_PURE SuccessiveEntries operator<<(size_type x) const
279  {
280  return {m_first << x};
281  }
282 
283  friend Vc_INTRINSIC SuccessiveEntries &internal_data(SuccessiveEntries &x)
284  {
285  return x;
286  }
287  friend Vc_INTRINSIC const SuccessiveEntries &internal_data(const SuccessiveEntries &x)
288  {
289  return x;
290  }
291 };
292 
293 // declaration for functions in common/malloc.h
294 template <std::size_t alignment>
295 Vc_INTRINSIC_L void *aligned_malloc(std::size_t n) Vc_INTRINSIC_R;
296 Vc_ALWAYS_INLINE_L void free(void *p) Vc_ALWAYS_INLINE_R;
297 
301 template <typename Mask, typename T, typename U>
302 using enable_if_mask_converts_implicitly =
303  enable_if<(!std::is_same<Mask, Traits::decay<U>>::value && // that'd be the copy ctor
305  Traits::is_implicit_cast_allowed_mask<
306  Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value)>;
310 template <typename T, typename U>
311 using enable_if_mask_converts_explicitly = enable_if<(
314  !Traits::is_implicit_cast_allowed_mask<
315  Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value))>;
316 
320 template <typename T> using WidthT = std::integral_constant<std::size_t, sizeof(T)>;
321 
322 // forward declaration of MaskBool in common/maskbool.h
323 template <std::size_t Bytes> class MaskBool;
324 
325 // forward declaration of SubscriptOperation in common/subscript.h
326 template <typename T, typename IndexVector, typename Scale, bool>
327 class SubscriptOperation;
328 
336 template <class T, class IndexVector, int Scale = 1>
337 struct GatherArguments {
338  static_assert(std::is_same<T, remove_cvref_t<T>>::value && !std::is_pointer<T>::value,
339  "GatherArguments expects an cv unqualified non-ref/ptr type");
340  const IndexVector indexes;
341  const T *const address;
342 };
343 template <int Scale, class T, class I>
344 GatherArguments<T, I, Scale> make_gather(const T *m, const I &i)
345 {
346  return {i, m};
347 }
348 
356 template <typename T, typename IndexVector> struct ScatterArguments
357 {
358  const IndexVector indexes;
359  T *const address;
360 };
361 
365 template <typename I, I Begin, I End, typename F>
366 Vc_INTRINSIC enable_if<(Begin >= End), void> unrolled_loop(F &&)
367 {
368 }
369 
375 template <typename I, I Begin, I End, typename F>
376 Vc_INTRINSIC Vc_FLATTEN enable_if<(Begin < End), void> unrolled_loop(F &&f)
377 {
378  f(Begin);
379  unrolled_loop<I, Begin + 1, End>(f);
380 }
381 
386 template <std::size_t Size, typename F> Vc_INTRINSIC void for_all_vector_entries(F &&f)
387 {
388  unrolled_loop<std::size_t, 0u, Size>(std::forward<F>(f));
389 }
390 
391 } // namespace Common
392 } // namespace Vc
393 
394 #include "vector.h"
395 #include "mask.h"
396 #include "memoryfwd.h"
397 
398 #endif // VC_COMMON_TYPES_H_
399 
400 // vim: foldmethod=marker
signed char schar
signed char shorthand
Definition: types.h:62
void free(T *p)
Frees memory that was allocated with Vc::malloc.
Definition: malloc.h:163
unsigned char uchar
unsigned char shorthand
Definition: types.h:60
unsigned int uint
unsigned int shorthand
Definition: types.h:56
unsigned long long ullong
unsigned long long shorthand
Definition: types.h:52
constexpr VectorSpecialInitializerIndexesFromZero IndexesFromZero
The special object Vc::IndexesFromZero can be used to construct Vector objects initialized to values ...
Definition: types.h:91
std::ostream & operator<<(std::ostream &out, const Vc::Vector< T, Abi > &v)
Prints the contents of a vector into a stream object.
Definition: IO:117
result_vector_type< L, R > operator*(L &&lhs, R &&rhs)
Applies * component-wise and concurrently.
Definition: simdarray.h:1721
Identifies any possible SimdMaskArray<T, N> type (independent of const/volatile or reference) ...
Definition: type_traits.h:143
long long llong
long long shorthand
Definition: types.h:50
result_vector_type< L, R > operator+(L &&lhs, R &&rhs)
Applies + component-wise and concurrently.
Definition: simdarray.h:1721
unsigned long ulong
unsigned long shorthand
Definition: types.h:54
unsigned short ushort
unsigned short shorthand
Definition: types.h:58
constexpr VectorSpecialInitializerZero Zero
The special object Vc::Zero can be used to construct Vector and Mask objects initialized to zero/fals...
Definition: types.h:81
constexpr VectorSpecialInitializerOne One
The special object Vc::One can be used to construct Vector and Mask objects initialized to one/true...
Definition: types.h:86
Identifies any SIMD mask type (independent of implementation or whether it&#39;s SimdMaskArray<T, N>).
Definition: type_traits.h:117
Common::AdaptSubscriptOperator< Common::span< T, Extent > > span
An adapted std::span with additional subscript operators supporting gather and scatter operations...
Definition: span.h:635
This is std::array with additional subscript operators supporting gather and scatter operations...
Definition: array:86