Added object comparability verification for context devices query (#2176)

Fixes #1485 according to work plan, point `CL_CONTEXT_DEVICES`
This commit is contained in:
Marcin Hajder
2025-02-25 17:42:09 +01:00
committed by GitHub
parent 32361e1d89
commit 0ddfbbe673
2 changed files with 168 additions and 8 deletions

View File

@@ -27,4 +27,24 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
// scope guard helper to ensure proper releasing of sub devices
struct SubDevicesScopeGuarded
{
SubDevicesScopeGuarded(const cl_int dev_count)
{
sub_devices.resize(dev_count);
}
~SubDevicesScopeGuarded()
{
for (auto &device : sub_devices)
{
cl_int err = clReleaseDevice(device);
if (err != CL_SUCCESS)
log_error("\n Releasing sub-device failed \n");
}
}
std::vector<cl_device_id> sub_devices;
};
#endif // _testBase_h #endif // _testBase_h

View File

@@ -18,8 +18,10 @@
#include "harness/propertyHelpers.h" #include "harness/propertyHelpers.h"
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <array>
#include <algorithm> #include <algorithm>
#include <cinttypes> #include <cinttypes>
#include <memory>
#include <vector> #include <vector>
REGISTER_TEST(get_platform_info) REGISTER_TEST(get_platform_info)
@@ -476,18 +478,41 @@ REGISTER_TEST(get_command_queue_info_compatibility)
REGISTER_TEST(get_context_info) REGISTER_TEST(get_context_info)
{ {
int error; int error;
// query single device context and perform object comparability test
cl_uint num_devices = 0;
error = clGetContextInfo(context, CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint),
&num_devices, nullptr);
test_error(error, "clGetContextInfo CL_CONTEXT_NUM_DEVICES failed\n");
test_assert_error(num_devices == 1,
"Context must contain exactly one device\n");
cl_device_id comp_device = nullptr;
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(cl_device_id),
&comp_device, nullptr);
test_error(error, "clGetContextInfo CL_CONTEXT_DEVICES failed\n");
test_assert_error(device == comp_device,
"Unexpected result returned by CL_CONTEXT_DEVICES query");
// query context properties against valid size
size_t size; size_t size;
cl_context_properties props; cl_context_properties props;
error = clGetContextInfo(context, CL_CONTEXT_PROPERTIES, sizeof(props),
&props, &size);
test_error(error, "Unable to get context props");
error = clGetContextInfo( context, CL_CONTEXT_PROPERTIES, sizeof( props ), &props, &size ); if (size == 0)
test_error( error, "Unable to get context props" ); {
if (size == 0) {
// Valid size // Valid size
return 0; return 0;
} else if (size == sizeof(cl_context_properties)) { }
else if (size == sizeof(cl_context_properties))
{
// Data must be NULL // Data must be NULL
if (props != 0) { if (props != 0)
{
log_error("ERROR: Returned properties is no NULL.\n"); log_error("ERROR: Returned properties is no NULL.\n");
return -1; return -1;
} }
@@ -495,11 +520,126 @@ REGISTER_TEST(get_context_info)
return 0; return 0;
} }
// Size was not 0 or 1 // Size was not 0 or 1
log_error( "ERROR: Returned size of context props is not valid! (expected 0 or %d, got %d)\n", log_error("ERROR: Returned size of context props is not valid! (expected 0 "
(int)sizeof(cl_context_properties), (int)size ); "or %d, got %d)\n",
(int)sizeof(cl_context_properties), (int)size);
return -1; return -1;
} }
REGISTER_TEST(get_context_info_mult_devices)
{
cl_int err = CL_SUCCESS;
size_t size = 0;
// query multi-device context and perform objects comparability test
err = clGetDeviceInfo(device, CL_DEVICE_PARTITION_PROPERTIES, 0, nullptr,
&size);
test_error_fail(err, "clGetDeviceInfo failed");
if (size == 0)
{
log_info("Can't partition device, test not supported\n");
return TEST_SKIPPED_ITSELF;
}
std::vector<cl_device_partition_property> supported_props(
size / sizeof(cl_device_partition_property), 0);
err = clGetDeviceInfo(device, CL_DEVICE_PARTITION_PROPERTIES,
supported_props.size()
* sizeof(cl_device_partition_property),
supported_props.data(), &size);
test_error_fail(err, "clGetDeviceInfo failed");
if (supported_props.empty() || supported_props.front() == 0)
{
log_info("Can't partition device, test not supported\n");
return TEST_SKIPPED_ITSELF;
}
cl_uint maxComputeUnits = 0;
err = clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS,
sizeof(maxComputeUnits), &maxComputeUnits, NULL);
test_error_fail(err, "Unable to get maximal number of compute units");
std::vector<std::array<cl_device_partition_property, 5>> partition_props = {
{ CL_DEVICE_PARTITION_EQUALLY, (cl_int)maxComputeUnits / 2, 0, 0, 0 },
{ CL_DEVICE_PARTITION_BY_COUNTS, 1, (cl_int)maxComputeUnits - 1,
CL_DEVICE_PARTITION_BY_COUNTS_LIST_END, 0 },
{ CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN,
CL_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE, 0, 0, 0 }
};
std::unique_ptr<SubDevicesScopeGuarded> scope_guard;
cl_uint num_devices = 0;
for (auto &sup_prop : supported_props)
{
for (auto &prop : partition_props)
{
if (sup_prop == prop[0])
{
// how many sub-devices can we create?
err = clCreateSubDevices(device, prop.data(), 0, nullptr,
&num_devices);
test_error_fail(err, "clCreateSubDevices failed");
if (num_devices < 2) continue;
// get the list of subDevices
scope_guard.reset(new SubDevicesScopeGuarded(num_devices));
err = clCreateSubDevices(device, prop.data(), num_devices,
scope_guard->sub_devices.data(),
&num_devices);
test_error_fail(err, "clCreateSubDevices failed");
break;
}
}
if (scope_guard.get() != nullptr) break;
}
if (scope_guard.get() == nullptr)
{
log_info("Can't partition device, test not supported\n");
return TEST_SKIPPED_ITSELF;
}
/* Create a multi device context */
clContextWrapper multi_device_context = clCreateContext(
NULL, (cl_uint)num_devices, scope_guard->sub_devices.data(), nullptr,
nullptr, &err);
test_error_fail(err, "Unable to create testing context");
err = clGetContextInfo(multi_device_context, CL_CONTEXT_NUM_DEVICES,
sizeof(cl_uint), &num_devices, nullptr);
test_error_fail(err, "clGetContextInfo CL_CONTEXT_NUM_DEVICES failed\n");
test_assert_error(num_devices == scope_guard->sub_devices.size(),
"Context must contain exact number of devices\n");
std::vector<cl_device_id> devices(num_devices);
err = clGetContextInfo(multi_device_context, CL_CONTEXT_DEVICES,
num_devices * sizeof(cl_device_id), devices.data(),
nullptr);
test_error_fail(err, "clGetContextInfo CL_CONTEXT_DEVICES failed\n");
test_assert_error(devices.size() == scope_guard->sub_devices.size(),
"Size of devices arrays must be in sync\n");
for (cl_uint i = 0; i < devices.size(); i++)
{
bool found = false;
for (auto &it : scope_guard->sub_devices)
{
if (it == devices[i])
{
found = true;
break;
}
}
test_error_fail(
!found, "Unexpected result returned by CL_CONTEXT_DEVICES query");
}
return TEST_PASS;
}
void CL_CALLBACK mem_obj_destructor_callback( cl_mem, void *data ) void CL_CALLBACK mem_obj_destructor_callback( cl_mem, void *data )
{ {
free( data ); free( data );