From c6f703aa5777d3e8bea2d1e70142d5e0c437a2ce Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 22 Mar 2022 16:02:40 +0000 Subject: [PATCH] SIMDRegister Test: Tidy up template functions --- .../containers/juce_SIMDRegister_test.cpp | 249 ++++++++---------- 1 file changed, 110 insertions(+), 139 deletions(-) diff --git a/modules/juce_dsp/containers/juce_SIMDRegister_test.cpp b/modules/juce_dsp/containers/juce_SIMDRegister_test.cpp index 1e26f7fe4f..867854ea87 100644 --- a/modules/juce_dsp/containers/juce_SIMDRegister_test.cpp +++ b/modules/juce_dsp/containers/juce_SIMDRegister_test.cpp @@ -39,7 +39,6 @@ namespace SIMDRegister_test_internal { return static_cast (std::is_signed::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 (random.nextInt64()); - - } - }; - - template struct RandomValue { static type next (Random& random) { return RandomPrimitive::next (random); } }; - template - struct RandomValue> - { - static std::complex next (Random& random) - { - return {RandomPrimitive::next (random), RandomPrimitive::next (random)}; } }; - template - struct VecFiller + struct RandomValue { - static void fill (type* dst, const int size, Random& random) - { - for (int i = 0; i < size; ++i) - dst[i] = RandomValue::next (random); - } + static type next (Random& random) { return RandomPrimitive::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 - struct VecFiller> + struct RandomValue> { - static void fill (std::complex* dst, const int size, Random& random) + static std::complex next (Random& random) { - for (int i = 0; i < size; ++i) - dst[i] = std::complex (RandomValue::next (random), RandomValue::next (random)); + return {RandomPrimitive::next (random), RandomPrimitive::next (random)}; } }; template - struct VecFiller> + static void fillVec (type* dst, Random& random) { - static SIMDRegister fill (Random& random) + std::generate_n (dst, SIMDRegister::SIMDNumElements, [&] { - constexpr int size = (int) SIMDRegister::SIMDNumElements; - #ifdef _MSC_VER - __declspec(align(sizeof (SIMDRegister))) type elements[size]; - #else - type elements[(size_t) size] __attribute__((aligned(sizeof (SIMDRegister)))); - #endif - - VecFiller::fill (elements, size, random); - return SIMDRegister::fromRawArray (elements); - } - }; + return RandomValue::next (random); + }); + } // Avoid visual studio warning template @@ -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 struct Tag {}; + SIMDRegisterUnitTests() : UnitTest ("SIMDRegister UnitTests", UnitTestCategories::dsp) {} @@ -290,7 +264,7 @@ public: struct InitializationTest { template - static void run (UnitTest& u, Random& random) + static void run (UnitTest& u, Random& random, Tag) { u.expect (allValuesEqualTo (SIMDRegister::expand (static_cast (23)), 23)); @@ -300,7 +274,7 @@ public: #else type elements[SIMDRegister::SIMDNumElements] __attribute__((aligned(sizeof (SIMDRegister)))); #endif - SIMDRegister_test_internal::VecFiller::fill (elements, SIMDRegister::SIMDNumElements, random); + SIMDRegister_test_internal::fillVec (elements, random); SIMDRegister a (SIMDRegister::fromRawArray (elements)); u.expect (vecEqualToArray (a, elements)); @@ -316,13 +290,13 @@ public: struct AccessTest { template - static void run (UnitTest& u, Random& random) + static void run (UnitTest& u, Random& random, Tag) { // set-up SIMDRegister a; type array [SIMDRegister::SIMDNumElements]; - SIMDRegister_test_internal::VecFiller::fill (array, SIMDRegister::SIMDNumElements, random); + SIMDRegister_test_internal::fillVec (array, random); // Test non-const access operator for (size_t i = 0; i < SIMDRegister::SIMDNumElements; ++i) @@ -342,7 +316,7 @@ public: struct OperatorTests { template - static void run (UnitTest& u, Random& random) + static void run (UnitTest& u, Random& random, Tag) { for (int n = 0; n < 100; ++n) { @@ -355,9 +329,9 @@ public: type array_b [SIMDRegister::SIMDNumElements]; type array_c [SIMDRegister::SIMDNumElements]; - SIMDRegister_test_internal::VecFiller::fill (array_a, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_b, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_c, SIMDRegister::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::fill (array_a, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_b, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_c, SIMDRegister::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::fill (array_a, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_b, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_c, SIMDRegister::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 - static void run (UnitTest& u, Random& random) + static void run (UnitTest& u, Random& random, Tag) { typedef typename SIMDRegister::vMaskType vMaskType; typedef typename SIMDRegister::MaskType MaskType; @@ -438,7 +412,7 @@ public: } a, b; vMaskType bitmask = vMaskType::expand (static_cast (1) << (sizeof (MaskType) - 1)); - SIMDRegister_test_internal::VecFiller::fill (array_a, SIMDRegister::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::SIMDNumElements]; type float_c [SIMDRegister::SIMDNumElements]; - SIMDRegister_test_internal::VecFiller::fill (float_a, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_b, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (float_c, SIMDRegister::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::SIMDNumElements); memcpy (array_c, float_c, sizeof (type) * SIMDRegister::SIMDNumElements); @@ -484,9 +458,9 @@ public: u.expect (vecEqualToArray (a, float_a)); u.expect (vecEqualToArray (b, array_b)); - SIMDRegister_test_internal::VecFiller::fill (float_a, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_b, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (float_c, SIMDRegister::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::SIMDNumElements); memcpy (array_c, float_c, sizeof (type) * SIMDRegister::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::fill (float_a, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_b, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (float_c, SIMDRegister::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::SIMDNumElements); memcpy (array_c, float_c, sizeof (type) * SIMDRegister::SIMDNumElements); copy (a, float_a); copy (b, array_b); copy (c, float_c); @@ -542,7 +516,7 @@ public: struct CheckComparisonOps { template - static void run (UnitTest& u, Random& random) + static void run (UnitTest& u, Random& random, Tag) { typedef typename SIMDRegister::vMaskType vMaskType; typedef typename SIMDRegister::MaskType MaskType; @@ -560,8 +534,8 @@ public: MaskType array_ge [SIMDRegister::SIMDNumElements]; - SIMDRegister_test_internal::VecFiller::fill (array_a, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_b, SIMDRegister::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::SIMDNumElements; ++j) @@ -598,8 +572,8 @@ public: do { - SIMDRegister_test_internal::VecFiller::fill (array_a, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_b, SIMDRegister::SIMDNumElements, random); + SIMDRegister_test_internal::fillVec (array_a, random); + SIMDRegister_test_internal::fillVec (array_b, random); } while (std::equal (array_a, array_a + SIMDRegister::SIMDNumElements, array_b)); copy (a, array_a); @@ -609,7 +583,7 @@ public: u.expect (! (a == b)); u.expect (! (b == a)); - SIMDRegister_test_internal::VecFiller::fill (array_a, SIMDRegister::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 - static void run (UnitTest& u, Random& random) + static void run (UnitTest& u, Random& random, Tag) { // set-up type array_a [SIMDRegister::SIMDNumElements]; @@ -643,10 +617,10 @@ public: type array_c [SIMDRegister::SIMDNumElements]; type array_d [SIMDRegister::SIMDNumElements]; - SIMDRegister_test_internal::VecFiller::fill (array_a, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_b, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_c, SIMDRegister::SIMDNumElements, random); - SIMDRegister_test_internal::VecFiller::fill (array_d, SIMDRegister::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::SIMDNumElements; ++i) @@ -667,7 +641,7 @@ public: struct CheckMinMax { template - static void run (UnitTest& u, Random& random) + static void run (UnitTest& u, Random& random, Tag) { for (int i = 0; i < 100; ++i) { @@ -717,17 +691,14 @@ public: struct CheckSum { template - static void run (UnitTest& u, Random& random) + static void run (UnitTest& u, Random& random, Tag) { type array [SIMDRegister::SIMDNumElements]; - type sumCheck = 0; - SIMDRegister_test_internal::VecFiller::fill (array, SIMDRegister::SIMDNumElements, random); + SIMDRegister_test_internal::fillVec (array, random); - for (size_t j = 0; j < SIMDRegister::SIMDNumElements; ++j) - { - sumCheck += array[j]; - } + using AddedType = decltype (type{} + type{}); + const auto sumCheck = (type) std::accumulate (std::begin (array), std::end (array), AddedType{}); SIMDRegister a; copy (a, array); @@ -739,12 +710,12 @@ public: struct CheckAbs { template - static void run (UnitTest& u, Random& random) + static void run (UnitTest& u, Random& random, Tag) { type inArray[SIMDRegister::SIMDNumElements]; type outArray[SIMDRegister::SIMDNumElements]; - SIMDRegister_test_internal::VecFiller::fill (inArray, SIMDRegister::SIMDNumElements, random); + SIMDRegister_test_internal::fillVec (inArray, random); SIMDRegister a; copy (a, inArray); @@ -762,12 +733,12 @@ public: struct CheckTruncate { template - static void run (UnitTest& u, Random& random) + static void run (UnitTest& u, Random& random, Tag) { type inArray[SIMDRegister::SIMDNumElements]; type outArray[SIMDRegister::SIMDNumElements]; - SIMDRegister_test_internal::VecFiller::fill (inArray, SIMDRegister::SIMDNumElements, random); + SIMDRegister_test_internal::fillVec (inArray, random); SIMDRegister a; copy (a, inArray); @@ -783,7 +754,7 @@ public: struct CheckBoolEquals { template - static void run (UnitTest& u, Random& random) + static void run (UnitTest& u, Random& random, Tag) { bool is_signed = std::is_signed::value; type array [SIMDRegister::SIMDNumElements]; @@ -802,14 +773,14 @@ public: u.expect (a != value); u.expect (! (a == value)); - SIMDRegister_test_internal::VecFiller::fill (array, SIMDRegister::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::fill (array, SIMDRegister::SIMDNumElements, random); + SIMDRegister_test_internal::fillVec (array, random); copy (b, array); u.expect (a != b); @@ -819,96 +790,96 @@ public: //============================================================================== template - void runTestFloatingPoint (const char* unitTestName) + void runTestFloatingPoint (const char* unitTestName, TheTest) { beginTest (unitTestName); Random random = getRandom(); - TheTest::template run (*this, random); - TheTest::template run (*this, random); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag{}); } //============================================================================== template - void runTestForAllTypes (const char* unitTestName) + void runTestForAllTypes (const char* unitTestName, TheTest) { beginTest (unitTestName); Random random = getRandom(); - TheTest::template run (*this, random); - TheTest::template run (*this, random); - TheTest::template run (*this, random); - TheTest::template run (*this, random); - TheTest::template run (*this, random); - TheTest::template run(*this, random); - TheTest::template run (*this, random); - TheTest::template run(*this, random); - TheTest::template run (*this, random); - TheTest::template run(*this, random); - TheTest::template run> (*this, random); - TheTest::template run> (*this, random); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag> {}); + TheTest::run (*this, random, Tag>{}); } template - void runTestNonComplex (const char* unitTestName) + void runTestNonComplex (const char* unitTestName, TheTest) { beginTest (unitTestName); Random random = getRandom(); - TheTest::template run (*this, random); - TheTest::template run (*this, random); - TheTest::template run (*this, random); - TheTest::template run (*this, random); - TheTest::template run (*this, random); - TheTest::template run(*this, random); - TheTest::template run (*this, random); - TheTest::template run(*this, random); - TheTest::template run (*this, random); - TheTest::template run(*this, random); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag{}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag{}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag{}); } template - void runTestSigned (const char* unitTestName) + void runTestSigned (const char* unitTestName, TheTest) { beginTest (unitTestName); Random random = getRandom(); - TheTest::template run (*this, random); - TheTest::template run (*this, random); - TheTest::template run (*this, random); - TheTest::template run (*this, random); - TheTest::template run (*this, random); - TheTest::template run (*this, random); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag {}); + TheTest::run (*this, random, Tag{}); + TheTest::run (*this, random, Tag{}); + TheTest::run (*this, random, Tag{}); } void runTest() { - runTestForAllTypes ("InitializationTest"); + runTestForAllTypes ("InitializationTest", InitializationTest{}); - runTestForAllTypes ("AccessTest"); + runTestForAllTypes ("AccessTest", AccessTest{}); - runTestForAllTypes> ("AdditionOperators"); - runTestForAllTypes> ("SubtractionOperators"); - runTestForAllTypes> ("MultiplicationOperators"); + runTestForAllTypes ("AdditionOperators", OperatorTests{}); + runTestForAllTypes ("SubtractionOperators", OperatorTests{}); + runTestForAllTypes ("MultiplicationOperators", OperatorTests{}); - runTestForAllTypes> ("BitANDOperators"); - runTestForAllTypes> ("BitOROperators"); - runTestForAllTypes> ("BitXOROperators"); + runTestForAllTypes ("BitANDOperators", BitOperatorTests{}); + runTestForAllTypes ("BitOROperators", BitOperatorTests{}); + runTestForAllTypes ("BitXOROperators", BitOperatorTests{}); - runTestNonComplex ("CheckComparisons"); - runTestNonComplex ("CheckBoolEquals"); - runTestNonComplex ("CheckMinMax"); + runTestNonComplex ("CheckComparisons", CheckComparisonOps{}); + runTestNonComplex ("CheckBoolEquals", CheckBoolEquals{}); + runTestNonComplex ("CheckMinMax", CheckMinMax{}); - runTestForAllTypes ("CheckMultiplyAdd"); - runTestForAllTypes ("CheckSum"); + runTestForAllTypes ("CheckMultiplyAdd", CheckMultiplyAdd{}); + runTestForAllTypes ("CheckSum", CheckSum{}); - runTestSigned ("CheckAbs"); + runTestSigned ("CheckAbs", CheckAbs{}); - runTestFloatingPoint ("CheckTruncate"); + runTestFloatingPoint ("CheckTruncate", CheckTruncate{}); } };