Tests for cl_khr_device_uuid (#813)

Basic conformance testing for the cl_khr_device_uuid extension.  Checks
that the ID queries return the right sizes and that the returned IDs are
stable across two calls to clGetDeviceInfo. If device LUID validity is
true, also checks that one and only one bit is set in the device node
mask.

Signed-off-by: Einar Hov <einar.hov@arm.com>
This commit is contained in:
Einar Hov
2020-07-09 11:23:38 +01:00
committed by GitHub
parent a69f3ca8cf
commit bb1285f6f2
3 changed files with 214 additions and 0 deletions

View File

@@ -2,6 +2,7 @@ set(MODULE_NAME computeinfo)
set(${MODULE_NAME}_SOURCES
main.cpp
device_uuid.cpp
extended_versioning.cpp
)

View File

@@ -0,0 +1,211 @@
//
// Copyright (c) 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 <array>
#include <bitset>
#include "harness/testHarness.h"
#include "harness/deviceInfo.h"
using uuid = std::array<cl_uchar, CL_UUID_SIZE_KHR>;
using luid = std::array<cl_uchar, CL_LUID_SIZE_KHR>;
template <typename T> static void log_info_uuid(const T &id)
{
for (const cl_uchar c : id)
{
log_info("%02x", static_cast<unsigned>(c));
}
}
template <typename T> static void log_error_uuid(const T &id)
{
for (const cl_uchar c : id)
{
log_error("%02x", static_cast<unsigned>(c));
}
}
static bool check_device_info_returns(const cl_int err, const size_t size,
const size_t expected_size)
{
if (err != CL_SUCCESS)
{
print_error(err, "clGetDeviceInfo failed");
return false;
}
else if (size != expected_size)
{
log_error("Invalid size written by clGetDeviceInfo (%zu != %zu)\n",
size, expected_size);
return false;
}
return true;
}
template <typename T>
static bool get_uuid(const cl_device_id device, const cl_device_info info,
T &id, const bool twice = true)
{
const size_t id_size = id.size() * sizeof(id[0]);
size_t size_ret;
cl_int err = clGetDeviceInfo(device, info, id_size, id.data(), &size_ret);
if (!check_device_info_returns(err, size_ret, id_size))
{
return false;
}
/* Check that IDs are (at the very least) stable across two successive
* clGetDeviceInfo calls. Check conditionally, as it is undefined what the
* query for CL_DEVICE_LUID_KHR returns if CL_DEVICE_LUID_VALID_KHR returns
* false. */
if (twice)
{
T id_2;
size_t size_ret_2;
err = clGetDeviceInfo(device, info, id_size, id_2.data(), &size_ret_2);
if (!check_device_info_returns(err, size_ret_2, id_size))
{
return false;
}
if (id != id_2)
{
log_error("Got different IDs from the same ID device info (");
log_error_uuid(id);
log_error(" != ");
log_error_uuid(id_2);
log_error(")\n");
return false;
}
}
return true;
}
int test_device_uuid(cl_device_id deviceID, cl_context context,
cl_command_queue ignoreQueue, int num_elements)
{
if (!is_extension_available(deviceID, "cl_khr_device_uuid"))
{
log_info("cl_khr_device_uuid not supported. Skipping test...\n");
return 0;
}
int total_errors = 0;
/* CL_DEVICE_UUID_KHR */
uuid device_uuid;
bool success = get_uuid(deviceID, CL_DEVICE_UUID_KHR, device_uuid);
if (!success)
{
log_error("Error getting device UUID\n");
++total_errors;
}
else
{
log_info("\tDevice UUID: ");
log_info_uuid(device_uuid);
log_info("\n");
}
/* CL_DRIVER_UUID_KHR */
uuid driver_uuid;
success = get_uuid(deviceID, CL_DRIVER_UUID_KHR, driver_uuid);
if (!success)
{
log_error("Error getting driver UUID\n");
++total_errors;
}
else
{
log_info("\tDriver UUID: ");
log_info_uuid(driver_uuid);
log_info("\n");
}
size_t size_ret{};
/* CL_DEVICE_LUID_VALID_KHR */
cl_bool device_luid_valid{};
cl_int err = clGetDeviceInfo(deviceID, CL_DEVICE_LUID_VALID_KHR,
sizeof(device_luid_valid), &device_luid_valid,
&size_ret);
if (!check_device_info_returns(err, size_ret, sizeof(device_luid_valid)))
{
log_error("Error getting device LUID validity\n");
++total_errors;
device_luid_valid = false;
}
else
{
log_info("\tDevice LUID validity is %s\n",
device_luid_valid ? "true" : "false");
}
/* CL_DEVICE_LUID_KHR */
luid device_luid;
success =
get_uuid(deviceID, CL_DEVICE_LUID_KHR, device_luid, device_luid_valid);
if (!success)
{
log_error("Error getting device LUID\n");
++total_errors;
}
else
{
log_info("\tDevice LUID: ");
log_info_uuid(device_luid);
log_info("\n");
}
/* CL_DEVICE_NODE_MASK_KHR */
cl_uint device_node_mask{};
err =
clGetDeviceInfo(deviceID, CL_DEVICE_NODE_MASK_KHR,
sizeof(device_node_mask), &device_node_mask, &size_ret);
if (!check_device_info_returns(err, size_ret, sizeof(device_node_mask)))
{
log_error("Error getting device node mask\n");
++total_errors;
}
else
{
log_info("\tNode mask : %08lx\n",
static_cast<unsigned long>(device_node_mask));
/* If the LUID is valid, there must be one and only one bit set in the
* node mask */
if (device_luid_valid)
{
static constexpr size_t cl_uint_size_in_bits = 32;
const size_t bit_count =
std::bitset<cl_uint_size_in_bits>(device_node_mask).count();
if (1 != bit_count)
{
log_error("Wrong amount of bits set in node mask (%zu != 1) "
"with valid LUID\n",
bit_count);
++total_errors;
}
}
}
return total_errors;
}

View File

@@ -1143,10 +1143,12 @@ int test_computeinfo(cl_device_id deviceID, cl_context context,
extern int test_extended_versioning(cl_device_id, cl_context, cl_command_queue,
int);
extern int test_device_uuid(cl_device_id, cl_context, cl_command_queue, int);
test_definition test_list[] = {
ADD_TEST(computeinfo),
ADD_TEST(extended_versioning),
ADD_TEST(device_uuid),
};
const int test_num = ARRAY_SIZE(test_list);