Vc  1.4.1
SIMD Vector Classes for C++
fwddecl.h
1 /* This file is part of the Vc library. {{{
2 Copyright © 2018 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_FWDDECL_H_
29 #define VC_FWDDECL_H_
30 
31 #include <cstddef> // for std::size_t
32 
33 #define Vc_VERSIONED_NAMESPACE Vc_1
34 
35 namespace Vc_VERSIONED_NAMESPACE
36 {
37 namespace VectorAbi
38 {
39 struct Scalar {};
40 struct Sse {};
41 struct Avx {};
42 struct Mic {};
43 template <class T> struct DeduceCompatible;
44 template <class T> struct DeduceBest;
45 } // namespace VectorAbi
46 
47 namespace Common
48 {
49 template <class T, std::size_t N> struct select_best_vector_type;
50 } // namespace Common
51 
52 template <class T, class Abi> class Mask;
53 template <class T, class Abi> class Vector;
54 
55 // === having SimdArray<T, N> in the Vc namespace leads to a ABI bug ===
56 //
57 // SimdArray<double, 4> can be { double[4] }, { __m128d[2] }, or { __m256d } even though the type
58 // is the same.
59 // The question is, what should SimdArray focus on?
60 // a) A type that makes interfacing between different implementations possible?
61 // b) Or a type that makes fixed size SIMD easier and efficient?
62 //
63 // a) can be achieved by using a union with T[N] as one member. But this may have more serious
64 // performance implications than only less efficient parameter passing (because compilers have a
65 // much harder time wrt. aliasing issues). Also alignment would need to be set to the sizeof in
66 // order to be compatible with targets with larger alignment requirements.
67 // But, the in-memory representation of masks is not portable. Thus, at the latest with AVX-512,
68 // there would be a problem with requiring SimdMaskArray<T, N> to be an ABI compatible type.
69 // AVX-512 uses one bit per boolean, whereas SSE/AVX use sizeof(T) Bytes per boolean. Conversion
70 // between the two representations is not a trivial operation. Therefore choosing one or the other
71 // representation will have a considerable impact for the targets that do not use this
72 // representation. Since the future probably belongs to one bit per boolean representation, I would
73 // go with that choice.
74 //
75 // b) requires that SimdArray<T, N> != SimdArray<T, N> if
76 // SimdArray<T, N>::vector_type != SimdArray<T, N>::vector_type
77 //
78 // Therefore use SimdArray<T, N, V>, where V follows from the above.
79 template <class T, std::size_t N,
80  class V = typename Common::select_best_vector_type<T, N>::type,
81  std::size_t Wt = V::Size>
82 class SimdArray;
83 template <class T, std::size_t N,
84  class V = typename Common::select_best_vector_type<T, N>::type,
85  std::size_t Wt = V::Size>
87 
88 namespace simd_abi
89 {
90 using scalar = VectorAbi::Scalar;
91 template <int N> struct fixed_size;
92 template <class T> using compatible = typename VectorAbi::DeduceCompatible<T>::type;
93 template <class T> using native = typename VectorAbi::DeduceBest<T>::type;
94 using __sse = VectorAbi::Sse;
95 using __avx = VectorAbi::Avx;
96 struct __avx512;
97 struct __neon;
98 } // namespace simd_abi
99 
100 template <class T, class Abi = simd_abi::compatible<T>> using simd = Vector<T, Abi>;
101 template <class T, class Abi = simd_abi::compatible<T>> using simd_mask = Mask<T, Abi>;
102 template <class T> using native_simd = simd<T, simd_abi::native<T>>;
103 template <class T> using native_simd_mask = simd_mask<T, simd_abi::native<T>>;
104 template <class T, int N> using fixed_size_simd = simd<T, simd_abi::fixed_size<N>>;
105 template <class T, int N>
107 
108 } // namespace Vc_VERSIONED_NAMESPACE
109 
110 #ifndef DOXYGEN
111 // doxygen has Vc_VERSIONED_NAMESPACE predefined to Vc
112 namespace Vc = Vc_VERSIONED_NAMESPACE;
113 #endif // DOXYGEN
114 
115 #endif // VC_FWDDECL_H_
116 
117 // vim: foldmethod=marker
The main vector class for expressing data parallelism.
Definition: fwddecl.h:53
Data-parallel arithmetic type with user-defined number of elements.
Definition: fwddecl.h:82
Data-parallel mask type with user-defined number of boolean elements.
Definition: fwddecl.h:86
The main SIMD mask class.
Definition: fwddecl.h:52
Vector Classes Namespace.
Definition: dox.h:584