diff --git a/opencl/source/cl_device/cl_device_info.cpp b/opencl/source/cl_device/cl_device_info.cpp index 378c8d8bdc..91ce8fb953 100644 --- a/opencl/source/cl_device/cl_device_info.cpp +++ b/opencl/source/cl_device/cl_device_info.cpp @@ -295,7 +295,9 @@ cl_int ClDevice::getDeviceInfo(cl_device_info paramName, } break; case CL_DEVICE_UUID_KHR: - device.generateUuid(uuid); + if (device.getUuid(uuid) == false) { + device.generateUuid(uuid); + } src = uuid.data(); retSize = srcSize = CL_UUID_SIZE_KHR; break; diff --git a/opencl/test/unit_test/device/get_device_info_tests.cpp b/opencl/test/unit_test/device/get_device_info_tests.cpp index 7db847c106..e7d8d1cdbd 100644 --- a/opencl/test/unit_test/device/get_device_info_tests.cpp +++ b/opencl/test/unit_test/device/get_device_info_tests.cpp @@ -1055,6 +1055,19 @@ TEST(GetDeviceInfo, givenDeviceUuidWhenGettingDeviceInfoThenGenerateDeviceUuid) EXPECT_EQ(generateDeviceUuid, deviceUuidKHR); } +TEST(GetDeviceInfo, givenDeviceUuidWhenGettingDeviceInfoThenGenerateDeviceUuidFromPci) { + std::array generateDeviceUuid, deviceUuidKHR; + size_t retSize = 0; + memset(generateDeviceUuid.data(), 1, CL_UUID_SIZE_KHR); + + auto device = std::make_unique(MockDevice::createWithNewExecutionEnvironment(nullptr)); + device->setPciUuid(generateDeviceUuid); + auto retVal = device->getDeviceInfo(CL_DEVICE_UUID_KHR, sizeof(deviceUuidKHR), &deviceUuidKHR, &retSize); + ASSERT_EQ(retVal, CL_SUCCESS); + + EXPECT_EQ(generateDeviceUuid, deviceUuidKHR); +} + struct DeviceAttributeQueryTest : public ::testing::TestWithParam { void SetUp() override { param = GetParam(); diff --git a/opencl/test/unit_test/mocks/mock_cl_device.cpp b/opencl/test/unit_test/mocks/mock_cl_device.cpp index 2a140cdf75..61254f8d0b 100644 --- a/opencl/test/unit_test/mocks/mock_cl_device.cpp +++ b/opencl/test/unit_test/mocks/mock_cl_device.cpp @@ -39,3 +39,8 @@ ExecutionEnvironment *MockClDevice::prepareExecutionEnvironment(const HardwareIn bool MockClDevice::areOcl21FeaturesSupported() const { return device.getHardwareInfo().capabilityTable.supportsOcl21Features; } + +void MockClDevice::setPciUuid(std::array &id) { + memcpy_s(device.uuid.id.data(), ProductHelper::uuidSize, id.data(), ProductHelper::uuidSize); + device.uuid.isValid = true; +} diff --git a/opencl/test/unit_test/mocks/mock_cl_device.h b/opencl/test/unit_test/mocks/mock_cl_device.h index 38740ba157..330dad2493 100644 --- a/opencl/test/unit_test/mocks/mock_cl_device.h +++ b/opencl/test/unit_test/mocks/mock_cl_device.h @@ -43,6 +43,7 @@ class MockClDevice : public ClDevice { explicit MockClDevice(MockDevice *pMockDevice); + void setPciUuid(std::array &id); bool createEngines() { return device.createEngines(); } void setOSTime(OSTime *osTime) { device.setOSTime(osTime); } bool getCpuTime(uint64_t *timeStamp) { return device.getCpuTime(timeStamp); } diff --git a/shared/source/device/device.cpp b/shared/source/device/device.cpp index 610601f584..59fe82ac94 100644 --- a/shared/source/device/device.cpp +++ b/shared/source/device/device.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2022 Intel Corporation + * Copyright (C) 2018-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -740,13 +740,47 @@ bool Device::getUuid(std::array &uuid) { bool Device::generateUuidFromPciBusInfo(const PhysicalDevicePciBusInfo &pciBusInfo, std::array &uuid) { if (pciBusInfo.pciDomain != PhysicalDevicePciBusInfo::invalidValue) { - uuid.fill(0); - memcpy_s(&uuid[0], 2, &pciBusInfo.pciDomain, 2); - memcpy_s(&uuid[2], 1, &pciBusInfo.pciBus, 1); - memcpy_s(&uuid[3], 1, &pciBusInfo.pciDevice, 1); - memcpy_s(&uuid[4], 1, &pciBusInfo.pciFunction, 1); - uuid[ProductHelper::uuidSize - 1] = isSubDevice() ? static_cast(this)->getSubDeviceIndex() + 1 : 0; + + /* Device UUID uniquely identifies a device within a system. + * We generate it based on device information along with PCI information + * This guarantees uniqueness of UUIDs on a system even when multiple + * identical Intel GPUs are present. + */ + + /* We want to have UUID matching between different GPU APIs (including outside + * of compute_runtime project - i.e. other than L0 or OCL). This structure definition + * has been agreed upon by various Intel driver teams. + * + * Consult other driver teams before changing this. + */ + + struct device_uuid { + uint16_t vendor_id; + uint16_t device_id; + uint16_t revision_id; + uint16_t pci_domain; + uint8_t pci_bus; + uint8_t pci_dev; + uint8_t pci_func; + uint8_t reserved[4]; + uint8_t sub_device_id; + }; + + device_uuid deviceUUID = {}; + deviceUUID.vendor_id = 0x8086; // Intel + deviceUUID.device_id = getHardwareInfo().platform.usDeviceID; + deviceUUID.revision_id = getHardwareInfo().platform.usRevId; + deviceUUID.pci_domain = static_cast(pciBusInfo.pciDomain); + deviceUUID.pci_bus = static_cast(pciBusInfo.pciBus); + deviceUUID.pci_dev = static_cast(pciBusInfo.pciDevice); + deviceUUID.pci_func = static_cast(pciBusInfo.pciFunction); + deviceUUID.sub_device_id = isSubDevice() ? static_cast(this)->getSubDeviceIndex() + 1 : 0; + + static_assert(sizeof(device_uuid) == ProductHelper::uuidSize); + + memcpy_s(uuid.data(), ProductHelper::uuidSize, &deviceUUID, sizeof(device_uuid)); + return true; } return false; diff --git a/shared/test/common/mocks/mock_device.h b/shared/test/common/mocks/mock_device.h index 2e2e0dc99f..e0a7228189 100644 --- a/shared/test/common/mocks/mock_device.h +++ b/shared/test/common/mocks/mock_device.h @@ -57,12 +57,14 @@ class MockDevice : public RootDevice { using Device::engineInstanced; using Device::engineInstancedType; using Device::executionEnvironment; + using Device::generateUuidFromPciBusInfo; using Device::getGlobalMemorySize; using Device::initializeCaps; using Device::isDebuggerActive; using Device::regularEngineGroups; using Device::rootCsrCreated; using Device::rtMemoryBackedBuffer; + using Device::uuid; using RootDevice::createEngines; using RootDevice::defaultEngineIndex; using RootDevice::getDeviceBitfield; diff --git a/shared/test/unit_test/device/neo_device_tests.cpp b/shared/test/unit_test/device/neo_device_tests.cpp index d63ac3cf86..91b27bdeeb 100644 --- a/shared/test/unit_test/device/neo_device_tests.cpp +++ b/shared/test/unit_test/device/neo_device_tests.cpp @@ -149,6 +149,33 @@ TEST_F(DeviceTest, GivenDeviceWhenGenerateUuidThenValidValuesAreSet) { EXPECT_EQ(memcmp(&uuid, &expectedUuid, ProductHelper::uuidSize), 0); } +TEST_F(DeviceTest, GivenDeviceWhenGenerateUuidFromPciBusInfoThenValidValuesAreSet) { + std::array uuid, expectedUuid; + + PhysicalDevicePciBusInfo pciBusInfo = {1, 1, 1, 1}; + + pDevice->generateUuidFromPciBusInfo(pciBusInfo, uuid); + + expectedUuid.fill(0); + uint16_t vendorId = 0x8086; // Intel + uint16_t deviceId = static_cast(pDevice->getHardwareInfo().platform.usDeviceID); + uint16_t revisionId = static_cast(pDevice->getHardwareInfo().platform.usRevId); + uint16_t pciDomain = static_cast(pciBusInfo.pciDomain); + uint8_t pciBus = static_cast(pciBusInfo.pciBus); + uint8_t pciDevice = static_cast(pciBusInfo.pciDevice); + uint8_t pciFunction = static_cast(pciBusInfo.pciFunction); + + memcpy_s(&expectedUuid[0], sizeof(uint16_t), &vendorId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[2], sizeof(uint16_t), &deviceId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[4], sizeof(uint16_t), &revisionId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[6], sizeof(uint16_t), &pciDomain, sizeof(uint16_t)); + memcpy_s(&expectedUuid[8], sizeof(uint8_t), &pciBus, sizeof(uint8_t)); + memcpy_s(&expectedUuid[9], sizeof(uint8_t), &pciDevice, sizeof(uint8_t)); + memcpy_s(&expectedUuid[10], sizeof(uint8_t), &pciFunction, sizeof(uint8_t)); + + EXPECT_EQ(memcmp(&uuid, &expectedUuid, ProductHelper::uuidSize), 0); +} + using DeviceGetCapsTest = Test; TEST_F(DeviceGetCapsTest, givenMockCompilerInterfaceWhenInitializeCapsIsCalledThenMaxParameterSizeIsSetCorrectly) { diff --git a/shared/test/unit_test/os_interface/device_uuid_tests.cpp b/shared/test/unit_test/os_interface/device_uuid_tests.cpp index 4247a458e5..491f25a86c 100644 --- a/shared/test/unit_test/os_interface/device_uuid_tests.cpp +++ b/shared/test/unit_test/os_interface/device_uuid_tests.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Intel Corporation + * Copyright (C) 2022-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -49,11 +49,24 @@ HWTEST2_F(MultipleDeviceBdfUuidTest, GivenValidBdfWithCombinationOfAffinityMaskT PhysicalDevicePciBusInfo pciBusInfo(0x00, 0x34, 0xab, 0xcd); const auto deviceFactory = createDevices(pciBusInfo, 4); - std::array uuid; - uint8_t expectedUuid[16] = {0x00, 0x00, 0x34, 0xab, - 0xcd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0}; + std::array uuid; + uint8_t expectedUuid[NEO::ProductHelper::uuidSize] = {}; + + uint16_t vendorId = 0x8086; // Intel + uint16_t deviceId = static_cast(deviceFactory->rootDevices[0]->getHardwareInfo().platform.usDeviceID); + uint16_t revisionId = static_cast(deviceFactory->rootDevices[0]->getHardwareInfo().platform.usRevId); + uint16_t pciDomain = static_cast(pciBusInfo.pciDomain); + uint8_t pciBus = static_cast(pciBusInfo.pciBus); + uint8_t pciDevice = static_cast(pciBusInfo.pciDevice); + uint8_t pciFunction = static_cast(pciBusInfo.pciFunction); + + memcpy_s(&expectedUuid[0], sizeof(uint16_t), &vendorId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[2], sizeof(uint16_t), &deviceId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[4], sizeof(uint16_t), &revisionId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[6], sizeof(uint16_t), &pciDomain, sizeof(uint16_t)); + memcpy_s(&expectedUuid[8], sizeof(uint8_t), &pciBus, sizeof(uint8_t)); + memcpy_s(&expectedUuid[9], sizeof(uint8_t), &pciDevice, sizeof(uint8_t)); + memcpy_s(&expectedUuid[10], sizeof(uint8_t), &pciFunction, sizeof(uint8_t)); EXPECT_EQ(true, deviceFactory->rootDevices[0]->getUuid(uuid)); EXPECT_TRUE(0 == std::memcmp(uuid.data(), expectedUuid, sizeof(expectedUuid))); @@ -83,14 +96,27 @@ HWTEST2_F(MultipleDeviceBdfUuidTest, GivenDefaultAffinityMaskWhenRetrievingDevic VariableBackup backupProductHelper(&productHelperFactory[productFamily], mockProductHelper.get()); std::array uuid; const uint32_t numSubDevices = 2; - uint8_t expectedUuid[16] = {0xad, 0x54, 0x34, 0xab, - 0xcd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0}; + uint8_t expectedUuid[NEO::ProductHelper::uuidSize] = {}; DebugManager.flags.ZE_AFFINITY_MASK.set("default"); PhysicalDevicePciBusInfo pciBusInfo(0x54ad, 0x34, 0xab, 0xcd); const auto deviceFactory = createDevices(pciBusInfo, numSubDevices); + uint16_t vendorId = 0x8086; // Intel + uint16_t deviceId = static_cast(deviceFactory->rootDevices[0]->getHardwareInfo().platform.usDeviceID); + uint16_t revisionId = static_cast(deviceFactory->rootDevices[0]->getHardwareInfo().platform.usRevId); + uint16_t pciDomain = static_cast(pciBusInfo.pciDomain); + uint8_t pciBus = static_cast(pciBusInfo.pciBus); + uint8_t pciDevice = static_cast(pciBusInfo.pciDevice); + uint8_t pciFunction = static_cast(pciBusInfo.pciFunction); + + memcpy_s(&expectedUuid[0], sizeof(uint16_t), &vendorId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[2], sizeof(uint16_t), &deviceId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[4], sizeof(uint16_t), &revisionId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[6], sizeof(uint16_t), &pciDomain, sizeof(uint16_t)); + memcpy_s(&expectedUuid[8], sizeof(uint8_t), &pciBus, sizeof(uint8_t)); + memcpy_s(&expectedUuid[9], sizeof(uint8_t), &pciDevice, sizeof(uint8_t)); + memcpy_s(&expectedUuid[10], sizeof(uint8_t), &pciFunction, sizeof(uint8_t)); + EXPECT_EQ(true, deviceFactory->rootDevices[0]->getUuid(uuid)); EXPECT_TRUE(0 == std::memcmp(uuid.data(), expectedUuid, sizeof(expectedUuid))); @@ -120,16 +146,30 @@ HWTEST2_F(MultipleDeviceBdfUuidTest, GivenNoSubDevicesInAffinityMaskwhenRetrievi setupMockProductHelper(); VariableBackup backupProductHelper(&productHelperFactory[productFamily], mockProductHelper.get()); - std::array uuid; - uint8_t expectedUuid[16] = {0x00, 0x00, 0x34, 0xab, - 0xcd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0}; + std::array uuid{}; + uint8_t expectedUuid[NEO::ProductHelper::uuidSize] = {}; + + PhysicalDevicePciBusInfo pciBusInfo(0x00, 0x34, 0xab, 0xcd); DebugManager.flags.ZE_AFFINITY_MASK.set("0"); - PhysicalDevicePciBusInfo pciBusInfo(0x00, 0x34, 0xab, 0xcd); const auto deviceFactory = createDevices(pciBusInfo, 2); + uint16_t vendorId = 0x8086; // Intel + uint16_t deviceId = static_cast(deviceFactory->rootDevices[0]->getHardwareInfo().platform.usDeviceID); + uint16_t revisionId = static_cast(deviceFactory->rootDevices[0]->getHardwareInfo().platform.usRevId); + uint16_t pciDomain = static_cast(pciBusInfo.pciDomain); + uint8_t pciBus = static_cast(pciBusInfo.pciBus); + uint8_t pciDevice = static_cast(pciBusInfo.pciDevice); + uint8_t pciFunction = static_cast(pciBusInfo.pciFunction); + + memcpy_s(&expectedUuid[0], sizeof(uint16_t), &vendorId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[2], sizeof(uint16_t), &deviceId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[4], sizeof(uint16_t), &revisionId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[6], sizeof(uint16_t), &pciDomain, sizeof(uint16_t)); + memcpy_s(&expectedUuid[8], sizeof(uint8_t), &pciBus, sizeof(uint8_t)); + memcpy_s(&expectedUuid[9], sizeof(uint8_t), &pciDevice, sizeof(uint8_t)); + memcpy_s(&expectedUuid[10], sizeof(uint8_t), &pciFunction, sizeof(uint8_t)); + EXPECT_EQ(true, deviceFactory->rootDevices[0]->getUuid(uuid)); EXPECT_TRUE(0 == std::memcmp(uuid.data(), expectedUuid, sizeof(expectedUuid))); } @@ -142,11 +182,24 @@ HWTEST2_F(MultipleDeviceBdfUuidTest, GivenValidBdfWithOneBitEnabledInAffinityMas PhysicalDevicePciBusInfo pciBusInfo(0x00, 0x34, 0xab, 0xcd); const auto deviceFactory = createDevices(pciBusInfo, 4); - std::array uuid; - uint8_t expectedUuid[16] = {0x00, 0x00, 0x34, 0xab, - 0xcd, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0}; + std::array uuid; + uint8_t expectedUuid[NEO::ProductHelper::uuidSize] = {}; + + uint16_t vendorId = 0x8086; // Intel + uint16_t deviceId = static_cast(deviceFactory->rootDevices[0]->getHardwareInfo().platform.usDeviceID); + uint16_t revisionId = static_cast(deviceFactory->rootDevices[0]->getHardwareInfo().platform.usRevId); + uint16_t pciDomain = static_cast(pciBusInfo.pciDomain); + uint8_t pciBus = static_cast(pciBusInfo.pciBus); + uint8_t pciDevice = static_cast(pciBusInfo.pciDevice); + uint8_t pciFunction = static_cast(pciBusInfo.pciFunction); + + memcpy_s(&expectedUuid[0], sizeof(uint16_t), &vendorId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[2], sizeof(uint16_t), &deviceId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[4], sizeof(uint16_t), &revisionId, sizeof(uint16_t)); + memcpy_s(&expectedUuid[6], sizeof(uint16_t), &pciDomain, sizeof(uint16_t)); + memcpy_s(&expectedUuid[8], sizeof(uint8_t), &pciBus, sizeof(uint8_t)); + memcpy_s(&expectedUuid[9], sizeof(uint8_t), &pciDevice, sizeof(uint8_t)); + memcpy_s(&expectedUuid[10], sizeof(uint8_t), &pciFunction, sizeof(uint8_t)); EXPECT_EQ(true, deviceFactory->rootDevices[0]->getUuid(uuid)); expectedUuid[15] = 4;