Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions projects/clr/hipamd/src/hip_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -625,15 +625,14 @@ hipError_t hipDeviceGetLuid(char* luid, unsigned int* deviceNodeMask, hipDevice_
HIP_RETURN(hipErrorInvalidValue);
}

if (IS_LINUX) {
// The LUID is a Windows/DXGI adapter concept; unsupported elsewhere and the
// output parameters are left untouched.
HIP_RETURN(hipErrorNotSupported);
}

auto* deviceHandle = g_devices[device]->devices()[0];
const auto& info = deviceHandle->info();

// No WDDM/DXGI adapter behind this device, so no LUID to report.
if (info.luidLowPart_ == 0 && info.luidHighPart_ == 0) {
HIP_RETURN(hipErrorNotSupported);
Comment thread
agunashe marked this conversation as resolved.
Resolved
}

// The LUID is an 8-byte value formed from the low and high parts reported by the backend.
static_assert(sizeof(info.luidLowPart_) + sizeof(info.luidHighPart_) == 8,
"LUID is expected to be 8 bytes");
Expand Down
96 changes: 60 additions & 36 deletions projects/hip-tests/catch/unit/device/hipDeviceGetLuid.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,21 @@

#include <hip_test_common.hh>
#include <cstring>
#if !defined(_WIN32)
#include <unistd.h>
#endif

static constexpr size_t LUID_LEN = 8;
static constexpr unsigned int kSentinel = 0xdeadbeefU;

static bool LuidMustBeSupported() {
#if defined(_WIN32)
return true;
#else
static const bool kIsWsl = (access("/dev/dxg", F_OK) == 0);
return kIsWsl;
#endif
}

/**
* @addtogroup hipDeviceGetLuid hipDeviceGetLuid
Expand All @@ -21,9 +34,10 @@ static constexpr size_t LUID_LEN = 8;
* Test Description
* ------------------------
* - Query the LUID for each available device.
* - The LUID is a Windows/DXGI adapter concept. On Windows the call succeeds;
* on other platforms it returns `hipErrorNotSupported` without writing the
* output parameters.
* - Where an adapter backs the device (Windows, or Linux under WSL - detected by
* the presence of `/dev/dxg`) the call must succeed and write a non-zero LUID
* and node mask; everywhere else it must return `hipErrorNotSupported` without
* touching the output parameters.
* Test source
* ------------------------
* - unit/device/hipDeviceGetLuid.cc
Expand All @@ -37,32 +51,36 @@ HIP_TEST_CASE(Unit_hipDeviceGetLuid_Positive) {
HIP_CHECK(hipDeviceGet(&device, deviceId));

char luid[LUID_LEN] = {0};
unsigned int deviceNodeMask = 0;
#if defined(_WIN32)
HIP_CHECK(hipDeviceGetLuid(luid, &deviceNodeMask, device));
// A valid adapter LUID is never all-zero and the node mask has at least one
// bit set, so verify the outputs were actually written.
unsigned int deviceNodeMask = kSentinel;
const hipError_t err = hipDeviceGetLuid(luid, &deviceNodeMask, device);

const bool supported = (err == hipSuccess);
const bool mustSupport = LuidMustBeSupported();
INFO("device " << deviceId << ", hipDeviceGetLuid returned " << hipGetErrorString(err));
REQUIRE(supported == mustSupport);

char zeroLuid[LUID_LEN] = {0};
REQUIRE(memcmp(luid, zeroLuid, LUID_LEN) != 0);
REQUIRE(deviceNodeMask != 0);
#else
const unsigned int kSentinel = 0xdeadbeefU;
deviceNodeMask = kSentinel;
REQUIRE(hipDeviceGetLuid(luid, &deviceNodeMask, device) == hipErrorNotSupported);
// Outputs must be left untouched on the unsupported path.
char zero[LUID_LEN] = {0};
REQUIRE(memcmp(luid, zero, LUID_LEN) == 0);
REQUIRE(deviceNodeMask == kSentinel);
#endif
if (err == hipSuccess) {
// A valid adapter LUID is never all-zero and the node mask has at least one
// bit set, so verify the outputs were actually written.
REQUIRE(memcmp(luid, zeroLuid, LUID_LEN) != 0);
REQUIRE(deviceNodeMask != 0);
} else {
REQUIRE(err == hipErrorNotSupported);
// Outputs must be left untouched on the unsupported path.
REQUIRE(memcmp(luid, zeroLuid, LUID_LEN) == 0);
REQUIRE(deviceNodeMask == kSentinel);
}
}

/**
* Test Description
* ------------------------
* - On Windows, verify that the LUID and device node mask returned by
* hipDeviceGetLuid match the values reported by hipGetDeviceProperties.
* - On other platforms, verify the API reports `hipErrorNotSupported` and that
* hipGetDeviceProperties reports an all-zero LUID and zero node mask.
* - Verify hipDeviceGetLuid and hipGetDeviceProperties agree for every device:
* on success the LUID and node mask must match; on `hipErrorNotSupported`
* the properties must report an all-zero LUID and zero node mask.
* - Success is required on Windows and WSL, and `hipErrorNotSupported` is
* required everywhere else.
* Test source
* ------------------------
* - unit/device/hipDeviceGetLuid.cc
Expand All @@ -79,22 +97,28 @@ HIP_TEST_CASE(Unit_hipDeviceGetLuid_VerifyLuidFrm_hipGetDeviceProperties) {
hipDevice_t device;
HIP_CHECK(hipDeviceGet(&device, dev));

char luid[LUID_LEN] = {0};
unsigned int deviceNodeMask = 0;

hipDeviceProp_t prop;
HIP_CHECK(hipGetDeviceProperties(&prop, dev));

#if defined(_WIN32)
HIP_CHECK(hipDeviceGetLuid(luid, &deviceNodeMask, device));
REQUIRE(memcmp(luid, prop.luid, LUID_LEN) == 0);
REQUIRE(deviceNodeMask == prop.luidDeviceNodeMask);
#else
REQUIRE(hipDeviceGetLuid(luid, &deviceNodeMask, device) == hipErrorNotSupported);
char zero[LUID_LEN] = {0};
REQUIRE(memcmp(prop.luid, zero, LUID_LEN) == 0);
REQUIRE(prop.luidDeviceNodeMask == 0);
#endif
char luid[LUID_LEN] = {0};
unsigned int deviceNodeMask = kSentinel;
const hipError_t err = hipDeviceGetLuid(luid, &deviceNodeMask, device);

const bool supported = (err == hipSuccess);
const bool mustSupport = LuidMustBeSupported();
INFO("device " << dev << ", hipDeviceGetLuid returned " << hipGetErrorString(err));
REQUIRE(supported == mustSupport);

if (err == hipSuccess) {
REQUIRE(memcmp(luid, prop.luid, LUID_LEN) == 0);
REQUIRE(deviceNodeMask == prop.luidDeviceNodeMask);
} else {
REQUIRE(err == hipErrorNotSupported);
// Properties must not report a LUID either.
char zero[LUID_LEN] = {0};
REQUIRE(memcmp(prop.luid, zero, LUID_LEN) == 0);
REQUIRE(prop.luidDeviceNodeMask == 0);
}
}
}

Expand Down
Loading