mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-26 08:49:02 +00:00
Ensure that test_preprocessors checks __OPENCL_C_VERSION__ correctly for CL 3.0 contexts. (#938)
This commit is contained in:
@@ -1584,43 +1584,8 @@ int printDeviceHeader( cl_device_id device )
|
|||||||
|
|
||||||
Version get_device_cl_c_version(cl_device_id device)
|
Version get_device_cl_c_version(cl_device_id device)
|
||||||
{
|
{
|
||||||
// Get the device OpenCL version.
|
|
||||||
auto device_cl_version = get_device_cl_version(device);
|
auto device_cl_version = get_device_cl_version(device);
|
||||||
|
|
||||||
// If the device version >= 3.0 it must support the
|
|
||||||
// CL_DEVICE_OPENCL_C_ALL_VERSIONS query from which we can extract the most
|
|
||||||
// recent CL C version supported by the device.
|
|
||||||
if (device_cl_version >= Version{ 3, 0 })
|
|
||||||
{
|
|
||||||
size_t opencl_c_all_versions_size_in_bytes{};
|
|
||||||
auto error =
|
|
||||||
clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_ALL_VERSIONS, 0, nullptr,
|
|
||||||
&opencl_c_all_versions_size_in_bytes);
|
|
||||||
test_error_ret(
|
|
||||||
error, "clGetDeviceInfo failed for CL_DEVICE_OPENCL_C_ALL_VERSIONS",
|
|
||||||
(Version{ -1, 0 }));
|
|
||||||
std::vector<cl_name_version> name_versions(
|
|
||||||
opencl_c_all_versions_size_in_bytes / sizeof(cl_name_version));
|
|
||||||
error = clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_ALL_VERSIONS,
|
|
||||||
opencl_c_all_versions_size_in_bytes,
|
|
||||||
name_versions.data(), nullptr);
|
|
||||||
test_error_ret(
|
|
||||||
error, "clGetDeviceInfo failed for CL_DEVICE_OPENCL_C_ALL_VERSIONS",
|
|
||||||
(Version{ -1, 0 }));
|
|
||||||
|
|
||||||
Version max_supported_cl_c_version{};
|
|
||||||
for (const auto &name_version : name_versions)
|
|
||||||
{
|
|
||||||
Version current_version{ CL_VERSION_MAJOR(name_version.version),
|
|
||||||
CL_VERSION_MINOR(name_version.version) };
|
|
||||||
max_supported_cl_c_version =
|
|
||||||
(current_version > max_supported_cl_c_version)
|
|
||||||
? current_version
|
|
||||||
: max_supported_cl_c_version;
|
|
||||||
}
|
|
||||||
return max_supported_cl_c_version;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The second special case is OpenCL-1.0 where CL_DEVICE_OPENCL_C_VERSION
|
// The second special case is OpenCL-1.0 where CL_DEVICE_OPENCL_C_VERSION
|
||||||
// did not exist, but since this is just the first version we can
|
// did not exist, but since this is just the first version we can
|
||||||
// return 1.0.
|
// return 1.0.
|
||||||
@@ -1656,6 +1621,47 @@ Version get_device_cl_c_version(cl_device_id device)
|
|||||||
return Version{ major - '0', minor - '0' };
|
return Version{ major - '0', minor - '0' };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Version get_device_latest_cl_c_version(cl_device_id device)
|
||||||
|
{
|
||||||
|
auto device_cl_version = get_device_cl_version(device);
|
||||||
|
|
||||||
|
// If the device version >= 3.0 it must support the
|
||||||
|
// CL_DEVICE_OPENCL_C_ALL_VERSIONS query from which we can extract the most
|
||||||
|
// recent CL C version supported by the device.
|
||||||
|
if (device_cl_version >= Version{ 3, 0 })
|
||||||
|
{
|
||||||
|
size_t opencl_c_all_versions_size_in_bytes{};
|
||||||
|
auto error =
|
||||||
|
clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_ALL_VERSIONS, 0, nullptr,
|
||||||
|
&opencl_c_all_versions_size_in_bytes);
|
||||||
|
test_error_ret(
|
||||||
|
error, "clGetDeviceInfo failed for CL_DEVICE_OPENCL_C_ALL_VERSIONS",
|
||||||
|
(Version{ -1, 0 }));
|
||||||
|
std::vector<cl_name_version> name_versions(
|
||||||
|
opencl_c_all_versions_size_in_bytes / sizeof(cl_name_version));
|
||||||
|
error = clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_ALL_VERSIONS,
|
||||||
|
opencl_c_all_versions_size_in_bytes,
|
||||||
|
name_versions.data(), nullptr);
|
||||||
|
test_error_ret(
|
||||||
|
error, "clGetDeviceInfo failed for CL_DEVICE_OPENCL_C_ALL_VERSIONS",
|
||||||
|
(Version{ -1, 0 }));
|
||||||
|
|
||||||
|
Version max_supported_cl_c_version{};
|
||||||
|
for (const auto &name_version : name_versions)
|
||||||
|
{
|
||||||
|
Version current_version{ CL_VERSION_MAJOR(name_version.version),
|
||||||
|
CL_VERSION_MINOR(name_version.version) };
|
||||||
|
max_supported_cl_c_version =
|
||||||
|
(current_version > max_supported_cl_c_version)
|
||||||
|
? current_version
|
||||||
|
: max_supported_cl_c_version;
|
||||||
|
}
|
||||||
|
return max_supported_cl_c_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_device_cl_c_version(device);
|
||||||
|
}
|
||||||
|
|
||||||
Version get_max_OpenCL_C_for_context(cl_context context)
|
Version get_max_OpenCL_C_for_context(cl_context context)
|
||||||
{
|
{
|
||||||
// Get all the devices in the context and find the maximum
|
// Get all the devices in the context and find the maximum
|
||||||
@@ -1669,10 +1675,11 @@ Version get_max_OpenCL_C_for_context(cl_context context)
|
|||||||
/ sizeof(cl_device_id));
|
/ sizeof(cl_device_id));
|
||||||
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, devices_size_in_bytes,
|
error = clGetContextInfo(context, CL_CONTEXT_DEVICES, devices_size_in_bytes,
|
||||||
devices.data(), nullptr);
|
devices.data(), nullptr);
|
||||||
auto current_version = get_device_cl_c_version(devices[0]);
|
auto current_version = get_device_latest_cl_c_version(devices[0]);
|
||||||
std::for_each(std::next(devices.begin()), devices.end(),
|
std::for_each(std::next(devices.begin()), devices.end(),
|
||||||
[¤t_version](cl_device_id device) {
|
[¤t_version](cl_device_id device) {
|
||||||
auto device_version = get_device_cl_c_version(device);
|
auto device_version =
|
||||||
|
get_device_latest_cl_c_version(device);
|
||||||
// OpenCL 3.0 is not backwards compatible with 2.0.
|
// OpenCL 3.0 is not backwards compatible with 2.0.
|
||||||
// If we have 3.0 and 2.0 in the same driver we
|
// If we have 3.0 and 2.0 in the same driver we
|
||||||
// use 1.2.
|
// use 1.2.
|
||||||
@@ -1694,6 +1701,50 @@ Version get_max_OpenCL_C_for_context(cl_context context)
|
|||||||
return current_version;
|
return current_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool device_supports_cl_c_version(cl_device_id device, Version version)
|
||||||
|
{
|
||||||
|
auto device_cl_version = get_device_cl_version(device);
|
||||||
|
|
||||||
|
// In general, a device does not support an OpenCL C version if it is <=
|
||||||
|
// CL_DEVICE_OPENCL_C_VERSION AND it does not appear in the
|
||||||
|
// CL_DEVICE_OPENCL_C_ALL_VERSIONS query.
|
||||||
|
|
||||||
|
// If the device version >= 3.0 it must support the
|
||||||
|
// CL_DEVICE_OPENCL_C_ALL_VERSIONS query, and the version of OpenCL C being
|
||||||
|
// used must appear in the query result if it's <=
|
||||||
|
// CL_DEVICE_OPENCL_C_VERSION.
|
||||||
|
if (device_cl_version >= Version{ 3, 0 })
|
||||||
|
{
|
||||||
|
size_t opencl_c_all_versions_size_in_bytes{};
|
||||||
|
auto error =
|
||||||
|
clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_ALL_VERSIONS, 0, nullptr,
|
||||||
|
&opencl_c_all_versions_size_in_bytes);
|
||||||
|
test_error_ret(
|
||||||
|
error, "clGetDeviceInfo failed for CL_DEVICE_OPENCL_C_ALL_VERSIONS",
|
||||||
|
(false));
|
||||||
|
std::vector<cl_name_version> name_versions(
|
||||||
|
opencl_c_all_versions_size_in_bytes / sizeof(cl_name_version));
|
||||||
|
error = clGetDeviceInfo(device, CL_DEVICE_OPENCL_C_ALL_VERSIONS,
|
||||||
|
opencl_c_all_versions_size_in_bytes,
|
||||||
|
name_versions.data(), nullptr);
|
||||||
|
test_error_ret(
|
||||||
|
error, "clGetDeviceInfo failed for CL_DEVICE_OPENCL_C_ALL_VERSIONS",
|
||||||
|
(false));
|
||||||
|
|
||||||
|
for (const auto &name_version : name_versions)
|
||||||
|
{
|
||||||
|
Version current_version{ CL_VERSION_MAJOR(name_version.version),
|
||||||
|
CL_VERSION_MINOR(name_version.version) };
|
||||||
|
if (current_version == version)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return version <= get_device_cl_c_version(device);
|
||||||
|
}
|
||||||
|
|
||||||
bool poll_until(unsigned timeout_ms, unsigned interval_ms,
|
bool poll_until(unsigned timeout_ms, unsigned interval_ms,
|
||||||
std::function<bool()> fn)
|
std::function<bool()> fn)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -175,14 +175,21 @@ cl_device_fp_config get_default_rounding_mode( cl_device_id device );
|
|||||||
/* Prints out the standard device header for all tests given the device to print for */
|
/* Prints out the standard device header for all tests given the device to print for */
|
||||||
extern int printDeviceHeader( cl_device_id device );
|
extern int printDeviceHeader( cl_device_id device );
|
||||||
|
|
||||||
|
// Execute the CL_DEVICE_OPENCL_C_VERSION query and return the OpenCL C version
|
||||||
|
// is supported by the device.
|
||||||
|
Version get_device_cl_c_version(cl_device_id device);
|
||||||
|
|
||||||
// Gets the latest (potentially non-backward compatible) OpenCL C version
|
// Gets the latest (potentially non-backward compatible) OpenCL C version
|
||||||
// supported by the device.
|
// supported by the device.
|
||||||
Version get_device_cl_c_version(cl_device_id device);
|
Version get_device_latest_cl_c_version(cl_device_id device);
|
||||||
|
|
||||||
// Gets the maximum universally supported OpenCL C version in a context, i.e.
|
// Gets the maximum universally supported OpenCL C version in a context, i.e.
|
||||||
// the OpenCL C version supported by all devices in a context.
|
// the OpenCL C version supported by all devices in a context.
|
||||||
Version get_max_OpenCL_C_for_context(cl_context context);
|
Version get_max_OpenCL_C_for_context(cl_context context);
|
||||||
|
|
||||||
|
// Checks whether a particular OpenCL C version is supported by the device.
|
||||||
|
bool device_supports_cl_c_version(cl_device_id device, Version version);
|
||||||
|
|
||||||
// Poll fn every interval_ms until timeout_ms or it returns true
|
// Poll fn every interval_ms until timeout_ms or it returns true
|
||||||
bool poll_until(unsigned timeout_ms, unsigned interval_ms,
|
bool poll_until(unsigned timeout_ms, unsigned interval_ms,
|
||||||
std::function<bool()> fn);
|
std::function<bool()> fn);
|
||||||
|
|||||||
@@ -213,33 +213,15 @@ int test_kernel_preprocessor_macros(cl_device_id deviceID, cl_context context, c
|
|||||||
|
|
||||||
// The OpenCL version reported by the macro reports the feature level supported by the compiler. Since
|
// The OpenCL version reported by the macro reports the feature level supported by the compiler. Since
|
||||||
// this doesn't directly match any property we can query, we just check to see if it's a sane value
|
// this doesn't directly match any property we can query, we just check to see if it's a sane value
|
||||||
char versionBuffer[ 128 ];
|
auto device_cl_version = get_device_cl_version(deviceID);
|
||||||
error = clGetDeviceInfo( deviceID, CL_DEVICE_VERSION, sizeof( versionBuffer ), versionBuffer, NULL );
|
int device_cl_version_int = device_cl_version.to_int() * 10;
|
||||||
test_error( error, "Unable to get device's version to validate against" );
|
if ((results[2] < 100) || (results[2] > device_cl_version_int))
|
||||||
|
|
||||||
// We need to parse to get the version number to compare against
|
|
||||||
char *p1, *p2, *p3;
|
|
||||||
for( p1 = versionBuffer; ( *p1 != 0 ) && !isdigit( *p1 ); p1++ )
|
|
||||||
;
|
|
||||||
for( p2 = p1; ( *p2 != 0 ) && ( *p2 != '.' ); p2++ )
|
|
||||||
;
|
|
||||||
for( p3 = p2; ( *p3 != 0 ) && ( *p3 != ' ' ); p3++ )
|
|
||||||
;
|
|
||||||
|
|
||||||
if( p2 == p3 )
|
|
||||||
{
|
{
|
||||||
log_error( "ERROR: Unable to verify OpenCL version string (platform string is incorrect format)\n" );
|
log_error("ERROR: Kernel preprocessor __OPENCL_VERSION__ does not make "
|
||||||
return -1;
|
"sense w.r.t. device's version string! "
|
||||||
}
|
"(preprocessor states %d, CL_DEVICE_VERSION is %d (%s))\n",
|
||||||
*p2 = 0;
|
results[2], device_cl_version_int,
|
||||||
*p3 = 0;
|
device_cl_version.to_string().c_str());
|
||||||
int major = atoi( p1 );
|
|
||||||
int minor = atoi( p2 + 1 );
|
|
||||||
int realVersion = ( major * 100 ) + ( minor * 10 );
|
|
||||||
if( ( results[ 2 ] < 100 ) || ( results[ 2 ] > realVersion ) )
|
|
||||||
{
|
|
||||||
log_error( "ERROR: Kernel preprocessor __OPENCL_VERSION__ does not make sense w.r.t. device's version string! "
|
|
||||||
"(preprocessor states %d, real version is %d (%d.%d))\n", results[ 2 ], realVersion, major, minor );
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,33 +232,29 @@ int test_kernel_preprocessor_macros(cl_device_id deviceID, cl_context context, c
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The OpenCL C version reported by the macro reports the OpenCL C supported by the compiler for this OpenCL device.
|
// The OpenCL C version reported by the macro reports the OpenCL C version
|
||||||
char cVersionBuffer[ 128 ];
|
// specified to the compiler. We need to see whether it is supported.
|
||||||
error = clGetDeviceInfo( deviceID, CL_DEVICE_OPENCL_C_VERSION, sizeof( cVersionBuffer ), cVersionBuffer, NULL );
|
int cl_c_major_version = results[3] / 100;
|
||||||
test_error( error, "Unable to get device's OpenCL C version to validate against" );
|
int cl_c_minor_version = (results[3] / 10) % 10;
|
||||||
|
if ((results[3] < 100)
|
||||||
// We need to parse to get the version number to compare against
|
|| (!device_supports_cl_c_version(
|
||||||
for( p1 = cVersionBuffer; ( *p1 != 0 ) && !isdigit( *p1 ); p1++ )
|
deviceID, Version{ cl_c_major_version, cl_c_minor_version })))
|
||||||
;
|
|
||||||
for( p2 = p1; ( *p2 != 0 ) && ( *p2 != '.' ); p2++ )
|
|
||||||
;
|
|
||||||
for( p3 = p2; ( *p3 != 0 ) && ( *p3 != ' ' ); p3++ )
|
|
||||||
;
|
|
||||||
|
|
||||||
if( p2 == p3 )
|
|
||||||
{
|
{
|
||||||
log_error( "ERROR: Unable to verify OpenCL C version string (platform string is incorrect format)\n" );
|
auto device_version = get_device_cl_c_version(deviceID);
|
||||||
return -1;
|
log_error(
|
||||||
|
"ERROR: Kernel preprocessor __OPENCL_C_VERSION__ does not make "
|
||||||
|
"sense w.r.t. device's version string! "
|
||||||
|
"(preprocessor states %d, CL_DEVICE_OPENCL_C_VERSION is %d (%s))\n",
|
||||||
|
results[3], device_version.to_int() * 10,
|
||||||
|
device_version.to_string().c_str());
|
||||||
|
log_error("This means that CL_DEVICE_OPENCL_C_VERSION < "
|
||||||
|
"__OPENCL_C_VERSION__");
|
||||||
|
if (device_cl_version >= Version{ 3, 0 })
|
||||||
|
{
|
||||||
|
log_error(", and __OPENCL_C_VERSION__ does not appear in "
|
||||||
|
"CL_DEVICE_OPENCL_C_ALL_VERSIONS");
|
||||||
}
|
}
|
||||||
*p2 = 0;
|
log_error("\n");
|
||||||
*p3 = 0;
|
|
||||||
major = atoi( p1 );
|
|
||||||
minor = atoi( p2 + 1 );
|
|
||||||
realVersion = ( major * 100 ) + ( minor * 10 );
|
|
||||||
if( ( results[ 3 ] < 100 ) || ( results[ 3 ] > realVersion ) )
|
|
||||||
{
|
|
||||||
log_error( "ERROR: Kernel preprocessor __OPENCL_C_VERSION__ does not make sense w.r.t. device's version string! "
|
|
||||||
"(preprocessor states %d, real version is %d (%d.%d))\n", results[ 2 ], realVersion, major, minor );
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user