Vc  1.3.2-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 T, typename U>
280 using enable_if_mask_converts_implicitly =
281  enable_if<(Traits::is_simd_mask<U>::value && !Traits::isSimdMaskArray<U>::value &&
282  Traits::is_implicit_cast_allowed_mask<
283  Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value)>;
287 template <typename T, typename U>
288 using enable_if_mask_converts_explicitly = enable_if<(
289  Traits::isSimdMaskArray<U>::value ||
290  (Traits::is_simd_mask<U>::value &&
291  !Traits::is_implicit_cast_allowed_mask<
292  Traits::entry_type_of<typename Traits::decay<U>::Vector>, T>::value))>;
293 
297 template <typename T> using WidthT = std::integral_constant<std::size_t, sizeof(T)>;
298 
299 // forward declaration of MaskBool in common/maskbool.h
300 template <std::size_t Bytes> class MaskBool;
301 
302 // forward declaration of SubscriptOperation in common/subscript.h
303 template <typename T, typename IndexVector, typename Scale, bool>
304 class SubscriptOperation;
305 
313 template <typename T, typename IndexVector> struct GatherArguments
314 {
315  const IndexVector indexes;
316  const T *const address;
317 };
318 
326 template <typename T, typename IndexVector> struct ScatterArguments
327 {
328  const IndexVector indexes;
329  T *const address;
330 };
331 
335 template <typename I, I Begin, I End, typename F>
336 Vc_INTRINSIC enable_if<(Begin >= End), void> unrolled_loop(F &&)
337 {
338 }
339 
345 template <typename I, I Begin, I End, typename F>
346 Vc_INTRINSIC Vc_FLATTEN enable_if<(Begin < End), void> unrolled_loop(F &&f)
347 {
348  f(Begin);
349  unrolled_loop<I, Begin + 1, End>(f);
350 }
351 
356 template <std::size_t Size, typename F> Vc_INTRINSIC void for_all_vector_entries(F &&f)
357 {
358  unrolled_loop<std::size_t, 0u, Size>(std::forward<F>(f));
359 }
360 
365 template <class T, std::size_t Size = sizeof(T), std::size_t Alignment = alignof(T)>
366 struct ensure_alignment_equals_sizeof {
367  Vc_ALIGNED_TYPEDEF(Size, T, type);
368 };
369 template <class T, std::size_t Size>
370 struct ensure_alignment_equals_sizeof<T, Size, Size> {
371  using type = T;
372 };
373 
374 } // namespace Common
375 } // namespace Vc
376 
377 #include "vector.h"
378 #include "mask.h"
379 #include "memoryfwd.h"
380 
381 #endif // VC_COMMON_TYPES_H_
382 
383 // 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
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