From 425dad30d0421e14f0297bc1597ccc7bc49d687d Mon Sep 17 00:00:00 2001 From: "Chodor, Jaroslaw" Date: Tue, 11 Jun 2019 22:50:45 +0200 Subject: [PATCH] Improving ocloc robustness * don't load FCL if not needed * don't fail because of patchtokens * print-out incompatible interfaces Change-Id: I9c06dc27aa4495a3cd103e7dedf1bb5dd411a5db --- offline_compiler/offline_compiler.cpp | 76 +++++++++++-------- unit_tests/mocks/mock_cif.h | 13 ++++ .../mock/mock_offline_compiler.h | 1 + .../offline_compiler_tests.cpp | 18 +++++ 4 files changed, 77 insertions(+), 31 deletions(-) diff --git a/offline_compiler/offline_compiler.cpp b/offline_compiler/offline_compiler.cpp index 4234bd0a26..29813e777a 100644 --- a/offline_compiler/offline_compiler.cpp +++ b/offline_compiler/offline_compiler.cpp @@ -124,12 +124,12 @@ int OfflineCompiler::buildSourceCode() { retVal = CL_INVALID_PROGRAM; break; } - UNRECOVERABLE_IF(fclDeviceCtx == nullptr); UNRECOVERABLE_IF(igcDeviceCtx == nullptr); CIF::RAII::UPtr_t igcOutput; bool inputIsIntermediateRepresentation = inputFileLlvm || inputFileSpirV; if (false == inputIsIntermediateRepresentation) { + UNRECOVERABLE_IF(fclDeviceCtx == nullptr); IGC::CodeType::CodeType_t intermediateRepresentation = useLlvmText ? IGC::CodeType::llvmLl : preferredIntermediateRepresentation; // sourceCode.size() returns the number of characters without null terminated char auto fclSrc = CIF::Builtins::CreateConstBuffer(fclMain.get(), sourceCode.c_str(), sourceCode.size() + 1); @@ -333,40 +333,47 @@ int OfflineCompiler::initialize(size_t numArgs, const std::vector & sourceCode = (pSource != nullptr) ? getStringWithinDelimiters((char *)pSourceFromFile) : (char *)pSourceFromFile; } - auto fclLibFile = OsLibrary::load(Os::frontEndDllName); - if (fclLibFile == nullptr) { - printf("Error: Failed to load %s\n", Os::frontEndDllName); - return CL_OUT_OF_HOST_MEMORY; - } + if ((inputFileSpirV == false) && (inputFileLlvm == false)) { + auto fclLibFile = OsLibrary::load(Os::frontEndDllName); + if (fclLibFile == nullptr) { + printf("Error: Failed to load %s\n", Os::frontEndDllName); + return CL_OUT_OF_HOST_MEMORY; + } - this->fclLib.reset(fclLibFile); - if (this->fclLib == nullptr) { - return CL_OUT_OF_HOST_MEMORY; - } + this->fclLib.reset(fclLibFile); + if (this->fclLib == nullptr) { + return CL_OUT_OF_HOST_MEMORY; + } - auto fclCreateMain = reinterpret_cast(this->fclLib->getProcAddress(CIF::CreateCIFMainFuncName)); - if (fclCreateMain == nullptr) { - return CL_OUT_OF_HOST_MEMORY; - } + auto fclCreateMain = reinterpret_cast(this->fclLib->getProcAddress(CIF::CreateCIFMainFuncName)); + if (fclCreateMain == nullptr) { + return CL_OUT_OF_HOST_MEMORY; + } - this->fclMain = CIF::RAII::UPtr(createMainNoSanitize(fclCreateMain)); - if (this->fclMain == nullptr) { - return CL_OUT_OF_HOST_MEMORY; - } + this->fclMain = CIF::RAII::UPtr(createMainNoSanitize(fclCreateMain)); + if (this->fclMain == nullptr) { + return CL_OUT_OF_HOST_MEMORY; + } - if (false == this->fclMain->IsCompatible()) { - // given FCL is not compatible - DEBUG_BREAK_IF(true); - return CL_OUT_OF_HOST_MEMORY; - } + if (false == this->fclMain->IsCompatible()) { + printf("Incompatible interface in FCL : %s\n", CIF::InterfaceIdCoder::Dec(this->fclMain->FindIncompatible()).c_str()); + DEBUG_BREAK_IF(true); + return CL_OUT_OF_HOST_MEMORY; + } - this->fclDeviceCtx = this->fclMain->CreateInterface(); - if (this->fclDeviceCtx == nullptr) { - return CL_OUT_OF_HOST_MEMORY; - } + this->fclDeviceCtx = this->fclMain->CreateInterface(); + if (this->fclDeviceCtx == nullptr) { + return CL_OUT_OF_HOST_MEMORY; + } - fclDeviceCtx->SetOclApiVersion(hwInfo->capabilityTable.clVersionSupport * 10); - preferredIntermediateRepresentation = fclDeviceCtx->GetPreferredIntermediateRepresentation(); + fclDeviceCtx->SetOclApiVersion(hwInfo->capabilityTable.clVersionSupport * 10); + preferredIntermediateRepresentation = fclDeviceCtx->GetPreferredIntermediateRepresentation(); + } else { + if (!isQuiet()) { + printf("Compilation from IR - skipping loading of FCL\n"); + } + preferredIntermediateRepresentation = IGC::CodeType::spirV; + } this->igcLib.reset(OsLibrary::load(Os::igcDllName)); if (this->igcLib == nullptr) { @@ -383,12 +390,19 @@ int OfflineCompiler::initialize(size_t numArgs, const std::vector & return CL_OUT_OF_HOST_MEMORY; } - if (false == this->igcMain->IsCompatible()) { - // given IGC is not compatible + std::vector interfacesToIgnore = {IGC::OclGenBinaryBase::GetInterfaceId()}; + if (false == this->igcMain->IsCompatible(&interfacesToIgnore)) { + printf("Incompatible interface in IGC : %s\n", CIF::InterfaceIdCoder::Dec(this->igcMain->FindIncompatible(&interfacesToIgnore)).c_str()); DEBUG_BREAK_IF(true); return CL_OUT_OF_HOST_MEMORY; } + CIF::Version_t verMin = 0, verMax = 0; + if (false == this->igcMain->FindSupportedVersions(IGC::OclGenBinaryBase::GetInterfaceId(), verMin, verMax)) { + printf("Patchtoken interface is missing"); + return CL_OUT_OF_HOST_MEMORY; + } + this->igcDeviceCtx = this->igcMain->CreateInterface(); if (this->igcDeviceCtx == nullptr) { return CL_OUT_OF_HOST_MEMORY; diff --git a/unit_tests/mocks/mock_cif.h b/unit_tests/mocks/mock_cif.h index 66e326c0a2..bbb41281fb 100644 --- a/unit_tests/mocks/mock_cif.h +++ b/unit_tests/mocks/mock_cif.h @@ -113,6 +113,19 @@ struct MockCIFMain : MockCIF { return entryPointInterface; } + bool FindSupportedVersionsImpl(CIF::InterfaceId_t entryPointInterface, CIF::InterfaceId_t interfaceToFind, CIF::Version_t &verMin, CIF::Version_t &verMax) const override { + if (globalCreators.find(entryPointInterface) != globalCreators.end()) { + verMin = verMax = 1; + return true; + } + if (defaultCreators.find(entryPointInterface) != defaultCreators.end()) { + verMin = verMax = 1; + return true; + } + + return false; + } + std::map defaultCreators; }; diff --git a/unit_tests/offline_compiler/mock/mock_offline_compiler.h b/unit_tests/offline_compiler/mock/mock_offline_compiler.h index ab6104dee6..0ac15c92f1 100644 --- a/unit_tests/offline_compiler/mock/mock_offline_compiler.h +++ b/unit_tests/offline_compiler/mock/mock_offline_compiler.h @@ -15,6 +15,7 @@ namespace NEO { class MockOfflineCompiler : public OfflineCompiler { public: using OfflineCompiler::deviceName; + using OfflineCompiler::fclDeviceCtx; using OfflineCompiler::generateFilePathForIr; using OfflineCompiler::generateOptsSuffix; using OfflineCompiler::igcDeviceCtx; diff --git a/unit_tests/offline_compiler/offline_compiler_tests.cpp b/unit_tests/offline_compiler/offline_compiler_tests.cpp index c2ac57d146..5b331891c6 100644 --- a/unit_tests/offline_compiler/offline_compiler_tests.cpp +++ b/unit_tests/offline_compiler/offline_compiler_tests.cpp @@ -246,6 +246,7 @@ TEST_F(OfflineCompilerTests, GoodBuildTest) { delete pOfflineCompiler; } + TEST_F(OfflineCompilerTests, GoodBuildTestWithLlvmText) { std::vector argv = { "ocloc", @@ -268,6 +269,23 @@ TEST_F(OfflineCompilerTests, GoodBuildTestWithLlvmText) { delete pOfflineCompiler; } + +TEST_F(OfflineCompilerTests, WhenFclNotNeededDontLoadIt) { + std::vector argv = { + "ocloc", + "-file", + "test_files/copybuffer.cl", + "-device", + gEnvironment->devicePrefix.c_str(), + "-spirv_input"}; + + MockOfflineCompiler offlineCompiler; + auto ret = offlineCompiler.initialize(argv.size(), argv); + EXPECT_EQ(0, ret); + EXPECT_EQ(nullptr, offlineCompiler.fclDeviceCtx); + EXPECT_NE(nullptr, offlineCompiler.igcDeviceCtx); +} + TEST_F(OfflineCompilerTests, GoodParseBinToCharArray) { std::vector argv = { "ocloc",