Skip to content
32 changes: 26 additions & 6 deletions unified-runtime/source/adapters/cuda/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1229,17 +1229,27 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice,
// std::array<std::byte, 8>. For details about this extension,
// see sycl/doc/extensions/supported/sycl_ext_intel_device_info.md.
std::array<char, 8> LUID{};
cuDeviceGetLuid(LUID.data(), nullptr, hDevice->get());
unsigned int nodeMask = 0;
// Must pass both parameters - CUDA returns SUCCESS with zeros on
// unsupported platforms
CUresult Result = cuDeviceGetLuid(LUID.data(), &nodeMask, hDevice->get());

// CUDA_ERROR_NOT_SUPPORTED means LUID is not available on this platform
if (Result == CUDA_ERROR_NOT_SUPPORTED) {
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}
UR_CHECK_ERROR(Result);

bool isAllZeros = true;
for (char num : LUID) {
if (num != 0) {
isAllZeros = false;
break;
}
}

if (isAllZeros) {
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}

std::array<unsigned char, 8> Name{};
Expand All @@ -1251,12 +1261,22 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice,
// Intel extension for device node mask. This returns the node mask as
// uint32_t. For details about this extension,
// see sycl/doc/extensions/supported/sycl_ext_intel_device_info.md.
uint32_t nodeMask = 0;
cuDeviceGetLuid(nullptr, &nodeMask, hDevice->get());
std::array<char, 8> LUID{};
unsigned int nodeMask = 0;
// Must pass both parameters - CUDA returns SUCCESS with zeros on
// unsupported platforms
CUresult Result = cuDeviceGetLuid(LUID.data(), &nodeMask, hDevice->get());

// CUDA_ERROR_NOT_SUPPORTED means node mask is not available on this
// platform
if (Result == CUDA_ERROR_NOT_SUPPORTED) {
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}
UR_CHECK_ERROR(Result);

// If nodeMask has not changed, return unsupported.
// If nodeMask is zero, the feature is not supported on this platform
if (nodeMask == 0) {
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}

return ReturnValue(nodeMask);
Expand Down
37 changes: 33 additions & 4 deletions unified-runtime/source/adapters/level_zero/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1541,12 +1541,30 @@ ur_result_t urDeviceGetInfo(
LuidDesc.stype = ZE_STRUCTURE_TYPE_DEVICE_LUID_EXT_PROPERTIES;
DeviceProp.pNext = (void *)&LuidDesc;

ZE2UR_CALL(zeDeviceGetProperties, (ZeDevice, &DeviceProp));
const auto ZeResult = zeDeviceGetProperties(ZeDevice, &DeviceProp);
if (ZeResult == ZE_RESULT_ERROR_UNSUPPORTED_FEATURE) {
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}
if (ZeResult != ZE_RESULT_SUCCESS) {
return ze2urResult(ZeResult);
}

const auto &LUID = LuidDesc.luid.id;
// If the LUID is all zeros the extension is present but not usable
// on this platform (e.g. Linux).
bool isAllZeros = true;
for (auto byte : LUID) {
if (byte != 0) {
isAllZeros = false;
break;
}
}
if (isAllZeros) {
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}
return ReturnValue(LUID, sizeof(LUID));
} else {
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}
}
case UR_DEVICE_INFO_NODE_MASK: {
Expand All @@ -1564,11 +1582,22 @@ ur_result_t urDeviceGetInfo(
LuidDesc.stype = ZE_STRUCTURE_TYPE_DEVICE_LUID_EXT_PROPERTIES;
DeviceProp.pNext = (void *)&LuidDesc;

ZE2UR_CALL(zeDeviceGetProperties, (ZeDevice, &DeviceProp));
const auto ZeResult = zeDeviceGetProperties(ZeDevice, &DeviceProp);
if (ZeResult == ZE_RESULT_ERROR_UNSUPPORTED_FEATURE) {
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}
if (ZeResult != ZE_RESULT_SUCCESS) {
return ze2urResult(ZeResult);
}

// If the node mask is zero the extension is present but not usable
// on this platform (e.g. Linux).
if (LuidDesc.nodeMask == 0) {
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}
return ReturnValue(LuidDesc.nodeMask);
} else {
return UR_RESULT_ERROR_UNSUPPORTED_FEATURE;
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}
}
case UR_DEVICE_INFO_CLOCK_SUB_GROUP_SUPPORT_EXP: {
Expand Down
6 changes: 6 additions & 0 deletions unified-runtime/source/adapters/native_cpu/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,12 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice,
case UR_DEVICE_INFO_GRAPH_RECORD_AND_REPLAY_SUPPORT_EXP:
return ReturnValue(false);

// LUID and NODE_MASK are Windows/D3D12 specific - not applicable on Native
// CPU
case UR_DEVICE_INFO_LUID:
case UR_DEVICE_INFO_NODE_MASK:
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;

default:
DIE_NO_IMPLEMENTATION;
}
Expand Down
4 changes: 2 additions & 2 deletions unified-runtime/source/adapters/opencl/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1488,11 +1488,11 @@ UR_APIEXPORT ur_result_t UR_APICALL urDeviceGetInfo(ur_device_handle_t hDevice,
return UR_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}

cl_int nodeMask = 0;
cl_uint nodeMask = 0;

CL_RETURN_ON_FAILURE(clGetDeviceInfo(Device->CLDevice,
CL_DEVICE_NODE_MASK_KHR,
sizeof(cl_int), &nodeMask, nullptr));
sizeof(cl_uint), &nodeMask, nullptr));

return ReturnValue(nodeMask);
}
Expand Down
35 changes: 35 additions & 0 deletions unified-runtime/test/conformance/device/urDeviceGetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2683,6 +2683,41 @@ TEST_P(urDeviceGetInfoTest, SuccessMinPowerLimit) {
property_value);
}

TEST_P(urDeviceGetInfoTest, SuccessLuid) {
size_t property_size = 0;
const ur_device_info_t property_name = UR_DEVICE_INFO_LUID;

ASSERT_SUCCESS_OR_OPTIONAL_QUERY(
urDeviceGetInfo(device, property_name, 0, nullptr, &property_size),
property_name);
ASSERT_EQ(property_size, sizeof(std::array<unsigned char, 8>));

std::array<unsigned char, 8> property_value{};
ASSERT_SUCCESS(urDeviceGetInfo(device, property_name, property_size,
property_value.data(), nullptr));

std::array<unsigned char, 8> returned_value{};
ASSERT_SUCCESS(urDeviceGetInfo(device, property_name, property_size,
returned_value.data(), nullptr));
ASSERT_EQ(property_value, returned_value);
}

TEST_P(urDeviceGetInfoTest, SuccessNodeMask) {
size_t property_size = 0;
const ur_device_info_t property_name = UR_DEVICE_INFO_NODE_MASK;

ASSERT_SUCCESS_OR_OPTIONAL_QUERY(
urDeviceGetInfo(device, property_name, 0, nullptr, &property_size),
property_name);
ASSERT_EQ(property_size, sizeof(uint32_t));

uint32_t property_value = 0;
ASSERT_QUERY_RETURNS_VALUE(urDeviceGetInfo(device, property_name,
property_size, &property_value,
nullptr),
property_value);
}

TEST_P(urDeviceGetInfoTest, InvalidNullHandleDevice) {
ur_device_type_t device_type;
ASSERT_EQ_RESULT(UR_RESULT_ERROR_INVALID_NULL_HANDLE,
Expand Down
Loading