summaryrefslogtreecommitdiffstats
path: root/vecmathlib.h
blob: cf46568bab2f808e92ac44b16c7440915dbc1603 (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
// -*-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

// 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"

// Use compiler-provided vector types
// Problem: How to determine which operations are available in hardware?
// #include "vec_builtin.h"

// 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_PCS_VFP       // ARM NEON
// TODO: VFP
#  include "vec_neon_float2.h"
#  include "vec_neon_float4.h"
#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"
#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"
#endif

// TODO: MIC

#if defined __ALTIVEC__         // IBM Altivec
#  include "vec_altivec_float4.h"
#endif
#if defined __VSX__             // IBM VSX
#  include "vec_vsx_double2.h"
#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"
#endif



// Define "best" vector types
namespace vecmathlib {
  
#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
  
#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
  
#ifdef VECMATHLIB_MAX_DOUBLE_VECSIZE
  typedef realvec<double,VECMATHLIB_MAX_DOUBLE_VECSIZE> double_vec;
  typedef intvec<double,VECMATHLIB_MAX_DOUBLE_VECSIZE>  long_vec;
  typedef boolvec<double,VECMATHLIB_MAX_DOUBLE_VECSIZE> bool_double_vec;
#endif
  
#ifdef VECMATHLIB_MAX_FLOAT_VECSIZE
  typedef realvec<float,VECMATHLIB_MAX_FLOAT_VECSIZE> float_vec;
  typedef intvec<float,VECMATHLIB_MAX_FLOAT_VECSIZE>  int_vec;
  typedef boolvec<float,VECMATHLIB_MAX_FLOAT_VECSIZE> bool_float_vec;
#endif
}

#endif // #ifndef VECMATHLIB_H
OpenPOWER on IntegriCloud