Default L0 Function & Global Symbols with fallback build for SPIRv

- Enabled default setting of Program & Global Symbols to be generated by
IGC when building L0 Modules with the ability to fallback to previous
behavior thru build failure checks.

- Enabled selective disable of default program or global symbol
generation thru debug variables.

Signed-off-by: Neil R Spruit <neil.r.spruit@intel.com>
This commit is contained in:
Neil R Spruit
2022-06-17 02:16:04 +00:00
committed by Compute-Runtime-Automation
parent ec4e3d0b10
commit 88b7a4f82d
7 changed files with 500 additions and 31 deletions

View File

@ -52,6 +52,8 @@ NEO::ConstStringRef hasBufferOffsetArg = "-ze-intel-has-buffer-offset-arg";
NEO::ConstStringRef debugKernelEnable = "-ze-kernel-debug-enable";
NEO::ConstStringRef profileFlags = "-zet-profile-flags";
NEO::ConstStringRef optLargeRegisterFile = "-ze-opt-large-register-file";
NEO::ConstStringRef enableLibraryCompile = "-library-compilation";
NEO::ConstStringRef enableGlobalVariableSymbols = "-ze-take-global-address";
} // namespace BuildOptions
ModuleTranslationUnit::ModuleTranslationUnit(L0::Device *device)
@ -173,6 +175,70 @@ bool ModuleTranslationUnit::processSpecConstantInfo(NEO::CompilerInterface *comp
return true;
}
bool ModuleTranslationUnit::attemptGenBinaryCompile(NEO::TranslationInput inputArgs, bool staticLink, bool libraryExportRequired, bool globalExportRequired) {
auto result = this->compileGenBinary(inputArgs, staticLink);
std::string enableGlobalFlag(BuildOptions::enableGlobalVariableSymbols.str().c_str());
std::string enableLibraryFlag(BuildOptions::enableLibraryCompile.str().c_str());
bool completedGlobalFlagRemovalCheck = false;
bool completedLibraryFlagRemovalCheck = false;
if (result == false) {
if (!globalExportRequired || !libraryExportRequired) {
// If the build failed, attempt to remove the implicit flags for Global Variables and/or Library Compile
std::string reducedOptions(options);
// Attempt build with only removing the Global Variable Flag
if (!globalExportRequired) {
std::string globalFlagRemoved(options);
size_t optionPos = std::string::npos;
optionPos = reducedOptions.find(enableGlobalFlag.c_str());
if (optionPos != std::string::npos) {
reducedOptions.erase(optionPos, BuildOptions::enableGlobalVariableSymbols.length());
}
optionPos = globalFlagRemoved.find(enableGlobalFlag.c_str());
if (optionPos != std::string::npos) {
globalFlagRemoved.erase(optionPos, BuildOptions::enableGlobalVariableSymbols.length());
inputArgs.apiOptions = ArrayRef<const char>(globalFlagRemoved.c_str(), globalFlagRemoved.length());
result = this->compileGenBinary(inputArgs, staticLink);
if (result == true) {
options.assign(globalFlagRemoved);
return result;
}
}
completedGlobalFlagRemovalCheck = true;
}
// Attempt build with only removing the Library Export Symbol Flag
if (!libraryExportRequired) {
std::string libraryFlagRemoved(options);
size_t optionPos = std::string::npos;
optionPos = reducedOptions.find(enableLibraryFlag.c_str());
if (optionPos != std::string::npos) {
reducedOptions.erase(optionPos, BuildOptions::enableLibraryCompile.length());
}
optionPos = libraryFlagRemoved.find(enableLibraryFlag.c_str());
if (optionPos != std::string::npos) {
libraryFlagRemoved.erase(optionPos, BuildOptions::enableLibraryCompile.length());
inputArgs.apiOptions = ArrayRef<const char>(libraryFlagRemoved.c_str(), libraryFlagRemoved.length());
result = this->compileGenBinary(inputArgs, staticLink);
if (result == true) {
options.assign(libraryFlagRemoved);
return result;
}
}
completedLibraryFlagRemovalCheck = true;
}
// Attempt build with the removal of both library and Global Variable flags
if (completedGlobalFlagRemovalCheck && completedLibraryFlagRemovalCheck) {
inputArgs.apiOptions = ArrayRef<const char>(reducedOptions.c_str(), reducedOptions.length());
result = this->compileGenBinary(inputArgs, staticLink);
if (result == true) {
options.assign(reducedOptions);
return result;
}
}
}
}
return result;
}
bool ModuleTranslationUnit::compileGenBinary(NEO::TranslationInput inputArgs, bool staticLink) {
auto compilerInterface = device->getNEODevice()->getCompilerInterface();
UNRECOVERABLE_IF(nullptr == compilerInterface);
@ -206,7 +272,7 @@ bool ModuleTranslationUnit::compileGenBinary(NEO::TranslationInput inputArgs, bo
}
bool ModuleTranslationUnit::staticLinkSpirV(std::vector<const char *> inputSpirVs, std::vector<uint32_t> inputModuleSizes, const char *buildOptions, const char *internalBuildOptions,
std::vector<const ze_module_constants_t *> specConstants) {
std::vector<const ze_module_constants_t *> specConstants, bool libraryExportRequired, bool globalExportRequired) {
auto compilerInterface = device->getNEODevice()->getCompilerInterface();
UNRECOVERABLE_IF(nullptr == compilerInterface);
@ -226,11 +292,11 @@ bool ModuleTranslationUnit::staticLinkSpirV(std::vector<const char *> inputSpirV
linkInputArgs.src = ArrayRef<const char>(reinterpret_cast<const char *>(spirvElfSource.data()), spirvElfSource.size());
linkInputArgs.apiOptions = ArrayRef<const char>(options.c_str(), options.length());
linkInputArgs.internalOptions = ArrayRef<const char>(internalOptions.c_str(), internalOptions.length());
return this->compileGenBinary(linkInputArgs, true);
return this->attemptGenBinaryCompile(linkInputArgs, true, libraryExportRequired, globalExportRequired);
}
bool ModuleTranslationUnit::buildFromSpirV(const char *input, uint32_t inputSize, const char *buildOptions, const char *internalBuildOptions,
const ze_module_constants_t *pConstants) {
const ze_module_constants_t *pConstants, bool libraryExportRequired, bool globalExportRequired) {
auto compilerInterface = device->getNEODevice()->getCompilerInterface();
UNRECOVERABLE_IF(nullptr == compilerInterface);
@ -245,10 +311,10 @@ bool ModuleTranslationUnit::buildFromSpirV(const char *input, uint32_t inputSize
inputArgs.src = ArrayRef<const char>(input, inputSize);
inputArgs.apiOptions = ArrayRef<const char>(options.c_str(), options.length());
inputArgs.internalOptions = ArrayRef<const char>(internalOptions.c_str(), internalOptions.length());
return this->compileGenBinary(inputArgs, false);
return this->attemptGenBinaryCompile(inputArgs, false, libraryExportRequired, globalExportRequired);
}
bool ModuleTranslationUnit::createFromNativeBinary(const char *input, size_t inputSize) {
bool ModuleTranslationUnit::createFromNativeBinary(const char *input, size_t inputSize, bool libraryExportRequired, bool globalExportRequired) {
UNRECOVERABLE_IF((nullptr == device) || (nullptr == device->getNEODevice()));
auto productAbbreviation = NEO::hardwarePrefix[device->getNEODevice()->getHardwareInfo().platform.eProductFamily];
@ -301,7 +367,7 @@ bool ModuleTranslationUnit::createFromNativeBinary(const char *input, size_t inp
updateBuildLog(NEO::CompilerWarnings::recompiledFromIr.str());
}
return buildFromSpirV(this->irBinary.get(), static_cast<uint32_t>(this->irBinarySize), this->options.c_str(), "", nullptr);
return buildFromSpirV(this->irBinary.get(), static_cast<uint32_t>(this->irBinarySize), this->options.c_str(), "", nullptr, libraryExportRequired, globalExportRequired);
} else {
return processUnpackedBinary();
}
@ -509,13 +575,17 @@ bool ModuleImp::initialize(const ze_module_desc_t *desc, NEO::Device *neoDevice)
inputModuleSizes,
buildOptions.c_str(),
internalBuildOptions.c_str(),
specConstants);
specConstants,
this->libraryExportRequired,
this->globalExportRequired);
} else {
success = this->translationUnit->buildFromSpirV(reinterpret_cast<const char *>(programExpDesc->pInputModules[0]),
inputModuleSizes[0],
buildOptions.c_str(),
internalBuildOptions.c_str(),
firstSpecConstants);
firstSpecConstants,
this->libraryExportRequired,
this->globalExportRequired);
}
} else {
return false;
@ -531,14 +601,16 @@ bool ModuleImp::initialize(const ze_module_desc_t *desc, NEO::Device *neoDevice)
if (desc->format == ZE_MODULE_FORMAT_NATIVE) {
success = this->translationUnit->createFromNativeBinary(
reinterpret_cast<const char *>(desc->pInputModule), desc->inputSize);
reinterpret_cast<const char *>(desc->pInputModule), desc->inputSize, this->libraryExportRequired, this->globalExportRequired);
} else if (desc->format == ZE_MODULE_FORMAT_IL_SPIRV) {
this->builtFromSPIRv = true;
success = this->translationUnit->buildFromSpirV(reinterpret_cast<const char *>(desc->pInputModule),
static_cast<uint32_t>(desc->inputSize),
buildOptions.c_str(),
internalBuildOptions.c_str(),
desc->pConstants);
desc->pConstants,
this->libraryExportRequired,
this->globalExportRequired);
} else {
return false;
}
@ -685,10 +757,18 @@ void ModuleImp::createBuildOptions(const char *pBuildFlags, std::string &apiOpti
moveOptLevelOption(apiOptions, apiOptions);
moveProfileFlagsOption(apiOptions, apiOptions);
this->libraryExportRequired = moveBuildOption(apiOptions, apiOptions, BuildOptions::enableLibraryCompile, BuildOptions::enableLibraryCompile);
this->globalExportRequired = moveBuildOption(apiOptions, apiOptions, BuildOptions::enableGlobalVariableSymbols, BuildOptions::enableGlobalVariableSymbols);
}
if (NEO::ApiSpecificConfig::getBindlessConfiguration()) {
NEO::CompilerOptions::concatenateAppend(internalBuildOptions, NEO::CompilerOptions::bindlessMode.str());
}
if (!this->libraryExportRequired && NEO::DebugManager.flags.EnableDefaultProgramSymbolTableGeneration.get()) {
NEO::CompilerOptions::concatenateAppend(apiOptions, BuildOptions::enableLibraryCompile.str());
}
if (!this->globalExportRequired && NEO::DebugManager.flags.EnableDefaultGlobalSymbolGeneration.get()) {
NEO::CompilerOptions::concatenateAppend(apiOptions, BuildOptions::enableGlobalVariableSymbols.str());
}
}
bool ModuleImp::moveOptLevelOption(std::string &dstOptionsSet, std::string &srcOptionSet) {

View File

@ -34,22 +34,24 @@ extern NEO::ConstStringRef hasBufferOffsetArg;
extern NEO::ConstStringRef debugKernelEnable;
extern NEO::ConstStringRef profileFlags;
extern NEO::ConstStringRef optLargeRegisterFile;
extern NEO::ConstStringRef enableLibraryCompile;
extern NEO::ConstStringRef enableGlobalVariableSymbols;
} // namespace BuildOptions
struct ModuleTranslationUnit {
ModuleTranslationUnit(L0::Device *device);
virtual ~ModuleTranslationUnit();
MOCKABLE_VIRTUAL bool buildFromSpirV(const char *input, uint32_t inputSize, const char *buildOptions, const char *internalBuildOptions,
const ze_module_constants_t *pConstants);
const ze_module_constants_t *pConstants, bool libraryExportRequired, bool globalExportRequired);
MOCKABLE_VIRTUAL bool staticLinkSpirV(std::vector<const char *> inputSpirVs, std::vector<uint32_t> inputModuleSizes, const char *buildOptions, const char *internalBuildOptions,
std::vector<const ze_module_constants_t *> specConstants);
MOCKABLE_VIRTUAL bool createFromNativeBinary(const char *input, size_t inputSize);
std::vector<const ze_module_constants_t *> specConstants, bool libraryExportRequired, bool globalExportRequired);
MOCKABLE_VIRTUAL bool createFromNativeBinary(const char *input, size_t inputSize, bool libraryExportRequired, bool globalExportRequired);
MOCKABLE_VIRTUAL bool processUnpackedBinary();
std::vector<uint8_t> generateElfFromSpirV(std::vector<const char *> inputSpirVs, std::vector<uint32_t> inputModuleSizes);
bool processSpecConstantInfo(NEO::CompilerInterface *compilerInterface, const ze_module_constants_t *pConstants, const char *input, uint32_t inputSize);
std::string generateCompilerOptions(const char *buildOptions, const char *internalBuildOptions);
MOCKABLE_VIRTUAL bool compileGenBinary(NEO::TranslationInput inputArgs, bool staticLink);
MOCKABLE_VIRTUAL bool attemptGenBinaryCompile(NEO::TranslationInput inputArgs, bool staticLink, bool libraryExportRequired, bool globalExportRequired);
void updateBuildLog(const std::string &newLogEntry);
void processDebugData();
L0::Device *device = nullptr;
@ -172,6 +174,8 @@ struct ModuleImp : public Module {
bool isFullyLinked = false;
bool allocatePrivateMemoryPerDispatch = true;
bool isZebinBinary = false;
bool libraryExportRequired = false;
bool globalExportRequired = false;
ModuleType type;
NEO::Linker::UnresolvedExternals unresolvedExternalsInfo{};
std::set<NEO::GraphicsAllocation *> importedSymbolAllocations{};

View File

@ -66,12 +66,36 @@ struct MockModuleTranslationUnit : public L0::ModuleTranslationUnit {
}
bool compileGenBinary(NEO::TranslationInput inputArgs, bool staticLink) override {
if (failGenCompile || failGenCompileCounter > 0) {
failGenCompileCounter = failGenCompileCounter - 1;
return false;
}
if (unpackedDeviceBinarySize && unpackedDeviceBinary) {
return true;
} else {
return ModuleTranslationUnit::compileGenBinary(inputArgs, staticLink);
}
}
bool attemptGenBinaryCompile(NEO::TranslationInput inputArgs, bool staticLink, bool libraryExportRequired, bool globalExportRequired) override {
bool libraryExport = libraryExportRequired;
bool globalExport = globalExportRequired;
if (requireGlobalExport) {
globalExport = true;
}
if (requireLibraryExport) {
libraryExport = true;
}
if (unpackedDeviceBinarySize && unpackedDeviceBinary) {
return true;
} else {
return ModuleTranslationUnit::attemptGenBinaryCompile(inputArgs, staticLink, libraryExport, globalExport);
}
}
bool failGenCompile = false;
bool requireGlobalExport = false;
bool requireLibraryExport = false;
int failGenCompileCounter = 0;
};
struct MockModule : public L0::ModuleImp {

View File

@ -1006,6 +1006,252 @@ TEST_F(ModuleStaticLinkTests, givenSingleModuleProvidedForSpirVStaticLinkAndBuil
runSprivLinkBuildWithOneModule();
}
using ModuleOptionsTests = Test<DeviceFixture>;
HWTEST_F(ModuleOptionsTests, givenFailureDuringGenCompileThenAttemptCompileFails) {
auto mockCompiler = new MockCompilerInterface();
auto rootDeviceEnvironment = neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0].get();
rootDeviceEnvironment->compilerInterface.reset(mockCompiler);
auto mockTranslationUnit = new MockModuleTranslationUnit(device);
mockTranslationUnit->failGenCompile = true;
uint8_t spirvData{};
ze_module_desc_t moduleDesc = {};
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
moduleDesc.pInputModule = &spirvData;
moduleDesc.inputSize = sizeof(spirvData);
Module module(device, nullptr, ModuleType::User);
module.translationUnit.reset(mockTranslationUnit);
bool success = module.initialize(&moduleDesc, neoDevice);
EXPECT_FALSE(success);
}
HWTEST_F(ModuleOptionsTests, givenValidModuleWithGlobalSymbolFlagThenGenCompileAttemptSucceeds) {
auto mockCompiler = new MockCompilerInterface();
auto rootDeviceEnvironment = neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0].get();
rootDeviceEnvironment->compilerInterface.reset(mockCompiler);
auto mockTranslationUnit = new MockModuleTranslationUnit(device);
mockTranslationUnit->options.append(BuildOptions::enableGlobalVariableSymbols.str());
mockTranslationUnit->requireGlobalExport = true;
uint8_t spirvData{};
ze_module_desc_t moduleDesc = {};
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
moduleDesc.pInputModule = &spirvData;
moduleDesc.inputSize = sizeof(spirvData);
Module module(device, nullptr, ModuleType::User);
module.translationUnit.reset(mockTranslationUnit);
bool success = module.initialize(&moduleDesc, neoDevice);
EXPECT_TRUE(success);
}
HWTEST_F(ModuleOptionsTests, givenModuleWithGlobalSymbolFlagThenGenCompileAttemptSucceedsAfterGlobalFlagRemoved) {
auto mockCompiler = new MockCompilerInterface();
auto rootDeviceEnvironment = neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0].get();
rootDeviceEnvironment->compilerInterface.reset(mockCompiler);
auto mockTranslationUnit = new MockModuleTranslationUnit(device);
mockTranslationUnit->options.append(BuildOptions::enableGlobalVariableSymbols.str());
mockTranslationUnit->requireGlobalExport = false;
mockTranslationUnit->failGenCompileCounter = 1;
uint8_t spirvData{};
ze_module_desc_t moduleDesc = {};
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
moduleDesc.pInputModule = &spirvData;
moduleDesc.inputSize = sizeof(spirvData);
Module module(device, nullptr, ModuleType::User);
module.translationUnit.reset(mockTranslationUnit);
bool success = module.initialize(&moduleDesc, neoDevice);
EXPECT_TRUE(success);
size_t optionPos = std::string::npos;
optionPos = mockTranslationUnit->options.find(BuildOptions::enableGlobalVariableSymbols.str().c_str());
EXPECT_EQ(optionPos, std::string::npos);
}
HWTEST_F(ModuleOptionsTests, givenModuleWithGlobalSymbolFlagRequiredThenGenCompileAttemptFails) {
auto mockCompiler = new MockCompilerInterface();
auto rootDeviceEnvironment = neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0].get();
rootDeviceEnvironment->compilerInterface.reset(mockCompiler);
auto mockTranslationUnit = new MockModuleTranslationUnit(device);
mockTranslationUnit->options.append(BuildOptions::enableGlobalVariableSymbols.str());
mockTranslationUnit->requireGlobalExport = true;
mockTranslationUnit->failGenCompile = true;
uint8_t spirvData{};
ze_module_desc_t moduleDesc = {};
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
moduleDesc.pInputModule = &spirvData;
moduleDesc.inputSize = sizeof(spirvData);
Module module(device, nullptr, ModuleType::User);
module.translationUnit.reset(mockTranslationUnit);
bool success = module.initialize(&moduleDesc, neoDevice);
EXPECT_FALSE(success);
size_t optionPos = std::string::npos;
optionPos = mockTranslationUnit->options.find(BuildOptions::enableGlobalVariableSymbols.str().c_str());
EXPECT_NE(optionPos, std::string::npos);
}
HWTEST_F(ModuleOptionsTests, givenValidModuleWithLibrarySymbolFlagThenGenCompileAttemptSucceeds) {
auto mockCompiler = new MockCompilerInterface();
auto rootDeviceEnvironment = neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0].get();
rootDeviceEnvironment->compilerInterface.reset(mockCompiler);
auto mockTranslationUnit = new MockModuleTranslationUnit(device);
mockTranslationUnit->options.append(BuildOptions::enableLibraryCompile.str());
mockTranslationUnit->requireLibraryExport = true;
uint8_t spirvData{};
ze_module_desc_t moduleDesc = {};
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
moduleDesc.pInputModule = &spirvData;
moduleDesc.inputSize = sizeof(spirvData);
Module module(device, nullptr, ModuleType::User);
module.translationUnit.reset(mockTranslationUnit);
bool success = module.initialize(&moduleDesc, neoDevice);
EXPECT_TRUE(success);
}
HWTEST_F(ModuleOptionsTests, givenModuleWithLibrarySymbolFlagThenGenCompileAttemptSucceedsAfterLibraryFlagRemoved) {
DebugManager.flags.EnableDefaultProgramSymbolTableGeneration.set(1);
auto mockCompiler = new MockCompilerInterface();
auto rootDeviceEnvironment = neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0].get();
rootDeviceEnvironment->compilerInterface.reset(mockCompiler);
auto mockTranslationUnit = new MockModuleTranslationUnit(device);
mockTranslationUnit->options.append(BuildOptions::enableLibraryCompile.str().c_str());
mockTranslationUnit->requireLibraryExport = false;
mockTranslationUnit->failGenCompileCounter = 2;
uint8_t spirvData{};
ze_module_desc_t moduleDesc = {};
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
moduleDesc.pInputModule = &spirvData;
moduleDesc.inputSize = sizeof(spirvData);
Module module(device, nullptr, ModuleType::User);
module.translationUnit.reset(mockTranslationUnit);
bool success = module.initialize(&moduleDesc, neoDevice);
EXPECT_TRUE(success);
size_t optionPos = std::string::npos;
optionPos = mockTranslationUnit->options.find(BuildOptions::enableLibraryCompile.str().c_str());
EXPECT_EQ(optionPos, std::string::npos);
DebugManager.flags.EnableDefaultProgramSymbolTableGeneration.set(0);
}
HWTEST_F(ModuleOptionsTests, givenModuleWithLibrarySymbolFlagRequiredThenGenCompileAttemptFailsInRetry) {
DebugManager.flags.EnableDefaultProgramSymbolTableGeneration.set(1);
auto mockCompiler = new MockCompilerInterface();
auto rootDeviceEnvironment = neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0].get();
rootDeviceEnvironment->compilerInterface.reset(mockCompiler);
auto mockTranslationUnit = new MockModuleTranslationUnit(device);
mockTranslationUnit->options.append(BuildOptions::enableLibraryCompile.str());
mockTranslationUnit->requireLibraryExport = true;
mockTranslationUnit->failGenCompileCounter = 3;
uint8_t spirvData{};
ze_module_desc_t moduleDesc = {};
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
moduleDesc.pInputModule = &spirvData;
moduleDesc.inputSize = sizeof(spirvData);
Module module(device, nullptr, ModuleType::User);
module.translationUnit.reset(mockTranslationUnit);
bool success = module.initialize(&moduleDesc, neoDevice);
EXPECT_FALSE(success);
size_t optionPos = std::string::npos;
optionPos = mockTranslationUnit->options.find(BuildOptions::enableLibraryCompile.str().c_str());
EXPECT_NE(optionPos, std::string::npos);
DebugManager.flags.EnableDefaultProgramSymbolTableGeneration.set(0);
}
HWTEST_F(ModuleOptionsTests, givenModuleWithLibraryAndGlobalSymbolFlagsRequiredThenGenCompileAttemptFailsInRetry) {
DebugManager.flags.EnableDefaultProgramSymbolTableGeneration.set(1);
auto mockCompiler = new MockCompilerInterface();
auto rootDeviceEnvironment = neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0].get();
rootDeviceEnvironment->compilerInterface.reset(mockCompiler);
auto mockTranslationUnit = new MockModuleTranslationUnit(device);
mockTranslationUnit->options.append(BuildOptions::enableLibraryCompile.str());
mockTranslationUnit->options.append(BuildOptions::enableGlobalVariableSymbols.str());
mockTranslationUnit->requireGlobalExport = true;
mockTranslationUnit->requireLibraryExport = true;
mockTranslationUnit->failGenCompile = true;
uint8_t spirvData{};
ze_module_desc_t moduleDesc = {};
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
moduleDesc.pInputModule = &spirvData;
moduleDesc.inputSize = sizeof(spirvData);
Module module(device, nullptr, ModuleType::User);
module.translationUnit.reset(mockTranslationUnit);
bool success = module.initialize(&moduleDesc, neoDevice);
EXPECT_FALSE(success);
size_t optionPos = std::string::npos;
optionPos = mockTranslationUnit->options.find(BuildOptions::enableLibraryCompile.str().c_str());
EXPECT_NE(optionPos, std::string::npos);
optionPos = mockTranslationUnit->options.find(BuildOptions::enableGlobalVariableSymbols.str().c_str());
EXPECT_NE(optionPos, std::string::npos);
DebugManager.flags.EnableDefaultProgramSymbolTableGeneration.set(0);
}
HWTEST_F(ModuleOptionsTests, givenModuleWithLibraryAndGlobalSymbolFlagsAndGenCompileFailsInAllSingleRemovalThenGenCompileAttemptSuccedsInRetry) {
DebugManager.flags.EnableDefaultProgramSymbolTableGeneration.set(1);
auto mockCompiler = new MockCompilerInterface();
auto rootDeviceEnvironment = neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[0].get();
rootDeviceEnvironment->compilerInterface.reset(mockCompiler);
auto mockTranslationUnit = new MockModuleTranslationUnit(device);
mockTranslationUnit->options.append(BuildOptions::enableLibraryCompile.str());
mockTranslationUnit->options.append(BuildOptions::enableGlobalVariableSymbols.str());
mockTranslationUnit->requireGlobalExport = false;
mockTranslationUnit->requireLibraryExport = false;
mockTranslationUnit->failGenCompileCounter = 3;
uint8_t spirvData{};
ze_module_desc_t moduleDesc = {};
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
moduleDesc.pInputModule = &spirvData;
moduleDesc.inputSize = sizeof(spirvData);
Module module(device, nullptr, ModuleType::User);
module.translationUnit.reset(mockTranslationUnit);
bool success = module.initialize(&moduleDesc, neoDevice);
EXPECT_TRUE(success);
size_t optionPos = std::string::npos;
optionPos = mockTranslationUnit->options.find(BuildOptions::enableLibraryCompile.str().c_str());
EXPECT_EQ(optionPos, std::string::npos);
optionPos = mockTranslationUnit->options.find(BuildOptions::enableGlobalVariableSymbols.str().c_str());
EXPECT_EQ(optionPos, std::string::npos);
DebugManager.flags.EnableDefaultProgramSymbolTableGeneration.set(0);
}
using ModuleLinkingTest = Test<DeviceFixture>;
HWTEST_F(ModuleLinkingTest, whenExternFunctionsAllocationIsPresentThenItsBeingAddedToResidencyContainer) {
@ -1959,14 +2205,14 @@ struct MockModuleTU : public L0::ModuleTranslationUnit {
MockModuleTU(L0::Device *device) : L0::ModuleTranslationUnit(device) {}
bool buildFromSpirV(const char *input, uint32_t inputSize, const char *buildOptions, const char *internalBuildOptions,
const ze_module_constants_t *pConstants) override {
const ze_module_constants_t *pConstants, bool libraryExportRequired, bool globalExportRequired) override {
wasBuildFromSpirVCalled = true;
return true;
}
bool createFromNativeBinary(const char *input, size_t inputSize) override {
bool createFromNativeBinary(const char *input, size_t inputSize, bool libraryExportRequired, bool globalExportRequired) override {
wasCreateFromNativeBinaryCalled = true;
return L0::ModuleTranslationUnit::createFromNativeBinary(input, inputSize);
return L0::ModuleTranslationUnit::createFromNativeBinary(input, inputSize, libraryExportRequired, globalExportRequired);
}
bool wasBuildFromSpirVCalled = false;
@ -2094,13 +2340,13 @@ HWTEST_F(ModuleTranslationUnitTest, WhenCreatingFromNativeBinaryThenSetsUpRequir
emptyProgram.elfHeader->machine = copyHwInfo.platform.eProductFamily;
L0::ModuleTranslationUnit moduleTuValid(this->device);
bool success = moduleTuValid.createFromNativeBinary(reinterpret_cast<const char *>(emptyProgram.storage.data()), emptyProgram.storage.size());
bool success = moduleTuValid.createFromNativeBinary(reinterpret_cast<const char *>(emptyProgram.storage.data()), emptyProgram.storage.size(), false, false);
EXPECT_TRUE(success);
emptyProgram.elfHeader->machine = copyHwInfo.platform.eProductFamily;
++emptyProgram.elfHeader->machine;
L0::ModuleTranslationUnit moduleTuInvalid(this->device);
success = moduleTuInvalid.createFromNativeBinary(reinterpret_cast<const char *>(emptyProgram.storage.data()), emptyProgram.storage.size());
success = moduleTuInvalid.createFromNativeBinary(reinterpret_cast<const char *>(emptyProgram.storage.data()), emptyProgram.storage.size(), false, false);
EXPECT_FALSE(success);
}
@ -2130,7 +2376,7 @@ HWTEST_F(ModuleTranslationUnitTest, WhenCreatingFromNativeBinaryThenSetsUpPacked
auto arData = encoder.encode();
L0::ModuleTranslationUnit moduleTuValid(this->device);
bool success = moduleTuValid.createFromNativeBinary(reinterpret_cast<const char *>(arData.data()), arData.size());
bool success = moduleTuValid.createFromNativeBinary(reinterpret_cast<const char *>(arData.data()), arData.size(), false, false);
EXPECT_TRUE(success);
EXPECT_NE(moduleTuValid.packedDeviceBinarySize, arData.size());
}
@ -2143,7 +2389,7 @@ HWTEST_F(ModuleTranslationUnitTest, WhenCreatingFromZebinThenAppendAllowZebinFla
zebin.elfHeader->machine = copyHwInfo.platform.eProductFamily;
L0::ModuleTranslationUnit moduleTu(this->device);
bool success = moduleTu.createFromNativeBinary(reinterpret_cast<const char *>(zebin.storage.data()), zebin.storage.size());
bool success = moduleTu.createFromNativeBinary(reinterpret_cast<const char *>(zebin.storage.data()), zebin.storage.size(), false, false);
EXPECT_TRUE(success);
auto expectedOptions = " " + NEO::CompilerOptions::allowZebin.str();
@ -2172,7 +2418,7 @@ kernels:
zebin.elfHeader->machine = copyHwInfo.platform.eProductFamily;
L0::ModuleTranslationUnit moduleTuValid(this->device);
bool success = moduleTuValid.createFromNativeBinary(reinterpret_cast<const char *>(zebin.storage.data()), zebin.storage.size());
bool success = moduleTuValid.createFromNativeBinary(reinterpret_cast<const char *>(zebin.storage.data()), zebin.storage.size(), false, false);
EXPECT_TRUE(success);
EXPECT_NE(nullptr, moduleTuValid.programInfo.linkerInput.get());
@ -2231,7 +2477,7 @@ HWTEST_F(ModuleTranslationUnitTest, WhenBuildOptionsAreNullThenReuseExistingOpti
moduleTu.options = "abcd";
pMockCompilerInterface->failBuild = true;
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr, false, false);
EXPECT_FALSE(ret);
EXPECT_STREQ("abcd", moduleTu.options.c_str());
EXPECT_STREQ("abcd", pMockCompilerInterface->receivedApiOptions.c_str());
@ -2246,7 +2492,7 @@ HWTEST_F(ModuleTranslationUnitTest, WhenBuildOptionsAreNullThenReuseExistingOpti
DebugManager.flags.DisableStatelessToStatefulOptimization.set(1);
MockModuleTranslationUnit moduleTu(this->device);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr, false, false);
EXPECT_TRUE(ret);
EXPECT_NE(pMockCompilerInterface->inputInternalOptions.find("cl-intel-greater-than-4GB-buffer-required"), std::string::npos);
}
@ -2256,7 +2502,7 @@ HWTEST_F(ModuleTranslationUnitTest, givenInternalOptionsThenLSCCachePolicyIsSet)
auto &rootDeviceEnvironment = this->neoDevice->executionEnvironment->rootDeviceEnvironments[this->neoDevice->getRootDeviceIndex()];
rootDeviceEnvironment->compilerInterface.reset(pMockCompilerInterface);
MockModuleTranslationUnit moduleTu(this->device);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr, false, false);
const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(defaultHwInfo->platform.eProductFamily);
EXPECT_TRUE(ret);
auto expectedPolicy = compilerHwInfoConfig.getCachingPolicyOptions(false);
@ -2275,7 +2521,7 @@ HWTEST2_F(ModuleTranslationUnitTest, givenDebugFlagSetToWbWhenGetInternalOptions
auto &rootDeviceEnvironment = this->neoDevice->executionEnvironment->rootDeviceEnvironments[this->neoDevice->getRootDeviceIndex()];
rootDeviceEnvironment->compilerInterface.reset(pMockCompilerInterface);
MockModuleTranslationUnit moduleTu(this->device);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr, false, false);
EXPECT_TRUE(ret);
EXPECT_NE(pMockCompilerInterface->inputInternalOptions.find("-cl-store-cache-default=7 -cl-load-cache-default=4"), std::string::npos);
}
@ -2288,7 +2534,7 @@ HWTEST2_F(ModuleTranslationUnitTest, givenDebugFlagSetForceAllResourcesUncachedW
auto &rootDeviceEnvironment = this->neoDevice->executionEnvironment->rootDeviceEnvironments[this->neoDevice->getRootDeviceIndex()];
rootDeviceEnvironment->compilerInterface.reset(pMockCompilerInterface);
MockModuleTranslationUnit moduleTu(this->device);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr, false, false);
EXPECT_TRUE(ret);
EXPECT_NE(pMockCompilerInterface->inputInternalOptions.find("-cl-store-cache-default=1 -cl-load-cache-default=1"), std::string::npos);
}
@ -2298,7 +2544,7 @@ HWTEST2_F(ModuleTranslationUnitTest, givenAtLeastXeHpgCoreWhenGetInternalOptions
auto &rootDeviceEnvironment = this->neoDevice->executionEnvironment->rootDeviceEnvironments[this->neoDevice->getRootDeviceIndex()];
rootDeviceEnvironment->compilerInterface.reset(pMockCompilerInterface);
MockModuleTranslationUnit moduleTu(this->device);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr, false, false);
EXPECT_TRUE(ret);
EXPECT_NE(pMockCompilerInterface->inputInternalOptions.find("-cl-store-cache-default=2 -cl-load-cache-default=4"), std::string::npos);
}
@ -2309,7 +2555,7 @@ HWTEST_F(ModuleTranslationUnitTest, givenForceToStatelessRequiredWhenBuildingMod
rootDeviceEnvironment->compilerInterface.reset(mockCompilerInterface);
MockModuleTranslationUnit moduleTu(device);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr, false, false);
EXPECT_TRUE(ret);
const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(defaultHwInfo->platform.eProductFamily);
@ -2408,6 +2654,117 @@ TEST(BuildOptions, givenSrcOptionNameInSrcNamesWhenMovingBuildOptionsThenOptionI
EXPECT_EQ(std::string::npos, srcNames.find(NEO::CompilerOptions::optDisable.str()));
}
TEST_F(ModuleTest, givenBuildOptionsWhenEnableDefaultProgramSymbolTableGenerationIsEnabledThenEnableLibraryCompileIsSet) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDefaultProgramSymbolTableGeneration.set(1);
auto module = std::make_unique<ModuleImp>(device, nullptr, ModuleType::User);
ASSERT_NE(nullptr, module);
std::string buildOptions;
std::string internalBuildOptions;
module->createBuildOptions("", buildOptions, internalBuildOptions);
EXPECT_TRUE(NEO::CompilerOptions::contains(buildOptions, BuildOptions::enableLibraryCompile));
}
TEST_F(ModuleTest, givenBuildOptionsWhenEnableDefaultProgramSymbolTableGenerationIsDisabledThenEnableLibraryCompileIsNotSet) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDefaultProgramSymbolTableGeneration.set(0);
auto module = std::make_unique<ModuleImp>(device, nullptr, ModuleType::User);
ASSERT_NE(nullptr, module);
std::string buildOptions;
std::string internalBuildOptions;
module->createBuildOptions("", buildOptions, internalBuildOptions);
EXPECT_FALSE(NEO::CompilerOptions::contains(buildOptions, BuildOptions::enableLibraryCompile));
}
TEST_F(ModuleTest, givenBuildOptionsWithEnableLibraryCompileWhenEnableDefaultProgramSymbolTableGenerationIsDisabledThenEnableLibraryCompileIsSet) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDefaultProgramSymbolTableGeneration.set(0);
auto module = std::make_unique<ModuleImp>(device, nullptr, ModuleType::User);
ASSERT_NE(nullptr, module);
std::string buildOptions;
std::string internalBuildOptions;
module->createBuildOptions(BuildOptions::enableLibraryCompile.str().c_str(), buildOptions, internalBuildOptions);
EXPECT_TRUE(NEO::CompilerOptions::contains(buildOptions, BuildOptions::enableLibraryCompile));
}
TEST_F(ModuleTest, givenBuildOptionsWithEnableLibraryCompileWhenEnableDefaultProgramSymbolTableGenerationIsEnabledThenEnableLibraryCompileIsSet) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDefaultProgramSymbolTableGeneration.set(1);
auto module = std::make_unique<ModuleImp>(device, nullptr, ModuleType::User);
ASSERT_NE(nullptr, module);
std::string buildOptions;
std::string internalBuildOptions;
module->createBuildOptions(BuildOptions::enableLibraryCompile.str().c_str(), buildOptions, internalBuildOptions);
EXPECT_TRUE(NEO::CompilerOptions::contains(buildOptions, BuildOptions::enableLibraryCompile));
}
TEST_F(ModuleTest, givenBuildOptionsWhenEnableDefaultGlobalSymbolGenerationIsEnabledThenEnableGlobalVariableSymbolsIsSet) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDefaultGlobalSymbolGeneration.set(1);
auto module = std::make_unique<ModuleImp>(device, nullptr, ModuleType::User);
ASSERT_NE(nullptr, module);
std::string buildOptions;
std::string internalBuildOptions;
module->createBuildOptions("", buildOptions, internalBuildOptions);
EXPECT_TRUE(NEO::CompilerOptions::contains(buildOptions, BuildOptions::enableGlobalVariableSymbols));
}
TEST_F(ModuleTest, givenBuildOptionsWhenEnableDefaultGlobalSymbolGenerationIsDisabledThenEnableGlobalVariableSymbolsIsNotSet) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDefaultGlobalSymbolGeneration.set(0);
auto module = std::make_unique<ModuleImp>(device, nullptr, ModuleType::User);
ASSERT_NE(nullptr, module);
std::string buildOptions;
std::string internalBuildOptions;
module->createBuildOptions("", buildOptions, internalBuildOptions);
EXPECT_FALSE(NEO::CompilerOptions::contains(buildOptions, BuildOptions::enableGlobalVariableSymbols));
}
TEST_F(ModuleTest, givenBuildOptionsWithEnableGlobalVariableSymbolsWhenEnableDefaultGlobalSymbolGenerationIsDisabledThenEnableGlobalVariableSymbolsIsSet) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDefaultGlobalSymbolGeneration.set(0);
auto module = std::make_unique<ModuleImp>(device, nullptr, ModuleType::User);
ASSERT_NE(nullptr, module);
std::string buildOptions;
std::string internalBuildOptions;
module->createBuildOptions(BuildOptions::enableGlobalVariableSymbols.str().c_str(), buildOptions, internalBuildOptions);
EXPECT_TRUE(NEO::CompilerOptions::contains(buildOptions, BuildOptions::enableGlobalVariableSymbols));
}
TEST_F(ModuleTest, givenBuildOptionsWithEnableGlobalVariableSymbolsWhenEnableDefaultGlobalSymbolGenerationIsEnabledThenEnableGlobalVariableSymbolsIsSet) {
DebugManagerStateRestore restorer;
DebugManager.flags.EnableDefaultGlobalSymbolGeneration.set(1);
auto module = std::make_unique<ModuleImp>(device, nullptr, ModuleType::User);
ASSERT_NE(nullptr, module);
std::string buildOptions;
std::string internalBuildOptions;
module->createBuildOptions(BuildOptions::enableGlobalVariableSymbols.str().c_str(), buildOptions, internalBuildOptions);
EXPECT_TRUE(NEO::CompilerOptions::contains(buildOptions, BuildOptions::enableGlobalVariableSymbols));
}
TEST_F(ModuleTest, givenInternalOptionsWhenBindlessEnabledThenBindlesOptionsPassed) {
DebugManagerStateRestore restorer;
DebugManager.flags.UseBindlessMode.set(1);
@ -2621,7 +2978,7 @@ TEST_F(ModuleInitializeTest, whenModuleInitializeIsCalledThenCorrectResultIsRetu
class MyMockModuleTU : public MockModuleTU {
public:
using MockModuleTU::MockModuleTU;
bool createFromNativeBinary(const char *input, size_t inputSize) override { return true; }
bool createFromNativeBinary(const char *input, size_t inputSize, bool libraryExportRequired, bool globalExportRequired) override { return true; }
};
const auto &compilerHwInfoConfig = *CompilerHwInfoConfig::get(defaultHwInfo->platform.eProductFamily);

View File

@ -51,7 +51,7 @@ HWTEST2_F(KernelPropertyTest, givenDG2WhenGetInternalOptionsThenWriteBackBuildOp
auto &rootDeviceEnvironment = this->neoDevice->executionEnvironment->rootDeviceEnvironments[this->neoDevice->getRootDeviceIndex()];
rootDeviceEnvironment->compilerInterface.reset(pMockCompilerInterface);
MockModuleTranslationUnit moduleTu(this->device);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr);
auto ret = moduleTu.buildFromSpirV("", 0U, nullptr, "", nullptr, false, false);
EXPECT_TRUE(ret);
EXPECT_NE(pMockCompilerInterface->inputInternalOptions.find("-cl-store-cache-default=7 -cl-load-cache-default=4"), std::string::npos);
}