From 7764ac44aec441b17f0bda1709fdb86dd3965a7c Mon Sep 17 00:00:00 2001 From: Aravind Gopalakrishnan Date: Thu, 11 Mar 2021 13:43:05 -0800 Subject: [PATCH] Implement support for zeDeviceGetGlobalTimestamps Related-To: LOCI-1933 Signed-off-by: Aravind Gopalakrishnan --- level_zero/api/core/ze_core_loader.cpp | 1 + level_zero/api/core/ze_device.cpp | 10 +- level_zero/core/source/device/device.h | 1 + level_zero/core/source/device/device_imp.cpp | 15 +++ level_zero/core/source/device/device_imp.h | 1 + .../core/test/unit_tests/mocks/mock_device.h | 5 + .../unit_tests/sources/device/test_device.cpp | 100 ++++++++++++++++++ 7 files changed, 132 insertions(+), 1 deletion(-) diff --git a/level_zero/api/core/ze_core_loader.cpp b/level_zero/api/core/ze_core_loader.cpp index b5eeeadf20..45f3df4433 100644 --- a/level_zero/api/core/ze_core_loader.cpp +++ b/level_zero/api/core/ze_core_loader.cpp @@ -219,6 +219,7 @@ zeGetDeviceProcAddrTable( pDdiTable->pfnCanAccessPeer = zeDeviceCanAccessPeer; pDdiTable->pfnGetStatus = zeDeviceGetStatus; pDdiTable->pfnGetExternalMemoryProperties = zeDeviceGetExternalMemoryProperties; + pDdiTable->pfnGetGlobalTimestamps = zeDeviceGetGlobalTimestamps; driver_ddiTable.core_ddiTable.Device = *pDdiTable; if (driver_ddiTable.enableTracing) { pDdiTable->pfnGet = zeDeviceGet_Tracing; diff --git a/level_zero/api/core/ze_device.cpp b/level_zero/api/core/ze_device.cpp index 49ad2b8cd8..6989ffff40 100644 --- a/level_zero/api/core/ze_device.cpp +++ b/level_zero/api/core/ze_device.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019-2020 Intel Corporation + * Copyright (C) 2019-2021 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -114,3 +114,11 @@ zeDeviceGetStatus( ze_device_handle_t hDevice) { return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } + +ZE_APIEXPORT ze_result_t ZE_APICALL +zeDeviceGetGlobalTimestamps( + ze_device_handle_t hDevice, + uint64_t *hostTimestamp, + uint64_t *deviceTimestamp) { + return L0::Device::fromHandle(hDevice)->getGlobalTimestamps(hostTimestamp, deviceTimestamp); +} \ No newline at end of file diff --git a/level_zero/core/source/device/device.h b/level_zero/core/source/device/device.h index 59d5aeda5e..10e71bd119 100644 --- a/level_zero/core/source/device/device.h +++ b/level_zero/core/source/device/device.h @@ -70,6 +70,7 @@ struct Device : _ze_device_handle_t { virtual ze_result_t imageGetProperties(const ze_image_desc_t *desc, ze_image_properties_t *pImageProperties) = 0; virtual ze_result_t getDeviceImageProperties(ze_device_image_properties_t *pDeviceImageProperties) = 0; virtual ze_result_t getExternalMemoryProperties(ze_device_external_memory_properties_t *pExternalMemoryProperties) = 0; + virtual ze_result_t getGlobalTimestamps(uint64_t *hostTimestamp, uint64_t *deviceTimestamp) = 0; virtual ze_result_t getCommandQueueGroupProperties(uint32_t *pCount, ze_command_queue_group_properties_t *pCommandQueueGroupProperties) = 0; diff --git a/level_zero/core/source/device/device_imp.cpp b/level_zero/core/source/device/device_imp.cpp index a16ed8db15..e622339c28 100644 --- a/level_zero/core/source/device/device_imp.cpp +++ b/level_zero/core/source/device/device_imp.cpp @@ -431,6 +431,21 @@ ze_result_t DeviceImp::getExternalMemoryProperties(ze_device_external_memory_pro return ZE_RESULT_SUCCESS; } +ze_result_t DeviceImp::getGlobalTimestamps(uint64_t *hostTimestamp, uint64_t *deviceTimestamp) { + NEO::TimeStampData queueTimeStamp; + bool retVal = this->neoDevice->getOSTime()->getCpuGpuTime(&queueTimeStamp); + if (!retVal) + return ZE_RESULT_ERROR_DEVICE_LOST; + + *deviceTimestamp = queueTimeStamp.GPUTimeStamp; + + retVal = this->neoDevice->getOSTime()->getCpuTime(hostTimestamp); + if (!retVal) + return ZE_RESULT_ERROR_DEVICE_LOST; + + return ZE_RESULT_SUCCESS; +} + ze_result_t DeviceImp::getSubDevices(uint32_t *pCount, ze_device_handle_t *phSubdevices) { if (*pCount == 0) { *pCount = this->numSubDevices; diff --git a/level_zero/core/source/device/device_imp.h b/level_zero/core/source/device/device_imp.h index 41397ee491..2f28833b29 100644 --- a/level_zero/core/source/device/device_imp.h +++ b/level_zero/core/source/device/device_imp.h @@ -46,6 +46,7 @@ struct DeviceImp : public Device { ze_result_t getCommandQueueGroupProperties(uint32_t *pCount, ze_command_queue_group_properties_t *pCommandQueueGroupProperties) override; ze_result_t getExternalMemoryProperties(ze_device_external_memory_properties_t *pExternalMemoryProperties) override; + ze_result_t getGlobalTimestamps(uint64_t *hostTimestamp, uint64_t *deviceTimestamp) override; ze_result_t getDebugProperties(zet_device_debug_properties_t *pDebugProperties) override; ze_result_t systemBarrier() override; diff --git a/level_zero/core/test/unit_tests/mocks/mock_device.h b/level_zero/core/test/unit_tests/mocks/mock_device.h index a3949e211b..0d8b441538 100644 --- a/level_zero/core/test/unit_tests/mocks/mock_device.h +++ b/level_zero/core/test/unit_tests/mocks/mock_device.h @@ -131,6 +131,11 @@ struct Mock : public Device { getExternalMemoryProperties, (ze_device_external_memory_properties_t * pExternalMemoryProperties), (override)); + MOCK_METHOD(ze_result_t, + getGlobalTimestamps, + (uint64_t * hostTimestamp, + uint64_t *deviceTimestamp), + (override)); MOCK_METHOD(ze_result_t, systemBarrier, (), diff --git a/level_zero/core/test/unit_tests/sources/device/test_device.cpp b/level_zero/core/test/unit_tests/sources/device/test_device.cpp index 263b811a09..3225b2e22d 100644 --- a/level_zero/core/test/unit_tests/sources/device/test_device.cpp +++ b/level_zero/core/test/unit_tests/sources/device/test_device.cpp @@ -8,6 +8,7 @@ #include "shared/source/device/root_device.h" #include "shared/source/helpers/bindless_heaps_helper.h" #include "shared/source/os_interface/hw_info_config.h" +#include "shared/source/os_interface/os_time.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/mocks/mock_device.h" #include "shared/test/common/mocks/ult_device_factory.h" @@ -326,6 +327,105 @@ TEST_F(DeviceTest, whenGetExternalMemoryPropertiesIsCalledThenSuccessIsReturnedA EXPECT_TRUE(externalMemoryProperties.memoryAllocationImportTypes & ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF); } +TEST_F(DeviceTest, whenGetGlobalTimestampIsCalledThenSuccessIsReturnedAndValuesSetCorrectly) { + uint64_t hostTs = 0u; + uint64_t deviceTs = 0u; + + ze_result_t result = device->getGlobalTimestamps(&hostTs, &deviceTs); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + EXPECT_NE(0u, hostTs); + EXPECT_NE(0u, deviceTs); +} + +class FalseCpuGpuTime : public NEO::OSTime { + public: + bool getCpuGpuTime(TimeStampData *pGpuCpuTime) override { + return false; + } + bool getCpuTime(uint64_t *timeStamp) override { + return true; + }; + double getHostTimerResolution() const override { + return 0; + } + double getDynamicDeviceTimerResolution(HardwareInfo const &hwInfo) const override { + return NEO::OSTime::getDeviceTimerResolution(hwInfo); + } + uint64_t getCpuRawTimestamp() override { + return 0; + } + static std::unique_ptr create() { + return std::unique_ptr(new FalseCpuGpuTime()); + } +}; + +struct GlobalTimestampTest : public ::testing::Test { + void SetUp() override { + DebugManager.flags.CreateMultipleRootDevices.set(numRootDevices); + neoDevice = NEO::MockDevice::createWithNewExecutionEnvironment(NEO::defaultHwInfo.get(), rootDeviceIndex); + } + + DebugManagerStateRestore restorer; + std::unique_ptr> driverHandle; + NEO::MockDevice *neoDevice = nullptr; + L0::Device *device = nullptr; + const uint32_t rootDeviceIndex = 1u; + const uint32_t numRootDevices = 2u; +}; + +TEST_F(GlobalTimestampTest, whenGetGlobalTimestampCalledAndGetCpuGpuTimeIsFalseReturnError) { + uint64_t hostTs = 0u; + uint64_t deviceTs = 0u; + + neoDevice->setOSTime(new FalseCpuGpuTime()); + NEO::DeviceVector devices; + devices.push_back(std::unique_ptr(neoDevice)); + driverHandle = std::make_unique>(); + driverHandle->initialize(std::move(devices)); + device = driverHandle->devices[0]; + + ze_result_t result = device->getGlobalTimestamps(&hostTs, &deviceTs); + EXPECT_EQ(ZE_RESULT_ERROR_DEVICE_LOST, result); +} + +class FalseCpuTime : public NEO::OSTime { + public: + bool getCpuGpuTime(TimeStampData *pGpuCpuTime) override { + return true; + } + bool getCpuTime(uint64_t *timeStamp) override { + return false; + }; + double getHostTimerResolution() const override { + return 0; + } + double getDynamicDeviceTimerResolution(HardwareInfo const &hwInfo) const override { + return NEO::OSTime::getDeviceTimerResolution(hwInfo); + } + uint64_t getCpuRawTimestamp() override { + return 0; + } + static std::unique_ptr create() { + return std::unique_ptr(new FalseCpuTime()); + } +}; + +TEST_F(GlobalTimestampTest, whenGetGlobalTimestampCalledAndGetCpuTimeIsFalseReturnError) { + uint64_t hostTs = 0u; + uint64_t deviceTs = 0u; + + neoDevice->setOSTime(new FalseCpuTime()); + NEO::DeviceVector devices; + devices.push_back(std::unique_ptr(neoDevice)); + driverHandle = std::make_unique>(); + driverHandle->initialize(std::move(devices)); + device = driverHandle->devices[0]; + + ze_result_t result = device->getGlobalTimestamps(&hostTs, &deviceTs); + EXPECT_EQ(ZE_RESULT_ERROR_DEVICE_LOST, result); +} + using DeviceGetMemoryTests = DeviceTest; TEST_F(DeviceGetMemoryTests, whenCallingGetMemoryPropertiesWithCountZeroThenOneIsReturned) {