fix(ocloc): optimize accesses to cache when building source code

when binary is zebin then don't look for separate debug binary

Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski
2024-06-12 16:06:30 +00:00
committed by Compute-Runtime-Automation
parent fcef00969e
commit a28d6557ad
2 changed files with 58 additions and 30 deletions

View File

@@ -3124,19 +3124,25 @@ TEST(OfflineCompilerTest, givenDefaultOfflineCompilerObjectWhenNoOptionsAreChang
EXPECT_FALSE(mockOfflineCompiler->inputFileSpirV); EXPECT_FALSE(mockOfflineCompiler->inputFileSpirV);
} }
TEST(OfflineCompilerTest, givenIntermediateRepresentationInputWhenBuildSourceCodeIsCalledThenProperTranslationContextIsUsed) { TEST(OfflineCompilerTest, givenSpirvRepresentationInputWhenBuildSourceCodeIsCalledThenProperTranslationContextIsUsed) {
MockOfflineCompiler mockOfflineCompiler; MockOfflineCompiler mockOfflineCompiler;
Source source{reinterpret_cast<const uint8_t *>(spirvMagic.data()), spirvMagic.size(), "some_file.spv"};
static_cast<MockOclocArgHelper *>(mockOfflineCompiler.argHelper)->inputs.push_back(source);
std::vector<std::string> argv = { std::vector<std::string> argv = {
"ocloc", "ocloc",
"-file", "-file",
clFiles + "emptykernel.cl", "some_file.spv",
"-device", "-device",
gEnvironment->devicePrefix.c_str()}; gEnvironment->devicePrefix.c_str()};
testing::internal::CaptureStdout(); testing::internal::CaptureStdout();
struct StdoutCaptureRAII { struct StdoutCaptureRAII {
~StdoutCaptureRAII() { ~StdoutCaptureRAII() {
testing::internal::GetCapturedStdout(); auto output = testing::internal::GetCapturedStdout();
if (HasFatalFailure()) {
printf("%s", output.c_str());
}
} }
} stdoutCaptureRAII; } stdoutCaptureRAII;
auto retVal = mockOfflineCompiler.initialize(argv.size(), argv); auto retVal = mockOfflineCompiler.initialize(argv.size(), argv);
@@ -3150,8 +3156,34 @@ TEST(OfflineCompilerTest, givenIntermediateRepresentationInputWhenBuildSourceCod
ASSERT_EQ(1U, mockIgcOclDeviceCtx->requestedTranslationCtxs.size()); ASSERT_EQ(1U, mockIgcOclDeviceCtx->requestedTranslationCtxs.size());
NEO::MockIgcOclDeviceCtx::TranslationOpT expectedTranslation = {IGC::CodeType::spirV, IGC::CodeType::oclGenBin}; NEO::MockIgcOclDeviceCtx::TranslationOpT expectedTranslation = {IGC::CodeType::spirV, IGC::CodeType::oclGenBin};
ASSERT_EQ(expectedTranslation, mockIgcOclDeviceCtx->requestedTranslationCtxs[0]); ASSERT_EQ(expectedTranslation, mockIgcOclDeviceCtx->requestedTranslationCtxs[0]);
}
TEST(OfflineCompilerTest, givenLlvmBcRepresentationInputWhenBuildSourceCodeIsCalledThenProperTranslationContextIsUsed) {
MockOfflineCompiler mockOfflineCompiler;
Source source{reinterpret_cast<const uint8_t *>(llvmBcMagic.data()), llvmBcMagic.size(), "some_file.bc"};
static_cast<MockOclocArgHelper *>(mockOfflineCompiler.argHelper)->inputs.push_back(source);
std::vector<std::string> argv = {
"ocloc",
"-file",
"some_file.bc",
"-device",
gEnvironment->devicePrefix.c_str()};
testing::internal::CaptureStdout();
struct StdoutCaptureRAII {
~StdoutCaptureRAII() {
auto output = testing::internal::GetCapturedStdout();
if (HasFatalFailure()) {
printf("%s", output.c_str());
}
}
} stdoutCaptureRAII;
auto retVal = mockOfflineCompiler.initialize(argv.size(), argv);
auto mockIgcOclDeviceCtx = new NEO::MockIgcOclDeviceCtx();
mockOfflineCompiler.mockIgcFacade->igcDeviceCtx = CIF::RAII::Pack<IGC::IgcOclDeviceCtxTagOCL>(mockIgcOclDeviceCtx);
ASSERT_EQ(CL_SUCCESS, retVal);
mockOfflineCompiler.inputFileSpirV = false;
mockOfflineCompiler.inputFileLlvm = true; mockOfflineCompiler.inputFileLlvm = true;
mockIgcOclDeviceCtx->requestedTranslationCtxs.clear(); mockIgcOclDeviceCtx->requestedTranslationCtxs.clear();
retVal = mockOfflineCompiler.build(); retVal = mockOfflineCompiler.build();
@@ -3161,7 +3193,7 @@ TEST(OfflineCompilerTest, givenIntermediateRepresentationInputWhenBuildSourceCod
EXPECT_FALSE(mockOfflineCompiler.isSpirV); EXPECT_FALSE(mockOfflineCompiler.isSpirV);
EXPECT_EQ(CL_SUCCESS, retVal); EXPECT_EQ(CL_SUCCESS, retVal);
ASSERT_EQ(1U, mockIgcOclDeviceCtx->requestedTranslationCtxs.size()); ASSERT_EQ(1U, mockIgcOclDeviceCtx->requestedTranslationCtxs.size());
expectedTranslation = {IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin}; NEO::MockIgcOclDeviceCtx::TranslationOpT expectedTranslation = {IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin};
ASSERT_EQ(expectedTranslation, mockIgcOclDeviceCtx->requestedTranslationCtxs[0]); ASSERT_EQ(expectedTranslation, mockIgcOclDeviceCtx->requestedTranslationCtxs[0]);
} }

View File

@@ -579,8 +579,17 @@ int OfflineCompiler::buildSourceCode() {
if (sourceCode.empty()) { if (sourceCode.empty()) {
return OCLOC_INVALID_PROGRAM; return OCLOC_INVALID_PROGRAM;
} }
auto inputTypeWarnings = validateInputType(sourceCode, inputFileLlvm, inputFileSpirV);
this->argHelper->printf(inputTypeWarnings.c_str());
bool inputIsIntermediateRepresentation = inputFileLlvm || inputFileSpirV; bool inputIsIntermediateRepresentation = inputFileLlvm || inputFileSpirV;
if (false == inputIsIntermediateRepresentation) { if (inputIsIntermediateRepresentation) {
storeBinary(irBinary, irBinarySize, sourceCode.c_str(), sourceCode.size());
auto asBitcode = ArrayRef<const uint8_t>::fromAny(irBinary, irBinarySize);
isSpirV = NEO::isSpirVBitcode(asBitcode);
pBuildInfo->intermediateRepresentation = isSpirV ? IGC::CodeType::spirV : IGC::CodeType::llvmBc;
} else {
retVal = buildIrBinary(); retVal = buildIrBinary();
if (retVal != OCLOC_SUCCESS) if (retVal != OCLOC_SUCCESS)
return retVal; return retVal;
@@ -589,26 +598,24 @@ int OfflineCompiler::buildSourceCode() {
const std::string igcRevision = igcFacade->getIgcRevision(); const std::string igcRevision = igcFacade->getIgcRevision();
const auto igcLibSize = igcFacade->getIgcLibSize(); const auto igcLibSize = igcFacade->getIgcLibSize();
const auto igcLibMTime = igcFacade->getIgcLibMTime(); const auto igcLibMTime = igcFacade->getIgcLibMTime();
const bool generateDebugInfo = CompilerOptions::contains(options, CompilerOptions::generateDebugInfo);
if (allowCaching) { if (allowCaching) {
genHash = cache->getCachedFileName(getHardwareInfo(), ArrayRef<const char>(irBinary, irBinarySize), options, internalOptions, ArrayRef<const char>(), ArrayRef<const char>(), igcRevision, igcLibSize, igcLibMTime); genHash = cache->getCachedFileName(getHardwareInfo(), ArrayRef<const char>(irBinary, irBinarySize), options, internalOptions, ArrayRef<const char>(), ArrayRef<const char>(), igcRevision, igcLibSize, igcLibMTime);
genBinary = cache->loadCachedBinary(genHash, genBinarySize).release();
const bool generateDebugInfo = CompilerOptions::contains(options, CompilerOptions::generateDebugInfo);
if (generateDebugInfo) { if (generateDebugInfo) {
dbgHash = cache->getCachedFileName(getHardwareInfo(), irHash, options, internalOptions, ArrayRef<const char>(), ArrayRef<const char>(), igcRevision, igcLibSize, igcLibMTime); dbgHash = cache->getCachedFileName(getHardwareInfo(), irHash, options, internalOptions, ArrayRef<const char>(), ArrayRef<const char>(), igcRevision, igcLibSize, igcLibMTime);
debugDataBinary = cache->loadCachedBinary(dbgHash, debugDataBinarySize).release();
} }
genBinary = cache->loadCachedBinary(genHash, genBinarySize).release();
if (genBinary) { if (genBinary) {
bool isZebin = isDeviceBinaryFormat<DeviceBinaryFormat::zebin>(ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(genBinary), genBinarySize)); bool isZebin = isDeviceBinaryFormat<DeviceBinaryFormat::zebin>(ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(genBinary), genBinarySize));
if (!generateDebugInfo || isZebin) {
auto asBitcode = ArrayRef<const uint8_t>::fromAny(irBinary, irBinarySize);
isSpirV = NEO::isSpirVBitcode(asBitcode);
if (!generateDebugInfo) {
return retVal; return retVal;
} else if (debugDataBinary || isZebin) { }
debugDataBinary = cache->loadCachedBinary(dbgHash, debugDataBinarySize).release();
if (debugDataBinary) {
return retVal; return retVal;
} }
} }
@@ -620,24 +627,13 @@ int OfflineCompiler::buildSourceCode() {
UNRECOVERABLE_IF(!igcFacade->isInitialized()); UNRECOVERABLE_IF(!igcFacade->isInitialized());
auto inputTypeWarnings = validateInputType(sourceCode, inputFileLlvm, inputFileSpirV); auto igcTranslationCtx = igcFacade->createTranslationContext(pBuildInfo->intermediateRepresentation, IGC::CodeType::oclGenBin);
this->argHelper->printf(inputTypeWarnings.c_str());
CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> igcOutput; auto igcSrc = igcFacade->createConstBuffer(irBinary, irBinarySize);
auto igcOptions = igcFacade->createConstBuffer(options.c_str(), options.size()); auto igcOptions = igcFacade->createConstBuffer(options.c_str(), options.size());
auto igcInternalOptions = igcFacade->createConstBuffer(internalOptions.c_str(), internalOptions.size()); auto igcInternalOptions = igcFacade->createConstBuffer(internalOptions.c_str(), internalOptions.size());
if (false == inputIsIntermediateRepresentation) { auto igcOutput = igcTranslationCtx->Translate(igcSrc.get(), igcOptions.get(), igcInternalOptions.get(), nullptr, 0);
auto igcTranslationCtx = igcFacade->createTranslationContext(pBuildInfo->intermediateRepresentation, IGC::CodeType::oclGenBin);
auto igcSrc = igcFacade->createConstBuffer(irBinary, irBinarySize);
igcOutput = igcTranslationCtx->Translate(igcSrc.get(), igcOptions.get(), igcInternalOptions.get(), nullptr, 0);
} else {
storeBinary(irBinary, irBinarySize, sourceCode.c_str(), sourceCode.size());
isSpirV = inputFileSpirV;
auto igcSrc = igcFacade->createConstBuffer(sourceCode.c_str(), sourceCode.size());
auto igcTranslationCtx = igcFacade->createTranslationContext(inputFileSpirV ? IGC::CodeType::spirV : IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin);
igcOutput = igcTranslationCtx->Translate(igcSrc.get(), igcOptions.get(), igcInternalOptions.get(), nullptr, 0);
}
if (igcOutput == nullptr) { if (igcOutput == nullptr) {
return OCLOC_OUT_OF_HOST_MEMORY; return OCLOC_OUT_OF_HOST_MEMORY;
} }