mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
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
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user