Skip to content

Commit 35a04e5

Browse files
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>
1 parent c637903 commit 35a04e5

File tree

11 files changed

+550
-59
lines changed

11 files changed

+550
-59
lines changed

opencl/test/unit_test/offline_compiler/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ set(IGDRCL_SRCS_offline_compiler_mock
2020
${CMAKE_CURRENT_SOURCE_DIR}/decoder/mock/mock_iga_wrapper.h
2121
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_argument_helper.h
2222
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_multi_command.h
23+
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_ocloc_fcl_facade.h
2324
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_ocloc_igc_facade.h
2425
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_offline_compiler.h
2526
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_offline_linker.h
@@ -62,6 +63,8 @@ set(IGDRCL_SRCS_offline_compiler_tests
6263
${CMAKE_CURRENT_SOURCE_DIR}/ocloc_api_tests.cpp
6364
${CMAKE_CURRENT_SOURCE_DIR}/ocloc_fatbinary_tests.cpp
6465
${CMAKE_CURRENT_SOURCE_DIR}/ocloc_fatbinary_tests.h
66+
${CMAKE_CURRENT_SOURCE_DIR}/ocloc_fcl_facade_tests.cpp
67+
${CMAKE_CURRENT_SOURCE_DIR}/ocloc_fcl_facade_tests.h
6568
${CMAKE_CURRENT_SOURCE_DIR}/ocloc_igc_facade_tests.cpp
6669
${CMAKE_CURRENT_SOURCE_DIR}/ocloc_igc_facade_tests.h
6770
${CMAKE_CURRENT_SOURCE_DIR}/ocloc_product_config_tests.cpp
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright (C) 2022 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#pragma once
9+
10+
#include "shared/offline_compiler/source/ocloc_fcl_facade.h"
11+
12+
#include <optional>
13+
#include <string>
14+
15+
namespace NEO {
16+
17+
class MockOclocFclFacade : public OclocFclFacade {
18+
public:
19+
using OclocFclFacade::fclDeviceCtx;
20+
21+
bool shouldFailLoadingOfFclLib{false};
22+
bool shouldFailLoadingOfFclCreateMainFunction{false};
23+
bool shouldFailCreationOfFclMain{false};
24+
bool shouldFailCreationOfFclDeviceContext{false};
25+
bool shouldReturnInvalidFclPlatformHandle{false};
26+
std::optional<bool> isFclInterfaceCompatibleReturnValue{};
27+
std::optional<std::string> getIncompatibleInterfaceReturnValue{};
28+
std::optional<bool> shouldPopulateFclInterfaceReturnValue{};
29+
int populateFclInterfaceCalledCount{0};
30+
31+
MockOclocFclFacade(OclocArgHelper *argHelper) : OclocFclFacade{argHelper} {}
32+
~MockOclocFclFacade() override = default;
33+
34+
std::unique_ptr<OsLibrary> loadFclLibrary() const override {
35+
if (shouldFailLoadingOfFclLib) {
36+
return nullptr;
37+
} else {
38+
return OclocFclFacade::loadFclLibrary();
39+
}
40+
}
41+
42+
CIF::CreateCIFMainFunc_t loadCreateFclMainFunction() const override {
43+
if (shouldFailLoadingOfFclCreateMainFunction) {
44+
return nullptr;
45+
} else {
46+
return OclocFclFacade::loadCreateFclMainFunction();
47+
}
48+
}
49+
50+
CIF::RAII::UPtr_t<CIF::CIFMain> createFclMain(CIF::CreateCIFMainFunc_t createMainFunction) const override {
51+
if (shouldFailCreationOfFclMain) {
52+
return nullptr;
53+
} else {
54+
return OclocFclFacade::createFclMain(createMainFunction);
55+
}
56+
}
57+
58+
bool isFclInterfaceCompatible() const override {
59+
if (isFclInterfaceCompatibleReturnValue.has_value()) {
60+
return *isFclInterfaceCompatibleReturnValue;
61+
} else {
62+
return OclocFclFacade::isFclInterfaceCompatible();
63+
}
64+
}
65+
66+
std::string getIncompatibleInterface() const override {
67+
if (getIncompatibleInterfaceReturnValue.has_value()) {
68+
return *getIncompatibleInterfaceReturnValue;
69+
} else {
70+
return OclocFclFacade::getIncompatibleInterface();
71+
}
72+
}
73+
74+
CIF::RAII::UPtr_t<IGC::FclOclDeviceCtxTagOCL> createFclDeviceContext() const override {
75+
if (shouldFailCreationOfFclDeviceContext) {
76+
return nullptr;
77+
} else {
78+
return OclocFclFacade::createFclDeviceContext();
79+
}
80+
}
81+
82+
bool shouldPopulateFclInterface() const override {
83+
if (shouldPopulateFclInterfaceReturnValue.has_value()) {
84+
return *shouldPopulateFclInterfaceReturnValue;
85+
} else {
86+
return OclocFclFacade::shouldPopulateFclInterface();
87+
}
88+
}
89+
90+
CIF::RAII::UPtr_t<IGC::PlatformTagOCL> getPlatformHandle() const override {
91+
if (shouldReturnInvalidFclPlatformHandle) {
92+
return nullptr;
93+
} else {
94+
return OclocFclFacade::getPlatformHandle();
95+
}
96+
}
97+
98+
void populateFclInterface(IGC::PlatformTagOCL &handle, const PLATFORM &platform) override {
99+
++populateFclInterfaceCalledCount;
100+
OclocFclFacade::populateFclInterface(handle, platform);
101+
}
102+
};
103+
104+
} // namespace NEO

opencl/test/unit_test/offline_compiler/mock/mock_offline_compiler.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "shared/offline_compiler/source/offline_compiler.h"
1111

1212
#include "opencl/test/unit_test/offline_compiler/mock/mock_argument_helper.h"
13+
#include "opencl/test/unit_test/offline_compiler/mock/mock_ocloc_fcl_facade.h"
1314
#include "opencl/test/unit_test/offline_compiler/mock/mock_ocloc_igc_facade.h"
1415

1516
#include <optional>
@@ -25,7 +26,7 @@ class MockOfflineCompiler : public OfflineCompiler {
2526
using OfflineCompiler::deviceName;
2627
using OfflineCompiler::elfBinary;
2728
using OfflineCompiler::excludeIr;
28-
using OfflineCompiler::fclDeviceCtx;
29+
using OfflineCompiler::fclFacade;
2930
using OfflineCompiler::forceStatelessToStatefulOptimization;
3031
using OfflineCompiler::genBinary;
3132
using OfflineCompiler::genBinarySize;
@@ -62,6 +63,10 @@ class MockOfflineCompiler : public OfflineCompiler {
6263
uniqueHelper->setAllCallBase(true);
6364
argHelper = uniqueHelper.get();
6465

66+
auto uniqueFclFacadeMock = std::make_unique<MockOclocFclFacade>(argHelper);
67+
mockFclFacade = uniqueFclFacadeMock.get();
68+
fclFacade = std::move(uniqueFclFacadeMock);
69+
6570
auto uniqueIgcFacadeMock = std::make_unique<MockOclocIgcFacade>(argHelper);
6671
mockIgcFacade = uniqueIgcFacadeMock.get();
6772
igcFacade = std::move(uniqueIgcFacadeMock);
@@ -125,6 +130,7 @@ class MockOfflineCompiler : public OfflineCompiler {
125130
uint32_t writeOutAllFilesCalled = 0u;
126131
std::unique_ptr<MockOclocArgHelper> uniqueHelper;
127132
MockOclocIgcFacade *mockIgcFacade = nullptr;
133+
MockOclocFclFacade *mockFclFacade = nullptr;
128134
int buildCalledCount{0};
129135
std::optional<int> buildReturnValue{};
130136
bool interceptCreatedDirs{false};
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
* Copyright (C) 2022 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#include "ocloc_fcl_facade_tests.h"
9+
10+
#include "shared/offline_compiler/source/ocloc_error_code.h"
11+
#include "shared/source/debug_settings/debug_settings_manager.h"
12+
#include "shared/source/os_interface/os_inc_base.h"
13+
#include "shared/test/common/helpers/debug_manager_state_restore.h"
14+
15+
#include "mock/mock_ocloc_fcl_facade.h"
16+
17+
#include <string>
18+
19+
namespace NEO {
20+
21+
TEST_F(OclocFclFacadeTest, GivenMissingFclLibraryWhenPreparingFclThenFailureIsReported) {
22+
MockOclocFclFacade mockFclFacade{&mockArgHelper};
23+
mockFclFacade.shouldFailLoadingOfFclLib = true;
24+
25+
::testing::internal::CaptureStdout();
26+
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
27+
const auto output{::testing::internal::GetCapturedStdout()};
28+
29+
EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, fclPreparationResult);
30+
EXPECT_FALSE(mockFclFacade.isInitialized());
31+
32+
std::stringstream expectedErrorMessage;
33+
expectedErrorMessage << "Error! Loading of FCL library has failed! Filename: " << Os::frontEndDllName << "\n";
34+
35+
EXPECT_EQ(expectedErrorMessage.str(), output);
36+
}
37+
38+
TEST_F(OclocFclFacadeTest, GivenFailingLoadingOfFclSymbolsWhenPreparingFclThenFailureIsReported) {
39+
MockOclocFclFacade mockFclFacade{&mockArgHelper};
40+
mockFclFacade.shouldFailLoadingOfFclCreateMainFunction = true;
41+
42+
::testing::internal::CaptureStdout();
43+
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
44+
const auto output{::testing::internal::GetCapturedStdout()};
45+
46+
EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, fclPreparationResult);
47+
EXPECT_FALSE(mockFclFacade.isInitialized());
48+
49+
const std::string expectedErrorMessage{"Error! Cannot load required functions from FCL library.\n"};
50+
EXPECT_EQ(expectedErrorMessage, output);
51+
}
52+
53+
TEST_F(OclocFclFacadeTest, GivenFailingCreationOfFclMainWhenPreparingFclThenFailureIsReported) {
54+
MockOclocFclFacade mockFclFacade{&mockArgHelper};
55+
mockFclFacade.shouldFailCreationOfFclMain = true;
56+
57+
::testing::internal::CaptureStdout();
58+
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
59+
const auto output{::testing::internal::GetCapturedStdout()};
60+
61+
EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, fclPreparationResult);
62+
EXPECT_FALSE(mockFclFacade.isInitialized());
63+
64+
const std::string expectedErrorMessage{"Error! Cannot create FCL main component!\n"};
65+
EXPECT_EQ(expectedErrorMessage, output);
66+
}
67+
68+
TEST_F(OclocFclFacadeTest, GivenIncompatibleFclInterfacesWhenPreparingFclThenFailureIsReported) {
69+
DebugManagerStateRestore stateRestore;
70+
DebugManager.flags.EnableDebugBreak.set(false);
71+
72+
MockOclocFclFacade mockFclFacade{&mockArgHelper};
73+
mockFclFacade.isFclInterfaceCompatibleReturnValue = false;
74+
mockFclFacade.getIncompatibleInterfaceReturnValue = "SomeImportantInterface";
75+
76+
::testing::internal::CaptureStdout();
77+
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
78+
const auto output{::testing::internal::GetCapturedStdout()};
79+
80+
EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, fclPreparationResult);
81+
EXPECT_FALSE(mockFclFacade.isInitialized());
82+
83+
const std::string expectedErrorMessage{"Error! Incompatible interface in FCL: SomeImportantInterface\n"};
84+
EXPECT_EQ(expectedErrorMessage, output);
85+
}
86+
87+
TEST_F(OclocFclFacadeTest, GivenFailingCreationOfFclDeviceContextWhenPreparingFclThenFailureIsReported) {
88+
MockOclocFclFacade mockFclFacade{&mockArgHelper};
89+
mockFclFacade.shouldFailCreationOfFclDeviceContext = true;
90+
91+
::testing::internal::CaptureStdout();
92+
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
93+
const auto output{::testing::internal::GetCapturedStdout()};
94+
95+
EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, fclPreparationResult);
96+
EXPECT_FALSE(mockFclFacade.isInitialized());
97+
98+
const std::string expectedErrorMessage{"Error! Cannot create FCL device context!\n"};
99+
EXPECT_EQ(expectedErrorMessage, output);
100+
}
101+
102+
TEST_F(OclocFclFacadeTest, GivenNoneErrorsSetAndNotPopulateFclInterfaceWhenPreparingFclThenSuccessIsReported) {
103+
MockOclocFclFacade mockFclFacade{&mockArgHelper};
104+
mockFclFacade.shouldPopulateFclInterfaceReturnValue = false;
105+
106+
::testing::internal::CaptureStdout();
107+
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
108+
const auto output{::testing::internal::GetCapturedStdout()};
109+
110+
EXPECT_EQ(OclocErrorCode::SUCCESS, fclPreparationResult);
111+
EXPECT_TRUE(output.empty()) << output;
112+
EXPECT_TRUE(mockFclFacade.isInitialized());
113+
EXPECT_EQ(0, mockFclFacade.populateFclInterfaceCalledCount);
114+
}
115+
116+
TEST_F(OclocFclFacadeTest, GivenPopulateFclInterfaceAndInvalidFclDeviceContextWhenPreparingFclThenFailureIsReported) {
117+
MockOclocFclFacade mockFclFacade{&mockArgHelper};
118+
mockFclFacade.shouldPopulateFclInterfaceReturnValue = true;
119+
mockFclFacade.shouldReturnInvalidFclPlatformHandle = true;
120+
121+
::testing::internal::CaptureStdout();
122+
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
123+
const auto output{::testing::internal::GetCapturedStdout()};
124+
125+
EXPECT_EQ(OclocErrorCode::OUT_OF_HOST_MEMORY, fclPreparationResult);
126+
EXPECT_FALSE(mockFclFacade.isInitialized());
127+
128+
const std::string expectedErrorMessage{"Error! FCL device context has not been properly created!\n"};
129+
EXPECT_EQ(expectedErrorMessage, output);
130+
131+
EXPECT_EQ(0, mockFclFacade.populateFclInterfaceCalledCount);
132+
}
133+
134+
TEST_F(OclocFclFacadeTest, GivenPopulateFclInterfaceWhenPreparingFclThenSuccessIsReported) {
135+
MockOclocFclFacade mockFclFacade{&mockArgHelper};
136+
mockFclFacade.shouldPopulateFclInterfaceReturnValue = true;
137+
138+
::testing::internal::CaptureStdout();
139+
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
140+
const auto output{::testing::internal::GetCapturedStdout()};
141+
142+
EXPECT_EQ(OclocErrorCode::SUCCESS, fclPreparationResult);
143+
EXPECT_TRUE(output.empty()) << output;
144+
EXPECT_TRUE(mockFclFacade.isInitialized());
145+
146+
EXPECT_EQ(1, mockFclFacade.populateFclInterfaceCalledCount);
147+
}
148+
149+
TEST_F(OclocFclFacadeTest, GivenNoneErrorsSetWhenPreparingFclThenSuccessIsReported) {
150+
MockOclocFclFacade mockFclFacade{&mockArgHelper};
151+
152+
::testing::internal::CaptureStdout();
153+
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
154+
const auto output{::testing::internal::GetCapturedStdout()};
155+
156+
EXPECT_EQ(OclocErrorCode::SUCCESS, fclPreparationResult);
157+
EXPECT_TRUE(output.empty()) << output;
158+
EXPECT_TRUE(mockFclFacade.isInitialized());
159+
160+
const auto expectedPopulateCalledCount = mockFclFacade.shouldPopulateFclInterface() ? 1 : 0;
161+
EXPECT_EQ(expectedPopulateCalledCount, mockFclFacade.populateFclInterfaceCalledCount);
162+
}
163+
164+
TEST_F(OclocFclFacadeTest, GivenInitializedFclWhenGettingIncompatibleInterfaceThenEmptyStringIsReturned) {
165+
MockOclocFclFacade mockFclFacade{&mockArgHelper};
166+
167+
::testing::internal::CaptureStdout();
168+
const auto fclPreparationResult{mockFclFacade.initialize(hwInfo)};
169+
const auto output{::testing::internal::GetCapturedStdout()};
170+
171+
ASSERT_EQ(OclocErrorCode::SUCCESS, fclPreparationResult);
172+
173+
const auto incompatibleInterface = mockFclFacade.getIncompatibleInterface();
174+
EXPECT_TRUE(incompatibleInterface.empty()) << incompatibleInterface;
175+
}
176+
177+
} // namespace NEO
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (C) 2022 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
*/
7+
8+
#pragma once
9+
10+
#include "shared/source/helpers/hw_info.h"
11+
12+
#include "gtest/gtest.h"
13+
#include "mock/mock_argument_helper.h"
14+
15+
namespace NEO {
16+
17+
class OclocFclFacadeTest : public ::testing::Test {
18+
protected:
19+
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{};
20+
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
21+
HardwareInfo hwInfo{};
22+
};
23+
24+
} // namespace NEO

0 commit comments

Comments
 (0)