fix: respect affinity mask with COMBINED hierarchy in OCL

Related-To: GSD-9560
Signed-off-by: Jaroslaw Warchulski <jaroslaw.warchulski@intel.com>
This commit is contained in:
Jaroslaw Warchulski
2025-01-13 12:18:55 +00:00
committed by Compute-Runtime-Automation
parent 4e20673e96
commit a180afa2e6
19 changed files with 217 additions and 216 deletions

View File

@@ -323,80 +323,6 @@ DriverHandle *DriverHandle::create(std::vector<std::unique_ptr<NEO::Device>> dev
return driverHandle;
}
ze_result_t DriverHandleImp::parseAffinityMaskCombined(uint32_t *pCount, ze_device_handle_t *phDevices) {
const auto &affinityMaskString = NEO::debugManager.flags.ZE_AFFINITY_MASK.get();
uint32_t totalNumDevices = 0u;
for (auto &device : this->devices) {
auto deviceImpl = static_cast<DeviceImp *>(device);
totalNumDevices += (deviceImpl->numSubDevices > 0 ? deviceImpl->numSubDevices : 1u);
}
auto affinityMaskEntries = StringHelpers::split(affinityMaskString, ",");
bool retrieveCount = false;
if (*pCount == 0) {
retrieveCount = true;
}
if (phDevices == nullptr && !retrieveCount) {
return ZE_RESULT_ERROR_INVALID_NULL_HANDLE;
}
uint32_t deviceIndex = 0;
for (const auto &entry : affinityMaskEntries) {
auto subEntries = StringHelpers::split(entry, ".");
uint32_t affinityIndex = StringHelpers::toUint32t(subEntries[0]);
if (affinityIndex > totalNumDevices) {
continue;
}
// Combined Device Hierarchy
// so ignore X.Y
if (subEntries.size() > 1) {
continue;
}
uint32_t actualIndex = 0;
for (auto device : devices) {
auto deviceImpl = static_cast<DeviceImp *>(device);
if (deviceImpl->numSubDevices > 0) {
for (auto subdevice : deviceImpl->subDevices) {
if (affinityIndex == actualIndex) {
if (retrieveCount) {
*pCount += 1;
} else {
phDevices[deviceIndex++] = subdevice;
}
}
actualIndex++;
if (!retrieveCount) {
if (deviceIndex == *pCount) {
return ZE_RESULT_SUCCESS;
}
}
}
} else {
if (affinityIndex == actualIndex) {
if (retrieveCount) {
*pCount += 1;
} else {
phDevices[deviceIndex++] = device;
}
}
actualIndex++;
if (!retrieveCount) {
if (deviceIndex == *pCount) {
return ZE_RESULT_SUCCESS;
}
}
}
}
}
return ZE_RESULT_SUCCESS;
}
void DriverHandleImp::initHostUsmAllocPool() {
auto usmHostAllocPoolingEnabled = NEO::ApiSpecificConfig::isHostUsmPoolingEnabled();
auto poolSize = 2 * MemoryConstants::megaByte;
@@ -414,22 +340,11 @@ void DriverHandleImp::initHostUsmAllocPool() {
ze_result_t DriverHandleImp::getDevice(uint32_t *pCount, ze_device_handle_t *phDevices) {
bool exposeSubDevices = false;
// If the user has requested FLAT device hierarchy model, then report all the sub devices as devices.
if (this->deviceHierarchyMode == L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_FLAT || this->deviceHierarchyMode == L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMBINED) {
// If the user has requested FLAT or COMBINED device hierarchy model, then report all the sub devices as devices.
if (this->deviceHierarchyMode != L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMPOSITE) {
exposeSubDevices = true;
}
const auto &affinityMaskString = NEO::debugManager.flags.ZE_AFFINITY_MASK.get();
bool affinitySet = true;
if (affinityMaskString.compare("default") == 0 ||
affinityMaskString.empty()) {
affinitySet = false;
}
if (this->deviceHierarchyMode == L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMBINED && affinitySet) {
return parseAffinityMaskCombined(pCount, phDevices);
}
uint32_t numDevices = 0;
if (exposeSubDevices) {
for (auto &device : this->devices) {

View File

@@ -125,7 +125,6 @@ struct DriverHandleImp : public DriverHandle {
ze_result_t createRTASParallelOperation(ze_rtas_parallel_operation_exp_handle_t *phParallelOperation) override;
ze_result_t formatRTASCompatibilityCheck(ze_rtas_format_exp_t rtasFormatA, ze_rtas_format_exp_t rtasFormatB) override;
ze_result_t parseAffinityMaskCombined(uint32_t *pCount, ze_device_handle_t *phDevices);
std::map<uint64_t, IpcHandleTracking *> &getIPCHandleMap() { return this->ipcHandles; };
[[nodiscard]] std::unique_lock<std::mutex> lockIPCHandleMap() { return std::unique_lock<std::mutex>(this->ipcHandleMapMutex); };
void initHostUsmAllocPool();

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2024 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -130,39 +130,27 @@ void MultiDeviceFixtureHierarchy::setUp() {
for (size_t i = 0; i < numRootDevices; ++i) {
executionEnvironment->rootDeviceEnvironments[i]->memoryOperationsInterface = std::make_unique<MockMemoryOperations>();
}
executionEnvironment->setExposeSubDevicesAsDevices(exposeSubDevices);
auto devices = NEO::DeviceFactory::createDevices(*executionEnvironment);
driverHandle = std::make_unique<Mock<L0::DriverHandleImp>>();
ze_result_t res = driverHandle->initialize(std::move(devices));
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_context_handle_t hContext;
ze_context_desc_t desc = {ZE_STRUCTURE_TYPE_CONTEXT_DESC, nullptr, 0};
res = driverHandle->createContext(&desc, 0u, nullptr, &hContext);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
context = static_cast<ContextImp *>(Context::fromHandle(hContext));
}
void MultiDeviceFixtureCombinedHierarchy::setUp() {
debugManager.flags.CreateMultipleRootDevices.set(numRootDevices);
debugManager.flags.CreateMultipleSubDevices.set(numSubDevices);
auto executionEnvironment = new NEO::ExecutionEnvironment;
executionEnvironment->prepareRootDeviceEnvironments(numRootDevices);
for (size_t i = 0; i < numRootDevices; ++i) {
executionEnvironment->rootDeviceEnvironments[i]->memoryOperationsInterface = std::make_unique<MockMemoryOperations>();
if (driverHandle->deviceHierarchyMode == L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_FLAT) {
executionEnvironment->setExposeSubDevicesAsDevices(true);
} else if (driverHandle->deviceHierarchyMode == L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMBINED) {
executionEnvironment->setCombinedDeviceHierarchy(true);
}
executionEnvironment->setExposeSubDevicesAsDevices(exposeSubDevices);
executionEnvironment->setCombinedDeviceHierarchy(combinedHierarchy);
auto devices = NEO::DeviceFactory::createDevices(*executionEnvironment);
driverHandle = std::make_unique<Mock<L0::DriverHandleImp>>();
ze_result_t res = driverHandle->initialize(std::move(devices));
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_context_handle_t hContext;
ze_context_desc_t desc = {ZE_STRUCTURE_TYPE_CONTEXT_DESC, nullptr, 0};
res = driverHandle->createContext(&desc, 0u, nullptr, &hContext);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
context = static_cast<ContextImp *>(Context::fromHandle(hContext));
auto devices = NEO::DeviceFactory::createDevices(*executionEnvironment);
if (devices.size()) {
ze_result_t res = driverHandle->initialize(std::move(devices));
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
ze_context_handle_t hContext;
ze_context_desc_t desc = {ZE_STRUCTURE_TYPE_CONTEXT_DESC, nullptr, 0};
res = driverHandle->createContext(&desc, 0u, nullptr, &hContext);
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
context = static_cast<ContextImp *>(Context::fromHandle(hContext));
} else {
delete executionEnvironment;
return;
}
}
void MultipleDevicesWithCustomHwInfo::setUp() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2024 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -126,7 +126,7 @@ struct MultiDeviceFixture {
void tearDown();
DebugManagerStateRestore restorer;
std::unique_ptr<Mock<L0::DriverHandleImp>> driverHandle;
std::unique_ptr<Mock<L0::DriverHandleImp>> driverHandle = std::make_unique<Mock<L0::DriverHandleImp>>();
uint32_t numRootDevices = 4u;
uint32_t numSubDevices = 2u;
L0::ContextImp *context = nullptr;
@@ -137,13 +137,27 @@ struct MultiDeviceFixture {
struct MultiDeviceFixtureHierarchy : public MultiDeviceFixture {
void setUp();
bool exposeSubDevices = true;
};
struct MultiDeviceFixtureCombinedHierarchy : public MultiDeviceFixture {
void setUp();
bool exposeSubDevices = true;
bool combinedHierarchy = true;
struct MultiDeviceFixtureCompositeHierarchy : public MultiDeviceFixtureHierarchy {
void setUp() {
this->driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMPOSITE;
MultiDeviceFixtureHierarchy::setUp();
}
};
struct MultiDeviceFixtureFlatHierarchy : public MultiDeviceFixtureHierarchy {
void setUp() {
this->driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_FLAT;
MultiDeviceFixtureHierarchy::setUp();
}
};
struct MultiDeviceFixtureCombinedHierarchy : public MultiDeviceFixtureHierarchy {
void setUp() {
this->driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMBINED;
MultiDeviceFixtureHierarchy::setUp();
}
};
struct SingleRootMultiSubDeviceFixture : public MultiDeviceFixture {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2024 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -5739,9 +5739,8 @@ TEST(DeviceReturnFlatHierarchyTest, GivenFlatHierarchyIsSetWithMaskThenFlagsOfDe
DebugManagerStateRestore restorer;
NEO::debugManager.flags.ZE_AFFINITY_MASK.set("0,1.1,2");
MultiDeviceFixtureHierarchy multiDeviceFixture{};
MultiDeviceFixtureFlatHierarchy multiDeviceFixture{};
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_FLAT;
uint32_t count = 0;
std::vector<ze_device_handle_t> hDevices;
@@ -5774,7 +5773,6 @@ TEST(DeviceReturnCombinedHierarchyTest, GivenCombinedHierarchyIsSetWithMaskThenF
NEO::debugManager.flags.ZE_AFFINITY_MASK.set("0,1.1,2");
MultiDeviceFixtureCombinedHierarchy multiDeviceFixture{};
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMBINED;
uint32_t count = 0;
std::vector<ze_device_handle_t> hDevices;
@@ -5807,7 +5805,6 @@ TEST(DeviceReturnCombinedHierarchyTest, GivenCombinedHierarchyIsSetWithMaskThenG
NEO::debugManager.flags.ZE_AFFINITY_MASK.set("0,1.1,2");
MultiDeviceFixtureCombinedHierarchy multiDeviceFixture{};
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMBINED;
uint32_t count = 0;
std::vector<ze_device_handle_t> hDevices;
@@ -5836,7 +5833,6 @@ TEST(DeviceReturnCombinedHierarchyTest, GivenCombinedHierarchyIsSetWithMaskWitho
MultiDeviceFixtureCombinedHierarchy multiDeviceFixture{};
multiDeviceFixture.numSubDevices = 0;
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMBINED;
uint32_t count = 0;
std::vector<ze_device_handle_t> hDevices;
@@ -5862,7 +5858,6 @@ TEST(DeviceReturnCombinedHierarchyTest, GivenCombinedHierarchyIsSetWithoutDevice
NEO::debugManager.flags.ZE_AFFINITY_MASK.set("0,1,2");
MultiDeviceFixtureCombinedHierarchy multiDeviceFixture{};
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMBINED;
uint32_t count = 0;
EXPECT_EQ(multiDeviceFixture.driverHandle->getDevice(&count, nullptr), ZE_RESULT_SUCCESS);
@@ -5880,20 +5875,16 @@ TEST(DeviceReturnCombinedHierarchyTest, GivenCombinedHierarchyIsSetWithInvalidAf
NEO::debugManager.flags.ZE_AFFINITY_MASK.set("90");
MultiDeviceFixtureCombinedHierarchy multiDeviceFixture{};
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMBINED;
uint32_t count = 0;
EXPECT_EQ(multiDeviceFixture.driverHandle->getDevice(&count, nullptr), ZE_RESULT_SUCCESS);
EXPECT_EQ(count, 0u);
multiDeviceFixture.tearDown();
}
TEST(DeviceReturnCombinedHierarchyTest, GivenCombinedHierarchyIsSetThenGetRootDeviceReturnsNullptr) {
MultiDeviceFixtureCombinedHierarchy multiDeviceFixture{};
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMBINED;
uint32_t count = 0;
std::vector<ze_device_handle_t> hDevices;
@@ -5919,7 +5910,6 @@ TEST(DeviceReturnCombinedHierarchyTest, GivenCombinedHierarchyIsSetAndDefaultAff
NEO::debugManager.flags.ZE_AFFINITY_MASK.set("");
MultiDeviceFixtureCombinedHierarchy multiDeviceFixture{};
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMBINED;
uint32_t count = 0;
std::vector<ze_device_handle_t> hDevices;
@@ -5948,7 +5938,6 @@ TEST(DeviceReturnCombinedHierarchyTest, GivenCombinedHierarchyIsSetAndEmptyAffin
MultiDeviceFixtureCombinedHierarchy multiDeviceFixture{};
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMBINED;
uint32_t count = 0;
std::vector<ze_device_handle_t> hDevices;
@@ -5975,9 +5964,8 @@ TEST(DeviceReturnCombinedHierarchyTest, GivenCombinedHierarchyIsSetAndEmptyAffin
TEST(DeviceReturnFlatHierarchyTest, GivenFlatHierarchyIsSetThenFlagsOfDevicePropertiesIsCorrect) {
MultiDeviceFixtureHierarchy multiDeviceFixture{};
MultiDeviceFixtureFlatHierarchy multiDeviceFixture{};
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_FLAT;
uint32_t count = 0;
std::vector<ze_device_handle_t> hDevices;
@@ -6006,9 +5994,8 @@ TEST(DeviceReturnFlatHierarchyTest, GivenFlatHierarchyIsSetWithMaskThenGetRootDe
DebugManagerStateRestore restorer;
NEO::debugManager.flags.ZE_AFFINITY_MASK.set("0,1.1,2");
MultiDeviceFixtureHierarchy multiDeviceFixture{};
MultiDeviceFixtureFlatHierarchy multiDeviceFixture{};
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_FLAT;
uint32_t count = 0;
std::vector<ze_device_handle_t> hDevices;
@@ -6032,9 +6019,8 @@ TEST(DeviceReturnFlatHierarchyTest, GivenFlatHierarchyIsSetWithMaskThenGetRootDe
TEST(DeviceReturnFlatHierarchyTest, GivenFlatHierarchyIsSetThenGetRootDeviceReturnsNullptr) {
MultiDeviceFixtureHierarchy multiDeviceFixture{};
MultiDeviceFixtureFlatHierarchy multiDeviceFixture{};
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_FLAT;
uint32_t count = 0;
std::vector<ze_device_handle_t> hDevices;
@@ -6058,9 +6044,8 @@ TEST(DeviceReturnCompositeHierarchyTest, GivenCompositeHierarchyIsSetWithMaskThe
DebugManagerStateRestore restorer;
NEO::debugManager.flags.ZE_AFFINITY_MASK.set("0,1,2");
MultiDeviceFixture multiDeviceFixture{};
MultiDeviceFixtureCompositeHierarchy multiDeviceFixture{};
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMPOSITE;
uint32_t count = 0;
std::vector<ze_device_handle_t> hDevices;
@@ -6095,9 +6080,8 @@ TEST(DeviceReturnCompositeHierarchyTest, GivenCompositeHierarchyIsSetWithMaskThe
TEST(DeviceReturnCompositeHierarchyTest, GivenCompositeHierarchyIsSetThenGetRootDeviceIsNotNullForSubDevices) {
MultiDeviceFixture multiDeviceFixture{};
MultiDeviceFixtureCompositeHierarchy multiDeviceFixture{};
multiDeviceFixture.setUp();
multiDeviceFixture.driverHandle->deviceHierarchyMode = L0::L0DeviceHierarchyMode::L0_DEVICE_HIERARCHY_COMPOSITE;
uint32_t count = 0;
std::vector<ze_device_handle_t> hDevices;
@@ -6158,7 +6142,7 @@ TEST_F(DeviceTest, givenDeviceWhenQueryingCmdListMemWaitOnMemDataSizeThenReturnV
EXPECT_EQ(l0GfxCoreHelper.getCmdListWaitOnMemoryDataSize(), sizeProps.cmdListWaitOnMemoryDataSizeInBytes);
}
TEST_F(DeviceTest, givenDeviecWhenQueryingMediaPropertiesThenReturnZero) {
TEST_F(DeviceTest, givenDeviceWhenQueryingMediaPropertiesThenReturnZero) {
ze_device_properties_t devProps = {ZE_STRUCTURE_TYPE_DEVICE_PROPERTIES};
ze_intel_device_media_exp_properties_t mediaProps = {ZE_STRUCTURE_TYPE_INTEL_DEVICE_MEDIA_EXP_PROPERTIES}; // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange), NEO-12901
mediaProps.numDecoderCores = 123;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2024 Intel Corporation
* Copyright (C) 2022-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -212,15 +212,15 @@ TEST_F(FabricVertexFixture, GivenDevicesAreCreatedWhenFabricVertexIsNotSetToDevi
EXPECT_EQ(hVertex, nullptr);
}
class FabricVertexFlatDeviceTestFixture : public MultiDeviceFixtureHierarchy,
class FabricVertexFlatDeviceTestFixture : public MultiDeviceFixtureFlatHierarchy,
public ::testing::Test {
void SetUp() override {
NEO::debugManager.flags.ZE_AFFINITY_MASK.set("0,1.1,2");
MultiDeviceFixtureHierarchy::setUp();
MultiDeviceFixtureFlatHierarchy::setUp();
}
void TearDown() override {
MultiDeviceFixtureHierarchy::tearDown();
MultiDeviceFixtureFlatHierarchy::tearDown();
}
DebugManagerStateRestore restorer;
};

View File

@@ -259,8 +259,7 @@ cl_int CL_API_CALL clGetDeviceIDs(cl_platform_id platform,
cl_uint retNum = 0;
for (auto platformDeviceIndex = 0u; platformDeviceIndex < numDev; platformDeviceIndex++) {
bool exposeSubDevices = pPlatform->peekExecutionEnvironment()->isExposingSubDevicesAsDevices() ||
pPlatform->peekExecutionEnvironment()->isCombinedDeviceHierarchy();
bool exposeSubDevices = pPlatform->peekExecutionEnvironment()->isExposingSubDevicesAsDevices();
ClDevice *device = pPlatform->getClDevice(platformDeviceIndex);
UNRECOVERABLE_IF(device == nullptr);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2024 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -51,7 +51,7 @@ ClDevice::ClDevice(Device &device, ClDevice &rootClDevice, Platform *platform) :
pClSubDevice->decRefApi();
pClSubDevice->internalParentDevice = this;
if (!device.getExecutionEnvironment()->isExposingSubDevicesAsDevices() && !device.getExecutionEnvironment()->isCombinedDeviceHierarchy()) {
if (!device.getExecutionEnvironment()->isExposingSubDevicesAsDevices()) {
auto &deviceInfo = pClSubDevice->deviceInfo;
deviceInfo.parentDevice = this;
deviceInfo.partitionType[0] = CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2024 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -296,4 +296,40 @@ TEST(clGetDeviceIDsNegativeTests, whenFailToCreateDeviceThenclGetDeviceIDsReturn
}
}
TEST(clGetDeviceIDsTest, givenMultipleRootDevicesWithAffinityMaskWhenGetDeviceIdsThenCorrectDevicesAreReturned) {
constexpr auto numRootDevices = 3u;
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
DebugManagerStateRestore restorer;
debugManager.flags.CreateMultipleRootDevices.set(numRootDevices);
debugManager.flags.ZE_AFFINITY_MASK.set("0,1");
cl_uint numDevices = 0;
cl_uint numEntries = numRootDevices;
cl_device_id devices[numRootDevices];
std::string hierarchies[] = {"COMPOSITE", "FLAT", "COMBINED"};
for (std::string hierarchy : hierarchies) {
platformsImpl->clear();
std::unordered_map<std::string, std::string> mockableEnvs = {{"ZE_FLAT_DEVICE_HIERARCHY", hierarchy}};
VariableBackup<std::unordered_map<std::string, std::string> *> mockableEnvValuesBackup(&IoFunctions::mockableEnvValues, &mockableEnvs);
const auto dummyDevice = reinterpret_cast<cl_device_id>(0x1357);
for (auto i = 0u; i < numRootDevices; i++) {
devices[i] = dummyDevice;
}
auto retVal = clGetDeviceIDs(nullptr, CL_DEVICE_TYPE_ALL, numEntries, devices, &numDevices);
EXPECT_EQ(retVal, CL_SUCCESS);
EXPECT_EQ(numDevices, 2u);
for (auto i = 0u; i < numRootDevices; i++) {
if (i < 2u) {
EXPECT_EQ(devices[i], platform()->getClDevice(i));
} else {
EXPECT_EQ(devices[i], dummyDevice);
}
}
}
}
} // namespace ULT

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2024 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -93,7 +93,7 @@ bool Device::genericSubDevicesAllowed() {
deviceBitfield = maxNBitValue(subDeviceCount);
deviceBitfield &= deviceMask;
numSubDevices = static_cast<uint32_t>(deviceBitfield.count());
if (numSubDevices == 1) {
if (numSubDevices == 1 && (!executionEnvironment->isCombinedDeviceHierarchy() || subDeviceCount == 1)) {
numSubDevices = 0;
}
@@ -130,13 +130,14 @@ bool Device::createSubDevices() {
}
bool Device::createDeviceImpl() {
// init sub devices first
if (!createSubDevices()) {
return false;
}
preemptionMode = PreemptionHelper::getDefaultPreemptionMode(getHardwareInfo());
if (!isSubDevice()) {
// init sub devices first
if (!createSubDevices()) {
return false;
}
// initialize common resources once
initializeCommonResources();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2024 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -287,7 +287,7 @@ class Device : public ReferenceTrackedObject<Device> {
virtual void createBindlessHeapsHelper() {}
bool createSubDevices();
bool createGenericSubDevices();
virtual bool genericSubDevicesAllowed();
bool genericSubDevicesAllowed();
void finalizeRayTracing();
void createSecondaryContexts(const EngineControl &primaryEngine, SecondaryContexts &secondaryEnginesForType, uint32_t contextCount, uint32_t regularPriorityCount, uint32_t highPriorityContextCount);
void allocateDebugSurface(size_t debugSurfaceSize);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2021 Intel Corporation
* Copyright (C) 2019-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -23,8 +23,6 @@ class SubDevice : public Device {
bool isSubDevice() const override { return true; }
protected:
bool genericSubDevicesAllowed() override { return false; };
RootDevice &rootDevice;
const uint32_t subDeviceIndex;
};

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2024 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -212,12 +212,6 @@ bool ExecutionEnvironment::getSubDeviceHierarchy(uint32_t index, std::tuple<uint
}
void ExecutionEnvironment::parseAffinityMask() {
// If the device hierarchy is Combined, then skip the affinity mask parsing until level zero device get.
if (isCombinedDeviceHierarchy()) {
return;
}
const auto &affinityMaskString = debugManager.flags.ZE_AFFINITY_MASK.get();
if (affinityMaskString.compare("default") == 0 ||
@@ -225,19 +219,22 @@ void ExecutionEnvironment::parseAffinityMask() {
return;
}
// If the user has requested FLAT device hierarchy models, then report all the sub devices as devices.
// If the user has requested FLAT or COMBINED device hierarchy models, then report all the sub devices as devices.
bool exposeSubDevicesAsApiDevices = isExposingSubDevicesAsDevices();
uint32_t numRootDevices = static_cast<uint32_t>(rootDeviceEnvironments.size());
RootDeviceIndicesMap mapOfIndices;
// Reserve at least for a size equal to rootDeviceEnvironments.size() times four,
// which is enough for typical configurations
uint32_t numRootDevices = static_cast<uint32_t>(rootDeviceEnvironments.size());
uint32_t numDevices = numRootDevices;
size_t reservedSizeForIndices = numRootDevices * 4;
RootDeviceIndicesMap mapOfIndices;
mapOfIndices.reserve(reservedSizeForIndices);
uint32_t hwSubDevicesCount = 0u;
if (exposeSubDevicesAsApiDevices) {
for (uint32_t currentRootDevice = 0u; currentRootDevice < static_cast<uint32_t>(rootDeviceEnvironments.size()); currentRootDevice++) {
for (uint32_t currentRootDevice = 0u; currentRootDevice < numRootDevices; currentRootDevice++) {
auto hwInfo = rootDeviceEnvironments[currentRootDevice]->getHardwareInfo();
hwSubDevicesCount = GfxCoreHelper::getSubDevicesCount(hwInfo);
uint32_t currentSubDevice = 0;
mapOfIndices.push_back(std::make_tuple(currentRootDevice, currentSubDevice));
@@ -246,7 +243,7 @@ void ExecutionEnvironment::parseAffinityMask() {
}
}
numRootDevices = static_cast<uint32_t>(mapOfIndices.size());
numDevices = static_cast<uint32_t>(mapOfIndices.size());
}
std::vector<AffinityMaskHelper> affinityMaskHelper(numRootDevices);
@@ -257,32 +254,27 @@ void ExecutionEnvironment::parseAffinityMask() {
uint32_t deviceIndex = 0;
for (const auto &entry : affinityMaskEntries) {
auto subEntries = StringHelpers::split(entry, ".");
uint32_t rootDeviceIndex = StringHelpers::toUint32t(subEntries[0]);
uint32_t entryIndex = StringHelpers::toUint32t(subEntries[0]);
// tiles as devices
if (exposeSubDevicesAsApiDevices) {
if (rootDeviceIndex >= numRootDevices) {
continue;
}
// FlatHierarchy
if (entryIndex >= numDevices) {
continue;
} else if (exposeSubDevicesAsApiDevices) {
// tiles as devices
// so ignore X.Y
if (subEntries.size() > 1) {
continue;
}
std::tuple<uint32_t, uint32_t> indexKey = mapOfIndices[rootDeviceIndex];
std::tuple<uint32_t, uint32_t> indexKey = mapOfIndices[entryIndex];
auto hwDeviceIndex = std::get<0>(indexKey);
auto tileIndex = std::get<1>(indexKey);
affinityMaskHelper[hwDeviceIndex].enableGenericSubDevice(tileIndex);
// Store the Physical Hierarchy for this SubDevice mapped to the Device Index passed to the user.
mapOfSubDeviceIndices[deviceIndex++] = std::make_tuple(hwDeviceIndex, tileIndex, hwSubDevicesCount);
continue;
}
// cards as devices
if (rootDeviceIndex < numRootDevices) {
auto hwInfo = rootDeviceEnvironments[rootDeviceIndex]->getHardwareInfo();
} else {
// cards as devices
auto hwInfo = rootDeviceEnvironments[entryIndex]->getHardwareInfo();
auto subDevicesCount = GfxCoreHelper::getSubDevicesCount(hwInfo);
if (subEntries.size() > 1) {
@@ -291,14 +283,14 @@ void ExecutionEnvironment::parseAffinityMask() {
if (subDeviceIndex < subDevicesCount) {
if (subEntries.size() == 2) {
// Store the Physical Hierarchy for this SubDevice mapped to the Device Index passed to the user.
mapOfSubDeviceIndices[rootDeviceIndex] = std::make_tuple(rootDeviceIndex, subDeviceIndex, subDevicesCount);
affinityMaskHelper[rootDeviceIndex].enableGenericSubDevice(subDeviceIndex); // Mask: X.Y
mapOfSubDeviceIndices[entryIndex] = std::make_tuple(entryIndex, subDeviceIndex, subDevicesCount);
affinityMaskHelper[entryIndex].enableGenericSubDevice(subDeviceIndex); // Mask: X.Y
} else {
UNRECOVERABLE_IF(subEntries.size() != 3);
}
}
} else {
affinityMaskHelper[rootDeviceIndex].enableAllGenericSubDevices(subDevicesCount); // Mask: X
affinityMaskHelper[entryIndex].enableAllGenericSubDevices(subDevicesCount); // Mask: X
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2024 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -54,6 +54,7 @@ class ExecutionEnvironment : public ReferenceTrackedObject<ExecutionEnvironment>
this->subDevicesAsDevices = value;
}
void setCombinedDeviceHierarchy(bool value) {
this->subDevicesAsDevices = value;
this->combinedDeviceHierarchy = value;
}
bool isExposingSubDevicesAsDevices() const { return this->subDevicesAsDevices; }

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2023 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -59,14 +59,16 @@ bool prepareDeviceEnvironments(ExecutionEnvironment &executionEnvironment) {
if (ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc) {
uint32_t numRootDevices = debugManager.flags.CreateMultipleRootDevices.get() != 0 ? debugManager.flags.CreateMultipleRootDevices.get() : 1u;
UltDeviceFactory::prepareDeviceEnvironments(executionEnvironment, numRootDevices);
retVal = ultHwConfig.mockedPrepareDeviceEnvironmentsFuncResult;
retVal = UltDeviceFactory::prepareDeviceEnvironments(executionEnvironment, numRootDevices);
retVal &= ultHwConfig.mockedPrepareDeviceEnvironmentsFuncResult;
} else {
retVal = prepareDeviceEnvironmentsImpl(executionEnvironment);
}
for (uint32_t rootDeviceIndex = 0u; rootDeviceIndex < executionEnvironment.rootDeviceEnvironments.size(); rootDeviceIndex++) {
executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->initGmm();
if (retVal) {
for (uint32_t rootDeviceIndex = 0u; rootDeviceIndex < executionEnvironment.rootDeviceEnvironments.size(); rootDeviceIndex++) {
executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->initGmm();
}
}
return retVal;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2024 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -60,7 +60,7 @@ UltDeviceFactory::~UltDeviceFactory() {
}
}
void UltDeviceFactory::prepareDeviceEnvironments(ExecutionEnvironment &executionEnvironment, uint32_t rootDevicesCount) {
bool UltDeviceFactory::prepareDeviceEnvironments(ExecutionEnvironment &executionEnvironment, uint32_t rootDevicesCount) {
uint32_t numRootDevices = rootDevicesCount;
executionEnvironment.prepareRootDeviceEnvironments(numRootDevices);
for (auto i = 0u; i < numRootDevices; i++) {
@@ -72,8 +72,12 @@ void UltDeviceFactory::prepareDeviceEnvironments(ExecutionEnvironment &execution
executionEnvironment.rootDeviceEnvironments[i]->memoryOperationsInterface = std::make_unique<MockMemoryOperations>();
}
executionEnvironment.parseAffinityMask();
executionEnvironment.calculateMaxOsContextCount();
DeviceFactory::createMemoryManagerFunc(executionEnvironment);
auto retVal = executionEnvironment.rootDeviceEnvironments.size();
if (retVal) {
executionEnvironment.calculateMaxOsContextCount();
DeviceFactory::createMemoryManagerFunc(executionEnvironment);
}
return retVal;
}
bool UltDeviceFactory::initializeMemoryManager(ExecutionEnvironment &executionEnvironment) {
if (executionEnvironment.memoryManager == nullptr) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2021 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -19,7 +19,7 @@ struct UltDeviceFactory {
UltDeviceFactory(uint32_t rootDevicesCount, uint32_t subDevicesCount, ExecutionEnvironment &executionEnvironment);
~UltDeviceFactory();
static void prepareDeviceEnvironments(ExecutionEnvironment &executionEnvironment, uint32_t rootDevicesCount);
static bool prepareDeviceEnvironments(ExecutionEnvironment &executionEnvironment, uint32_t rootDevicesCount);
static bool initializeMemoryManager(ExecutionEnvironment &executionEnvironment);
std::vector<MockDevice *> rootDevices;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2024 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -946,6 +946,74 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, DeviceTests, givenZeAffinityMaskSetWhenAllocateRTDi
}
}
TEST_F(DeviceTests, givenDifferentHierarchiesWithoutSubDevicesThenNumSubDevicesIsZero) {
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
DebugManagerStateRestore restorer;
uint32_t numRootDevices = 4;
debugManager.flags.CreateMultipleRootDevices.set(numRootDevices);
auto hwInfo = *defaultHwInfo;
std::string hierarchies[] = {"COMPOSITE", "FLAT", "COMBINED"};
for (std::string hierarchy : hierarchies) {
std::unordered_map<std::string, std::string> mockableEnvs = {{"ZE_FLAT_DEVICE_HIERARCHY", hierarchy}};
VariableBackup<std::unordered_map<std::string, std::string> *> mockableEnvValuesBackup(&IoFunctions::mockableEnvValues, &mockableEnvs);
MockExecutionEnvironment executionEnvironment(&hwInfo, false, numRootDevices);
executionEnvironment.incRefInternal();
auto devices = DeviceFactory::createDevices(executionEnvironment);
EXPECT_EQ(devices.size(), numRootDevices);
for (uint32_t i = 0u; i < devices.size(); i++) {
EXPECT_EQ(devices[i]->getNumSubDevices(), 0u);
}
}
}
TEST_F(DeviceTests, givenZeAffinityMaskSetWithDifferentHierarchiesThenNumSubDevicesIsCorrect) {
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
DebugManagerStateRestore restorer;
uint32_t numRootDevices = 4;
uint32_t numSubDevices = 2;
uint32_t expectedNumSubDevices;
debugManager.flags.CreateMultipleRootDevices.set(numRootDevices);
debugManager.flags.CreateMultipleSubDevices.set(numSubDevices);
debugManager.flags.ZE_AFFINITY_MASK.set("0,2");
auto hwInfo = *defaultHwInfo;
std::string hierarchies[] = {"COMPOSITE", "FLAT", "COMBINED"};
for (std::string hierarchy : hierarchies) {
std::unordered_map<std::string, std::string> mockableEnvs = {{"ZE_FLAT_DEVICE_HIERARCHY", hierarchy}};
VariableBackup<std::unordered_map<std::string, std::string> *> mockableEnvValuesBackup(&IoFunctions::mockableEnvValues, &mockableEnvs);
MockExecutionEnvironment executionEnvironment(&hwInfo, false, numRootDevices);
executionEnvironment.incRefInternal();
auto devices = DeviceFactory::createDevices(executionEnvironment);
EXPECT_EQ(devices.size(), 2u);
if (hierarchy == "COMPOSITE") {
expectedNumSubDevices = 2u;
} else if (hierarchy == "FLAT") {
expectedNumSubDevices = 0u;
} else if (hierarchy == "COMBINED") {
expectedNumSubDevices = 1u;
}
for (uint32_t i = 0u; i < devices.size(); i++) {
EXPECT_EQ(devices[i]->getNumSubDevices(), expectedNumSubDevices);
}
}
}
HWCMDTEST_F(IGFX_XE_HP_CORE, DeviceTests, givenZexNumberOfCssEnvVariableIsLargerThanNumberOfAvailableCcsCountWhenDeviceIsCreatedThenCreateDevicesWithAvailableCcsCount) {
VariableBackup<UltHwConfig> backup(&ultHwConfig);
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2024 Intel Corporation
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -664,7 +664,7 @@ TEST(ExecutionEnvironmentDeviceHierarchy, givenExecutionEnvironmentWithCombinedD
MockExecutionEnvironment executionEnvironment;
executionEnvironment.rootDeviceEnvironments[0]->setHwInfoAndInitHelpers(defaultHwInfo.get());
executionEnvironment.setDeviceHierarchy(executionEnvironment.rootDeviceEnvironments[0]->getHelper<GfxCoreHelper>());
EXPECT_FALSE(executionEnvironment.isExposingSubDevicesAsDevices());
EXPECT_TRUE(executionEnvironment.isExposingSubDevicesAsDevices());
}
TEST(ExecutionEnvironment, givenExecutionEnvironmentWhenSetErrorDescriptionIsCalledThenGetErrorDescriptionGetsStringCorrectly) {