38 template<
typename A,
typename B>
struct TPair {
typedef A V;
typedef B M; };
60 typedef typename Pair::V V;
61 typedef typename Pair::M M;
62 typedef typename V::IndexType
I;
64 const bool isSigned = std::numeric_limits<M>::is_signed;
66 const typename V::EntryType offset = isSigned ? -512 : 0;
70 for (
int i = 0; i < 1024; ++i) {
71 memory[i] =
static_cast<M
>(i + offset);
76 for (
int i = 0; i < 1024 - 2 *
V::Size; ++i) {
80 if (reinterpret_cast<unsigned long>(&memory[i]) & (
VectorAlignment - 1)) {
90 template<
typename T,
size_t N>
struct SomeStruct
95 template<
typename V,
size_t StructSize>
struct Types
97 typedef typename V::EntryType
T;
98 typedef typename V::IndexType
I;
99 typedef typename V::AsArg VArg;
100 typedef typename I::AsArg IArg;
101 typedef SomeStruct<T, StructSize>
S;
102 typedef const Vc::InterleavedMemoryWrapper<S, V> &Wrapper;
104 template<
typename V,
size_t StructSize,
size_t N = StructSize>
struct TestDeinterleaveGatherCompare;
105 template<
typename V,
size_t StructSize>
struct TestDeinterleaveGatherCompare<V, StructSize, 8> {
106 static void test(
typename Types<V, StructSize>::Wrapper data_v,
typename Types<V, StructSize>::IArg indexes,
const typename V::AsArg reference)
108 V v0,
v1, v2, v3, v4, v5, v6, v7;
109 (v0,
v1, v2, v3, v4, v5, v6, v7) = data_v[indexes];
110 COMPARE(v0, reference + 0) <<
"N = 8";
111 COMPARE(v1, reference + 1) <<
"N = 8";
112 COMPARE(v2, reference + 2) <<
"N = 8";
113 COMPARE(v3, reference + 3) <<
"N = 8";
114 COMPARE(v4, reference + 4) <<
"N = 8";
115 COMPARE(v5, reference + 5) <<
"N = 8";
116 COMPARE(v6, reference + 6) <<
"N = 8";
117 COMPARE(v7, reference + 7) <<
"N = 8";
118 TestDeinterleaveGatherCompare<V, StructSize, 7>::test(data_v, indexes, reference);
121 template<
typename V,
size_t StructSize>
struct TestDeinterleaveGatherCompare<V, StructSize, 7> {
122 static void test(
typename Types<V, StructSize>::Wrapper data_v,
typename Types<V, StructSize>::IArg indexes,
const typename V::AsArg reference)
124 V v0,
v1, v2, v3, v4, v5, v6;
125 (v0,
v1, v2, v3, v4, v5, v6) = data_v[indexes];
126 COMPARE(v0, reference + 0) <<
"N = 7";
127 COMPARE(v1, reference + 1) <<
"N = 7";
128 COMPARE(v2, reference + 2) <<
"N = 7";
129 COMPARE(v3, reference + 3) <<
"N = 7";
130 COMPARE(v4, reference + 4) <<
"N = 7";
131 COMPARE(v5, reference + 5) <<
"N = 7";
132 COMPARE(v6, reference + 6) <<
"N = 7";
133 TestDeinterleaveGatherCompare<V, StructSize, 6>::test(data_v, indexes, reference);
136 template<
typename V,
size_t StructSize>
struct TestDeinterleaveGatherCompare<V, StructSize, 6> {
137 static void test(
typename Types<V, StructSize>::Wrapper data_v,
typename Types<V, StructSize>::IArg indexes,
const typename V::AsArg reference)
139 V v0,
v1, v2, v3, v4, v5;
140 (v0,
v1, v2, v3, v4, v5) = data_v[indexes];
141 COMPARE(v0, reference + 0) <<
"N = 6";
142 COMPARE(v1, reference + 1) <<
"N = 6";
143 COMPARE(v2, reference + 2) <<
"N = 6";
144 COMPARE(v3, reference + 3) <<
"N = 6";
145 COMPARE(v4, reference + 4) <<
"N = 6";
146 COMPARE(v5, reference + 5) <<
"N = 6";
147 TestDeinterleaveGatherCompare<V, StructSize, 5>::test(data_v, indexes, reference);
150 template<
typename V,
size_t StructSize>
struct TestDeinterleaveGatherCompare<V, StructSize, 5> {
151 static void test(
typename Types<V, StructSize>::Wrapper data_v,
typename Types<V, StructSize>::IArg indexes,
const typename V::AsArg reference)
153 V v0,
v1, v2, v3, v4;
154 (v0,
v1, v2, v3, v4) = data_v[indexes];
155 COMPARE(v0, reference + 0) <<
"N = 5";
156 COMPARE(v1, reference + 1) <<
"N = 5";
157 COMPARE(v2, reference + 2) <<
"N = 5";
158 COMPARE(v3, reference + 3) <<
"N = 5";
159 COMPARE(v4, reference + 4) <<
"N = 5";
160 TestDeinterleaveGatherCompare<V, StructSize, 4>::test(data_v, indexes, reference);
163 template<
typename V,
size_t StructSize>
struct TestDeinterleaveGatherCompare<V, StructSize, 4> {
164 static void test(
typename Types<V, StructSize>::Wrapper data_v,
typename Types<V, StructSize>::IArg indexes,
const typename V::AsArg reference)
167 (
a, b,
c, d) = data_v[indexes];
168 COMPARE(a, reference + 0) <<
"N = 4";
169 COMPARE(b, reference + 1) <<
"N = 4";
170 COMPARE(c, reference + 2) <<
"N = 4";
171 COMPARE(d, reference + 3) <<
"N = 4";
172 TestDeinterleaveGatherCompare<V, StructSize, 3>::test(data_v, indexes, reference);
175 template<
typename V,
size_t StructSize>
struct TestDeinterleaveGatherCompare<V, StructSize, 3> {
176 static void test(
typename Types<V, StructSize>::Wrapper data_v,
typename Types<V, StructSize>::IArg indexes,
const typename V::AsArg reference)
179 (
a, b,
c) = data_v[indexes];
180 COMPARE(a, reference + 0) <<
"N = 3";
181 COMPARE(b, reference + 1) <<
"N = 3";
182 COMPARE(c, reference + 2) <<
"N = 3";
183 TestDeinterleaveGatherCompare<V, StructSize, 2>::test(data_v, indexes, reference);
186 template<
typename V,
size_t StructSize>
struct TestDeinterleaveGatherCompare<V, StructSize, 2> {
187 static void test(
typename Types<V, StructSize>::Wrapper data_v,
typename Types<V, StructSize>::IArg indexes,
const typename V::AsArg reference)
190 (
a, b) = data_v[indexes];
191 COMPARE(a, reference + 0) <<
"N = 2";
192 COMPARE(b, reference + 1) <<
"N = 2";
198 size_t NMask = (N >> 1) | (N >> 2);
199 for (
size_t shift = 2; shift <
sizeof(
size_t) * 8; shift *= 2) {
200 NMask |= NMask >> shift;
207 typedef typename V::EntryType
T;
208 typedef typename V::IndexType
I;
209 typedef SomeStruct<T, StructSize>
S;
210 typedef Vc::InterleavedMemoryWrapper<S, V> Wrapper;
214 S *data = Vc::malloc<S, Vc::AlignOnVector>(
N);
215 for (
size_t i = 0; i <
N; ++i) {
216 for (
size_t j = 0; j < StructSize; ++j) {
217 data[i].d[j] = i * StructSize + j;
220 const Wrapper data_v(data);
222 for (
int retest = 0; retest < 10000; ++retest) {
226 const V reference =
static_cast<V
>(indexes) * V(StructSize);
228 TestDeinterleaveGatherCompare<V, StructSize>::test(data_v, indexes, reference);
234 testDeinterleaveGatherImpl<V, 2>();
235 testDeinterleaveGatherImpl<V, 3>();
236 testDeinterleaveGatherImpl<V, 4>();
237 testDeinterleaveGatherImpl<V, 5>();
238 testDeinterleaveGatherImpl<V, 6>();
239 testDeinterleaveGatherImpl<V, 7>();
240 testDeinterleaveGatherImpl<V, 8>();
243 template<
typename V,
size_t StructSize>
struct TestInterleavingScatterCompare;
244 #define _IMPL(STRUCTSIZE, _code_) \
245 template<typename V> struct TestInterleavingScatterCompare<V, STRUCTSIZE> { \
246 typedef TestInterleavingScatterCompare<V, STRUCTSIZE - 1> NextTest; \
247 template<typename Wrapper> static void test(Wrapper &data, const typename V::IndexType &i) { \
266 data[i] = (v0,
v1, v2);
267 (t0,
t1, t2) = data[i];
271 NextTest::test(data, i);
278 V t0; V
t1; V t2; V t3;
279 data[i] = (v0,
v1, v2, v3);
280 (t0,
t1, t2, t3) = data[i];
285 NextTest::test(data, i);
293 V t0; V
t1; V t2; V t3; V t4;
294 data[i] = (v0,
v1, v2, v3, v4);
295 (t0,
t1, t2, t3, t4) = data[i];
301 NextTest::test(data, i);
310 V t0; V
t1; V t2; V t3; V t4; V t5;
311 data[i] = (v0,
v1, v2, v3, v4, v5);
312 (t0,
t1, t2, t3, t4, t5) = data[i];
319 NextTest::test(data, i);
329 V t0; V
t1; V t2; V t3; V t4; V t5; V t6;
330 data[i] = (v0,
v1, v2, v3, v4, v5, v6);
331 (t0,
t1, t2, t3, t4, t5, t6) = data[i];
339 NextTest::test(data, i);
350 V t0; V
t1; V t2; V t3; V t4; V t5; V t6; V t7;
351 data[i] = (v0,
v1, v2, v3, v4, v5, v6, v7);
352 (t0,
t1, t2, t3, t4, t5, t6, t7) = data[i];
361 NextTest::test(data, i);
366 typedef typename V::EntryType
T;
367 typedef typename V::IndexType
I;
368 typedef SomeStruct<T, StructSize>
S;
369 typedef Vc::InterleavedMemoryWrapper<S, V> Wrapper;
373 S *data = Vc::malloc<S, Vc::AlignOnVector>(
N);
374 std::memset(data, 0,
sizeof(S) * N);
375 Wrapper data_v(data);
377 for (
int retest = 0; retest < 10000; ++retest) {
381 while(!(indexes.sorted() == indexes.sorted().rotated(1)).isEmpty()) {
388 TestInterleavingScatterCompare<V, StructSize>::test(data_v, indexes);
394 testInterleavingScatterImpl<V, 2>();
395 testInterleavingScatterImpl<V, 3>();
396 testInterleavingScatterImpl<V, 4>();
397 testInterleavingScatterImpl<V, 5>();
398 testInterleavingScatterImpl<V, 6>();
399 testInterleavingScatterImpl<V, 7>();
400 testInterleavingScatterImpl<V, 8>();
405 runTest(testDeinterleave<float_float>);
406 runTest(testDeinterleave<float_ushort>);
407 runTest(testDeinterleave<float_short>);
408 runTest(testDeinterleave<sfloat_float>);
409 runTest(testDeinterleave<sfloat_ushort>);
410 runTest(testDeinterleave<sfloat_short>);
411 runTest(testDeinterleave<double_double>);
412 runTest(testDeinterleave<int_int>);
413 runTest(testDeinterleave<int_short>);
414 runTest(testDeinterleave<uint_uint>);
415 runTest(testDeinterleave<uint_ushort>);
416 runTest(testDeinterleave<short_short>);
417 runTest(testDeinterleave<ushort_ushort>);
Vc_ALWAYS_INLINE void deinterleave(V *a, V *b, const M *memory, A align)
Loads two vectors of values from an interleaved array.
TPair< float_v, short > float_short
#define _IMPL(STRUCTSIZE, _code_)
void testDeinterleaveGather()
TPair< ushort_v, unsigned short > ushort_ushort
TPair< sfloat_v, short > sfloat_short
TPair< uint_v, unsigned short > uint_ushort
TPair< float_v, unsigned short > float_ushort
TPair< uint_v, unsigned int > uint_uint
#define testAllTypes(name)
TPair< int_v, int > int_int
void testInterleavingScatterImpl()
TPair< sfloat_v, unsigned short > sfloat_ushort
TPair< int_v, short > int_short
void testInterleavingScatter()
TPair< double_v, double > double_double
void testDeinterleaveGatherImpl()
Class used by TMap to store (key,value) pairs.
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
TPair< float_v, float > float_float
size_t createNMask(size_t N)
TPair< short_v, short > short_short
TPair< sfloat_v, float > sfloat_float