mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-05 09:09:04 +08:00
Add debug flag to fail build program with stateful access
I've added debug flag FailBuildProgramWithStatefulAccess which makes possible to fail build program/module creation with stateful access(except builtins) on pvc and later platforms. Related-To: NEO-6075 Signed-off-by: Kamil Kopryk <kamil.kopryk@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
b24635b0c0
commit
99db73c034
@@ -16,6 +16,7 @@
|
||||
#include "shared/source/device_binary_format/elf/elf.h"
|
||||
#include "shared/source/device_binary_format/elf/elf_encoder.h"
|
||||
#include "shared/source/device_binary_format/elf/ocl_elf.h"
|
||||
#include "shared/source/helpers/addressing_mode_helper.h"
|
||||
#include "shared/source/helpers/api_specific_config.h"
|
||||
#include "shared/source/helpers/compiler_hw_info_config.h"
|
||||
#include "shared/source/helpers/constants.h"
|
||||
@@ -116,8 +117,9 @@ std::string ModuleTranslationUnit::generateCompilerOptions(const char *buildOpti
|
||||
options = buildOptions;
|
||||
}
|
||||
std::string internalOptions = NEO::CompilerOptions::concatenate(internalBuildOptions, BuildOptions::hasBufferOffsetArg);
|
||||
auto &neoDevice = *device->getNEODevice();
|
||||
|
||||
if (device->getNEODevice()->getDeviceInfo().debuggerActive) {
|
||||
if (neoDevice.getDeviceInfo().debuggerActive) {
|
||||
if (NEO::SourceLevelDebugger::shouldAppendOptDisable(*device->getSourceLevelDebugger())) {
|
||||
NEO::CompilerOptions::concatenateAppend(options, BuildOptions::optDisable);
|
||||
}
|
||||
@@ -126,8 +128,11 @@ std::string ModuleTranslationUnit::generateCompilerOptions(const char *buildOpti
|
||||
internalOptions = NEO::CompilerOptions::concatenate(internalOptions, BuildOptions::debugKernelEnable);
|
||||
}
|
||||
|
||||
if (NEO::DebugManager.flags.DisableStatelessToStatefulOptimization.get() ||
|
||||
device->getNEODevice()->areSharedSystemAllocationsAllowed()) {
|
||||
const auto &compilerHwInfoConfig = *NEO::CompilerHwInfoConfig::get(neoDevice.getHardwareInfo().platform.eProductFamily);
|
||||
auto forceToStatelessRequired = compilerHwInfoConfig.isForceToStatelessRequired();
|
||||
auto statelessToStatefulOptimizationDisabled = NEO::DebugManager.flags.DisableStatelessToStatefulOptimization.get();
|
||||
|
||||
if (forceToStatelessRequired || statelessToStatefulOptimizationDisabled) {
|
||||
internalOptions = NEO::CompilerOptions::concatenate(internalOptions, NEO::CompilerOptions::greaterThan4gbBuffersRequired);
|
||||
}
|
||||
|
||||
@@ -527,6 +532,18 @@ bool ModuleImp::initialize(const ze_module_desc_t *desc, NEO::Device *neoDevice)
|
||||
this->updateBuildLog(neoDevice);
|
||||
verifyDebugCapabilities();
|
||||
|
||||
auto &hwInfo = neoDevice->getHardwareInfo();
|
||||
auto containsStatefulAccess = NEO::AddressingModeHelper::containsStatefulAccess(translationUnit->programInfo.kernelInfos);
|
||||
auto isUserKernel = (type == ModuleType::User);
|
||||
|
||||
auto failBuildProgram = containsStatefulAccess &&
|
||||
isUserKernel &&
|
||||
NEO::AddressingModeHelper::failBuildProgramWithStatefulAccess(hwInfo);
|
||||
|
||||
if (failBuildProgram) {
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (false == success) {
|
||||
return false;
|
||||
}
|
||||
@@ -554,7 +571,6 @@ bool ModuleImp::initialize(const ze_module_desc_t *desc, NEO::Device *neoDevice)
|
||||
passDebugData();
|
||||
}
|
||||
|
||||
auto &hwInfo = neoDevice->getHardwareInfo();
|
||||
auto &hwHelper = NEO::HwHelper::get(hwInfo.platform.eRenderCoreFamily);
|
||||
|
||||
if (this->isFullyLinked && this->type == ModuleType::User) {
|
||||
|
||||
@@ -126,7 +126,7 @@ struct ModuleImp : public Module {
|
||||
|
||||
Device *getDevice() const override { return device; }
|
||||
|
||||
bool linkBinary();
|
||||
MOCKABLE_VIRTUAL bool linkBinary();
|
||||
|
||||
bool initialize(const ze_module_desc_t *desc, NEO::Device *neoDevice);
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "shared/source/device_binary_format/debug_zebin.h"
|
||||
#include "shared/source/gmm_helper/gmm.h"
|
||||
#include "shared/source/gmm_helper/gmm_helper.h"
|
||||
#include "shared/source/helpers/addressing_mode_helper.h"
|
||||
#include "shared/source/helpers/compiler_hw_info_config.h"
|
||||
#include "shared/source/kernel/implicit_args.h"
|
||||
#include "shared/source/program/kernel_info.h"
|
||||
#include "shared/test/common/helpers/debug_manager_state_restore.h"
|
||||
@@ -2079,28 +2081,19 @@ HWTEST_F(ModuleTranslationUnitTest, WhenBuildOptionsAreNullThenReuseExistingOpti
|
||||
EXPECT_NE(pMockCompilerInterface->inputInternalOptions.find("cl-intel-greater-than-4GB-buffer-required"), std::string::npos);
|
||||
}
|
||||
|
||||
HWTEST_F(ModuleTranslationUnitTest, givenSystemSharedAllocationAllowedWhenBuildingModuleThen4GbBuffersAreRequired) {
|
||||
HWTEST_F(ModuleTranslationUnitTest, givenForceToStatelessRequiredWhenBuildingModuleThen4GbBuffersAreRequired) {
|
||||
auto mockCompilerInterface = new MockCompilerInterface;
|
||||
auto &rootDeviceEnvironment = neoDevice->executionEnvironment->rootDeviceEnvironments[neoDevice->getRootDeviceIndex()];
|
||||
rootDeviceEnvironment->compilerInterface.reset(mockCompilerInterface);
|
||||
|
||||
{
|
||||
neoDevice->getRootDeviceEnvironment().getMutableHardwareInfo()->capabilityTable.sharedSystemMemCapabilities = 1;
|
||||
|
||||
MockModuleTranslationUnit moduleTu(device);
|
||||
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr);
|
||||
EXPECT_TRUE(ret);
|
||||
MockModuleTranslationUnit moduleTu(device);
|
||||
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr);
|
||||
EXPECT_TRUE(ret);
|
||||
|
||||
const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(defaultHwInfo->platform.eProductFamily);
|
||||
if (compilerHwInfoConfig.isForceToStatelessRequired()) {
|
||||
EXPECT_NE(mockCompilerInterface->inputInternalOptions.find("cl-intel-greater-than-4GB-buffer-required"), std::string::npos);
|
||||
}
|
||||
|
||||
{
|
||||
neoDevice->getRootDeviceEnvironment().getMutableHardwareInfo()->capabilityTable.sharedSystemMemCapabilities = 0;
|
||||
|
||||
MockModuleTranslationUnit moduleTu(device);
|
||||
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr);
|
||||
EXPECT_TRUE(ret);
|
||||
|
||||
} else {
|
||||
EXPECT_EQ(mockCompilerInterface->inputInternalOptions.find("cl-intel-greater-than-4GB-buffer-required"), std::string::npos);
|
||||
}
|
||||
}
|
||||
@@ -2308,6 +2301,110 @@ TEST_F(ModuleTest, GivenInjectInternalBuildOptionsWhenBuildingBuiltinModuleThenI
|
||||
EXPECT_FALSE(CompilerOptions::contains(cip->buildInternalOptions, "-abc"));
|
||||
};
|
||||
|
||||
TEST_F(ModuleTest, whenContainsStatefulAccessIsCalledThenResultIsCorrect) {
|
||||
class MyModuleImpl : public ModuleImp {
|
||||
public:
|
||||
using ModuleImp::ModuleImp;
|
||||
};
|
||||
|
||||
std::vector<std::tuple<bool, SurfaceStateHeapOffset, CrossThreadDataOffset>> testParams = {
|
||||
{false, undefined<SurfaceStateHeapOffset>, undefined<CrossThreadDataOffset>},
|
||||
{true, 0x40, undefined<CrossThreadDataOffset>},
|
||||
{true, undefined<SurfaceStateHeapOffset>, 0x40},
|
||||
{true, 0x40, 0x40},
|
||||
};
|
||||
|
||||
for (auto &[expectedResult, surfaceStateHeapOffset, crossThreadDataOffset] : testParams) {
|
||||
auto module = std::make_unique<MyModuleImpl>(device, nullptr, ModuleType::User);
|
||||
ASSERT_NE(nullptr, module);
|
||||
auto moduleTranslationUnit = module->getTranslationUnit();
|
||||
ASSERT_NE(nullptr, moduleTranslationUnit);
|
||||
auto kernelInfo = std::make_unique<KernelInfo>();
|
||||
kernelInfo->kernelDescriptor.payloadMappings.explicitArgs.clear();
|
||||
auto argDescriptor = ArgDescriptor(ArgDescriptor::ArgTPointer);
|
||||
argDescriptor.as<ArgDescPointer>().bindful = surfaceStateHeapOffset;
|
||||
argDescriptor.as<ArgDescPointer>().bindless = crossThreadDataOffset;
|
||||
kernelInfo->kernelDescriptor.payloadMappings.explicitArgs.push_back(argDescriptor);
|
||||
moduleTranslationUnit->programInfo.kernelInfos.clear();
|
||||
moduleTranslationUnit->programInfo.kernelInfos.push_back(kernelInfo.release());
|
||||
|
||||
EXPECT_EQ(expectedResult, NEO::AddressingModeHelper::containsStatefulAccess(moduleTranslationUnit->programInfo.kernelInfos));
|
||||
}
|
||||
}
|
||||
|
||||
using ModuleInitializeTest = Test<DeviceFixture>;
|
||||
|
||||
TEST_F(ModuleInitializeTest, whenModuleInitializeIsCalledThenCorrectResultIsReturned) {
|
||||
class MockModuleImp : public ModuleImp {
|
||||
public:
|
||||
using ModuleImp::isFullyLinked;
|
||||
using ModuleImp::ModuleImp;
|
||||
using ModuleImp::translationUnit;
|
||||
|
||||
bool linkBinary() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
void setAddressingMode(bool isStateful) {
|
||||
auto kernelInfo = std::make_unique<KernelInfo>();
|
||||
kernelInfo->kernelDescriptor.payloadMappings.explicitArgs.clear();
|
||||
auto argDescriptor = ArgDescriptor(ArgDescriptor::ArgTPointer);
|
||||
if (isStateful) {
|
||||
argDescriptor.as<ArgDescPointer>().bindful = 0x40;
|
||||
argDescriptor.as<ArgDescPointer>().bindless = 0x40;
|
||||
} else {
|
||||
argDescriptor.as<ArgDescPointer>().bindful = undefined<SurfaceStateHeapOffset>;
|
||||
argDescriptor.as<ArgDescPointer>().bindless = undefined<CrossThreadDataOffset>;
|
||||
}
|
||||
kernelInfo->kernelDescriptor.payloadMappings.explicitArgs.push_back(argDescriptor);
|
||||
kernelInfo->heapInfo.KernelHeapSize = 0x1;
|
||||
kernelInfo->heapInfo.pKernelHeap = reinterpret_cast<void *>(0xffff);
|
||||
|
||||
this->translationUnit->programInfo.kernelInfos.clear();
|
||||
this->translationUnit->programInfo.kernelInfos.push_back(kernelInfo.release());
|
||||
}
|
||||
};
|
||||
|
||||
class MyMockModuleTU : public MockModuleTU {
|
||||
public:
|
||||
using MockModuleTU::MockModuleTU;
|
||||
bool createFromNativeBinary(const char *input, size_t inputSize) override { return true; }
|
||||
};
|
||||
|
||||
const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(defaultHwInfo->platform.eProductFamily);
|
||||
if (!compilerHwInfoConfig.isForceToStatelessRequired()) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
DebugManagerStateRestore restorer;
|
||||
std::string testFile;
|
||||
retrieveBinaryKernelFilenameApiSpecific(testFile, "test_kernel_", ".bin");
|
||||
size_t size = 0;
|
||||
auto src = loadDataFromFile(testFile.c_str(), size);
|
||||
ASSERT_NE(0u, size);
|
||||
ASSERT_NE(nullptr, src);
|
||||
ze_module_desc_t moduleDesc = {};
|
||||
moduleDesc.format = ZE_MODULE_FORMAT_NATIVE;
|
||||
moduleDesc.pInputModule = reinterpret_cast<const uint8_t *>(src.get());
|
||||
moduleDesc.inputSize = size;
|
||||
|
||||
std::array<std::tuple<bool, bool, ModuleType, int32_t>, 5> testParams = {{
|
||||
{true, false, ModuleType::Builtin, -1},
|
||||
{true, true, ModuleType::Builtin, 0},
|
||||
{true, true, ModuleType::User, 0},
|
||||
{true, true, ModuleType::Builtin, 1},
|
||||
{false, true, ModuleType::User, 1},
|
||||
}};
|
||||
|
||||
for (auto &[expectedResult, isStateful, moduleType, debugKey] : testParams) {
|
||||
MockModuleImp module(device, nullptr, moduleType);
|
||||
module.translationUnit = std::make_unique<MyMockModuleTU>(device);
|
||||
DebugManager.flags.FailBuildProgramWithStatefulAccess.set(debugKey);
|
||||
module.setAddressingMode(isStateful);
|
||||
EXPECT_EQ(expectedResult, module.initialize(&moduleDesc, device->getNEODevice()));
|
||||
}
|
||||
}
|
||||
|
||||
using ModuleDebugDataTest = Test<DeviceFixture>;
|
||||
TEST_F(ModuleDebugDataTest, GivenDebugDataWithRelocationsWhenCreatingRelocatedDebugDataThenRelocationsAreApplied) {
|
||||
auto cip = new NEO::MockCompilerInterfaceCaptureBuildOptions();
|
||||
|
||||
Reference in New Issue
Block a user