Vc  1.3.3-dev
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 <Vc/global.h>
37 #include "../traits/type_traits.h"
38 #include "permutation.h"
39 #include "vectorabi.h"
40 
41 namespace Vc_VERSIONED_NAMESPACE
42 {
43 template<typename T, typename Abi> class Mask;
44 template<typename T, typename Abi> class Vector;
45 
48 
50 using std::size_t;
51 
53 using llong = long long;
55 using ullong = unsigned long long;
57 using ulong = unsigned long;
59 using uint = unsigned int;
61 using ushort = unsigned short;
63 using uchar = unsigned char;
65 using schar = signed char;
66 
70 struct VectorSpecialInitializerZero {};
74 struct VectorSpecialInitializerOne {};
78 struct VectorSpecialInitializerIndexesFromZero {};
79 
84 constexpr VectorSpecialInitializerZero Zero = {};
89 constexpr VectorSpecialInitializerOne One = {};
94 constexpr VectorSpecialInitializerIndexesFromZero IndexesFromZero = {};
96 
97 namespace Detail
98 {
99 template<typename T> struct MayAliasImpl {
100 #ifdef __GNUC__
101 #pragma GCC diagnostic push
102 #pragma GCC diagnostic ignored "-Wattributes"
103 #endif
104  typedef T type Vc_MAY_ALIAS;
105 #ifdef __GNUC__
106 #pragma GCC diagnostic pop
107 #endif
108 };
109 //template<size_t Bytes> struct MayAlias<MaskBool<Bytes>> { typedef MaskBool<Bytes> type; };
110 } // namespace Detail
117 #ifdef Vc_ICC
118 template <typename T> using MayAlias [[gnu::may_alias]] = T;
119 #else
120 template <typename T> using MayAlias = typename Detail::MayAliasImpl<T>::type;
121 #endif
122 
129 enum class Operator : char {
130  Assign,
131  Multiply,
132  MultiplyAssign,
133  Divide,
134  DivideAssign,
135  Remainder,
136  RemainderAssign,
137  Plus,
138  PlusAssign,
139  Minus,
140  MinusAssign,
141  RightShift,
142  RightShiftAssign,
143  LeftShift,
144  LeftShiftAssign,
145  And,
146  AndAssign,
147  Xor,
148  XorAssign,
149  Or,
150  OrAssign,
151  PreIncrement,
152  PostIncrement,
153  PreDecrement,
154  PostDecrement,
155  LogicalAnd,
156  LogicalOr,
157  Comma,
158  UnaryPlus,
159  UnaryMinus,
160  UnaryNot,
161  UnaryOnesComplement,
162  CompareEqual,
163  CompareNotEqual,
164  CompareLess,
165  CompareGreater,
166  CompareLessEqual,
167  CompareGreaterEqual
168 };
169 
170 // forward declaration for Vc::array in <Vc/array>
171 template <typename T, std::size_t N> struct array;
172 
173 /* TODO: add type for half-float, something along these lines:
174 class half_float
175 {
176  uint16_t data;
177 public:
178  constexpr half_float() : data(0) {}
179  constexpr half_float(const half_float &) = default;
180  constexpr half_float(half_float &&) = default;
181  constexpr half_float &operator=(const half_float &) = default;
182 
183  constexpr explicit half_float(float);
184  constexpr explicit half_float(double);
185  constexpr explicit half_float(int);
186  constexpr explicit half_float(unsigned int);
187 
188  explicit operator float () const;
189  explicit operator double () const;
190  explicit operator int () const;
191  explicit operator unsigned int() const;
192 
193  bool operator==(half_float rhs) const;
194  bool operator!=(half_float rhs) const;
195  bool operator>=(half_float rhs) const;
196  bool operator<=(half_float rhs) const;
197  bool operator> (half_float rhs) const;
198  bool operator< (half_float rhs) const;
199 
200  half_float operator+(half_float rhs) const;
201  half_float operator-(half_float rhs) const;
202  half_float operator*(half_float rhs) const;
203  half_float operator/(half_float rhs) const;
204 };
205 */
206 
207 // TODO: the following doesn't really belong into the toplevel Vc namespace.
208 #ifndef Vc_CHECK_ALIGNMENT
209 template<typename _T> static Vc_ALWAYS_INLINE void assertCorrectAlignment(const _T *){}
210 #else
211 template<typename _T> static Vc_ALWAYS_INLINE void assertCorrectAlignment(const _T *ptr)
212 {
213  const size_t s = alignof(_T);
214  if((reinterpret_cast<size_t>(ptr) & ((s ^ (s & (s - 1))) - 1)) != 0) {
215  fprintf(stderr, "A vector with incorrect alignment has just been created. Look at the stacktrace to find the guilty object.\n");
216  abort();
217  }
218 }
219 #endif
220 
221 namespace Common
222 {
229 template<size_t StructSize> class SuccessiveEntries
230 {
231 #ifdef Vc_MSVC
232  // scatterinterleavedmemory fails with garbage values in m_first if size_type is a
233  // 64-bit integer type. Using a 32-bit type seems to work around the miscompilation.
234  using size_type = unsigned;
235 #else
236  using size_type = size_t;
237 #endif
238  const size_type m_first;
239 
240 public:
241  typedef SuccessiveEntries AsArg;
242  Vc_INTRINSIC SuccessiveEntries(size_type first) : m_first(first) {}
243  Vc_INTRINSIC Vc_PURE size_type operator[](size_type offset) const
244  {
245  return m_first + offset * StructSize;
246  }
247  Vc_INTRINSIC Vc_PURE size_type data() const { return m_first; }
248  Vc_INTRINSIC Vc_PURE SuccessiveEntries operator+(const SuccessiveEntries &rhs) const
249  {
250  return SuccessiveEntries(m_first + rhs.m_first);
251  }
252  Vc_INTRINSIC Vc_PURE SuccessiveEntries operator*(const SuccessiveEntries &rhs) const
253  {
254  return SuccessiveEntries(m_first * rhs.m_first);
255  }
256  Vc_INTRINSIC Vc_PURE SuccessiveEntries operator<<(size_type x) const
257  {
258  return {m_first << x};
259  }
260 
261  friend Vc_INTRINSIC SuccessiveEntries &internal_data(SuccessiveEntries &x)
262  {
263  return x;
264  }
265  friend Vc_INTRINSIC const SuccessiveEntries &internal_data(const SuccessiveEntries &x)
266  {
267  return x;
268  }
269 };
270 
271 // declaration for functions in common/malloc.h
272 template <std::size_t alignment>
273 Vc_INTRINSIC_L void *aligned_malloc(std::size_t n) Vc_INTRINSIC_R;
274 Vc_ALWAYS_INLINE_L void free(void *p) Vc_ALWAYS_INLINE_R;
275 
279 template <typename Mask, typename T, typename U>
280 using enable_if_mask_converts_implicitly =
281  enable_if<(!std::is_same<Mask, Traits::decay<U>>::value && // that'd be the copy ctor
283  Traits::is_implicit_cast_allowed_mask<
284  Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value)>;
288 template <typename T, typename U>
289 using enable_if_mask_converts_explicitly = enable_if<(
292  !Traits::is_implicit_cast_allowed_mask<
293  Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value))>;
294 
298 template <typename T> using WidthT = std::integral_constant<std::size_t, sizeof(T)>;
299 
300 // forward declaration of MaskBool in common/maskbool.h
301 template <std::size_t Bytes> class MaskBool;
302 
303 // forward declaration of SubscriptOperation in common/subscript.h
304 template <typename T, typename IndexVector, typename Scale, bool>
305 class SubscriptOperation;
306 
314 template <typename T, typename IndexVector> struct GatherArguments
315 {
316  const IndexVector indexes;
317  const T *const address;
318 };
319 
327 template <typename T, typename IndexVector> struct ScatterArguments
328 {
329  const IndexVector indexes;
330  T *const address;
331 };
332 
336 template <typename I, I Begin, I End, typename F>
337 Vc_INTRINSIC enable_if<(Begin >= End), void> unrolled_loop(F &&)
338 {
339 }
340 
346 template <typename I, I Begin, I End, typename F>
347 Vc_INTRINSIC Vc_FLATTEN enable_if<(Begin < End), void> unrolled_loop(F &&f)
348 {
349  f(Begin);
350  unrolled_loop<I, Begin + 1, End>(f);
351 }
352 
357 template <std::size_t Size, typename F> Vc_INTRINSIC void for_all_vector_entries(F &&f)
358 {
359  unrolled_loop<std::size_t, 0u, Size>(std::forward<F>(f));
360 }
361 
366 template <class T, std::size_t Size = sizeof(T), std::size_t Alignment = alignof(T)>
367 struct ensure_alignment_equals_sizeof {
368  Vc_ALIGNED_TYPEDEF(Size, T, type);
369 };
370 template <class T, std::size_t Size>
371 struct ensure_alignment_equals_sizeof<T, Size, Size> {
372  using type = T;
373 };
374 
375 } // namespace Common
376 } // namespace Vc
377 
378 #include "vector.h"
379 #include "mask.h"
380 #include "memoryfwd.h"
381 
382 #endif // VC_COMMON_TYPES_H_
383 
384 // vim: foldmethod=marker
signed char schar
signed char shorthand
Definition: types.h:65
void free(T *p)
Frees memory that was allocated with Vc::malloc.
Definition: memory.h:102
unsigned char uchar
unsigned char shorthand
Definition: types.h:63
unsigned int uint
unsigned int shorthand
Definition: types.h:59
unsigned long long ullong
unsigned long long shorthand
Definition: types.h:55
The main vector class for expressing data parallelism.
Definition: types.h:44
constexpr VectorSpecialInitializerIndexesFromZero IndexesFromZero
The special object Vc::IndexesFromZero can be used to construct Vector objects initialized to values ...
Definition: types.h:94
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:1611
Identifies any possible SimdMaskArray<T, N> type (independent of const/volatile or reference) ...
Definition: type_traits.h:158
long long llong
long long shorthand
Definition: types.h:53
result_vector_type< L, R > operator+(L &&lhs, R &&rhs)
Applies + component-wise and concurrently.
Definition: simdarray.h:1611
unsigned long ulong
unsigned long shorthand
Definition: types.h:57
unsigned short ushort
unsigned short shorthand
Definition: types.h:61
constexpr VectorSpecialInitializerZero Zero
The special object Vc::Zero can be used to construct Vector and Mask objects initialized to zero/fals...
Definition: types.h:84
constexpr VectorSpecialInitializerOne One
The special object Vc::One can be used to construct Vector and Mask objects initialized to one/true...
Definition: types.h:89
Identifies any SIMD mask type (independent of implementation or whether it&#39;s SimdMaskArray<T, N>).
Definition: type_traits.h:132
This is std::array with additional subscript operators supporting gather and scatter operations...
Definition: array:86