blob: f88e6c4aab64dd6ac280ce5caff30e9775a6c6df [file] [edit]
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
#include "packetmath_test_shared.h"
#include <memory>
namespace Eigen {
namespace test {
template <typename Scalar, typename Packet>
struct runall<Scalar, Packet, false, false> {
static void run() {
constexpr int PacketSize = internal::unpacket_traits<Packet>::size;
auto samples = special_values<Scalar>();
using Bits = typename numext::get_integer_by_size<sizeof(Scalar)>::unsigned_type;
const Bits nan_payload = numext::bit_cast<Bits>(NumTraits<Scalar>::quiet_NaN()) | Bits(0x123);
samples.push_back(numext::bit_cast<Scalar>(nan_payload));
Scalar actual[PacketSize], expected[PacketSize];
for (Index stride : {Index(-7), Index(-2), Index(-1), Index(0), Index(1), Index(2), Index(3), Index(7)}) {
const Index span = (PacketSize - 1) * numext::abs(stride) + 1;
for (Index offset = 0; offset < PacketSize; ++offset) {
// Exact-size new[] lets sanitizers detect reads past the last gathered coefficient.
std::unique_ptr<Scalar[]> storage(new Scalar[span + offset]);
Scalar* data = storage.get() + offset;
const Scalar* from = stride < 0 ? data + span - 1 : data;
for (Index rotation = 0; rotation < Index(samples.size()); ++rotation) {
for (Index i = 0; i < span; ++i) data[i] = samples[(i + rotation) % samples.size()];
for (Index i = 0; i < PacketSize; ++i) expected[i] = from[i * stride];
volatile Index runtime_stride = stride;
internal::pstoreu(actual, internal::pgather<Scalar, Packet>(from, runtime_stride));
VERIFY(areEqualBits(expected, actual, PacketSize, false));
if (stride == 2) {
internal::pstoreu(actual, internal::pgather<Scalar, Packet>(from, 2));
VERIFY(areEqualBits(expected, actual, PacketSize, false));
}
}
}
}
}
};
} // namespace test
} // namespace Eigen
EIGEN_DECLARE_TEST(packetmath_gather) {
CALL_SUBTEST_1(test::runner<float>::run());
CALL_SUBTEST_2(test::runner<double>::run());
}