summaryrefslogtreecommitdiffstats
path: root/vecmathlib.h
blob: 5fe283201aa934bec17a3b97b5714317fc2be39c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
// -*-C++-*-

#ifndef VECMATHLIB_H
#define VECMATHLIB_H

#if defined VML_DEBUG || defined VML_NODEBUG
#if defined VML_DEBUG && defined VML_NODEBUG
#error "Only one of VML_DEBUG or VML_NODEBUG may be defined"
#endif
#else
// default
#define VML_DEBUG
#endif

// FP settings

// Possible effects of not having VML_HAVE_FP_CONTRACT:
// - can re-associate
// - can replace division by reciprocal
// - (can break ties differently when rounding) no, this seems too invasive
// - can evaluate functions with reduced precision (80% of significant digits)

// default settings
#undef VML_HAVE_DENORMALS // TODO
#define VML_HAVE_FP_CONTRACT
#define VML_HAVE_INF
#define VML_HAVE_NAN
#define VML_HAVE_SIGNED_ZERO

// optimized settings
#ifdef __FAST_MATH__
#undef VML_HAVE_DENORMALS
#undef VML_HAVE_FP_CONTRACT
#undef VML_HAVE_INF
#undef VML_HAVE_NAN
#endif

#ifdef VML_DEBUG
#define VML_CONFIG_DEBUG " debug"
#else
#define VML_CONFIG_DEBUG " no-debug"
#endif
#ifdef VML_DENORMALS
#define VML_CONFIG_DENORMALS " denormals"
#else
#define VML_CONFIG_DENORMALS " no-denormals"
#endif
#ifdef VML_FP_CONTRACT
#define VML_CONFIG_FP_CONTRACT " fp-contract"
#else
#define VML_CONFIG_FP_CONTRACT " no-fp-contract"
#endif
#ifdef VML_INF
#define VML_CONFIG_INF " inf"
#else
#define VML_CONFIG_INF " no-inf"
#endif
#ifdef VML_NAN
#define VML_CONFIG_NAN " nan"
#else
#define VML_CONFIG_NAN " no-nan"
#endif

// TODO: introduce mad, as fast version of fma (check FP_FAST_FMA)
// TODO: introduce ieee_isnan and friends
// TODO: switch between isnan and ieee_isnan at an outside level

// This workaround is needed for older libstdc++ versions such as the
// one in Debian 6.0 when compiled with clang++
// <http://lists.cs.uiuc.edu/pipermail/cfe-dev/2011-February/013207.html>.
// The version time stamp used below is the one in Debian 6.0.
#include <cstring> // pull in __GLIBCXX__
#if defined __GLIBCXX__ && __GLIBCXX__ <= 20101114
namespace std {
class type_info;
}
#endif

#include <cassert>

#ifdef VML_DEBUG
#define VML_ASSERT(x) assert(x)
#else
#define VML_ASSERT(x) ((void)0)
#endif

// Scalarise all vector operations, and use libm's functions (mostly
// useful as fallback)
#include "vec_pseudo.h"

#ifdef __clang__
// Use compiler-provided vector types
#include "vec_builtin.h"
#endif

// Scalarise all vector operations; don't use libm, use only
// Vecmathlib's functions (mostly useful for testing Vecmathlib)
#include "vec_test.h"

#if defined __ARM_NEON__ // ARM NEON
#include "vec_neon_float2.h"
#include "vec_neon_float4.h"
#define VML_CONFIG_NEON " NEON"
#else
#define VML_CONFIG_NEON
#endif

#if defined __SSE2__ // Intel SSE 2
#include "vec_sse_float1.h"
#include "vec_sse_float4.h"
#include "vec_sse_double1.h"
#include "vec_sse_double2.h"
#if defined __SSE3__
#define VML_CONFIG_SSE3 " SSE3"
#else
#define VML_CONFIG_SSE3
#endif
#if defined __SSSE3__
#define VML_CONFIG_SSSE3 " SSSE3"
#else
#define VML_CONFIG_SSSE3
#endif
#if defined __SSE4_1__
#define VML_CONFIG_SSE4_1 " SSE4.1"
#else
#define VML_CONFIG_SSE4_1
#endif
#if defined __SSE4a__
#define VML_CONFIG_SSE4a " SSE4a"
#else
#define VML_CONFIG_SSE4a
#endif
#define VML_CONFIG_SSE2                                                        \
  " SSE2" VML_CONFIG_SSE3 VML_CONFIG_SSSE3 VML_CONFIG_SSE4_1 VML_CONFIG_SSE4a
#else
#define VML_CONFIG_SSE2
#endif

#if defined __AVX__ // Intel AVX
#include "vec_avx_fp8_32.h"
#include "vec_avx_fp16_16.h"
#include "vec_avx_float8.h"
#include "vec_avx_double4.h"
#if defined __AVX2__
#define VML_CONFIG_AVX2 " AVX2"
#else
#define VML_CONFIG_AVX2
#endif
#define VML_CONFIG_AVX " AVX" VML_CONFIG_AVX2
#else
#define VML_CONFIG_AVX
#endif

#if defined __MIC__ // Intel MIC
// TODO: single precision?
#include "vec_mic_double8.h"
#define VML_CONFIG_MIC " MIC"
#else
#define VML_CONFIG_MIC
#endif

#if defined __ALTIVEC__ // IBM Altivec
#include "vec_altivec_float4.h"
#define VML_CONFIG_ALTIVEC " Altivec"
#else
#define VML_CONFIG_ALTIVEC
#endif
#if defined __ALTIVEC__ && defined _ARCH_PWR7 // IBM VSX
#include "vec_vsx_double2.h"
#define VML_CONFIG_VSX " VSX"
#else
#define VML_CONFIG_VSX
#endif

// TODO: IBM Blue Gene/P DoubleHummer

#if defined __bgq__ && defined __VECTOR4DOUBLE__ // IBM Blue Gene/Q QPX
// TODO: vec_qpx_float4
#include "vec_qpx_double4.h"
#define VML_CONFIG_QPX " QPX"
#else
#define VML_CONFIG_QPX
#endif

#define VECMATHLIB_CONFIGURATION                                               \
  "VecmathlibConfiguration" VML_CONFIG_DEBUG VML_CONFIG_DENORMALS              \
      VML_CONFIG_FP_CONTRACT VML_CONFIG_INF VML_CONFIG_NAN VML_CONFIG_NEON     \
          VML_CONFIG_SSE2 VML_CONFIG_AVX VML_CONFIG_MIC VML_CONFIG_ALTIVEC     \
              VML_CONFIG_VSX VML_CONFIG_QPX

// Define "best" vector types
namespace vecmathlib {

#if defined VECMATHLIB_HAVE_VEC_FLOAT_16
#define VECMATHLIB_MAX_FLOAT_VECSIZE 16
#elif defined VECMATHLIB_HAVE_VEC_FLOAT_8
#define VECMATHLIB_MAX_FLOAT_VECSIZE 8
#elif defined VECMATHLIB_HAVE_VEC_FLOAT_4
#define VECMATHLIB_MAX_FLOAT_VECSIZE 4
#elif defined VECMATHLIB_HAVE_VEC_FLOAT_2
#define VECMATHLIB_MAX_FLOAT_VECSIZE 2
#elif defined VECMATHLIB_HAVE_VEC_FLOAT_1
#define VECMATHLIB_MAX_FLOAT_VECSIZE 1
#endif

#if defined VECMATHLIB_HAVE_VEC_DOUBLE_8
#define VECMATHLIB_MAX_DOUBLE_VECSIZE 8
#elif defined VECMATHLIB_HAVE_VEC_DOUBLE_4
#define VECMATHLIB_MAX_DOUBLE_VECSIZE 4
#elif defined VECMATHLIB_HAVE_VEC_DOUBLE_2
#define VECMATHLIB_MAX_DOUBLE_VECSIZE 2
#elif defined VECMATHLIB_HAVE_VEC_DOUBLE_1
#define VECMATHLIB_MAX_DOUBLE_VECSIZE 1
#endif

#ifdef VECMATHLIB_MAX_FLOAT_VECSIZE
typedef realvec<float, VECMATHLIB_MAX_FLOAT_VECSIZE> float32_vec;
typedef intvec<float, VECMATHLIB_MAX_FLOAT_VECSIZE> int32_vec;
typedef boolvec<float, VECMATHLIB_MAX_FLOAT_VECSIZE> bool32_vec;
#else
typedef realpseudovec<float, 1> float32_vec;
typedef intpseudovec<float, 1> int32_vec;
typedef boolpseudovec<float, 1> bool32_vec;
#endif

#ifdef VECMATHLIB_MAX_DOUBLE_VECSIZE
typedef realvec<double, VECMATHLIB_MAX_DOUBLE_VECSIZE> float64_vec;
typedef intvec<double, VECMATHLIB_MAX_DOUBLE_VECSIZE> int64_vec;
typedef boolvec<double, VECMATHLIB_MAX_DOUBLE_VECSIZE> bool64_vec;
#else
typedef realpseudovec<double, 1> float64_vec;
typedef intpseudovec<double, 1> int64_vec;
typedef boolpseudovec<double, 1> bool64_vec;
#endif
}

#endif // #ifndef VECMATHLIB_H
OpenPOWER on IntegriCloud