From b8faf7f0925d2148c80c3e89eb0091c85e57711c Mon Sep 17 00:00:00 2001 From: Zbigniew Zdanowicz Date: Mon, 14 Jul 2025 12:01:46 +0000 Subject: [PATCH] test: add missing mutable command list tests - expand existing for missing subcases Related-To: NEO-10492 Signed-off-by: Zbigniew Zdanowicz --- .../tests/mutable_cmdlist_kernels_tests.cpp | 7 +- .../tests/mutable_cmdlist_tests.cpp | 62 +++++++ .../tests/mutable_kernel_group_tests.cpp | 39 +++++ .../mutable_cmdlist/tests/variable_tests.cpp | 156 +++++++++++++++++- 4 files changed, 260 insertions(+), 4 deletions(-) diff --git a/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/mutable_cmdlist_kernels_tests.cpp b/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/mutable_cmdlist_kernels_tests.cpp index 8778f21092..daddbfe19b 100644 --- a/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/mutable_cmdlist_kernels_tests.cpp +++ b/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/mutable_cmdlist_kernels_tests.cpp @@ -641,7 +641,10 @@ HWTEST2_F(MutableCommandListKernelTest, givenPrefetchDisabledWhenAppendingKernelThenKernelGroupHasNoPrefetchCaptured, IsAtLeastXeHpcCore) { debugManager.flags.EnableMemoryPrefetch.set(0); - mutableCommandIdDesc.flags = ZE_MUTABLE_COMMAND_EXP_FLAG_KERNEL_INSTRUCTION | ZE_MUTABLE_COMMAND_EXP_FLAG_GROUP_COUNT; + mutableCommandIdDesc.flags = ZE_MUTABLE_COMMAND_EXP_FLAG_KERNEL_INSTRUCTION | ZE_MUTABLE_COMMAND_EXP_FLAG_GROUP_COUNT | ZE_MUTABLE_COMMAND_EXP_FLAG_WAIT_EVENTS; + + auto event = createTestEvent(false, false, false, false); + auto eventHandle = event->toHandle(); ze_kernel_handle_t kernels[2] = {kernel->toHandle(), kernel2->toHandle()}; @@ -651,7 +654,7 @@ HWTEST2_F(MutableCommandListKernelTest, auto &mutation = mutableCommandList->mutations[commandId - 1]; ASSERT_NE(nullptr, mutation.kernelGroup); - EXPECT_EQ(ZE_RESULT_SUCCESS, mutableCommandList->appendLaunchKernel(kernel->toHandle(), this->testGroupCount, nullptr, 0, nullptr, this->testLaunchParams)); + EXPECT_EQ(ZE_RESULT_SUCCESS, mutableCommandList->appendLaunchKernel(kernel->toHandle(), this->testGroupCount, nullptr, 1, &eventHandle, this->testLaunchParams)); mutableCommandList->close(); EXPECT_EQ(nullptr, mutation.kernelGroup->getIohForPrefetch()); diff --git a/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/mutable_cmdlist_tests.cpp b/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/mutable_cmdlist_tests.cpp index c741887e26..d35d7ab773 100644 --- a/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/mutable_cmdlist_tests.cpp +++ b/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/mutable_cmdlist_tests.cpp @@ -2576,6 +2576,68 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, } } +HWCMDTEST_F(IGFX_XE_HP_CORE, + MutableCommandListInOrderTest, + givenKernelWithWaitCbTimestampEventBelongingToDifferentCmdListWhenMutateIntoDifferentEventThenDataIsUpdated) { + using MI_SEMAPHORE_WAIT = typename FamilyType::MI_SEMAPHORE_WAIT; + + auto event = createTestEvent(true, false, true, false); + auto eventHandle = event->toHandle(); + auto newEvent = createTestEvent(true, false, true, false); + auto newEventHandle = newEvent->toHandle(); + + auto externalCmdList = createMutableCmdList(); + // attach event 1 to the external command list + auto result = externalCmdList->appendLaunchKernel(kernel2->toHandle(), this->testGroupCount, eventHandle, 0, nullptr, this->testLaunchParams); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + // attach event 2 to the external command list + result = externalCmdList->appendLaunchKernel(kernel2->toHandle(), this->testGroupCount, newEventHandle, 0, nullptr, this->testLaunchParams); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + result = externalCmdList->close(); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + // mutation point + mutableCommandIdDesc.flags = ZE_MUTABLE_COMMAND_EXP_FLAG_WAIT_EVENTS; + result = mutableCommandList->getNextCommandId(&mutableCommandIdDesc, 0, nullptr, &commandId); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + // use event 1 as wait event + result = mutableCommandList->appendLaunchKernel(kernel->toHandle(), this->testGroupCount, nullptr, 1, &eventHandle, this->testLaunchParams); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + result = mutableCommandList->close(); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + auto waitEvents = getVariableList(commandId, L0::MCL::VariableType::waitEvent, nullptr); + ASSERT_EQ(1u, waitEvents.size()); + auto waitEventVar = waitEvents[0]; + ASSERT_EQ(1u, waitEventVar->getSemWaitList().size()); + + auto mutableSemWait = waitEventVar->getSemWaitList()[0]; + auto mockMutableSemWait = static_cast *>(mutableSemWait); + auto semWaitCmd = reinterpret_cast(mockMutableSemWait->semWait); + uint64_t waitAddress = 0; + if (mutableCommandList->getBase()->isHeaplessModeEnabled()) { + waitAddress = event->getInOrderExecInfo()->getBaseDeviceAddress() + event->getInOrderAllocationOffset(); + } else { + waitAddress = event->getCompletionFieldGpuAddress(this->device); + } + EXPECT_EQ(waitAddress, semWaitCmd->getSemaphoreGraphicsAddress()); + + result = mutableCommandList->updateMutableCommandWaitEventsExp(commandId, 1, &newEventHandle); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + result = mutableCommandList->close(); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + if (mutableCommandList->getBase()->isHeaplessModeEnabled()) { + waitAddress = newEvent->getInOrderExecInfo()->getBaseDeviceAddress() + newEvent->getInOrderAllocationOffset(); + } else { + waitAddress = newEvent->getCompletionFieldGpuAddress(this->device); + } + EXPECT_EQ(waitAddress, semWaitCmd->getSemaphoreGraphicsAddress()); +} + HWCMDTEST_F(IGFX_XE_HP_CORE, MutableCommandListInOrderTest, givenKernelWithWaitCbEventBelongingToDifferentCmdListWhenNoopedAndMutatedBackThenDataIsUpdatedAndCommandNoopedAndRestored) { diff --git a/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/mutable_kernel_group_tests.cpp b/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/mutable_kernel_group_tests.cpp index a9141f0807..1c6450a648 100644 --- a/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/mutable_kernel_group_tests.cpp +++ b/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/mutable_kernel_group_tests.cpp @@ -127,6 +127,45 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, EXPECT_EQ(expectedCrossThreadSize, actualCrossThreadDataSize); } +HWCMDTEST_F(IGFX_XE_HP_CORE, + MutableKernelGroupTest, + givenMutableKernelHasPassInlineDataWhenCreateHostViewIndirectWithoutCopyingInlineThenInitializeAndNoCopyInline) { + using WalkerType = typename FamilyType::PorWalkerType; + + mutableCommandIdDesc.flags = kernelIsaMutationFlags; + auto result = mutableCommandList->getNextCommandId(&mutableCommandIdDesc, 2, kernelMutationGroup, &commandId); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + auto kernel2Data = mutableCommandList->kernelData[1].get(); + auto kdPtr = std::make_unique(); + auto kernelDispatch = kdPtr.get(); + + mockKernelImmData2->kernelDescriptor->kernelAttributes.flags.passInlineData = true; + auto crossThreadDataSize = kernel2->getCrossThreadDataSize(); + + createMutableComputeWalker(); + createMutableKernelGroup(); + mutableKernels[1]->setComputeWalker(mutableComputeWalker.get()); + mutableKernels[1]->setKernelDispatch(kernelDispatch); + auto expectedCrossThreadSize = crossThreadDataSize - mutableKernels[1]->inlineDataSize; + kernelDispatch->kernelData = kernel2Data; + kernelDispatch->offsets.perThreadOffset = expectedCrossThreadSize; + kernel2->perThreadDataSizeForWholeThreadGroup = 0x40; + kernel2->perThreadDataForWholeThreadGroup = static_cast(alignedMalloc(kernel2->perThreadDataSizeForWholeThreadGroup, 32)); + + auto srcPtr = kernel2->crossThreadData.get(); + memset(srcPtr, 0xFF, mutableKernels[1]->inlineDataSize); + + auto dstPtr = mutableKernels[1]->getMutableComputeWalker()->getHostMemoryInlineDataPointer(); + memset(dstPtr, 0x00, mutableKernels[1]->inlineDataSize); + + mutableKernels[1]->createHostViewIndirectData(false); + auto actualCrossThreadDataSize = mutableKernels[1]->getHostViewIndirectData()->getCrossThreadDataSize(); + EXPECT_EQ(expectedCrossThreadSize, actualCrossThreadDataSize); + + EXPECT_NE(0, memcmp(srcPtr, dstPtr, mutableKernels[1]->inlineDataSize)); +} + HWCMDTEST_F(IGFX_XE_HP_CORE, MutableKernelGroupTest, givenMutableKernelGroupWhenSettingScratchPatchIndexThenIndexIsSet) { diff --git a/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/variable_tests.cpp b/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/variable_tests.cpp index 90ddf88331..01d3b0d52e 100644 --- a/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/variable_tests.cpp +++ b/level_zero/core/test/unit_tests/sources/mutable_cmdlist/tests/variable_tests.cpp @@ -35,6 +35,46 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, EXPECT_EQ(groupCountValues[2], this->variable->kernelDispatch.groupCount[2]); EXPECT_TRUE(this->variable->desc.commitRequired); + + auto groupCountVar = this->variable.get(); + auto variableHandle = this->variable->toHandle(); + EXPECT_EQ(groupCountVar, variableHandle); + + ret = this->variable->setValue(kernelDispatchVariableSize + 1, 0, argValue); + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, ret); +} + +HWCMDTEST_F(IGFX_XE_HP_CORE, + VariableTest, + givenBufferVariableWhenSettingBufferUsagesThenOffsetsAreSet) { + createVariable(L0::MCL::VariableType::buffer, true, -1, -1); + + L0::MCL::BufferUsages bufferUsages; + bufferUsages.statelessWithoutOffset.push_back(0x40); + + this->variable->setBufferUsages(std::move(bufferUsages)); + const auto &bufferUsage = this->variable->getBufferUsages(); + ASSERT_EQ(1u, bufferUsage.statelessWithoutOffset.size()); + EXPECT_EQ(0x40u, bufferUsage.statelessWithoutOffset[0]); + + const auto &desc = this->variable->getDesc(); + EXPECT_EQ(L0::MCL::VariableType::buffer, desc.type); + + EXPECT_EQ(nullptr, this->variable->getInitialVariableDispatch()); +} + +HWCMDTEST_F(IGFX_XE_HP_CORE, + VariableTest, + givenValueVariableWhenSettingValueUsagesThenOffsetsAreSet) { + createVariable(L0::MCL::VariableType::value, true, -1, -1); + + L0::MCL::ValueUsages valueUsages; + valueUsages.commandBufferWithoutOffset.push_back(0x40); + + this->variable->setValueUsages(std::move(valueUsages)); + const auto &valueUsage = this->variable->getValueUsages(); + ASSERT_EQ(1u, valueUsage.commandBufferWithoutOffset.size()); + EXPECT_EQ(0x40u, valueUsage.commandBufferWithoutOffset[0]); } HWCMDTEST_F(IGFX_XE_HP_CORE, @@ -50,6 +90,8 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, Variable *groupCount = getVariable(L0::MCL::VariableType::groupCount); EXPECT_EQ(groupCount, this->variableDispatch->getGroupCountVar()); + EXPECT_NE(nullptr, groupCount->getInitialVariableDispatch()); + auto ret = groupCount->setValue(kernelDispatchVariableSize, 0, argValue); EXPECT_EQ(ZE_RESULT_SUCCESS, ret); @@ -182,8 +224,8 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, Variable *groupSize = getVariable(L0::MCL::VariableType::groupSize); EXPECT_EQ(groupSize, this->variableDispatch->getGroupSizeVar()); + groupSize->setAsKernelGroupSize(this->kernelHandle); auto &mclKernelExt = L0::MCL::MclKernelExt::get(this->kernel.get()); - mclKernelExt.setGroupSizeVariable(groupSize); EXPECT_EQ(groupSize, mclKernelExt.getGroupSizeVariable()); auto ret = groupSize->setValue(kernelDispatchVariableSize, 0, argValue); @@ -302,6 +344,35 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, EXPECT_EQ(groupSizeValues[2], enqLocalWorkSizePatch[2]); } +HWCMDTEST_F(IGFX_XE_HP_CORE, + VariableTest, + givenGroupSizeVariableNonCommitDispatchWithCalculateRegionWhenSettingGroupSizeThenGroupSizeIsPatchedImmediatelyAndMaxWgCalculated) { + using WalkerType = typename FamilyType::PorWalkerType; + + debugManager.flags.OverrideMaxWorkGroupCount.set(64); + + createMutableComputeWalker(0); + + this->calculateRegion = true; + this->stageCommitMode = false; + this->slmInlineSize = 1024; + createVariableDispatch(false, true, false, false); + uint32_t groupSizeValues[3] = {4, 2, 1}; + const void *argValue = &groupSizeValues; + + Variable *groupSize = getVariable(L0::MCL::VariableType::groupSize); + + auto ret = groupSize->setValue(kernelDispatchVariableSize, 0, argValue); + EXPECT_EQ(ZE_RESULT_SUCCESS, ret); + + uint32_t *localWorkSizePatch = reinterpret_cast(ptrOffset(this->crossThreadData.get(), this->offsets.localWorkSize)); + EXPECT_EQ(groupSizeValues[0], localWorkSizePatch[0]); + EXPECT_EQ(groupSizeValues[1], localWorkSizePatch[1]); + EXPECT_EQ(groupSizeValues[2], localWorkSizePatch[2]); + + EXPECT_EQ(64u, this->variableDispatch->maxWgCountPerTile); +} + HWCMDTEST_F(IGFX_XE_HP_CORE, VariableTest, givenKernelChannelsZeroAndGroupSizeVariableDispatchWhenSettingGroupSizeThenGenerateLocalIdsDisabledAndKernelStartOffsetAdded) { @@ -462,6 +533,7 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, this->kernelDispatch->kernelData->numLocalIdChannels = 3; this->kernelDispatch->kernelData->kernelStartAddress = 0x4000; this->kernelDispatch->kernelData->skipPerThreadDataLoad = 0x100; + this->kernelDispatch->kernelData->requiresWorkgroupWalkOrder = true; uint64_t kernelStartAddress = this->kernelDispatch->kernelData->kernelStartAddress; uint32_t groupSizeValues[3] = {4, 2, 1}; @@ -779,6 +851,32 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, EXPECT_EQ(slmSize, this->kernelDispatch->slmTotalSize); } +HWCMDTEST_F(IGFX_XE_HP_CORE, + VariableTest, + givenSingleSlmVariableInNonCommitModeWithCalculateRegionWhenMutatingSlmArgumentThenSlmSizeChangedImmediatelyAndMaxWgCalculated) { + using WalkerType = typename FamilyType::PorWalkerType; + + debugManager.flags.OverrideMaxWorkGroupCount.set(64); + + createMutableComputeWalker(0); + + uint32_t slmSize = 1 * MemoryConstants::kiloByte; + + this->calculateRegion = true; + this->stageCommitMode = false; + createVariableDispatch(false, false, false, true); + Variable *slmArgument = getVariable(L0::MCL::VariableType::slmBuffer); + EXPECT_EQ(nullptr, slmArgument->slmValue.nextSlmVariable); + EXPECT_EQ(0u, slmArgument->slmValue.slmOffsetValue); + + auto ret = slmArgument->setValue(slmSize, 0, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, ret); + EXPECT_FALSE(slmArgument->desc.commitRequired); + EXPECT_EQ(slmSize, slmArgument->slmValue.slmSize); + EXPECT_EQ(slmSize, this->kernelDispatch->slmTotalSize); + EXPECT_EQ(64u, this->variableDispatch->maxWgCountPerTile); +} + HWCMDTEST_F(IGFX_XE_HP_CORE, VariableTest, givenSingleSlmVariableWhenMutatingMisalignedSlmValueThenSlmSizeChangedWithAlignedValues) { @@ -876,6 +974,19 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, slmLastArgument->commitVariable(); EXPECT_EQ(slmFirstSize + slmSecondSize, this->kernelDispatch->slmTotalSize); + + auto slmNextValue = slmFirstSize + 1; + ret = slmFirstArgument->setValue(slmNextValue, 0, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, ret); + EXPECT_EQ(slmNextValue, slmFirstArgument->slmValue.slmSize); + auto slmLastOffset = alignUp(slmNextValue, defaultSlmArgumentAlignment); + EXPECT_EQ(slmLastOffset, slmLastArgument->slmValue.slmOffsetValue); + + slmNextValue += 1; + ret = slmFirstArgument->setValue(slmNextValue, 0, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, ret); + EXPECT_EQ(slmNextValue, slmFirstArgument->slmValue.slmSize); + EXPECT_EQ(slmLastOffset, slmLastArgument->slmValue.slmOffsetValue); } HWCMDTEST_F(IGFX_XE_HP_CORE, @@ -1124,6 +1235,9 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, for (uint32_t i = 0; i < this->defaultValueStatelessSize; i++) { EXPECT_EQ(*(valuesPatch + i), immediateValue[i]); } + + ret = this->variable->setValue(0, 0, argValue); + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, ret); } HWCMDTEST_F(IGFX_XE_HP_CORE, @@ -1313,6 +1427,10 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, auto semWaitCmd = reinterpret_cast(this->semaphoreWaitBuffer); auto testWaitAddress = semWaitCmd->getSemaphoreGraphicsAddress(); EXPECT_EQ(expectedWaitAddress, testWaitAddress); + + ret = this->variable->setValue(0, 0, newEvent); + EXPECT_EQ(ZE_RESULT_SUCCESS, ret); + EXPECT_EQ(this->variable->eventValue.event, newEvent); } HWCMDTEST_F(IGFX_XE_HP_CORE, @@ -1434,7 +1552,7 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, HWCMDTEST_F(IGFX_XE_HP_CORE, VariableTest, givenBufferVariableWhenSetAsWaitEventThenErrorIsReturned) { - auto event = this->createTestEvent(true, false, false, false); + auto event = this->createTestEvent(false, false, false, false); ASSERT_NE(nullptr, event); createVariable(L0::MCL::VariableType::buffer, true, -1, -1); @@ -1443,6 +1561,36 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, ret); } +HWCMDTEST_F(IGFX_XE_HP_CORE, + VariableTest, + givenBufferVariableWhenSetAsSignalEventThenErrorIsReturned) { + auto event = this->createTestEvent(false, false, false, false); + ASSERT_NE(nullptr, event); + + createVariable(L0::MCL::VariableType::buffer, true, -1, -1); + + auto ret = this->variable->setAsSignalEvent(event, nullptr, nullptr); + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, ret); +} + +HWCMDTEST_F(IGFX_XE_HP_CORE, + VariableTest, + givenBufferVariableWhenSetAsGroupSizeThenErrorIsReturned) { + createVariable(L0::MCL::VariableType::buffer, true, -1, -1); + + auto ret = this->variable->setAsKernelGroupSize(this->kernelHandle); + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, ret); +} + +HWCMDTEST_F(IGFX_XE_HP_CORE, + VariableTest, + givenBufferVariableInInitializedStateWhenQueriedTypeThenReturnFalse) { + createVariable(L0::MCL::VariableType::buffer, true, -1, -1); + + this->variable->getDesc().state = L0::MCL::VariableDescriptor::State::initialized; + EXPECT_FALSE(this->variable->isType(L0::MCL::VariableType::buffer)); +} + HWCMDTEST_F(IGFX_XE_HP_CORE, VariableInOrderTest, givenSignalEventRegularNoCounterBasedSignalScopeTimestampWhenMutatingVariableThenNewPostSyncAddressSet) { @@ -1469,6 +1617,10 @@ HWCMDTEST_F(IGFX_XE_HP_CORE, auto storeDataImmCmd = reinterpret_cast(this->storeDataImmBuffer); auto testPostSyncAddress = storeDataImmCmd->getAddress(); EXPECT_EQ(expectedPostSyncAddress, testPostSyncAddress); + + ret = this->variable->setValue(0, 0, newEvent); + EXPECT_EQ(ZE_RESULT_SUCCESS, ret); + EXPECT_EQ(this->variable->eventValue.event, newEvent); } HWCMDTEST_F(IGFX_XE_HP_CORE,