diff options
author | Michal Babej <franz@users.noreply.github.com> | 2023-10-10 19:22:50 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-10 09:22:50 -0700 |
commit | af2710355db1ce873f8ea79b16e576abcbab6666 (patch) | |
tree | 188f3f50f432c4bb0f7dadd4646568423e9faad9 | |
parent | a7c33f8dc47ec3f1869a94284d3fbb15a3eacc13 (diff) | |
download | OpenCL-CTS-af2710355db1ce873f8ea79b16e576abcbab6666.tar.gz |
add tests for clCommandSVMMemcpyKHR & clCommandSVMMemfillKHR (#1821)
* add tests for clCommandSVMMemcpyKHR & clCommandSVMMemfillKHR
* Fix typo SVMMemfill -> SVMMemFill
* fix clCommandSVMMemFillKHR calls to match extension
* add Khronos license + minor fixes
* review fixes
10 files changed, 342 insertions, 11 deletions
diff --git a/test_common/harness/typeWrappers.h b/test_common/harness/typeWrappers.h index 50c7c938..ad11b480 100644 --- a/test_common/harness/typeWrappers.h +++ b/test_common/harness/typeWrappers.h @@ -145,6 +145,48 @@ using clSamplerWrapper = using clEventWrapper = wrapper_details::Wrapper<cl_event, clRetainEvent, clReleaseEvent>; +class clSVMWrapper { + void *Ptr = nullptr; + cl_context Ctx = nullptr; + +public: + clSVMWrapper() = default; + + clSVMWrapper(cl_context C, size_t Size, + cl_svm_mem_flags F = CL_MEM_READ_WRITE) + : Ctx(C) + { + Ptr = clSVMAlloc(C, F, Size, 0); + } + + clSVMWrapper &operator=(void *other) = delete; + clSVMWrapper(clSVMWrapper const &other) = delete; + clSVMWrapper &operator=(clSVMWrapper const &other) = delete; + clSVMWrapper(clSVMWrapper &&other) + { + Ptr = other.Ptr; + Ctx = other.Ctx; + other.Ptr = nullptr; + other.Ctx = nullptr; + } + clSVMWrapper &operator=(clSVMWrapper &&other) + { + Ptr = other.Ptr; + Ctx = other.Ctx; + other.Ptr = nullptr; + other.Ctx = nullptr; + return *this; + } + + ~clSVMWrapper() + { + if (Ptr) clSVMFree(Ctx, Ptr); + } + + void *operator()() const { return Ptr; } +}; + + class clProtectedImage { public: clProtectedImage() diff --git a/test_conformance/extensions/cl_khr_command_buffer/CMakeLists.txt b/test_conformance/extensions/cl_khr_command_buffer/CMakeLists.txt index be5fd1c9..8a4a116a 100644 --- a/test_conformance/extensions/cl_khr_command_buffer/CMakeLists.txt +++ b/test_conformance/extensions/cl_khr_command_buffer/CMakeLists.txt @@ -3,6 +3,7 @@ set(MODULE_NAME CL_KHR_COMMAND_BUFFER) set(${MODULE_NAME}_SOURCES main.cpp basic_command_buffer.cpp + svm_command_basic.cpp command_buffer_printf.cpp command_buffer_get_command_buffer_info.cpp command_buffer_set_kernel_arg.cpp diff --git a/test_conformance/extensions/cl_khr_command_buffer/basic_command_buffer.h b/test_conformance/extensions/cl_khr_command_buffer/basic_command_buffer.h index 44f4cc63..d08a11af 100644 --- a/test_conformance/extensions/cl_khr_command_buffer/basic_command_buffer.h +++ b/test_conformance/extensions/cl_khr_command_buffer/basic_command_buffer.h @@ -34,6 +34,18 @@ } \ } +// If it is supported get the addresses of all the APIs here. +#define GET_EXTENSION_ADDRESS(FUNC) \ + FUNC = reinterpret_cast<FUNC##_fn>( \ + clGetExtensionFunctionAddressForPlatform(platform, #FUNC)); \ + if (FUNC == nullptr) \ + { \ + log_error("ERROR: clGetExtensionFunctionAddressForPlatform failed" \ + " with " #FUNC "\n"); \ + return TEST_FAIL; \ + } + + // Helper test fixture for constructing OpenCL objects used in testing // a variety of simple command-buffer enqueue scenarios. struct BasicCommandBufferTest : CommandBufferTestBase @@ -70,6 +82,7 @@ protected: clCommandBufferWrapper command_buffer; }; + template <class T> int MakeAndRunTest(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements) diff --git a/test_conformance/extensions/cl_khr_command_buffer/cl_khr_command_buffer_mutable_dispatch/mutable_command_basic.h b/test_conformance/extensions/cl_khr_command_buffer/cl_khr_command_buffer_mutable_dispatch/mutable_command_basic.h index c88c14d1..19147556 100644 --- a/test_conformance/extensions/cl_khr_command_buffer/cl_khr_command_buffer_mutable_dispatch/mutable_command_basic.h +++ b/test_conformance/extensions/cl_khr_command_buffer/cl_khr_command_buffer_mutable_dispatch/mutable_command_basic.h @@ -19,17 +19,6 @@ #include "../basic_command_buffer.h" #include "../command_buffer_test_base.h" -// If it is supported get the addresses of all the APIs here. -#define GET_EXTENSION_ADDRESS(FUNC) \ - FUNC = reinterpret_cast<FUNC##_fn>( \ - clGetExtensionFunctionAddressForPlatform(platform, #FUNC)); \ - if (FUNC == nullptr) \ - { \ - log_error("ERROR: clGetExtensionFunctionAddressForPlatform failed" \ - " with " #FUNC "\n"); \ - return TEST_FAIL; \ - } - struct BasicMutableCommandBufferTest : BasicCommandBufferTest { BasicMutableCommandBufferTest(cl_device_id device, cl_context context, diff --git a/test_conformance/extensions/cl_khr_command_buffer/command_buffer_test_copy.cpp b/test_conformance/extensions/cl_khr_command_buffer/command_buffer_test_copy.cpp index 7a1f0e6d..0a30e76b 100644 --- a/test_conformance/extensions/cl_khr_command_buffer/command_buffer_test_copy.cpp +++ b/test_conformance/extensions/cl_khr_command_buffer/command_buffer_test_copy.cpp @@ -14,6 +14,7 @@ // limitations under the License. // #include "basic_command_buffer.h" +#include "svm_command_basic.h" #include "harness/typeWrappers.h" #include "procs.h" @@ -197,6 +198,74 @@ struct CopyBufferKHR : public BasicCommandBufferTest const cl_char pattern_2 = 0x28; }; +struct CopySVMBufferKHR : public BasicSVMCommandBufferTest +{ + using BasicSVMCommandBufferTest::BasicSVMCommandBufferTest; + + cl_int Run() override + { + cl_int error = clCommandSVMMemFillKHR( + command_buffer, nullptr, svm_in_mem(), &pattern_1, sizeof(cl_char), + data_size(), 0, nullptr, nullptr, nullptr); + test_error(error, "clCommandSVMMemFillKHR failed"); + + error = clCommandSVMMemcpyKHR(command_buffer, nullptr, svm_out_mem(), + svm_in_mem(), data_size(), 0, nullptr, + nullptr, nullptr); + test_error(error, "clCommandSVMMemcpyKHR failed"); + + error = clFinalizeCommandBufferKHR(command_buffer); + test_error(error, "clFinalizeCommandBufferKHR failed"); + + error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, + nullptr, nullptr); + test_error(error, "clEnqueueCommandBufferKHR failed"); + + std::vector<cl_char> output_data_1(data_size()); + error = + clEnqueueSVMMemcpy(queue, CL_TRUE, output_data_1.data(), + svm_out_mem(), data_size(), 0, nullptr, nullptr); + test_error(error, "clEnqueueSVMMemcpy failed"); + + for (size_t i = 0; i < data_size(); i++) + { + CHECK_VERIFICATION_ERROR(pattern_1, output_data_1[i], i); + } + + /* Check second enqueue of command buffer */ + error = clEnqueueSVMMemFill(queue, svm_in_mem(), &pattern_2, + sizeof(cl_char), data_size(), 0, nullptr, + nullptr); + test_error(error, "clEnqueueSVMMemFill failed"); + + error = clEnqueueSVMMemFill(queue, svm_out_mem(), &pattern_2, + sizeof(cl_char), data_size(), 0, nullptr, + nullptr); + test_error(error, "clEnqueueSVMMemFill failed"); + + error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, + nullptr, nullptr); + test_error(error, "clEnqueueCommandBufferKHR failed"); + + std::vector<cl_char> output_data_2(data_size()); + + error = + clEnqueueSVMMemcpy(queue, CL_TRUE, output_data_2.data(), + svm_out_mem(), data_size(), 0, nullptr, nullptr); + test_error(error, "clEnqueueSVMMemcpy failed"); + + for (size_t i = 0; i < data_size(); i++) + { + CHECK_VERIFICATION_ERROR(pattern_1, output_data_2[i], i); + } + + return CL_SUCCESS; + } + + const cl_char pattern_1 = 0x14; + const cl_char pattern_2 = 0x28; +}; + struct CopyBufferToImageKHR : public BasicCommandBufferTest { using BasicCommandBufferTest::BasicCommandBufferTest; @@ -510,6 +579,14 @@ int test_copy_buffer(cl_device_id device, cl_context context, return MakeAndRunTest<CopyBufferKHR>(device, context, queue, num_elements); } +int test_copy_svm_buffer(cl_device_id device, cl_context context, + cl_command_queue queue, int num_elements) +{ + return MakeAndRunTest<CopySVMBufferKHR>(device, context, queue, + num_elements); +} + + int test_copy_buffer_to_image(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements) { diff --git a/test_conformance/extensions/cl_khr_command_buffer/command_buffer_test_fill.cpp b/test_conformance/extensions/cl_khr_command_buffer/command_buffer_test_fill.cpp index 0ba8055a..67809cfb 100644 --- a/test_conformance/extensions/cl_khr_command_buffer/command_buffer_test_fill.cpp +++ b/test_conformance/extensions/cl_khr_command_buffer/command_buffer_test_fill.cpp @@ -14,6 +14,7 @@ // limitations under the License. // #include "basic_command_buffer.h" +#include "svm_command_basic.h" #include "harness/typeWrappers.h" #include "procs.h" @@ -171,6 +172,64 @@ struct FillBufferKHR : public BasicCommandBufferTest const char pattern_2 = 0x30; }; +struct FillSVMBufferKHR : public BasicSVMCommandBufferTest +{ + using BasicSVMCommandBufferTest::BasicSVMCommandBufferTest; + + cl_int Run() override + { + cl_int error = clCommandSVMMemFillKHR( + command_buffer, nullptr, svm_in_mem(), &pattern_1, sizeof(cl_char), + data_size(), 0, nullptr, nullptr, nullptr); + test_error(error, "clCommandSVMMemFillKHR failed"); + + error = clFinalizeCommandBufferKHR(command_buffer); + test_error(error, "clFinalizeCommandBufferKHR failed"); + + error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, + nullptr, nullptr); + test_error(error, "clEnqueueCommandBufferKHR failed"); + + std::vector<cl_char> output_data_1(data_size()); + + error = + clEnqueueSVMMemcpy(queue, CL_TRUE, output_data_1.data(), + svm_in_mem(), data_size(), 0, nullptr, nullptr); + test_error(error, "clEnqueueSVMMemcpy failed"); + + for (size_t i = 0; i < data_size(); i++) + { + CHECK_VERIFICATION_ERROR(pattern_1, output_data_1[i], i); + } + + /* Check second enqueue of command buffer */ + error = clEnqueueSVMMemFill(queue, svm_in_mem(), &pattern_2, + sizeof(cl_char), data_size(), 0, nullptr, + nullptr); + test_error(error, "clEnqueueSVMMemFill failed"); + + error = clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, + nullptr, nullptr); + test_error(error, "clEnqueueCommandBufferKHR failed"); + + std::vector<cl_char> output_data_2(data_size()); + + error = + clEnqueueSVMMemcpy(queue, CL_TRUE, output_data_2.data(), + svm_in_mem(), data_size(), 0, nullptr, nullptr); + test_error(error, "clEnqueueSVMMemcpy failed"); + + for (size_t i = 0; i < data_size(); i++) + { + CHECK_VERIFICATION_ERROR(pattern_1, output_data_2[i], i); + } + + return CL_SUCCESS; + } + + const char pattern_1 = 0x15; + const char pattern_2 = 0x30; +}; }; int test_fill_buffer(cl_device_id device, cl_context context, @@ -179,6 +238,14 @@ int test_fill_buffer(cl_device_id device, cl_context context, return MakeAndRunTest<FillBufferKHR>(device, context, queue, num_elements); } +int test_fill_svm_buffer(cl_device_id device, cl_context context, + cl_command_queue queue, int num_elements) +{ + return MakeAndRunTest<FillSVMBufferKHR>(device, context, queue, + num_elements); +} + + int test_fill_image(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements) { diff --git a/test_conformance/extensions/cl_khr_command_buffer/main.cpp b/test_conformance/extensions/cl_khr_command_buffer/main.cpp index 3e923f6c..4ecb0806 100644 --- a/test_conformance/extensions/cl_khr_command_buffer/main.cpp +++ b/test_conformance/extensions/cl_khr_command_buffer/main.cpp @@ -45,8 +45,10 @@ test_definition test_list[] = { ADD_TEST(simultaneous_queue_substitution), ADD_TEST(fill_image), ADD_TEST(fill_buffer), + ADD_TEST(fill_svm_buffer), ADD_TEST(copy_image), ADD_TEST(copy_buffer), + ADD_TEST(copy_svm_buffer), ADD_TEST(copy_buffer_to_image), ADD_TEST(copy_image_to_buffer), ADD_TEST(copy_buffer_rect), diff --git a/test_conformance/extensions/cl_khr_command_buffer/procs.h b/test_conformance/extensions/cl_khr_command_buffer/procs.h index cd839cbb..ce121cea 100644 --- a/test_conformance/extensions/cl_khr_command_buffer/procs.h +++ b/test_conformance/extensions/cl_khr_command_buffer/procs.h @@ -103,10 +103,14 @@ extern int test_fill_image(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements); extern int test_fill_buffer(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements); +extern int test_fill_svm_buffer(cl_device_id device, cl_context context, + cl_command_queue queue, int num_elements); extern int test_copy_image(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements); extern int test_copy_buffer(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements); +extern int test_copy_svm_buffer(cl_device_id device, cl_context context, + cl_command_queue queue, int num_elements); extern int test_copy_buffer_to_image(cl_device_id device, cl_context context, cl_command_queue queue, int num_elements); extern int test_copy_image_to_buffer(cl_device_id device, cl_context context, diff --git a/test_conformance/extensions/cl_khr_command_buffer/svm_command_basic.cpp b/test_conformance/extensions/cl_khr_command_buffer/svm_command_basic.cpp new file mode 100644 index 00000000..1fc48ce5 --- /dev/null +++ b/test_conformance/extensions/cl_khr_command_buffer/svm_command_basic.cpp @@ -0,0 +1,94 @@ +// +// Copyright (c) 2023 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "svm_command_basic.h" + +//-------------------------------------------------------------------------- + +bool BasicSVMCommandBufferTest::Skip() +{ + if (BasicCommandBufferTest::Skip()) return true; + + Version version = get_device_cl_version(device); + if (version < Version(2, 0)) + { + log_info("test requires OpenCL 2.x/3.0 device"); + return true; + } + + cl_device_svm_capabilities svm_capabilities; + cl_int error = + clGetDeviceInfo(device, CL_DEVICE_SVM_CAPABILITIES, + sizeof(svm_capabilities), &svm_capabilities, NULL); + if (error != CL_SUCCESS) + { + print_error(error, "Unable to query CL_DEVICE_SVM_CAPABILITIES"); + return true; + } + + if (svm_capabilities == 0) + { + log_info("Device property CL_DEVICE_SVM_COARSE_GRAIN_BUFFER not " + "supported \n"); + return true; + } + + if (init_extension_functions() != CL_SUCCESS) + { + log_error("Unable to initialise extension functions"); + return true; + } + + return false; +} + +//-------------------------------------------------------------------------- + +cl_int BasicSVMCommandBufferTest::SetUpKernelArgs(void) +{ + size_t size = sizeof(cl_int) * num_elements * buffer_size_multiplier; + svm_in_mem = clSVMWrapper(context, size); + if (svm_in_mem() == nullptr) + { + log_error("Unable to allocate SVM memory"); + return CL_OUT_OF_RESOURCES; + } + svm_out_mem = clSVMWrapper(context, size); + if (svm_out_mem() == nullptr) + { + log_error("Unable to allocate SVM memory"); + return CL_OUT_OF_RESOURCES; + } + return CL_SUCCESS; +} + +//-------------------------------------------------------------------------- + +cl_int BasicSVMCommandBufferTest::init_extension_functions() +{ + cl_int error = BasicCommandBufferTest::init_extension_functions(); + test_error(error, "Unable to initialise extension functions"); + + cl_platform_id platform; + error = clGetDeviceInfo(device, CL_DEVICE_PLATFORM, sizeof(cl_platform_id), + &platform, nullptr); + test_error(error, "clGetDeviceInfo for CL_DEVICE_PLATFORM failed"); + + GET_EXTENSION_ADDRESS(clCommandSVMMemFillKHR); + GET_EXTENSION_ADDRESS(clCommandSVMMemcpyKHR); + + return CL_SUCCESS; +} diff --git a/test_conformance/extensions/cl_khr_command_buffer/svm_command_basic.h b/test_conformance/extensions/cl_khr_command_buffer/svm_command_basic.h new file mode 100644 index 00000000..f6b6b427 --- /dev/null +++ b/test_conformance/extensions/cl_khr_command_buffer/svm_command_basic.h @@ -0,0 +1,42 @@ +// +// Copyright (c) 2023 The Khronos Group Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef CL_KHR_SVM_COMMAND_BASIC_H +#define CL_KHR_SVM_COMMAND_BASIC_H + +#include "basic_command_buffer.h" + + +struct BasicSVMCommandBufferTest : BasicCommandBufferTest +{ + BasicSVMCommandBufferTest(cl_device_id device, cl_context context, + cl_command_queue queue) + : BasicCommandBufferTest(device, context, queue) + {} + + virtual bool Skip() override; + virtual cl_int SetUpKernelArgs(void) override; + +protected: + cl_int init_extension_functions(); + + clCommandSVMMemFillKHR_fn clCommandSVMMemFillKHR = nullptr; + clCommandSVMMemcpyKHR_fn clCommandSVMMemcpyKHR = nullptr; + + clSVMWrapper svm_in_mem, svm_out_mem; +}; + +#endif |