fix: wa for multi ccs execution on bmg

Related-To: NEO-15771
Signed-off-by: Maciej Plewka <maciej.plewka@intel.com>
This commit is contained in:
Maciej Plewka
2025-09-24 12:44:57 +00:00
committed by Compute-Runtime-Automation
parent 4133827e6f
commit cf35f8b40e
26 changed files with 122 additions and 5 deletions

View File

@@ -27,7 +27,7 @@ XE2_HPG_CORETEST_F(PreambleCfeState, givenXe2HpgCoreAndConcurrentKernelExecution
EXPECT_FALSE(cfeState->getSingleSliceDispatchCcsMode()); EXPECT_FALSE(cfeState->getSingleSliceDispatchCcsMode());
} }
XE2_HPG_CORETEST_F(PreambleCfeState, givenXe2HpgCoreAndDefaultKernelExecutionTypeWhenCallingProgramVFEStateThenSingleSpliceDispatchCcsModeIsDisabled) { XE2_HPG_CORETEST_F(PreambleCfeState, givenXe2HpgCoreAndDefaultKernelExecutionTypeWhenCallingProgramVFEStateThenSingleSliceDispatchCcsModeIsDisabled) {
using CFE_STATE = typename FamilyType::CFE_STATE; using CFE_STATE = typename FamilyType::CFE_STATE;
auto pVfeCmd = PreambleHelper<FamilyType>::getSpaceForVfeState(&linearStream, *defaultHwInfo, EngineGroupType::renderCompute, nullptr); auto pVfeCmd = PreambleHelper<FamilyType>::getSpaceForVfeState(&linearStream, *defaultHwInfo, EngineGroupType::renderCompute, nullptr);
@@ -42,3 +42,21 @@ XE2_HPG_CORETEST_F(PreambleCfeState, givenXe2HpgCoreAndDefaultKernelExecutionTyp
EXPECT_FALSE(cfeState->getComputeOverdispatchDisable()); EXPECT_FALSE(cfeState->getComputeOverdispatchDisable());
EXPECT_FALSE(cfeState->getSingleSliceDispatchCcsMode()); EXPECT_FALSE(cfeState->getSingleSliceDispatchCcsMode());
} }
BMGTEST_F(PreambleCfeState, givenXe2HpgCoreWithMultiCCSAndDefaultKernelExecutionTypeWhenCallingProgramVFEStateThenSingleSliceDispatchCcsModeIsEnabled) {
using CFE_STATE = typename FamilyType::CFE_STATE;
auto mutableHwInfo = pDevice->getRootDeviceEnvironment().getMutableHardwareInfo();
mutableHwInfo->gtSystemInfo.CCSInfo.NumberOfCCSEnabled = 2;
auto pVfeCmd = PreambleHelper<FamilyType>::getSpaceForVfeState(&linearStream, *defaultHwInfo, EngineGroupType::renderCompute, nullptr);
StreamProperties streamProperties{};
streamProperties.initSupport(pDevice->getRootDeviceEnvironment());
streamProperties.frontEndState.setPropertiesAll(false, false, false);
PreambleHelper<FamilyType>::programVfeState(pVfeCmd, pDevice->getRootDeviceEnvironment(), 0u, 0, 0, streamProperties);
parseCommands<FamilyType>(linearStream);
auto cfeStateIt = find<CFE_STATE *>(cmdList.begin(), cmdList.end());
ASSERT_NE(cmdList.end(), cfeStateIt);
auto cfeState = reinterpret_cast<CFE_STATE *>(*cfeStateIt);
EXPECT_FALSE(cfeState->getComputeOverdispatchDisable());
EXPECT_TRUE(cfeState->getSingleSliceDispatchCcsMode());
}

View File

@@ -247,7 +247,6 @@ BuiltIns *RootDeviceEnvironment::getBuiltIns() {
} }
void RootDeviceEnvironment::setNumberOfCcs(uint32_t numberOfCcs) { void RootDeviceEnvironment::setNumberOfCcs(uint32_t numberOfCcs) {
hwInfo->gtSystemInfo.CCSInfo.NumberOfCCSEnabled = std::min(hwInfo->gtSystemInfo.CCSInfo.NumberOfCCSEnabled, numberOfCcs); hwInfo->gtSystemInfo.CCSInfo.NumberOfCCSEnabled = std::min(hwInfo->gtSystemInfo.CCSInfo.NumberOfCCSEnabled, numberOfCcs);
limitedNumberOfCcs = true; limitedNumberOfCcs = true;
if (aubCenter) { if (aubCenter) {
@@ -255,6 +254,10 @@ void RootDeviceEnvironment::setNumberOfCcs(uint32_t numberOfCcs) {
} }
} }
uint32_t RootDeviceEnvironment::getNumberOfCcs() const {
return hwInfo->gtSystemInfo.CCSInfo.NumberOfCCSEnabled;
}
bool RootDeviceEnvironment::isNumberOfCcsLimited() const { bool RootDeviceEnvironment::isNumberOfCcsLimited() const {
return limitedNumberOfCcs; return limitedNumberOfCcs;
} }

View File

@@ -82,6 +82,7 @@ struct RootDeviceEnvironment : NonCopyableClass {
AssertHandler *getAssertHandler(Device *neoDevice); AssertHandler *getAssertHandler(Device *neoDevice);
void createBindlessHeapsHelper(Device *rootDevice, bool availableDevices); void createBindlessHeapsHelper(Device *rootDevice, bool availableDevices);
void setNumberOfCcs(uint32_t numberOfCcs); void setNumberOfCcs(uint32_t numberOfCcs);
uint32_t getNumberOfCcs() const;
bool isNumberOfCcsLimited() const; bool isNumberOfCcsLimited() const;
void setRcsExposure(); void setRcsExposure();
void initProductHelper(); void initProductHelper();

View File

@@ -13,6 +13,7 @@
#include "shared/source/helpers/pipe_control_args.h" #include "shared/source/helpers/pipe_control_args.h"
#include "shared/source/helpers/pipeline_select_helper.h" #include "shared/source/helpers/pipeline_select_helper.h"
#include "shared/source/helpers/preamble_base.inl" #include "shared/source/helpers/preamble_base.inl"
#include "shared/source/release_helper/release_helper.h"
namespace NEO { namespace NEO {
@@ -64,8 +65,9 @@ void PreambleHelper<GfxFamily>::programVfeState(void *pVfeState,
cmd.setMaximumNumberOfThreads(maxFrontEndThreads); cmd.setMaximumNumberOfThreads(maxFrontEndThreads);
cmd.setComputeOverdispatchDisable(streamProperties.frontEndState.disableOverdispatch.value == 1); cmd.setComputeOverdispatchDisable(streamProperties.frontEndState.disableOverdispatch.value == 1);
auto singleSliceDispatchCcsMode = streamProperties.frontEndState.singleSliceDispatchCcsMode.value == 1 || (rootDeviceEnvironment.getNumberOfCcs() > 1 && rootDeviceEnvironment.getReleaseHelper()->isSingleDispatchRequiredForMultiCCS());
PreambleHelper<GfxFamily>::setSingleSliceDispatchMode(&cmd, streamProperties.frontEndState.singleSliceDispatchCcsMode.value == 1); PreambleHelper<GfxFamily>::setSingleSliceDispatchMode(&cmd, singleSliceDispatchCcsMode);
appendProgramVFEState(rootDeviceEnvironment, streamProperties, &cmd); appendProgramVFEState(rootDeviceEnvironment, streamProperties, &cmd);

View File

@@ -70,6 +70,7 @@ class ReleaseHelper {
virtual uint32_t adjustMaxThreadsPerEuCount(uint32_t maxThreadsPerEuCount, uint32_t grfCount) const = 0; virtual uint32_t adjustMaxThreadsPerEuCount(uint32_t maxThreadsPerEuCount, uint32_t grfCount) const = 0;
virtual bool shouldQueryPeerAccess() const = 0; virtual bool shouldQueryPeerAccess() const = 0;
virtual bool isSpirSupported() const = 0; virtual bool isSpirSupported() const = 0;
virtual bool isSingleDispatchRequiredForMultiCCS() const = 0;
protected: protected:
ReleaseHelper(HardwareIpVersion hardwareIpVersion) : hardwareIpVersion(hardwareIpVersion) {} ReleaseHelper(HardwareIpVersion hardwareIpVersion) : hardwareIpVersion(hardwareIpVersion) {}
@@ -119,6 +120,7 @@ class ReleaseHelperHw : public ReleaseHelper {
uint32_t adjustMaxThreadsPerEuCount(uint32_t maxThreadsPerEuCount, uint32_t grfCount) const override; uint32_t adjustMaxThreadsPerEuCount(uint32_t maxThreadsPerEuCount, uint32_t grfCount) const override;
bool shouldQueryPeerAccess() const override; bool shouldQueryPeerAccess() const override;
bool isSpirSupported() const override; bool isSpirSupported() const override;
bool isSingleDispatchRequiredForMultiCCS() const override;
protected: protected:
ReleaseHelperHw(HardwareIpVersion hardwareIpVersion) : ReleaseHelper(hardwareIpVersion) {} ReleaseHelperHw(HardwareIpVersion hardwareIpVersion) : ReleaseHelper(hardwareIpVersion) {}

View File

@@ -54,6 +54,11 @@ bool ReleaseHelperHw<release>::shouldQueryPeerAccess() const {
return true; return true;
} }
template <>
bool ReleaseHelperHw<release>::isSingleDispatchRequiredForMultiCCS() const {
return true;
}
} // namespace NEO } // namespace NEO
#include "shared/source/release_helper/release_helper_common_xe2_hpg.inl" #include "shared/source/release_helper/release_helper_common_xe2_hpg.inl"

View File

@@ -54,6 +54,11 @@ bool ReleaseHelperHw<release>::shouldQueryPeerAccess() const {
return true; return true;
} }
template <>
bool ReleaseHelperHw<release>::isSingleDispatchRequiredForMultiCCS() const {
return true;
}
} // namespace NEO } // namespace NEO
#include "shared/source/release_helper/release_helper_common_xe2_hpg.inl" #include "shared/source/release_helper/release_helper_common_xe2_hpg.inl"

View File

@@ -196,4 +196,9 @@ bool ReleaseHelperHw<releaseType>::isSpirSupported() const {
return true; return true;
} }
template <ReleaseType releaseType>
bool ReleaseHelperHw<releaseType>::isSingleDispatchRequiredForMultiCCS() const {
return false;
}
} // namespace NEO } // namespace NEO

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2024 Intel Corporation * Copyright (C) 2024-2025 Intel Corporation
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
@@ -32,5 +32,4 @@ template <>
bool ReleaseHelperHw<release>::isGlobalBindlessAllocatorEnabled() const { bool ReleaseHelperHw<release>::isGlobalBindlessAllocatorEnabled() const {
return true; return true;
} }
} // namespace NEO } // namespace NEO

View File

@@ -48,6 +48,7 @@ class MockReleaseHelper : public ReleaseHelper {
ADDMETHOD_CONST_NOBASE_VOIDRETURN(adjustRTDispatchGlobals, (void *rtDispatchGlobals, uint32_t rtStacksPerDss, bool heaplessEnabled, uint32_t maxBvhLevels)); ADDMETHOD_CONST_NOBASE_VOIDRETURN(adjustRTDispatchGlobals, (void *rtDispatchGlobals, uint32_t rtStacksPerDss, bool heaplessEnabled, uint32_t maxBvhLevels));
ADDMETHOD_CONST_NOBASE(shouldQueryPeerAccess, bool, false, ()); ADDMETHOD_CONST_NOBASE(shouldQueryPeerAccess, bool, false, ());
ADDMETHOD_CONST_NOBASE(isSpirSupported, bool, true, ()); ADDMETHOD_CONST_NOBASE(isSpirSupported, bool, true, ());
ADDMETHOD_CONST_NOBASE(isSingleDispatchRequiredForMultiCCS, bool, false, ());
const SizeToPreferredSlmValueArray &getSizeToPreferredSlmValue(bool isHeapless) const override { const SizeToPreferredSlmValueArray &getSizeToPreferredSlmValue(bool isHeapless) const override {
static SizeToPreferredSlmValueArray sizeToPreferredSlmValue = {}; static SizeToPreferredSlmValueArray sizeToPreferredSlmValue = {};

View File

@@ -126,3 +126,7 @@ TEST_F(ReleaseHelper1255Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper1255Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) { TEST_F(ReleaseHelper1255Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) {
whenShouldQueryPeerAccessCalledThenFalseReturned(); whenShouldQueryPeerAccessCalledThenFalseReturned();
} }
TEST_F(ReleaseHelper1255Tests, whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned();
}

View File

@@ -126,3 +126,7 @@ TEST_F(ReleaseHelper1256Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper1256Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) { TEST_F(ReleaseHelper1256Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) {
whenShouldQueryPeerAccessCalledThenFalseReturned(); whenShouldQueryPeerAccessCalledThenFalseReturned();
} }
TEST_F(ReleaseHelper1256Tests, whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned();
}

View File

@@ -126,3 +126,7 @@ TEST_F(ReleaseHelper1257Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper1257Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) { TEST_F(ReleaseHelper1257Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) {
whenShouldQueryPeerAccessCalledThenFalseReturned(); whenShouldQueryPeerAccessCalledThenFalseReturned();
} }
TEST_F(ReleaseHelper1257Tests, whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned();
}

View File

@@ -110,3 +110,7 @@ TEST_F(ReleaseHelper1260Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper1260Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) { TEST_F(ReleaseHelper1260Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) {
whenShouldQueryPeerAccessCalledThenFalseReturned(); whenShouldQueryPeerAccessCalledThenFalseReturned();
} }
TEST_F(ReleaseHelper1260Tests, whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned();
}

View File

@@ -109,3 +109,7 @@ TEST_F(ReleaseHelper1261Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper1261Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) { TEST_F(ReleaseHelper1261Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) {
whenShouldQueryPeerAccessCalledThenFalseReturned(); whenShouldQueryPeerAccessCalledThenFalseReturned();
} }
TEST_F(ReleaseHelper1261Tests, whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned();
}

View File

@@ -120,3 +120,7 @@ TEST_F(ReleaseHelper1270Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper1270Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) { TEST_F(ReleaseHelper1270Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) {
whenShouldQueryPeerAccessCalledThenFalseReturned(); whenShouldQueryPeerAccessCalledThenFalseReturned();
} }
TEST_F(ReleaseHelper1270Tests, whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned();
}

View File

@@ -120,3 +120,7 @@ TEST_F(ReleaseHelper1271Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper1271Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) { TEST_F(ReleaseHelper1271Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) {
whenShouldQueryPeerAccessCalledThenFalseReturned(); whenShouldQueryPeerAccessCalledThenFalseReturned();
} }
TEST_F(ReleaseHelper1271Tests, whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned();
}

View File

@@ -126,3 +126,7 @@ TEST_F(ReleaseHelper1274Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper1274Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) { TEST_F(ReleaseHelper1274Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) {
whenShouldQueryPeerAccessCalledThenFalseReturned(); whenShouldQueryPeerAccessCalledThenFalseReturned();
} }
TEST_F(ReleaseHelper1274Tests, whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned();
}

View File

@@ -119,3 +119,7 @@ TEST_F(ReleaseHelper2001Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper2001Tests, whenShouldQueryPeerAccessCalledThenTrueReturned) { TEST_F(ReleaseHelper2001Tests, whenShouldQueryPeerAccessCalledThenTrueReturned) {
whenShouldQueryPeerAccessCalledThenTrueReturned(); whenShouldQueryPeerAccessCalledThenTrueReturned();
} }
TEST_F(ReleaseHelper2001Tests, whenIsSingleDispatchRequiredForMultiCCSThenTrueReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenTrueReturned();
}

View File

@@ -119,3 +119,7 @@ TEST_F(ReleaseHelper2002Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper2002Tests, whenShouldQueryPeerAccessCalledThenTrueReturned) { TEST_F(ReleaseHelper2002Tests, whenShouldQueryPeerAccessCalledThenTrueReturned) {
whenShouldQueryPeerAccessCalledThenTrueReturned(); whenShouldQueryPeerAccessCalledThenTrueReturned();
} }
TEST_F(ReleaseHelper2002Tests, whenIsSingleDispatchRequiredForMultiCCSThenTrueReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenTrueReturned();
}

View File

@@ -122,3 +122,7 @@ TEST_F(ReleaseHelper2004Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper2004Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) { TEST_F(ReleaseHelper2004Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) {
whenShouldQueryPeerAccessCalledThenFalseReturned(); whenShouldQueryPeerAccessCalledThenFalseReturned();
} }
TEST_F(ReleaseHelper2004Tests, whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned();
}

View File

@@ -120,3 +120,7 @@ TEST_F(ReleaseHelper3000Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper3000Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) { TEST_F(ReleaseHelper3000Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) {
whenShouldQueryPeerAccessCalledThenFalseReturned(); whenShouldQueryPeerAccessCalledThenFalseReturned();
} }
TEST_F(ReleaseHelper3000Tests, whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned();
}

View File

@@ -120,3 +120,7 @@ TEST_F(ReleaseHelper3001Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper3001Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) { TEST_F(ReleaseHelper3001Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) {
whenShouldQueryPeerAccessCalledThenFalseReturned(); whenShouldQueryPeerAccessCalledThenFalseReturned();
} }
TEST_F(ReleaseHelper3001Tests, whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned();
}

View File

@@ -120,3 +120,7 @@ TEST_F(ReleaseHelper3003Tests, whenCallingAdjustMaxThreadsPerEuCountThenCorrectV
TEST_F(ReleaseHelper3003Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) { TEST_F(ReleaseHelper3003Tests, whenShouldQueryPeerAccessCalledThenFalseReturned) {
whenShouldQueryPeerAccessCalledThenFalseReturned(); whenShouldQueryPeerAccessCalledThenFalseReturned();
} }
TEST_F(ReleaseHelper3003Tests, whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned) {
whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned();
}

View File

@@ -214,3 +214,21 @@ void ReleaseHelperTestsBase::whenShouldQueryPeerAccessCalledThenTrueReturned() {
EXPECT_TRUE(releaseHelper->shouldQueryPeerAccess()); EXPECT_TRUE(releaseHelper->shouldQueryPeerAccess());
} }
} }
void ReleaseHelperTestsBase::whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned() {
for (auto &revision : getRevisions()) {
ipVersion.revision = revision;
releaseHelper = ReleaseHelper::create(ipVersion);
ASSERT_NE(nullptr, releaseHelper);
EXPECT_FALSE(releaseHelper->isSingleDispatchRequiredForMultiCCS());
}
}
void ReleaseHelperTestsBase::whenIsSingleDispatchRequiredForMultiCCSCalledThenTrueReturned() {
for (auto &revision : getRevisions()) {
ipVersion.revision = revision;
releaseHelper = ReleaseHelper::create(ipVersion);
ASSERT_NE(nullptr, releaseHelper);
EXPECT_TRUE(releaseHelper->isSingleDispatchRequiredForMultiCCS());
}
}

View File

@@ -39,6 +39,8 @@ struct ReleaseHelperTestsBase : public ::testing::Test {
void whenCallingAdjustMaxThreadsPerEuCountThenCorrectValueIsReturned(); void whenCallingAdjustMaxThreadsPerEuCountThenCorrectValueIsReturned();
void whenShouldQueryPeerAccessCalledThenFalseReturned(); void whenShouldQueryPeerAccessCalledThenFalseReturned();
void whenShouldQueryPeerAccessCalledThenTrueReturned(); void whenShouldQueryPeerAccessCalledThenTrueReturned();
void whenIsSingleDispatchRequiredForMultiCCSCalledThenFalseReturned();
void whenIsSingleDispatchRequiredForMultiCCSCalledThenTrueReturned();
virtual std::vector<uint32_t> getRevisions() = 0; virtual std::vector<uint32_t> getRevisions() = 0;
std::unique_ptr<ReleaseHelper> releaseHelper; std::unique_ptr<ReleaseHelper> releaseHelper;