| 106 | } |
| 107 | |
| 108 | template <class V, class T> void gatherArrayImpl() |
| 109 | { |
| 110 | using It = typename V::IndexType; |
| 111 | using M = typename It::Mask; |
| 112 | |
| 113 | const int count = 39999; |
| 114 | T array[count]; |
| 115 | using value_type = typename V::value_type; |
| 116 | using limits = typename std::conditional< |
| 117 | (std::is_floating_point<T>::value && std::is_integral<value_type>::value), |
| 118 | std::numeric_limits<value_type>, std::numeric_limits<T>>::type; |
| 119 | const T max = static_cast<T>(limits::max()); |
| 120 | for (int i = 0; i < count; ++i) { |
| 121 | T tmp = i + 1; |
| 122 | while (tmp > max) { |
| 123 | tmp -= max; |
| 124 | } |
| 125 | array[i] = tmp; |
| 126 | } |
| 127 | M mask; |
| 128 | for (It i([](int n) { return n ^ 1; }); !(mask = (i < count)).isEmpty(); |
| 129 | i += V::Size) { |
| 130 | const V ii([&](int n) { return i[n] < count ? array[i[n]] : i[n]; }); |
| 131 | const typename V::Mask castedMask = simd_cast<typename V::Mask>(mask); |
| 132 | if (all_of(castedMask)) { |
| 133 | V a(array, i); |
| 134 | COMPARE(a, ii) << "\n i: " << i; |
| 135 | V b(Zero); |
| 136 | b.gather(array, i); |
| 137 | COMPARE(b, ii); |
| 138 | COMPARE(a, b); |
| 139 | } |
| 140 | V b(Zero); |
| 141 | b.gather(array, i, castedMask); |
| 142 | COMPARE(castedMask, (b == ii)) |
| 143 | << ", b = " << b << ", ii = " << ii << ", i = " << i; |
| 144 | if (!all_of(castedMask)) { |
| 145 | COMPARE(!castedMask, b == V(Zero)) |
| 146 | << "\nb: " << b << "\ncastedMask: " << castedMask << !castedMask; |
| 147 | } |
| 148 | } |
| 149 | |
| 150 | const typename V::Mask k(false); |
| 151 | V a(1); |
| 152 | a.gather(array, It(IndexesFromZero), k); |
| 153 | COMPARE(a, V(1)); |
| 154 | vir::test::ADD_PASS() << "gatherArray<" << vir::typeToString<V>() << "> from " |
| 155 | << vir::typeToString<T>(); |
| 156 | } |
| 157 | TEST_TYPES(Vec, gatherArray, ALL_TYPES) |
| 158 | { |
| 159 | gatherArrayImpl<Vec, uchar>(); |