feature: assign secondary BCS engines at queue creation

Related-To: NEO-7824

Signed-off-by: Bartosz Dunajski <bartosz.dunajski@intel.com>
This commit is contained in:
Bartosz Dunajski
2024-05-31 14:39:53 +00:00
committed by Compute-Runtime-Automation
parent 78eda1e952
commit 88ed909e57
8 changed files with 145 additions and 29 deletions

View File

@@ -1694,6 +1694,9 @@ ze_result_t DeviceImp::getCsrForOrdinalAndIndex(NEO::CommandStreamReceiver **csr
} }
} }
const NEO::GfxCoreHelper &gfxCoreHelper = neoDevice->getGfxCoreHelper();
bool secondaryContextsEnabled = gfxCoreHelper.areSecondaryContextsSupported();
if (ordinal < numEngineGroups) { if (ordinal < numEngineGroups) {
auto &engines = engineGroups[ordinal].engines; auto &engines = engineGroups[ordinal].engines;
if (index >= engines.size()) { if (index >= engines.size()) {
@@ -1703,19 +1706,10 @@ ze_result_t DeviceImp::getCsrForOrdinalAndIndex(NEO::CommandStreamReceiver **csr
auto &osContext = (*csr)->getOsContext(); auto &osContext = (*csr)->getOsContext();
const NEO::GfxCoreHelper &gfxCoreHelper = neoDevice->getGfxCoreHelper();
bool secondaryContextsEnabled = gfxCoreHelper.areSecondaryContextsSupported();
if (neoDevice->isMultiRegularContextSelectionAllowed(osContext.getEngineType(), osContext.getEngineUsage())) { if (neoDevice->isMultiRegularContextSelectionAllowed(osContext.getEngineType(), osContext.getEngineUsage())) {
*csr = neoDevice->getNextEngineForMultiRegularContextMode(osContext.getEngineType()).commandStreamReceiver; *csr = neoDevice->getNextEngineForMultiRegularContextMode(osContext.getEngineType()).commandStreamReceiver;
} else if (secondaryContextsEnabled && neoDevice->isSecondaryContextEngineType(osContext.getEngineType())) { } else if (secondaryContextsEnabled) {
NEO::EngineTypeUsage engineTypeUsage; tryAssignSecondaryContext(osContext.getEngineType(), NEO::EngineUsage::regular, csr);
engineTypeUsage.first = osContext.getEngineType();
engineTypeUsage.second = NEO::EngineUsage::regular;
auto engine = neoDevice->getSecondaryEngineCsr(engineTypeUsage);
if (engine) {
*csr = engine->commandStreamReceiver;
}
} }
} else { } else {
auto subDeviceOrdinal = ordinal - numEngineGroups; auto subDeviceOrdinal = ordinal - numEngineGroups;
@@ -1723,11 +1717,30 @@ ze_result_t DeviceImp::getCsrForOrdinalAndIndex(NEO::CommandStreamReceiver **csr
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;
if (secondaryContextsEnabled) {
tryAssignSecondaryContext((*csr)->getOsContext().getEngineType(), NEO::EngineUsage::regular, csr);
}
} }
return ZE_RESULT_SUCCESS; return ZE_RESULT_SUCCESS;
} }
bool DeviceImp::tryAssignSecondaryContext(aub_stream::EngineType engineType, NEO::EngineUsage engineUsage, NEO::CommandStreamReceiver **csr) {
if (neoDevice->isSecondaryContextEngineType(engineType)) {
NEO::EngineTypeUsage engineTypeUsage;
engineTypeUsage.first = engineType;
engineTypeUsage.second = engineUsage;
auto engine = neoDevice->getSecondaryEngineCsr(engineTypeUsage);
if (engine) {
*csr = engine->commandStreamReceiver;
return true;
}
}
return false;
}
ze_result_t DeviceImp::getCsrForOrdinalAndIndexWithPriority(NEO::CommandStreamReceiver **csr, uint32_t ordinal, uint32_t index, ze_command_queue_priority_t priority) { ze_result_t DeviceImp::getCsrForOrdinalAndIndexWithPriority(NEO::CommandStreamReceiver **csr, uint32_t ordinal, uint32_t index, ze_command_queue_priority_t priority) {
if (!this->isQueueGroupOrdinalValid(ordinal)) { if (!this->isQueueGroupOrdinalValid(ordinal)) {
@@ -1750,15 +1763,8 @@ ze_result_t DeviceImp::getCsrForOrdinalAndIndexWithPriority(NEO::CommandStreamRe
*csr = engines[index].commandStreamReceiver; *csr = engines[index].commandStreamReceiver;
auto &osContext = (*csr)->getOsContext(); auto &osContext = (*csr)->getOsContext();
if (neoDevice->isSecondaryContextEngineType(osContext.getEngineType())) { if (tryAssignSecondaryContext(osContext.getEngineType(), NEO::EngineUsage::highPriority, csr)) {
NEO::EngineTypeUsage engineTypeUsage; return ZE_RESULT_SUCCESS;
engineTypeUsage.first = osContext.getEngineType();
engineTypeUsage.second = NEO::EngineUsage::highPriority;
auto engine = neoDevice->getSecondaryEngineCsr(engineTypeUsage);
if (engine) {
*csr = engine->commandStreamReceiver;
return ZE_RESULT_SUCCESS;
}
} }
} }
} else if (isSuitableForLowPriority(priority, NEO::EngineHelper::isCopyOnlyEngineType( } else if (isSuitableForLowPriority(priority, NEO::EngineHelper::isCopyOnlyEngineType(

View File

@@ -177,6 +177,7 @@ struct DeviceImp : public Device, NEO::NonCopyableOrMovableClass {
NEO::EngineGroupType getEngineGroupTypeForOrdinal(uint32_t ordinal) const; NEO::EngineGroupType getEngineGroupTypeForOrdinal(uint32_t ordinal) const;
void getP2PPropertiesDirectFabricConnection(DeviceImp *peerDeviceImp, void getP2PPropertiesDirectFabricConnection(DeviceImp *peerDeviceImp,
ze_device_p2p_bandwidth_exp_properties_t *bandwidthPropertiesDesc); ze_device_p2p_bandwidth_exp_properties_t *bandwidthPropertiesDesc);
bool tryAssignSecondaryContext(aub_stream::EngineType engineType, NEO::EngineUsage engineUsage, NEO::CommandStreamReceiver **csr);
NEO::EngineGroupsT subDeviceCopyEngineGroups{}; NEO::EngineGroupsT subDeviceCopyEngineGroups{};
NEO::GraphicsAllocation *debugSurface = nullptr; NEO::GraphicsAllocation *debugSurface = nullptr;

View File

@@ -1981,5 +1981,68 @@ TEST(CommandList, givenContextGroupEnabledWhenCreatingImmediateCommandListThenEa
commandList2->destroy(); commandList2->destroy();
} }
TEST(CommandList, givenCopyContextGroupEnabledWhenCreatingImmediateCommandListThenEachCmdListHasDifferentCsr) {
HardwareInfo hwInfo = *defaultHwInfo;
DebugManagerStateRestore dbgRestorer;
debugManager.flags.ContextGroupSize.set(5);
hwInfo.featureTable.ftrBcsInfo = 0b111;
hwInfo.capabilityTable.blitterOperationsSupported = true;
auto neoDevice = NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo);
NEO::DeviceVector devices;
devices.push_back(std::unique_ptr<NEO::Device>(neoDevice));
auto driverHandle = std::make_unique<Mock<L0::DriverHandleImp>>();
driverHandle->initialize(std::move(devices));
auto device = static_cast<DeviceImp *>(driverHandle->devices[0]);
auto &regularEngines = device->getNEODevice()->getRegularEngineGroups();
auto iter = std::find_if(regularEngines.begin(), regularEngines.end(), [](const auto &engine) {
return (engine.engineGroupType == EngineGroupType::copy || engine.engineGroupType == EngineGroupType::linkedCopy);
});
if (iter == regularEngines.end()) {
GTEST_SKIP();
}
ze_command_queue_desc_t desc = {};
desc.ordinal = device->getCopyEngineOrdinal();
desc.index = 0;
ze_command_list_handle_t commandListHandle1, commandListHandle2;
auto result = device->createCommandListImmediate(&desc, &commandListHandle1);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = device->createCommandListImmediate(&desc, &commandListHandle2);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
auto commandList1 = static_cast<CommandListImp *>(L0::CommandList::fromHandle(commandListHandle1));
auto commandList2 = static_cast<CommandListImp *>(L0::CommandList::fromHandle(commandListHandle2));
EXPECT_NE(commandList1->getCsr(), commandList2->getCsr());
commandList1->destroy();
commandList2->destroy();
desc.priority = ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_HIGH;
result = device->createCommandListImmediate(&desc, &commandListHandle1);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = device->createCommandListImmediate(&desc, &commandListHandle2);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
commandList1 = static_cast<CommandListImp *>(L0::CommandList::fromHandle(commandListHandle1));
commandList2 = static_cast<CommandListImp *>(L0::CommandList::fromHandle(commandListHandle2));
EXPECT_NE(commandList1->getCsr(), commandList2->getCsr());
commandList1->destroy();
commandList2->destroy();
}
} // namespace ult } // namespace ult
} // namespace L0 } // namespace L0

View File

@@ -356,6 +356,11 @@ void CommandQueue::constructBcsEngine(bool internalUsage) {
if (bcsEngines[bcsIndex]) { if (bcsEngines[bcsIndex]) {
bcsQueueEngineType = bcsEngineType; bcsQueueEngineType = bcsEngineType;
if (gfxCoreHelper.areSecondaryContextsSupported() && !internalUsage) {
bcsEngines[bcsIndex] = device->getDevice().getSecondaryEngineCsr({bcsEngineType, engineUsage});
}
bcsEngines[bcsIndex]->osContext->ensureContextInitialized(); bcsEngines[bcsIndex]->osContext->ensureContextInitialized();
bcsEngines[bcsIndex]->commandStreamReceiver->initDirectSubmission(); bcsEngines[bcsIndex]->commandStreamReceiver->initDirectSubmission();
} }
@@ -1218,6 +1223,10 @@ void CommandQueue::overrideEngine(aub_stream::EngineType engineType, EngineUsage
} }
if (bcsEngines[engineIndex]) { if (bcsEngines[engineIndex]) {
bcsQueueEngineType = engineType; bcsQueueEngineType = engineType;
if (secondaryContextsEnabled) {
bcsEngines[engineIndex] = device->getDevice().getSecondaryEngineCsr({engineType, engineUsage});
}
} }
timestampPacketContainer = std::make_unique<TimestampPacketContainer>(); timestampPacketContainer = std::make_unique<TimestampPacketContainer>();
deferredTimestampPackets = std::make_unique<TimestampPacketContainer>(); deferredTimestampPackets = std::make_unique<TimestampPacketContainer>();

View File

@@ -2718,6 +2718,41 @@ HWTEST_F(CommandQueueOnSpecificEngineTests, givenMultipleFamiliesWhenCreatingQue
EXPECT_NE(nullptr, queueBcs.getTimestampPacketContainer()); EXPECT_NE(nullptr, queueBcs.getTimestampPacketContainer());
} }
HWTEST_F(CommandQueueOnSpecificEngineTests, givenContextGroupWhenCreatingQueuesThenAssignDifferentCsr) {
DebugManagerStateRestore restore;
debugManager.flags.ContextGroupSize.set(8);
HardwareInfo hwInfo = *defaultHwInfo;
hwInfo.capabilityTable.blitterOperationsSupported = true;
MockExecutionEnvironment mockExecutionEnvironment{&hwInfo};
auto raiiGfxCoreHelper = overrideGfxCoreHelper<FamilyType, MockGfxCoreHelper<FamilyType, 0, 1, 1>>(*mockExecutionEnvironment.rootDeviceEnvironments[0]);
MockDevice *device = MockDevice::createWithNewExecutionEnvironment<MockDevice>(&hwInfo, 0);
MockClDevice clDevice{device};
MockContext context{&clDevice};
cl_command_queue_properties properties[5] = {};
fillProperties(properties, 1, 0);
MockCommandQueue queueBcs0(&context, context.getDevice(0), properties, false);
MockCommandQueue queueBcs1(&context, context.getDevice(0), properties, false);
MockCommandQueue queueBcs2(&context, context.getDevice(0), properties, false);
EXPECT_EQ(aub_stream::EngineType::ENGINE_BCS, queueBcs1.bcsEngines[0]->osContext->getEngineType());
EXPECT_EQ(aub_stream::EngineType::ENGINE_BCS, queueBcs2.bcsEngines[0]->osContext->getEngineType());
auto csr1 = static_cast<UltCommandStreamReceiver<FamilyType> *>(queueBcs1.bcsEngines[0]->commandStreamReceiver);
auto csr2 = static_cast<UltCommandStreamReceiver<FamilyType> *>(queueBcs2.bcsEngines[0]->commandStreamReceiver);
EXPECT_NE(csr1, csr2);
EXPECT_NE(nullptr, csr1->primaryCsr);
EXPECT_NE(nullptr, csr2->primaryCsr);
EXPECT_EQ(csr1->primaryCsr, csr2->primaryCsr);
}
HWTEST_F(CommandQueueOnSpecificEngineTests, givenRootDeviceAndMultipleFamiliesWhenCreatingQueueOnSpecificEngineThenUseDefaultEngine) { HWTEST_F(CommandQueueOnSpecificEngineTests, givenRootDeviceAndMultipleFamiliesWhenCreatingQueueOnSpecificEngineThenUseDefaultEngine) {
VariableBackup<HardwareInfo> backupHwInfo(defaultHwInfo.get()); VariableBackup<HardwareInfo> backupHwInfo(defaultHwInfo.get());
defaultHwInfo->capabilityTable.blitterOperationsSupported = true; defaultHwInfo->capabilityTable.blitterOperationsSupported = true;

View File

@@ -195,7 +195,7 @@ class Device : public ReferenceTrackedObject<Device> {
MOCKABLE_VIRTUAL EngineControl *getSecondaryEngineCsr(EngineTypeUsage engineTypeUsage); MOCKABLE_VIRTUAL EngineControl *getSecondaryEngineCsr(EngineTypeUsage engineTypeUsage);
bool isSecondaryContextEngineType(aub_stream::EngineType type) { bool isSecondaryContextEngineType(aub_stream::EngineType type) {
return EngineHelpers::isCcs(type); return EngineHelpers::isCcs(type) || EngineHelpers::isBcs(type);
} }
std::atomic<uint32_t> debugExecutionCounter = 0; std::atomic<uint32_t> debugExecutionCounter = 0;

View File

@@ -78,6 +78,7 @@ class UltCommandStreamReceiver : public CommandStreamReceiverHw<GfxFamily>, publ
using BaseClass::pageTableManagerInitialized; using BaseClass::pageTableManagerInitialized;
using BaseClass::perDssBackedBuffer; using BaseClass::perDssBackedBuffer;
using BaseClass::postInitFlagsSetup; using BaseClass::postInitFlagsSetup;
using BaseClass::primaryCsr;
using BaseClass::programActivePartitionConfig; using BaseClass::programActivePartitionConfig;
using BaseClass::programEnginePrologue; using BaseClass::programEnginePrologue;
using BaseClass::programPerDssBackedBuffer; using BaseClass::programPerDssBackedBuffer;

View File

@@ -1107,17 +1107,18 @@ TEST_F(DeviceTests, whenCheckingPreferredPlatformNameThenNullIsReturned) {
EXPECT_EQ(nullptr, defaultHwInfo->capabilityTable.preferredPlatformName); EXPECT_EQ(nullptr, defaultHwInfo->capabilityTable.preferredPlatformName);
} }
TEST(Device, givenDifferentEngineTypesWhenIsSecondaryContextEngineTypeCalledThenTrueReturnedForCCS) { TEST(Device, givenDifferentEngineTypesWhenIsSecondaryContextEngineTypeCalledThenTrueReturnedForCcsOrBcs) {
auto device = std::unique_ptr<Device>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get())); auto device = std::unique_ptr<Device>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
EXPECT_TRUE(device->isSecondaryContextEngineType(aub_stream::ENGINE_CCS)); for (uint32_t i = 0; i < static_cast<uint32_t>(aub_stream::EngineType::NUM_ENGINES); i++) {
EXPECT_TRUE(device->isSecondaryContextEngineType(aub_stream::ENGINE_CCS1)); auto type = static_cast<aub_stream::EngineType>(i);
EXPECT_TRUE(device->isSecondaryContextEngineType(aub_stream::ENGINE_CCS2));
EXPECT_TRUE(device->isSecondaryContextEngineType(aub_stream::ENGINE_CCS3));
EXPECT_FALSE(device->isSecondaryContextEngineType(aub_stream::ENGINE_RCS)); if (EngineHelpers::isBcs(type) || EngineHelpers::isCcs(type)) {
EXPECT_FALSE(device->isSecondaryContextEngineType(aub_stream::ENGINE_CCCS)); EXPECT_TRUE(device->isSecondaryContextEngineType(type));
EXPECT_FALSE(device->isSecondaryContextEngineType(aub_stream::ENGINE_BCS)); } else {
EXPECT_FALSE(device->isSecondaryContextEngineType(type));
}
}
} }
HWCMDTEST_F(IGFX_XE_HP_CORE, DeviceTests, givenCCSEngineAndContextGroupSizeEnabledWhenCreatingEngineThenItsContextHasContextGroupFlagSet) { HWCMDTEST_F(IGFX_XE_HP_CORE, DeviceTests, givenCCSEngineAndContextGroupSizeEnabledWhenCreatingEngineThenItsContextHasContextGroupFlagSet) {