diff --git a/opencl/test/unit_test/offline_compiler/CMakeLists.txt b/opencl/test/unit_test/offline_compiler/CMakeLists.txt index 98a6947fc5..74719f8ba2 100644 --- a/opencl/test/unit_test/offline_compiler/CMakeLists.txt +++ b/opencl/test/unit_test/offline_compiler/CMakeLists.txt @@ -20,6 +20,7 @@ set(IGDRCL_SRCS_offline_compiler_mock ${CMAKE_CURRENT_SOURCE_DIR}/decoder/mock/mock_iga_wrapper.h ${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_argument_helper.h ${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_multi_command.h + ${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_ocloc_igc_facade.h ${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_offline_compiler.h ${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_offline_linker.h ${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_sip_ocloc_tests.cpp @@ -57,6 +58,8 @@ set(IGDRCL_SRCS_offline_compiler_tests ${CMAKE_CURRENT_SOURCE_DIR}/ocloc_api_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ocloc_fatbinary_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ocloc_fatbinary_tests.h + ${CMAKE_CURRENT_SOURCE_DIR}/ocloc_igc_facade_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/ocloc_igc_facade_tests.h ${CMAKE_CURRENT_SOURCE_DIR}/ocloc_product_config_tests.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ocloc_product_config_tests.h ${CMAKE_CURRENT_SOURCE_DIR}/ocloc_tests_configuration.cpp diff --git a/opencl/test/unit_test/offline_compiler/mock/mock_ocloc_igc_facade.h b/opencl/test/unit_test/offline_compiler/mock/mock_ocloc_igc_facade.h new file mode 100644 index 0000000000..4d59bb5339 --- /dev/null +++ b/opencl/test/unit_test/offline_compiler/mock/mock_ocloc_igc_facade.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/offline_compiler/source/ocloc_igc_facade.h" + +#include +#include + +namespace NEO { + +class MockOclocIgcFacade : public OclocIgcFacade { + public: + using OclocIgcFacade::igcDeviceCtx; + + bool shouldFailLoadingOfIgcLib{false}; + bool shouldFailLoadingOfIgcCreateMainFunction{false}; + bool shouldFailCreationOfIgcMain{false}; + bool shouldFailCreationOfIgcDeviceContext{false}; + bool shouldReturnInvalidIgcPlatformHandle{false}; + bool shouldReturnInvalidGTSystemInfoHandle{false}; + bool shouldReturnInvalidIgcFeaturesAndWorkaroundsHandle{false}; + std::optional isIgcInterfaceCompatibleReturnValue{}; + std::optional getIncompatibleInterfaceReturnValue{}; + std::optional isPatchtokenInterfaceSupportedReturnValue{}; + + MockOclocIgcFacade(OclocArgHelper *argHelper) : OclocIgcFacade{argHelper} {} + ~MockOclocIgcFacade() override = default; + + std::unique_ptr loadIgcLibrary() const override { + if (shouldFailLoadingOfIgcLib) { + return nullptr; + } else { + return OclocIgcFacade::loadIgcLibrary(); + } + } + + CIF::CreateCIFMainFunc_t loadCreateIgcMainFunction() const override { + if (shouldFailLoadingOfIgcCreateMainFunction) { + return nullptr; + } else { + return OclocIgcFacade::loadCreateIgcMainFunction(); + } + } + + CIF::RAII::UPtr_t createIgcMain(CIF::CreateCIFMainFunc_t createMainFunction) const override { + if (shouldFailCreationOfIgcMain) { + return nullptr; + } else { + return OclocIgcFacade::createIgcMain(createMainFunction); + } + } + + bool isIgcInterfaceCompatible(const std::vector &interfacesToIgnore) const override { + if (isIgcInterfaceCompatibleReturnValue.has_value()) { + return *isIgcInterfaceCompatibleReturnValue; + } else { + return OclocIgcFacade::isIgcInterfaceCompatible(interfacesToIgnore); + } + } + + std::string getIncompatibleInterface(const std::vector &interfacesToIgnore) const override { + if (getIncompatibleInterfaceReturnValue.has_value()) { + return *getIncompatibleInterfaceReturnValue; + } else { + return OclocIgcFacade::getIncompatibleInterface(interfacesToIgnore); + } + } + + bool isPatchtokenInterfaceSupported() const override { + if (isPatchtokenInterfaceSupportedReturnValue.has_value()) { + return *isPatchtokenInterfaceSupportedReturnValue; + } else { + return OclocIgcFacade::isPatchtokenInterfaceSupported(); + } + } + + CIF::RAII::UPtr_t createIgcDeviceContext() const override { + if (shouldFailCreationOfIgcDeviceContext) { + return nullptr; + } else { + return OclocIgcFacade::createIgcDeviceContext(); + } + } + + CIF::RAII::UPtr_t getIgcPlatformHandle() const override { + if (shouldReturnInvalidIgcPlatformHandle) { + return nullptr; + } else { + return OclocIgcFacade::getIgcPlatformHandle(); + } + } + + CIF::RAII::UPtr_t getGTSystemInfoHandle() const override { + if (shouldReturnInvalidGTSystemInfoHandle) { + return nullptr; + } else { + return OclocIgcFacade::getGTSystemInfoHandle(); + } + } + + CIF::RAII::UPtr_t getIgcFeaturesAndWorkaroundsHandle() const override { + if (shouldReturnInvalidIgcFeaturesAndWorkaroundsHandle) { + return nullptr; + } else { + return OclocIgcFacade::getIgcFeaturesAndWorkaroundsHandle(); + } + } +}; + +} // namespace NEO \ No newline at end of file diff --git a/opencl/test/unit_test/offline_compiler/mock/mock_offline_compiler.h b/opencl/test/unit_test/offline_compiler/mock/mock_offline_compiler.h index d2264a679f..498d2b6f6c 100644 --- a/opencl/test/unit_test/offline_compiler/mock/mock_offline_compiler.h +++ b/opencl/test/unit_test/offline_compiler/mock/mock_offline_compiler.h @@ -10,6 +10,7 @@ #include "shared/offline_compiler/source/offline_compiler.h" #include "opencl/test/unit_test/offline_compiler/mock/mock_argument_helper.h" +#include "opencl/test/unit_test/offline_compiler/mock/mock_ocloc_igc_facade.h" #include #include @@ -32,7 +33,7 @@ class MockOfflineCompiler : public OfflineCompiler { using OfflineCompiler::generateOptsSuffix; using OfflineCompiler::getStringWithinDelimiters; using OfflineCompiler::hwInfo; - using OfflineCompiler::igcDeviceCtx; + using OfflineCompiler::igcFacade; using OfflineCompiler::initHardwareInfo; using OfflineCompiler::inputFile; using OfflineCompiler::inputFileLlvm; @@ -60,7 +61,12 @@ class MockOfflineCompiler : public OfflineCompiler { uniqueHelper = std::make_unique(filesMap); uniqueHelper->setAllCallBase(true); argHelper = uniqueHelper.get(); + + auto uniqueIgcFacadeMock = std::make_unique(argHelper); + mockIgcFacade = uniqueIgcFacadeMock.get(); + igcFacade = std::move(uniqueIgcFacadeMock); } + ~MockOfflineCompiler() override = default; int initialize(size_t numArgs, const std::vector &argv) { @@ -118,6 +124,7 @@ class MockOfflineCompiler : public OfflineCompiler { uint32_t generateElfBinaryCalled = 0u; uint32_t writeOutAllFilesCalled = 0u; std::unique_ptr uniqueHelper; + MockOclocIgcFacade *mockIgcFacade = nullptr; int buildCalledCount{0}; std::optional buildReturnValue{}; bool interceptCreatedDirs{false}; diff --git a/opencl/test/unit_test/offline_compiler/mock/mock_offline_linker.h b/opencl/test/unit_test/offline_compiler/mock/mock_offline_linker.h index 14a464c23b..c950eb65d3 100644 --- a/opencl/test/unit_test/offline_compiler/mock/mock_offline_linker.h +++ b/opencl/test/unit_test/offline_compiler/mock/mock_offline_linker.h @@ -20,7 +20,6 @@ class MockOfflineLinker : public OfflineLinker { using OfflineLinker::initialize; using OfflineLinker::loadInputFilesContent; using OfflineLinker::parseCommand; - using OfflineLinker::prepareIgc; using OfflineLinker::tryToStoreBuildLog; using OfflineLinker::verifyLinkerCommand; @@ -34,14 +33,9 @@ class MockOfflineLinker : public OfflineLinker { using OfflineLinker::outputFormat; bool shouldReturnEmptyHardwareInfoTable{false}; - bool shouldFailLoadingOfIgcLib{false}; - bool shouldFailLoadingOfIgcCreateMainFunction{false}; - bool shouldFailCreationOfIgcMain{false}; - bool shouldFailCreationOfIgcDeviceContext{false}; - bool shouldReturnInvalidIgcPlatformHandle{false}; - bool shouldReturnInvalidGTSystemInfoHandle{false}; - MockOfflineLinker(OclocArgHelper *argHelper) : OfflineLinker{argHelper} {} + MockOfflineLinker(OclocArgHelper *argHelper, std::unique_ptr igcFacade) + : OfflineLinker{argHelper, std::move(igcFacade)} {} ArrayRef getHardwareInfoTable() const override { if (shouldReturnEmptyHardwareInfoTable) { @@ -50,54 +44,6 @@ class MockOfflineLinker : public OfflineLinker { return OfflineLinker::getHardwareInfoTable(); } } - - std::unique_ptr loadIgcLibrary() const override { - if (shouldFailLoadingOfIgcLib) { - return nullptr; - } else { - return OfflineLinker::loadIgcLibrary(); - } - } - - CIF::CreateCIFMainFunc_t loadCreateIgcMainFunction() const override { - if (shouldFailLoadingOfIgcCreateMainFunction) { - return nullptr; - } else { - return OfflineLinker::loadCreateIgcMainFunction(); - } - } - - CIF::RAII::UPtr_t createIgcMain(CIF::CreateCIFMainFunc_t createMainFunction) const override { - if (shouldFailCreationOfIgcMain) { - return nullptr; - } else { - return OfflineLinker::createIgcMain(createMainFunction); - } - } - - CIF::RAII::UPtr_t createIgcDeviceContext() const override { - if (shouldFailCreationOfIgcDeviceContext) { - return nullptr; - } else { - return OfflineLinker::createIgcDeviceContext(); - } - } - - CIF::RAII::UPtr_t getIgcPlatformHandle() const override { - if (shouldReturnInvalidIgcPlatformHandle) { - return nullptr; - } else { - return OfflineLinker::getIgcPlatformHandle(); - } - } - - CIF::RAII::UPtr_t getGTSystemInfoHandle() const override { - if (shouldReturnInvalidGTSystemInfoHandle) { - return nullptr; - } else { - return OfflineLinker::getGTSystemInfoHandle(); - } - } }; } // namespace NEO \ No newline at end of file diff --git a/opencl/test/unit_test/offline_compiler/ocloc_igc_facade_tests.cpp b/opencl/test/unit_test/offline_compiler/ocloc_igc_facade_tests.cpp new file mode 100644 index 0000000000..27ad5c742a --- /dev/null +++ b/opencl/test/unit_test/offline_compiler/ocloc_igc_facade_tests.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "ocloc_igc_facade_tests.h" + +#include "shared/offline_compiler/source/ocloc_error_code.h" +#include "shared/source/debug_settings/debug_settings_manager.h" +#include "shared/source/os_interface/os_inc_base.h" +#include "shared/test/common/helpers/debug_manager_state_restore.h" + +#include "mock/mock_ocloc_igc_facade.h" + +#include + +namespace NEO { + +TEST_F(OclocIgcFacadeTest, GivenMissingIgcLibraryWhenPreparingIgcThenFailureIsReported) { + MockOclocIgcFacade mockIgcFacade{&mockArgHelper}; + mockIgcFacade.shouldFailLoadingOfIgcLib = true; + + ::testing::internal::CaptureStdout(); + const auto igcPreparationResult{mockIgcFacade.initialize(hwInfo)}; + const auto output{::testing::internal::GetCapturedStdout()}; + + EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, igcPreparationResult); + EXPECT_FALSE(mockIgcFacade.isInitialized()); + + std::stringstream expectedErrorMessage; + expectedErrorMessage << "Error! Loading of IGC library has failed! Filename: " << Os::igcDllName << "\n"; + + EXPECT_EQ(expectedErrorMessage.str(), output); +} + +TEST_F(OclocIgcFacadeTest, GivenFailingLoadingOfIgcSymbolsWhenPreparingIgcThenFailureIsReported) { + MockOclocIgcFacade mockIgcFacade{&mockArgHelper}; + mockIgcFacade.shouldFailLoadingOfIgcCreateMainFunction = true; + + ::testing::internal::CaptureStdout(); + const auto igcPreparationResult{mockIgcFacade.initialize(hwInfo)}; + const auto output{::testing::internal::GetCapturedStdout()}; + + EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, igcPreparationResult); + EXPECT_FALSE(mockIgcFacade.isInitialized()); + + const std::string expectedErrorMessage{"Error! Cannot load required functions from IGC library.\n"}; + EXPECT_EQ(expectedErrorMessage, output); +} + +TEST_F(OclocIgcFacadeTest, GivenFailingCreationOfIgcMainWhenPreparingIgcThenFailureIsReported) { + MockOclocIgcFacade mockIgcFacade{&mockArgHelper}; + mockIgcFacade.shouldFailCreationOfIgcMain = true; + + ::testing::internal::CaptureStdout(); + const auto igcPreparationResult{mockIgcFacade.initialize(hwInfo)}; + const auto output{::testing::internal::GetCapturedStdout()}; + + EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, igcPreparationResult); + EXPECT_FALSE(mockIgcFacade.isInitialized()); + + const std::string expectedErrorMessage{"Error! Cannot create IGC main component!\n"}; + EXPECT_EQ(expectedErrorMessage, output); +} + +TEST_F(OclocIgcFacadeTest, GivenIncompatibleIgcInterfacesWhenPreparingIgcThenFailureIsReported) { + DebugManagerStateRestore stateRestore; + DebugManager.flags.EnableDebugBreak.set(false); + + MockOclocIgcFacade mockIgcFacade{&mockArgHelper}; + mockIgcFacade.isIgcInterfaceCompatibleReturnValue = false; + mockIgcFacade.getIncompatibleInterfaceReturnValue = "SomeImportantInterface"; + + ::testing::internal::CaptureStdout(); + const auto igcPreparationResult{mockIgcFacade.initialize(hwInfo)}; + const auto output{::testing::internal::GetCapturedStdout()}; + + EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, igcPreparationResult); + EXPECT_FALSE(mockIgcFacade.isInitialized()); + + const std::string expectedErrorMessage{"Error! Incompatible interface in IGC: SomeImportantInterface\n"}; + EXPECT_EQ(expectedErrorMessage, output); +} + +TEST_F(OclocIgcFacadeTest, GivenMissingPatchtokenInterfaceWhenPreparingIgcThenFailureIsReported) { + MockOclocIgcFacade mockIgcFacade{&mockArgHelper}; + mockIgcFacade.isPatchtokenInterfaceSupportedReturnValue = false; + + ::testing::internal::CaptureStdout(); + const auto igcPreparationResult{mockIgcFacade.initialize(hwInfo)}; + const auto output{::testing::internal::GetCapturedStdout()}; + + EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, igcPreparationResult); + EXPECT_FALSE(mockIgcFacade.isInitialized()); + + const std::string expectedErrorMessage{"Error! Patchtoken interface is missing.\n"}; + EXPECT_EQ(expectedErrorMessage, output); +} + +TEST_F(OclocIgcFacadeTest, GivenFailingCreationOfIgcDeviceContextWhenPreparingIgcThenFailureIsReported) { + MockOclocIgcFacade mockIgcFacade{&mockArgHelper}; + mockIgcFacade.shouldFailCreationOfIgcDeviceContext = true; + + ::testing::internal::CaptureStdout(); + const auto igcPreparationResult{mockIgcFacade.initialize(hwInfo)}; + const auto output{::testing::internal::GetCapturedStdout()}; + + EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, igcPreparationResult); + EXPECT_FALSE(mockIgcFacade.isInitialized()); + + const std::string expectedErrorMessage{"Error! Cannot create IGC device context!\n"}; + EXPECT_EQ(expectedErrorMessage, output); +} + +TEST_F(OclocIgcFacadeTest, GivenInvalidIgcDeviceContextWhenPreparingIgcThenFailureIsReported) { + constexpr std::array invalidReturnFlags = { + &MockOclocIgcFacade::shouldReturnInvalidIgcPlatformHandle, + &MockOclocIgcFacade::shouldReturnInvalidGTSystemInfoHandle, + &MockOclocIgcFacade::shouldReturnInvalidIgcFeaturesAndWorkaroundsHandle}; + + for (const auto &invalidReturnFlag : invalidReturnFlags) { + MockOclocIgcFacade mockIgcFacade{&mockArgHelper}; + mockIgcFacade.*invalidReturnFlag = true; + + ::testing::internal::CaptureStdout(); + const auto igcPreparationResult{mockIgcFacade.initialize(hwInfo)}; + const auto output{::testing::internal::GetCapturedStdout()}; + + EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, igcPreparationResult); + EXPECT_FALSE(mockIgcFacade.isInitialized()); + + const std::string expectedErrorMessage{"Error! IGC device context has not been properly created!\n"}; + EXPECT_EQ(expectedErrorMessage, output); + } +} + +TEST_F(OclocIgcFacadeTest, GivenNoneErrorsSetWhenPreparingIgcThenSuccessIsReported) { + MockOclocIgcFacade mockIgcFacade{&mockArgHelper}; + + ::testing::internal::CaptureStdout(); + const auto igcPreparationResult{mockIgcFacade.initialize(hwInfo)}; + const auto output{::testing::internal::GetCapturedStdout()}; + + EXPECT_EQ(OclocErrorCode::SUCCESS, igcPreparationResult); + EXPECT_TRUE(output.empty()) << output; + EXPECT_TRUE(mockIgcFacade.isInitialized()); +} + +TEST_F(OclocIgcFacadeTest, GivenInitializedIgcWhenGettingIncompatibleInterfaceThenEmptyStringIsReturned) { + MockOclocIgcFacade mockIgcFacade{&mockArgHelper}; + + ::testing::internal::CaptureStdout(); + const auto igcPreparationResult{mockIgcFacade.initialize(hwInfo)}; + const auto output{::testing::internal::GetCapturedStdout()}; + + ASSERT_EQ(OclocErrorCode::SUCCESS, igcPreparationResult); + + const std::vector interfacesToIgnore{}; + const auto incompatibleInterface = mockIgcFacade.getIncompatibleInterface(interfacesToIgnore); + + EXPECT_TRUE(incompatibleInterface.empty()) << incompatibleInterface; +} + +} // namespace NEO \ No newline at end of file diff --git a/opencl/test/unit_test/offline_compiler/ocloc_igc_facade_tests.h b/opencl/test/unit_test/offline_compiler/ocloc_igc_facade_tests.h new file mode 100644 index 0000000000..1c5ac38355 --- /dev/null +++ b/opencl/test/unit_test/offline_compiler/ocloc_igc_facade_tests.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "shared/source/helpers/hw_info.h" + +#include "gtest/gtest.h" +#include "mock/mock_argument_helper.h" + +namespace NEO { + +class OclocIgcFacadeTest : public ::testing::Test { + protected: + MockOclocArgHelper::FilesMap mockArgHelperFilesMap{}; + MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap}; + HardwareInfo hwInfo{}; +}; + +} // namespace NEO \ No newline at end of file diff --git a/opencl/test/unit_test/offline_compiler/offline_compiler_tests.cpp b/opencl/test/unit_test/offline_compiler/offline_compiler_tests.cpp index 201f726fd0..b90e9ba1ba 100644 --- a/opencl/test/unit_test/offline_compiler/offline_compiler_tests.cpp +++ b/opencl/test/unit_test/offline_compiler/offline_compiler_tests.cpp @@ -956,6 +956,29 @@ TEST_F(OfflineCompilerTests, givenExcludeIrFromZebinInternalOptionWhenInitIsPerf EXPECT_TRUE(mockOfflineCompiler.excludeIr); } +TEST_F(OfflineCompilerTests, givenValidArgumentsAndIgcInitFailureWhenInitIsPerformedThenFailureIsPropagatedAndErrorIsPrinted) { + std::vector argv = { + "ocloc", + "-file", + "test_files/copybuffer.cl", + "-device", + gEnvironment->devicePrefix.c_str()}; + + MockOfflineCompiler mockOfflineCompiler{}; + mockOfflineCompiler.mockIgcFacade->shouldFailLoadingOfIgcLib = true; + + testing::internal::CaptureStdout(); + const auto initResult = mockOfflineCompiler.initialize(argv.size(), argv); + const auto output = testing::internal::GetCapturedStdout(); + + std::stringstream expectedErrorMessage; + expectedErrorMessage << "Error! Loading of IGC library has failed! Filename: " << Os::igcDllName << "\n" + << "Error! IGC initialization failure. Error code = -6\n"; + + EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, initResult); + EXPECT_EQ(expectedErrorMessage.str(), output); +} + TEST_F(OfflineCompilerTests, givenExcludeIrArgumentWhenInitIsPerformedThenIrExcludeFlagsShouldBeUnified) { std::vector argv = { "ocloc", @@ -1333,7 +1356,7 @@ TEST_F(OfflineCompilerTests, WhenFclNotNeededThenDontLoadIt) { auto ret = offlineCompiler.initialize(argv.size(), argv); EXPECT_EQ(0, ret); EXPECT_EQ(nullptr, offlineCompiler.fclDeviceCtx); - EXPECT_NE(nullptr, offlineCompiler.igcDeviceCtx); + EXPECT_TRUE(offlineCompiler.igcFacade->isInitialized()); } TEST_F(OfflineCompilerTests, WhenParsingBinToCharArrayThenCorrectResult) { @@ -1981,7 +2004,7 @@ TEST(OfflineCompilerTest, givenIntermediateRepresentationInputWhenBuildSourceCod testing::internal::CaptureStdout(); auto retVal = mockOfflineCompiler.initialize(argv.size(), argv); auto mockIgcOclDeviceCtx = new NEO::MockIgcOclDeviceCtx(); - mockOfflineCompiler.igcDeviceCtx = CIF::RAII::Pack(mockIgcOclDeviceCtx); + mockOfflineCompiler.mockIgcFacade->igcDeviceCtx = CIF::RAII::Pack(mockIgcOclDeviceCtx); ASSERT_EQ(CL_SUCCESS, retVal); mockOfflineCompiler.inputFileSpirV = true; @@ -2067,7 +2090,7 @@ TEST(OfflineCompilerTest, givenSpirvInputFileWhenCmdLineHasOptionsThenCorrectOpt auto retVal = mockOfflineCompiler.initialize(argv.size(), argv); auto mockIgcOclDeviceCtx = new NEO::MockIgcOclDeviceCtx(); - mockOfflineCompiler.igcDeviceCtx = CIF::RAII::Pack(mockIgcOclDeviceCtx); + mockOfflineCompiler.mockIgcFacade->igcDeviceCtx = CIF::RAII::Pack(mockIgcOclDeviceCtx); ASSERT_EQ(CL_SUCCESS, retVal); mockOfflineCompiler.inputFileSpirV = true; diff --git a/opencl/test/unit_test/offline_compiler/offline_linker_tests.cpp b/opencl/test/unit_test/offline_compiler/offline_linker_tests.cpp index e8a9c43cc5..04055c6653 100644 --- a/opencl/test/unit_test/offline_compiler/offline_linker_tests.cpp +++ b/opencl/test/unit_test/offline_compiler/offline_linker_tests.cpp @@ -65,7 +65,7 @@ MockOfflineLinker::InputFileContent OfflineLinkerTest::createFileContent(const s } TEST_F(OfflineLinkerTest, GivenDefaultConstructedLinkerThenRequiredFieldsHaveDefaultValues) { - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; EXPECT_EQ(OperationMode::SKIP_EXECUTION, mockOfflineLinker.operationMode); EXPECT_EQ("linker_output", mockOfflineLinker.outputFilename); @@ -76,7 +76,7 @@ TEST_F(OfflineLinkerTest, GivenLessThanTwoArgumentsWhenParsingThenInvalidCommand const std::vector argv = { "ocloc.exe"}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; const auto result = mockOfflineLinker.parseCommand(argv.size(), argv); EXPECT_EQ(OclocErrorCode::INVALID_COMMAND_LINE, result); } @@ -93,7 +93,7 @@ TEST_F(OfflineLinkerTest, GivenInputFilesArgumentsWhenParsingThenListOfFilenames "-file", secondFile}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; const auto result = mockOfflineLinker.parseCommand(argv.size(), argv); ASSERT_EQ(OclocErrorCode::SUCCESS, result); @@ -112,7 +112,7 @@ TEST_F(OfflineLinkerTest, GivenOutputFilenameArgumentWhenParsingThenOutputFilena "-out", outputFilename}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; const auto result = mockOfflineLinker.parseCommand(argv.size(), argv); ASSERT_EQ(OclocErrorCode::SUCCESS, result); @@ -126,7 +126,7 @@ TEST_F(OfflineLinkerTest, GivenValidOutputFileFormatWhenParsingThenOutputFormatI "-out_format", "LLVM_BC"}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; const auto result = mockOfflineLinker.parseCommand(argv.size(), argv); ASSERT_EQ(OclocErrorCode::SUCCESS, result); @@ -140,7 +140,7 @@ TEST_F(OfflineLinkerTest, GivenUnknownOutputFileFormatWhenParsingThenInvalidForm "-out_format", "StrangeFormat"}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; const auto result = mockOfflineLinker.parseCommand(argv.size(), argv); ASSERT_EQ(OclocErrorCode::SUCCESS, result); @@ -156,7 +156,7 @@ TEST_F(OfflineLinkerTest, GivenOptionsArgumentWhenParsingThenOptionsAreSet) { "-options", options}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; const auto result = mockOfflineLinker.parseCommand(argv.size(), argv); ASSERT_EQ(OclocErrorCode::SUCCESS, result); @@ -172,7 +172,7 @@ TEST_F(OfflineLinkerTest, GivenInternalOptionsArgumentWhenParsingThenInternalOpt "-internal_options", internalOptions}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; const auto result = mockOfflineLinker.parseCommand(argv.size(), argv); ASSERT_EQ(OclocErrorCode::SUCCESS, result); @@ -185,7 +185,7 @@ TEST_F(OfflineLinkerTest, GivenHelpArgumentWhenParsingThenShowHelpOperationIsSet "link", "--help"}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; const auto result = mockOfflineLinker.parseCommand(argv.size(), argv); ASSERT_EQ(OclocErrorCode::SUCCESS, result); @@ -199,7 +199,7 @@ TEST_F(OfflineLinkerTest, GivenUnknownArgumentWhenParsingThenErrorIsReported) { "-some_new_unknown_command"}; ::testing::internal::CaptureStdout(); - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; const auto result = mockOfflineLinker.initialize(argv.size(), argv); const auto output{::testing::internal::GetCapturedStdout()}; @@ -219,7 +219,8 @@ TEST_F(OfflineLinkerTest, GivenFlagsWhichRequireMoreArgsWithoutThemWhenParsingTh "link", flag}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + mockOclocIgcFacade = std::make_unique(&mockArgHelper); + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; ::testing::internal::CaptureStdout(); const auto result = mockOfflineLinker.parseCommand(argv.size(), argv); @@ -233,7 +234,7 @@ TEST_F(OfflineLinkerTest, GivenFlagsWhichRequireMoreArgsWithoutThemWhenParsingTh } TEST_F(OfflineLinkerTest, GivenCommandWithoutInputFilesWhenVerificationIsPerformedThenErrorIsReturned) { - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; mockOfflineLinker.inputFilenames = {}; ::testing::internal::CaptureStdout(); @@ -253,7 +254,7 @@ TEST_F(OfflineLinkerTest, GivenCommandWithEmptyFilenameWhenVerificationIsPerform "-file", ""}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; ::testing::internal::CaptureStdout(); const auto verificationResult = mockOfflineLinker.initialize(argv.size(), argv); @@ -274,7 +275,7 @@ TEST_F(OfflineLinkerTest, GivenCommandWithNonexistentInputFileWhenVerificationIs "-file", "some_file2.spv"}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; const auto parsingResult = mockOfflineLinker.parseCommand(argv.size(), argv); ASSERT_EQ(OclocErrorCode::SUCCESS, parsingResult); @@ -299,7 +300,7 @@ TEST_F(OfflineLinkerTest, GivenCommandWithInvalidOutputFormatWhenVerificationIsP "-out_format", "SomeDummyUnknownFormat"}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; const auto parsingResult = mockOfflineLinker.parseCommand(argv.size(), argv); ASSERT_EQ(OclocErrorCode::SUCCESS, parsingResult); @@ -325,7 +326,7 @@ TEST_F(OfflineLinkerTest, GivenValidCommandWhenVerificationIsPerformedThenSucces "-file", "some_file2.spv"}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; const auto parsingResult = mockOfflineLinker.parseCommand(argv.size(), argv); ASSERT_EQ(OclocErrorCode::SUCCESS, parsingResult); @@ -348,13 +349,13 @@ TEST_F(OfflineLinkerTest, GivenEmptyFileWhenLoadingInputFilesThenErrorIsReturned "-file", filename}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; ::testing::internal::CaptureStdout(); - const auto readingResult = mockOfflineLinker.initialize(argv.size(), argv); + const auto initializationResult = mockOfflineLinker.initialize(argv.size(), argv); const auto output{::testing::internal::GetCapturedStdout()}; - ASSERT_EQ(OclocErrorCode::INVALID_FILE, readingResult); + ASSERT_EQ(OclocErrorCode::INVALID_FILE, initializationResult); const std::string expectedErrorMessage{"Error: Cannot read input file: some_file.spv\n"}; EXPECT_EQ(expectedErrorMessage, output); @@ -366,7 +367,7 @@ TEST_F(OfflineLinkerTest, GivenValidFileWithUnknownFormatWhenLoadingInputFilesTh // Spir-V or LLVM-BC magic constants are required. This should be treated as error. mockArgHelperFilesMap[filename] = "Some unknown format!"; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; mockOfflineLinker.inputFilenames.push_back(filename); ::testing::internal::CaptureStdout(); @@ -386,7 +387,7 @@ TEST_F(OfflineLinkerTest, GivenValidFilesWithValidFormatsWhenLoadingInputFilesTh mockArgHelperFilesMap[firstFilename] = getEmptySpirvFile(); mockArgHelperFilesMap[secondFilename] = getEmptyLlvmBcFile(); - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; mockOfflineLinker.inputFilenames.push_back(firstFilename); mockOfflineLinker.inputFilenames.push_back(secondFilename); @@ -427,13 +428,13 @@ TEST_F(OfflineLinkerTest, GivenValidFilesWhenInitializationIsSuccessfulThenLinkM "-file", secondFilename}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; ::testing::internal::CaptureStdout(); - const auto readingResult = mockOfflineLinker.initialize(argv.size(), argv); + const auto initializationResult = mockOfflineLinker.initialize(argv.size(), argv); const auto output{::testing::internal::GetCapturedStdout()}; - EXPECT_EQ(OclocErrorCode::SUCCESS, readingResult); + EXPECT_EQ(OclocErrorCode::SUCCESS, initializationResult); EXPECT_TRUE(output.empty()); EXPECT_EQ(OperationMode::LINK_FILES, mockOfflineLinker.operationMode); @@ -445,7 +446,7 @@ TEST_F(OfflineLinkerTest, GivenSPIRVandLLVMBCFilesWhenElfOutputIsRequestedThenEl mockArgHelper.interceptOutput = true; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; mockOfflineLinker.inputFilesContent.emplace_back(std::move(spirvFileContent.bytes), spirvFileContent.size, spirvFileContent.codeType); mockOfflineLinker.inputFilesContent.emplace_back(std::move(llvmbcFileContent.bytes), llvmbcFileContent.size, llvmbcFileContent.codeType); mockOfflineLinker.outputFormat = IGC::CodeType::elf; @@ -492,15 +493,16 @@ TEST_F(OfflineLinkerTest, GivenValidInputFileContentsWhenLlvmBcOutputIsRequested mockArgHelper.interceptOutput = true; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + HardwareInfo hwInfo{}; + const auto igcInitializationResult{mockOclocIgcFacade->initialize(hwInfo)}; + ASSERT_EQ(OclocErrorCode::SUCCESS, igcInitializationResult); + + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; mockOfflineLinker.inputFilesContent.emplace_back(std::move(spirvFileContent.bytes), spirvFileContent.size, spirvFileContent.codeType); mockOfflineLinker.inputFilesContent.emplace_back(std::move(llvmbcFileContent.bytes), llvmbcFileContent.size, llvmbcFileContent.codeType); mockOfflineLinker.outputFormat = IGC::CodeType::llvmBc; mockOfflineLinker.operationMode = OperationMode::LINK_FILES; - const auto igcInitializationResult{mockOfflineLinker.prepareIgc()}; - ASSERT_EQ(OclocErrorCode::SUCCESS, igcInitializationResult); - const auto linkingResult{mockOfflineLinker.execute()}; ASSERT_EQ(OclocErrorCode::SUCCESS, linkingResult); @@ -524,15 +526,16 @@ TEST_F(OfflineLinkerTest, GivenValidInputFileContentsAndFailingIGCWhenLlvmBcOutp mockArgHelper.interceptOutput = true; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + HardwareInfo hwInfo{}; + const auto igcInitializationResult{mockOclocIgcFacade->initialize(hwInfo)}; + ASSERT_EQ(OclocErrorCode::SUCCESS, igcInitializationResult); + + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; mockOfflineLinker.inputFilesContent.emplace_back(std::move(spirvFileContent.bytes), spirvFileContent.size, spirvFileContent.codeType); mockOfflineLinker.inputFilesContent.emplace_back(std::move(llvmbcFileContent.bytes), llvmbcFileContent.size, llvmbcFileContent.codeType); mockOfflineLinker.outputFormat = IGC::CodeType::llvmBc; mockOfflineLinker.operationMode = OperationMode::LINK_FILES; - const auto igcInitializationResult{mockOfflineLinker.prepareIgc()}; - ASSERT_EQ(OclocErrorCode::SUCCESS, igcInitializationResult); - ::testing::internal::CaptureStdout(); const auto linkingResult{mockOfflineLinker.execute()}; const auto output{::testing::internal::GetCapturedStdout()}; @@ -554,15 +557,16 @@ TEST_F(OfflineLinkerTest, GivenValidInputFileContentsAndInvalidTranslationOutput mockArgHelper.interceptOutput = true; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + HardwareInfo hwInfo{}; + const auto igcInitializationResult{mockOclocIgcFacade->initialize(hwInfo)}; + ASSERT_EQ(OclocErrorCode::SUCCESS, igcInitializationResult); + + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; mockOfflineLinker.inputFilesContent.emplace_back(std::move(spirvFileContent.bytes), spirvFileContent.size, spirvFileContent.codeType); mockOfflineLinker.inputFilesContent.emplace_back(std::move(llvmbcFileContent.bytes), llvmbcFileContent.size, llvmbcFileContent.codeType); mockOfflineLinker.outputFormat = IGC::CodeType::llvmBc; mockOfflineLinker.operationMode = OperationMode::LINK_FILES; - const auto igcInitializationResult{mockOfflineLinker.prepareIgc()}; - ASSERT_EQ(OclocErrorCode::SUCCESS, igcInitializationResult); - ::testing::internal::CaptureStdout(); const auto linkingResult{mockOfflineLinker.execute()}; const auto output{::testing::internal::GetCapturedStdout()}; @@ -575,7 +579,7 @@ TEST_F(OfflineLinkerTest, GivenValidInputFileContentsAndInvalidTranslationOutput } TEST_F(OfflineLinkerTest, GivenUninitializedLinkerWhenExecuteIsInvokedThenErrorIsIssued) { - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; ::testing::internal::CaptureStdout(); const auto executionResult{mockOfflineLinker.execute()}; @@ -586,7 +590,7 @@ TEST_F(OfflineLinkerTest, GivenUninitializedLinkerWhenExecuteIsInvokedThenErrorI } TEST_F(OfflineLinkerTest, GivenHelpRequestWhenExecuteIsInvokedThenHelpIsPrinted) { - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; mockOfflineLinker.operationMode = OperationMode::SHOW_HELP; ::testing::internal::CaptureStdout(); @@ -598,7 +602,7 @@ TEST_F(OfflineLinkerTest, GivenHelpRequestWhenExecuteIsInvokedThenHelpIsPrinted) } TEST_F(OfflineLinkerTest, GivenInvalidOperationModeWhenExecuteIsInvokedThenErrorIsIssued) { - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; mockOfflineLinker.operationMode = static_cast(7); ::testing::internal::CaptureStdout(); @@ -610,7 +614,7 @@ TEST_F(OfflineLinkerTest, GivenInvalidOperationModeWhenExecuteIsInvokedThenError } TEST_F(OfflineLinkerTest, GivenUninitializedHwInfoWhenInitIsCalledThenHwInfoIsInitialized) { - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; ASSERT_EQ(IGFX_UNKNOWN, mockOfflineLinker.hwInfo.platform.eProductFamily); const auto hwInfoInitializationResult{mockOfflineLinker.initHardwareInfo()}; @@ -633,14 +637,14 @@ TEST_F(OfflineLinkerTest, GivenEmptyHwInfoTableWhenInitializationIsPerformedThen "-file", secondFilename}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; mockOfflineLinker.shouldReturnEmptyHardwareInfoTable = true; ::testing::internal::CaptureStdout(); - const auto readingResult = mockOfflineLinker.initialize(argv.size(), argv); + const auto initializationResult = mockOfflineLinker.initialize(argv.size(), argv); const auto output{::testing::internal::GetCapturedStdout()}; - EXPECT_EQ(OclocErrorCode::INVALID_DEVICE, readingResult); + EXPECT_EQ(OclocErrorCode::INVALID_DEVICE, initializationResult); const std::string expectedErrorMessage{"Error! Cannot retrieve any valid hardware information!\n"}; EXPECT_EQ(expectedErrorMessage, output); @@ -661,14 +665,14 @@ TEST_F(OfflineLinkerTest, GivenMissingIgcLibraryWhenInitializationIsPerformedThe "-file", secondFilename}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; - mockOfflineLinker.shouldFailLoadingOfIgcLib = true; + mockOclocIgcFacade->shouldFailLoadingOfIgcLib = true; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; ::testing::internal::CaptureStdout(); - const auto readingResult = mockOfflineLinker.initialize(argv.size(), argv); + const auto initializationResult = mockOfflineLinker.initialize(argv.size(), argv); const auto output{::testing::internal::GetCapturedStdout()}; - EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, readingResult); + EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, initializationResult); std::stringstream expectedErrorMessage; expectedErrorMessage << "Error! Loading of IGC library has failed! Filename: " << Os::igcDllName << "\n"; @@ -679,14 +683,14 @@ TEST_F(OfflineLinkerTest, GivenMissingIgcLibraryWhenInitializationIsPerformedThe TEST_F(OfflineLinkerTest, GivenOfflineLinkerWhenStoringValidBuildLogThenItIsSaved) { const std::string someValidLog{"Warning: This is a build log!"}; - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; mockOfflineLinker.tryToStoreBuildLog(someValidLog.data(), someValidLog.size()); EXPECT_EQ(someValidLog, mockOfflineLinker.getBuildLog()); } TEST_F(OfflineLinkerTest, GivenOfflineLinkerWhenStoringInvalidBuildLogThenItIsIgnored) { - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; + MockOfflineLinker mockOfflineLinker{&mockArgHelper, std::move(mockOclocIgcFacade)}; mockOfflineLinker.tryToStoreBuildLog(nullptr, 0); const auto buildLog{mockOfflineLinker.getBuildLog()}; @@ -700,74 +704,4 @@ TEST_F(OfflineLinkerTest, GivenOfflineLinkerWhenStoringInvalidBuildLogThenItIsIg EXPECT_TRUE(buildLog2.empty()); } -TEST_F(OfflineLinkerTest, GivenFailingLoadingOfIgcSymbolsWhenPreparingIgcThenFailureIsReported) { - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; - mockOfflineLinker.shouldFailLoadingOfIgcCreateMainFunction = true; - - ::testing::internal::CaptureStdout(); - const auto igcPreparationResult{mockOfflineLinker.prepareIgc()}; - const auto output{::testing::internal::GetCapturedStdout()}; - - EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, igcPreparationResult); - - const std::string expectedErrorMessage{"Error! Cannot load required functions from IGC library.\n"}; - EXPECT_EQ(expectedErrorMessage, output); -} - -TEST_F(OfflineLinkerTest, GivenFailingCreationOfIgcMainWhenPreparingIgcThenFailureIsReported) { - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; - mockOfflineLinker.shouldFailCreationOfIgcMain = true; - - ::testing::internal::CaptureStdout(); - const auto igcPreparationResult{mockOfflineLinker.prepareIgc()}; - const auto output{::testing::internal::GetCapturedStdout()}; - - EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, igcPreparationResult); - - const std::string expectedErrorMessage{"Error! Cannot create IGC main component!\n"}; - EXPECT_EQ(expectedErrorMessage, output); -} - -TEST_F(OfflineLinkerTest, GivenFailingCreationOfIgcDeviceContextWhenPreparingIgcThenFailureIsReported) { - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; - mockOfflineLinker.shouldFailCreationOfIgcDeviceContext = true; - - ::testing::internal::CaptureStdout(); - const auto igcPreparationResult{mockOfflineLinker.prepareIgc()}; - const auto output{::testing::internal::GetCapturedStdout()}; - - EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, igcPreparationResult); - - const std::string expectedErrorMessage{"Error! Cannot create IGC device context!\n"}; - EXPECT_EQ(expectedErrorMessage, output); -} - -TEST_F(OfflineLinkerTest, GivenInvalidIgcPlatformHandleWhenPreparingIgcThenFailureIsReported) { - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; - mockOfflineLinker.shouldReturnInvalidIgcPlatformHandle = true; - - ::testing::internal::CaptureStdout(); - const auto igcPreparationResult{mockOfflineLinker.prepareIgc()}; - const auto output{::testing::internal::GetCapturedStdout()}; - - EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, igcPreparationResult); - - const std::string expectedErrorMessage{"Error! IGC device context has not been properly created!\n"}; - EXPECT_EQ(expectedErrorMessage, output); -} - -TEST_F(OfflineLinkerTest, GivenInvalidIgcGTSystemInfoHandleWhenPreparingIgcThenFailureIsReported) { - MockOfflineLinker mockOfflineLinker{&mockArgHelper}; - mockOfflineLinker.shouldReturnInvalidGTSystemInfoHandle = true; - - ::testing::internal::CaptureStdout(); - const auto igcPreparationResult{mockOfflineLinker.prepareIgc()}; - const auto output{::testing::internal::GetCapturedStdout()}; - - EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, igcPreparationResult); - - const std::string expectedErrorMessage{"Error! IGC device context has not been properly created!\n"}; - EXPECT_EQ(expectedErrorMessage, output); -} - } // namespace NEO \ No newline at end of file diff --git a/opencl/test/unit_test/offline_compiler/offline_linker_tests.h b/opencl/test/unit_test/offline_compiler/offline_linker_tests.h index 678394dd4c..ba87820cb8 100644 --- a/opencl/test/unit_test/offline_compiler/offline_linker_tests.h +++ b/opencl/test/unit_test/offline_compiler/offline_linker_tests.h @@ -9,12 +9,17 @@ #include "gtest/gtest.h" #include "mock/mock_argument_helper.h" +#include "mock/mock_ocloc_igc_facade.h" #include "mock/mock_offline_linker.h" namespace NEO { class OfflineLinkerTest : public ::testing::Test { public: + OfflineLinkerTest() { + mockOclocIgcFacade = std::make_unique(&mockArgHelper); + } + void SetUp() override; void TearDown() override; @@ -25,6 +30,7 @@ class OfflineLinkerTest : public ::testing::Test { protected: MockOclocArgHelper::FilesMap mockArgHelperFilesMap{}; MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap}; + std::unique_ptr mockOclocIgcFacade{}; char binaryToReturn[8]{7, 7, 7, 7, 0, 1, 2, 3}; }; diff --git a/shared/offline_compiler/source/CMakeLists.txt b/shared/offline_compiler/source/CMakeLists.txt index d88b1bf871..70dcd335ba 100644 --- a/shared/offline_compiler/source/CMakeLists.txt +++ b/shared/offline_compiler/source/CMakeLists.txt @@ -63,6 +63,8 @@ set(CLOC_LIB_SRCS_LIB ${OCLOC_DIRECTORY}/source/ocloc_error_code.h ${OCLOC_DIRECTORY}/source/ocloc_fatbinary.cpp ${OCLOC_DIRECTORY}/source/ocloc_fatbinary.h + ${OCLOC_DIRECTORY}/source/ocloc_igc_facade.cpp + ${OCLOC_DIRECTORY}/source/ocloc_igc_facade.h ${OCLOC_DIRECTORY}/source/ocloc_validator.cpp ${OCLOC_DIRECTORY}/source/ocloc_validator.h ${OCLOC_DIRECTORY}/source/offline_compiler.cpp diff --git a/shared/offline_compiler/source/ocloc_igc_facade.cpp b/shared/offline_compiler/source/ocloc_igc_facade.cpp new file mode 100644 index 0000000000..0434967497 --- /dev/null +++ b/shared/offline_compiler/source/ocloc_igc_facade.cpp @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/offline_compiler/source/ocloc_igc_facade.h" + +#include "shared/offline_compiler/source/ocloc_arg_helper.h" +#include "shared/offline_compiler/source/ocloc_error_code.h" +#include "shared/source/helpers/compiler_hw_info_config.h" +#include "shared/source/helpers/hw_info.h" +#include "shared/source/os_interface/os_inc_base.h" +#include "shared/source/os_interface/os_library.h" + +#include "ocl_igc_interface/platform_helper.h" + +#include + +namespace NEO { + +CIF::CIFMain *createMainNoSanitize(CIF::CreateCIFMainFunc_t createFunc); + +OclocIgcFacade::OclocIgcFacade(OclocArgHelper *argHelper) + : argHelper{argHelper} { +} + +OclocIgcFacade::~OclocIgcFacade() = default; + +int OclocIgcFacade::initialize(const HardwareInfo &hwInfo) { + igcLib = loadIgcLibrary(); + if (!igcLib) { + argHelper->printf("Error! Loading of IGC library has failed! Filename: %s\n", Os::igcDllName); + return OclocErrorCode::OUT_OF_HOST_MEMORY; + } + + const auto igcCreateMainFunction = loadCreateIgcMainFunction(); + if (!igcCreateMainFunction) { + argHelper->printf("Error! Cannot load required functions from IGC library.\n"); + return OclocErrorCode::OUT_OF_HOST_MEMORY; + } + + igcMain = createIgcMain(igcCreateMainFunction); + if (!igcMain) { + argHelper->printf("Error! Cannot create IGC main component!\n"); + return OclocErrorCode::OUT_OF_HOST_MEMORY; + } + + const std::vector interfacesToIgnore = {IGC::OclGenBinaryBase::GetInterfaceId()}; + if (!isIgcInterfaceCompatible(interfacesToIgnore)) { + const auto incompatibleInterface{getIncompatibleInterface(interfacesToIgnore)}; + argHelper->printf("Error! Incompatible interface in IGC: %s\n", incompatibleInterface.c_str()); + + DEBUG_BREAK_IF(true); + return OclocErrorCode::OUT_OF_HOST_MEMORY; + } + + if (!isPatchtokenInterfaceSupported()) { + argHelper->printf("Error! Patchtoken interface is missing.\n"); + return OclocErrorCode::OUT_OF_HOST_MEMORY; + } + + igcDeviceCtx = createIgcDeviceContext(); + if (!igcDeviceCtx) { + argHelper->printf("Error! Cannot create IGC device context!\n"); + return OclocErrorCode::OUT_OF_HOST_MEMORY; + } + + igcDeviceCtx->SetProfilingTimerResolution(static_cast(hwInfo.capabilityTable.defaultProfilingTimerResolution)); + + const auto igcPlatform = getIgcPlatformHandle(); + const auto igcGtSystemInfo = getGTSystemInfoHandle(); + const auto igcFtrWa = getIgcFeaturesAndWorkaroundsHandle(); + + if (!igcPlatform || !igcGtSystemInfo || !igcFtrWa) { + argHelper->printf("Error! IGC device context has not been properly created!\n"); + return OclocErrorCode::OUT_OF_HOST_MEMORY; + } + + const auto compilerHwInfoConfig = CompilerHwInfoConfig::get(hwInfo.platform.eProductFamily); + auto copyHwInfo = hwInfo; + if (compilerHwInfoConfig) { + compilerHwInfoConfig->adjustHwInfoForIgc(copyHwInfo); + } + + IGC::PlatformHelper::PopulateInterfaceWith(*igcPlatform.get(), copyHwInfo.platform); + IGC::GtSysInfoHelper::PopulateInterfaceWith(*igcGtSystemInfo.get(), copyHwInfo.gtSystemInfo); + + populateWithFeatures(igcFtrWa.get(), hwInfo, compilerHwInfoConfig); + + initialized = true; + return OclocErrorCode::SUCCESS; +} + +std::unique_ptr OclocIgcFacade::loadIgcLibrary() const { + return std::unique_ptr{OsLibrary::load(Os::igcDllName)}; +} + +CIF::CreateCIFMainFunc_t OclocIgcFacade::loadCreateIgcMainFunction() const { + return reinterpret_cast(igcLib->getProcAddress(CIF::CreateCIFMainFuncName)); +} + +CIF::RAII::UPtr_t OclocIgcFacade::createIgcMain(CIF::CreateCIFMainFunc_t createMainFunction) const { + return CIF::RAII::UPtr(createMainNoSanitize(createMainFunction)); +} + +bool OclocIgcFacade::isIgcInterfaceCompatible(const std::vector &interfacesToIgnore) const { + return igcMain->IsCompatible(&interfacesToIgnore); +} + +std::string OclocIgcFacade::getIncompatibleInterface(const std::vector &interfacesToIgnore) const { + return CIF::InterfaceIdCoder::Dec(igcMain->FindIncompatible(&interfacesToIgnore)); +} + +bool OclocIgcFacade::isPatchtokenInterfaceSupported() const { + CIF::Version_t verMin = 0, verMax = 0; + return igcMain->FindSupportedVersions(IGC::OclGenBinaryBase::GetInterfaceId(), verMin, verMax); +} + +CIF::RAII::UPtr_t OclocIgcFacade::createIgcDeviceContext() const { + return igcMain->CreateInterface(); +} + +CIF::RAII::UPtr_t OclocIgcFacade::getIgcPlatformHandle() const { + return igcDeviceCtx->GetPlatformHandle(); +} + +CIF::RAII::UPtr_t OclocIgcFacade::getGTSystemInfoHandle() const { + return igcDeviceCtx->GetGTSystemInfoHandle(); +} + +CIF::RAII::UPtr_t OclocIgcFacade::getIgcFeaturesAndWorkaroundsHandle() const { + return igcDeviceCtx->GetIgcFeaturesAndWorkaroundsHandle(); +} + +void OclocIgcFacade::populateWithFeatures(IGC::IgcFeaturesAndWorkaroundsTagOCL *handle, const HardwareInfo &hwInfo, const CompilerHwInfoConfig *compilerHwInfoConfig) const { + handle->SetFtrDesktop(hwInfo.featureTable.flags.ftrDesktop); + handle->SetFtrChannelSwizzlingXOREnabled(hwInfo.featureTable.flags.ftrChannelSwizzlingXOREnabled); + handle->SetFtrIVBM0M1Platform(hwInfo.featureTable.flags.ftrIVBM0M1Platform); + handle->SetFtrSGTPVSKUStrapPresent(hwInfo.featureTable.flags.ftrSGTPVSKUStrapPresent); + handle->SetFtr5Slice(hwInfo.featureTable.flags.ftr5Slice); + + if (compilerHwInfoConfig) { + handle->SetFtrGpGpuMidThreadLevelPreempt(compilerHwInfoConfig->isMidThreadPreemptionSupported(hwInfo)); + } + + handle->SetFtrIoMmuPageFaulting(hwInfo.featureTable.flags.ftrIoMmuPageFaulting); + handle->SetFtrWddm2Svm(hwInfo.featureTable.flags.ftrWddm2Svm); + handle->SetFtrPooledEuEnabled(hwInfo.featureTable.flags.ftrPooledEuEnabled); + + handle->SetFtrResourceStreamer(hwInfo.featureTable.flags.ftrResourceStreamer); +} + +CIF::RAII::UPtr_t OclocIgcFacade::createConstBuffer(const void *data, size_t size) { + return CIF::Builtins::CreateConstBuffer(igcMain.get(), data, size); +} + +CIF::RAII::UPtr_t OclocIgcFacade::createTranslationContext(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType) { + return igcDeviceCtx->CreateTranslationCtx(inType, outType); +} + +bool OclocIgcFacade::isInitialized() const { + return initialized; +} + +} // namespace NEO \ No newline at end of file diff --git a/shared/offline_compiler/source/ocloc_igc_facade.h b/shared/offline_compiler/source/ocloc_igc_facade.h new file mode 100644 index 0000000000..5bafebd54c --- /dev/null +++ b/shared/offline_compiler/source/ocloc_igc_facade.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2022 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#pragma once + +#include "cif/common/cif_main.h" +#include "cif/import/library_api.h" +#include "ocl_igc_interface/code_type.h" +#include "ocl_igc_interface/igc_ocl_device_ctx.h" + +#include +#include + +class OclocArgHelper; + +namespace NEO { + +class CompilerHwInfoConfig; +class OsLibrary; + +struct HardwareInfo; + +class OclocIgcFacade { + public: + OclocIgcFacade(OclocArgHelper *argHelper); + MOCKABLE_VIRTUAL ~OclocIgcFacade(); + + OclocIgcFacade(OclocIgcFacade &) = delete; + OclocIgcFacade(const OclocIgcFacade &&) = delete; + OclocIgcFacade &operator=(const OclocIgcFacade &) = delete; + OclocIgcFacade &operator=(OclocIgcFacade &&) = delete; + + int initialize(const HardwareInfo &hwInfo); + bool isInitialized() const; + CIF::RAII::UPtr_t createConstBuffer(const void *data, size_t size); + CIF::RAII::UPtr_t createTranslationContext(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType); + + protected: + MOCKABLE_VIRTUAL std::unique_ptr loadIgcLibrary() const; + MOCKABLE_VIRTUAL CIF::CreateCIFMainFunc_t loadCreateIgcMainFunction() const; + MOCKABLE_VIRTUAL CIF::RAII::UPtr_t createIgcMain(CIF::CreateCIFMainFunc_t createMainFunction) const; + MOCKABLE_VIRTUAL bool isIgcInterfaceCompatible(const std::vector &interfacesToIgnore) const; + MOCKABLE_VIRTUAL std::string getIncompatibleInterface(const std::vector &interfacesToIgnore) const; + MOCKABLE_VIRTUAL bool isPatchtokenInterfaceSupported() const; + MOCKABLE_VIRTUAL CIF::RAII::UPtr_t createIgcDeviceContext() const; + MOCKABLE_VIRTUAL CIF::RAII::UPtr_t getIgcPlatformHandle() const; + MOCKABLE_VIRTUAL CIF::RAII::UPtr_t getGTSystemInfoHandle() const; + MOCKABLE_VIRTUAL CIF::RAII::UPtr_t getIgcFeaturesAndWorkaroundsHandle() const; + void populateWithFeatures(IGC::IgcFeaturesAndWorkaroundsTagOCL *handle, const HardwareInfo &hwInfo, const CompilerHwInfoConfig *compilerHwInfoConfig) const; + + OclocArgHelper *argHelper{}; + std::unique_ptr igcLib{}; + CIF::RAII::UPtr_t igcMain{}; + CIF::RAII::UPtr_t igcDeviceCtx{}; + bool initialized{false}; +}; + +} // namespace NEO \ No newline at end of file diff --git a/shared/offline_compiler/source/ocloc_wrapper.h b/shared/offline_compiler/source/ocloc_wrapper.h index 8db09d6be6..74e78672f0 100644 --- a/shared/offline_compiler/source/ocloc_wrapper.h +++ b/shared/offline_compiler/source/ocloc_wrapper.h @@ -1,10 +1,12 @@ /* - * Copyright (C) 2020 Intel Corporation + * Copyright (C) 2020-2022 Intel Corporation * * SPDX-License-Identifier: MIT * */ +#pragma once + #include #include #include diff --git a/shared/offline_compiler/source/offline_compiler.cpp b/shared/offline_compiler/source/offline_compiler.cpp index 1a8fa337ff..da75fbaeec 100644 --- a/shared/offline_compiler/source/offline_compiler.cpp +++ b/shared/offline_compiler/source/offline_compiler.cpp @@ -89,6 +89,7 @@ OfflineCompiler *OfflineCompiler::create(size_t numArgs, const std::vectorargHelper = helper; + pOffCompiler->igcFacade = std::make_unique(helper); retVal = pOffCompiler->initialize(numArgs, allArgs, dumpFiles); } @@ -244,7 +245,9 @@ int OfflineCompiler::buildSourceCode() { retVal = INVALID_PROGRAM; break; } - UNRECOVERABLE_IF(igcDeviceCtx == nullptr); + + UNRECOVERABLE_IF(!igcFacade->isInitialized()); + auto inputTypeWarnings = validateInputType(sourceCode, inputFileLlvm, inputFileSpirV); this->argHelper->printf(inputTypeWarnings.c_str()); @@ -255,7 +258,7 @@ int OfflineCompiler::buildSourceCode() { if (retVal != SUCCESS) break; - auto igcTranslationCtx = igcDeviceCtx->CreateTranslationCtx(pBuildInfo->intermediateRepresentation, IGC::CodeType::oclGenBin); + auto igcTranslationCtx = igcFacade->createTranslationContext(pBuildInfo->intermediateRepresentation, IGC::CodeType::oclGenBin); igcOutput = igcTranslationCtx->Translate(pBuildInfo->fclOutput->GetOutput(), pBuildInfo->fclOptions.get(), pBuildInfo->fclInternalOptions.get(), nullptr, 0); @@ -263,10 +266,10 @@ int OfflineCompiler::buildSourceCode() { } else { storeBinary(irBinary, irBinarySize, sourceCode.c_str(), sourceCode.size()); isSpirV = inputFileSpirV; - auto igcSrc = CIF::Builtins::CreateConstBuffer(igcMain.get(), sourceCode.c_str(), sourceCode.size()); - auto igcOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), options.c_str(), options.size()); - auto igcInternalOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), internalOptions.c_str(), internalOptions.size()); - auto igcTranslationCtx = igcDeviceCtx->CreateTranslationCtx(inputFileSpirV ? IGC::CodeType::spirV : IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin); + auto igcSrc = igcFacade->createConstBuffer(sourceCode.c_str(), sourceCode.size()); + auto igcOptions = igcFacade->createConstBuffer(options.c_str(), options.size()); + auto igcInternalOptions = igcFacade->createConstBuffer(internalOptions.c_str(), internalOptions.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) { @@ -568,71 +571,12 @@ int OfflineCompiler::initialize(size_t numArgs, const std::vector & preferredIntermediateRepresentation = IGC::CodeType::spirV; } - this->igcLib.reset(OsLibrary::load(Os::igcDllName)); - if (this->igcLib == nullptr) { - return OUT_OF_HOST_MEMORY; + const auto igcInitializationResult = igcFacade->initialize(hwInfo); + if (igcInitializationResult != SUCCESS) { + argHelper->printf("Error! IGC initialization failure. Error code = %d\n", igcInitializationResult); + return igcInitializationResult; } - auto igcCreateMain = reinterpret_cast(this->igcLib->getProcAddress(CIF::CreateCIFMainFuncName)); - if (igcCreateMain == nullptr) { - return OUT_OF_HOST_MEMORY; - } - - this->igcMain = CIF::RAII::UPtr(createMainNoSanitize(igcCreateMain)); - if (this->igcMain == nullptr) { - return OUT_OF_HOST_MEMORY; - } - - std::vector interfacesToIgnore = {IGC::OclGenBinaryBase::GetInterfaceId()}; - if (false == this->igcMain->IsCompatible(&interfacesToIgnore)) { - argHelper->printf("Incompatible interface in IGC : %s\n", CIF::InterfaceIdCoder::Dec(this->igcMain->FindIncompatible(&interfacesToIgnore)).c_str()); - DEBUG_BREAK_IF(true); - return OUT_OF_HOST_MEMORY; - } - - CIF::Version_t verMin = 0, verMax = 0; - if (false == this->igcMain->FindSupportedVersions(IGC::OclGenBinaryBase::GetInterfaceId(), verMin, verMax)) { - argHelper->printf("Patchtoken interface is missing"); - return OUT_OF_HOST_MEMORY; - } - - this->igcDeviceCtx = this->igcMain->CreateInterface(); - if (this->igcDeviceCtx == nullptr) { - return OUT_OF_HOST_MEMORY; - } - this->igcDeviceCtx->SetProfilingTimerResolution(static_cast(hwInfo.capabilityTable.defaultProfilingTimerResolution)); - auto igcPlatform = this->igcDeviceCtx->GetPlatformHandle(); - auto igcGtSystemInfo = this->igcDeviceCtx->GetGTSystemInfoHandle(); - auto igcFtrWa = this->igcDeviceCtx->GetIgcFeaturesAndWorkaroundsHandle(); - if ((igcPlatform == nullptr) || (igcGtSystemInfo == nullptr) || (igcFtrWa == nullptr)) { - return OUT_OF_HOST_MEMORY; - } - - auto compilerHwInfoConfig = CompilerHwInfoConfig::get(hwInfo.platform.eProductFamily); - auto copyHwInfo = hwInfo; - if (compilerHwInfoConfig) { - compilerHwInfoConfig->adjustHwInfoForIgc(copyHwInfo); - } - - IGC::PlatformHelper::PopulateInterfaceWith(*igcPlatform.get(), copyHwInfo.platform); - IGC::GtSysInfoHelper::PopulateInterfaceWith(*igcGtSystemInfo.get(), copyHwInfo.gtSystemInfo); - // populate with features - - igcFtrWa.get()->SetFtrDesktop(hwInfo.featureTable.flags.ftrDesktop); - igcFtrWa.get()->SetFtrChannelSwizzlingXOREnabled(hwInfo.featureTable.flags.ftrChannelSwizzlingXOREnabled); - igcFtrWa.get()->SetFtrIVBM0M1Platform(hwInfo.featureTable.flags.ftrIVBM0M1Platform); - igcFtrWa.get()->SetFtrSGTPVSKUStrapPresent(hwInfo.featureTable.flags.ftrSGTPVSKUStrapPresent); - igcFtrWa.get()->SetFtr5Slice(hwInfo.featureTable.flags.ftr5Slice); - - if (compilerHwInfoConfig) { - igcFtrWa.get()->SetFtrGpGpuMidThreadLevelPreempt(compilerHwInfoConfig->isMidThreadPreemptionSupported(hwInfo)); - } - igcFtrWa.get()->SetFtrIoMmuPageFaulting(hwInfo.featureTable.flags.ftrIoMmuPageFaulting); - igcFtrWa.get()->SetFtrWddm2Svm(hwInfo.featureTable.flags.ftrWddm2Svm); - igcFtrWa.get()->SetFtrPooledEuEnabled(hwInfo.featureTable.flags.ftrPooledEuEnabled); - - igcFtrWa.get()->SetFtrResourceStreamer(hwInfo.featureTable.flags.ftrResourceStreamer); - return retVal; } diff --git a/shared/offline_compiler/source/offline_compiler.h b/shared/offline_compiler/source/offline_compiler.h index 7a5ac26d4d..ca694532fa 100644 --- a/shared/offline_compiler/source/offline_compiler.h +++ b/shared/offline_compiler/source/offline_compiler.h @@ -8,6 +8,7 @@ #pragma once #include "shared/offline_compiler/source/ocloc_arg_helper.h" +#include "shared/offline_compiler/source/ocloc_igc_facade.h" #include "shared/source/helpers/hw_info.h" #include "shared/source/os_interface/os_library.h" #include "shared/source/utilities/arrayref.h" @@ -15,7 +16,6 @@ #include "cif/common/cif_main.h" #include "ocl_igc_interface/fcl_ocl_device_ctx.h" -#include "ocl_igc_interface/igc_ocl_device_ctx.h" #include #include @@ -113,6 +113,7 @@ class OfflineCompiler { std::replace(suffix.begin(), suffix.end(), ' ', '_'); return suffix; } + MOCKABLE_VIRTUAL void writeOutAllFiles(); MOCKABLE_VIRTUAL void createDir(const std::string &path); void unifyExcludeIrFlags(); @@ -156,11 +157,10 @@ class OfflineCompiler { size_t debugDataBinarySize = 0; struct buildInfo; std::unique_ptr pBuildInfo; - std::unique_ptr igcLib = nullptr; - CIF::RAII::UPtr_t igcMain = nullptr; - CIF::RAII::UPtr_t igcDeviceCtx = nullptr; int revisionId = -1; + std::unique_ptr igcFacade{nullptr}; + std::unique_ptr fclLib = nullptr; CIF::RAII::UPtr_t fclMain = nullptr; CIF::RAII::UPtr_t fclDeviceCtx = nullptr; diff --git a/shared/offline_compiler/source/offline_linker.cpp b/shared/offline_compiler/source/offline_linker.cpp index acc76d5797..75a6d3e5ab 100644 --- a/shared/offline_compiler/source/offline_linker.cpp +++ b/shared/offline_compiler/source/offline_linker.cpp @@ -18,6 +18,8 @@ #include "shared/source/os_interface/os_library.h" #include "cif/common/cif_main.h" +#include "cif/import/library_api.h" +#include "ocl_igc_interface/igc_ocl_device_ctx.h" #include "ocl_igc_interface/platform_helper.h" #include @@ -28,14 +30,14 @@ namespace NEO { CIF::CIFMain *createMainNoSanitize(CIF::CreateCIFMainFunc_t createFunc); std::unique_ptr OfflineLinker::create(size_t argsCount, const std::vector &args, int &errorCode, OclocArgHelper *argHelper) { - std::unique_ptr linker{new OfflineLinker{argHelper}}; + std::unique_ptr linker{new OfflineLinker{argHelper, std::make_unique(argHelper)}}; errorCode = linker->initialize(argsCount, args); return linker; } -OfflineLinker::OfflineLinker(OclocArgHelper *argHelper) - : argHelper{argHelper}, operationMode{OperationMode::SKIP_EXECUTION}, outputFilename{"linker_output"}, outputFormat{IGC::CodeType::llvmBc} {} +OfflineLinker::OfflineLinker(OclocArgHelper *argHelper, std::unique_ptr igcFacade) + : argHelper{argHelper}, operationMode{OperationMode::SKIP_EXECUTION}, outputFilename{"linker_output"}, outputFormat{IGC::CodeType::llvmBc}, igcFacade{std::move(igcFacade)} {} OfflineLinker::~OfflineLinker() = default; @@ -65,7 +67,7 @@ int OfflineLinker::initialize(size_t argsCount, const std::vector & return hwInfoInitializationResult; } - const auto igcPreparationResult{prepareIgc()}; + const auto igcPreparationResult{igcFacade->initialize(hwInfo)}; if (igcPreparationResult != OclocErrorCode::SUCCESS) { return igcPreparationResult; } @@ -218,68 +220,6 @@ ArrayRef OfflineLinker::getHardwareInfoTable() const { return {hardwareInfoTable}; } -int OfflineLinker::prepareIgc() { - igcLib = loadIgcLibrary(); - if (!igcLib) { - argHelper->printf("Error! Loading of IGC library has failed! Filename: %s\n", Os::igcDllName); - return OclocErrorCode::OUT_OF_HOST_MEMORY; - } - - const auto igcCreateMainFunction = loadCreateIgcMainFunction(); - if (!igcCreateMainFunction) { - argHelper->printf("Error! Cannot load required functions from IGC library.\n"); - return OclocErrorCode::OUT_OF_HOST_MEMORY; - } - - igcMain = createIgcMain(igcCreateMainFunction); - if (!igcMain) { - argHelper->printf("Error! Cannot create IGC main component!\n"); - return OclocErrorCode::OUT_OF_HOST_MEMORY; - } - - igcDeviceCtx = createIgcDeviceContext(); - if (!igcDeviceCtx) { - argHelper->printf("Error! Cannot create IGC device context!\n"); - return OclocErrorCode::OUT_OF_HOST_MEMORY; - } - - const auto igcPlatform = getIgcPlatformHandle(); - const auto igcGtSystemInfo = getGTSystemInfoHandle(); - if (!igcPlatform || !igcGtSystemInfo) { - argHelper->printf("Error! IGC device context has not been properly created!\n"); - return OclocErrorCode::OUT_OF_HOST_MEMORY; - } - - IGC::PlatformHelper::PopulateInterfaceWith(*igcPlatform.get(), hwInfo.platform); - IGC::GtSysInfoHelper::PopulateInterfaceWith(*igcGtSystemInfo.get(), hwInfo.gtSystemInfo); - - return OclocErrorCode::SUCCESS; -} - -std::unique_ptr OfflineLinker::loadIgcLibrary() const { - return std::unique_ptr{OsLibrary::load(Os::igcDllName)}; -} - -CIF::CreateCIFMainFunc_t OfflineLinker::loadCreateIgcMainFunction() const { - return reinterpret_cast(igcLib->getProcAddress(CIF::CreateCIFMainFuncName)); -} - -CIF::RAII::UPtr_t OfflineLinker::createIgcMain(CIF::CreateCIFMainFunc_t createMainFunction) const { - return CIF::RAII::UPtr(createMainNoSanitize(createMainFunction)); -} - -CIF::RAII::UPtr_t OfflineLinker::createIgcDeviceContext() const { - return igcMain->CreateInterface(); -} - -CIF::RAII::UPtr_t OfflineLinker::getIgcPlatformHandle() const { - return igcDeviceCtx->GetPlatformHandle(); -} - -CIF::RAII::UPtr_t OfflineLinker::getGTSystemInfoHandle() const { - return igcDeviceCtx->GetGTSystemInfoHandle(); -} - int OfflineLinker::execute() { switch (operationMode) { case OperationMode::SHOW_HELP: @@ -366,10 +306,10 @@ std::vector OfflineLinker::createSingleInputFile() const { } std::pair> OfflineLinker::translateToOutputFormat(const std::vector &elfInput) { - auto igcSrc = CIF::Builtins::CreateConstBuffer(igcMain.get(), elfInput.data(), elfInput.size()); - auto igcOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), options.c_str(), options.size()); - auto igcInternalOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), internalOptions.c_str(), internalOptions.size()); - auto igcTranslationCtx = igcDeviceCtx->CreateTranslationCtx(IGC::CodeType::elf, outputFormat); + auto igcSrc = igcFacade->createConstBuffer(elfInput.data(), elfInput.size()); + auto igcOptions = igcFacade->createConstBuffer(options.c_str(), options.size()); + auto igcInternalOptions = igcFacade->createConstBuffer(internalOptions.c_str(), internalOptions.size()); + auto igcTranslationCtx = igcFacade->createTranslationContext(IGC::CodeType::elf, outputFormat); const auto tracingOptions{nullptr}; const auto tracingOptionsSize{0}; diff --git a/shared/offline_compiler/source/offline_linker.h b/shared/offline_compiler/source/offline_linker.h index f4f26a7a5d..b0e6cd41f2 100644 --- a/shared/offline_compiler/source/offline_linker.h +++ b/shared/offline_compiler/source/offline_linker.h @@ -7,13 +7,11 @@ #pragma once +#include "shared/offline_compiler/source/ocloc_igc_facade.h" #include "shared/source/helpers/hw_info.h" #include "shared/source/utilities/arrayref.h" -#include "cif/common/cif_main.h" -#include "cif/import/library_api.h" #include "ocl_igc_interface/code_type.h" -#include "ocl_igc_interface/igc_ocl_device_ctx.h" #include #include @@ -52,7 +50,7 @@ class OfflineLinker { std::string getBuildLog() const; protected: - explicit OfflineLinker(OclocArgHelper *argHelper); + explicit OfflineLinker(OclocArgHelper *argHelper, std::unique_ptr igcFacade); int initialize(size_t argsCount, const std::vector &args); int parseCommand(size_t argsCount, const std::vector &args); IGC::CodeType::CodeType_t parseOutputFormat(const std::string &outputFormatName); @@ -60,7 +58,6 @@ class OfflineLinker { int loadInputFilesContent(); IGC::CodeType::CodeType_t detectCodeType(char *bytes, size_t size) const; int initHardwareInfo(); - int prepareIgc(); int link(); int showHelp(); std::vector createSingleInputFile() const; @@ -68,12 +65,6 @@ class OfflineLinker { void tryToStoreBuildLog(const char *buildLogRaw, size_t size); MOCKABLE_VIRTUAL ArrayRef getHardwareInfoTable() const; - MOCKABLE_VIRTUAL std::unique_ptr loadIgcLibrary() const; - MOCKABLE_VIRTUAL CIF::CreateCIFMainFunc_t loadCreateIgcMainFunction() const; - MOCKABLE_VIRTUAL CIF::RAII::UPtr_t createIgcMain(CIF::CreateCIFMainFunc_t createMainFunction) const; - MOCKABLE_VIRTUAL CIF::RAII::UPtr_t createIgcDeviceContext() const; - MOCKABLE_VIRTUAL CIF::RAII::UPtr_t getIgcPlatformHandle() const; - MOCKABLE_VIRTUAL CIF::RAII::UPtr_t getGTSystemInfoHandle() const; OclocArgHelper *argHelper{}; OperationMode operationMode{}; @@ -85,9 +76,7 @@ class OfflineLinker { std::string options{}; std::string internalOptions{}; - std::unique_ptr igcLib{}; - CIF::RAII::UPtr_t igcMain{}; - CIF::RAII::UPtr_t igcDeviceCtx{}; + std::unique_ptr igcFacade{}; HardwareInfo hwInfo{}; std::string buildLog{}; };