fix: assign secondary contexts from correct device

- for root device, copy engines from subdevice are used, secondary
contexts must be selected from subdevice in this case

- return low priority BCS from subdevice

Related-To: NEO-14559

Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:
Mateusz Hoppe
2025-04-17 15:44:22 +00:00
committed by Compute-Runtime-Automation
parent fe1db94454
commit 990fa0d8a9
4 changed files with 78 additions and 67 deletions

View File

@@ -1845,11 +1845,13 @@ ze_result_t DeviceImp::getCsrForOrdinalAndIndex(NEO::CommandStreamReceiver **csr
contextPriority = NEO::EngineUsage::lowPriority; contextPriority = NEO::EngineUsage::lowPriority;
} }
auto selectedDevice = this;
if (ordinal < numEngineGroups) { if (ordinal < numEngineGroups) {
if (contextPriority == NEO::EngineUsage::lowPriority) { if (contextPriority == NEO::EngineUsage::lowPriority) {
getCsrForLowPriority(csr, copyOnly); auto result = getCsrForLowPriority(csr, copyOnly);
return ZE_RESULT_SUCCESS; DEBUG_BREAK_IF(result != ZE_RESULT_SUCCESS);
return result;
} }
auto &engines = engineGroups[ordinal].engines; auto &engines = engineGroups[ordinal].engines;
@@ -1858,22 +1860,30 @@ ze_result_t DeviceImp::getCsrForOrdinalAndIndex(NEO::CommandStreamReceiver **csr
} }
*csr = engines[index].commandStreamReceiver; *csr = engines[index].commandStreamReceiver;
if (copyOnly && contextPriority == NEO::EngineUsage::highPriority) {
getCsrForHighPriority(csr, copyOnly);
}
} else { } else {
auto subDeviceOrdinal = ordinal - numEngineGroups; auto subDeviceOrdinal = ordinal - numEngineGroups;
if (index >= this->subDeviceCopyEngineGroups[subDeviceOrdinal].engines.size()) { if (index >= this->subDeviceCopyEngineGroups[subDeviceOrdinal].engines.size()) {
return ZE_RESULT_ERROR_INVALID_ARGUMENT; return ZE_RESULT_ERROR_INVALID_ARGUMENT;
} }
*csr = this->subDeviceCopyEngineGroups[subDeviceOrdinal].engines[index].commandStreamReceiver; *csr = this->subDeviceCopyEngineGroups[subDeviceOrdinal].engines[index].commandStreamReceiver;
selectedDevice = static_cast<DeviceImp *>(this->subDevices[subDeviceOrdinal]);
}
if (copyOnly) {
if (contextPriority == NEO::EngineUsage::highPriority) {
selectedDevice->getCsrForHighPriority(csr, copyOnly);
} else if (contextPriority == NEO::EngineUsage::lowPriority) {
if (selectedDevice->getCsrForLowPriority(csr, copyOnly) == ZE_RESULT_SUCCESS) {
return ZE_RESULT_SUCCESS;
}
}
} }
auto &osContext = (*csr)->getOsContext(); auto &osContext = (*csr)->getOsContext();
if (secondaryContextsEnabled) { if (secondaryContextsEnabled) {
tryAssignSecondaryContext(osContext.getEngineType(), contextPriority, csr, allocateInterrupt); selectedDevice->tryAssignSecondaryContext(osContext.getEngineType(), contextPriority, csr, allocateInterrupt);
} }
return ZE_RESULT_SUCCESS; return ZE_RESULT_SUCCESS;
@@ -1904,8 +1914,6 @@ ze_result_t DeviceImp::getCsrForLowPriority(NEO::CommandStreamReceiver **csr, bo
} }
// if the code falls through, we have no low priority context created by neoDevice. // if the code falls through, we have no low priority context created by neoDevice.
UNRECOVERABLE_IF(true);
return ZE_RESULT_ERROR_UNKNOWN; return ZE_RESULT_ERROR_UNKNOWN;
} }
ze_result_t DeviceImp::getCsrForHighPriority(NEO::CommandStreamReceiver **csr, bool copyOnly) { ze_result_t DeviceImp::getCsrForHighPriority(NEO::CommandStreamReceiver **csr, bool copyOnly) {

View File

@@ -7,7 +7,9 @@
#pragma once #pragma once
#include "shared/source/command_container/implicit_scaling.h"
#include "shared/source/helpers/hw_info.h" #include "shared/source/helpers/hw_info.h"
#include "shared/source/os_interface/os_interface.h"
#include "shared/source/os_interface/os_time.h" #include "shared/source/os_interface/os_time.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h" #include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/variable_backup.h" #include "shared/test/common/helpers/variable_backup.h"
@@ -280,5 +282,53 @@ class FalseUnSupportedFeatureGpuCpuTime : public NEO::OSTime {
} }
}; };
template <bool osLocalMemory, bool apiSupport, int32_t enablePartitionWalker, int32_t enableImplicitScaling>
struct MultiSubDeviceFixture : public DeviceFixture {
void setUp() {
setUp(nullptr);
}
void setUp(NEO::HardwareInfo *hwInfo) {
debugManager.flags.CreateMultipleSubDevices.set(2);
debugManager.flags.EnableWalkerPartition.set(enablePartitionWalker);
debugManager.flags.EnableImplicitScaling.set(enableImplicitScaling);
osLocalMemoryBackup = std::make_unique<VariableBackup<bool>>(&NEO::OSInterface::osEnableLocalMemory, osLocalMemory);
apiSupportBackup = std::make_unique<VariableBackup<bool>>(&NEO::ImplicitScaling::apiSupport, apiSupport);
if (hwInfo == nullptr) {
DeviceFixture::setUp();
} else {
DeviceFixture::setUpImpl(hwInfo);
}
deviceImp = reinterpret_cast<L0::DeviceImp *>(device);
subDevice = neoDevice->getSubDevice(0);
}
L0::DeviceImp *deviceImp = nullptr;
NEO::Device *subDevice = nullptr;
DebugManagerStateRestore restorer;
std::unique_ptr<VariableBackup<bool>> osLocalMemoryBackup;
std::unique_ptr<VariableBackup<bool>> apiSupportBackup;
};
struct MultiSubDeviceWithContextGroupAndImplicitScalingTest : public MultiSubDeviceFixture<true, true, -1, 1>, public ::testing::Test {
void SetUp() override {
debugManager.flags.ContextGroupSize.set(8);
hardwareInfo = *defaultHwInfo;
hardwareInfo.featureTable.ftrBcsInfo = 0b1111;
hardwareInfo.capabilityTable.blitterOperationsSupported = true;
MultiSubDeviceFixture<true, true, -1, 1>::setUp(&hardwareInfo);
}
void TearDown() override {
MultiSubDeviceFixture<true, true, -1, 1>::tearDown();
}
DebugManagerStateRestore restorer;
HardwareInfo hardwareInfo;
};
} // namespace ult } // namespace ult
} // namespace L0 } // namespace L0

View File

@@ -934,7 +934,7 @@ TEST_F(DeviceCreateCommandQueueTest,
commandQueue->destroy(); commandQueue->destroy();
} }
TEST_F(DeviceCreateCommandQueueTest, givenLowPriorityDescAndWithoutLowPriorityCsrWhenCreateCommandQueueIsCalledThenAbortIsThrown) { TEST_F(DeviceCreateCommandQueueTest, givenLowPriorityDescAndWithoutLowPriorityCsrWhenCreateCommandQueueIsCalledThenErrorReturned) {
// remove low priority EngineControl objects for negative testing // remove low priority EngineControl objects for negative testing
neoDevice->allEngines.erase(std::remove_if( neoDevice->allEngines.erase(std::remove_if(
neoDevice->allEngines.begin(), neoDevice->allEngines.begin(),
@@ -948,7 +948,7 @@ TEST_F(DeviceCreateCommandQueueTest, givenLowPriorityDescAndWithoutLowPriorityCs
ze_command_queue_handle_t commandQueueHandle = {}; ze_command_queue_handle_t commandQueueHandle = {};
EXPECT_THROW(device->createCommandQueue(&desc, &commandQueueHandle), std::exception); EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, device->createCommandQueue(&desc, &commandQueueHandle));
} }
struct MultiDeviceCreateCommandQueueFixture : MultiDeviceFixture { struct MultiDeviceCreateCommandQueueFixture : MultiDeviceFixture {

View File

@@ -5251,36 +5251,6 @@ TEST_F(zeDeviceSystemBarrierTest, whenCallingSystemBarrierThenReturnErrorUnsuppo
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result); EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
} }
template <bool osLocalMemory, bool apiSupport, int32_t enablePartitionWalker, int32_t enableImplicitScaling>
struct MultiSubDeviceFixture : public DeviceFixture {
void setUp() {
setUp(nullptr);
}
void setUp(NEO::HardwareInfo *hwInfo) {
debugManager.flags.CreateMultipleSubDevices.set(2);
debugManager.flags.EnableWalkerPartition.set(enablePartitionWalker);
debugManager.flags.EnableImplicitScaling.set(enableImplicitScaling);
osLocalMemoryBackup = std::make_unique<VariableBackup<bool>>(&NEO::OSInterface::osEnableLocalMemory, osLocalMemory);
apiSupportBackup = std::make_unique<VariableBackup<bool>>(&NEO::ImplicitScaling::apiSupport, apiSupport);
if (hwInfo == nullptr) {
DeviceFixture::setUp();
} else {
DeviceFixture::setUpImpl(hwInfo);
}
deviceImp = reinterpret_cast<L0::DeviceImp *>(device);
subDevice = neoDevice->getSubDevice(0);
}
L0::DeviceImp *deviceImp = nullptr;
NEO::Device *subDevice = nullptr;
DebugManagerStateRestore restorer;
std::unique_ptr<VariableBackup<bool>> osLocalMemoryBackup;
std::unique_ptr<VariableBackup<bool>> apiSupportBackup;
};
using MultiSubDeviceTest = Test<MultiSubDeviceFixture<true, true, -1, -1>>; using MultiSubDeviceTest = Test<MultiSubDeviceFixture<true, true, -1, -1>>;
TEST_F(MultiSubDeviceTest, GivenApiSupportAndLocalMemoryEnabledWhenDeviceContainsSubDevicesThenItIsImplicitScalingCapable) { TEST_F(MultiSubDeviceTest, GivenApiSupportAndLocalMemoryEnabledWhenDeviceContainsSubDevicesThenItIsImplicitScalingCapable) {
auto &gfxCoreHelper = neoDevice->getGfxCoreHelper(); auto &gfxCoreHelper = neoDevice->getGfxCoreHelper();
@@ -5321,7 +5291,7 @@ TEST_F(MultiSubDeviceEnabledImplicitScalingTest, GivenEnabledImplicitScalingWhen
auto &defaultEngine = deviceImp->getActiveDevice()->getDefaultEngine(); auto &defaultEngine = deviceImp->getActiveDevice()->getDefaultEngine();
NEO::CommandStreamReceiver *csr = nullptr; NEO::CommandStreamReceiver *csr = nullptr;
EXPECT_ANY_THROW(deviceImp->getCsrForLowPriority(&csr, false)); EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, deviceImp->getCsrForLowPriority(&csr, false));
auto ret = deviceImp->getCsrForOrdinalAndIndex(&csr, 0, 0, ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW, false); auto ret = deviceImp->getCsrForOrdinalAndIndex(&csr, 0, 0, ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW, false);
@@ -5329,29 +5299,11 @@ TEST_F(MultiSubDeviceEnabledImplicitScalingTest, GivenEnabledImplicitScalingWhen
EXPECT_EQ(defaultEngine.commandStreamReceiver, csr); EXPECT_EQ(defaultEngine.commandStreamReceiver, csr);
} }
struct MultiSubDeviceWithContextGroupAndImplicitScalingTest : public MultiSubDeviceFixture<true, true, -1, 1>, public ::testing::Test {
void SetUp() override {
debugManager.flags.ContextGroupSize.set(8);
hardwareInfo = *defaultHwInfo;
hardwareInfo.featureTable.ftrBcsInfo = 0b1111;
hardwareInfo.capabilityTable.blitterOperationsSupported = true;
MultiSubDeviceFixture<true, true, -1, 1>::setUp(&hardwareInfo);
}
void TearDown() override {
MultiSubDeviceFixture<true, true, -1, 1>::tearDown();
}
DebugManagerStateRestore restorer;
HardwareInfo hardwareInfo;
};
HWTEST2_F(MultiSubDeviceWithContextGroupAndImplicitScalingTest, GivenRootDeviceWhenGettingLowPriorityCsrForComputeEngineThenDefaultCsrReturned, IsAtLeastXeHpgCore) { HWTEST2_F(MultiSubDeviceWithContextGroupAndImplicitScalingTest, GivenRootDeviceWhenGettingLowPriorityCsrForComputeEngineThenDefaultCsrReturned, IsAtLeastXeHpgCore) {
auto &defaultEngine = deviceImp->getActiveDevice()->getDefaultEngine(); auto &defaultEngine = deviceImp->getActiveDevice()->getDefaultEngine();
NEO::CommandStreamReceiver *csr = nullptr; NEO::CommandStreamReceiver *csr = nullptr;
EXPECT_ANY_THROW(deviceImp->getCsrForLowPriority(&csr, false)); EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, deviceImp->getCsrForLowPriority(&csr, false));
auto ret = deviceImp->getCsrForOrdinalAndIndex(&csr, 0, 0, ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW, false); auto ret = deviceImp->getCsrForOrdinalAndIndex(&csr, 0, 0, ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW, false);
@@ -5359,29 +5311,30 @@ HWTEST2_F(MultiSubDeviceWithContextGroupAndImplicitScalingTest, GivenRootDeviceW
EXPECT_EQ(defaultEngine.commandStreamReceiver, csr); EXPECT_EQ(defaultEngine.commandStreamReceiver, csr);
} }
HWTEST2_F(MultiSubDeviceWithContextGroupAndImplicitScalingTest, GivenRootDeviceWhenGettingLowPriorityCsrForCopyEngineThenRegularBcsIsReturned, IsAtLeastXeHpgCore) { HWTEST2_F(MultiSubDeviceWithContextGroupAndImplicitScalingTest, GivenRootDeviceWhenGettingLowPriorityCsrForCopyEngineThenRegularBcsIsReturned, IsAtMostXe3Core) {
NEO::CommandStreamReceiver *csr = nullptr; NEO::CommandStreamReceiver *csr = nullptr;
EXPECT_ANY_THROW(deviceImp->getCsrForLowPriority(&csr, true)); EXPECT_EQ(ZE_RESULT_ERROR_UNKNOWN, deviceImp->getCsrForLowPriority(&csr, true));
auto ordinal = deviceImp->getCopyEngineOrdinal();
auto ordinal = deviceImp->getCopyEngineOrdinal();
auto ret = deviceImp->getCsrForOrdinalAndIndex(&csr, ordinal, 0, ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW, false); auto ret = deviceImp->getCsrForOrdinalAndIndex(&csr, ordinal, 0, ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW, false);
EXPECT_EQ(ZE_RESULT_SUCCESS, ret); EXPECT_EQ(ZE_RESULT_SUCCESS, ret);
EXPECT_NE(nullptr, csr); EXPECT_NE(nullptr, csr);
EXPECT_TRUE(csr->getOsContext().isRegular()); EXPECT_TRUE(csr->getOsContext().isRegular());
EXPECT_EQ(1u, csr->getOsContext().getDeviceBitfield().count());
} }
HWTEST2_F(MultiSubDeviceWithContextGroupAndImplicitScalingTest, GivenRootDeviceWhenGettingHighPriorityCsrForCopyEngineThenRegularBcsIsReturned, IsAtLeastXeHpgCore) { HWTEST2_F(MultiSubDeviceWithContextGroupAndImplicitScalingTest, GivenRootDeviceWhenGettingHighPriorityCsrForCopyEngineThenSubDeviceHpBcsIsReturned, IsAtLeastXeHpgCore) {
NEO::CommandStreamReceiver *csr = nullptr; NEO::CommandStreamReceiver *csr = nullptr;
EXPECT_ANY_THROW(deviceImp->getCsrForLowPriority(&csr, true));
auto ordinal = deviceImp->getCopyEngineOrdinal(); auto ordinal = deviceImp->getCopyEngineOrdinal();
auto ret = deviceImp->getCsrForOrdinalAndIndex(&csr, ordinal, 0, ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_HIGH, false); auto ret = deviceImp->getCsrForOrdinalAndIndex(&csr, ordinal, 0, ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_HIGH, false);
EXPECT_EQ(ZE_RESULT_SUCCESS, ret); EXPECT_EQ(ZE_RESULT_SUCCESS, ret);
EXPECT_NE(nullptr, csr); EXPECT_NE(nullptr, csr);
EXPECT_TRUE(csr->getOsContext().isRegular()); EXPECT_TRUE(csr->getOsContext().isHighPriority());
EXPECT_EQ(1u, csr->getOsContext().getDeviceBitfield().count());
} }
using DeviceSimpleTests = Test<DeviceFixture>; using DeviceSimpleTests = Test<DeviceFixture>;