Skip to content

Commit e6e6ae2

Browse files
Don't use low-priority CSR for copy-only cmdq
getCsrForLowPriority will always return a CSR with a compute engine regardless of the ordinal used. When a copy-only ordinal is used to create a command queue or command list, batch buffers are written using BCS style commands rather than CCS style. This caused BCS commands to be submitted to a low-priority compute engine which was invalid. This patch ensures a copy engine is selected when a copy-only ordinal is used even if ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW is specified. Related-To: LOCI-2980 Signed-off-by: Lisanna Dettwyler <[email protected]>
1 parent 8f5dd3c commit e6e6ae2

File tree

2 files changed

+74
-4
lines changed

2 files changed

+74
-4
lines changed

level_zero/core/source/device/device_imp.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,11 @@ ze_result_t DeviceImp::createCommandQueue(const ze_command_queue_desc_t *desc,
179179
if (desc->ordinal >= engineGroups.size()) {
180180
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
181181
}
182-
if (desc->priority == ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW) {
182+
183+
auto &hwHelper = NEO::HwHelper::get(platform.eRenderCoreFamily);
184+
bool isCopyOnly = hwHelper.isCopyOnlyEngineType(engineGroups[desc->ordinal].engineGroupType);
185+
186+
if (desc->priority == ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW && !isCopyOnly) {
183187
getCsrForLowPriority(&csr);
184188
} else {
185189
auto ret = getCsrForOrdinalAndIndex(&csr, desc->ordinal, desc->index);
@@ -190,9 +194,6 @@ ze_result_t DeviceImp::createCommandQueue(const ze_command_queue_desc_t *desc,
190194

191195
UNRECOVERABLE_IF(csr == nullptr);
192196

193-
auto &hwHelper = NEO::HwHelper::get(platform.eRenderCoreFamily);
194-
bool isCopyOnly = hwHelper.isCopyOnlyEngineType(engineGroups[desc->ordinal].engineGroupType);
195-
196197
ze_result_t returnValue = ZE_RESULT_SUCCESS;
197198
*commandQueue = CommandQueue::create(platform.eProductFamily, this, csr, desc, isCopyOnly, false, returnValue);
198199

level_zero/core/test/unit_tests/sources/cmdqueue/test_cmdqueue_1.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,75 @@ TEST_F(DeviceCreateCommandQueueTest, givenLowPriorityDescWhenCreateCommandQueueI
10501050
commandQueue->destroy();
10511051
}
10521052

1053+
TEST_F(DeviceCreateCommandQueueTest, givenCopyOrdinalWhenCreateCommandQueueWithLowPriorityDescIsCalledThenCopyCsrIsAssigned) {
1054+
auto copyCsr = std::unique_ptr<NEO::CommandStreamReceiver>(neoDevice->createCommandStreamReceiver());
1055+
EngineDescriptor copyEngineDescriptor({aub_stream::ENGINE_BCS, EngineUsage::Regular}, neoDevice->getDeviceBitfield(), neoDevice->getPreemptionMode(), false, false);
1056+
auto copyOsContext = neoDevice->getExecutionEnvironment()->memoryManager->createAndRegisterOsContext(copyCsr.get(), copyEngineDescriptor);
1057+
copyCsr->setupContext(*copyOsContext);
1058+
1059+
auto computeCsr = std::unique_ptr<NEO::CommandStreamReceiver>(neoDevice->createCommandStreamReceiver());
1060+
EngineDescriptor computeEngineDescriptor({aub_stream::ENGINE_CCS, EngineUsage::LowPriority}, neoDevice->getDeviceBitfield(), neoDevice->getPreemptionMode(), false, false);
1061+
auto computeOsContext = neoDevice->getExecutionEnvironment()->memoryManager->createAndRegisterOsContext(computeCsr.get(), computeEngineDescriptor);
1062+
computeCsr->setupContext(*computeOsContext);
1063+
1064+
auto &engineGroups = neoDevice->getRegularEngineGroups();
1065+
engineGroups.clear();
1066+
1067+
auto &allEngines = const_cast<std::vector<NEO::EngineControl> &>(neoDevice->getAllEngines());
1068+
allEngines.clear();
1069+
1070+
engineGroups.push_back(NEO::Device::EngineGroupT{});
1071+
engineGroups.back().engineGroupType = EngineGroupType::Copy;
1072+
engineGroups.back().engines.resize(1);
1073+
engineGroups.back().engines[0].commandStreamReceiver = copyCsr.get();
1074+
EngineControl copyEngine{copyCsr.get(), copyOsContext};
1075+
allEngines.push_back(copyEngine);
1076+
1077+
engineGroups.push_back(NEO::Device::EngineGroupT{});
1078+
engineGroups.back().engineGroupType = EngineGroupType::Compute;
1079+
engineGroups.back().engines.resize(1);
1080+
engineGroups.back().engines[0].commandStreamReceiver = computeCsr.get();
1081+
EngineControl computeEngine{computeCsr.get(), computeOsContext};
1082+
allEngines.push_back(computeEngine);
1083+
1084+
uint32_t count = 0u;
1085+
ze_result_t res = device->getCommandQueueGroupProperties(&count, nullptr);
1086+
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
1087+
EXPECT_GT(count, 0u);
1088+
1089+
std::vector<ze_command_queue_group_properties_t> properties(count);
1090+
res = device->getCommandQueueGroupProperties(&count, properties.data());
1091+
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
1092+
1093+
uint32_t ordinal = 0u;
1094+
for (ordinal = 0u; ordinal < count; ordinal++) {
1095+
if ((properties[ordinal].flags & ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_COPY) &&
1096+
!(properties[ordinal].flags & ZE_COMMAND_QUEUE_GROUP_PROPERTY_FLAG_COMPUTE)) {
1097+
if (properties[ordinal].numQueues == 0)
1098+
continue;
1099+
break;
1100+
}
1101+
}
1102+
EXPECT_LT(ordinal, count);
1103+
1104+
ze_command_queue_desc_t desc{};
1105+
desc.ordinal = ordinal;
1106+
desc.index = 0u;
1107+
desc.priority = ZE_COMMAND_QUEUE_PRIORITY_PRIORITY_LOW;
1108+
1109+
ze_command_queue_handle_t commandQueueHandle = {};
1110+
1111+
res = device->createCommandQueue(&desc, &commandQueueHandle);
1112+
EXPECT_EQ(ZE_RESULT_SUCCESS, res);
1113+
auto commandQueue = static_cast<CommandQueueImp *>(L0::CommandQueue::fromHandle(commandQueueHandle));
1114+
EXPECT_NE(commandQueue, nullptr);
1115+
EXPECT_EQ(copyCsr.get(), commandQueue->getCsr());
1116+
commandQueue->destroy();
1117+
1118+
engineGroups.clear();
1119+
allEngines.clear();
1120+
}
1121+
10531122
struct DeferredContextCreationDeviceCreateCommandQueueTest : DeviceCreateCommandQueueTest {
10541123
void SetUp() override {
10551124
DebugManager.flags.DeferOsContextInitialization.set(1);

0 commit comments

Comments
 (0)