mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-21 09:14:47 +08:00
Extend DRM mock and queryTopology tests - part 1
Signed-off-by: Daniel Chabrowski daniel.chabrowski@intel.com Related-To: NEO-6591
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
452de80d70
commit
f2c4231a27
@@ -50,7 +50,7 @@ class ZesEngineFixture : public SysmanDeviceFixture {
|
||||
|
||||
EngineHandleContext *pEngineHandleContext = pSysmanDeviceImp->pEngineHandleContext;
|
||||
pDrm = std::make_unique<NiceMock<Mock<EngineNeoDrm>>>(const_cast<NEO::RootDeviceEnvironment &>(neoDevice->getRootDeviceEnvironment()));
|
||||
pDrm->setupIoctlHelper();
|
||||
pDrm->setupIoctlHelper(neoDevice->getRootDeviceEnvironment().getHardwareInfo()->platform.eProductFamily);
|
||||
pPmuInterface = std::make_unique<NiceMock<Mock<MockPmuInterfaceImp>>>(pLinuxSysmanImp);
|
||||
pOriginalDrm = pLinuxSysmanImp->pDrm;
|
||||
pOriginalPmuInterface = pLinuxSysmanImp->pPmuInterface;
|
||||
|
||||
@@ -32,7 +32,7 @@ constexpr int mockFd = 0;
|
||||
class SysmanMockDrm : public Drm {
|
||||
public:
|
||||
SysmanMockDrm(RootDeviceEnvironment &rootDeviceEnvironment) : Drm(std::make_unique<HwDeviceIdDrm>(mockFd, ""), rootDeviceEnvironment) {
|
||||
setupIoctlHelper();
|
||||
setupIoctlHelper(rootDeviceEnvironment.getHardwareInfo()->platform.eProductFamily);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class DrmCommandStreamTest : public ::testing::Test {
|
||||
|
||||
auto hwInfo = executionEnvironment.rootDeviceEnvironments[0]->getHardwareInfo();
|
||||
mock->createVirtualMemoryAddressSpace(HwHelper::getSubDevicesCount(hwInfo));
|
||||
mock->setupIoctlHelper();
|
||||
mock->setupIoctlHelper(hwInfo->platform.eProductFamily);
|
||||
osContext = std::make_unique<OsContextLinux>(*mock, 0u,
|
||||
EngineDescriptorHelper::getDefaultDescriptor(HwHelper::get(hwInfo->platform.eRenderCoreFamily).getGpgpuEngineInstances(*hwInfo)[0],
|
||||
PreemptionHelper::getDefaultPreemptionMode(*hwInfo)));
|
||||
|
||||
@@ -20,7 +20,7 @@ class DrmTipMock : public DrmMock {
|
||||
DrmTipMock(RootDeviceEnvironment &rootDeviceEnvironment) : DrmTipMock(rootDeviceEnvironment, defaultHwInfo.get()) {}
|
||||
DrmTipMock(RootDeviceEnvironment &rootDeviceEnvironment, const HardwareInfo *inputHwInfo) : DrmMock(rootDeviceEnvironment) {
|
||||
rootDeviceEnvironment.setHwInfo(inputHwInfo);
|
||||
setupIoctlHelper();
|
||||
setupIoctlHelper(inputHwInfo->platform.eProductFamily);
|
||||
}
|
||||
|
||||
uint32_t i915QuerySuccessCount = std::numeric_limits<uint32_t>::max();
|
||||
|
||||
@@ -736,6 +736,7 @@ TEST(DrmQueryTest, GivenDrmWhenSetupHardwareInfoCalledThenCorrectMaxValuesInGtSy
|
||||
auto setupHardwareInfo = [](HardwareInfo *, bool) {};
|
||||
DeviceDescriptor device = {0, hwInfo, setupHardwareInfo};
|
||||
|
||||
drm.ioctlHelper.reset();
|
||||
drm.setupHardwareInfo(&device, false);
|
||||
EXPECT_NE(nullptr, drm.getIoctlHelper());
|
||||
EXPECT_EQ(NEO::defaultHwInfo->gtSystemInfo.MaxSlicesSupported, hwInfo->gtSystemInfo.MaxSlicesSupported);
|
||||
@@ -1005,7 +1006,8 @@ TEST(DrmQueryTest, givenUapiPrelimVersionWithInvalidPathThenReturnEmptyString) {
|
||||
}
|
||||
|
||||
TEST(DrmTest, givenInvalidUapiPrelimVersionThenFallbackToBasePrelim) {
|
||||
std::unique_ptr<IoctlHelper> ioctlHelper(IoctlHelper::get(defaultHwInfo.get(), "-1"));
|
||||
const auto productFamily = defaultHwInfo.get()->platform.eProductFamily;
|
||||
std::unique_ptr<IoctlHelper> ioctlHelper(IoctlHelper::get(productFamily, "-1"));
|
||||
EXPECT_NE(nullptr, ioctlHelper.get());
|
||||
}
|
||||
|
||||
@@ -1192,7 +1194,9 @@ TEST(DrmTest, givenSetupIoctlHelperThenIoctlHelperNotNull) {
|
||||
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
|
||||
drm.ioctlHelper.reset(nullptr);
|
||||
drm.setupIoctlHelper();
|
||||
|
||||
const auto productFamily = executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo()->platform.eProductFamily;
|
||||
drm.setupIoctlHelper(productFamily);
|
||||
|
||||
EXPECT_NE(nullptr, drm.ioctlHelper.get());
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class IoctlHelperPrelimFixture : public ::testing::Test {
|
||||
executionEnvironment = std::make_unique<ExecutionEnvironment>();
|
||||
executionEnvironment->prepareRootDeviceEnvironments(1);
|
||||
drm = std::make_unique<DrmPrelimMock>(*executionEnvironment->rootDeviceEnvironments[0]);
|
||||
drm->setupIoctlHelper();
|
||||
drm->setupIoctlHelper(executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo()->platform.eProductFamily);
|
||||
}
|
||||
|
||||
std::unique_ptr<ExecutionEnvironment> executionEnvironment;
|
||||
|
||||
@@ -369,3 +369,4 @@ ForceExtendedBufferSize = -1
|
||||
MakeIndirectAllocationsResidentAsPack = -1
|
||||
EnableChipsetUniqueUUID = -1
|
||||
ForceSimdMessageSizeInWalker = -1
|
||||
UseNewQueryTopoIoctl = 1
|
||||
|
||||
@@ -73,6 +73,7 @@ DECLARE_DEBUG_VARIABLE(bool, AllowMixingRegularAndCooperativeKernels, false, "tr
|
||||
DECLARE_DEBUG_VARIABLE(bool, AllowPatchingVfeStateInCommandLists, false, "true: MEDIA_VFE_STATE may be programmed in a command list")
|
||||
DECLARE_DEBUG_VARIABLE(bool, PrintMemoryRegionSizes, false, "print memory bank type, instance and it's size")
|
||||
DECLARE_DEBUG_VARIABLE(bool, UpdateCrossThreadDataSize, false, "Turn on cross thread data size calculation for PATCH TOKEN binary")
|
||||
DECLARE_DEBUG_VARIABLE(bool, UseNewQueryTopoIoctl, true, "Use DRM_I915_QUERY_COMPUTE_SLICES")
|
||||
DECLARE_DEBUG_VARIABLE(std::string, ForceDeviceId, std::string("unk"), "DeviceId selected for testing")
|
||||
DECLARE_DEBUG_VARIABLE(std::string, FilterDeviceId, std::string("unk"), "Device id filter, adapter matching device id will be opened. Ignored when unk.")
|
||||
DECLARE_DEBUG_VARIABLE(std::string, FilterBdfPath, std::string("unk"), "Linux-only, BDF path filter, only matching paths will be opened. Ignored when unk.")
|
||||
|
||||
@@ -481,6 +481,9 @@ int Drm::setupHardwareInfo(DeviceDescriptor *device, bool setupFeatureTableAndWo
|
||||
HardwareInfo *hwInfo = const_cast<HardwareInfo *>(device->pHwInfo);
|
||||
int ret;
|
||||
|
||||
const auto productFamily = hwInfo->platform.eProductFamily;
|
||||
setupIoctlHelper(productFamily);
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
|
||||
bool status = queryTopology(*hwInfo, topologyData);
|
||||
@@ -506,7 +509,6 @@ int Drm::setupHardwareInfo(DeviceDescriptor *device, bool setupFeatureTableAndWo
|
||||
hwInfo->gtSystemInfo.DualSubSliceCount = static_cast<uint32_t>(topologyData.subSliceCount);
|
||||
hwInfo->gtSystemInfo.EUCount = static_cast<uint32_t>(topologyData.euCount);
|
||||
rootDeviceEnvironment.setHwInfo(hwInfo);
|
||||
setupIoctlHelper();
|
||||
|
||||
status = querySystemInfo();
|
||||
if (status) {
|
||||
@@ -1081,11 +1083,82 @@ bool Drm::completionFenceSupport() {
|
||||
return completionFenceSupported;
|
||||
}
|
||||
|
||||
void Drm::setupIoctlHelper() {
|
||||
auto hwInfo = rootDeviceEnvironment.getHardwareInfo();
|
||||
void Drm::setupIoctlHelper(const PRODUCT_FAMILY productFamily) {
|
||||
std::string prelimVersion = "";
|
||||
getPrelimVersion(prelimVersion);
|
||||
this->ioctlHelper.reset(IoctlHelper::get(hwInfo, prelimVersion));
|
||||
this->ioctlHelper.reset(IoctlHelper::get(productFamily, prelimVersion));
|
||||
}
|
||||
|
||||
bool Drm::queryTopology(const HardwareInfo &hwInfo, QueryTopologyData &topologyData) {
|
||||
topologyData.sliceCount = 0;
|
||||
topologyData.subSliceCount = 0;
|
||||
topologyData.euCount = 0;
|
||||
|
||||
int sliceCount = 0;
|
||||
int subSliceCount = 0;
|
||||
int euCount = 0;
|
||||
|
||||
const auto queryComputeSlicesIoctl = ioctlHelper->getComputeSlicesIoctlVal();
|
||||
if (DebugManager.flags.UseNewQueryTopoIoctl.get() && this->engineInfo && hwInfo.gtSystemInfo.MultiTileArchInfo.TileCount > 0 && queryComputeSlicesIoctl != 0) {
|
||||
bool success = true;
|
||||
|
||||
for (uint32_t i = 0; i < hwInfo.gtSystemInfo.MultiTileArchInfo.TileCount; i++) {
|
||||
auto classInstance = this->engineInfo->getEngineInstance(i, hwInfo.capabilityTable.defaultEngineType);
|
||||
UNRECOVERABLE_IF(!classInstance);
|
||||
|
||||
uint32_t flags = classInstance->engineClass;
|
||||
flags |= (classInstance->engineInstance << 8);
|
||||
|
||||
auto dataQuery = this->query(queryComputeSlicesIoctl, flags);
|
||||
if (dataQuery.empty()) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
auto data = reinterpret_cast<drm_i915_query_topology_info *>(dataQuery.data());
|
||||
|
||||
QueryTopologyData tileTopologyData = {};
|
||||
TopologyMapping mapping;
|
||||
if (!translateTopologyInfo(data, tileTopologyData, mapping)) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// pick smallest config
|
||||
sliceCount = (sliceCount == 0) ? tileTopologyData.sliceCount : std::min(sliceCount, tileTopologyData.sliceCount);
|
||||
subSliceCount = (subSliceCount == 0) ? tileTopologyData.subSliceCount : std::min(subSliceCount, tileTopologyData.subSliceCount);
|
||||
euCount = (euCount == 0) ? tileTopologyData.euCount : std::min(euCount, tileTopologyData.euCount);
|
||||
|
||||
topologyData.maxSliceCount = std::max(topologyData.maxSliceCount, tileTopologyData.maxSliceCount);
|
||||
topologyData.maxSubSliceCount = std::max(topologyData.maxSubSliceCount, tileTopologyData.maxSubSliceCount);
|
||||
topologyData.maxEuCount = std::max(topologyData.maxEuCount, static_cast<int>(data->max_eus_per_subslice));
|
||||
|
||||
this->topologyMap[i] = mapping;
|
||||
}
|
||||
|
||||
if (success) {
|
||||
topologyData.sliceCount = sliceCount;
|
||||
topologyData.subSliceCount = subSliceCount;
|
||||
topologyData.euCount = euCount;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// fallback to DRM_I915_QUERY_TOPOLOGY_INFO
|
||||
|
||||
auto dataQuery = this->query(DRM_I915_QUERY_TOPOLOGY_INFO, DrmQueryItemFlags::topology);
|
||||
if (dataQuery.empty()) {
|
||||
return false;
|
||||
}
|
||||
auto data = reinterpret_cast<drm_i915_query_topology_info *>(dataQuery.data());
|
||||
|
||||
TopologyMapping mapping;
|
||||
auto retVal = translateTopologyInfo(data, topologyData, mapping);
|
||||
topologyData.maxEuCount = data->max_eus_per_subslice;
|
||||
|
||||
this->topologyMap.clear();
|
||||
this->topologyMap[0] = mapping;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
} // namespace NEO
|
||||
|
||||
@@ -267,7 +267,7 @@ class Drm : public DriverModel {
|
||||
std::string getSysFsPciPath();
|
||||
std::vector<uint8_t> query(uint32_t queryId, uint32_t queryItemFlags);
|
||||
void printIoctlStatistics();
|
||||
void setupIoctlHelper();
|
||||
void setupIoctlHelper(const PRODUCT_FAMILY productFamily);
|
||||
|
||||
#pragma pack(1)
|
||||
struct PCIConfig {
|
||||
|
||||
@@ -49,23 +49,6 @@ int Drm::createDrmVirtualMemory(uint32_t &drmVmId) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Drm::queryTopology(const HardwareInfo &hwInfo, QueryTopologyData &topologyData) {
|
||||
auto dataQuery = this->query(DRM_I915_QUERY_TOPOLOGY_INFO, DrmQueryItemFlags::topology);
|
||||
if (dataQuery.empty()) {
|
||||
return false;
|
||||
}
|
||||
auto data = reinterpret_cast<drm_i915_query_topology_info *>(dataQuery.data());
|
||||
|
||||
topologyData.maxSliceCount = data->max_slices;
|
||||
topologyData.maxSubSliceCount = data->max_subslices;
|
||||
topologyData.maxEuCount = data->max_eus_per_subslice;
|
||||
|
||||
TopologyMapping mapping;
|
||||
auto result = translateTopologyInfo(data, topologyData, mapping);
|
||||
this->topologyMap[0] = mapping;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Drm::isDebugAttachAvailable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ using MemRegionsVec = StackVec<MemoryClassInstance, 5>;
|
||||
class IoctlHelper {
|
||||
public:
|
||||
virtual ~IoctlHelper() {}
|
||||
static IoctlHelper *get(const HardwareInfo *hwInfo, const std::string &prelimVersion);
|
||||
static IoctlHelper *get(const PRODUCT_FAMILY productFamily, const std::string &prelimVersion);
|
||||
static uint32_t ioctl(Drm *drm, unsigned long request, void *arg);
|
||||
virtual IoctlHelper *clone() = 0;
|
||||
|
||||
@@ -77,6 +77,7 @@ class IoctlHelper {
|
||||
virtual uint32_t getDirectSubmissionFlag() = 0;
|
||||
virtual int32_t getMemRegionsIoctlVal() = 0;
|
||||
virtual int32_t getEngineInfoIoctlVal() = 0;
|
||||
virtual uint32_t getComputeSlicesIoctlVal() = 0;
|
||||
virtual std::vector<EngineCapabilities> translateToEngineCaps(const std::vector<uint8_t> &data) = 0;
|
||||
virtual uint32_t queryDistances(Drm *drm, std::vector<drm_i915_query_item> &queryItems, std::vector<DistanceInfo> &distanceInfos) = 0;
|
||||
virtual int32_t getComputeEngineClass() = 0;
|
||||
@@ -102,6 +103,7 @@ class IoctlHelperUpstream : public IoctlHelper {
|
||||
uint32_t getDirectSubmissionFlag() override;
|
||||
int32_t getMemRegionsIoctlVal() override;
|
||||
int32_t getEngineInfoIoctlVal() override;
|
||||
uint32_t getComputeSlicesIoctlVal() override;
|
||||
std::vector<EngineCapabilities> translateToEngineCaps(const std::vector<uint8_t> &data) override;
|
||||
uint32_t queryDistances(Drm *drm, std::vector<drm_i915_query_item> &queryItems, std::vector<DistanceInfo> &distanceInfos) override;
|
||||
int32_t getComputeEngineClass() override;
|
||||
@@ -140,6 +142,7 @@ class IoctlHelperPrelim20 : public IoctlHelper {
|
||||
uint32_t getDirectSubmissionFlag() override;
|
||||
int32_t getMemRegionsIoctlVal() override;
|
||||
int32_t getEngineInfoIoctlVal() override;
|
||||
uint32_t getComputeSlicesIoctlVal() override;
|
||||
std::vector<EngineCapabilities> translateToEngineCaps(const std::vector<uint8_t> &data) override;
|
||||
uint32_t queryDistances(Drm *drm, std::vector<drm_i915_query_item> &queryItems, std::vector<DistanceInfo> &distanceInfos) override;
|
||||
int32_t getComputeEngineClass() override;
|
||||
|
||||
@@ -20,10 +20,8 @@ std::map<std::string, std::shared_ptr<IoctlHelper>> ioctlHelperImpls{
|
||||
{"", std::make_shared<IoctlHelperUpstream>()},
|
||||
{"2.0", std::make_shared<IoctlHelperPrelim20>()}};
|
||||
|
||||
IoctlHelper *IoctlHelper::get(const HardwareInfo *hwInfo, const std::string &prelimVersion) {
|
||||
auto product = hwInfo->platform.eProductFamily;
|
||||
|
||||
auto productSpecificIoctlHelper = ioctlHelperFactory[product];
|
||||
IoctlHelper *IoctlHelper::get(const PRODUCT_FAMILY productFamily, const std::string &prelimVersion) {
|
||||
auto productSpecificIoctlHelper = ioctlHelperFactory[productFamily];
|
||||
if (productSpecificIoctlHelper) {
|
||||
return productSpecificIoctlHelper->clone();
|
||||
}
|
||||
|
||||
@@ -13,10 +13,8 @@
|
||||
namespace NEO {
|
||||
IoctlHelper *ioctlHelperFactory[IGFX_MAX_PRODUCT] = {};
|
||||
|
||||
IoctlHelper *IoctlHelper::get(const HardwareInfo *hwInfo, const std::string &prelimVersion) {
|
||||
auto product = hwInfo->platform.eProductFamily;
|
||||
|
||||
auto productSpecificIoctlHelper = ioctlHelperFactory[product];
|
||||
IoctlHelper *IoctlHelper::get(const PRODUCT_FAMILY productFamily, const std::string &prelimVersion) {
|
||||
auto productSpecificIoctlHelper = ioctlHelperFactory[productFamily];
|
||||
if (productSpecificIoctlHelper) {
|
||||
return productSpecificIoctlHelper->clone();
|
||||
}
|
||||
|
||||
@@ -194,6 +194,10 @@ int32_t IoctlHelperPrelim20::getEngineInfoIoctlVal() {
|
||||
return PRELIM_DRM_I915_QUERY_ENGINE_INFO;
|
||||
}
|
||||
|
||||
uint32_t IoctlHelperPrelim20::getComputeSlicesIoctlVal() {
|
||||
return PRELIM_DRM_I915_QUERY_COMPUTE_SLICES;
|
||||
}
|
||||
|
||||
std::vector<EngineCapabilities> IoctlHelperPrelim20::translateToEngineCaps(const std::vector<uint8_t> &data) {
|
||||
auto engineInfo = reinterpret_cast<const prelim_drm_i915_query_engine_info *>(data.data());
|
||||
std::vector<EngineCapabilities> engines;
|
||||
|
||||
@@ -109,6 +109,10 @@ int32_t IoctlHelperUpstream::getEngineInfoIoctlVal() {
|
||||
return DRM_I915_QUERY_ENGINE_INFO;
|
||||
}
|
||||
|
||||
uint32_t IoctlHelperUpstream::getComputeSlicesIoctlVal() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<EngineCapabilities> IoctlHelperUpstream::translateToEngineCaps(const std::vector<uint8_t> &data) {
|
||||
auto engineInfo = reinterpret_cast<const drm_i915_query_engine_info *>(data.data());
|
||||
std::vector<EngineCapabilities> engines;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2021 Intel Corporation
|
||||
# Copyright (C) 2021-2022 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
@@ -11,6 +11,18 @@ if(UNIX)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drm_mock.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}drm_mock_engine.cpp
|
||||
)
|
||||
|
||||
if(NEO_ENABLE_i915_PRELIM_DETECTION)
|
||||
target_sources(neo_libult_common PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drm_query_mock.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drm_query_mock.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drm_query_mock_context.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drm_query_mock_prelim.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drm_prelim_helper.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drm_prelim_helper.h
|
||||
)
|
||||
endif()
|
||||
|
||||
target_sources(neo_libult PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/directory_linux.cpp
|
||||
)
|
||||
|
||||
@@ -58,7 +58,7 @@ class DrmMock : public Drm {
|
||||
if (!isPerContextVMRequired()) {
|
||||
createVirtualMemoryAddressSpace(HwHelper::getSubDevicesCount(rootDeviceEnvironment.getHardwareInfo()));
|
||||
}
|
||||
setupIoctlHelper();
|
||||
setupIoctlHelper(rootDeviceEnvironment.getHardwareInfo()->platform.eProductFamily);
|
||||
}
|
||||
DrmMock(RootDeviceEnvironment &rootDeviceEnvironment) : DrmMock(mockFd, rootDeviceEnvironment) {}
|
||||
|
||||
|
||||
14
shared/test/common/libult/linux/drm_prelim_helper.cpp
Normal file
14
shared/test/common/libult/linux/drm_prelim_helper.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/test/common/libult/linux/drm_prelim_helper.h"
|
||||
|
||||
#include "third_party/uapi/prelim/drm/i915_drm.h"
|
||||
|
||||
uint32_t getQueryComputeSlicesIoctl() {
|
||||
return PRELIM_DRM_I915_QUERY_COMPUTE_SLICES;
|
||||
}
|
||||
12
shared/test/common/libult/linux/drm_prelim_helper.h
Normal file
12
shared/test/common/libult/linux/drm_prelim_helper.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
uint32_t getQueryComputeSlicesIoctl();
|
||||
35
shared/test/common/libult/linux/drm_query_mock.cpp
Normal file
35
shared/test/common/libult/linux/drm_query_mock.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/test/common/libult/linux/drm_query_mock.h"
|
||||
|
||||
extern int handlePrelimDrmQueryRequests(DrmQueryMockContext &context, unsigned long request, void *arg);
|
||||
extern bool handlePrelimDrmQueryItem(DrmQueryMockContext &context, void *arg);
|
||||
|
||||
int DrmQueryMock::handleRemainingRequests(unsigned long request, void *arg) {
|
||||
if (request == DRM_IOCTL_I915_QUERY && arg) {
|
||||
auto query = static_cast<drm_i915_query *>(arg);
|
||||
if (query->items_ptr == 0) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
for (auto i = 0u; i < query->num_items; ++i) {
|
||||
const auto queryItem = reinterpret_cast<drm_i915_query_item *>(query->items_ptr) + i;
|
||||
if (!this->handleQueryItem(queryItem)) {
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return handlePrelimDrmQueryRequests(context, request, arg);
|
||||
}
|
||||
|
||||
bool DrmQueryMock::handleQueryItem(void *arg) {
|
||||
return handlePrelimDrmQueryItem(context, arg);
|
||||
}
|
||||
40
shared/test/common/libult/linux/drm_query_mock.h
Normal file
40
shared/test/common/libult/linux/drm_query_mock.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared/source/execution_environment/root_device_environment.h"
|
||||
#include "shared/source/os_interface/linux/ioctl_helper.h"
|
||||
#include "shared/test/common/helpers/default_hw_info.h"
|
||||
#include "shared/test/common/libult/linux/drm_mock.h"
|
||||
#include "shared/test/common/libult/linux/drm_query_mock_context.h"
|
||||
|
||||
using namespace NEO;
|
||||
|
||||
class DrmQueryMock : public DrmMock {
|
||||
public:
|
||||
DrmQueryMock(RootDeviceEnvironment &rootDeviceEnvironment) : DrmQueryMock(rootDeviceEnvironment, defaultHwInfo.get()) {}
|
||||
DrmQueryMock(RootDeviceEnvironment &rootDeviceEnvironment, const HardwareInfo *inputHwInfo) : DrmMock(rootDeviceEnvironment) {
|
||||
rootDeviceEnvironment.setHwInfo(inputHwInfo);
|
||||
context.hwInfo = rootDeviceEnvironment.getHardwareInfo();
|
||||
|
||||
setupIoctlHelper(IGFX_UNKNOWN);
|
||||
}
|
||||
|
||||
void getPrelimVersion(std::string &prelimVersion) override {
|
||||
prelimVersion = "2.0";
|
||||
}
|
||||
|
||||
DrmQueryMockContext context{
|
||||
.hwInfo = nullptr,
|
||||
.rootDeviceEnvironment = rootDeviceEnvironment,
|
||||
.failRetTopology = failRetTopology,
|
||||
};
|
||||
|
||||
int handleRemainingRequests(unsigned long request, void *arg) override;
|
||||
virtual bool handleQueryItem(void *queryItem);
|
||||
};
|
||||
17
shared/test/common/libult/linux/drm_query_mock_context.h
Normal file
17
shared/test/common/libult/linux/drm_query_mock_context.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/execution_environment/root_device_environment.h"
|
||||
#include "shared/source/helpers/hw_info.h"
|
||||
|
||||
using namespace NEO;
|
||||
|
||||
struct DrmQueryMockContext {
|
||||
const HardwareInfo *hwInfo;
|
||||
const RootDeviceEnvironment &rootDeviceEnvironment;
|
||||
const bool &failRetTopology;
|
||||
};
|
||||
197
shared/test/common/libult/linux/drm_query_mock_prelim.cpp
Normal file
197
shared/test/common/libult/linux/drm_query_mock_prelim.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/helpers/basic_math.h"
|
||||
#include "shared/source/helpers/ptr_math.h"
|
||||
#include "shared/test/common/libult/linux/drm_query_mock_context.h"
|
||||
|
||||
#include "third_party/uapi/prelim/drm/i915_drm.h"
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <errno.h>
|
||||
|
||||
namespace {
|
||||
|
||||
uint32_t getTileFromEngineOrMemoryInstance(uint16_t instanceValue) {
|
||||
uint8_t tileMask = (instanceValue >> 8);
|
||||
return Math::log2(static_cast<uint64_t>(tileMask));
|
||||
}
|
||||
|
||||
uint16_t getEngineOrMemoryInstanceValue(uint16_t tile, uint16_t id) {
|
||||
EXPECT_TRUE(id < 256);
|
||||
uint16_t tileMask = ((1 << tile) << 8);
|
||||
return (id | tileMask);
|
||||
}
|
||||
|
||||
constexpr BcsInfoMask supportedCopyEnginesMask = 1;
|
||||
|
||||
constexpr std::array<uint64_t, 9> copyEnginesCapsMap = {{
|
||||
PRELIM_I915_COPY_CLASS_CAP_SATURATE_LMEM,
|
||||
PRELIM_I915_COPY_CLASS_CAP_SATURATE_PCIE,
|
||||
PRELIM_I915_COPY_CLASS_CAP_SATURATE_PCIE,
|
||||
PRELIM_I915_COPY_CLASS_CAP_SATURATE_LINK,
|
||||
PRELIM_I915_COPY_CLASS_CAP_SATURATE_LINK,
|
||||
PRELIM_I915_COPY_CLASS_CAP_SATURATE_LINK,
|
||||
PRELIM_I915_COPY_CLASS_CAP_SATURATE_LINK,
|
||||
PRELIM_I915_COPY_CLASS_CAP_SATURATE_LINK,
|
||||
PRELIM_I915_COPY_CLASS_CAP_SATURATE_LINK,
|
||||
}};
|
||||
|
||||
} // namespace
|
||||
|
||||
int handlePrelimDrmQueryRequests(DrmQueryMockContext &context, unsigned long request, void *arg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool handlePrelimDrmQueryItem(DrmQueryMockContext &context, void *arg) {
|
||||
auto queryItem = reinterpret_cast<drm_i915_query_item *>(arg);
|
||||
|
||||
auto >SystemInfo = context.hwInfo->gtSystemInfo;
|
||||
auto numberOfCCS = gtSystemInfo.CCSInfo.IsValid ? gtSystemInfo.CCSInfo.NumberOfCCSEnabled : 0u;
|
||||
|
||||
switch (queryItem->query_id) {
|
||||
case PRELIM_DRM_I915_QUERY_ENGINE_INFO: {
|
||||
auto numberOfTiles = gtSystemInfo.MultiTileArchInfo.IsValid ? gtSystemInfo.MultiTileArchInfo.TileCount : 1u;
|
||||
uint32_t numberOfEngines = numberOfTiles * (4u + numberOfCCS + static_cast<uint32_t>(supportedCopyEnginesMask.count()));
|
||||
int engineInfoSize = sizeof(prelim_drm_i915_query_engine_info) + numberOfEngines * sizeof(prelim_drm_i915_engine_info);
|
||||
if (queryItem->length == 0) {
|
||||
queryItem->length = engineInfoSize;
|
||||
} else {
|
||||
EXPECT_EQ(engineInfoSize, queryItem->length);
|
||||
auto queryEngineInfo = reinterpret_cast<prelim_drm_i915_query_engine_info *>(queryItem->data_ptr);
|
||||
EXPECT_EQ(0u, queryEngineInfo->num_engines);
|
||||
queryEngineInfo->num_engines = numberOfEngines;
|
||||
auto p = queryEngineInfo->engines;
|
||||
for (uint32_t tile = 0u; tile < numberOfTiles; tile++) {
|
||||
p++->engine = {I915_ENGINE_CLASS_RENDER, getEngineOrMemoryInstanceValue(tile, 0)};
|
||||
for (uint32_t i = 0u; i < supportedCopyEnginesMask.size(); i++) {
|
||||
if (supportedCopyEnginesMask.test(i)) {
|
||||
auto copyEngineInfo = p++;
|
||||
copyEngineInfo->engine = {I915_ENGINE_CLASS_COPY, getEngineOrMemoryInstanceValue(tile, i)};
|
||||
copyEngineInfo->capabilities = copyEnginesCapsMap[i];
|
||||
}
|
||||
}
|
||||
p++->engine = {I915_ENGINE_CLASS_VIDEO, getEngineOrMemoryInstanceValue(tile, 0)};
|
||||
p++->engine = {I915_ENGINE_CLASS_VIDEO, getEngineOrMemoryInstanceValue(tile, 0)};
|
||||
p++->engine = {I915_ENGINE_CLASS_VIDEO_ENHANCE, getEngineOrMemoryInstanceValue(tile, 0)};
|
||||
for (auto i = 0u; i < numberOfCCS; i++) {
|
||||
p++->engine = {PRELIM_I915_ENGINE_CLASS_COMPUTE, getEngineOrMemoryInstanceValue(tile, i)};
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PRELIM_DRM_I915_QUERY_MEMORY_REGIONS: {
|
||||
auto numberOfLocalMemories = gtSystemInfo.MultiTileArchInfo.IsValid ? gtSystemInfo.MultiTileArchInfo.TileCount : 0u;
|
||||
auto numberOfRegions = 1u + numberOfLocalMemories;
|
||||
|
||||
int regionInfoSize = sizeof(prelim_drm_i915_query_memory_regions) + numberOfRegions * sizeof(prelim_drm_i915_memory_region_info);
|
||||
if (queryItem->length == 0) {
|
||||
queryItem->length = regionInfoSize;
|
||||
} else {
|
||||
EXPECT_EQ(regionInfoSize, queryItem->length);
|
||||
auto queryMemoryRegionInfo = reinterpret_cast<prelim_drm_i915_query_memory_regions *>(queryItem->data_ptr);
|
||||
EXPECT_EQ(0u, queryMemoryRegionInfo->num_regions);
|
||||
queryMemoryRegionInfo->num_regions = numberOfRegions;
|
||||
queryMemoryRegionInfo->regions[0].region.memory_class = PRELIM_I915_MEMORY_CLASS_SYSTEM;
|
||||
queryMemoryRegionInfo->regions[0].region.memory_instance = 1;
|
||||
queryMemoryRegionInfo->regions[0].probed_size = 2 * MemoryConstants::gigaByte;
|
||||
for (auto tile = 0u; tile < numberOfLocalMemories; tile++) {
|
||||
queryMemoryRegionInfo->regions[1 + tile].region.memory_class = PRELIM_I915_MEMORY_CLASS_DEVICE;
|
||||
queryMemoryRegionInfo->regions[1 + tile].region.memory_instance = getEngineOrMemoryInstanceValue(tile, 0);
|
||||
queryMemoryRegionInfo->regions[1 + tile].probed_size = 2 * MemoryConstants::gigaByte;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case PRELIM_DRM_I915_QUERY_DISTANCE_INFO: {
|
||||
auto queryDistanceInfo = reinterpret_cast<prelim_drm_i915_query_distance_info *>(queryItem->data_ptr);
|
||||
switch (queryDistanceInfo->region.memory_class) {
|
||||
case PRELIM_I915_MEMORY_CLASS_SYSTEM:
|
||||
EXPECT_EQ(sizeof(prelim_drm_i915_query_distance_info), static_cast<size_t>(queryItem->length));
|
||||
queryDistanceInfo->distance = -1;
|
||||
break;
|
||||
case PRELIM_I915_MEMORY_CLASS_DEVICE: {
|
||||
EXPECT_EQ(sizeof(prelim_drm_i915_query_distance_info), static_cast<size_t>(queryItem->length));
|
||||
|
||||
auto engineTile = getTileFromEngineOrMemoryInstance(queryDistanceInfo->engine.engine_instance);
|
||||
auto memoryTile = getTileFromEngineOrMemoryInstance(queryDistanceInfo->region.memory_instance);
|
||||
|
||||
queryDistanceInfo->distance = (memoryTile == engineTile) ? 0 : 100;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
queryItem->length = -EINVAL;
|
||||
break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case PRELIM_DRM_I915_QUERY_COMPUTE_SLICES: {
|
||||
auto >SystemInfo = context.rootDeviceEnvironment.getHardwareInfo()->gtSystemInfo;
|
||||
auto maxEuPerSubslice = gtSystemInfo.MaxEuPerSubSlice;
|
||||
auto maxSlices = gtSystemInfo.MaxSlicesSupported;
|
||||
auto maxSubslices = gtSystemInfo.MaxSubSlicesSupported / maxSlices;
|
||||
auto threadsPerEu = gtSystemInfo.ThreadCount / gtSystemInfo.EUCount;
|
||||
auto realEuCount = threadsPerEu * maxEuPerSubslice * maxSubslices * maxSlices;
|
||||
|
||||
auto dataSize = static_cast<size_t>(std::ceil(realEuCount / 8.0)) + maxSlices * static_cast<uint16_t>(std::ceil(maxSubslices / 8.0)) +
|
||||
static_cast<uint16_t>(std::ceil(maxSlices / 8.0));
|
||||
|
||||
if (queryItem->length == 0) {
|
||||
queryItem->length = static_cast<int32_t>(sizeof(drm_i915_query_topology_info) + dataSize);
|
||||
break;
|
||||
} else {
|
||||
auto topologyArg = reinterpret_cast<drm_i915_query_topology_info *>(queryItem->data_ptr);
|
||||
if (context.failRetTopology) {
|
||||
return false;
|
||||
}
|
||||
topologyArg->max_slices = maxSlices;
|
||||
topologyArg->max_subslices = maxSubslices;
|
||||
topologyArg->max_eus_per_subslice = maxEuPerSubslice;
|
||||
|
||||
topologyArg->subslice_stride = static_cast<uint16_t>(std::ceil(maxSubslices / 8.0));
|
||||
topologyArg->eu_stride = static_cast<uint16_t>(std::ceil(maxEuPerSubslice / 8.0));
|
||||
topologyArg->subslice_offset = static_cast<uint16_t>(std::ceil(maxSlices / 8.0));
|
||||
topologyArg->eu_offset = static_cast<uint16_t>(std::ceil(maxSubslices / 8.0)) * maxSlices;
|
||||
|
||||
int threadData = (threadsPerEu == 8) ? 0xff : 0x7f;
|
||||
|
||||
uint8_t *data = topologyArg->data;
|
||||
for (uint32_t sliceId = 0; sliceId < maxSlices; sliceId++) {
|
||||
data[0] |= 1 << (sliceId % 8);
|
||||
if (sliceId == 7 || sliceId == maxSlices - 1) {
|
||||
data++;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_BREAK_IF(ptrDiff(data, topologyArg->data) != topologyArg->subslice_offset);
|
||||
|
||||
data = ptrOffset(topologyArg->data, topologyArg->subslice_offset);
|
||||
for (uint32_t sliceId = 0; sliceId < maxSlices; sliceId++) {
|
||||
for (uint32_t i = 0; i < maxSubslices; i++) {
|
||||
data[0] |= 1 << (i % 8);
|
||||
|
||||
if (i == 7 || i == maxSubslices - 1) {
|
||||
data++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_BREAK_IF(ptrDiff(data, topologyArg->data) != topologyArg->eu_offset);
|
||||
auto size = dataSize - topologyArg->eu_offset;
|
||||
memset(ptrOffset(topologyArg->data, topologyArg->eu_offset), threadData, size);
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
queryItem->length = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -202,7 +202,7 @@ DrmMockCustom::DrmMockCustom(RootDeviceEnvironment &rootDeviceEnvironment)
|
||||
ioctl_expected.contextDestroy = ioctl_expected.contextCreate.load();
|
||||
createVirtualMemoryAddressSpace(NEO::HwHelper::getSubDevicesCount(rootDeviceEnvironment.getHardwareInfo()));
|
||||
isVmBindAvailable();
|
||||
setupIoctlHelper();
|
||||
setupIoctlHelper(rootDeviceEnvironment.getHardwareInfo()->platform.eProductFamily);
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ Drm *Drm::create(std::unique_ptr<HwDeviceIdDrm> &&hwDeviceId, RootDeviceEnvironm
|
||||
|
||||
const HardwareInfo *hwInfo = rootDeviceEnvironment.getHardwareInfo();
|
||||
|
||||
drm->setupIoctlHelper();
|
||||
drm->setupIoctlHelper(hwInfo->platform.eProductFamily);
|
||||
|
||||
drm->queryAdapterBDF();
|
||||
|
||||
|
||||
@@ -7,12 +7,19 @@
|
||||
set(NEO_CORE_OS_INTERFACE_TESTS_LINUX
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
|
||||
${CMAKE_CURRENT_SOURCE_DIR}${BRANCH_DIR_SUFFIX}drm_query_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drm_query_topology_upstream_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drm_special_heap_test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hw_info_config_uuid_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/os_context_linux_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drm_command_stream_l0_tests.cpp
|
||||
)
|
||||
|
||||
if(NEO_ENABLE_i915_PRELIM_DETECTION)
|
||||
list(APPEND NEO_CORE_OS_INTERFACE_TESTS_LINUX
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/drm_query_topology_prelim_tests.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
set_property(GLOBAL PROPERTY NEO_CORE_OS_INTERFACE_TESTS_LINUX ${NEO_CORE_OS_INTERFACE_TESTS_LINUX})
|
||||
|
||||
if(UNIX)
|
||||
|
||||
@@ -27,48 +27,6 @@ TEST(DrmQueryTest, WhenCallingIsDebugAttachAvailableThenReturnValueIsFalse) {
|
||||
EXPECT_FALSE(drm.isDebugAttachAvailable());
|
||||
}
|
||||
|
||||
TEST(DrmQueryTest, GivenDrmWhenQueryingTopologyInfoCorrectMaxValuesAreSet) {
|
||||
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
|
||||
executionEnvironment->prepareRootDeviceEnvironments(1);
|
||||
|
||||
*executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo() = *NEO::defaultHwInfo.get();
|
||||
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
|
||||
EXPECT_TRUE(drm.queryTopology(*executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(), topologyData));
|
||||
|
||||
EXPECT_EQ(drm.storedSVal, topologyData.sliceCount);
|
||||
EXPECT_EQ(drm.storedSSVal, topologyData.subSliceCount);
|
||||
EXPECT_EQ(drm.storedEUVal, topologyData.euCount);
|
||||
|
||||
EXPECT_EQ(drm.storedSVal, topologyData.maxSliceCount);
|
||||
EXPECT_EQ(drm.storedSSVal / drm.storedSVal, topologyData.maxSubSliceCount);
|
||||
EXPECT_EQ(drm.storedEUVal / drm.storedSSVal, topologyData.maxEuCount);
|
||||
}
|
||||
|
||||
TEST(DrmQueryTest, givenDrmWhenGettingSliceMappingsThenCorrectMappingReturned) {
|
||||
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
|
||||
executionEnvironment->prepareRootDeviceEnvironments(1);
|
||||
|
||||
*executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo() = *NEO::defaultHwInfo.get();
|
||||
DrmMock drmMock{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
|
||||
EXPECT_TRUE(drmMock.queryTopology(*executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(), topologyData));
|
||||
|
||||
auto device0SliceMapping = drmMock.getSliceMappings(0);
|
||||
auto device1SliceMapping = drmMock.getSliceMappings(1);
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(topologyData.maxSliceCount), device0SliceMapping.size());
|
||||
EXPECT_EQ(0u, device1SliceMapping.size());
|
||||
|
||||
for (int i = 0; i < topologyData.maxSliceCount; i++) {
|
||||
EXPECT_EQ(i, device0SliceMapping[i]);
|
||||
}
|
||||
}
|
||||
|
||||
using HwConfigTopologyQuery = ::testing::Test;
|
||||
|
||||
HWTEST2_F(HwConfigTopologyQuery, WhenGettingTopologyFailsThenSetMaxValuesBasedOnSubsliceIoctlQuery, MatchAny) {
|
||||
|
||||
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/helpers/hw_info.h"
|
||||
#include "shared/source/os_interface/hw_info_config.h"
|
||||
#include "shared/source/os_interface/os_interface.h"
|
||||
#include "shared/test/common/helpers/debug_manager_state_restore.h"
|
||||
#include "shared/test/common/helpers/default_hw_info.h"
|
||||
#include "shared/test/common/libult/linux/drm_prelim_helper.h"
|
||||
#include "shared/test/common/libult/linux/drm_query_mock.h"
|
||||
#include "shared/test/common/test_macros/test.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(DrmQueryTopologyTest, givenDrmWhenQueryTopologyCalledThenPassNoFlags) {
|
||||
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
|
||||
executionEnvironment->prepareRootDeviceEnvironments(1);
|
||||
DrmQueryMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
|
||||
EXPECT_TRUE(drm.queryTopology(*drm.context.hwInfo, topologyData));
|
||||
|
||||
constexpr uint32_t expectedFlag = 0;
|
||||
EXPECT_EQ(expectedFlag, drm.storedQueryItem.flags);
|
||||
}
|
||||
|
||||
struct QueryTopologyTests : ::testing::Test {
|
||||
class MyDrmQueryMock : public DrmQueryMock {
|
||||
public:
|
||||
using DrmQueryMock::DrmQueryMock;
|
||||
|
||||
bool handleQueryItem(void *arg) override {
|
||||
const auto queryItem = reinterpret_cast<drm_i915_query_item *>(arg);
|
||||
if (queryItem->query_id != getQueryComputeSlicesIoctl()) {
|
||||
return DrmQueryMock::handleQueryItem(queryItem);
|
||||
}
|
||||
|
||||
queryComputeSlicesCallCount++;
|
||||
|
||||
if (failOnQuery) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto realEuCount = rootDeviceEnvironment.getHardwareInfo()->gtSystemInfo.EUCount;
|
||||
auto dataSize = static_cast<size_t>(std::ceil(realEuCount / 8.0));
|
||||
|
||||
if (queryItem->length == 0) {
|
||||
queryItem->length = static_cast<int32_t>(sizeof(drm_i915_query_topology_info) + dataSize);
|
||||
} else {
|
||||
auto topologyArg = reinterpret_cast<drm_i915_query_topology_info *>(queryItem->data_ptr);
|
||||
|
||||
uint16_t finalSVal = queryComputeSlicesSCount;
|
||||
uint16_t finalSSVal = queryComputeSlicesSSCount;
|
||||
uint16_t finalEUVal = queryComputeSlicesEuCount;
|
||||
|
||||
if (useSmallerValuesOnSecondCall && queryComputeSlicesCallCount == 2) {
|
||||
finalSVal /= 2;
|
||||
finalSSVal /= 2;
|
||||
finalEUVal /= 2;
|
||||
}
|
||||
|
||||
topologyArg->max_slices = finalSVal;
|
||||
topologyArg->max_subslices = (finalSSVal / finalSVal);
|
||||
topologyArg->max_eus_per_subslice = (finalEUVal / finalSSVal);
|
||||
|
||||
memset(topologyArg->data, 0xFF, dataSize);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t queryComputeSlicesCallCount = 0;
|
||||
|
||||
uint16_t queryComputeSlicesSCount = 0;
|
||||
uint16_t queryComputeSlicesSSCount = 0;
|
||||
uint16_t queryComputeSlicesEuCount = 0;
|
||||
|
||||
bool useSmallerValuesOnSecondCall = false;
|
||||
bool failOnQuery = false;
|
||||
};
|
||||
|
||||
void SetUp() override {
|
||||
executionEnvironment = std::make_unique<ExecutionEnvironment>();
|
||||
executionEnvironment->prepareRootDeviceEnvironments(1);
|
||||
|
||||
rootDeviceEnvironment = executionEnvironment->rootDeviceEnvironments[0].get();
|
||||
rootDeviceEnvironment->setHwInfo(NEO::defaultHwInfo.get());
|
||||
}
|
||||
|
||||
void createDrm(uint32_t tileCount) {
|
||||
GT_MULTI_TILE_ARCH_INFO &multiTileArch = rootDeviceEnvironment->getMutableHardwareInfo()->gtSystemInfo.MultiTileArchInfo;
|
||||
multiTileArch.IsValid = (tileCount > 0);
|
||||
multiTileArch.TileCount = tileCount;
|
||||
multiTileArch.TileMask = static_cast<uint8_t>(maxNBitValue(tileCount));
|
||||
|
||||
drmMock = std::make_unique<MyDrmQueryMock>(*rootDeviceEnvironment, rootDeviceEnvironment->getHardwareInfo());
|
||||
|
||||
drmMock->storedSVal = 8;
|
||||
drmMock->storedSSVal = 32;
|
||||
drmMock->storedEUVal = 512;
|
||||
|
||||
drmMock->queryComputeSlicesSCount = 4;
|
||||
drmMock->queryComputeSlicesSSCount = 16;
|
||||
drmMock->queryComputeSlicesEuCount = 256;
|
||||
|
||||
EXPECT_TRUE(drmMock->queryMemoryInfo());
|
||||
EXPECT_TRUE(drmMock->queryEngineInfo());
|
||||
}
|
||||
|
||||
DebugManagerStateRestore stateRestorer;
|
||||
std::unique_ptr<ExecutionEnvironment> executionEnvironment;
|
||||
std::unique_ptr<MyDrmQueryMock> drmMock;
|
||||
RootDeviceEnvironment *rootDeviceEnvironment;
|
||||
int receivedSliceCount = 0;
|
||||
int receivedSubSliceCount = 0;
|
||||
int receivedEuCount = 0;
|
||||
};
|
||||
|
||||
TEST_F(QueryTopologyTests, givenZeroTilesWhenQueryingThenFallbackToQueryTopology) {
|
||||
createDrm(0);
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
|
||||
drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData);
|
||||
|
||||
EXPECT_EQ(0u, drmMock->queryComputeSlicesCallCount);
|
||||
|
||||
EXPECT_EQ(drmMock->storedSVal, topologyData.sliceCount);
|
||||
EXPECT_EQ(drmMock->storedSSVal, topologyData.subSliceCount);
|
||||
EXPECT_EQ(drmMock->storedEUVal, topologyData.euCount);
|
||||
|
||||
EXPECT_EQ(drmMock->storedSVal, topologyData.maxSliceCount);
|
||||
EXPECT_EQ(drmMock->storedSSVal / drmMock->storedSVal, topologyData.maxSubSliceCount);
|
||||
EXPECT_EQ(drmMock->storedEUVal / drmMock->storedSSVal, topologyData.maxEuCount);
|
||||
}
|
||||
|
||||
TEST_F(QueryTopologyTests, givenNonZeroTilesWhenDebugFlagDisabledThenFallbackToQueryTopology) {
|
||||
DebugManager.flags.UseNewQueryTopoIoctl.set(false);
|
||||
createDrm(2);
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
|
||||
drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData);
|
||||
|
||||
EXPECT_EQ(0u, drmMock->queryComputeSlicesCallCount);
|
||||
|
||||
EXPECT_EQ(drmMock->storedSVal, topologyData.sliceCount);
|
||||
EXPECT_EQ(drmMock->storedSSVal, topologyData.subSliceCount);
|
||||
EXPECT_EQ(drmMock->storedEUVal, topologyData.euCount);
|
||||
|
||||
EXPECT_EQ(drmMock->storedSVal, topologyData.maxSliceCount);
|
||||
EXPECT_EQ(drmMock->storedSSVal / drmMock->storedSVal, topologyData.maxSubSliceCount);
|
||||
EXPECT_EQ(drmMock->storedEUVal / drmMock->storedSSVal, topologyData.maxEuCount);
|
||||
}
|
||||
|
||||
TEST_F(QueryTopologyTests, givenNonZeroTilesWhenQueryingThenUseOnlyNewIoctl) {
|
||||
createDrm(2);
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
|
||||
drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData);
|
||||
|
||||
EXPECT_EQ(4u, drmMock->queryComputeSlicesCallCount); // 2x length + 2x query
|
||||
|
||||
EXPECT_EQ(drmMock->queryComputeSlicesSCount, topologyData.sliceCount);
|
||||
EXPECT_EQ(drmMock->queryComputeSlicesSSCount, topologyData.subSliceCount);
|
||||
EXPECT_EQ(drmMock->queryComputeSlicesEuCount, topologyData.euCount);
|
||||
|
||||
EXPECT_EQ(drmMock->queryComputeSlicesSCount, topologyData.maxSliceCount);
|
||||
EXPECT_EQ(drmMock->queryComputeSlicesSSCount / drmMock->queryComputeSlicesSCount, topologyData.maxSubSliceCount);
|
||||
EXPECT_EQ(drmMock->queryComputeSlicesEuCount / drmMock->queryComputeSlicesSSCount, topologyData.maxEuCount);
|
||||
}
|
||||
|
||||
TEST_F(QueryTopologyTests, givenNonZeroTilesWithoutEngineInfoThenFallback) {
|
||||
createDrm(2);
|
||||
|
||||
drmMock->engineInfo.reset();
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData);
|
||||
|
||||
EXPECT_EQ(0u, drmMock->queryComputeSlicesCallCount);
|
||||
|
||||
EXPECT_EQ(drmMock->storedSVal, topologyData.sliceCount);
|
||||
EXPECT_EQ(drmMock->storedSSVal, topologyData.subSliceCount);
|
||||
EXPECT_EQ(drmMock->storedEUVal, topologyData.euCount);
|
||||
|
||||
EXPECT_EQ(drmMock->storedSVal, topologyData.maxSliceCount);
|
||||
EXPECT_EQ(drmMock->storedSSVal / drmMock->storedSVal, topologyData.maxSubSliceCount);
|
||||
EXPECT_EQ(drmMock->storedEUVal / drmMock->storedSSVal, topologyData.maxEuCount);
|
||||
}
|
||||
|
||||
TEST_F(QueryTopologyTests, givenNonZeroTilesWhenFailOnNewQueryThenFallback) {
|
||||
createDrm(2);
|
||||
|
||||
drmMock->queryComputeSlicesEuCount = 0;
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData);
|
||||
|
||||
EXPECT_EQ(2u, drmMock->queryComputeSlicesCallCount);
|
||||
|
||||
EXPECT_EQ(drmMock->storedSVal, topologyData.sliceCount);
|
||||
EXPECT_EQ(drmMock->storedSSVal, topologyData.subSliceCount);
|
||||
EXPECT_EQ(drmMock->storedEUVal, topologyData.euCount);
|
||||
|
||||
EXPECT_EQ(drmMock->storedSVal, topologyData.maxSliceCount);
|
||||
EXPECT_EQ(drmMock->storedSSVal / drmMock->storedSVal, topologyData.maxSubSliceCount);
|
||||
EXPECT_EQ(drmMock->storedEUVal / drmMock->storedSSVal, topologyData.maxEuCount);
|
||||
}
|
||||
|
||||
TEST_F(QueryTopologyTests, givenNonZeroTilesWhenIncorrectValuesQueriedThenFallback) {
|
||||
createDrm(2);
|
||||
|
||||
drmMock->failOnQuery = true;
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData);
|
||||
|
||||
EXPECT_EQ(1u, drmMock->queryComputeSlicesCallCount);
|
||||
|
||||
EXPECT_EQ(drmMock->storedSVal, topologyData.sliceCount);
|
||||
EXPECT_EQ(drmMock->storedSSVal, topologyData.subSliceCount);
|
||||
EXPECT_EQ(drmMock->storedEUVal, topologyData.euCount);
|
||||
|
||||
EXPECT_EQ(drmMock->storedSVal, topologyData.maxSliceCount);
|
||||
EXPECT_EQ(drmMock->storedSSVal / drmMock->storedSVal, topologyData.maxSubSliceCount);
|
||||
EXPECT_EQ(drmMock->storedEUVal / drmMock->storedSSVal, topologyData.maxEuCount);
|
||||
}
|
||||
|
||||
TEST_F(QueryTopologyTests, givenAsymetricTilesWhenQueryingThenPickSmallerValue) {
|
||||
createDrm(2);
|
||||
|
||||
drmMock->useSmallerValuesOnSecondCall = true;
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData);
|
||||
|
||||
EXPECT_EQ(drmMock->queryComputeSlicesSCount / 2, topologyData.sliceCount);
|
||||
EXPECT_EQ(drmMock->queryComputeSlicesSSCount / 2, topologyData.subSliceCount);
|
||||
EXPECT_EQ(drmMock->queryComputeSlicesEuCount / 2, topologyData.euCount);
|
||||
|
||||
EXPECT_EQ(drmMock->queryComputeSlicesSCount, topologyData.maxSliceCount);
|
||||
EXPECT_EQ(drmMock->queryComputeSlicesSSCount / drmMock->queryComputeSlicesSCount, topologyData.maxSubSliceCount);
|
||||
EXPECT_EQ(drmMock->queryComputeSlicesEuCount / drmMock->queryComputeSlicesSSCount, topologyData.maxEuCount);
|
||||
}
|
||||
|
||||
TEST_F(QueryTopologyTests, givenAsymetricTilesWhenGettingSliceMappingsThenCorrectMappingsReturnedForBothDeviceIndexes) {
|
||||
createDrm(2);
|
||||
|
||||
drmMock->useSmallerValuesOnSecondCall = true;
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData);
|
||||
|
||||
auto device0SliceMapping = drmMock->getSliceMappings(0);
|
||||
auto device1SliceMapping = drmMock->getSliceMappings(1);
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(drmMock->queryComputeSlicesSCount / 2), device0SliceMapping.size());
|
||||
for (int i = 0; i < drmMock->queryComputeSlicesSCount / 2; i++) {
|
||||
EXPECT_EQ(i, device0SliceMapping[i]);
|
||||
}
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(drmMock->queryComputeSlicesSCount), device1SliceMapping.size());
|
||||
for (int i = 0; i < drmMock->queryComputeSlicesSCount; i++) {
|
||||
EXPECT_EQ(i, device1SliceMapping[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(QueryTopologyTests, givenNonZeroTilesAndFallbackPathWhenGettingSliceMappingsThenMappingStoredForIndexZeroOnly) {
|
||||
DebugManager.flags.UseNewQueryTopoIoctl.set(false);
|
||||
createDrm(2);
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
|
||||
drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData);
|
||||
|
||||
EXPECT_EQ(0u, drmMock->queryComputeSlicesCallCount);
|
||||
|
||||
EXPECT_EQ(drmMock->storedSVal, topologyData.sliceCount);
|
||||
EXPECT_EQ(drmMock->storedSSVal, topologyData.subSliceCount);
|
||||
EXPECT_EQ(drmMock->storedEUVal, topologyData.euCount);
|
||||
|
||||
auto device0SliceMapping = drmMock->getSliceMappings(0);
|
||||
auto device1SliceMapping = drmMock->getSliceMappings(1);
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(drmMock->storedSVal), device0SliceMapping.size());
|
||||
for (int i = 0; i < drmMock->storedSVal; i++) {
|
||||
EXPECT_EQ(i, device0SliceMapping[i]);
|
||||
}
|
||||
|
||||
ASSERT_EQ(0u, device1SliceMapping.size());
|
||||
}
|
||||
|
||||
TEST_F(QueryTopologyTests, givenDrmWhenGettingTopologyMapThenCorrectMapIsReturned) {
|
||||
createDrm(2);
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
drmMock->queryTopology(*rootDeviceEnvironment->getHardwareInfo(), topologyData);
|
||||
|
||||
auto topologyMap = drmMock->getTopologyMap();
|
||||
|
||||
if (executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo()->gtSystemInfo.MultiTileArchInfo.TileCount > 0) {
|
||||
EXPECT_EQ(executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo()->gtSystemInfo.MultiTileArchInfo.TileCount, topologyMap.size());
|
||||
} else {
|
||||
EXPECT_EQ(1u, topologyMap.size());
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < topologyMap.size(); i++) {
|
||||
EXPECT_EQ(drmMock->queryComputeSlicesSCount, topologyMap.at(i).sliceIndices.size());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/helpers/hw_info.h"
|
||||
#include "shared/source/os_interface/hw_info_config.h"
|
||||
#include "shared/source/os_interface/os_interface.h"
|
||||
#include "shared/test/common/helpers/default_hw_info.h"
|
||||
#include "shared/test/common/libult/linux/drm_mock.h"
|
||||
#include "shared/test/common/test_macros/test.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(DrmQueryTopologyTest, GivenDrmWhenQueryingTopologyInfoCorrectMaxValuesAreSet) {
|
||||
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
|
||||
executionEnvironment->prepareRootDeviceEnvironments(1);
|
||||
|
||||
*executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo() = *NEO::defaultHwInfo.get();
|
||||
DrmMock drm{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
|
||||
EXPECT_TRUE(drm.queryTopology(*executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(), topologyData));
|
||||
|
||||
EXPECT_EQ(drm.storedSVal, topologyData.sliceCount);
|
||||
EXPECT_EQ(drm.storedSSVal, topologyData.subSliceCount);
|
||||
EXPECT_EQ(drm.storedEUVal, topologyData.euCount);
|
||||
|
||||
EXPECT_EQ(drm.storedSVal, topologyData.maxSliceCount);
|
||||
EXPECT_EQ(drm.storedSSVal / drm.storedSVal, topologyData.maxSubSliceCount);
|
||||
EXPECT_EQ(drm.storedEUVal / drm.storedSSVal, topologyData.maxEuCount);
|
||||
}
|
||||
|
||||
TEST(DrmQueryTopologyTest, givenDrmWhenGettingSliceMappingsThenCorrectMappingReturned) {
|
||||
auto executionEnvironment = std::make_unique<ExecutionEnvironment>();
|
||||
executionEnvironment->prepareRootDeviceEnvironments(1);
|
||||
|
||||
*executionEnvironment->rootDeviceEnvironments[0]->getMutableHardwareInfo() = *NEO::defaultHwInfo.get();
|
||||
DrmMock drmMock{*executionEnvironment->rootDeviceEnvironments[0]};
|
||||
|
||||
Drm::QueryTopologyData topologyData = {};
|
||||
|
||||
EXPECT_TRUE(drmMock.queryTopology(*executionEnvironment->rootDeviceEnvironments[0]->getHardwareInfo(), topologyData));
|
||||
|
||||
auto device0SliceMapping = drmMock.getSliceMappings(0);
|
||||
auto device1SliceMapping = drmMock.getSliceMappings(1);
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(topologyData.maxSliceCount), device0SliceMapping.size());
|
||||
EXPECT_EQ(0u, device1SliceMapping.size());
|
||||
|
||||
for (int i = 0; i < topologyData.maxSliceCount; i++) {
|
||||
EXPECT_EQ(i, device0SliceMapping[i]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user