mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
Added object comparability verification for context devices query (#2176)
Fixes #1485 according to work plan, point `CL_CONTEXT_DEVICES`
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|||||||
Reference in New Issue
Block a user