ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
load.cpp
Go to the documentation of this file.
1 /* This file is part of the Vc library.
2 
3  Copyright (C) 2009-2012 Matthias Kretz <kretz@kde.org>
4 
5  Vc is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as
7  published by the Free Software Foundation, either version 3 of
8  the License, or (at your option) any later version.
9 
10  Vc is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with Vc. If not, see <http://www.gnu.org/licenses/>.
17 
18 */
19 
20 #include "unittest.h"
21 #include <iostream>
22 
23 using namespace Vc;
24 
25 template<typename Vec> unsigned long alignmentMask()
26 {
27  if (Vec::Size == 1) {
28  // on 32bit the maximal alignment is 4 Bytes, even for 8-Byte doubles.
29  return std::min(sizeof(void*), sizeof(typename Vec::EntryType)) - 1;
30  }
31  // sizeof(SSE::sfloat_v) is too large
32  // AVX::VectorAlignment is too large
33  return std::min<unsigned long>(sizeof(Vec), VectorAlignment) - 1;
34 }
35 
36 template<typename Vec> void checkAlignment()
37 {
38  unsigned char i = 1;
39  Vec a[10];
40  unsigned long mask = alignmentMask<Vec>();
41  for (i = 0; i < 10; ++i) {
42  VERIFY((reinterpret_cast<size_t>(&a[i]) & mask) == 0) << "a = " << a << ", mask = " << mask;
43  }
44  const char *data = reinterpret_cast<const char *>(&a[0]);
45  for (i = 0; i < 10; ++i) {
46  VERIFY(&data[i * Vec::Size * sizeof(typename Vec::EntryType)] == reinterpret_cast<const char *>(&a[i]));
47  }
48 }
49 
51 
52 template<typename Vec> void checkMemoryAlignment()
53 {
54  typedef typename Vec::EntryType T;
55  const T *b = 0;
57  b = a;
59  unsigned long mask = alignmentMask<Vec>();
60  for (int i = 0; i < 10; ++i) {
61  VERIFY((reinterpret_cast<size_t>(&b[i * Vec::Size]) & mask) == 0) << "b = " << b << ", mask = " << mask;
62  }
63 }
64 
65 template<typename Vec> void loadArray()
66 {
67  typedef typename Vec::EntryType T;
68  typedef typename Vec::IndexType I;
69 
70  enum loadArrayEnum { count = 256 * 1024 / sizeof(T) };
72  for (int i = 0; i < count; ++i) {
73  array[i] = i;
74  }
75 
76  const I indexesFromZero(IndexesFromZero);
77 
78  const Vec offsets(indexesFromZero);
79  for (int i = 0; i < count; i += Vec::Size) {
80  const T *const addr = &array[i];
81  Vec ii(i);
82  ii += offsets;
83 
84  Vec a(addr);
85  COMPARE(a, ii);
86 
87  Vec b = Vec::Zero();
88  b.load(addr);
89  COMPARE(b, ii);
90  }
91 }
92 
93 enum Enum {
94  loadArrayShortCount = 32 * 1024,
96 };
97 template<typename Vec> void loadArrayShort()
98 {
99  typedef typename Vec::EntryType T;
100 
102  for (int i = 0; i < loadArrayShortCount; ++i) {
103  array[i] = i;
104  }
105 
106  const Vec &offsets = static_cast<Vec>(ushort_v::IndexesFromZero());
107  for (int i = 0; i < loadArrayShortCount; i += Vec::Size) {
108  const T *const addr = &array[i];
109  Vec ii(i);
110  ii += offsets;
111 
112  Vec a(addr);
113  COMPARE(a, ii);
114 
115  Vec b = Vec::Zero();
116  b.load(addr);
117  COMPARE(b, ii);
118  }
119 }
120 
121 template<typename Vec> void streamingLoad()
122 {
123  typedef typename Vec::EntryType T;
124 
126  data[0] = static_cast<T>(-streamingLoadCount/2);
127  for (int i = 1; i < streamingLoadCount; ++i) {
128  data[i] = data[i - 1];
129  ++data[i];
130  }
131 
132  Vec ref = data.firstVector();
133  for (int i = 0; i < streamingLoadCount - Vec::Size; ++i, ++ref) {
134  Vec v1, v2;
135  if (0 == i % Vec::Size) {
136  v1 = Vec(&data[i], Vc::Streaming | Vc::Aligned);
137  v2.load (&data[i], Vc::Streaming | Vc::Aligned);
138  } else {
139  v1 = Vec(&data[i], Vc::Streaming | Vc::Unaligned);
140  v2.load (&data[i], Vc::Streaming | Vc::Unaligned);
141  }
142  COMPARE(v1, ref);
143  COMPARE(v2, ref);
144  }
145 }
146 
147 template<typename T> struct TypeInfo;
148 template<> struct TypeInfo<double > { static const char *string() { return "double"; } };
149 template<> struct TypeInfo<float > { static const char *string() { return "float"; } };
150 template<> struct TypeInfo<int > { static const char *string() { return "int"; } };
151 template<> struct TypeInfo<unsigned int > { static const char *string() { return "uint"; } };
152 template<> struct TypeInfo<short > { static const char *string() { return "short"; } };
153 template<> struct TypeInfo<unsigned short> { static const char *string() { return "ushort"; } };
154 template<> struct TypeInfo<signed char > { static const char *string() { return "schar"; } };
155 template<> struct TypeInfo<unsigned char > { static const char *string() { return "uchar"; } };
156 template<> struct TypeInfo<double_v > { static const char *string() { return "double_v"; } };
157 template<> struct TypeInfo<float_v > { static const char *string() { return "float_v"; } };
158 template<> struct TypeInfo<sfloat_v > { static const char *string() { return "sfloat_v"; } };
159 template<> struct TypeInfo<int_v > { static const char *string() { return "int_v"; } };
160 template<> struct TypeInfo<uint_v > { static const char *string() { return "uint_v"; } };
161 template<> struct TypeInfo<short_v > { static const char *string() { return "short_v"; } };
162 template<> struct TypeInfo<ushort_v > { static const char *string() { return "ushort_v"; } };
163 
164 template<typename T, typename Current = void> struct SupportedConversions { typedef void Next; };
165 template<> struct SupportedConversions<float, void> { typedef double Next; };
166 template<> struct SupportedConversions<float, double> { typedef int Next; };
167 template<> struct SupportedConversions<float, int> { typedef unsigned int Next; };
168 template<> struct SupportedConversions<float, unsigned int> { typedef short Next; };
169 template<> struct SupportedConversions<float, short> { typedef unsigned short Next; };
170 template<> struct SupportedConversions<float, unsigned short> { typedef signed char Next; };
171 template<> struct SupportedConversions<float, signed char> { typedef unsigned char Next; };
172 template<> struct SupportedConversions<float, unsigned char> { typedef void Next; };
173 template<> struct SupportedConversions<int , void > { typedef unsigned int Next; };
174 template<> struct SupportedConversions<int , unsigned int > { typedef short Next; };
175 template<> struct SupportedConversions<int , short > { typedef unsigned short Next; };
176 template<> struct SupportedConversions<int , unsigned short> { typedef signed char Next; };
177 template<> struct SupportedConversions<int , signed char > { typedef unsigned char Next; };
178 template<> struct SupportedConversions<int , unsigned char > { typedef void Next; };
179 template<> struct SupportedConversions<unsigned int, void > { typedef unsigned short Next; };
180 template<> struct SupportedConversions<unsigned int, unsigned short> { typedef unsigned char Next; };
181 template<> struct SupportedConversions<unsigned int, unsigned char > { typedef void Next; };
182 template<> struct SupportedConversions<unsigned short, void > { typedef unsigned char Next; };
183 template<> struct SupportedConversions<unsigned short, unsigned char > { typedef void Next; };
184 template<> struct SupportedConversions< short, void > { typedef unsigned char Next; };
185 template<> struct SupportedConversions< short, unsigned char > { typedef signed char Next; };
186 template<> struct SupportedConversions< short, signed char > { typedef void Next; };
187 
188 template<typename Vec, typename MemT> struct LoadCvt {
189  static void test() {
190  typedef typename Vec::EntryType VecT;
191  MemT *data = Vc::malloc<MemT, Vc::AlignOnCacheline>(128);
192  for (size_t i = 0; i < 128; ++i) {
193  data[i] = static_cast<MemT>(i - 64);
194  }
195 
196  for (size_t i = 0; i < 128 - Vec::Size + 1; ++i) {
197  Vec v;
198  if (i % (2 * Vec::Size) == 0) {
199  v = Vec(&data[i]);
200  } else if (i % Vec::Size == 0) {
201  v = Vec(&data[i], Vc::Aligned);
202  } else {
203  v = Vec(&data[i], Vc::Unaligned);
204  }
205  for (size_t j = 0; j < Vec::Size; ++j) {
206  COMPARE(v[j], static_cast<VecT>(data[i + j])) << " " << TypeInfo<MemT>::string();
207  }
208  }
209  for (size_t i = 0; i < 128 - Vec::Size + 1; ++i) {
210  Vec v;
211  if (i % (2 * Vec::Size) == 0) {
212  v.load(&data[i]);
213  } else if (i % Vec::Size == 0) {
214  v.load(&data[i], Vc::Aligned);
215  } else {
216  v.load(&data[i], Vc::Unaligned);
217  }
218  for (size_t j = 0; j < Vec::Size; ++j) {
219  COMPARE(v[j], static_cast<VecT>(data[i + j])) << " " << TypeInfo<MemT>::string();
220  }
221  }
222  for (size_t i = 0; i < 128 - Vec::Size + 1; ++i) {
223  Vec v;
224  if (i % (2 * Vec::Size) == 0) {
225  v = Vec(&data[i], Vc::Streaming);
226  } else if (i % Vec::Size == 0) {
227  v = Vec(&data[i], Vc::Streaming | Vc::Aligned);
228  } else {
229  v = Vec(&data[i], Vc::Streaming | Vc::Unaligned);
230  }
231  for (size_t j = 0; j < Vec::Size; ++j) {
232  COMPARE(v[j], static_cast<VecT>(data[i + j])) << " " << TypeInfo<MemT>::string();
233  }
234  }
235 
236  ADD_PASS() << "loadCvt: load " << TypeInfo<MemT>::string() << "* as " << TypeInfo<Vec>::string();
237  LoadCvt<Vec, typename SupportedConversions<VecT, MemT>::Next>::test();
238  }
239 };
240 template<typename Vec> struct LoadCvt<Vec, void> { static void test() {} };
241 
242 template<typename Vec> void loadCvt()
243 {
244  typedef typename Vec::EntryType T;
245  LoadCvt<Vec, typename SupportedConversions<T>::Next>::test();
246 }
247 
248 int main()
249 {
250  runTest(checkAlignment<int_v>);
251  runTest(checkAlignment<uint_v>);
252  runTest(checkAlignment<float_v>);
253  runTest(checkAlignment<double_v>);
254  runTest(checkAlignment<short_v>);
255  runTest(checkAlignment<ushort_v>);
256  runTest(checkAlignment<sfloat_v>);
258  runTest(loadArray<int_v>);
259  runTest(loadArray<uint_v>);
260  runTest(loadArray<float_v>);
261  runTest(loadArray<double_v>);
262  runTest(loadArray<sfloat_v>);
263  runTest(loadArrayShort<short_v>);
264  runTest(loadArrayShort<ushort_v>);
265 
267 
269  return 0;
270 }
VECTOR_NAMESPACE::uint_v uint_v
Definition: vector.h:88
VECTOR_NAMESPACE::sfloat_v sfloat_v
Definition: vector.h:82
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
Definition: vector.h:433
const Double_t * v1
Definition: TArcBall.cxx:33
const char * Size
Definition: TXMLSetup.cxx:56
TArc * a
Definition: textangle.C:12
void checkAlignment()
Definition: load.cpp:36
VECTOR_NAMESPACE::short_v short_v
Definition: vector.h:90
TTree * T
int main()
Definition: load.cpp:248
#define COMPARE(a, b)
Definition: unittest.h:509
VECTOR_NAMESPACE::ushort_v ushort_v
Definition: vector.h:92
#define testAllTypes(name)
Definition: unittest.h:43
void loadCvt()
Definition: load.cpp:242
void streamingLoad()
Definition: load.cpp:121
VECTOR_NAMESPACE::int_v int_v
Definition: vector.h:86
void loadArray()
Definition: load.cpp:65
SVector< double, 2 > v
Definition: Dict.h:5
VECTOR_NAMESPACE::double_v double_v
Definition: vector.h:80
void loadArrayShort()
Definition: load.cpp:97
#define VERIFY(cond)
Definition: unittest.h:515
A helper class for fixed-size two-dimensional arrays.
Definition: memory.h:120
void checkMemoryAlignment()
Definition: load.cpp:52
Enum
Definition: load.cpp:93
VECTOR_NAMESPACE::float_v float_v
Definition: vector.h:84
Vc_ALWAYS_INLINE Vc_PURE VectorPointerHelper< V, AlignedFlag > firstVector()
Definition: memorybase.h:414
typedef void((*Func_t)())
void * hack_to_put_b_on_the_stack
Definition: load.cpp:50
#define I(x, y, z)
unsigned long alignmentMask()
Definition: load.cpp:25
#define runTest(name)
Definition: unittest.h:42
int ii
Definition: hprod.C:34