You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
753 lines
24 KiB
753 lines
24 KiB
//
|
|
// Copyright (c) 2019-2020 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 "harness/compat.h"
|
|
|
|
#include <vector>
|
|
#include <set>
|
|
#include <iterator>
|
|
#include <algorithm>
|
|
#include <cstring>
|
|
#include "harness/testHarness.h"
|
|
#include "harness/deviceInfo.h"
|
|
|
|
using name_version_set = std::set<cl_name_version_khr>;
|
|
|
|
static bool operator<(const cl_name_version_khr& lhs,
|
|
const cl_name_version_khr& rhs)
|
|
{
|
|
const int cmp = strcmp(lhs.name, rhs.name);
|
|
if (0 == cmp)
|
|
{
|
|
return lhs.version < rhs.version;
|
|
}
|
|
|
|
return cmp < 0;
|
|
}
|
|
|
|
static bool operator==(const cl_name_version_khr& lhs,
|
|
const cl_name_version_khr& rhs)
|
|
{
|
|
return (0 == strcmp(lhs.name, rhs.name)) && (lhs.version == rhs.version);
|
|
}
|
|
|
|
/* Parse major and minor version numbers out of version_string according to
|
|
* format, which is a scanf-format with two %u specifiers, then compare the
|
|
* version to the major and minor versions of version_numeric */
|
|
static bool is_same_version(const char* const format,
|
|
const char* const version_string,
|
|
const cl_version_khr version_numeric)
|
|
{
|
|
unsigned int string_major = 0;
|
|
unsigned int string_minor = 0;
|
|
const int matched =
|
|
sscanf(version_string, format, &string_major, &string_minor);
|
|
|
|
if (2 != matched)
|
|
{
|
|
log_error("sscanf() fail on version string \"%s\", format=\"%s\"\n",
|
|
version_string, format);
|
|
return false;
|
|
}
|
|
|
|
const unsigned int numeric_major = CL_VERSION_MAJOR_KHR(version_numeric);
|
|
const unsigned int numeric_minor = CL_VERSION_MINOR_KHR(version_numeric);
|
|
|
|
return (string_major == numeric_major) && (string_minor == numeric_minor);
|
|
}
|
|
|
|
static std::vector<char> get_platform_string(cl_platform_id platform,
|
|
cl_platform_info name)
|
|
{
|
|
size_t size{};
|
|
cl_int err = clGetPlatformInfo(platform, name, 0, nullptr, &size);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetPlatformInfo failed\n");
|
|
return {};
|
|
}
|
|
|
|
std::vector<char> result(size);
|
|
|
|
err = clGetPlatformInfo(platform, name, size, result.data(), nullptr);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetPlatformInfo failed\n");
|
|
return {};
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static std::vector<char> get_device_string(cl_device_id device,
|
|
cl_device_info name)
|
|
{
|
|
size_t size{};
|
|
cl_int err = clGetDeviceInfo(device, name, 0, nullptr, &size);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetDeviceInfo failed\n");
|
|
return {};
|
|
}
|
|
|
|
std::vector<char> result(size);
|
|
|
|
err = clGetDeviceInfo(device, name, size, result.data(), nullptr);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetDeviceInfo failed\n");
|
|
return {};
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/* Parse an extension string into a cl_name_version_khr set. Error out if we
|
|
* have an invalid extension string */
|
|
static bool name_version_set_from_extension_string(char* const src,
|
|
name_version_set& dest)
|
|
{
|
|
for (char* token = strtok(src, " "); nullptr != token;
|
|
token = strtok(nullptr, " "))
|
|
{
|
|
if (CL_NAME_VERSION_MAX_NAME_SIZE_KHR <= strlen(token))
|
|
{
|
|
log_error("Extension name is longer than allowed\n");
|
|
return false;
|
|
}
|
|
|
|
cl_name_version_khr name_version{};
|
|
strncpy(name_version.name, token, CL_NAME_VERSION_MAX_NAME_SIZE_KHR);
|
|
|
|
if (dest.find(name_version) != dest.cend())
|
|
{
|
|
log_error("Duplicate extension in extension string\n");
|
|
return false;
|
|
}
|
|
|
|
dest.insert(name_version);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* Parse a built-in kernels string into a cl_name_version_khr set. Error out if
|
|
* we have an invalid built-in kernels string */
|
|
static bool name_version_set_from_built_in_kernel_string(char* const src,
|
|
name_version_set& dest)
|
|
{
|
|
for (char* token = strtok(src, ";"); nullptr != token;
|
|
token = strtok(nullptr, ";"))
|
|
{
|
|
if (CL_NAME_VERSION_MAX_NAME_SIZE_KHR <= strlen(token))
|
|
{
|
|
log_error("Kernel name is longer than allowed\n");
|
|
return false;
|
|
}
|
|
|
|
cl_name_version_khr name_version{};
|
|
strncpy(name_version.name, token, CL_NAME_VERSION_MAX_NAME_SIZE_KHR);
|
|
|
|
if (dest.find(name_version) != dest.cend())
|
|
{
|
|
log_error("Duplicate kernel name in kernel string\n");
|
|
return false;
|
|
}
|
|
|
|
dest.insert(name_version);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* Helper to log the names of elements of the set difference of two
|
|
* cl_name_version_khr sets */
|
|
static void log_name_only_set_difference(const name_version_set& lhs,
|
|
const name_version_set& rhs)
|
|
{
|
|
std::vector<cl_name_version_khr> difference;
|
|
std::set_difference(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend(),
|
|
std::back_inserter(difference));
|
|
|
|
for (const cl_name_version_khr& il : difference)
|
|
{
|
|
log_info(" %s", il.name);
|
|
}
|
|
}
|
|
|
|
/* Helper to log as IL versions the elements of the set difference of two
|
|
* cl_name_version_khr sets */
|
|
static void log_il_set_difference(const name_version_set& lhs,
|
|
const name_version_set& rhs)
|
|
{
|
|
std::vector<cl_name_version_khr> difference;
|
|
std::set_difference(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend(),
|
|
std::back_inserter(difference));
|
|
|
|
for (const cl_name_version_khr& il : difference)
|
|
{
|
|
const unsigned int major = CL_VERSION_MAJOR_KHR(il.version);
|
|
const unsigned int minor = CL_VERSION_MINOR_KHR(il.version);
|
|
log_info(" %s_%u.%u", il.name, major, minor);
|
|
}
|
|
}
|
|
|
|
/* Check that CL_PLATFORM_NUMERIC_VERSION_KHR returns the same version as
|
|
* CL_PLATFORM_VERSION */
|
|
static int test_extended_versioning_platform_version(cl_platform_id platform)
|
|
{
|
|
log_info("Platform versions:\n");
|
|
|
|
const std::vector<char> version_string(
|
|
get_platform_string(platform, CL_PLATFORM_VERSION));
|
|
if (version_string.empty())
|
|
{
|
|
log_error("Could not get CL platform version string\n");
|
|
return 1;
|
|
}
|
|
|
|
cl_version_khr version_numeric{};
|
|
cl_int err =
|
|
clGetPlatformInfo(platform, CL_PLATFORM_NUMERIC_VERSION_KHR,
|
|
sizeof(version_numeric), &version_numeric, nullptr);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetPlatformInfo failed\n");
|
|
return 1;
|
|
}
|
|
|
|
if (!is_same_version("OpenCL %u.%u", version_string.data(),
|
|
version_numeric))
|
|
{
|
|
log_error(
|
|
"Numeric platform version does not match the version string\n");
|
|
return 1;
|
|
}
|
|
|
|
log_info("\tMatched the platform version\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Check that CL_DEVICE{,_OPENCL_C}_NUMERIC_VERSION_KHR return the same versions
|
|
* as CL_DEVICE{,_OPENCL_C}_VERSION */
|
|
static int test_extended_versioning_device_versions(bool ext,
|
|
cl_device_id deviceID)
|
|
{
|
|
log_info("Device versions:\n");
|
|
|
|
static constexpr struct
|
|
{
|
|
cl_platform_info param_name_numeric;
|
|
cl_platform_info param_name_string;
|
|
const char* format;
|
|
} device_version_queries[]{
|
|
{ CL_DEVICE_NUMERIC_VERSION_KHR, CL_DEVICE_VERSION, "OpenCL %u.%u" },
|
|
{ CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR, CL_DEVICE_OPENCL_C_VERSION,
|
|
"OpenCL C %u.%u" },
|
|
};
|
|
|
|
for (const auto& query : device_version_queries)
|
|
{
|
|
// CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR is only supported by
|
|
// cl_khr_extended_versioning:
|
|
if (!ext
|
|
&& query.param_name_numeric
|
|
== CL_DEVICE_OPENCL_C_NUMERIC_VERSION_KHR)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
const std::vector<char> version_string(
|
|
get_device_string(deviceID, query.param_name_string));
|
|
if (version_string.empty())
|
|
{
|
|
log_error("Could not get CL platform version string\n");
|
|
return 1;
|
|
}
|
|
|
|
cl_version_khr version_numeric{};
|
|
cl_int err =
|
|
clGetDeviceInfo(deviceID, query.param_name_numeric,
|
|
sizeof(version_numeric), &version_numeric, nullptr);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetDeviceInfo failed\n");
|
|
return 1;
|
|
}
|
|
|
|
if (!is_same_version(query.format, version_string.data(),
|
|
version_numeric))
|
|
{
|
|
log_error(
|
|
"Numeric device version does not match the version string\n");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
log_info("\tMatched the device OpenCL and OpenCL C versions\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Check that the platform extension string and name_version queries return the
|
|
* same set */
|
|
static int test_extended_versioning_platform_extensions(cl_platform_id platform)
|
|
{
|
|
log_info("Platform extensions:\n");
|
|
std::vector<char> extension_string{ get_platform_string(
|
|
platform, CL_PLATFORM_EXTENSIONS) };
|
|
if (extension_string.empty())
|
|
{
|
|
log_error("Could not get CL platform extensions string\n");
|
|
return 1;
|
|
}
|
|
|
|
size_t size{};
|
|
cl_int err = clGetPlatformInfo(
|
|
platform, CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR, 0, nullptr, &size);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetPlatformInfo failed\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((size % sizeof(cl_name_version_khr)) != 0)
|
|
{
|
|
log_error("CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR return size not a "
|
|
"multiple of sizeof(cl_name_version_khr)\n");
|
|
return 1;
|
|
}
|
|
|
|
const size_t extension_name_vers_count = size / sizeof(cl_name_version_khr);
|
|
std::vector<cl_name_version_khr> extension_name_vers(
|
|
extension_name_vers_count);
|
|
|
|
err = clGetPlatformInfo(platform, CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR,
|
|
size, extension_name_vers.data(), nullptr);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetPlatformInfo failed\n");
|
|
return 1;
|
|
}
|
|
|
|
name_version_set extension_name_vers_set;
|
|
for (const auto& extension : extension_name_vers)
|
|
{
|
|
/* Extension string doesn't have versions, so set it to all zeroes for
|
|
* matching */
|
|
cl_name_version_khr name_version = extension;
|
|
name_version.version = CL_MAKE_VERSION_KHR(0, 0, 0);
|
|
|
|
if (extension_name_vers_set.find(name_version)
|
|
!= extension_name_vers_set.cend())
|
|
{
|
|
log_error("Duplicate extension in extension name-version array\n");
|
|
return 1;
|
|
}
|
|
|
|
extension_name_vers_set.insert(name_version);
|
|
}
|
|
|
|
name_version_set extension_string_set;
|
|
if (!name_version_set_from_extension_string(extension_string.data(),
|
|
extension_string_set))
|
|
{
|
|
log_error("Failed to parse platform extension string\n");
|
|
return 1;
|
|
}
|
|
|
|
if (extension_string_set != extension_name_vers_set)
|
|
{
|
|
log_error("Platform extension mismatch\n");
|
|
|
|
log_info("\tExtensions only in numeric:");
|
|
log_name_only_set_difference(extension_name_vers_set,
|
|
extension_string_set);
|
|
log_info("\n\tExtensions only in string:");
|
|
log_name_only_set_difference(extension_string_set,
|
|
extension_name_vers_set);
|
|
log_info("\n");
|
|
|
|
return 1;
|
|
}
|
|
|
|
log_info("\tMatched %zu extensions\n", extension_name_vers_set.size());
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Check that the device extension string and name_version queries return the
|
|
* same set */
|
|
static int test_extended_versioning_device_extensions(cl_device_id device)
|
|
{
|
|
log_info("Device extensions:\n");
|
|
std::vector<char> extension_string{ get_device_string(
|
|
device, CL_DEVICE_EXTENSIONS) };
|
|
if (extension_string.empty())
|
|
{
|
|
log_error("Could not get CL device extensions string\n");
|
|
return 1;
|
|
}
|
|
|
|
size_t size{};
|
|
cl_int err = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR,
|
|
0, nullptr, &size);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetDeviceInfo failed\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((size % sizeof(cl_name_version_khr)) != 0)
|
|
{
|
|
log_error("CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR return size not a "
|
|
"multiple of sizeof(cl_name_version_khr)\n");
|
|
return 1;
|
|
}
|
|
|
|
const size_t extension_name_vers_count = size / sizeof(cl_name_version_khr);
|
|
std::vector<cl_name_version_khr> extension_name_vers(
|
|
extension_name_vers_count);
|
|
|
|
err = clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR, size,
|
|
extension_name_vers.data(), nullptr);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetDeviceInfo failed\n");
|
|
return 1;
|
|
}
|
|
|
|
name_version_set extension_name_vers_set;
|
|
for (const auto& extension : extension_name_vers)
|
|
{
|
|
/* Extension string doesn't have versions, so set it to all zeroes for
|
|
* matching */
|
|
cl_name_version_khr name_version = extension;
|
|
name_version.version = CL_MAKE_VERSION_KHR(0, 0, 0);
|
|
|
|
if (extension_name_vers_set.find(name_version)
|
|
!= extension_name_vers_set.cend())
|
|
{
|
|
log_error("Duplicate extension in extension name-version array\n");
|
|
return 1;
|
|
}
|
|
|
|
extension_name_vers_set.insert(name_version);
|
|
}
|
|
|
|
name_version_set extension_string_set;
|
|
if (!name_version_set_from_extension_string(extension_string.data(),
|
|
extension_string_set))
|
|
{
|
|
log_error("Failed to parse device extension string\n");
|
|
return 1;
|
|
}
|
|
|
|
if (extension_string_set != extension_name_vers_set)
|
|
{
|
|
log_error("Device extension mismatch\n");
|
|
|
|
log_info("\tExtensions only in numeric:");
|
|
log_name_only_set_difference(extension_name_vers_set,
|
|
extension_string_set);
|
|
log_info("\n\tExtensions only in string:");
|
|
log_name_only_set_difference(extension_string_set,
|
|
extension_name_vers_set);
|
|
log_info("\n");
|
|
|
|
return 1;
|
|
}
|
|
|
|
log_info("\tMatched %zu extensions\n", extension_name_vers_set.size());
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Check that the device ILs string and numeric queries return the same set */
|
|
static int test_extended_versioning_device_il(cl_device_id device)
|
|
{
|
|
log_info("Device ILs:\n");
|
|
|
|
size_t size{};
|
|
cl_int err = clGetDeviceInfo(device, CL_DEVICE_ILS_WITH_VERSION_KHR, 0,
|
|
nullptr, &size);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetDeviceInfo failed\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((size % sizeof(cl_name_version_khr)) != 0)
|
|
{
|
|
log_error("CL_DEVICE_ILS_WITH_VERSION_KHR return size not a multiple "
|
|
"of sizeof(cl_name_version_khr)\n");
|
|
return 1;
|
|
}
|
|
|
|
const size_t il_name_vers_count = size / sizeof(cl_name_version_khr);
|
|
std::vector<cl_name_version_khr> il_name_vers(il_name_vers_count);
|
|
|
|
err = clGetDeviceInfo(device, CL_DEVICE_ILS_WITH_VERSION_KHR, size,
|
|
il_name_vers.data(), nullptr);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetDeviceInfo failed\n");
|
|
return 1;
|
|
}
|
|
|
|
const bool has_khr_il_program =
|
|
is_extension_available(device, "cl_khr_il_program");
|
|
const bool has_core_il_program =
|
|
get_device_cl_version(device) > Version(2, 0);
|
|
|
|
// IL query should return an empty list if the device does not support IL
|
|
// programs
|
|
if (!(has_khr_il_program || has_core_il_program))
|
|
{
|
|
const bool success = il_name_vers.empty();
|
|
if (!success)
|
|
{
|
|
log_error(
|
|
"No il_program support, but CL_DEVICE_ILS_WITH_VERSION_KHR "
|
|
"returned a non-empty list\n");
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
log_info(
|
|
"\tNo il_program support, and CL_DEVICE_ILS_WITH_VERSION_KHR "
|
|
"correctly returned the empty list\n");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// Pick the core or extension version of the query parameter name
|
|
const cl_device_info il_version_param_name =
|
|
has_core_il_program ? CL_DEVICE_IL_VERSION : CL_DEVICE_IL_VERSION_KHR;
|
|
|
|
std::vector<char> il_string{ get_device_string(device,
|
|
il_version_param_name) };
|
|
if (il_string.empty())
|
|
{
|
|
log_error("Couldn't get device IL string\n");
|
|
return 1;
|
|
}
|
|
|
|
name_version_set il_string_set;
|
|
char* saveptr_outer = nullptr;
|
|
for (char* token = strtok_r(il_string.data(), " ", &saveptr_outer);
|
|
nullptr != token; token = strtok_r(nullptr, " ", &saveptr_outer))
|
|
{
|
|
char* saveptr_inner = nullptr;
|
|
const char* const prefix = strtok_r(token, "_", &saveptr_inner);
|
|
const char* const version = strtok_r(nullptr, "", &saveptr_inner);
|
|
|
|
unsigned major = 0;
|
|
unsigned minor = 0;
|
|
const int matched = sscanf(version, "%u.%u", &major, &minor);
|
|
if (2 != matched)
|
|
{
|
|
log_error("IL version string scan mismatch\n");
|
|
return 1;
|
|
}
|
|
if (CL_NAME_VERSION_MAX_NAME_SIZE_KHR <= strlen(prefix))
|
|
{
|
|
log_error("IL name longer than allowed\n");
|
|
return 1;
|
|
}
|
|
|
|
cl_name_version_khr name_version{};
|
|
strncpy(name_version.name, prefix, CL_NAME_VERSION_MAX_NAME_SIZE_KHR);
|
|
name_version.version = CL_MAKE_VERSION_KHR(major, minor, 0);
|
|
|
|
if (il_string_set.find(name_version) != il_string_set.end())
|
|
{
|
|
log_error("Duplicate IL version in IL string\n");
|
|
return 1;
|
|
}
|
|
|
|
il_string_set.insert(name_version);
|
|
}
|
|
|
|
name_version_set il_name_vers_set;
|
|
for (const auto& il : il_name_vers)
|
|
{
|
|
const unsigned major = CL_VERSION_MAJOR_KHR(il.version);
|
|
const unsigned minor = CL_VERSION_MINOR_KHR(il.version);
|
|
|
|
cl_name_version_khr name_version = il;
|
|
name_version.version = CL_MAKE_VERSION_KHR(major, minor, 0);
|
|
|
|
if (il_name_vers_set.find(name_version) != il_name_vers_set.cend())
|
|
{
|
|
log_error("Duplicate IL in name-version array\n");
|
|
return 1;
|
|
}
|
|
|
|
il_name_vers_set.insert(name_version);
|
|
}
|
|
|
|
if (il_string_set != il_name_vers_set)
|
|
{
|
|
log_error("Device IL mismatch\n");
|
|
|
|
log_info("\tILs only in numeric:");
|
|
log_il_set_difference(il_name_vers_set, il_string_set);
|
|
log_info("\n\tILs only in string:");
|
|
log_il_set_difference(il_string_set, il_name_vers_set);
|
|
log_info("\n");
|
|
|
|
return 1;
|
|
}
|
|
|
|
log_info("\tMatched %zu ILs\n", il_name_vers_set.size());
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int test_extended_versioning_device_built_in_kernels(cl_device_id device)
|
|
{
|
|
log_info("Device built-in kernels:\n");
|
|
std::vector<char> kernel_string{ get_device_string(
|
|
device, CL_DEVICE_BUILT_IN_KERNELS) };
|
|
if (kernel_string.empty())
|
|
{
|
|
log_error("Could not get CL device extensions string\n");
|
|
return 1;
|
|
}
|
|
|
|
size_t size{};
|
|
cl_int err = clGetDeviceInfo(
|
|
device, CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR, 0, nullptr, &size);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetDeviceInfo failed\n");
|
|
return 1;
|
|
}
|
|
|
|
if ((size % sizeof(cl_name_version_khr)) != 0)
|
|
{
|
|
log_error("CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR return size not "
|
|
"a multiple of sizeof(cl_name_version_khr)\n");
|
|
return 1;
|
|
}
|
|
|
|
const size_t kernel_name_vers_count = size / sizeof(cl_name_version_khr);
|
|
std::vector<cl_name_version_khr> kernel_name_vers(kernel_name_vers_count);
|
|
|
|
err = clGetDeviceInfo(device, CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR,
|
|
size, kernel_name_vers.data(), nullptr);
|
|
if (err != CL_SUCCESS)
|
|
{
|
|
log_error("clGetDeviceInfo failed\n");
|
|
return 1;
|
|
}
|
|
|
|
name_version_set kernel_name_vers_set;
|
|
for (const auto& kernel : kernel_name_vers)
|
|
{
|
|
cl_name_version_khr name_version = kernel;
|
|
name_version.version = CL_MAKE_VERSION_KHR(0, 0, 0);
|
|
|
|
if (kernel_name_vers_set.find(name_version)
|
|
!= kernel_name_vers_set.cend())
|
|
{
|
|
log_error("Duplicate kernel in kernel name-version array\n");
|
|
return 1;
|
|
}
|
|
|
|
kernel_name_vers_set.insert(name_version);
|
|
}
|
|
|
|
name_version_set kernel_string_set;
|
|
if (!name_version_set_from_built_in_kernel_string(kernel_string.data(),
|
|
kernel_string_set))
|
|
{
|
|
log_error("Failed to parse device kernel string\n");
|
|
return 1;
|
|
}
|
|
|
|
if (kernel_string_set != kernel_name_vers_set)
|
|
{
|
|
log_error("Device kernel mismatch\n");
|
|
|
|
log_info("\tKernels only in numeric:");
|
|
log_name_only_set_difference(kernel_name_vers_set, kernel_string_set);
|
|
log_info("\n\tKernels only in string:");
|
|
log_name_only_set_difference(kernel_string_set, kernel_name_vers_set);
|
|
log_info("\n");
|
|
|
|
return 1;
|
|
}
|
|
|
|
log_info("\tMatched %zu kernels\n", kernel_name_vers_set.size());
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Assumes the core enums, structures, and macros exactly match
|
|
// the extension enums, structures, and macros:
|
|
|
|
static_assert(CL_PLATFORM_NUMERIC_VERSION == CL_PLATFORM_NUMERIC_VERSION_KHR,
|
|
"CL_PLATFORM_NUMERIC_VERSION mismatch");
|
|
static_assert(CL_PLATFORM_EXTENSIONS_WITH_VERSION
|
|
== CL_PLATFORM_EXTENSIONS_WITH_VERSION_KHR,
|
|
"CL_PLATFORM_EXTENSIONS_WITH_VERSION mismatch");
|
|
|
|
static_assert(CL_DEVICE_NUMERIC_VERSION == CL_DEVICE_NUMERIC_VERSION_KHR,
|
|
"CL_DEVICE_NUMERIC_VERSION mismatch");
|
|
static_assert(CL_DEVICE_EXTENSIONS_WITH_VERSION
|
|
== CL_DEVICE_EXTENSIONS_WITH_VERSION_KHR,
|
|
"CL_DEVICE_EXTENSIONS_WITH_VERSION mismatch");
|
|
static_assert(CL_DEVICE_ILS_WITH_VERSION == CL_DEVICE_ILS_WITH_VERSION_KHR,
|
|
"CL_DEVICE_ILS_WITH_VERSION mismatch");
|
|
static_assert(CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION
|
|
== CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION_KHR,
|
|
"CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION mismatch");
|
|
|
|
static_assert(sizeof(cl_name_version) == sizeof(cl_name_version_khr),
|
|
"cl_name_version mismatch");
|
|
|
|
static_assert(CL_MAKE_VERSION(1, 2, 3) == CL_MAKE_VERSION_KHR(1, 2, 3),
|
|
"CL_MAKE_VERSION mismatch");
|
|
|
|
int test_extended_versioning(cl_device_id deviceID, cl_context context,
|
|
cl_command_queue ignoreQueue, int num_elements)
|
|
{
|
|
bool ext = is_extension_available(deviceID, "cl_khr_extended_versioning");
|
|
bool core = get_device_cl_version(deviceID) >= Version(3, 0);
|
|
|
|
if (!ext && !core)
|
|
{
|
|
return TEST_SKIPPED_ITSELF;
|
|
}
|
|
|
|
cl_platform_id platform;
|
|
cl_int err = clGetDeviceInfo(deviceID, CL_DEVICE_PLATFORM, sizeof(platform),
|
|
&platform, nullptr);
|
|
test_error(err, "clGetDeviceInfo failed\n");
|
|
|
|
int total_errors = 0;
|
|
total_errors += test_extended_versioning_platform_version(platform);
|
|
total_errors += test_extended_versioning_platform_extensions(platform);
|
|
total_errors += test_extended_versioning_device_versions(ext, deviceID);
|
|
total_errors += test_extended_versioning_device_extensions(deviceID);
|
|
total_errors += test_extended_versioning_device_il(deviceID);
|
|
total_errors += test_extended_versioning_device_built_in_kernels(deviceID);
|
|
|
|
return total_errors;
|
|
}
|