From 277c3ae37a15bc5f5182b60034c409ea922418ca Mon Sep 17 00:00:00 2001 From: Denes Tarjan Date: Tue, 26 Mar 2024 16:52:03 +0100 Subject: [PATCH] [test] Add full-vector tests to increase branch coverage in utils.h --- test/api/test_merge.cpp | 33 ++++++++++++++++++++++++++------- test/api/test_min_max.cpp | 8 +++++--- test/api/test_rgb_and_gray.cpp | 24 ++++++++++++++++++------ test/api/test_split.cpp | 32 ++++++++++++++++++++++++++------ test/framework/operation.h | 2 +- 5 files changed, 76 insertions(+), 23 deletions(-) diff --git a/test/api/test_merge.cpp b/test/api/test_merge.cpp index 1fcbdbf8a..d19d97e6f 100644 --- a/test/api/test_merge.cpp +++ b/test/api/test_merge.cpp @@ -15,6 +15,8 @@ class MergeTest final { // Shorthand for internal data layout representation. using ArrayType = test::Array2D; + MergeTest() : output_padding_{0} { inputs_padding_.fill(0); } + // Sets the number of padding bytes at the end of rows. MergeTest& with_paddings(std::initializer_list inputs_padding, size_t output_padding) { @@ -26,11 +28,16 @@ class MergeTest final { return *this; } + // Sets the number of elements in a row. + MergeTest& with_width(size_t width) { + width_ = width; + return *this; + } + // Executes the test void test() { - // Width of input is set to execute 2 vector paths and 1 scalar path - size_t vector_length = test::Options::vector_length(); - size_t input_width = (vector_length * 2) + 1; + size_t vector_lanes = test::Options::vector_lanes(); + size_t input_width = width_; size_t output_width = input_width * Channels; size_t height = 2; @@ -56,8 +63,8 @@ class MergeTest final { expected_output.set(0, i, {running_test_value}); running_test_value++; - inputs[i].set(0, vector_length * 2, {running_test_value}); - expected_output.set(0, (vector_length * 2 * Channels) + i, + inputs[i].set(0, vector_lanes * 2, {running_test_value}); + expected_output.set(0, (vector_lanes * 2 * Channels) + i, {running_test_value}); running_test_value++; @@ -65,8 +72,8 @@ class MergeTest final { expected_output.set(1, i, {running_test_value}); running_test_value++; - inputs[i].set(1, vector_length * 2, {running_test_value}); - expected_output.set(1, (vector_length * 2 * Channels) + i, + inputs[i].set(1, vector_lanes * 2, {running_test_value}); + expected_output.set(1, (vector_lanes * 2 * Channels) + i, {running_test_value}); running_test_value++; } @@ -96,6 +103,9 @@ class MergeTest final { // Number of padding bytes at the end of rows. std::array inputs_padding_; size_t output_padding_; + // Tested number of elements in a row. + // Sufficient number of elements to exercise both vector and scalar paths. + size_t width_{2 * test::Options::vector_lanes() + 1}; }; template @@ -135,6 +145,9 @@ TYPED_TEST(Merge, TwoChannels) { MergeTest().with_paddings({1, 0}, 1).test(); MergeTest().with_paddings({1, 1}, 0).test(); MergeTest().with_paddings({1, 1}, 1).test(); + MergeTest() + .with_width(4 * test::Options::vector_lanes()) + .test(); } TYPED_TEST(Merge, ThreeChannels) { @@ -154,6 +167,9 @@ TYPED_TEST(Merge, ThreeChannels) { MergeTest().with_paddings({1, 1, 0}, 1).test(); MergeTest().with_paddings({1, 1, 1}, 0).test(); MergeTest().with_paddings({1, 1, 1}, 1).test(); + MergeTest() + .with_width(4 * test::Options::vector_lanes()) + .test(); } TYPED_TEST(Merge, FourChannels) { @@ -189,6 +205,9 @@ TYPED_TEST(Merge, FourChannels) { MergeTest().with_paddings({1, 1, 1, 0}, 1).test(); MergeTest().with_paddings({1, 1, 1, 1}, 0).test(); MergeTest().with_paddings({1, 1, 1, 1}, 1).test(); + MergeTest() + .with_width(4 * test::Options::vector_lanes()) + .test(); } TYPED_TEST(Merge, OneChannelOutOfRange) { diff --git a/test/api/test_min_max.cpp b/test/api/test_min_max.cpp index d98e64d7f..6d376805c 100644 --- a/test/api/test_min_max.cpp +++ b/test/api/test_min_max.cpp @@ -54,7 +54,7 @@ class MinMaxTest { static size_t scalar_offset() { return 2 * test::Options::vector_length(); } // Total number of bytes per row, padding included - static size_t stride() { return width() * sizeof(ElementType) + Padding; } + static size_t stride() { return (width() + Padding) * sizeof(ElementType); } struct Elements { std::initializer_list source_row0_vector; @@ -185,8 +185,10 @@ class MinMaxTest { source.fill(testData.filler_value); source.set(0, 0, testData.source_row0_vector); source.set(1, 0, testData.source_row1_vector); - source.set(0, (width() / lanes()) * lanes(), testData.source_row0_scalar); - source.set(1, (width() / lanes()) * lanes(), testData.source_row1_scalar); + source.set(0, scalar_offset() / sizeof(ElementType), + testData.source_row0_scalar); + source.set(1, scalar_offset() / sizeof(ElementType), + testData.source_row1_scalar); } void one_test_call(const ArrayType& source, ElementType* p_min, diff --git a/test/api/test_rgb_and_gray.cpp b/test/api/test_rgb_and_gray.cpp index d832a5d37..e848ae107 100644 --- a/test/api/test_rgb_and_gray.cpp +++ b/test/api/test_rgb_and_gray.cpp @@ -20,14 +20,19 @@ class GrayTest final { return *this; } + // Sets the number of elementsin a row. + GrayTest &with_width(size_t width) { + width_ = width; + return *this; + } + template void execute_test(F impl) { // Set width to be more than vector length, but not quite a multiple of // vector length to force both vector and scalar paths - size_t logical_width = 3 * test::Options::vector_lanes() - 1; - test::Array2D source{logical_width, 3, padding_}; - test::Array2D actual{logical_width * outChannels_, 3, padding_}; - test::Array2D expected{logical_width * outChannels_, 3, padding_}; + test::Array2D source{width_, 3, padding_}; + test::Array2D actual{width_ * outChannels_, 3, padding_}; + test::Array2D expected{width_ * outChannels_, 3, padding_}; source.set(0, 0, {1}); source.set(1, 0, {0xFF}); @@ -36,13 +41,13 @@ class GrayTest final { calculate_expected(source, expected); auto err = impl(source.data(), source.stride(), actual.data(), - actual.stride(), logical_width, actual.height()); + actual.stride(), width_, actual.height()); ASSERT_EQ(INTRINSICCV_OK, err); EXPECT_EQ_ARRAY2D(actual, expected); test::test_null_args(impl, source.data(), source.stride(), actual.data(), - actual.stride(), logical_width, actual.height()); + actual.stride(), width_, actual.height()); EXPECT_EQ(INTRINSICCV_ERROR_RANGE, impl(source.data(), source.stride(), actual.data(), @@ -72,6 +77,7 @@ class GrayTest final { } } + size_t width_{3 * test::Options::vector_lanes() - 1}; size_t padding_{0}; bool hasAlpha_; size_t outChannels_; @@ -163,11 +169,17 @@ class ColourTest final { TEST(GRAY2, RGB) { GrayTest{false}.execute_test(intrinsiccv_gray_to_rgb_u8); GrayTest{false}.with_padding(1).execute_test(intrinsiccv_gray_to_rgb_u8); + GrayTest{false} + .with_width(2 * test::Options::vector_lanes()) + .execute_test(intrinsiccv_gray_to_rgb_u8); } TEST(GRAY2, RGBA) { GrayTest{true}.execute_test(intrinsiccv_gray_to_rgba_u8); GrayTest{true}.with_padding(1).execute_test(intrinsiccv_gray_to_rgba_u8); + GrayTest{true} + .with_width(2 * test::Options::vector_lanes()) + .execute_test(intrinsiccv_gray_to_rgba_u8); } TEST(RGB2, RGB) { diff --git a/test/api/test_split.cpp b/test/api/test_split.cpp index e28b9e4ef..374775f21 100644 --- a/test/api/test_split.cpp +++ b/test/api/test_split.cpp @@ -15,6 +15,8 @@ class SplitTest final { // Shorthand for internal data layout representation. using ArrayType = test::Array2D; + SplitTest() : input_padding_{0} { outputs_padding_.fill(0); } + // Sets the number of padding bytes at the end of rows. SplitTest& with_paddings(size_t input_padding, std::initializer_list outputs_padding) { @@ -26,11 +28,17 @@ class SplitTest final { return *this; } + // Sets the number of elements in a row. + SplitTest& with_width(size_t width) { + width_ = width; + return *this; + } + // Executes the test void test() { // Width of input is set to execute 2 vector paths and 1 scalar path - size_t vector_length = test::Options::vector_length(); - size_t output_width = (vector_length * 2) + 1; + size_t vector_lanes = test::Options::vector_lanes(); + size_t output_width = width_; size_t input_width = output_width * Channels; size_t height = 2; @@ -58,16 +66,16 @@ class SplitTest final { expected_outputs[i].set(0, 0, {running_test_value}); running_test_value++; - input.set(0, (vector_length * 2 * Channels) + i, {running_test_value}); - expected_outputs[i].set(0, vector_length * 2, {running_test_value}); + input.set(0, (vector_lanes * 2 * Channels) + i, {running_test_value}); + expected_outputs[i].set(0, vector_lanes * 2, {running_test_value}); running_test_value++; input.set(1, i, {running_test_value}); expected_outputs[i].set(1, 0, {running_test_value}); running_test_value++; - input.set(1, (vector_length * 2 * Channels) + i, {running_test_value}); - expected_outputs[i].set(1, vector_length * 2, {running_test_value}); + input.set(1, (vector_lanes * 2 * Channels) + i, {running_test_value}); + expected_outputs[i].set(1, vector_lanes * 2, {running_test_value}); running_test_value++; } @@ -95,6 +103,9 @@ class SplitTest final { // Number of padding bytes at the end of rows. size_t input_padding_; std::array outputs_padding_; + // Tested number of elements in a row. + // Sufficient number of elements to exercise both vector and scalar paths. + size_t width_{2 * test::Options::vector_lanes() + 1}; }; template @@ -135,6 +146,9 @@ TYPED_TEST(Split, TwoChannels) { SplitTest().with_paddings(1, {0, 1}).test(); SplitTest().with_paddings(1, {1, 0}).test(); SplitTest().with_paddings(1, {1, 1}).test(); + SplitTest() + .with_width(4 * test::Options::vector_lanes()) + .test(); } TYPED_TEST(Split, ThreeChannels) { @@ -154,6 +168,9 @@ TYPED_TEST(Split, ThreeChannels) { SplitTest().with_paddings(1, {1, 0, 1}).test(); SplitTest().with_paddings(1, {1, 1, 0}).test(); SplitTest().with_paddings(1, {1, 1, 1}).test(); + SplitTest() + .with_width(4 * test::Options::vector_lanes()) + .test(); } TYPED_TEST(Split, FourChannels) { @@ -173,6 +190,9 @@ TYPED_TEST(Split, FourChannels) { SplitTest().with_paddings(1, {1, 1, 0, 1}).test(); SplitTest().with_paddings(1, {1, 1, 1, 0}).test(); SplitTest().with_paddings(1, {1, 1, 1, 1}).test(); + SplitTest() + .with_width(4 * test::Options::vector_lanes()) + .test(); } TYPED_TEST(Split, OneChannelOutOfRange) { diff --git a/test/framework/operation.h b/test/framework/operation.h index e3235adf3..7bc5c58e1 100644 --- a/test/framework/operation.h +++ b/test/framework/operation.h @@ -60,7 +60,7 @@ class OperationTest { return *this; } - // Sets the number of padding bytes at the end of rows. + // Sets the number of elements in a row. OperationTest& with_width( size_t width) { width_ = width; -- GitLab