Browse Source

SIMDRegister Test: Tidy up template functions

pull/22/head
reuk 3 years ago
parent
commit
c6f703aa57
No known key found for this signature in database GPG Key ID: FCB43929F012EE5C
1 changed files with 110 additions and 139 deletions
  1. +110
    -139
      modules/juce_dsp/containers/juce_SIMDRegister_test.cpp

+ 110
- 139
modules/juce_dsp/containers/juce_SIMDRegister_test.cpp View File

@@ -39,7 +39,6 @@ namespace SIMDRegister_test_internal
{
return static_cast<type> (std::is_signed<type>::value ? (random.nextFloat() * 16.0) - 8.0
: (random.nextFloat() * 8.0));
}
};
@@ -49,59 +48,32 @@ namespace SIMDRegister_test_internal
static type next (Random& random)
{
return static_cast<type> (random.nextInt64());
}
};
template <typename type> struct RandomValue { static type next (Random& random) { return RandomPrimitive<type>::next (random); } };
template <typename type>
struct RandomValue<std::complex<type>>
{
static std::complex<type> next (Random& random)
{
return {RandomPrimitive<type>::next (random), RandomPrimitive<type>::next (random)};
}
};
template <typename type>
struct VecFiller
struct RandomValue
{
static void fill (type* dst, const int size, Random& random)
{
for (int i = 0; i < size; ++i)
dst[i] = RandomValue<type>::next (random);
}
static type next (Random& random) { return RandomPrimitive<type>::next (random); }
};
// We need to specialise for complex types: otherwise GCC 6 gives
// us an ICE internal compiler error after which the compiler seg faults.
template <typename type>
struct VecFiller<std::complex<type>>
struct RandomValue<std::complex<type>>
{
static void fill (std::complex<type>* dst, const int size, Random& random)
static std::complex<type> next (Random& random)
{
for (int i = 0; i < size; ++i)
dst[i] = std::complex<type> (RandomValue<type>::next (random), RandomValue<type>::next (random));
return {RandomPrimitive<type>::next (random), RandomPrimitive<type>::next (random)};
}
};
template <typename type>
struct VecFiller<SIMDRegister<type>>
static void fillVec (type* dst, Random& random)
{
static SIMDRegister<type> fill (Random& random)
std::generate_n (dst, SIMDRegister<type>::SIMDNumElements, [&]
{
constexpr int size = (int) SIMDRegister<type>::SIMDNumElements;
#ifdef _MSC_VER
__declspec(align(sizeof (SIMDRegister<type>))) type elements[size];
#else
type elements[(size_t) size] __attribute__((aligned(sizeof (SIMDRegister<type>))));
#endif
VecFiller<type>::fill (elements, size, random);
return SIMDRegister<type>::fromRawArray (elements);
}
};
return RandomValue<type>::next (random);
});
}
// Avoid visual studio warning
template <typename type>
@@ -127,7 +99,7 @@ namespace SIMDRegister_test_internal
{
return difference (a - b);
}
}
} // namespace SIMDRegister_test_internal
// These tests need to be strictly run on all platforms supported by JUCE as the
// SIMD code is highly platform dependent.
@@ -135,6 +107,8 @@ namespace SIMDRegister_test_internal
class SIMDRegisterUnitTests : public UnitTest
{
public:
template <typename> struct Tag {};
SIMDRegisterUnitTests()
: UnitTest ("SIMDRegister UnitTests", UnitTestCategories::dsp)
{}
@@ -290,7 +264,7 @@ public:
struct InitializationTest
{
template <typename type>
static void run (UnitTest& u, Random& random)
static void run (UnitTest& u, Random& random, Tag<type>)
{
u.expect (allValuesEqualTo<type> (SIMDRegister<type>::expand (static_cast<type> (23)), 23));
@@ -300,7 +274,7 @@ public:
#else
type elements[SIMDRegister<type>::SIMDNumElements] __attribute__((aligned(sizeof (SIMDRegister<type>))));
#endif
SIMDRegister_test_internal::VecFiller<type>::fill (elements, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (elements, random);
SIMDRegister<type> a (SIMDRegister<type>::fromRawArray (elements));
u.expect (vecEqualToArray (a, elements));
@@ -316,13 +290,13 @@ public:
struct AccessTest
{
template <typename type>
static void run (UnitTest& u, Random& random)
static void run (UnitTest& u, Random& random, Tag<type>)
{
// set-up
SIMDRegister<type> a;
type array [SIMDRegister<type>::SIMDNumElements];
SIMDRegister_test_internal::VecFiller<type>::fill (array, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (array, random);
// Test non-const access operator
for (size_t i = 0; i < SIMDRegister<type>::SIMDNumElements; ++i)
@@ -342,7 +316,7 @@ public:
struct OperatorTests
{
template <typename type>
static void run (UnitTest& u, Random& random)
static void run (UnitTest& u, Random& random, Tag<type>)
{
for (int n = 0; n < 100; ++n)
{
@@ -355,9 +329,9 @@ public:
type array_b [SIMDRegister<type>::SIMDNumElements];
type array_c [SIMDRegister<type>::SIMDNumElements];
SIMDRegister_test_internal::VecFiller<type>::fill (array_a, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (array_b, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (array_c, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (array_a, random);
SIMDRegister_test_internal::fillVec (array_b, random);
SIMDRegister_test_internal::fillVec (array_c, random);
copy (a, array_a); copy (b, array_b); copy (c, array_c);
@@ -370,9 +344,9 @@ public:
u.expect (vecEqualToArray (a, array_a));
u.expect (vecEqualToArray (b, array_b));
SIMDRegister_test_internal::VecFiller<type>::fill (array_a, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (array_b, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (array_c, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (array_a, random);
SIMDRegister_test_internal::fillVec (array_b, random);
SIMDRegister_test_internal::fillVec (array_c, random);
copy (a, array_a); copy (b, array_b); copy (c, array_c);
@@ -386,9 +360,9 @@ public:
u.expect (vecEqualToArray (b, array_b));
// set-up again
SIMDRegister_test_internal::VecFiller<type>::fill (array_a, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (array_b, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (array_c, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (array_a, random);
SIMDRegister_test_internal::fillVec (array_b, random);
SIMDRegister_test_internal::fillVec (array_c, random);
copy (a, array_a); copy (b, array_b); copy (c, array_c);
// test out-of-place with both params being vectors
@@ -418,7 +392,7 @@ public:
struct BitOperatorTests
{
template <typename type>
static void run (UnitTest& u, Random& random)
static void run (UnitTest& u, Random& random, Tag<type>)
{
typedef typename SIMDRegister<type>::vMaskType vMaskType;
typedef typename SIMDRegister<type>::MaskType MaskType;
@@ -438,7 +412,7 @@ public:
} a, b;
vMaskType bitmask = vMaskType::expand (static_cast<MaskType> (1) << (sizeof (MaskType) - 1));
SIMDRegister_test_internal::VecFiller<type>::fill (array_a, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (array_a, random);
copy (a.floatVersion, array_a);
copy (b.floatVersion, array_a);
@@ -466,9 +440,9 @@ public:
type float_a [SIMDRegister<type>::SIMDNumElements];
type float_c [SIMDRegister<type>::SIMDNumElements];
SIMDRegister_test_internal::VecFiller<type>::fill (float_a, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<MaskType>::fill (array_b, SIMDRegister<MaskType>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (float_c, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (float_a, random);
SIMDRegister_test_internal::fillVec (array_b, random);
SIMDRegister_test_internal::fillVec (float_c, random);
memcpy (array_a, float_a, sizeof (type) * SIMDRegister<type>::SIMDNumElements);
memcpy (array_c, float_c, sizeof (type) * SIMDRegister<type>::SIMDNumElements);
@@ -484,9 +458,9 @@ public:
u.expect (vecEqualToArray (a, float_a));
u.expect (vecEqualToArray (b, array_b));
SIMDRegister_test_internal::VecFiller<type>::fill (float_a, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<MaskType>::fill (array_b, SIMDRegister<MaskType>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (float_c, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (float_a, random);
SIMDRegister_test_internal::fillVec (array_b, random);
SIMDRegister_test_internal::fillVec (float_c, random);
memcpy (array_a, float_a, sizeof (type) * SIMDRegister<type>::SIMDNumElements);
memcpy (array_c, float_c, sizeof (type) * SIMDRegister<type>::SIMDNumElements);
copy (a, float_a); copy (b, array_b); copy (c, float_c);
@@ -502,9 +476,9 @@ public:
u.expect (vecEqualToArray (b, array_b));
// set-up again
SIMDRegister_test_internal::VecFiller<type>::fill (float_a, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<MaskType>::fill (array_b, SIMDRegister<MaskType>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (float_c, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (float_a, random);
SIMDRegister_test_internal::fillVec (array_b, random);
SIMDRegister_test_internal::fillVec (float_c, random);
memcpy (array_a, float_a, sizeof (type) * SIMDRegister<type>::SIMDNumElements);
memcpy (array_c, float_c, sizeof (type) * SIMDRegister<type>::SIMDNumElements);
copy (a, float_a); copy (b, array_b); copy (c, float_c);
@@ -542,7 +516,7 @@ public:
struct CheckComparisonOps
{
template <typename type>
static void run (UnitTest& u, Random& random)
static void run (UnitTest& u, Random& random, Tag<type>)
{
typedef typename SIMDRegister<type>::vMaskType vMaskType;
typedef typename SIMDRegister<type>::MaskType MaskType;
@@ -560,8 +534,8 @@ public:
MaskType array_ge [SIMDRegister<type>::SIMDNumElements];
SIMDRegister_test_internal::VecFiller<type>::fill (array_a, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (array_b, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (array_a, random);
SIMDRegister_test_internal::fillVec (array_b, random);
// do check
for (size_t j = 0; j < SIMDRegister<type>::SIMDNumElements; ++j)
@@ -598,8 +572,8 @@ public:
do
{
SIMDRegister_test_internal::VecFiller<type>::fill (array_a, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (array_b, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (array_a, random);
SIMDRegister_test_internal::fillVec (array_b, random);
} while (std::equal (array_a, array_a + SIMDRegister<type>::SIMDNumElements, array_b));
copy (a, array_a);
@@ -609,7 +583,7 @@ public:
u.expect (! (a == b));
u.expect (! (b == a));
SIMDRegister_test_internal::VecFiller<type>::fill (array_a, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (array_a, random);
copy (a, array_a);
copy (b, array_a);
@@ -635,7 +609,7 @@ public:
struct CheckMultiplyAdd
{
template <typename type>
static void run (UnitTest& u, Random& random)
static void run (UnitTest& u, Random& random, Tag<type>)
{
// set-up
type array_a [SIMDRegister<type>::SIMDNumElements];
@@ -643,10 +617,10 @@ public:
type array_c [SIMDRegister<type>::SIMDNumElements];
type array_d [SIMDRegister<type>::SIMDNumElements];
SIMDRegister_test_internal::VecFiller<type>::fill (array_a, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (array_b, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (array_c, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::VecFiller<type>::fill (array_d, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (array_a, random);
SIMDRegister_test_internal::fillVec (array_b, random);
SIMDRegister_test_internal::fillVec (array_c, random);
SIMDRegister_test_internal::fillVec (array_d, random);
// check
for (size_t i = 0; i < SIMDRegister<type>::SIMDNumElements; ++i)
@@ -667,7 +641,7 @@ public:
struct CheckMinMax
{
template <typename type>
static void run (UnitTest& u, Random& random)
static void run (UnitTest& u, Random& random, Tag<type>)
{
for (int i = 0; i < 100; ++i)
{
@@ -717,17 +691,14 @@ public:
struct CheckSum
{
template <typename type>
static void run (UnitTest& u, Random& random)
static void run (UnitTest& u, Random& random, Tag<type>)
{
type array [SIMDRegister<type>::SIMDNumElements];
type sumCheck = 0;
SIMDRegister_test_internal::VecFiller<type>::fill (array, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (array, random);
for (size_t j = 0; j < SIMDRegister<type>::SIMDNumElements; ++j)
{
sumCheck += array[j];
}
using AddedType = decltype (type{} + type{});
const auto sumCheck = (type) std::accumulate (std::begin (array), std::end (array), AddedType{});
SIMDRegister<type> a;
copy (a, array);
@@ -739,12 +710,12 @@ public:
struct CheckAbs
{
template <typename type>
static void run (UnitTest& u, Random& random)
static void run (UnitTest& u, Random& random, Tag<type>)
{
type inArray[SIMDRegister<type>::SIMDNumElements];
type outArray[SIMDRegister<type>::SIMDNumElements];
SIMDRegister_test_internal::VecFiller<type>::fill (inArray, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (inArray, random);
SIMDRegister<type> a;
copy (a, inArray);
@@ -762,12 +733,12 @@ public:
struct CheckTruncate
{
template <typename type>
static void run (UnitTest& u, Random& random)
static void run (UnitTest& u, Random& random, Tag<type>)
{
type inArray[SIMDRegister<type>::SIMDNumElements];
type outArray[SIMDRegister<type>::SIMDNumElements];
SIMDRegister_test_internal::VecFiller<type>::fill (inArray, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (inArray, random);
SIMDRegister<type> a;
copy (a, inArray);
@@ -783,7 +754,7 @@ public:
struct CheckBoolEquals
{
template <typename type>
static void run (UnitTest& u, Random& random)
static void run (UnitTest& u, Random& random, Tag<type>)
{
bool is_signed = std::is_signed<type>::value;
type array [SIMDRegister<type>::SIMDNumElements];
@@ -802,14 +773,14 @@ public:
u.expect (a != value);
u.expect (! (a == value));
SIMDRegister_test_internal::VecFiller<type>::fill (array, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (array, random);
copy (a, array);
copy (b, array);
u.expect (a == b);
u.expect (! (a != b));
SIMDRegister_test_internal::VecFiller<type>::fill (array, SIMDRegister<type>::SIMDNumElements, random);
SIMDRegister_test_internal::fillVec (array, random);
copy (b, array);
u.expect (a != b);
@@ -819,96 +790,96 @@ public:
//==============================================================================
template <class TheTest>
void runTestFloatingPoint (const char* unitTestName)
void runTestFloatingPoint (const char* unitTestName, TheTest)
{
beginTest (unitTestName);
Random random = getRandom();
TheTest::template run<float> (*this, random);
TheTest::template run<double> (*this, random);
TheTest::run (*this, random, Tag<float> {});
TheTest::run (*this, random, Tag<double>{});
}
//==============================================================================
template <class TheTest>
void runTestForAllTypes (const char* unitTestName)
void runTestForAllTypes (const char* unitTestName, TheTest)
{
beginTest (unitTestName);
Random random = getRandom();
TheTest::template run<float> (*this, random);
TheTest::template run<double> (*this, random);
TheTest::template run<int8_t> (*this, random);
TheTest::template run<uint8_t> (*this, random);
TheTest::template run<int16_t> (*this, random);
TheTest::template run<uint16_t>(*this, random);
TheTest::template run<int32_t> (*this, random);
TheTest::template run<uint32_t>(*this, random);
TheTest::template run<int64_t> (*this, random);
TheTest::template run<uint64_t>(*this, random);
TheTest::template run<std::complex<float>> (*this, random);
TheTest::template run<std::complex<double>> (*this, random);
TheTest::run (*this, random, Tag<float> {});
TheTest::run (*this, random, Tag<double> {});
TheTest::run (*this, random, Tag<int8_t> {});
TheTest::run (*this, random, Tag<uint8_t> {});
TheTest::run (*this, random, Tag<int16_t> {});
TheTest::run (*this, random, Tag<uint16_t> {});
TheTest::run (*this, random, Tag<int32_t> {});
TheTest::run (*this, random, Tag<uint32_t> {});
TheTest::run (*this, random, Tag<int64_t> {});
TheTest::run (*this, random, Tag<uint64_t> {});
TheTest::run (*this, random, Tag<std::complex<float>> {});
TheTest::run (*this, random, Tag<std::complex<double>>{});
}
template <class TheTest>
void runTestNonComplex (const char* unitTestName)
void runTestNonComplex (const char* unitTestName, TheTest)
{
beginTest (unitTestName);
Random random = getRandom();
TheTest::template run<float> (*this, random);
TheTest::template run<double> (*this, random);
TheTest::template run<int8_t> (*this, random);
TheTest::template run<uint8_t> (*this, random);
TheTest::template run<int16_t> (*this, random);
TheTest::template run<uint16_t>(*this, random);
TheTest::template run<int32_t> (*this, random);
TheTest::template run<uint32_t>(*this, random);
TheTest::template run<int64_t> (*this, random);
TheTest::template run<uint64_t>(*this, random);
TheTest::run (*this, random, Tag<float> {});
TheTest::run (*this, random, Tag<double> {});
TheTest::run (*this, random, Tag<int8_t> {});
TheTest::run (*this, random, Tag<uint8_t> {});
TheTest::run (*this, random, Tag<int16_t> {});
TheTest::run (*this, random, Tag<uint16_t>{});
TheTest::run (*this, random, Tag<int32_t> {});
TheTest::run (*this, random, Tag<uint32_t>{});
TheTest::run (*this, random, Tag<int64_t> {});
TheTest::run (*this, random, Tag<uint64_t>{});
}
template <class TheTest>
void runTestSigned (const char* unitTestName)
void runTestSigned (const char* unitTestName, TheTest)
{
beginTest (unitTestName);
Random random = getRandom();
TheTest::template run<float> (*this, random);
TheTest::template run<double> (*this, random);
TheTest::template run<int8_t> (*this, random);
TheTest::template run<int16_t> (*this, random);
TheTest::template run<int32_t> (*this, random);
TheTest::template run<int64_t> (*this, random);
TheTest::run (*this, random, Tag<float> {});
TheTest::run (*this, random, Tag<double> {});
TheTest::run (*this, random, Tag<int8_t> {});
TheTest::run (*this, random, Tag<int16_t>{});
TheTest::run (*this, random, Tag<int32_t>{});
TheTest::run (*this, random, Tag<int64_t>{});
}
void runTest()
{
runTestForAllTypes<InitializationTest> ("InitializationTest");
runTestForAllTypes ("InitializationTest", InitializationTest{});
runTestForAllTypes<AccessTest> ("AccessTest");
runTestForAllTypes ("AccessTest", AccessTest{});
runTestForAllTypes<OperatorTests<Addition>> ("AdditionOperators");
runTestForAllTypes<OperatorTests<Subtraction>> ("SubtractionOperators");
runTestForAllTypes<OperatorTests<Multiplication>> ("MultiplicationOperators");
runTestForAllTypes ("AdditionOperators", OperatorTests<Addition>{});
runTestForAllTypes ("SubtractionOperators", OperatorTests<Subtraction>{});
runTestForAllTypes ("MultiplicationOperators", OperatorTests<Multiplication>{});
runTestForAllTypes<BitOperatorTests<BitAND>> ("BitANDOperators");
runTestForAllTypes<BitOperatorTests<BitOR>> ("BitOROperators");
runTestForAllTypes<BitOperatorTests<BitXOR>> ("BitXOROperators");
runTestForAllTypes ("BitANDOperators", BitOperatorTests<BitAND>{});
runTestForAllTypes ("BitOROperators", BitOperatorTests<BitOR>{});
runTestForAllTypes ("BitXOROperators", BitOperatorTests<BitXOR>{});
runTestNonComplex<CheckComparisonOps> ("CheckComparisons");
runTestNonComplex<CheckBoolEquals> ("CheckBoolEquals");
runTestNonComplex<CheckMinMax> ("CheckMinMax");
runTestNonComplex ("CheckComparisons", CheckComparisonOps{});
runTestNonComplex ("CheckBoolEquals", CheckBoolEquals{});
runTestNonComplex ("CheckMinMax", CheckMinMax{});
runTestForAllTypes<CheckMultiplyAdd> ("CheckMultiplyAdd");
runTestForAllTypes<CheckSum> ("CheckSum");
runTestForAllTypes ("CheckMultiplyAdd", CheckMultiplyAdd{});
runTestForAllTypes ("CheckSum", CheckSum{});
runTestSigned<CheckAbs> ("CheckAbs");
runTestSigned ("CheckAbs", CheckAbs{});
runTestFloatingPoint<CheckTruncate> ("CheckTruncate");
runTestFloatingPoint ("CheckTruncate", CheckTruncate{});
}
};


Loading…
Cancel
Save