From bbda1bbb3c2fdc977c04473b803694f22dde6b59 Mon Sep 17 00:00:00 2001 From: Mel Chen Date: Fri, 3 Jan 2025 02:01:17 -0800 Subject: [PATCH 1/3] [SingleSource/Vectorizer] Add unit tests for AnyOf pattern. --- SingleSource/UnitTests/Vectorizer/any-of.cpp | 181 ++++++++++++++++++ .../Vectorizer/any-of.reference_output | 8 + 2 files changed, 189 insertions(+) create mode 100644 SingleSource/UnitTests/Vectorizer/any-of.cpp create mode 100644 SingleSource/UnitTests/Vectorizer/any-of.reference_output diff --git a/SingleSource/UnitTests/Vectorizer/any-of.cpp b/SingleSource/UnitTests/Vectorizer/any-of.cpp new file mode 100644 index 0000000000..19acfc8af4 --- /dev/null +++ b/SingleSource/UnitTests/Vectorizer/any-of.cpp @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include +#include + +#include "common.h" + +template +using Fn2Ty = std::function; +template +static void checkVectorFunction(Fn2Ty ScalarFn, + Fn2Ty VectorFn, const char *Name) { + std::cout << "Checking " << Name << "\n"; + + unsigned N = 1000; + std::unique_ptr Src1(new Ty[N]); + std::unique_ptr Src2(new Ty[N]); + init_data(Src1, N); + init_data(Src2, N); + + // Test VectorFn with different input data. + { + // Check with random inputs. + auto Reference = ScalarFn(&Src1[0], &Src2[0], N); + auto ToCheck = VectorFn(&Src1[0], &Src2[0], N); + if (Reference != ToCheck) { + std::cerr << "Miscompare\n"; + exit(1); + } + } + + { + // Check with Src1 > Src2 for all elements. + for (unsigned I = 0; I != N; ++I) { + Src1[I] = std::numeric_limits::max(); + Src2[I] = std::numeric_limits::min(); + } + auto Reference = ScalarFn(&Src1[0], &Src2[0], N); + auto ToCheck = VectorFn(&Src1[0], &Src2[0], N); + if (Reference != ToCheck) { + std::cerr << "Miscompare\n"; + exit(1); + } + } + + { + // Check with Src1 < Src2 for all elements. + for (unsigned I = 0; I != N; ++I) { + Src1[I] = std::numeric_limits::min(); + Src2[I] = std::numeric_limits::max(); + } + auto Reference = ScalarFn(&Src1[0], &Src2[0], N); + auto ToCheck = VectorFn(&Src1[0], &Src2[0], N); + if (Reference != ToCheck) { + std::cerr << "Miscompare\n"; + exit(1); + } + } + + { + // Check with only Src1[998] > Src2[998]. + for (unsigned I = 0; I != N; ++I) + Src1[I] = Src2[I] = std::numeric_limits::min(); + Src1[998] = std::numeric_limits::max(); + auto Reference = ScalarFn(&Src1[0], &Src2[0], N); + auto ToCheck = VectorFn(&Src1[0], &Src2[0], N); + if (Reference != ToCheck) { + std::cerr << "Miscompare\n"; + exit(1); + } + } + + { + // Check with only Src1[0] > Src2[0]. + for (unsigned I = 0; I != N; ++I) + Src1[I] = Src2[I] = std::numeric_limits::min(); + Src1[0] = std::numeric_limits::max(); + auto Reference = ScalarFn(&Src1[0], &Src2[0], N); + auto ToCheck = VectorFn(&Src1[0], &Src2[0], N); + if (Reference != ToCheck) { + std::cerr << "Miscompare\n"; + exit(1); + } + } + + { + // Check with only Src1[N - 1] > Src2[N - 1]. + for (unsigned I = 0; I != N; ++I) + Src1[I] = Src2[I] = std::numeric_limits::min(); + Src1[N - 1] = std::numeric_limits::max(); + auto Reference = ScalarFn(&Src1[0], &Src2[0], N); + auto ToCheck = VectorFn(&Src1[0], &Src2[0], N); + if (Reference != ToCheck) { + std::cerr << "Miscompare\n"; + exit(1); + } + } + + { + // Check with only Src1[0] > Src2[0] and Src1[N - 1] > Src2[N - 1]. + for (unsigned I = 0; I != N; ++I) + Src1[I] = Src2[I] = std::numeric_limits::min(); + Src1[0] = Src1[N - 1] = std::numeric_limits::max(); + auto Reference = ScalarFn(&Src1[0], &Src2[0], N); + auto ToCheck = VectorFn(&Src1[0], &Src2[0], N); + if (Reference != ToCheck) { + std::cerr << "Miscompare\n"; + exit(1); + } + } +} + +int main(void) { + rng = std::mt19937(15); + + { + // Update Rdx to 3 once any A[i] > B[i] is true. + DEFINE_SCALAR_AND_VECTOR_FN2( + uint32_t Rdx = -1;, + for (unsigned I = 0; I < TC; I++) { + Rdx = A[I] > B[I] ? 3 : Rdx; + } + return Rdx; + ); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_icmp_true_update"); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_fcmp_true_update"); + } + + { + // Update Rdx to 3 once any A[i] > B[i] is false. + DEFINE_SCALAR_AND_VECTOR_FN2( + uint32_t Rdx = -1;, + for (unsigned I = 0; I < TC; I++) { + Rdx = A[I] > B[I] ? Rdx : 3; + } + return Rdx; + ); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_icmp_false_update"); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_fcmp_false_update"); + } + + { + // Rdx starts from TC, and will be updated to 3 once any A[i] > B[i] is + // true. + DEFINE_SCALAR_AND_VECTOR_FN2( + uint32_t Rdx = TC;, + for (unsigned I = 0; I < TC; I++) { + Rdx = A[I] > B[I] ? Rdx : 3; + } + return Rdx; + ); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_icmp_start_TC"); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_fcmp_start_TC"); + } + + { + // Rdx starts from -1, and will be updated to TC once any A[i] > B[i] is + // true. + DEFINE_SCALAR_AND_VECTOR_FN2( + int32_t Rdx = -1;, + for (unsigned I = 0; I < TC; I++) { + Rdx = A[I] > B[I] ? TC : Rdx; + } + return Rdx; + ); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_icmp_update_by_TC"); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_fcmp_update_by_TC"); + } + + return 0; +} diff --git a/SingleSource/UnitTests/Vectorizer/any-of.reference_output b/SingleSource/UnitTests/Vectorizer/any-of.reference_output new file mode 100644 index 0000000000..d26635482d --- /dev/null +++ b/SingleSource/UnitTests/Vectorizer/any-of.reference_output @@ -0,0 +1,8 @@ +Checking anyof_icmp_true_update +Checking anyof_fcmp_true_update +Checking anyof_icmp_false_update +Checking anyof_fcmp_false_update +Checking anyof_icmp_start_TC +Checking anyof_fcmp_start_TC +Checking anyof_icmp_update_by_TC +Checking anyof_fcmp_update_by_TC From 37b1efc0c9e80356effe9192ef9cf3d960d6f9d0 Mon Sep 17 00:00:00 2001 From: Mel Chen Date: Mon, 6 Jan 2025 01:49:54 -0800 Subject: [PATCH 2/3] Test for s16 --- SingleSource/UnitTests/Vectorizer/any-of.cpp | 116 +++++++++++------- .../Vectorizer/any-of.reference_output | 20 +-- 2 files changed, 84 insertions(+), 52 deletions(-) diff --git a/SingleSource/UnitTests/Vectorizer/any-of.cpp b/SingleSource/UnitTests/Vectorizer/any-of.cpp index 19acfc8af4..4c069d3293 100644 --- a/SingleSource/UnitTests/Vectorizer/any-of.cpp +++ b/SingleSource/UnitTests/Vectorizer/any-of.cpp @@ -115,66 +115,94 @@ static void checkVectorFunction(Fn2Ty ScalarFn, int main(void) { rng = std::mt19937(15); +#define DEFINE_ANYOF_LOOP_BODY(TrueVal, FalseVal) \ + for (unsigned I = 0; I < TC; I++) { \ + Rdx = A[I] > B[I] ? TrueVal : FalseVal; \ + } \ + return Rdx; + { - // Update Rdx to 3 once any A[i] > B[i] is true. + // Update 32-bits integer Rdx to 3 once any A[i] > B[i] is true. DEFINE_SCALAR_AND_VECTOR_FN2( - uint32_t Rdx = -1;, - for (unsigned I = 0; I < TC; I++) { - Rdx = A[I] > B[I] ? 3 : Rdx; - } - return Rdx; - ); - checkVectorFunction(ScalarFn, VectorFn, - "anyof_icmp_true_update"); - checkVectorFunction(ScalarFn, VectorFn, - "anyof_fcmp_true_update"); + int32_t Rdx = -1; + , DEFINE_ANYOF_LOOP_BODY(/* TrueVal= */ 3, /* FalseVal= */ Rdx)); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_icmp_s32_true_update"); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_fcmp_s32_true_update"); } { - // Update Rdx to 3 once any A[i] > B[i] is false. + // Update 16-bits integer Rdx to 3 once any A[i] > B[i] is true. DEFINE_SCALAR_AND_VECTOR_FN2( - uint32_t Rdx = -1;, - for (unsigned I = 0; I < TC; I++) { - Rdx = A[I] > B[I] ? Rdx : 3; - } - return Rdx; - ); - checkVectorFunction(ScalarFn, VectorFn, - "anyof_icmp_false_update"); - checkVectorFunction(ScalarFn, VectorFn, - "anyof_fcmp_false_update"); + int16_t Rdx = -1; + , DEFINE_ANYOF_LOOP_BODY(/* TrueVal= */ 3, /* FalseVal= */ Rdx)); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_icmp_s16_true_update"); + } + + { + // Update 32-bits integer Rdx to 3 once any A[i] > B[i] is false. + DEFINE_SCALAR_AND_VECTOR_FN2( + int32_t Rdx = -1; + , DEFINE_ANYOF_LOOP_BODY(/* TrueVal= */ Rdx, /* FalseVal= */ 3)); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_icmp_s32_false_update"); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_fcmp_s32_false_update"); } { - // Rdx starts from TC, and will be updated to 3 once any A[i] > B[i] is - // true. + // Update 16-bits integer Rdx to 3 once any A[i] > B[i] is false. DEFINE_SCALAR_AND_VECTOR_FN2( - uint32_t Rdx = TC;, - for (unsigned I = 0; I < TC; I++) { - Rdx = A[I] > B[I] ? Rdx : 3; - } - return Rdx; - ); - checkVectorFunction(ScalarFn, VectorFn, - "anyof_icmp_start_TC"); + int16_t Rdx = -1; + , DEFINE_ANYOF_LOOP_BODY(/* TrueVal= */ Rdx, /* FalseVal= */ 3)); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_icmp_s16_false_update"); + } + + { + // 32-bits integer Rdx starts from TC, and will be updated to 3 once any + // A[i] > B[i] is true. + DEFINE_SCALAR_AND_VECTOR_FN2( + uint32_t Rdx = TC; + , DEFINE_ANYOF_LOOP_BODY(/* TrueVal= */ 3, /* FalseVal= */ Rdx)); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_icmp_u32_start_TC"); checkVectorFunction(ScalarFn, VectorFn, - "anyof_fcmp_start_TC"); + "anyof_fcmp_u32_start_TC"); + } + + { + // 16-bits integer Rdx starts from TC, and will be updated to 3 once any + // A[i] > B[i] is true. + DEFINE_SCALAR_AND_VECTOR_FN2( + uint16_t Rdx = TC; + , DEFINE_ANYOF_LOOP_BODY(/* TrueVal= */ 3, /* FalseVal= */ Rdx)); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_icmp_u16_start_TC"); } { - // Rdx starts from -1, and will be updated to TC once any A[i] > B[i] is - // true. + // 32-bits integer Rdx starts from 3, and will be updated to TC once any + // A[i] > B[i] is true. DEFINE_SCALAR_AND_VECTOR_FN2( - int32_t Rdx = -1;, - for (unsigned I = 0; I < TC; I++) { - Rdx = A[I] > B[I] ? TC : Rdx; - } - return Rdx; - ); - checkVectorFunction(ScalarFn, VectorFn, - "anyof_icmp_update_by_TC"); + uint32_t Rdx = 3; + , DEFINE_ANYOF_LOOP_BODY(/* TrueVal= */ TC, /* FalseVal= */ Rdx)); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_icmp_u32_update_by_TC"); checkVectorFunction(ScalarFn, VectorFn, - "anyof_fcmp_update_by_TC"); + "anyof_fcmp_u32_update_by_TC"); + } + + { + // 16-bits integer Rdx starts from 3, and will be updated to TC once any + // A[i] > B[i] is true. + DEFINE_SCALAR_AND_VECTOR_FN2( + uint16_t Rdx = 3; + , DEFINE_ANYOF_LOOP_BODY(/* TrueVal= */ TC, /* FalseVal= */ Rdx)); + checkVectorFunction(ScalarFn, VectorFn, + "anyof_icmp_u16_update_by_TC"); } return 0; diff --git a/SingleSource/UnitTests/Vectorizer/any-of.reference_output b/SingleSource/UnitTests/Vectorizer/any-of.reference_output index d26635482d..8a0d0ee8fa 100644 --- a/SingleSource/UnitTests/Vectorizer/any-of.reference_output +++ b/SingleSource/UnitTests/Vectorizer/any-of.reference_output @@ -1,8 +1,12 @@ -Checking anyof_icmp_true_update -Checking anyof_fcmp_true_update -Checking anyof_icmp_false_update -Checking anyof_fcmp_false_update -Checking anyof_icmp_start_TC -Checking anyof_fcmp_start_TC -Checking anyof_icmp_update_by_TC -Checking anyof_fcmp_update_by_TC +Checking anyof_icmp_s32_true_update +Checking anyof_fcmp_s32_true_update +Checking anyof_icmp_s16_true_update +Checking anyof_icmp_s32_false_update +Checking anyof_fcmp_s32_false_update +Checking anyof_icmp_s16_false_update +Checking anyof_icmp_u32_start_TC +Checking anyof_fcmp_u32_start_TC +Checking anyof_icmp_u16_start_TC +Checking anyof_icmp_u32_update_by_TC +Checking anyof_fcmp_u32_update_by_TC +Checking anyof_icmp_u16_update_by_TC From 77dc1e06b10e553435b77dc025605d2f39184c1c Mon Sep 17 00:00:00 2001 From: Mel Chen Date: Mon, 13 Jan 2025 16:31:54 +0800 Subject: [PATCH 3/3] Update SingleSource/UnitTests/Vectorizer/any-of.reference_output Add exit 0 Co-authored-by: Florian Hahn --- SingleSource/UnitTests/Vectorizer/any-of.reference_output | 1 + 1 file changed, 1 insertion(+) diff --git a/SingleSource/UnitTests/Vectorizer/any-of.reference_output b/SingleSource/UnitTests/Vectorizer/any-of.reference_output index 8a0d0ee8fa..79b21fbaae 100644 --- a/SingleSource/UnitTests/Vectorizer/any-of.reference_output +++ b/SingleSource/UnitTests/Vectorizer/any-of.reference_output @@ -10,3 +10,4 @@ Checking anyof_icmp_u16_start_TC Checking anyof_icmp_u32_update_by_TC Checking anyof_fcmp_u32_update_by_TC Checking anyof_icmp_u16_update_by_TC +exit 0