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{};