From 4a02d7bf00f6d9d778b9b200157d1e7b37cb60cd Mon Sep 17 00:00:00 2001 From: Aaron Greig Date: Tue, 8 Aug 2023 16:18:53 +0100 Subject: [PATCH] Add some parameterization to MemBufferFill tests. This effectively ports some cases from the old PI unit tests. --- .../enqueue/urEnqueueMemBufferFill.cpp | 162 +++++++++++++----- test/conformance/enqueue/urEnqueueUSMFill.cpp | 22 +-- .../enqueue/urEnqueueUSMFill2D.cpp | 15 +- .../testing/include/uur/fixtures.h | 15 ++ 4 files changed, 144 insertions(+), 70 deletions(-) diff --git a/test/conformance/enqueue/urEnqueueMemBufferFill.cpp b/test/conformance/enqueue/urEnqueueMemBufferFill.cpp index e9e39b00fd..cbeae5e85c 100644 --- a/test/conformance/enqueue/urEnqueueMemBufferFill.cpp +++ b/test/conformance/enqueue/urEnqueueMemBufferFill.cpp @@ -4,67 +4,149 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include -using urEnqueueMemBufferFillTest = uur::urMemBufferQueueTest; -UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(urEnqueueMemBufferFillTest); +struct testParametersFill { + size_t size; + size_t pattern_size; +}; + +template +inline std::string +printFillTestString(const testing::TestParamInfo &info) { + const auto device_handle = std::get<0>(info.param); + const auto platform_device_name = + uur::GetPlatformAndDeviceName(device_handle); + std::stringstream test_name; + test_name << platform_device_name << "__size__" + << std::get<1>(info.param).size << "__patternSize__" + << std::get<1>(info.param).pattern_size; + return test_name.str(); +} + +struct urEnqueueMemBufferFillTest + : uur::urQueueTestWithParam { + void SetUp() override { + UUR_RETURN_ON_FATAL_FAILURE( + urQueueTestWithParam::SetUp()); + size = std::get<1>(GetParam()).size; + pattern_size = std::get<1>(GetParam()).pattern_size; + pattern = std::vector(pattern_size); + uur::generateMemFillPattern(pattern); + ASSERT_SUCCESS(urMemBufferCreate(this->context, UR_MEM_FLAG_READ_WRITE, + size, nullptr, &buffer)); + } + + void TearDown() override { + if (buffer) { + EXPECT_SUCCESS(urMemRelease(buffer)); + } + UUR_RETURN_ON_FATAL_FAILURE( + urQueueTestWithParam::TearDown()); + } + + void verifyData(std::vector &output, size_t verify_size) { + size_t pattern_index = 0; + for (size_t i = 0; i < verify_size; ++i) { + ASSERT_EQ(output[i], pattern[pattern_index]) + << "Result mismatch at index: " << i; + + ++pattern_index; + if (pattern_index % pattern_size == 0) { + pattern_index = 0; + } + } + } + + ur_mem_handle_t buffer = nullptr; + std::vector pattern; + size_t size; + size_t pattern_size; +}; + +static std::vector test_cases{ + /* Everything set to 1 */ + {1, 1}, + /* pattern_size == size */ + {256, 256}, + /* pattern_size < size */ + {1024, 256}, + /* pattern sizes corresponding to some common scalar and vector types */ + {256, 4}, + {256, 8}, + {256, 16}, + {256, 32}}; + +UUR_TEST_SUITE_P(urEnqueueMemBufferFillTest, testing::ValuesIn(test_cases), + printFillTestString); TEST_P(urEnqueueMemBufferFillTest, Success) { - const uint32_t pattern = 0xdeadbeef; - ASSERT_SUCCESS(urEnqueueMemBufferFill(queue, buffer, &pattern, - sizeof(pattern), 0, size, 0, nullptr, + ASSERT_SUCCESS(urEnqueueMemBufferFill(queue, buffer, pattern.data(), + pattern_size, 0, size, 0, nullptr, nullptr)); - std::vector output(count, 1); + std::vector output(size, 1); ASSERT_SUCCESS(urEnqueueMemBufferRead(queue, buffer, true, 0, size, output.data(), 0, nullptr, nullptr)); - for (unsigned i = 0; i < count; ++i) { - ASSERT_EQ(output[i], pattern) << "Result mismatch at index: " << i; - } + verifyData(output, size); } - TEST_P(urEnqueueMemBufferFillTest, SuccessPartialFill) { - const std::vector input(count, 42); + if (size == 1) { + // Can't partially fill one byte + GTEST_SKIP(); + } + const std::vector input(size, 0); ASSERT_SUCCESS(urEnqueueMemBufferWrite(queue, buffer, true, 0, size, input.data(), 0, nullptr, nullptr)); - const uint32_t pattern = 0xdeadbeef; const size_t partial_fill_size = size / 2; - const size_t fill_count = count / 2; - ASSERT_SUCCESS(urEnqueueMemBufferFill(queue, buffer, &pattern, - sizeof(pattern), 0, partial_fill_size, - 0, nullptr, nullptr)); - std::vector output(count, 1); + // Make sure we don't end up with pattern_size > size + pattern_size = pattern_size / 2; + ASSERT_SUCCESS(urEnqueueMemBufferFill(queue, buffer, pattern.data(), + pattern_size, 0, partial_fill_size, 0, + nullptr, nullptr)); + std::vector output(size, 1); ASSERT_SUCCESS(urEnqueueMemBufferRead(queue, buffer, true, 0, size, output.data(), 0, nullptr, nullptr)); - for (size_t i = 0; i < count - fill_count; ++i) { - ASSERT_EQ(output[i], pattern) << "Result mismatch at index: " << i; - } + // Check the first half matches the pattern and the second half remains untouched. + verifyData(output, partial_fill_size); - for (size_t i = fill_count; i < count; ++i) { - ASSERT_EQ(output[i], 42) << "Result mismatch at index: " << i; + for (size_t i = partial_fill_size; i < size; ++i) { + ASSERT_EQ(output[i], input[i]) << "Result mismatch at index: " << i; } } TEST_P(urEnqueueMemBufferFillTest, SuccessOffset) { - const std::vector input(count, 42); + if (size == 1) { + // No room for an offset + GTEST_SKIP(); + } + const std::vector input(size, 0); ASSERT_SUCCESS(urEnqueueMemBufferWrite(queue, buffer, true, 0, size, input.data(), 0, nullptr, nullptr)); - const uint32_t pattern = 0xdeadbeef; + const size_t offset_size = size / 2; - const size_t offset_count = count / 2; - ASSERT_SUCCESS(urEnqueueMemBufferFill(queue, buffer, &pattern, - sizeof(pattern), offset_size, + // Make sure we don't end up with pattern_size > size + pattern_size = pattern_size / 2; + ASSERT_SUCCESS(urEnqueueMemBufferFill(queue, buffer, pattern.data(), + pattern_size, offset_size, offset_size, 0, nullptr, nullptr)); - std::vector output(count, 1); - ASSERT_SUCCESS(urEnqueueMemBufferRead(queue, buffer, true, 0, size, - output.data(), 0, nullptr, nullptr)); - for (size_t i = 0; i < offset_count; ++i) { - ASSERT_EQ(output[i], 42) << "Result mismatch at index: " << i; - } - for (size_t i = offset_count; i < count; ++i) { - ASSERT_EQ(output[i], pattern) << "Result mismatch at index: " << i; + // Check the second half matches the pattern and the first half remains untouched. + std::vector output(offset_size); + ASSERT_SUCCESS(urEnqueueMemBufferRead(queue, buffer, true, offset_size, + offset_size, output.data(), 0, + nullptr, nullptr)); + verifyData(output, offset_size); + + ASSERT_SUCCESS(urEnqueueMemBufferRead(queue, buffer, true, 0, offset_size, + output.data(), 0, nullptr, nullptr)); + for (size_t i = 0; i < offset_size; ++i) { + ASSERT_EQ(output[i], input[i]) << "Result mismatch at index: " << i; } } -TEST_P(urEnqueueMemBufferFillTest, InvalidNullHandleQueue) { +using urEnqueueMemBufferFillNegativeTest = uur::urMemBufferQueueTest; + +UUR_INSTANTIATE_DEVICE_TEST_SUITE_P(urEnqueueMemBufferFillNegativeTest); + +TEST_P(urEnqueueMemBufferFillNegativeTest, InvalidNullHandleQueue) { const uint32_t pattern = 0xdeadbeef; ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE, urEnqueueMemBufferFill(nullptr, buffer, &pattern, @@ -72,7 +154,7 @@ TEST_P(urEnqueueMemBufferFillTest, InvalidNullHandleQueue) { nullptr, nullptr)); } -TEST_P(urEnqueueMemBufferFillTest, InvalidNullHandleBuffer) { +TEST_P(urEnqueueMemBufferFillNegativeTest, InvalidNullHandleBuffer) { const uint32_t pattern = 0xdeadbeef; ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE, urEnqueueMemBufferFill(queue, nullptr, &pattern, @@ -80,14 +162,14 @@ TEST_P(urEnqueueMemBufferFillTest, InvalidNullHandleBuffer) { nullptr, nullptr)); } -TEST_P(urEnqueueMemBufferFillTest, InvalidNullHandlePointerPattern) { +TEST_P(urEnqueueMemBufferFillNegativeTest, InvalidNullHandlePointerPattern) { ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_POINTER, urEnqueueMemBufferFill(queue, buffer, nullptr, sizeof(uint32_t), 0, size, 0, nullptr, nullptr)); } -TEST_P(urEnqueueMemBufferFillTest, InvalidNullPtrEventWaitList) { +TEST_P(urEnqueueMemBufferFillNegativeTest, InvalidNullPtrEventWaitList) { const uint32_t pattern = 0xdeadbeef; ASSERT_EQ_RESULT(urEnqueueMemBufferFill(queue, buffer, &pattern, sizeof(uint32_t), 0, size, 1, @@ -103,7 +185,7 @@ TEST_P(urEnqueueMemBufferFillTest, InvalidNullPtrEventWaitList) { UR_RESULT_ERROR_INVALID_EVENT_WAIT_LIST); } -TEST_P(urEnqueueMemBufferFillTest, InvalidSize) { +TEST_P(urEnqueueMemBufferFillNegativeTest, InvalidSize) { const uint32_t pattern = 0xdeadbeef; ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_SIZE, urEnqueueMemBufferFill(queue, buffer, &pattern, diff --git a/test/conformance/enqueue/urEnqueueUSMFill.cpp b/test/conformance/enqueue/urEnqueueUSMFill.cpp index 79c86e6953..e595056035 100644 --- a/test/conformance/enqueue/urEnqueueUSMFill.cpp +++ b/test/conformance/enqueue/urEnqueueUSMFill.cpp @@ -3,7 +3,6 @@ // See LICENSE.TXT // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include #include struct testParametersFill { @@ -34,7 +33,7 @@ struct urEnqueueUSMFillTestWithParam host_mem = std::vector(size); pattern_size = std::get<1>(GetParam()).pattern_size; pattern = std::vector(pattern_size); - generatePattern(); + uur::generateMemFillPattern(pattern); ur_device_usm_access_capability_flags_t device_usm = 0; ASSERT_SUCCESS(uur::GetDeviceUSMDeviceSupport(device, device_usm)); @@ -54,19 +53,6 @@ struct urEnqueueUSMFillTestWithParam UUR_RETURN_ON_FATAL_FAILURE(urQueueTestWithParam::TearDown()); } - void generatePattern() { - - const size_t seed = 1; - std::mt19937 mersenne_engine{seed}; - std::uniform_int_distribution dist{0, 255}; - - auto gen = [&dist, &mersenne_engine]() { - return static_cast(dist(mersenne_engine)); - }; - - std::generate(begin(pattern), end(pattern), gen); - } - void verifyData() { ASSERT_SUCCESS(urEnqueueUSMMemcpy(queue, true, host_mem.data(), ptr, size, 0, nullptr, nullptr)); @@ -98,7 +84,11 @@ static std::vector test_cases{ {256, 256}, /* pattern_size < size */ {1024, 256}, -}; + /* pattern sizes corresponding to some common scalar and vector types */ + {256, 4}, + {256, 8}, + {256, 16}, + {256, 32}}; UUR_TEST_SUITE_P(urEnqueueUSMFillTestWithParam, testing::ValuesIn(test_cases), printFillTestString); diff --git a/test/conformance/enqueue/urEnqueueUSMFill2D.cpp b/test/conformance/enqueue/urEnqueueUSMFill2D.cpp index ed870ee5fd..9cd5bc7591 100644 --- a/test/conformance/enqueue/urEnqueueUSMFill2D.cpp +++ b/test/conformance/enqueue/urEnqueueUSMFill2D.cpp @@ -38,7 +38,7 @@ struct urEnqueueUSMFill2DTestWithParam height = std::get<1>(GetParam()).height; pattern_size = std::get<1>(GetParam()).pattern_size; pattern = std::vector(pattern_size); - generatePattern(); + uur::generateMemFillPattern(pattern); allocation_size = pitch * height; host_mem = std::vector(allocation_size); @@ -60,19 +60,6 @@ struct urEnqueueUSMFill2DTestWithParam UUR_RETURN_ON_FATAL_FAILURE(urQueueTestWithParam::TearDown()); } - void generatePattern() { - - const size_t seed = 1; - std::mt19937 mersenne_engine{seed}; - std::uniform_int_distribution dist{0, 255}; - - auto gen = [&dist, &mersenne_engine]() { - return static_cast(dist(mersenne_engine)); - }; - - std::generate(begin(pattern), end(pattern), gen); - } - void verifyData() { ASSERT_SUCCESS(urEnqueueUSMMemcpy2D(queue, true, host_mem.data(), pitch, ptr, pitch, width, height, 0, diff --git a/test/conformance/testing/include/uur/fixtures.h b/test/conformance/testing/include/uur/fixtures.h index 7765e00ade..6aebee0f40 100644 --- a/test/conformance/testing/include/uur/fixtures.h +++ b/test/conformance/testing/include/uur/fixtures.h @@ -11,6 +11,8 @@ #include #include +#include + #define UUR_RETURN_ON_FATAL_FAILURE(...) \ __VA_ARGS__; \ if (this->HasFatalFailure() || this->IsSkipped()) { \ @@ -846,6 +848,19 @@ struct urUSMDeviceAllocTestWithParam : urQueueTestWithParam { void *ptr = nullptr; }; +// Generates a random byte pattern for MemFill type entry-points. +inline void generateMemFillPattern(std::vector &pattern) { + const size_t seed = 1; + std::mt19937 mersenne_engine{seed}; + std::uniform_int_distribution dist{0, 255}; + + auto gen = [&dist, &mersenne_engine]() { + return static_cast(dist(mersenne_engine)); + }; + + std::generate(begin(pattern), end(pattern), gen); +} + /// @brief /// @tparam T /// @param info