Refactor and test initialization of FCL in ocloc
This change: - extracts FCL to a separate class called OclocFclFacade - tests the new class - tests its usage in offline compiler Related-To: NEO-6834 Signed-off-by: Patryk Wrobel <patryk.wrobel@intel.com>
This commit is contained in:
parent
c637903132
commit
35a04e5915
|
@ -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_fcl_facade.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
|
||||
|
@ -62,6 +63,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_fcl_facade_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ocloc_fcl_facade_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
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared/offline_compiler/source/ocloc_fcl_facade.h"
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
class MockOclocFclFacade : public OclocFclFacade {
|
||||
public:
|
||||
using OclocFclFacade::fclDeviceCtx;
|
||||
|
||||
bool shouldFailLoadingOfFclLib{false};
|
||||
bool shouldFailLoadingOfFclCreateMainFunction{false};
|
||||
bool shouldFailCreationOfFclMain{false};
|
||||
bool shouldFailCreationOfFclDeviceContext{false};
|
||||
bool shouldReturnInvalidFclPlatformHandle{false};
|
||||
std::optional<bool> isFclInterfaceCompatibleReturnValue{};
|
||||
std::optional<std::string> getIncompatibleInterfaceReturnValue{};
|
||||
std::optional<bool> shouldPopulateFclInterfaceReturnValue{};
|
||||
int populateFclInterfaceCalledCount{0};
|
||||
|
||||
MockOclocFclFacade(OclocArgHelper *argHelper) : OclocFclFacade{argHelper} {}
|
||||
~MockOclocFclFacade() override = default;
|
||||
|
||||
std::unique_ptr<OsLibrary> loadFclLibrary() const override {
|
||||
if (shouldFailLoadingOfFclLib) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return OclocFclFacade::loadFclLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
CIF::CreateCIFMainFunc_t loadCreateFclMainFunction() const override {
|
||||
if (shouldFailLoadingOfFclCreateMainFunction) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return OclocFclFacade::loadCreateFclMainFunction();
|
||||
}
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<CIF::CIFMain> createFclMain(CIF::CreateCIFMainFunc_t createMainFunction) const override {
|
||||
if (shouldFailCreationOfFclMain) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return OclocFclFacade::createFclMain(createMainFunction);
|
||||
}
|
||||
}
|
||||
|
||||
bool isFclInterfaceCompatible() const override {
|
||||
if (isFclInterfaceCompatibleReturnValue.has_value()) {
|
||||
return *isFclInterfaceCompatibleReturnValue;
|
||||
} else {
|
||||
return OclocFclFacade::isFclInterfaceCompatible();
|
||||
}
|
||||
}
|
||||
|
||||
std::string getIncompatibleInterface() const override {
|
||||
if (getIncompatibleInterfaceReturnValue.has_value()) {
|
||||
return *getIncompatibleInterfaceReturnValue;
|
||||
} else {
|
||||
return OclocFclFacade::getIncompatibleInterface();
|
||||
}
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<IGC::FclOclDeviceCtxTagOCL> createFclDeviceContext() const override {
|
||||
if (shouldFailCreationOfFclDeviceContext) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return OclocFclFacade::createFclDeviceContext();
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldPopulateFclInterface() const override {
|
||||
if (shouldPopulateFclInterfaceReturnValue.has_value()) {
|
||||
return *shouldPopulateFclInterfaceReturnValue;
|
||||
} else {
|
||||
return OclocFclFacade::shouldPopulateFclInterface();
|
||||
}
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<IGC::PlatformTagOCL> getPlatformHandle() const override {
|
||||
if (shouldReturnInvalidFclPlatformHandle) {
|
||||
return nullptr;
|
||||
} else {
|
||||
return OclocFclFacade::getPlatformHandle();
|
||||
}
|
||||
}
|
||||
|
||||
void populateFclInterface(IGC::PlatformTagOCL &handle, const PLATFORM &platform) override {
|
||||
++populateFclInterfaceCalledCount;
|
||||
OclocFclFacade::populateFclInterface(handle, platform);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace NEO
|
|
@ -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_fcl_facade.h"
|
||||
#include "opencl/test/unit_test/offline_compiler/mock/mock_ocloc_igc_facade.h"
|
||||
|
||||
#include <optional>
|
||||
|
@ -25,7 +26,7 @@ class MockOfflineCompiler : public OfflineCompiler {
|
|||
using OfflineCompiler::deviceName;
|
||||
using OfflineCompiler::elfBinary;
|
||||
using OfflineCompiler::excludeIr;
|
||||
using OfflineCompiler::fclDeviceCtx;
|
||||
using OfflineCompiler::fclFacade;
|
||||
using OfflineCompiler::forceStatelessToStatefulOptimization;
|
||||
using OfflineCompiler::genBinary;
|
||||
using OfflineCompiler::genBinarySize;
|
||||
|
@ -62,6 +63,10 @@ class MockOfflineCompiler : public OfflineCompiler {
|
|||
uniqueHelper->setAllCallBase(true);
|
||||
argHelper = uniqueHelper.get();
|
||||
|
||||
auto uniqueFclFacadeMock = std::make_unique<MockOclocFclFacade>(argHelper);
|
||||
mockFclFacade = uniqueFclFacadeMock.get();
|
||||
fclFacade = std::move(uniqueFclFacadeMock);
|
||||
|
||||
auto uniqueIgcFacadeMock = std::make_unique<MockOclocIgcFacade>(argHelper);
|
||||
mockIgcFacade = uniqueIgcFacadeMock.get();
|
||||
igcFacade = std::move(uniqueIgcFacadeMock);
|
||||
|
@ -125,6 +130,7 @@ class MockOfflineCompiler : public OfflineCompiler {
|
|||
uint32_t writeOutAllFilesCalled = 0u;
|
||||
std::unique_ptr<MockOclocArgHelper> uniqueHelper;
|
||||
MockOclocIgcFacade *mockIgcFacade = nullptr;
|
||||
MockOclocFclFacade *mockFclFacade = nullptr;
|
||||
int buildCalledCount{0};
|
||||
std::optional<int> buildReturnValue{};
|
||||
bool interceptCreatedDirs{false};
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ocloc_fcl_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_fcl_facade.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace NEO {
|
||||
|
||||
TEST_F(OclocFclFacadeTest, GivenMissingFclLibraryWhenPreparingFclThenFailureIsReported) {
|
||||
MockOclocFclFacade mockFclFacade{&mockArgHelper};
|
||||
mockFclFacade.shouldFailLoadingOfFclLib = true;
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
|
||||
const auto output{::testing::internal::GetCapturedStdout()};
|
||||
|
||||
EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, fclPreparationResult);
|
||||
EXPECT_FALSE(mockFclFacade.isInitialized());
|
||||
|
||||
std::stringstream expectedErrorMessage;
|
||||
expectedErrorMessage << "Error! Loading of FCL library has failed! Filename: " << Os::frontEndDllName << "\n";
|
||||
|
||||
EXPECT_EQ(expectedErrorMessage.str(), output);
|
||||
}
|
||||
|
||||
TEST_F(OclocFclFacadeTest, GivenFailingLoadingOfFclSymbolsWhenPreparingFclThenFailureIsReported) {
|
||||
MockOclocFclFacade mockFclFacade{&mockArgHelper};
|
||||
mockFclFacade.shouldFailLoadingOfFclCreateMainFunction = true;
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
|
||||
const auto output{::testing::internal::GetCapturedStdout()};
|
||||
|
||||
EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, fclPreparationResult);
|
||||
EXPECT_FALSE(mockFclFacade.isInitialized());
|
||||
|
||||
const std::string expectedErrorMessage{"Error! Cannot load required functions from FCL library.\n"};
|
||||
EXPECT_EQ(expectedErrorMessage, output);
|
||||
}
|
||||
|
||||
TEST_F(OclocFclFacadeTest, GivenFailingCreationOfFclMainWhenPreparingFclThenFailureIsReported) {
|
||||
MockOclocFclFacade mockFclFacade{&mockArgHelper};
|
||||
mockFclFacade.shouldFailCreationOfFclMain = true;
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
|
||||
const auto output{::testing::internal::GetCapturedStdout()};
|
||||
|
||||
EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, fclPreparationResult);
|
||||
EXPECT_FALSE(mockFclFacade.isInitialized());
|
||||
|
||||
const std::string expectedErrorMessage{"Error! Cannot create FCL main component!\n"};
|
||||
EXPECT_EQ(expectedErrorMessage, output);
|
||||
}
|
||||
|
||||
TEST_F(OclocFclFacadeTest, GivenIncompatibleFclInterfacesWhenPreparingFclThenFailureIsReported) {
|
||||
DebugManagerStateRestore stateRestore;
|
||||
DebugManager.flags.EnableDebugBreak.set(false);
|
||||
|
||||
MockOclocFclFacade mockFclFacade{&mockArgHelper};
|
||||
mockFclFacade.isFclInterfaceCompatibleReturnValue = false;
|
||||
mockFclFacade.getIncompatibleInterfaceReturnValue = "SomeImportantInterface";
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
|
||||
const auto output{::testing::internal::GetCapturedStdout()};
|
||||
|
||||
EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, fclPreparationResult);
|
||||
EXPECT_FALSE(mockFclFacade.isInitialized());
|
||||
|
||||
const std::string expectedErrorMessage{"Error! Incompatible interface in FCL: SomeImportantInterface\n"};
|
||||
EXPECT_EQ(expectedErrorMessage, output);
|
||||
}
|
||||
|
||||
TEST_F(OclocFclFacadeTest, GivenFailingCreationOfFclDeviceContextWhenPreparingFclThenFailureIsReported) {
|
||||
MockOclocFclFacade mockFclFacade{&mockArgHelper};
|
||||
mockFclFacade.shouldFailCreationOfFclDeviceContext = true;
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
|
||||
const auto output{::testing::internal::GetCapturedStdout()};
|
||||
|
||||
EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, fclPreparationResult);
|
||||
EXPECT_FALSE(mockFclFacade.isInitialized());
|
||||
|
||||
const std::string expectedErrorMessage{"Error! Cannot create FCL device context!\n"};
|
||||
EXPECT_EQ(expectedErrorMessage, output);
|
||||
}
|
||||
|
||||
TEST_F(OclocFclFacadeTest, GivenNoneErrorsSetAndNotPopulateFclInterfaceWhenPreparingFclThenSuccessIsReported) {
|
||||
MockOclocFclFacade mockFclFacade{&mockArgHelper};
|
||||
mockFclFacade.shouldPopulateFclInterfaceReturnValue = false;
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
|
||||
const auto output{::testing::internal::GetCapturedStdout()};
|
||||
|
||||
EXPECT_EQ(OclocErrorCode::SUCCESS, fclPreparationResult);
|
||||
EXPECT_TRUE(output.empty()) << output;
|
||||
EXPECT_TRUE(mockFclFacade.isInitialized());
|
||||
EXPECT_EQ(0, mockFclFacade.populateFclInterfaceCalledCount);
|
||||
}
|
||||
|
||||
TEST_F(OclocFclFacadeTest, GivenPopulateFclInterfaceAndInvalidFclDeviceContextWhenPreparingFclThenFailureIsReported) {
|
||||
MockOclocFclFacade mockFclFacade{&mockArgHelper};
|
||||
mockFclFacade.shouldPopulateFclInterfaceReturnValue = true;
|
||||
mockFclFacade.shouldReturnInvalidFclPlatformHandle = true;
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
|
||||
const auto output{::testing::internal::GetCapturedStdout()};
|
||||
|
||||
EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, fclPreparationResult);
|
||||
EXPECT_FALSE(mockFclFacade.isInitialized());
|
||||
|
||||
const std::string expectedErrorMessage{"Error! FCL device context has not been properly created!\n"};
|
||||
EXPECT_EQ(expectedErrorMessage, output);
|
||||
|
||||
EXPECT_EQ(0, mockFclFacade.populateFclInterfaceCalledCount);
|
||||
}
|
||||
|
||||
TEST_F(OclocFclFacadeTest, GivenPopulateFclInterfaceWhenPreparingFclThenSuccessIsReported) {
|
||||
MockOclocFclFacade mockFclFacade{&mockArgHelper};
|
||||
mockFclFacade.shouldPopulateFclInterfaceReturnValue = true;
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
|
||||
const auto output{::testing::internal::GetCapturedStdout()};
|
||||
|
||||
EXPECT_EQ(OclocErrorCode::SUCCESS, fclPreparationResult);
|
||||
EXPECT_TRUE(output.empty()) << output;
|
||||
EXPECT_TRUE(mockFclFacade.isInitialized());
|
||||
|
||||
EXPECT_EQ(1, mockFclFacade.populateFclInterfaceCalledCount);
|
||||
}
|
||||
|
||||
TEST_F(OclocFclFacadeTest, GivenNoneErrorsSetWhenPreparingFclThenSuccessIsReported) {
|
||||
MockOclocFclFacade mockFclFacade{&mockArgHelper};
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
|
||||
const auto output{::testing::internal::GetCapturedStdout()};
|
||||
|
||||
EXPECT_EQ(OclocErrorCode::SUCCESS, fclPreparationResult);
|
||||
EXPECT_TRUE(output.empty()) << output;
|
||||
EXPECT_TRUE(mockFclFacade.isInitialized());
|
||||
|
||||
const auto expectedPopulateCalledCount = mockFclFacade.shouldPopulateFclInterface() ? 1 : 0;
|
||||
EXPECT_EQ(expectedPopulateCalledCount, mockFclFacade.populateFclInterfaceCalledCount);
|
||||
}
|
||||
|
||||
TEST_F(OclocFclFacadeTest, GivenInitializedFclWhenGettingIncompatibleInterfaceThenEmptyStringIsReturned) {
|
||||
MockOclocFclFacade mockFclFacade{&mockArgHelper};
|
||||
|
||||
::testing::internal::CaptureStdout();
|
||||
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
|
||||
const auto output{::testing::internal::GetCapturedStdout()};
|
||||
|
||||
ASSERT_EQ(OclocErrorCode::SUCCESS, fclPreparationResult);
|
||||
|
||||
const auto incompatibleInterface = mockFclFacade.getIncompatibleInterface();
|
||||
EXPECT_TRUE(incompatibleInterface.empty()) << incompatibleInterface;
|
||||
}
|
||||
|
||||
} // namespace NEO
|
|
@ -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 OclocFclFacadeTest : public ::testing::Test {
|
||||
protected:
|
||||
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{};
|
||||
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
|
||||
HardwareInfo hwInfo{};
|
||||
};
|
||||
|
||||
} // namespace NEO
|
|
@ -956,6 +956,29 @@ TEST_F(OfflineCompilerTests, givenExcludeIrFromZebinInternalOptionWhenInitIsPerf
|
|||
EXPECT_TRUE(mockOfflineCompiler.excludeIr);
|
||||
}
|
||||
|
||||
TEST_F(OfflineCompilerTests, givenValidArgumentsAndFclInitFailureWhenInitIsPerformedThenFailureIsPropagatedAndErrorIsPrinted) {
|
||||
std::vector<std::string> argv = {
|
||||
"ocloc",
|
||||
"-file",
|
||||
"test_files/copybuffer.cl",
|
||||
"-device",
|
||||
gEnvironment->devicePrefix.c_str()};
|
||||
|
||||
MockOfflineCompiler mockOfflineCompiler{};
|
||||
mockOfflineCompiler.mockFclFacade->shouldFailLoadingOfFclLib = 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 FCL library has failed! Filename: " << Os::frontEndDllName << "\n"
|
||||
<< "Error! FCL initialization failure. Error code = -6\n";
|
||||
|
||||
EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, initResult);
|
||||
EXPECT_EQ(expectedErrorMessage.str(), output);
|
||||
}
|
||||
|
||||
TEST_F(OfflineCompilerTests, givenValidArgumentsAndIgcInitFailureWhenInitIsPerformedThenFailureIsPropagatedAndErrorIsPrinted) {
|
||||
std::vector<std::string> argv = {
|
||||
"ocloc",
|
||||
|
@ -1355,7 +1378,7 @@ TEST_F(OfflineCompilerTests, WhenFclNotNeededThenDontLoadIt) {
|
|||
MockOfflineCompiler offlineCompiler;
|
||||
auto ret = offlineCompiler.initialize(argv.size(), argv);
|
||||
EXPECT_EQ(0, ret);
|
||||
EXPECT_EQ(nullptr, offlineCompiler.fclDeviceCtx);
|
||||
EXPECT_FALSE(offlineCompiler.fclFacade->isInitialized());
|
||||
EXPECT_TRUE(offlineCompiler.igcFacade->isInitialized());
|
||||
}
|
||||
|
||||
|
@ -2043,7 +2066,7 @@ TEST(OfflineCompilerTest, givenUseLlvmBcFlagWhenBuildingIrBinaryThenProperTransl
|
|||
ASSERT_EQ(CL_SUCCESS, initResult);
|
||||
|
||||
auto mockFclOclDeviceCtx = new NEO::MockFclOclDeviceCtx();
|
||||
mockOfflineCompiler.fclDeviceCtx = CIF::RAII::Pack<IGC::FclOclDeviceCtxTagOCL>(mockFclOclDeviceCtx);
|
||||
mockOfflineCompiler.mockFclFacade->fclDeviceCtx = CIF::RAII::Pack<IGC::FclOclDeviceCtxTagOCL>(mockFclOclDeviceCtx);
|
||||
|
||||
mockOfflineCompiler.useLlvmBc = true;
|
||||
const auto buildResult = mockOfflineCompiler.buildIrBinary();
|
||||
|
|
|
@ -65,6 +65,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_fcl_facade.cpp
|
||||
${OCLOC_DIRECTORY}/source/ocloc_fcl_facade.h
|
||||
${OCLOC_DIRECTORY}/source/ocloc_igc_facade.cpp
|
||||
${OCLOC_DIRECTORY}/source/ocloc_igc_facade.h
|
||||
${OCLOC_DIRECTORY}/source/ocloc_validator.cpp
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/offline_compiler/source/ocloc_fcl_facade.h"
|
||||
|
||||
#include "shared/offline_compiler/source/ocloc_arg_helper.h"
|
||||
#include "shared/offline_compiler/source/ocloc_error_code.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/igc_ocl_device_ctx.h"
|
||||
#include "ocl_igc_interface/platform_helper.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
CIF::CIFMain *createMainNoSanitize(CIF::CreateCIFMainFunc_t createFunc);
|
||||
|
||||
OclocFclFacade::OclocFclFacade(OclocArgHelper *argHelper)
|
||||
: argHelper{argHelper} {
|
||||
}
|
||||
|
||||
OclocFclFacade::~OclocFclFacade() = default;
|
||||
|
||||
int OclocFclFacade::initialize(const HardwareInfo &hwInfo) {
|
||||
fclLib = loadFclLibrary();
|
||||
if (!fclLib) {
|
||||
argHelper->printf("Error! Loading of FCL library has failed! Filename: %s\n", Os::frontEndDllName);
|
||||
return OclocErrorCode::OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
const auto fclCreateMainFunction = loadCreateFclMainFunction();
|
||||
if (!fclCreateMainFunction) {
|
||||
argHelper->printf("Error! Cannot load required functions from FCL library.\n");
|
||||
return OclocErrorCode::OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
fclMain = createFclMain(fclCreateMainFunction);
|
||||
if (!fclMain) {
|
||||
argHelper->printf("Error! Cannot create FCL main component!\n");
|
||||
return OclocErrorCode::OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
if (!isFclInterfaceCompatible()) {
|
||||
const auto incompatibleInterface{getIncompatibleInterface()};
|
||||
argHelper->printf("Error! Incompatible interface in FCL: %s\n", incompatibleInterface.c_str());
|
||||
|
||||
DEBUG_BREAK_IF(true);
|
||||
return OclocErrorCode::OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
fclDeviceCtx = createFclDeviceContext();
|
||||
if (!fclDeviceCtx) {
|
||||
argHelper->printf("Error! Cannot create FCL device context!\n");
|
||||
return OclocErrorCode::OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
fclDeviceCtx->SetOclApiVersion(hwInfo.capabilityTable.clVersionSupport * 10);
|
||||
|
||||
if (shouldPopulateFclInterface()) {
|
||||
const auto platform = getPlatformHandle();
|
||||
if (!platform) {
|
||||
argHelper->printf("Error! FCL device context has not been properly created!\n");
|
||||
return OclocErrorCode::OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
populateFclInterface(*platform, hwInfo.platform);
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
return OclocErrorCode::SUCCESS;
|
||||
}
|
||||
|
||||
std::unique_ptr<OsLibrary> OclocFclFacade::loadFclLibrary() const {
|
||||
return std::unique_ptr<OsLibrary>{OsLibrary::load(Os::frontEndDllName)};
|
||||
}
|
||||
|
||||
CIF::CreateCIFMainFunc_t OclocFclFacade::loadCreateFclMainFunction() const {
|
||||
return reinterpret_cast<CIF::CreateCIFMainFunc_t>(fclLib->getProcAddress(CIF::CreateCIFMainFuncName));
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<CIF::CIFMain> OclocFclFacade::createFclMain(CIF::CreateCIFMainFunc_t createMainFunction) const {
|
||||
return CIF::RAII::UPtr(createMainNoSanitize(createMainFunction));
|
||||
}
|
||||
|
||||
bool OclocFclFacade::isFclInterfaceCompatible() const {
|
||||
return fclMain->IsCompatible<IGC::FclOclDeviceCtx>();
|
||||
}
|
||||
|
||||
std::string OclocFclFacade::getIncompatibleInterface() const {
|
||||
return CIF::InterfaceIdCoder::Dec(fclMain->FindIncompatible<IGC::FclOclDeviceCtx>());
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<IGC::FclOclDeviceCtxTagOCL> OclocFclFacade::createFclDeviceContext() const {
|
||||
return fclMain->CreateInterface<IGC::FclOclDeviceCtxTagOCL>();
|
||||
}
|
||||
|
||||
bool OclocFclFacade::shouldPopulateFclInterface() const {
|
||||
return fclDeviceCtx->GetUnderlyingVersion() > 4U;
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<IGC::PlatformTagOCL> OclocFclFacade::getPlatformHandle() const {
|
||||
return fclDeviceCtx->GetPlatformHandle();
|
||||
}
|
||||
|
||||
void OclocFclFacade::populateFclInterface(IGC::PlatformTagOCL &handle, const PLATFORM &platform) {
|
||||
IGC::PlatformHelper::PopulateInterfaceWith(handle, platform);
|
||||
}
|
||||
|
||||
IGC::CodeType::CodeType_t OclocFclFacade::getPreferredIntermediateRepresentation() const {
|
||||
return fclDeviceCtx->GetPreferredIntermediateRepresentation();
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> OclocFclFacade::createConstBuffer(const void *data, size_t size) {
|
||||
return CIF::Builtins::CreateConstBuffer(fclMain.get(), data, size);
|
||||
}
|
||||
|
||||
CIF::RAII::UPtr_t<IGC::FclOclTranslationCtxTagOCL> OclocFclFacade::createTranslationContext(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType, CIF::Builtins::BufferLatest *error) {
|
||||
return fclDeviceCtx->CreateTranslationCtx(inType, outType, error);
|
||||
}
|
||||
|
||||
bool OclocFclFacade::isInitialized() const {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
} // namespace NEO
|
|
@ -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 "igfxfmid.h"
|
||||
#include "ocl_igc_interface/code_type.h"
|
||||
#include "ocl_igc_interface/fcl_ocl_device_ctx.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class OclocArgHelper;
|
||||
|
||||
namespace NEO {
|
||||
|
||||
class CompilerHwInfoConfig;
|
||||
class OsLibrary;
|
||||
|
||||
struct HardwareInfo;
|
||||
|
||||
class OclocFclFacade {
|
||||
public:
|
||||
OclocFclFacade(OclocArgHelper *argHelper);
|
||||
MOCKABLE_VIRTUAL ~OclocFclFacade();
|
||||
|
||||
OclocFclFacade(OclocFclFacade &) = delete;
|
||||
OclocFclFacade(const OclocFclFacade &&) = delete;
|
||||
OclocFclFacade &operator=(const OclocFclFacade &) = delete;
|
||||
OclocFclFacade &operator=(OclocFclFacade &&) = delete;
|
||||
|
||||
int initialize(const HardwareInfo &hwInfo);
|
||||
bool isInitialized() const;
|
||||
IGC::CodeType::CodeType_t getPreferredIntermediateRepresentation() const;
|
||||
CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> createConstBuffer(const void *data, size_t size);
|
||||
CIF::RAII::UPtr_t<IGC::FclOclTranslationCtxTagOCL> createTranslationContext(IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType, CIF::Builtins::BufferLatest *error);
|
||||
|
||||
protected:
|
||||
MOCKABLE_VIRTUAL std::unique_ptr<OsLibrary> loadFclLibrary() const;
|
||||
MOCKABLE_VIRTUAL CIF::CreateCIFMainFunc_t loadCreateFclMainFunction() const;
|
||||
MOCKABLE_VIRTUAL CIF::RAII::UPtr_t<CIF::CIFMain> createFclMain(CIF::CreateCIFMainFunc_t createMainFunction) const;
|
||||
MOCKABLE_VIRTUAL bool isFclInterfaceCompatible() const;
|
||||
MOCKABLE_VIRTUAL std::string getIncompatibleInterface() const;
|
||||
MOCKABLE_VIRTUAL CIF::RAII::UPtr_t<IGC::FclOclDeviceCtxTagOCL> createFclDeviceContext() const;
|
||||
MOCKABLE_VIRTUAL bool shouldPopulateFclInterface() const;
|
||||
MOCKABLE_VIRTUAL CIF::RAII::UPtr_t<IGC::PlatformTagOCL> getPlatformHandle() const;
|
||||
MOCKABLE_VIRTUAL void populateFclInterface(IGC::PlatformTagOCL &handle, const PLATFORM &platform);
|
||||
|
||||
OclocArgHelper *argHelper{};
|
||||
std::unique_ptr<OsLibrary> fclLib{};
|
||||
CIF::RAII::UPtr_t<CIF::CIFMain> fclMain{};
|
||||
CIF::RAII::UPtr_t<IGC::FclOclDeviceCtxTagOCL> fclDeviceCtx{};
|
||||
bool initialized{false};
|
||||
};
|
||||
|
||||
} // namespace NEO
|
|
@ -32,7 +32,6 @@
|
|||
#include "cif/import/library_api.h"
|
||||
#include "compiler_options.h"
|
||||
#include "igfxfmid.h"
|
||||
#include "ocl_igc_interface/code_type.h"
|
||||
#include "ocl_igc_interface/fcl_ocl_device_ctx.h"
|
||||
#include "ocl_igc_interface/igc_ocl_device_ctx.h"
|
||||
#include "ocl_igc_interface/platform_helper.h"
|
||||
|
@ -56,8 +55,6 @@ using namespace NEO::OclocErrorCode;
|
|||
|
||||
namespace NEO {
|
||||
|
||||
CIF::CIFMain *createMainNoSanitize(CIF::CreateCIFMainFunc_t createFunc);
|
||||
|
||||
std::string convertToPascalCase(const std::string &inString) {
|
||||
std::string outString;
|
||||
bool capitalize = true;
|
||||
|
@ -89,6 +86,7 @@ OfflineCompiler *OfflineCompiler::create(size_t numArgs, const std::vector<std::
|
|||
|
||||
if (pOffCompiler) {
|
||||
pOffCompiler->argHelper = helper;
|
||||
pOffCompiler->fclFacade = std::make_unique<OclocFclFacade>(helper);
|
||||
pOffCompiler->igcFacade = std::make_unique<OclocIgcFacade>(helper);
|
||||
retVal = pOffCompiler->initialize(numArgs, allArgs, dumpFiles);
|
||||
}
|
||||
|
@ -139,15 +137,15 @@ struct OfflineCompiler::buildInfo {
|
|||
|
||||
int OfflineCompiler::buildIrBinary() {
|
||||
int retVal = SUCCESS;
|
||||
UNRECOVERABLE_IF(fclDeviceCtx == nullptr);
|
||||
UNRECOVERABLE_IF(!fclFacade->isInitialized());
|
||||
pBuildInfo->intermediateRepresentation = useLlvmText ? IGC::CodeType::llvmLl
|
||||
: (useLlvmBc ? IGC::CodeType::llvmBc : preferredIntermediateRepresentation);
|
||||
|
||||
//sourceCode.size() returns the number of characters without null terminated char
|
||||
CIF::RAII::UPtr_t<CIF::Builtins::BufferLatest> fclSrc = nullptr;
|
||||
pBuildInfo->fclOptions = CIF::Builtins::CreateConstBuffer(fclMain.get(), options.c_str(), options.size());
|
||||
pBuildInfo->fclInternalOptions = CIF::Builtins::CreateConstBuffer(fclMain.get(), internalOptions.c_str(), internalOptions.size());
|
||||
auto err = CIF::Builtins::CreateConstBuffer(fclMain.get(), nullptr, 0);
|
||||
pBuildInfo->fclOptions = fclFacade->createConstBuffer(options.c_str(), options.size());
|
||||
pBuildInfo->fclInternalOptions = fclFacade->createConstBuffer(internalOptions.c_str(), internalOptions.size());
|
||||
auto err = fclFacade->createConstBuffer(nullptr, 0);
|
||||
|
||||
auto srcType = IGC::CodeType::undefined;
|
||||
std::vector<uint8_t> tempSrcStorage;
|
||||
|
@ -165,13 +163,13 @@ int OfflineCompiler::buildIrBinary() {
|
|||
elfEncoder.appendSection(NEO::Elf::SHT_OPENCL_HEADER, headerName, headerData);
|
||||
}
|
||||
tempSrcStorage = elfEncoder.encode();
|
||||
fclSrc = CIF::Builtins::CreateConstBuffer(fclMain.get(), tempSrcStorage.data(), tempSrcStorage.size());
|
||||
fclSrc = fclFacade->createConstBuffer(tempSrcStorage.data(), tempSrcStorage.size());
|
||||
} else {
|
||||
srcType = IGC::CodeType::oclC;
|
||||
fclSrc = CIF::Builtins::CreateConstBuffer(fclMain.get(), sourceCode.c_str(), sourceCode.size() + 1);
|
||||
fclSrc = fclFacade->createConstBuffer(sourceCode.c_str(), sourceCode.size() + 1);
|
||||
}
|
||||
|
||||
auto fclTranslationCtx = fclDeviceCtx->CreateTranslationCtx(srcType, pBuildInfo->intermediateRepresentation, err.get());
|
||||
auto fclTranslationCtx = fclFacade->createTranslationContext(srcType, pBuildInfo->intermediateRepresentation, err.get());
|
||||
|
||||
if (true == NEO::areNotNullptr(err->GetMemory<char>())) {
|
||||
updateBuildLog(err->GetMemory<char>(), err->GetSizeRaw());
|
||||
|
@ -522,48 +520,13 @@ int OfflineCompiler::initialize(size_t numArgs, const std::vector<std::string> &
|
|||
}
|
||||
|
||||
if ((inputFileSpirV == false) && (inputFileLlvm == false)) {
|
||||
auto fclLibFile = OsLibrary::load(Os::frontEndDllName);
|
||||
|
||||
if (fclLibFile == nullptr) {
|
||||
argHelper->printf("Error: Failed to load %s\n", Os::frontEndDllName);
|
||||
return OUT_OF_HOST_MEMORY;
|
||||
const auto fclInitializationResult = fclFacade->initialize(hwInfo);
|
||||
if (fclInitializationResult != SUCCESS) {
|
||||
argHelper->printf("Error! FCL initialization failure. Error code = %d\n", fclInitializationResult);
|
||||
return fclInitializationResult;
|
||||
}
|
||||
|
||||
this->fclLib.reset(fclLibFile);
|
||||
if (this->fclLib == nullptr) {
|
||||
return OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
auto fclCreateMain = reinterpret_cast<CIF::CreateCIFMainFunc_t>(this->fclLib->getProcAddress(CIF::CreateCIFMainFuncName));
|
||||
if (fclCreateMain == nullptr) {
|
||||
return OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
this->fclMain = CIF::RAII::UPtr(createMainNoSanitize(fclCreateMain));
|
||||
if (this->fclMain == nullptr) {
|
||||
return OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
if (false == this->fclMain->IsCompatible<IGC::FclOclDeviceCtx>()) {
|
||||
argHelper->printf("Incompatible interface in FCL : %s\n", CIF::InterfaceIdCoder::Dec(this->fclMain->FindIncompatible<IGC::FclOclDeviceCtx>()).c_str());
|
||||
DEBUG_BREAK_IF(true);
|
||||
return OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
this->fclDeviceCtx = this->fclMain->CreateInterface<IGC::FclOclDeviceCtxTagOCL>();
|
||||
if (this->fclDeviceCtx == nullptr) {
|
||||
return OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
|
||||
fclDeviceCtx->SetOclApiVersion(hwInfo.capabilityTable.clVersionSupport * 10);
|
||||
preferredIntermediateRepresentation = fclDeviceCtx->GetPreferredIntermediateRepresentation();
|
||||
if (this->fclDeviceCtx->GetUnderlyingVersion() > 4U) {
|
||||
auto igcPlatform = fclDeviceCtx->GetPlatformHandle();
|
||||
if (nullptr == igcPlatform) {
|
||||
return OUT_OF_HOST_MEMORY;
|
||||
}
|
||||
IGC::PlatformHelper::PopulateInterfaceWith(*igcPlatform, hwInfo.platform);
|
||||
}
|
||||
preferredIntermediateRepresentation = fclFacade->getPreferredIntermediateRepresentation();
|
||||
} else {
|
||||
if (!isQuiet()) {
|
||||
argHelper->printf("Compilation from IR - skipping loading of FCL\n");
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
#pragma once
|
||||
|
||||
#include "shared/offline_compiler/source/ocloc_arg_helper.h"
|
||||
#include "shared/offline_compiler/source/ocloc_fcl_facade.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"
|
||||
#include "shared/source/utilities/const_stringref.h"
|
||||
|
||||
#include "cif/common/cif_main.h"
|
||||
#include "ocl_igc_interface/fcl_ocl_device_ctx.h"
|
||||
#include "ocl_igc_interface/code_type.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
@ -160,10 +160,7 @@ class OfflineCompiler {
|
|||
int revisionId = -1;
|
||||
|
||||
std::unique_ptr<OclocIgcFacade> igcFacade{nullptr};
|
||||
|
||||
std::unique_ptr<OsLibrary> fclLib = nullptr;
|
||||
CIF::RAII::UPtr_t<CIF::CIFMain> fclMain = nullptr;
|
||||
CIF::RAII::UPtr_t<IGC::FclOclDeviceCtxTagOCL> fclDeviceCtx = nullptr;
|
||||
std::unique_ptr<OclocFclFacade> fclFacade{nullptr};
|
||||
IGC::CodeType::CodeType_t preferredIntermediateRepresentation;
|
||||
|
||||
OclocArgHelper *argHelper = nullptr;
|
||||
|
|
Loading…
Reference in New Issue