Skip to content

Commit caf1ab6

Browse files
Do not allow mixing cooperative and non-cooperative kernels in an execute
When executing command lists, ensure that all lists contain either cooperative or non-cooperative kernels. When appending kernels to a command list, do not allow mixing cooperative and non-cooperative kernels. Related-To: NEO-4940, NEO-5757 Signed-off-by: Filip Hazubski <filip.hazubski@intel.com>
1 parent 66ee5bd commit caf1ab6

File tree

9 files changed

+133
-7
lines changed

9 files changed

+133
-7
lines changed

level_zero/core/source/cmdlist/cmdlist.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ struct CommandList : _ze_command_list_handle_t {
207207
bool isInternal() const {
208208
return internalUsage;
209209
}
210+
bool containsCooperativeKernels() const {
211+
return containsCooperativeKernelsFlag;
212+
}
210213

211214
enum CommandListType : uint32_t {
212215
TYPE_REGULAR = 0u,
@@ -252,6 +255,7 @@ struct CommandList : _ze_command_list_handle_t {
252255
UnifiedMemoryControls unifiedMemoryControls;
253256
bool indirectAllocationsAllowed = false;
254257
bool internalUsage = false;
258+
bool containsCooperativeKernelsFlag = false;
255259
NEO::GraphicsAllocation *getAllocationFromHostPtrMap(const void *buffer, uint64_t bufferSize);
256260
NEO::GraphicsAllocation *getHostPtrAlloc(const void *buffer, uint64_t bufferSize);
257261
bool containsStatelessUncachedResource = false;

level_zero/core/source/cmdlist/cmdlist_hw.inl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ ze_result_t CommandListCoreFamily<gfxCoreFamily>::reset() {
9191
requiredStreamState = {};
9292
finalStreamState = requiredStreamState;
9393
containsAnyKernel = false;
94+
containsCooperativeKernelsFlag = false;
9495
clearCommandsToPatch();
9596
commandListSLMEnabled = false;
9697

level_zero/core/source/cmdlist/cmdlist_hw_base.inl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,12 @@ ze_result_t CommandListCoreFamily<gfxCoreFamily>::appendLaunchKernelWithParams(z
120120
this->indirectAllocationsAllowed = true;
121121
}
122122

123+
if (!containsAnyKernel) {
124+
containsCooperativeKernelsFlag = isCooperative;
125+
} else if (containsCooperativeKernelsFlag != isCooperative) {
126+
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
127+
}
128+
123129
if (kernel->usesSyncBuffer()) {
124130
auto retVal = (isCooperative
125131
? programSyncBuffer(*kernel, *device->getNEODevice(), pThreadGroupDimensions)

level_zero/core/source/cmdlist/cmdlist_hw_xehp_plus.inl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,12 @@ ze_result_t CommandListCoreFamily<gfxCoreFamily>::appendLaunchKernelWithParams(z
189189
kernelDescriptor.kernelMetadata.kernelName.c_str());
190190
}
191191

192+
if (!containsAnyKernel) {
193+
containsCooperativeKernelsFlag = isCooperative;
194+
} else if (containsCooperativeKernelsFlag != isCooperative) {
195+
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
196+
}
197+
192198
if (kernel->usesSyncBuffer()) {
193199
auto retVal = (isCooperative
194200
? programSyncBuffer(*kernel, *neoDevice, pThreadGroupDimensions)

level_zero/core/source/cmdqueue/cmdqueue_hw.inl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,17 @@ ze_result_t CommandQueueHw<gfxCoreFamily>::executeCommandLists(
7575

7676
auto lockCSR = csr->obtainUniqueOwnership();
7777

78+
auto commandListsContainCooperativeKernels = CommandList::fromHandle(phCommandLists[0])->containsCooperativeKernels();
79+
7880
for (auto i = 0u; i < numCommandLists; i++) {
7981
auto commandList = CommandList::fromHandle(phCommandLists[i]);
8082
if (peekIsCopyOnlyCommandQueue() != commandList->isCopyOnly()) {
8183
return ZE_RESULT_ERROR_INVALID_COMMAND_LIST_TYPE;
8284
}
85+
86+
if (commandListsContainCooperativeKernels != commandList->containsCooperativeKernels()) {
87+
return ZE_RESULT_ERROR_INVALID_COMMAND_LIST_TYPE;
88+
}
8389
}
8490

8591
size_t spaceForResidency = 0;

level_zero/core/test/unit_tests/mocks/mock_cmdlist.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ struct WhiteBox<::L0::CommandListCoreFamily<gfxCoreFamily>>
4040
using BaseClass::commandListPerThreadScratchSize;
4141
using BaseClass::commandListPreemptionMode;
4242
using BaseClass::commandsToPatch;
43+
using BaseClass::containsAnyKernel;
44+
using BaseClass::containsCooperativeKernelsFlag;
4345
using BaseClass::engineGroupType;
4446
using BaseClass::finalStreamState;
4547
using BaseClass::flags;

level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_5.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -827,5 +827,16 @@ HWTEST2_F(CommandListCreate, givenIndirectAccessFlagsAreChangedWhenResetingComma
827827
EXPECT_FALSE(commandList->unifiedMemoryControls.indirectDeviceAllocationsAllowed);
828828
}
829829

830+
HWTEST2_F(CommandListCreate, whenContainsCooperativeKernelsIsCalledThenCorrectValueIsReturned, TestPlatforms) {
831+
for (auto testValue : ::testing::Bool()) {
832+
MockCommandListForAppendLaunchKernel<gfxCoreFamily> commandList;
833+
commandList.initialize(device, NEO::EngineGroupType::Compute, 0u);
834+
commandList.containsCooperativeKernelsFlag = testValue;
835+
EXPECT_EQ(testValue, commandList.containsCooperativeKernels());
836+
commandList.reset();
837+
EXPECT_FALSE(commandList.containsCooperativeKernels());
838+
}
839+
}
840+
830841
} // namespace ult
831842
} // namespace L0

level_zero/core/test/unit_tests/sources/cmdlist/test_cmdlist_append_launch_kernel.cpp

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,23 +1256,26 @@ HWTEST2_F(CommandListAppendLaunchKernel, givenKernelUsingSyncBufferWhenAppendLau
12561256

12571257
kernel.setGroupSize(4, 1, 1);
12581258
ze_group_count_t groupCount{8, 1, 1};
1259-
auto pCommandList = std::make_unique<WhiteBox<::L0::CommandListCoreFamily<gfxCoreFamily>>>();
1260-
auto result = pCommandList->initialize(device, NEO::EngineGroupType::Compute, 0u);
1261-
ASSERT_EQ(ZE_RESULT_SUCCESS, result);
12621259

12631260
auto &kernelAttributes = kernel.immutableData.kernelDescriptor->kernelAttributes;
12641261
kernelAttributes.flags.usesSyncBuffer = true;
12651262
kernelAttributes.numGrfRequired = GrfConfig::DefaultGrfNumber;
12661263
bool isCooperative = true;
1267-
result = pCommandList->appendLaunchCooperativeKernel(kernel.toHandle(), &groupCount, nullptr, 0, nullptr);
1264+
auto pCommandList = std::make_unique<WhiteBox<::L0::CommandListCoreFamily<gfxCoreFamily>>>();
1265+
pCommandList->initialize(device, NEO::EngineGroupType::Compute, 0u);
1266+
auto result = pCommandList->appendLaunchCooperativeKernel(kernel.toHandle(), &groupCount, nullptr, 0, nullptr);
12681267
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
12691268

1269+
pCommandList = std::make_unique<WhiteBox<::L0::CommandListCoreFamily<gfxCoreFamily>>>();
1270+
pCommandList->initialize(device, NEO::EngineGroupType::Compute, 0u);
12701271
result = pCommandList->appendLaunchKernelWithParams(kernel.toHandle(), &groupCount, nullptr, false, false, isCooperative);
12711272
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
12721273

12731274
{
12741275
VariableBackup<uint32_t> usesSyncBuffer{&kernelAttributes.flags.packed};
12751276
usesSyncBuffer = false;
1277+
pCommandList = std::make_unique<WhiteBox<::L0::CommandListCoreFamily<gfxCoreFamily>>>();
1278+
pCommandList->initialize(device, NEO::EngineGroupType::Compute, 0u);
12761279
result = pCommandList->appendLaunchKernelWithParams(kernel.toHandle(), &groupCount, nullptr, false, false, isCooperative);
12771280
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
12781281
}
@@ -1281,6 +1284,8 @@ HWTEST2_F(CommandListAppendLaunchKernel, givenKernelUsingSyncBufferWhenAppendLau
12811284
uint32_t maximalNumberOfWorkgroupsAllowed;
12821285
kernel.suggestMaxCooperativeGroupCount(&maximalNumberOfWorkgroupsAllowed);
12831286
groupCountX = maximalNumberOfWorkgroupsAllowed + 1;
1287+
pCommandList = std::make_unique<WhiteBox<::L0::CommandListCoreFamily<gfxCoreFamily>>>();
1288+
pCommandList->initialize(device, NEO::EngineGroupType::Compute, 0u);
12841289
result = pCommandList->appendLaunchKernelWithParams(kernel.toHandle(), &groupCount, nullptr, false, false, isCooperative);
12851290
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
12861291
}
@@ -1292,9 +1297,7 @@ HWTEST2_F(CommandListAppendLaunchKernel, givenKernelUsingSyncBufferWhenAppendLau
12921297
}
12931298
}
12941299

1295-
using Platforms = IsAtLeastProduct<IGFX_SKYLAKE>;
1296-
1297-
HWTEST2_F(CommandListAppendLaunchKernel, whenUpdateStreamPropertiesIsCalledThenRequiredStateAndFinalStateAreCorrectlySet, Platforms) {
1300+
HWTEST2_F(CommandListAppendLaunchKernel, whenUpdateStreamPropertiesIsCalledThenRequiredStateAndFinalStateAreCorrectlySet, SklPlusMatcher) {
12981301
Mock<::L0::Kernel> kernel;
12991302
auto pMockModule = std::unique_ptr<Module>(new Mock<Module>(device, nullptr));
13001303
kernel.module = pMockModule.get();
@@ -1318,5 +1321,54 @@ HWTEST2_F(CommandListAppendLaunchKernel, whenUpdateStreamPropertiesIsCalledThenR
13181321
EXPECT_EQ(expectedDisableOverdispatch, pCommandList->finalStreamState.frontEndState.disableOverdispatch.value);
13191322
}
13201323

1324+
HWTEST2_F(CommandListAppendLaunchKernel, givenCooperativeKernelWhenAppendLaunchCooperativeKernelIsCalledThenCommandListTypeIsProperlySet, SklPlusMatcher) {
1325+
createKernel();
1326+
kernel->setGroupSize(4, 1, 1);
1327+
ze_group_count_t groupCount{8, 1, 1};
1328+
1329+
auto pCommandList = std::make_unique<WhiteBox<::L0::CommandListCoreFamily<gfxCoreFamily>>>();
1330+
pCommandList->initialize(device, NEO::EngineGroupType::Compute, 0u);
1331+
bool isCooperative = false;
1332+
auto result = pCommandList->appendLaunchKernelWithParams(kernel->toHandle(), &groupCount, nullptr, false, false, isCooperative);
1333+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
1334+
EXPECT_TRUE(pCommandList->containsAnyKernel);
1335+
EXPECT_FALSE(pCommandList->containsCooperativeKernelsFlag);
1336+
1337+
pCommandList = std::make_unique<WhiteBox<::L0::CommandListCoreFamily<gfxCoreFamily>>>();
1338+
pCommandList->initialize(device, NEO::EngineGroupType::Compute, 0u);
1339+
isCooperative = true;
1340+
result = pCommandList->appendLaunchKernelWithParams(kernel->toHandle(), &groupCount, nullptr, false, false, isCooperative);
1341+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
1342+
EXPECT_TRUE(pCommandList->containsAnyKernel);
1343+
EXPECT_TRUE(pCommandList->containsCooperativeKernelsFlag);
1344+
}
1345+
1346+
HWTEST2_F(CommandListAppendLaunchKernel, givenCooperativeAndNonCooperativeKernelsWhenAppendLaunchCooperativeKernelIsCalledThenReturnError, SklPlusMatcher) {
1347+
Mock<::L0::Kernel> kernel;
1348+
auto pMockModule = std::unique_ptr<Module>(new Mock<Module>(device, nullptr));
1349+
kernel.module = pMockModule.get();
1350+
1351+
kernel.setGroupSize(4, 1, 1);
1352+
ze_group_count_t groupCount{8, 1, 1};
1353+
1354+
auto pCommandList = std::make_unique<WhiteBox<::L0::CommandListCoreFamily<gfxCoreFamily>>>();
1355+
pCommandList->initialize(device, NEO::EngineGroupType::Compute, 0u);
1356+
bool isCooperative = false;
1357+
auto result = pCommandList->appendLaunchKernelWithParams(kernel.toHandle(), &groupCount, nullptr, false, false, isCooperative);
1358+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
1359+
isCooperative = true;
1360+
result = pCommandList->appendLaunchKernelWithParams(kernel.toHandle(), &groupCount, nullptr, false, false, isCooperative);
1361+
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
1362+
1363+
pCommandList = std::make_unique<WhiteBox<::L0::CommandListCoreFamily<gfxCoreFamily>>>();
1364+
pCommandList->initialize(device, NEO::EngineGroupType::Compute, 0u);
1365+
isCooperative = true;
1366+
result = pCommandList->appendLaunchKernelWithParams(kernel.toHandle(), &groupCount, nullptr, false, false, isCooperative);
1367+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
1368+
isCooperative = false;
1369+
result = pCommandList->appendLaunchKernelWithParams(kernel.toHandle(), &groupCount, nullptr, false, false, isCooperative);
1370+
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
1371+
}
1372+
13211373
} // namespace ult
13221374
} // namespace L0

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include "level_zero/core/test/unit_tests/fixtures/device_fixture.h"
1616
#include "level_zero/core/test/unit_tests/mocks/mock_cmdlist.h"
1717
#include "level_zero/core/test/unit_tests/mocks/mock_cmdqueue.h"
18+
#include "level_zero/core/test/unit_tests/mocks/mock_kernel.h"
19+
#include "level_zero/core/test/unit_tests/mocks/mock_module.h"
1820

1921
namespace L0 {
2022
namespace ult {
@@ -393,6 +395,42 @@ HWTEST2_F(CommandQueueExecuteCommandLists, givenMidThreadPreemptionWhenCommandsA
393395
}
394396
}
395397

398+
HWTEST2_F(CommandQueueExecuteCommandLists, givenCommandListsWithCooperativeAndNonCooperativeKernelsWhenExecuteCommandListsIsCalledThenErrorIsReturned, IsSklOrAbove) {
399+
ze_command_queue_desc_t desc = {};
400+
NEO::CommandStreamReceiver *csr;
401+
device->getCsrForOrdinalAndIndex(&csr, 0u, 0u);
402+
403+
auto pCommandQueue = new MockCommandQueueHw<gfxCoreFamily>{device, csr, &desc};
404+
pCommandQueue->initialize(false, false);
405+
406+
Mock<::L0::Kernel> kernel;
407+
auto pMockModule = std::unique_ptr<Module>(new Mock<Module>(device, nullptr));
408+
kernel.module = pMockModule.get();
409+
410+
ze_group_count_t threadGroupDimensions{1, 1, 1};
411+
auto pCommandListWithCooperativeKernels = std::make_unique<WhiteBox<::L0::CommandListCoreFamily<gfxCoreFamily>>>();
412+
pCommandListWithCooperativeKernels->initialize(device, NEO::EngineGroupType::Compute, 0u);
413+
pCommandListWithCooperativeKernels->appendLaunchKernelWithParams(&kernel, &threadGroupDimensions, nullptr, false, false, true);
414+
415+
auto pCommandListWithNonCooperativeKernels = std::make_unique<WhiteBox<::L0::CommandListCoreFamily<gfxCoreFamily>>>();
416+
pCommandListWithNonCooperativeKernels->initialize(device, NEO::EngineGroupType::Compute, 0u);
417+
pCommandListWithNonCooperativeKernels->appendLaunchKernelWithParams(&kernel, &threadGroupDimensions, nullptr, false, false, false);
418+
419+
{
420+
ze_command_list_handle_t commandLists[] = {pCommandListWithCooperativeKernels->toHandle(),
421+
pCommandListWithNonCooperativeKernels->toHandle()};
422+
auto result = pCommandQueue->executeCommandLists(2, commandLists, nullptr, false);
423+
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_COMMAND_LIST_TYPE, result);
424+
}
425+
{
426+
ze_command_list_handle_t commandLists[] = {pCommandListWithNonCooperativeKernels->toHandle(),
427+
pCommandListWithCooperativeKernels->toHandle()};
428+
auto result = pCommandQueue->executeCommandLists(2, commandLists, nullptr, false);
429+
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_COMMAND_LIST_TYPE, result);
430+
}
431+
pCommandQueue->destroy();
432+
}
433+
396434
template <typename FamilyType>
397435
void CommandQueueExecuteCommandLists::twoCommandListCommandPreemptionTest(bool preemptionCmdProgramming) {
398436
ze_command_queue_desc_t desc = {};

0 commit comments

Comments
 (0)