diff --git a/level_zero/api/sysman/zes_sysman_api_entrypoints.h b/level_zero/api/sysman/zes_sysman_api_entrypoints.h index 4d63d1e664..984afe167a 100644 --- a/level_zero/api/sysman/zes_sysman_api_entrypoints.h +++ b/level_zero/api/sysman/zes_sysman_api_entrypoints.h @@ -7,10 +7,31 @@ #pragma once #include "level_zero/core/source/driver/driver_handle.h" +#include "level_zero/sysman/source/sysman_device.h" +#include "level_zero/sysman/source/sysman_driver.h" +#include "level_zero/sysman/source/sysman_driver_handle.h" #include "sysman/sysman.h" namespace L0 { +ze_result_t zesInit( + zes_init_flags_t flags) { + return L0::Sysman::init(flags); +} + +ze_result_t zesDriverGet( + uint32_t *pCount, + zes_driver_handle_t *phDrivers) { + return L0::Sysman::driverHandleGet(pCount, phDrivers); +} + +ze_result_t zesDeviceGet( + zes_driver_handle_t hDriver, + uint32_t *pCount, + zes_device_handle_t *phDevices) { + return L0::Sysman::SysmanDriverHandle::fromHandle(hDriver)->getDevice(pCount, phDevices); +} + ze_result_t zesDeviceGetProperties( zes_device_handle_t hDevice, zes_device_properties_t *pProperties) { @@ -763,24 +784,6 @@ ze_result_t zesFabricPortGetFabricErrorCounters( return L0::FabricPort::fromHandle(hPort)->fabricPortGetErrorCounters(pErrors); } -ze_result_t zesInit( - zes_init_flags_t flags) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; -} - -ze_result_t zesDeviceGet( - zes_driver_handle_t hDriver, - uint32_t *pCount, - zes_device_handle_t *phDevices) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; -} - -ze_result_t zesDriverGet( - uint32_t *pCount, - zes_driver_handle_t *phDrivers) { - return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; -} - ze_result_t zesDeviceSetOverclockWaiver( zes_device_handle_t hDevice) { return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; diff --git a/level_zero/core/source/driver/driver.h b/level_zero/core/source/driver/driver.h index 2a66613e47..5f776005c0 100644 --- a/level_zero/core/source/driver/driver.h +++ b/level_zero/core/source/driver/driver.h @@ -23,6 +23,7 @@ struct Driver { ze_result_t init(ze_init_flags_t); ze_result_t driverHandleGet(uint32_t *pCount, ze_driver_handle_t *phDrivers); +extern bool sysmanInitFromCore; extern uint32_t driverCount; extern _ze_driver_handle_t *GlobalDriverHandle; } // namespace L0 diff --git a/level_zero/sysman/source/CMakeLists.txt b/level_zero/sysman/source/CMakeLists.txt index 1b4be191af..d5937d8c84 100644 --- a/level_zero/sysman/source/CMakeLists.txt +++ b/level_zero/sysman/source/CMakeLists.txt @@ -5,6 +5,16 @@ # set(L0_SRCS_SYSMAN + ${CMAKE_CURRENT_SOURCE_DIR}/sysman_driver.h + ${CMAKE_CURRENT_SOURCE_DIR}/sysman_driver_imp.h + ${CMAKE_CURRENT_SOURCE_DIR}/sysman_driver.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/sysman_driver_handle.h + ${CMAKE_CURRENT_SOURCE_DIR}/sysman_driver_handle_imp.h + ${CMAKE_CURRENT_SOURCE_DIR}/sysman_driver_handle_imp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/sysman_device.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/sysman_device.h + ${CMAKE_CURRENT_SOURCE_DIR}/sysman_device_imp.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/sysman_device_imp.h ) target_sources(${L0_STATIC_LIB_NAME} diff --git a/level_zero/sysman/source/os_sysman.h b/level_zero/sysman/source/os_sysman.h new file mode 100644 index 0000000000..8e355a5269 --- /dev/null +++ b/level_zero/sysman/source/os_sysman.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include + +#include + +namespace L0 { +namespace Sysman { + +struct SysmanDeviceImp; + +struct OsSysman { + virtual ~OsSysman(){}; + + virtual ze_result_t init() = 0; + static OsSysman *create(SysmanDeviceImp *pSysmanImp); + virtual uint32_t getSubDeviceCount() = 0; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/sysman_const.h b/level_zero/sysman/source/sysman_const.h new file mode 100644 index 0000000000..72cfdc1354 --- /dev/null +++ b/level_zero/sysman/source/sysman_const.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include +#include +const std::string vendorIntel("Intel(R) Corporation"); +const std::string unknown("unknown"); +const std::string intelPciId("0x8086"); +constexpr uint32_t MbpsToBytesPerSecond = 125000; +constexpr double milliVoltsFactor = 1000.0; + +namespace L0 { +namespace Sysman { +struct steadyClock { + typedef std::chrono::duration duration; + typedef duration::rep rep; + typedef duration::period period; + typedef std::chrono::time_point time_point; + static time_point now() noexcept { + static auto epoch = std::chrono::steady_clock::now(); + return time_point(std::chrono::duration_cast(std::chrono::steady_clock::now() - epoch)); + } +}; +} // namespace Sysman +} // namespace L0 + +namespace PciLinkSpeeds { +constexpr double Pci2_5GigatransfersPerSecond = 2.5; +constexpr double Pci5_0GigatransfersPerSecond = 5.0; +constexpr double Pci8_0GigatransfersPerSecond = 8.0; +constexpr double Pci16_0GigatransfersPerSecond = 16.0; +constexpr double Pci32_0GigatransfersPerSecond = 32.0; + +} // namespace PciLinkSpeeds +enum PciGenerations { + PciGen1 = 1, + PciGen2, + PciGen3, + PciGen4, + PciGen5, +}; + +constexpr uint8_t maxPciBars = 6; +// Linux kernel would report 255 link width, as an indication of unknown. +constexpr uint32_t unknownPcieLinkWidth = 255u; + +constexpr uint32_t microSecondsToNanoSeconds = 1000u; + +constexpr uint64_t convertJouleToMicroJoule = 1000000u; +constexpr uint64_t minTimeoutModeHeartbeat = 5000u; +constexpr uint64_t minTimeoutInMicroSeconds = 1000u; +constexpr uint16_t milliSecsToMicroSecs = 1000; +constexpr uint32_t milliFactor = 1000u; +constexpr uint32_t microFacor = milliFactor * milliFactor; +constexpr uint64_t gigaUnitTransferToUnitTransfer = 1000 * 1000 * 1000; + +constexpr int32_t memoryBusWidth = 128; // bus width in bits +constexpr int32_t numMemoryChannels = 8; +#define BITS(x, at, width) (((x) >> (at)) & ((1 << (width)) - 1)) diff --git a/level_zero/sysman/source/sysman_device.cpp b/level_zero/sysman/source/sysman_device.cpp new file mode 100644 index 0000000000..82084241bc --- /dev/null +++ b/level_zero/sysman/source/sysman_device.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/execution_environment/execution_environment.h" + +#include "level_zero/sysman/source/sysman_device_imp.h" + +#include +#include + +namespace L0 { +namespace Sysman { + +SysmanDevice *SysmanDevice::create(NEO::ExecutionEnvironment &executionEnvironment, const uint32_t rootDeviceIndex) { + SysmanDeviceImp *pSysmanDevice = new SysmanDeviceImp(&executionEnvironment, rootDeviceIndex); + DEBUG_BREAK_IF(!pSysmanDevice); + if (pSysmanDevice->init() != ZE_RESULT_SUCCESS) { + delete pSysmanDevice; + pSysmanDevice = nullptr; + } + return pSysmanDevice; +} + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/sysman_device.h b/level_zero/sysman/source/sysman_device.h new file mode 100644 index 0000000000..7590f59221 --- /dev/null +++ b/level_zero/sysman/source/sysman_device.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/execution_environment/execution_environment.h" + +#include "level_zero/core/source/device/device.h" +#include +#include + +#include + +namespace L0 { +namespace Sysman { + +struct SysmanDevice : _ze_device_handle_t { + + static SysmanDevice *fromHandle(zes_device_handle_t handle) { return static_cast(handle); } + inline zes_device_handle_t toHandle() { return this; } + virtual ~SysmanDevice() = default; + static SysmanDevice *create(NEO::ExecutionEnvironment &executionEnvironment, const uint32_t rootDeviceIndex); + virtual const NEO::HardwareInfo &getHardwareInfo() const = 0; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/sysman_device_imp.cpp b/level_zero/sysman/source/sysman_device_imp.cpp new file mode 100644 index 0000000000..dd3fe32f2c --- /dev/null +++ b/level_zero/sysman/source/sysman_device_imp.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/source/sysman_device_imp.h" + +#include "shared/source/helpers/debug_helpers.h" + +#include "level_zero/sysman/source/os_sysman.h" + +#include + +namespace L0 { +namespace Sysman { + +SysmanDeviceImp::SysmanDeviceImp(NEO::ExecutionEnvironment *executionEnvironment, const uint32_t rootDeviceIndex) + : executionEnvironment(executionEnvironment), rootDeviceIndex(rootDeviceIndex) { + this->executionEnvironment->incRefInternal(); +} + +SysmanDeviceImp::~SysmanDeviceImp() { + executionEnvironment->decRefInternal(); +} + +ze_result_t SysmanDeviceImp::init() { + return ZE_RESULT_SUCCESS; +} + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/sysman_device_imp.h b/level_zero/sysman/source/sysman_device_imp.h new file mode 100644 index 0000000000..e7a0760c74 --- /dev/null +++ b/level_zero/sysman/source/sysman_device_imp.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/execution_environment/execution_environment.h" +#include "shared/source/execution_environment/root_device_environment.h" +#include "shared/source/helpers/hw_info.h" +#include "shared/source/helpers/non_copyable_or_moveable.h" + +#include "level_zero/sysman/source/sysman_device.h" + +#include + +namespace L0 { +namespace Sysman { +struct OsSysman; + +struct SysmanDeviceImp : SysmanDevice, NEO::NonCopyableOrMovableClass { + + SysmanDeviceImp(NEO::ExecutionEnvironment *executionEnvironment, const uint32_t rootDeviceIndex); + ~SysmanDeviceImp() override; + + SysmanDeviceImp() = delete; + ze_result_t init(); + OsSysman *pOsSysman = nullptr; + const NEO::RootDeviceEnvironment &getRootDeviceEnvironment() const { + return *executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]; + } + const NEO::HardwareInfo &getHardwareInfo() const override { return *getRootDeviceEnvironment().getHardwareInfo(); } + PRODUCT_FAMILY getProductFamily() const { return getHardwareInfo().platform.eProductFamily; } + + private: + NEO::ExecutionEnvironment *executionEnvironment = nullptr; + const uint32_t rootDeviceIndex; + template + void inline freeResource(T *&resource) { + if (resource) { + delete resource; + resource = nullptr; + } + } +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/sysman_driver.cpp b/level_zero/sysman/source/sysman_driver.cpp new file mode 100644 index 0000000000..69da3c52a6 --- /dev/null +++ b/level_zero/sysman/source/sysman_driver.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/debug_settings/debug_settings_manager.h" +#include "shared/source/execution_environment/execution_environment.h" +#include "shared/source/execution_environment/root_device_environment.h" +#include "shared/source/os_interface/debug_env_reader.h" +#include "shared/source/os_interface/os_interface.h" + +#include "level_zero/core/source/driver/driver.h" +#include "level_zero/sysman/source/sysman_driver_handle_imp.h" +#include "level_zero/sysman/source/sysman_driver_imp.h" + +#include +#include + +namespace L0 { +namespace Sysman { +_ze_driver_handle_t *GlobalDriverHandle; +uint32_t driverCount = 1; + +void SysmanDriverImp::initialize(ze_result_t *result) { + *result = ZE_RESULT_ERROR_UNINITIALIZED; + + if (sysmanInitFromCore) { + // Sysman is already initialized while zeInit + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, + "%s", "Sysman Initialization already happened via zeInit\n"); + return; + } + + auto executionEnvironment = new NEO::ExecutionEnvironment(); + UNRECOVERABLE_IF(nullptr == executionEnvironment); + executionEnvironment->incRefInternal(); + + using HwDeviceIds = std::vector>; + + HwDeviceIds hwDeviceIds = NEO::OSInterface::discoverDevices(*executionEnvironment); + if (!hwDeviceIds.empty()) { + executionEnvironment->prepareRootDeviceEnvironments(static_cast(hwDeviceIds.size())); + uint32_t rootDeviceIndex = 0u; + for (auto &hwDeviceId : hwDeviceIds) { + if (!executionEnvironment->rootDeviceEnvironments[rootDeviceIndex]->initOsInterface(std::move(hwDeviceId), rootDeviceIndex)) { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, + "OsInterface initialization failed for device : %d\n", rootDeviceIndex); + *result = ZE_RESULT_ERROR_UNINITIALIZED; + executionEnvironment->decRefInternal(); + return; + } + rootDeviceIndex++; + } + + GlobalDriverHandle = SysmanDriverHandle::create(*executionEnvironment, result); + if (GlobalDriverHandle != nullptr) { + *result = ZE_RESULT_SUCCESS; + } + } else { + NEO::printDebugString(NEO::DebugManager.flags.PrintDebugMessages.get(), stderr, + "%s\n", "No devices found"); + *result = ZE_RESULT_ERROR_UNINITIALIZED; + } + executionEnvironment->decRefInternal(); +} + +ze_result_t SysmanDriverImp::initStatus(ZE_RESULT_ERROR_UNINITIALIZED); + +ze_result_t SysmanDriverImp::driverInit(zes_init_flags_t flags) { + std::call_once(initDriverOnce, [this]() { + ze_result_t result; + this->initialize(&result); + initStatus = result; + }); + return initStatus; +} + +SysmanDriverImp::~SysmanDriverImp() { + if (GlobalDriverHandle != nullptr) { + delete GlobalDriverHandle; + GlobalDriverHandle = nullptr; + } +} + +ze_result_t driverHandleGet(uint32_t *pCount, zes_driver_handle_t *phDriverHandles) { + if (*pCount == 0) { + *pCount = driverCount; + return ZE_RESULT_SUCCESS; + } + + if (*pCount > driverCount) { + *pCount = driverCount; + } + + if (phDriverHandles == nullptr) { + return ZE_RESULT_ERROR_INVALID_NULL_POINTER; + } + + for (uint32_t i = 0; i < *pCount; i++) { + phDriverHandles[i] = GlobalDriverHandle; + } + + return ZE_RESULT_SUCCESS; +} + +static SysmanDriverImp driverImp; +SysmanDriver *SysmanDriver::driver = &driverImp; + +ze_result_t init(zes_init_flags_t flags) { + if (flags && !(flags & ZE_INIT_FLAG_GPU_ONLY)) { + return ZE_RESULT_ERROR_UNINITIALIZED; + } else { + return SysmanDriver::get()->driverInit(flags); + } +} + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/sysman_driver.h b/level_zero/sysman/source/sysman_driver.h new file mode 100644 index 0000000000..02869d36e1 --- /dev/null +++ b/level_zero/sysman/source/sysman_driver.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include +#include + +#include +namespace L0 { +namespace Sysman { +struct SysmanDriver { + virtual ze_result_t driverInit(zes_init_flags_t flags) = 0; + virtual void initialize(ze_result_t *result) = 0; + static SysmanDriver *get() { return driver; } + virtual ~SysmanDriver() = default; + + protected: + static SysmanDriver *driver; +}; + +ze_result_t init(zes_init_flags_t); +ze_result_t driverHandleGet(uint32_t *pCount, ze_driver_handle_t *phDrivers); + +extern uint32_t driverCount; +extern _ze_driver_handle_t *GlobalDriverHandle; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/sysman_driver_handle.h b/level_zero/sysman/source/sysman_driver_handle.h new file mode 100644 index 0000000000..2d5afcf4b1 --- /dev/null +++ b/level_zero/sysman/source/sysman_driver_handle.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "shared/source/execution_environment/execution_environment.h" + +#include "level_zero/core/source/driver/driver_handle.h" +#include +#include + +#include + +namespace L0 { +namespace Sysman { + +struct SysmanDriverHandle : _ze_driver_handle_t { + static SysmanDriverHandle *fromHandle(zes_driver_handle_t handle) { return static_cast(handle); } + inline zes_driver_handle_t toHandle() { return this; } + + SysmanDriverHandle &operator=(const SysmanDriverHandle &) = delete; + SysmanDriverHandle &operator=(SysmanDriverHandle &&) = delete; + + static SysmanDriverHandle *create(NEO::ExecutionEnvironment &executionEnvironment, ze_result_t *returnValue); + virtual ze_result_t getDevice(uint32_t *pCount, zes_device_handle_t *phDevices) = 0; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/sysman_driver_handle_imp.cpp b/level_zero/sysman/source/sysman_driver_handle_imp.cpp new file mode 100644 index 0000000000..a578ff3bb7 --- /dev/null +++ b/level_zero/sysman/source/sysman_driver_handle_imp.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "level_zero/sysman/source/sysman_driver_handle_imp.h" + +#include "shared/source/debug_settings/debug_settings_manager.h" +#include "shared/source/execution_environment/execution_environment.h" +#include "shared/source/execution_environment/root_device_environment.h" +#include "shared/source/helpers/hw_info.h" +#include "shared/source/os_interface/os_interface.h" + +#include "level_zero/sysman/source/sysman_device.h" +#include "level_zero/sysman/source/sysman_driver.h" + +#include +#include + +namespace L0 { +namespace Sysman { + +struct SysmanDriverHandleImp *GlobalDriver; + +SysmanDriverHandleImp::SysmanDriverHandleImp() = default; + +ze_result_t SysmanDriverHandleImp::initialize(NEO::ExecutionEnvironment &executionEnvironment) { + for (uint32_t rootDeviceIndex = 0u; rootDeviceIndex < executionEnvironment.rootDeviceEnvironments.size(); rootDeviceIndex++) { + if (!executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->getHardwareInfo()->capabilityTable.levelZeroSupported) { + continue; + } + auto pSysmanDevice = SysmanDevice::create(executionEnvironment, rootDeviceIndex); + this->sysmanDevices.push_back(pSysmanDevice); + } + + if (this->sysmanDevices.size() == 0) { + return ZE_RESULT_ERROR_UNINITIALIZED; + } + this->numDevices = static_cast(this->sysmanDevices.size()); + return ZE_RESULT_SUCCESS; +} + +SysmanDriverHandle *SysmanDriverHandle::create(NEO::ExecutionEnvironment &executionEnvironment, ze_result_t *returnValue) { + SysmanDriverHandleImp *driverHandle = new SysmanDriverHandleImp; + UNRECOVERABLE_IF(nullptr == driverHandle); + + ze_result_t res = driverHandle->initialize(executionEnvironment); + if (res != ZE_RESULT_SUCCESS) { + delete driverHandle; + driverHandle = nullptr; + *returnValue = res; + return nullptr; + } + + GlobalDriver = driverHandle; + + return driverHandle; +} + +ze_result_t SysmanDriverHandleImp::getDevice(uint32_t *pCount, zes_device_handle_t *phDevices) { + if (*pCount == 0) { + *pCount = this->numDevices; + return ZE_RESULT_SUCCESS; + } + + if (*pCount > this->numDevices) { + *pCount = this->numDevices; + } + + if (phDevices == nullptr) { + return ZE_RESULT_ERROR_INVALID_NULL_HANDLE; + } + + for (uint32_t i = 0; i < *pCount; i++) { + phDevices[i] = this->sysmanDevices[i]; + } + + return ZE_RESULT_SUCCESS; +} + +SysmanDriverHandleImp::~SysmanDriverHandleImp() { + for (auto &device : this->sysmanDevices) { + delete device; + } + this->sysmanDevices.clear(); +} + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/sysman_driver_handle_imp.h b/level_zero/sysman/source/sysman_driver_handle_imp.h new file mode 100644 index 0000000000..7e93d84c1f --- /dev/null +++ b/level_zero/sysman/source/sysman_driver_handle_imp.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "level_zero/sysman/source/sysman_driver_handle.h" + +namespace L0 { +namespace Sysman { +struct SysmanDevice; +struct SysmanDriverHandleImp : SysmanDriverHandle { + ~SysmanDriverHandleImp() override; + SysmanDriverHandleImp(); + ze_result_t initialize(NEO::ExecutionEnvironment &executionEnvironment); + ze_result_t getDevice(uint32_t *pCount, zes_device_handle_t *phDevices) override; + std::vector sysmanDevices; + uint32_t numDevices = 0; +}; + +extern struct SysmanDriverHandleImp *GlobalDriver; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/source/sysman_driver_imp.h b/level_zero/sysman/source/sysman_driver_imp.h new file mode 100644 index 0000000000..3fd84bd4bc --- /dev/null +++ b/level_zero/sysman/source/sysman_driver_imp.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "level_zero/sysman/source/sysman_driver.h" + +#include + +namespace L0 { +namespace Sysman { + +class SysmanDriverImp : public SysmanDriver { + public: + ze_result_t driverInit(zes_init_flags_t flags) override; + + void initialize(ze_result_t *result) override; + ~SysmanDriverImp() override; + + protected: + std::once_flag initDriverOnce; + static ze_result_t initStatus; +}; + +} // namespace Sysman +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/CMakeLists.txt b/level_zero/sysman/test/unit_tests/sources/CMakeLists.txt new file mode 100644 index 0000000000..0a1eb84022 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/CMakeLists.txt @@ -0,0 +1,13 @@ +# +# Copyright (C) 2023 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +target_sources(${TARGET_NAME} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/mock_sysman_driver.h + ${CMAKE_CURRENT_SOURCE_DIR}/test_sysman_driver.cpp +) + +add_subdirectories() diff --git a/level_zero/sysman/test/unit_tests/sources/mock_sysman_driver.h b/level_zero/sysman/test/unit_tests/sources/mock_sysman_driver.h new file mode 100644 index 0000000000..6da7c00b20 --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/mock_sysman_driver.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once +#include "level_zero/sysman/source/sysman_driver_imp.h" + +namespace L0 { +namespace ult { +namespace Sysman { + +struct MockSysmanDriver : public ::L0::Sysman::SysmanDriverImp { + MockSysmanDriver() { + previousDriver = driver; + driver = this; + } + ~MockSysmanDriver() override { + driver = previousDriver; + } + + ze_result_t driverInit(ze_init_flags_t flag) override { + initCalledCount++; + return ZE_RESULT_SUCCESS; + } + + ::L0::Sysman::SysmanDriver *previousDriver = nullptr; + uint32_t initCalledCount = 0; +}; + +} // namespace Sysman +} // namespace ult +} // namespace L0 diff --git a/level_zero/sysman/test/unit_tests/sources/test_sysman_driver.cpp b/level_zero/sysman/test/unit_tests/sources/test_sysman_driver.cpp new file mode 100644 index 0000000000..c335de9eeb --- /dev/null +++ b/level_zero/sysman/test/unit_tests/sources/test_sysman_driver.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/helpers/hw_info.h" +#include "shared/test/common/helpers/default_hw_info.h" +#include "shared/test/common/mocks/mock_execution_environment.h" + +#include "level_zero/sysman/source/sysman_device.h" +#include "level_zero/sysman/source/sysman_driver_handle.h" +#include "level_zero/sysman/source/sysman_driver_handle_imp.h" +#include "level_zero/sysman/test/unit_tests/sources/mock_sysman_driver.h" + +#include "gtest/gtest.h" + +#include + +namespace L0 { +namespace ult { +namespace Sysman { + +TEST(zesInit, whenCallingZesInitThenInitializeOnDriverIsCalled) { + MockSysmanDriver driver; + + auto result = zesInit(ZE_INIT_FLAG_GPU_ONLY); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(1u, driver.initCalledCount); +} + +TEST(zesInit, whenCallingZesInitWithNoFlagsThenInitializeOnDriverIsCalled) { + MockSysmanDriver driver; + + auto result = zesInit(0); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(1u, driver.initCalledCount); +} + +TEST(zesInit, whenCallingZesInitWithoutGpuOnlyFlagThenInitializeOnDriverIsNotCalled) { + MockSysmanDriver driver; + + auto result = zesInit(ZE_INIT_FLAG_VPU_ONLY); + EXPECT_EQ(ZE_RESULT_ERROR_UNINITIALIZED, result); + EXPECT_EQ(0u, driver.initCalledCount); +} + +struct SysmanDriverTestMultipleFamilySupport : public ::testing::Test { + void SetUp() override { + executionEnvironment = new NEO::ExecutionEnvironment(); + executionEnvironment->prepareRootDeviceEnvironments(numRootDevices); + for (auto i = 0u; i < numRootDevices; i++) { + executionEnvironment->rootDeviceEnvironments[i]->setHwInfoAndInitHelpers(NEO::defaultHwInfo.get()); + if (i < numSupportedRootDevices) { + executionEnvironment->rootDeviceEnvironments[i]->getMutableHardwareInfo()->capabilityTable.levelZeroSupported = true; + } else { + executionEnvironment->rootDeviceEnvironments[i]->getMutableHardwareInfo()->capabilityTable.levelZeroSupported = false; + } + } + } + + NEO::ExecutionEnvironment *executionEnvironment = nullptr; + const uint32_t numRootDevices = 3u; + const uint32_t numSubDevices = 2u; + const uint32_t numSupportedRootDevices = 2u; +}; + +TEST_F(SysmanDriverTestMultipleFamilySupport, whenInitializingSysmanDriverWithArrayOfDevicesThenDriverIsInitializedOnlyWithThoseSupported) { + ze_result_t returnValue; + + auto driverHandle = L0::Sysman::SysmanDriverHandle::create(*executionEnvironment, &returnValue); + EXPECT_NE(nullptr, driverHandle); + + L0::Sysman::SysmanDriverHandleImp *driverHandleImp = reinterpret_cast(driverHandle); + EXPECT_EQ(numSupportedRootDevices, driverHandleImp->sysmanDevices.size()); + + for (auto d : driverHandleImp->sysmanDevices) { + EXPECT_TRUE(d->getHardwareInfo().capabilityTable.levelZeroSupported); + } + + delete driverHandle; + L0::Sysman::GlobalDriver = nullptr; +} + +struct SysmanDriverTestMultipleFamilyNoSupport : public ::testing::Test { + void SetUp() override { + executionEnvironment = new NEO::ExecutionEnvironment(); + executionEnvironment->prepareRootDeviceEnvironments(numRootDevices); + for (auto i = 0u; i < executionEnvironment->rootDeviceEnvironments.size(); i++) { + executionEnvironment->rootDeviceEnvironments[i]->setHwInfoAndInitHelpers(NEO::defaultHwInfo.get()); + } + + for (auto i = 0u; i < executionEnvironment->rootDeviceEnvironments.size(); i++) { + executionEnvironment->rootDeviceEnvironments[i]->getMutableHardwareInfo()->capabilityTable.levelZeroSupported = false; + } + } + + NEO::ExecutionEnvironment *executionEnvironment = nullptr; + const uint32_t numRootDevices = 3u; +}; + +TEST_F(SysmanDriverTestMultipleFamilyNoSupport, whenInitializingSysmanDriverWithArrayOfNotSupportedDevicesThenDriverIsNull) { + ze_result_t returnValue; + this->executionEnvironment->incRefInternal(); + auto driverHandle = L0::Sysman::SysmanDriverHandle::create(*executionEnvironment, &returnValue); + EXPECT_EQ(nullptr, driverHandle); + EXPECT_EQ(returnValue, ZE_RESULT_ERROR_UNINITIALIZED); + this->executionEnvironment->decRefInternal(); +} + +struct SysmanDriverHandleTest : public ::testing::Test { + void SetUp() override { + + ze_result_t returnValue; + NEO::HardwareInfo hwInfo = *NEO::defaultHwInfo.get(); + hwInfo.capabilityTable.levelZeroSupported = true; + + executionEnvironment = new NEO::ExecutionEnvironment(); + executionEnvironment->prepareRootDeviceEnvironments(numRootDevices); + for (auto i = 0u; i < executionEnvironment->rootDeviceEnvironments.size(); i++) { + executionEnvironment->rootDeviceEnvironments[i]->setHwInfoAndInitHelpers(NEO::defaultHwInfo.get()); + // executionEnvironment->rootDeviceEnvironments[i]->initGmm(); + } + + driverHandle = L0::Sysman::SysmanDriverHandle::create(*executionEnvironment, &returnValue); + L0::Sysman::GlobalDriverHandle = driverHandle; + } + void TearDown() override { + delete driverHandle; + L0::Sysman::GlobalDriver = nullptr; + L0::Sysman::GlobalDriverHandle = nullptr; + } + L0::Sysman::SysmanDriverHandle *driverHandle; + NEO::ExecutionEnvironment *executionEnvironment = nullptr; + const uint32_t numRootDevices = 3u; +}; + +TEST_F(SysmanDriverHandleTest, givenInitializedDriverWhenZesDriverGetIsCalledThenDriverHandleCountIsObtained) { + uint32_t count = 0; + auto result = zesDriverGet(&count, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(1U, count); +} + +TEST_F(SysmanDriverHandleTest, + givenInitializedDriverWhenZesDriverGetIsCalledWithGreaterThanCountAvailableThenCorrectCountIsReturned) { + uint32_t count = 0; + ze_result_t result = zesDriverGet(&count, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(1U, count); + + count++; + ze_driver_handle_t driverHandle = {}; + result = zesDriverGet(&count, &driverHandle); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(1U, count); + EXPECT_NE(nullptr, driverHandle); +} + +TEST_F(SysmanDriverHandleTest, + givenInitializedDriverWhenZesDriverGetIsCalledWithGreaterThanZeroCountAndNullDriverHandleThenInvalidNullPointerIsReturned) { + uint32_t count = 0; + ze_result_t result = zesDriverGet(&count, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(1U, count); + + result = zesDriverGet(&count, nullptr); + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_NULL_POINTER, result); +} + +TEST_F(SysmanDriverHandleTest, givenInitializedDriverWhenZesDriverGetIsCalledThenDriverHandleIsObtained) { + ze_result_t result = ZE_RESULT_SUCCESS; + uint32_t count = 0; + result = zesDriverGet(&count, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(1U, count); + + ze_driver_handle_t *phDriverHandles = new ze_driver_handle_t[count]; + + result = zesDriverGet(&count, phDriverHandles); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(driverHandle->toHandle(), phDriverHandles[0]); + delete[] phDriverHandles; +} + +TEST_F(SysmanDriverHandleTest, givenInitializedDriverWhenZesDriverGetIsCalledThenGlobalDriverHandleIsObtained) { + ze_result_t result = ZE_RESULT_SUCCESS; + + uint32_t count = 1; + zes_driver_handle_t hDriverHandle = reinterpret_cast(&hDriverHandle); + + result = zesDriverGet(&count, &hDriverHandle); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(nullptr, hDriverHandle); + EXPECT_EQ(hDriverHandle, L0::Sysman::GlobalDriver); +} + +TEST_F(SysmanDriverHandleTest, givenInitializedDriverWhenGetDeviceIsCalledThenOneDeviceIsObtained) { + ze_result_t result = ZE_RESULT_SUCCESS; + uint32_t count = 1; + + ze_device_handle_t device; + result = driverHandle->getDevice(&count, &device); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(nullptr, &device); +} + +TEST_F(SysmanDriverHandleTest, whenQueryingForDevicesWithCountGreaterThanZeroAndNullDevicePointerThenNullHandleIsReturned) { + uint32_t count = 1; + ze_result_t result = driverHandle->getDevice(&count, nullptr); + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_NULL_HANDLE, result); +} + +} // namespace Sysman +} // namespace ult +} // namespace L0 diff --git a/level_zero/tools/source/sysman/sysman.cpp b/level_zero/tools/source/sysman/sysman.cpp index 536bd15550..d423523838 100644 --- a/level_zero/tools/source/sysman/sysman.cpp +++ b/level_zero/tools/source/sysman/sysman.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2022 Intel Corporation + * Copyright (C) 2020-2023 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -18,6 +18,7 @@ #include namespace L0 { +bool sysmanInitFromCore = false; void DeviceImp::createSysmanHandle(bool isSubDevice) { if (static_cast(driverHandle)->enableSysman && !isSubDevice) { @@ -35,6 +36,8 @@ SysmanDevice *SysmanDeviceHandleContext::init(ze_device_handle_t coreDevice) { delete sysmanDevice; sysmanDevice = nullptr; } + sysmanInitFromCore = true; + L0::DeviceImp *device = static_cast(Device::fromHandle(coreDevice)); for (auto &subDevice : device->subDevices) { static_cast(subDevice)->setSysmanHandle(sysmanDevice);