1 /*
2  * Copyright (C) 2018-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "shared/source/compiler_interface/compiler_interface.h"
9 #include "shared/source/compiler_interface/compiler_interface.inl"
10 #include "shared/source/helpers/file_io.h"
11 #include "shared/source/helpers/hw_info.h"
12 #include "shared/test/common/fixtures/device_fixture.h"
13 #include "shared/test/common/helpers/debug_manager_state_restore.h"
14 #include "shared/test/common/helpers/test_files.h"
15 #include "shared/test/common/helpers/unit_test_helper.h"
16 #include "shared/test/common/libult/global_environment.h"
17 #include "shared/test/common/mocks/mock_cif.h"
18 #include "shared/test/common/mocks/mock_compiler_interface.h"
19 #include "shared/test/common/mocks/mock_compilers.h"
20 #include "shared/test/common/test_macros/test.h"
21 
22 #include "gmock/gmock.h"
23 #include "hw_cmds.h"
24 
25 #include <memory>
26 
27 using namespace NEO;
28 
29 #if defined(_WIN32)
30 const char *gBadDompilerDllName = "bad_compiler.dll";
31 #elif defined(__linux__)
32 const char *gCBadDompilerDllName = "libbad_compiler.so";
33 #else
34 #error "Unknown OS!"
35 #endif
36 
37 class CompilerInterfaceTest : public DeviceFixture,
38                               public ::testing::Test {
39   public:
SetUp()40     void SetUp() override {
41         DeviceFixture::SetUp();
42 
43         // create the compiler interface
44         this->pCompilerInterface = new MockCompilerInterface();
45         bool initRet = pCompilerInterface->initialize(std::make_unique<CompilerCache>(CompilerCacheConfig{}), true);
46         ASSERT_TRUE(initRet);
47         pDevice->getExecutionEnvironment()->rootDeviceEnvironments[pDevice->getRootDeviceIndex()]->compilerInterface.reset(pCompilerInterface);
48 
49         std::string testFile;
50 
51         testFile.append(clFiles);
52         testFile.append("CopyBuffer_simd32.cl");
53 
54         pSource = loadDataFromFile(
55             testFile.c_str(),
56             sourceSize);
57 
58         ASSERT_NE(0u, sourceSize);
59         ASSERT_NE(nullptr, pSource);
60 
61         inputArgs.src = ArrayRef<char>(pSource.get(), sourceSize);
62     }
63 
TearDown()64     void TearDown() override {
65         pSource.reset();
66 
67         DeviceFixture::TearDown();
68     }
69 
70     MockCompilerInterface *pCompilerInterface;
71     TranslationInput inputArgs = {IGC::CodeType::oclC, IGC::CodeType::oclGenBin};
72     std::unique_ptr<char[]> pSource = nullptr;
73     size_t sourceSize = 0;
74 };
75 
TEST(CompilerInterface,WhenInitializeIsCalledThenFailIfCompilerCacheHandlerIsEmpty)76 TEST(CompilerInterface, WhenInitializeIsCalledThenFailIfCompilerCacheHandlerIsEmpty) {
77     MockCompilerInterface ci;
78 
79     ci.failLoadFcl = false;
80     ci.failLoadIgc = false;
81     bool initSuccess = ci.initialize(nullptr, true);
82     EXPECT_FALSE(initSuccess);
83 }
84 
TEST(CompilerInterface,WhenInitializeIsCalledThenFailIfOneOfRequiredCompilersIsUnavailable)85 TEST(CompilerInterface, WhenInitializeIsCalledThenFailIfOneOfRequiredCompilersIsUnavailable) {
86     bool initSuccess = false;
87     bool requireFcl = true;
88     MockCompilerInterface ci;
89 
90     ci.failLoadFcl = false;
91     ci.failLoadIgc = false;
92     requireFcl = true;
93     initSuccess = ci.initialize(std::make_unique<CompilerCache>(CompilerCacheConfig{}), requireFcl);
94     EXPECT_TRUE(initSuccess);
95 
96     ci.failLoadFcl = false;
97     ci.failLoadIgc = false;
98     requireFcl = false;
99     initSuccess = ci.initialize(std::make_unique<CompilerCache>(CompilerCacheConfig{}), requireFcl);
100     EXPECT_TRUE(initSuccess);
101 
102     ci.failLoadFcl = true;
103     ci.failLoadIgc = false;
104     requireFcl = false;
105     initSuccess = ci.initialize(std::make_unique<CompilerCache>(CompilerCacheConfig{}), requireFcl);
106     EXPECT_TRUE(initSuccess);
107 
108     ci.failLoadFcl = true;
109     ci.failLoadIgc = false;
110     requireFcl = true;
111     initSuccess = ci.initialize(std::make_unique<CompilerCache>(CompilerCacheConfig{}), requireFcl);
112     EXPECT_FALSE(initSuccess);
113 
114     ci.failLoadFcl = false;
115     ci.failLoadIgc = true;
116     requireFcl = true;
117     initSuccess = ci.initialize(std::make_unique<CompilerCache>(CompilerCacheConfig{}), requireFcl);
118     EXPECT_FALSE(initSuccess);
119 
120     ci.failLoadFcl = false;
121     ci.failLoadIgc = true;
122     requireFcl = false;
123     initSuccess = ci.initialize(std::make_unique<CompilerCache>(CompilerCacheConfig{}), requireFcl);
124     EXPECT_FALSE(initSuccess);
125 
126     ci.failLoadFcl = true;
127     ci.failLoadIgc = true;
128     requireFcl = false;
129     initSuccess = ci.initialize(std::make_unique<CompilerCache>(CompilerCacheConfig{}), requireFcl);
130     EXPECT_FALSE(initSuccess);
131 
132     ci.failLoadFcl = true;
133     ci.failLoadIgc = true;
134     requireFcl = true;
135     initSuccess = ci.initialize(std::make_unique<CompilerCache>(CompilerCacheConfig{}), requireFcl);
136     EXPECT_FALSE(initSuccess);
137 }
138 
TEST(CompilerInterfaceCreateInstance,WhenInitializeFailedThenReturnNull)139 TEST(CompilerInterfaceCreateInstance, WhenInitializeFailedThenReturnNull) {
140     struct FailInitializeCompilerInterface : CompilerInterface {
141         bool initialize(std::unique_ptr<CompilerCache> &&cache, bool requireFcl) override {
142             return false;
143         }
144     };
145     EXPECT_EQ(nullptr, CompilerInterface::createInstance<FailInitializeCompilerInterface>(std::make_unique<CompilerCache>(CompilerCacheConfig{}), false));
146 }
147 
TEST_F(CompilerInterfaceTest,WhenCompilingToIsaThenSuccessIsReturned)148 TEST_F(CompilerInterfaceTest, WhenCompilingToIsaThenSuccessIsReturned) {
149     TranslationOutput translationOutput;
150     auto err = pCompilerInterface->build(*pDevice, inputArgs, translationOutput);
151     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
152 }
153 
TEST_F(CompilerInterfaceTest,WhenPreferredIntermediateRepresentationSpecifiedThenPreserveIt)154 TEST_F(CompilerInterfaceTest, WhenPreferredIntermediateRepresentationSpecifiedThenPreserveIt) {
155     TranslationOutput translationOutput;
156     inputArgs.preferredIntermediateType = IGC::CodeType::llvmLl;
157     auto err = pCompilerInterface->build(*pDevice, inputArgs, translationOutput);
158     EXPECT_EQ(IGC::CodeType::llvmLl, translationOutput.intermediateCodeType);
159     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
160 }
161 
TEST_F(CompilerInterfaceTest,whenCompilerIsNotAvailableThenBuildFailsGracefully)162 TEST_F(CompilerInterfaceTest, whenCompilerIsNotAvailableThenBuildFailsGracefully) {
163     pCompilerInterface->igcMain.reset(nullptr);
164     TranslationOutput translationOutput = {};
165     auto err = pCompilerInterface->build(*pDevice, inputArgs, translationOutput);
166     EXPECT_EQ(TranslationOutput::ErrorCode::CompilerNotAvailable, err);
167 }
168 
TEST_F(CompilerInterfaceTest,whenFclTranslatorReturnsNullptrThenBuildFailsGracefully)169 TEST_F(CompilerInterfaceTest, whenFclTranslatorReturnsNullptrThenBuildFailsGracefully) {
170     pCompilerInterface->failCreateFclTranslationCtx = true;
171     TranslationOutput translationOutput = {};
172     auto err = pCompilerInterface->build(*pDevice, inputArgs, translationOutput);
173     pCompilerInterface->failCreateFclTranslationCtx = false;
174     EXPECT_EQ(TranslationOutput::ErrorCode::UnknownError, err);
175 }
176 
TEST_F(CompilerInterfaceTest,whenIgcTranslatorReturnsNullptrThenBuildFailsGracefully)177 TEST_F(CompilerInterfaceTest, whenIgcTranslatorReturnsNullptrThenBuildFailsGracefully) {
178     pCompilerInterface->failCreateIgcTranslationCtx = true;
179     TranslationOutput translationOutput = {};
180     auto err = pCompilerInterface->build(*pDevice, inputArgs, translationOutput);
181     pCompilerInterface->failCreateIgcTranslationCtx = true;
182     EXPECT_EQ(TranslationOutput::ErrorCode::UnknownError, err);
183 }
184 
TEST_F(CompilerInterfaceTest,GivenOptionsWhenCompilingToIsaThenSuccessIsReturned)185 TEST_F(CompilerInterfaceTest, GivenOptionsWhenCompilingToIsaThenSuccessIsReturned) {
186     std::string internalOptions = "SOME_OPTION";
187 
188     MockCompilerDebugVars fclDebugVars;
189     fclDebugVars.fileName = gEnvironment->fclGetMockFile();
190     fclDebugVars.internalOptionsExpected = true;
191     gEnvironment->fclPushDebugVars(fclDebugVars);
192 
193     MockCompilerDebugVars igcDebugVars;
194     igcDebugVars.fileName = gEnvironment->igcGetMockFile();
195     igcDebugVars.internalOptionsExpected = true;
196     gEnvironment->igcPushDebugVars(igcDebugVars);
197 
198     inputArgs.internalOptions = ArrayRef<const char>(internalOptions.c_str(), internalOptions.length());
199 
200     TranslationOutput translationOutput = {};
201     auto err = pCompilerInterface->build(*pDevice, inputArgs, translationOutput);
202     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
203 
204     gEnvironment->fclPopDebugVars();
205     gEnvironment->igcPopDebugVars();
206 }
207 
TEST_F(CompilerInterfaceTest,WhenCompilingToIrThenSuccessIsReturned)208 TEST_F(CompilerInterfaceTest, WhenCompilingToIrThenSuccessIsReturned) {
209     MockCompilerDebugVars fclDebugVars;
210     retrieveBinaryKernelFilename(fclDebugVars.fileName, "CopyBuffer_simd32_", ".bc");
211     gEnvironment->fclPushDebugVars(fclDebugVars);
212     TranslationOutput translationOutput = {};
213     auto err = pCompilerInterface->compile(*pDevice, inputArgs, translationOutput);
214     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
215 
216     gEnvironment->fclPopDebugVars();
217 }
218 
TEST_F(CompilerInterfaceTest,GivenProgramCreatedFromIrWhenCompileIsCalledThenDontRecompile)219 TEST_F(CompilerInterfaceTest, GivenProgramCreatedFromIrWhenCompileIsCalledThenDontRecompile) {
220     TranslationOutput translationOutput = {};
221     inputArgs.srcType = IGC::CodeType::spirV;
222     auto err = pCompilerInterface->compile(*pDevice, inputArgs, translationOutput);
223     EXPECT_EQ(TranslationOutput::ErrorCode::AlreadyCompiled, err);
224 
225     inputArgs.srcType = IGC::CodeType::llvmBc;
226     err = pCompilerInterface->compile(*pDevice, inputArgs, translationOutput);
227     EXPECT_EQ(TranslationOutput::ErrorCode::AlreadyCompiled, err);
228 
229     inputArgs.srcType = IGC::CodeType::llvmLl;
230     err = pCompilerInterface->compile(*pDevice, inputArgs, translationOutput);
231     EXPECT_EQ(TranslationOutput::ErrorCode::AlreadyCompiled, err);
232 
233     inputArgs.srcType = IGC::CodeType::oclGenBin;
234     err = pCompilerInterface->compile(*pDevice, inputArgs, translationOutput);
235     EXPECT_EQ(TranslationOutput::ErrorCode::AlreadyCompiled, err);
236 }
237 
TEST_F(CompilerInterfaceTest,whenCompilerIsNotAvailableThenCompileFailsGracefully)238 TEST_F(CompilerInterfaceTest, whenCompilerIsNotAvailableThenCompileFailsGracefully) {
239     MockCompilerDebugVars fclDebugVars;
240     fclDebugVars.fileName = clFiles + "copybuffer.elf";
241     gEnvironment->fclPushDebugVars(fclDebugVars);
242     pCompilerInterface->igcMain->Release();
243     pCompilerInterface->setIgcMain(nullptr);
244     TranslationOutput translationOutput = {};
245     auto err = pCompilerInterface->compile(*pDevice, inputArgs, translationOutput);
246     EXPECT_EQ(TranslationOutput::ErrorCode::CompilerNotAvailable, err);
247 
248     gEnvironment->fclPopDebugVars();
249 }
250 
TEST_F(CompilerInterfaceTest,whenFclTranslatorReturnsNullptrThenCompileFailsGracefully)251 TEST_F(CompilerInterfaceTest, whenFclTranslatorReturnsNullptrThenCompileFailsGracefully) {
252     MockCompilerDebugVars fclDebugVars;
253     fclDebugVars.fileName = clFiles + "copybuffer.elf";
254     gEnvironment->fclPushDebugVars(fclDebugVars);
255     pCompilerInterface->failCreateFclTranslationCtx = true;
256     TranslationOutput translationOutput = {};
257     auto err = pCompilerInterface->compile(*pDevice, inputArgs, translationOutput);
258     pCompilerInterface->failCreateFclTranslationCtx = false;
259     EXPECT_EQ(TranslationOutput::ErrorCode::UnknownError, err);
260 
261     gEnvironment->fclPopDebugVars();
262 }
263 
TEST_F(CompilerInterfaceTest,GivenForceBuildFailureWhenCompilingToIrThenCompilationFailureErrorIsReturned)264 TEST_F(CompilerInterfaceTest, GivenForceBuildFailureWhenCompilingToIrThenCompilationFailureErrorIsReturned) {
265     MockCompilerDebugVars fclDebugVars;
266     fclDebugVars.fileName = "../copybuffer.elf";
267     fclDebugVars.forceBuildFailure = true;
268     gEnvironment->fclPushDebugVars(fclDebugVars);
269     TranslationOutput translationOutput = {};
270     auto err = pCompilerInterface->compile(*pDevice, inputArgs, translationOutput);
271     EXPECT_EQ(TranslationOutput::ErrorCode::CompilationFailure, err);
272 
273     gEnvironment->fclPopDebugVars();
274 }
275 
TEST_F(CompilerInterfaceTest,GivenForceBuildFailureWhenLinkingIrThenLinkFailureErrorIsReturned)276 TEST_F(CompilerInterfaceTest, GivenForceBuildFailureWhenLinkingIrThenLinkFailureErrorIsReturned) {
277     MockCompilerDebugVars igcDebugVars;
278     igcDebugVars.fileName = "../copybuffer.ll";
279     igcDebugVars.forceBuildFailure = true;
280     gEnvironment->igcPushDebugVars(igcDebugVars);
281     TranslationOutput translationOutput = {};
282     auto err = pCompilerInterface->link(*pDevice, inputArgs, translationOutput);
283     EXPECT_EQ(TranslationOutput::ErrorCode::LinkFailure, err);
284 
285     gEnvironment->igcPopDebugVars();
286 }
287 
TEST_F(CompilerInterfaceTest,WhenLinkIsCalledThenLlvmBcIsUsedAsIntermediateRepresentation)288 TEST_F(CompilerInterfaceTest, WhenLinkIsCalledThenLlvmBcIsUsedAsIntermediateRepresentation) {
289     // link only from .ll to gen ISA
290     MockCompilerDebugVars igcDebugVars;
291     retrieveBinaryKernelFilename(igcDebugVars.fileName, "CopyBuffer_simd32_", ".bc");
292     gEnvironment->igcPushDebugVars(igcDebugVars);
293     TranslationOutput translationOutput = {};
294     auto err = pCompilerInterface->link(*pDevice, inputArgs, translationOutput);
295     gEnvironment->igcPopDebugVars();
296     ASSERT_EQ(TranslationOutput::ErrorCode::Success, err);
297     ASSERT_EQ(2U, pCompilerInterface->requestedTranslationCtxs.size());
298 
299     MockCompilerInterface::TranslationOpT firstTranslation = {IGC::CodeType::elf, IGC::CodeType::llvmBc},
300                                           secondTranslation = {IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin};
301     EXPECT_EQ(firstTranslation, pCompilerInterface->requestedTranslationCtxs[0]);
302     EXPECT_EQ(secondTranslation, pCompilerInterface->requestedTranslationCtxs[1]);
303 }
304 
TEST_F(CompilerInterfaceTest,whenCompilerIsNotAvailableThenLinkFailsGracefully)305 TEST_F(CompilerInterfaceTest, whenCompilerIsNotAvailableThenLinkFailsGracefully) {
306     MockCompilerDebugVars igcDebugVars;
307     igcDebugVars.fileName = clFiles + "copybuffer.ll";
308     gEnvironment->igcPushDebugVars(igcDebugVars);
309     pCompilerInterface->igcMain->Release();
310     pCompilerInterface->setIgcMain(nullptr);
311     TranslationOutput translationOutput = {};
312     auto err = pCompilerInterface->link(*pDevice, inputArgs, translationOutput);
313     EXPECT_EQ(TranslationOutput::ErrorCode::CompilerNotAvailable, err);
314 
315     gEnvironment->igcPopDebugVars();
316 }
317 
TEST_F(CompilerInterfaceTest,whenSrcAllocationFailsThenLinkFailsGracefully)318 TEST_F(CompilerInterfaceTest, whenSrcAllocationFailsThenLinkFailsGracefully) {
319     MockCompilerDebugVars igcDebugVars;
320     igcDebugVars.fileName = clFiles + "copybuffer.ll";
321     gEnvironment->igcPushDebugVars(igcDebugVars);
322     MockCIFBuffer::failAllocations = true;
323     TranslationOutput translationOutput = {};
324     auto err = pCompilerInterface->link(*pDevice, inputArgs, translationOutput);
325     MockCIFBuffer::failAllocations = false;
326     EXPECT_EQ(TranslationOutput::ErrorCode::UnknownError, err);
327 
328     gEnvironment->igcPopDebugVars();
329 }
330 
TEST_F(CompilerInterfaceTest,whenTranslateReturnsNullptrThenLinkFailsGracefully)331 TEST_F(CompilerInterfaceTest, whenTranslateReturnsNullptrThenLinkFailsGracefully) {
332     MockCompilerDebugVars igcDebugVars;
333     igcDebugVars.fileName = clFiles + "copybuffer.ll";
334     gEnvironment->igcPushDebugVars(igcDebugVars);
335     pCompilerInterface->failCreateIgcTranslationCtx = true;
336     TranslationOutput translationOutput = {};
337     auto err = pCompilerInterface->link(*pDevice, inputArgs, translationOutput);
338     pCompilerInterface->failCreateIgcTranslationCtx = false;
339     EXPECT_EQ(TranslationOutput::ErrorCode::UnknownError, err);
340 
341     gEnvironment->igcPopDebugVars();
342 }
343 
TEST_F(CompilerInterfaceTest,GivenForceBuildFailureWhenCreatingLibraryThenLinkFailureErrorIsReturned)344 TEST_F(CompilerInterfaceTest, GivenForceBuildFailureWhenCreatingLibraryThenLinkFailureErrorIsReturned) {
345     // create library from .ll to IR
346     MockCompilerDebugVars igcDebugVars;
347     igcDebugVars.fileName = "../copybuffer.ll";
348     igcDebugVars.forceBuildFailure = true;
349     gEnvironment->igcPushDebugVars(igcDebugVars);
350     TranslationOutput translationOutput = {};
351     auto err = pCompilerInterface->createLibrary(*pDevice, inputArgs, translationOutput);
352     EXPECT_EQ(TranslationOutput::ErrorCode::LinkFailure, err);
353 
354     gEnvironment->igcPopDebugVars();
355 }
356 
TEST_F(CompilerInterfaceTest,WhenCreateLibraryIsCalledThenLlvmBcIsUsedAsIntermediateRepresentation)357 TEST_F(CompilerInterfaceTest, WhenCreateLibraryIsCalledThenLlvmBcIsUsedAsIntermediateRepresentation) {
358     // create library from .ll to IR
359     MockCompilerDebugVars igcDebugVars;
360     retrieveBinaryKernelFilename(igcDebugVars.fileName, "CopyBuffer_simd32_", ".bc");
361     gEnvironment->igcPushDebugVars(igcDebugVars);
362     TranslationOutput translationOutput = {};
363     auto err = pCompilerInterface->createLibrary(*pDevice, inputArgs, translationOutput);
364     gEnvironment->igcPopDebugVars();
365     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
366     ASSERT_EQ(1U, pCompilerInterface->requestedTranslationCtxs.size());
367 
368     EXPECT_EQ(IGC::CodeType::llvmBc, pCompilerInterface->requestedTranslationCtxs[0].second);
369 }
370 
TEST_F(CompilerInterfaceTest,whenCompilerIsNotAvailableThenCreateLibraryFailsGracefully)371 TEST_F(CompilerInterfaceTest, whenCompilerIsNotAvailableThenCreateLibraryFailsGracefully) {
372     MockCompilerDebugVars igcDebugVars;
373     igcDebugVars.fileName = clFiles + "copybuffer.ll";
374     gEnvironment->igcPushDebugVars(igcDebugVars);
375     pCompilerInterface->igcMain->Release();
376     pCompilerInterface->setIgcMain(nullptr);
377     TranslationOutput translationOutput = {};
378     auto err = pCompilerInterface->createLibrary(*pDevice, inputArgs, translationOutput);
379     EXPECT_EQ(TranslationOutput::ErrorCode::CompilerNotAvailable, err);
380 
381     gEnvironment->igcPopDebugVars();
382 }
383 
TEST_F(CompilerInterfaceTest,whenIgcTranslatorReturnsNullptrThenCreateLibraryFailsGracefully)384 TEST_F(CompilerInterfaceTest, whenIgcTranslatorReturnsNullptrThenCreateLibraryFailsGracefully) {
385     MockCompilerDebugVars igcDebugVars;
386     igcDebugVars.fileName = clFiles + "copybuffer.ll";
387     gEnvironment->igcPushDebugVars(igcDebugVars);
388     pCompilerInterface->failCreateIgcTranslationCtx = true;
389     TranslationOutput translationOutput = {};
390     auto err = pCompilerInterface->createLibrary(*pDevice, inputArgs, translationOutput);
391     pCompilerInterface->failCreateIgcTranslationCtx = false;
392     EXPECT_EQ(TranslationOutput::ErrorCode::UnknownError, err);
393 
394     gEnvironment->igcPopDebugVars();
395 }
396 
TEST_F(CompilerInterfaceTest,GivenForceBuildFailureWhenFclBuildingThenBuildFailureErrorIsReturned)397 TEST_F(CompilerInterfaceTest, GivenForceBuildFailureWhenFclBuildingThenBuildFailureErrorIsReturned) {
398     MockCompilerDebugVars fclDebugVars;
399     fclDebugVars.forceCreateFailure = false;
400     fclDebugVars.forceBuildFailure = true;
401     fclDebugVars.forceRegisterFail = false;
402     fclDebugVars.fileName = "copybuffer_skl.bc";
403 
404     gEnvironment->fclPushDebugVars(fclDebugVars);
405 
406     TranslationOutput translationOutput = {};
407     auto err = pCompilerInterface->build(*pDevice, inputArgs, translationOutput);
408     EXPECT_EQ(TranslationOutput::ErrorCode::BuildFailure, err);
409 
410     gEnvironment->fclPopDebugVars();
411 }
412 
TEST_F(CompilerInterfaceTest,GivenForceBuildFailureWhenIgcBuildingThenBuildFailureErrorIsReturned)413 TEST_F(CompilerInterfaceTest, GivenForceBuildFailureWhenIgcBuildingThenBuildFailureErrorIsReturned) {
414     MockCompilerDebugVars igcDebugVars;
415     igcDebugVars.forceCreateFailure = false;
416     igcDebugVars.forceBuildFailure = true;
417     igcDebugVars.forceRegisterFail = false;
418     igcDebugVars.fileName = "copybuffer_skl.gen";
419 
420     gEnvironment->igcPushDebugVars(igcDebugVars);
421 
422     TranslationOutput translationOutput = {};
423     auto err = pCompilerInterface->build(*pDevice, inputArgs, translationOutput);
424     EXPECT_EQ(TranslationOutput::ErrorCode::BuildFailure, err);
425 
426     gEnvironment->igcPopDebugVars();
427 }
428 
429 struct TranslationCtxMock {
430     bool returnNullptr = false;
431     bool returnNullptrOutput = false;
432     bool returnNullptrLog = false;
433     bool returnNullptrDebugData = false;
434 
435     CIF::Builtins::BufferSimple *receivedSrc = nullptr;
436     CIF::Builtins::BufferSimple *receivedOpt = nullptr;
437     CIF::Builtins::BufferSimple *receivedIntOpt = nullptr;
438     CIF::Builtins::BufferSimple *receivedTracingOpt = nullptr;
439 
TranslateTranslationCtxMock440     CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> Translate(CIF::Builtins::BufferSimple *src,
441                                                                  CIF::Builtins::BufferSimple *options,
442                                                                  CIF::Builtins::BufferSimple *internalOptions,
443                                                                  CIF::Builtins::BufferSimple *tracingOptions,
444                                                                  uint32_t tracingOptionsCount) { // NOLINT(readability-identifier-naming)
445         this->receivedSrc = src;
446         this->receivedOpt = options;
447         this->receivedIntOpt = internalOptions;
448         this->receivedTracingOpt = tracingOptions;
449 
450         if (returnNullptr) {
451             return CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL>(nullptr);
452         }
453 
454         auto ret = new MockOclTranslationOutput();
455         if (returnNullptrOutput) {
456             ret->output->Release();
457             ret->output = nullptr;
458         }
459 
460         if (returnNullptrLog) {
461             ret->log->Release();
462             ret->log = nullptr;
463         }
464 
465         if (returnNullptrDebugData) {
466             ret->debugData->Release();
467             ret->debugData = nullptr;
468         }
469 
470         return CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL>(ret);
471     }
TranslateTranslationCtxMock472     CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> Translate(CIF::Builtins::BufferSimple *src,
473                                                                  CIF::Builtins::BufferSimple *options,
474                                                                  CIF::Builtins::BufferSimple *internalOptions,
475                                                                  CIF::Builtins::BufferSimple *tracingOptions,
476                                                                  uint32_t tracingOptionsCount,
477                                                                  void *gtpinInit) { // NOLINT(readability-identifier-naming)
478         return this->Translate(src, options, internalOptions, tracingOptions, tracingOptionsCount);
479     }
TranslateTranslationCtxMock480     CIF::RAII::UPtr_t<IGC::OclTranslationOutputTagOCL> Translate(CIF::Builtins::BufferSimple *src,
481                                                                  CIF::Builtins::BufferSimple *specConstantsIds,
482                                                                  CIF::Builtins::BufferSimple *specConstantsValues,
483                                                                  CIF::Builtins::BufferSimple *options,
484                                                                  CIF::Builtins::BufferSimple *internalOptions,
485                                                                  CIF::Builtins::BufferSimple *tracingOptions,
486                                                                  uint32_t tracingOptionsCount,
487                                                                  void *gtPinInput) { // NOLINT(readability-identifier-naming)
488         return this->Translate(src, options, internalOptions, tracingOptions, tracingOptionsCount);
489     }
490 };
491 
TEST(TranslateTest,whenArgsAreValidAndTranslatorReturnsValidOutputThenValidOutputIsReturned)492 TEST(TranslateTest, whenArgsAreValidAndTranslatorReturnsValidOutputThenValidOutputIsReturned) {
493     TranslationCtxMock mockTranslationCtx;
494     auto mockSrc = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
495     auto mockOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
496     auto mockIntOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
497 
498     auto ret = NEO::translate(&mockTranslationCtx, mockSrc.get(), mockOpt.get(), mockIntOpt.get());
499     EXPECT_NE(nullptr, ret);
500 
501     EXPECT_EQ(mockSrc.get(), mockTranslationCtx.receivedSrc);
502     EXPECT_EQ(mockOpt.get(), mockTranslationCtx.receivedOpt);
503     EXPECT_EQ(mockIntOpt.get(), mockTranslationCtx.receivedIntOpt);
504 }
505 
TEST(TranslateTest,givenGtPinInputWhenArgsAreValidAndTranslatorReturnsValidOutputThenValidOutputIsReturned)506 TEST(TranslateTest, givenGtPinInputWhenArgsAreValidAndTranslatorReturnsValidOutputThenValidOutputIsReturned) {
507     TranslationCtxMock mockTranslationCtx;
508     auto mockSrc = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
509     auto mockOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
510     auto mockIntOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
511 
512     auto ret = NEO::translate(&mockTranslationCtx, mockSrc.get(), mockOpt.get(), mockIntOpt.get(), nullptr);
513     EXPECT_NE(nullptr, ret);
514 
515     EXPECT_EQ(mockSrc.get(), mockTranslationCtx.receivedSrc);
516     EXPECT_EQ(mockOpt.get(), mockTranslationCtx.receivedOpt);
517     EXPECT_EQ(mockIntOpt.get(), mockTranslationCtx.receivedIntOpt);
518 }
519 
TEST(TranslateTest,whenArgsAreInvalidThenNullptrIsReturned)520 TEST(TranslateTest, whenArgsAreInvalidThenNullptrIsReturned) {
521     auto mockSrc = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
522     auto mockOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
523     auto mockIntOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
524 
525     auto ret = NEO::translate<TranslationCtxMock>(nullptr, mockSrc.get(), mockOpt.get(), mockIntOpt.get());
526 
527     EXPECT_EQ(nullptr, ret);
528 }
529 
TEST(TranslateTest,givenGtPinInputWhenArgsAreInvalidThenNullptrIsReturned)530 TEST(TranslateTest, givenGtPinInputWhenArgsAreInvalidThenNullptrIsReturned) {
531     auto mockSrc = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
532     auto mockOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
533     auto mockIntOpt = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
534 
535     auto ret = NEO::translate<TranslationCtxMock>(nullptr, mockSrc.get(), mockOpt.get(), mockIntOpt.get(), nullptr);
536 
537     EXPECT_EQ(nullptr, ret);
538 }
539 
TEST(TranslateTest,whenTranslatorReturnsNullptrThenNullptrIsReturned)540 TEST(TranslateTest, whenTranslatorReturnsNullptrThenNullptrIsReturned) {
541     TranslationCtxMock mockTranslationCtx;
542     mockTranslationCtx.returnNullptr = true;
543     auto mockCifBuffer = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
544 
545     auto ret = NEO::translate(&mockTranslationCtx, mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get());
546     EXPECT_EQ(nullptr, ret);
547 }
548 
TEST(TranslateTest,givenSpecConstantsBuffersWhenTranslatorReturnsNullptrThenNullptrIsReturned)549 TEST(TranslateTest, givenSpecConstantsBuffersWhenTranslatorReturnsNullptrThenNullptrIsReturned) {
550     TranslationCtxMock mockTranslationCtx;
551     mockTranslationCtx.returnNullptr = true;
552     auto mockCifBuffer = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
553 
554     auto ret = NEO::translate(&mockTranslationCtx, mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), nullptr);
555     EXPECT_EQ(nullptr, ret);
556 }
557 
TEST(TranslateTest,givenNullPtrAsGtPinInputWhenTranslatorReturnsNullptrThenNullptrIsReturned)558 TEST(TranslateTest, givenNullPtrAsGtPinInputWhenTranslatorReturnsNullptrThenNullptrIsReturned) {
559     TranslationCtxMock mockTranslationCtx;
560     mockTranslationCtx.returnNullptr = true;
561     auto mockCifBuffer = std::make_unique<MockCIFBuffer>();
562 
563     auto ret = NEO::translate(&mockTranslationCtx, mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), nullptr);
564     EXPECT_EQ(nullptr, ret);
565 }
566 
TEST(TranslateTest,whenTranslatorReturnsInvalidOutputThenNullptrIsReturned)567 TEST(TranslateTest, whenTranslatorReturnsInvalidOutputThenNullptrIsReturned) {
568     TranslationCtxMock mockTranslationCtx;
569     auto mockCifBuffer = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
570     for (uint32_t i = 1; i <= maxNBitValue(3); ++i) {
571         mockTranslationCtx.returnNullptrDebugData = (i & 1) != 0;
572         mockTranslationCtx.returnNullptrLog = (i & (1 << 1)) != 0;
573         mockTranslationCtx.returnNullptrOutput = (i & (1 << 2)) != 0;
574         auto ret = NEO::translate(&mockTranslationCtx, mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get());
575         EXPECT_EQ(nullptr, ret);
576     }
577 }
578 
TEST(TranslateTest,givenNullPtrAsGtPinInputWhenTranslatorReturnsInvalidOutputThenNullptrIsReturned)579 TEST(TranslateTest, givenNullPtrAsGtPinInputWhenTranslatorReturnsInvalidOutputThenNullptrIsReturned) {
580     TranslationCtxMock mockTranslationCtx;
581     auto mockCifBuffer = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
582     for (uint32_t i = 1; i <= maxNBitValue(3); ++i) {
583         mockTranslationCtx.returnNullptrDebugData = (i & 1) != 0;
584         mockTranslationCtx.returnNullptrLog = (i & (1 << 1)) != 0;
585         mockTranslationCtx.returnNullptrOutput = (i & (1 << 2)) != 0;
586         auto ret = NEO::translate(&mockTranslationCtx, mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), nullptr);
587         EXPECT_EQ(nullptr, ret);
588     }
589 }
590 
TEST(TranslateTest,givenSpecConstantsBuffersAndNullPtrAsGtPinInputWhenTranslatorReturnsInvalidOutputThenNullptrIsReturned)591 TEST(TranslateTest, givenSpecConstantsBuffersAndNullPtrAsGtPinInputWhenTranslatorReturnsInvalidOutputThenNullptrIsReturned) {
592     TranslationCtxMock mockTranslationCtx;
593     auto mockCifBuffer = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
594     for (uint32_t i = 1; i <= maxNBitValue(3); ++i) {
595         mockTranslationCtx.returnNullptrDebugData = (i & 1) != 0;
596         mockTranslationCtx.returnNullptrLog = (i & (1 << 1)) != 0;
597         mockTranslationCtx.returnNullptrOutput = (i & (1 << 2)) != 0;
598         auto ret = NEO::translate(&mockTranslationCtx, mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), mockCifBuffer.get(), nullptr);
599         EXPECT_EQ(nullptr, ret);
600     }
601 }
602 
TEST(TranslateTest,whenAnyArgIsNullThenNullptrIsReturnedAndTranslatorIsNotInvoked)603 TEST(TranslateTest, whenAnyArgIsNullThenNullptrIsReturnedAndTranslatorIsNotInvoked) {
604     TranslationCtxMock mockTranslationCtx;
605     auto mockCifBuffer = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
606     for (uint32_t i = 0; i < maxNBitValue(3); ++i) {
607         auto src = (i & 1) ? mockCifBuffer.get() : nullptr;
608         auto opts = (i & (1 << 1)) ? mockCifBuffer.get() : nullptr;
609         auto intOpts = (i & (1 << 2)) ? mockCifBuffer.get() : nullptr;
610 
611         auto ret = NEO::translate(&mockTranslationCtx, src, opts, intOpts);
612         EXPECT_EQ(nullptr, ret);
613     }
614 
615     EXPECT_EQ(nullptr, mockTranslationCtx.receivedSrc);
616     EXPECT_EQ(nullptr, mockTranslationCtx.receivedOpt);
617     EXPECT_EQ(nullptr, mockTranslationCtx.receivedIntOpt);
618     EXPECT_EQ(nullptr, mockTranslationCtx.receivedTracingOpt);
619 }
620 
TEST(LoadCompilerTest,whenEverythingIsOkThenReturnsTrueAndValidOutputs)621 TEST(LoadCompilerTest, whenEverythingIsOkThenReturnsTrueAndValidOutputs) {
622     MockCompilerEnableGuard mock;
623     std::unique_ptr<NEO::OsLibrary> retLib;
624     CIF::RAII::UPtr_t<CIF::CIFMain> retMain;
625     bool retVal = loadCompiler<IGC::IgcOclDeviceCtx>("", retLib, retMain);
626     EXPECT_TRUE(retVal);
627     EXPECT_NE(nullptr, retLib.get());
628     EXPECT_NE(nullptr, retMain.get());
629 }
630 
TEST(LoadCompilerTest,whenCouldNotLoadLibraryThenReturnFalseAndNullOutputs)631 TEST(LoadCompilerTest, whenCouldNotLoadLibraryThenReturnFalseAndNullOutputs) {
632     MockCompilerEnableGuard mock;
633     std::unique_ptr<NEO::OsLibrary> retLib;
634     CIF::RAII::UPtr_t<CIF::CIFMain> retMain;
635     bool retVal = loadCompiler<IGC::IgcOclDeviceCtx>("_falseName.notRealLib", retLib, retMain);
636     EXPECT_FALSE(retVal);
637     EXPECT_EQ(nullptr, retLib.get());
638     EXPECT_EQ(nullptr, retMain.get());
639 }
640 
TEST(LoadCompilerTest,whenCreateMainFailsThenReturnFalseAndNullOutputs)641 TEST(LoadCompilerTest, whenCreateMainFailsThenReturnFalseAndNullOutputs) {
642     NEO::failCreateCifMain = true;
643 
644     MockCompilerEnableGuard mock;
645     std::unique_ptr<NEO::OsLibrary> retLib;
646     CIF::RAII::UPtr_t<CIF::CIFMain> retMain;
647     bool retVal = loadCompiler<IGC::IgcOclDeviceCtx>("", retLib, retMain);
648     EXPECT_FALSE(retVal);
649     EXPECT_EQ(nullptr, retLib.get());
650     EXPECT_EQ(nullptr, retMain.get());
651 
652     NEO::failCreateCifMain = false;
653 }
654 
TEST(LoadCompilerTest,whenEntrypointInterfaceIsNotCompatibleThenReturnFalseAndNullOutputs)655 TEST(LoadCompilerTest, whenEntrypointInterfaceIsNotCompatibleThenReturnFalseAndNullOutputs) {
656     MockCompilerEnableGuard mock;
657     std::unique_ptr<NEO::OsLibrary> retLib;
658     CIF::RAII::UPtr_t<CIF::CIFMain> retMain;
659     bool retVal = loadCompiler<IGC::GTSystemInfo>("", retLib, retMain);
660     EXPECT_FALSE(retVal);
661     EXPECT_EQ(nullptr, retLib.get());
662     EXPECT_EQ(nullptr, retMain.get());
663 }
664 
TEST(LoadCompilerTest,GivenZebinIgnoreIcbeVersionDebugFlagThenIgnoreIgcsIcbeVersion)665 TEST(LoadCompilerTest, GivenZebinIgnoreIcbeVersionDebugFlagThenIgnoreIgcsIcbeVersion) {
666     DebugManagerStateRestore dbgRestore;
667     DebugManager.flags.ZebinIgnoreIcbeVersion.set(true);
668 
669     MockCompilerEnableGuard mock;
670     std::unique_ptr<NEO::OsLibrary> retLib;
671     CIF::RAII::UPtr_t<CIF::CIFMain> retMain;
672     bool retVal = loadCompiler<IGC::IgcOclDeviceCtx>("", retLib, retMain);
673     EXPECT_TRUE(retVal);
674     EXPECT_NE(nullptr, retLib.get());
675     EXPECT_NE(nullptr, retMain.get());
676 }
677 
678 template <typename DeviceCtxBase, typename TranslationCtx>
679 struct MockCompilerDeviceCtx : DeviceCtxBase {
CreateTranslationCtxImplMockCompilerDeviceCtx680     TranslationCtx *CreateTranslationCtxImpl(CIF::Version_t ver, IGC::CodeType::CodeType_t inType,
681                                              IGC::CodeType::CodeType_t outType) override { // NOLINT(readability-identifier-naming)
682         returned = new TranslationCtx;
683         return returned;
684     }
685 
686     TranslationCtx *returned = nullptr;
687 };
688 
689 template <typename DeviceCtx, typename MockDeviceCtx>
690 struct LockListener {
LockListenerLockListener691     LockListener(NEO::Device *device)
692         : device(device) {
693     }
694 
listenerLockListener695     static void listener(MockCompilerInterface &compInt) {
696         auto data = (LockListener *)compInt.lockListenerData;
697         auto deviceCtx = CIF::RAII::UPtr(new MockDeviceCtx);
698         EXPECT_TRUE(compInt.getDeviceContexts<DeviceCtx>().empty());
699         compInt.setDeviceCtx(*data->device, deviceCtx.get());
700         data->createdDeviceCtx = deviceCtx.get();
701     }
702 
703     NEO::Device *device = nullptr;
704     MockDeviceCtx *createdDeviceCtx = nullptr;
705 };
706 
707 struct WasLockedListener {
listenerWasLockedListener708     static void listener(MockCompilerInterface &compInt) {
709         auto data = (WasLockedListener *)compInt.lockListenerData;
710         data->wasLocked = true;
711     }
712     bool wasLocked = false;
713 };
714 
TEST_F(CompilerInterfaceTest,givenUpdatedSpecConstValuesWhenBuildProgramThenProperValuesArePassed)715 TEST_F(CompilerInterfaceTest, givenUpdatedSpecConstValuesWhenBuildProgramThenProperValuesArePassed) {
716     struct MockTranslationContextSpecConst : public MockIgcOclTranslationCtx {
717         IGC::OclTranslationOutputBase *TranslateImpl(
718             CIF::Version_t outVersion,
719             CIF::Builtins::BufferSimple *src,
720             CIF::Builtins::BufferSimple *specConstantsIds,
721             CIF::Builtins::BufferSimple *specConstantsValues,
722             CIF::Builtins::BufferSimple *options,
723             CIF::Builtins::BufferSimple *internalOptions,
724             CIF::Builtins::BufferSimple *tracingOptions,
725             uint32_t tracingOptionsCount,
726             void *gtPinInput) override {
727             EXPECT_EQ(10u, specConstantsIds->GetMemory<uint32_t>()[0]);
728             EXPECT_EQ(100u, specConstantsValues->GetMemory<uint64_t>()[0]);
729             return new MockOclTranslationOutput();
730         }
731     };
732 
733     auto specConstCtx = CIF::RAII::UPtr(new MockCompilerDeviceCtx<MockIgcOclDeviceCtx, MockTranslationContextSpecConst>());
734     pCompilerInterface->setDeviceCtx(*pDevice, specConstCtx.get());
735 
736     specConstValuesMap specConst{{10, 100}};
737     inputArgs.specializedValues = specConst;
738 
739     TranslationOutput translationOutput;
740     auto err = pCompilerInterface->build(*pDevice, inputArgs, translationOutput);
741 
742     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
743 }
744 
TEST_F(CompilerInterfaceTest,GivenRequestForNewFclTranslationCtxWhenDeviceCtxIsNotAvailableThenCreateNewDeviceCtxAndUseItToReturnValidTranslationCtx)745 TEST_F(CompilerInterfaceTest, GivenRequestForNewFclTranslationCtxWhenDeviceCtxIsNotAvailableThenCreateNewDeviceCtxAndUseItToReturnValidTranslationCtx) {
746     auto device = this->pDevice;
747     auto ret = this->pCompilerInterface->createFclTranslationCtx(*device, IGC::CodeType::oclC, IGC::CodeType::spirV);
748     EXPECT_NE(nullptr, ret.get());
749     auto firstBaseCtx = this->pCompilerInterface->getFclBaseTranslationCtx();
750     EXPECT_NE(nullptr, firstBaseCtx);
751 
752     MockDevice md;
753     auto ret2 = this->pCompilerInterface->createFclTranslationCtx(md, IGC::CodeType::oclC, IGC::CodeType::spirV);
754     EXPECT_NE(nullptr, ret2.get());
755     EXPECT_EQ(firstBaseCtx, this->pCompilerInterface->getFclBaseTranslationCtx());
756 }
757 
TEST_F(CompilerInterfaceTest,GivenRequestForNewFclTranslationCtxWhenDeviceCtxIsAlreadyAvailableThenUseItToReturnValidTranslationCtx)758 TEST_F(CompilerInterfaceTest, GivenRequestForNewFclTranslationCtxWhenDeviceCtxIsAlreadyAvailableThenUseItToReturnValidTranslationCtx) {
759     auto device = this->pDevice;
760     auto deviceCtx = CIF::RAII::UPtr(new MockCompilerDeviceCtx<MockFclOclDeviceCtx, MockFclOclTranslationCtx>);
761     this->pCompilerInterface->setFclDeviceCtx(*device, deviceCtx.get());
762     auto ret = this->pCompilerInterface->createFclTranslationCtx(*device, IGC::CodeType::oclC, IGC::CodeType::spirV);
763     EXPECT_NE(nullptr, ret.get());
764     EXPECT_EQ(deviceCtx->returned, ret.get());
765 }
766 
TEST_F(CompilerInterfaceTest,GivenSimultaneousRequestForNewFclTranslationContextsWhenDeviceCtxIsNotAlreadyAvailableThenSynchronizeToCreateOnlyOneNewDeviceCtx)767 TEST_F(CompilerInterfaceTest, GivenSimultaneousRequestForNewFclTranslationContextsWhenDeviceCtxIsNotAlreadyAvailableThenSynchronizeToCreateOnlyOneNewDeviceCtx) {
768     auto device = this->pDevice;
769 
770     using ListenerT = LockListener<IGC::FclOclDeviceCtxTagOCL, MockFclOclDeviceCtx>;
771     ListenerT listenerData(device);
772     this->pCompilerInterface->lockListenerData = &listenerData;
773     this->pCompilerInterface->lockListener = ListenerT::listener;
774 
775     auto ret = this->pCompilerInterface->createFclTranslationCtx(*device, IGC::CodeType::oclC, IGC::CodeType::spirV);
776     EXPECT_NE(nullptr, ret.get());
777     ASSERT_EQ(1U, this->pCompilerInterface->getFclDeviceContexts().size());
778     ASSERT_NE(this->pCompilerInterface->getFclDeviceContexts().end(),
779               this->pCompilerInterface->getFclDeviceContexts().find(device));
780     EXPECT_NE(nullptr, listenerData.createdDeviceCtx);
781     EXPECT_EQ(listenerData.createdDeviceCtx, this->pCompilerInterface->getFclDeviceContexts()[device].get());
782 
783     WasLockedListener wasLockedListenerData;
784     this->pCompilerInterface->lockListenerData = &wasLockedListenerData;
785     this->pCompilerInterface->lockListener = WasLockedListener::listener;
786     ret = this->pCompilerInterface->createFclTranslationCtx(*device, IGC::CodeType::spirV, IGC::CodeType::oclGenBin);
787     EXPECT_NE(nullptr, ret.get());
788     ASSERT_EQ(1U, this->pCompilerInterface->getFclDeviceContexts().size());
789     EXPECT_TRUE(wasLockedListenerData.wasLocked);
790 }
791 
TEST_F(CompilerInterfaceTest,GivenRequestForNewTranslationCtxWhenFclMainIsNotAvailableThenReturnNullptr)792 TEST_F(CompilerInterfaceTest, GivenRequestForNewTranslationCtxWhenFclMainIsNotAvailableThenReturnNullptr) {
793     NEO::failCreateCifMain = true;
794 
795     auto device = this->pDevice;
796     MockCompilerInterface tempCompilerInterface;
797     auto retFcl = tempCompilerInterface.createFclTranslationCtx(*device, IGC::CodeType::oclC, IGC::CodeType::spirV);
798     EXPECT_EQ(nullptr, retFcl);
799     auto retIgc = tempCompilerInterface.createIgcTranslationCtx(*device, IGC::CodeType::oclC, IGC::CodeType::spirV);
800     EXPECT_EQ(nullptr, retIgc);
801 
802     NEO::failCreateCifMain = false;
803 }
804 
TEST_F(CompilerInterfaceTest,GivenRequestForNewTranslationCtxWhenCouldNotCreateDeviceCtxThenReturnNullptr)805 TEST_F(CompilerInterfaceTest, GivenRequestForNewTranslationCtxWhenCouldNotCreateDeviceCtxThenReturnNullptr) {
806     auto device = this->pDevice;
807 
808     auto befFclMock = NEO::MockCIFMain::getGlobalCreatorFunc<NEO::MockFclOclDeviceCtx>();
809     auto befIgcMock = NEO::MockCIFMain::getGlobalCreatorFunc<NEO::MockIgcOclDeviceCtx>();
810     NEO::MockCIFMain::setGlobalCreatorFunc<NEO::MockFclOclDeviceCtx>(nullptr);
811     NEO::MockCIFMain::setGlobalCreatorFunc<NEO::MockIgcOclDeviceCtx>(nullptr);
812 
813     auto retFcl = pCompilerInterface->createFclTranslationCtx(*device, IGC::CodeType::oclC, IGC::CodeType::spirV);
814     EXPECT_EQ(nullptr, retFcl);
815 
816     auto retIgc = pCompilerInterface->createIgcTranslationCtx(*device, IGC::CodeType::oclC, IGC::CodeType::spirV);
817     EXPECT_EQ(nullptr, retIgc);
818 
819     NEO::MockCIFMain::setGlobalCreatorFunc<NEO::MockFclOclDeviceCtx>(befFclMock);
820     NEO::MockCIFMain::setGlobalCreatorFunc<NEO::MockIgcOclDeviceCtx>(befIgcMock);
821 }
822 
TEST_F(CompilerInterfaceTest,GivenRequestForNewIgcTranslationCtxWhenDeviceCtxIsAlreadyAvailableThenUseItToReturnValidTranslationCtx)823 TEST_F(CompilerInterfaceTest, GivenRequestForNewIgcTranslationCtxWhenDeviceCtxIsAlreadyAvailableThenUseItToReturnValidTranslationCtx) {
824     auto device = this->pDevice;
825     auto deviceCtx = CIF::RAII::UPtr(new MockCompilerDeviceCtx<MockIgcOclDeviceCtx, MockIgcOclTranslationCtx>);
826     this->pCompilerInterface->setIgcDeviceCtx(*device, deviceCtx.get());
827     auto ret = this->pCompilerInterface->createIgcTranslationCtx(*device, IGC::CodeType::spirV, IGC::CodeType::oclGenBin);
828     EXPECT_NE(nullptr, ret.get());
829     EXPECT_EQ(deviceCtx->returned, ret.get());
830 }
831 
TEST_F(CompilerInterfaceTest,GivenSimultaneousRequestForNewIgcTranslationContextsWhenDeviceCtxIsNotAlreadyAvailableThenSynchronizeToCreateOnlyOneNewDeviceCtx)832 TEST_F(CompilerInterfaceTest, GivenSimultaneousRequestForNewIgcTranslationContextsWhenDeviceCtxIsNotAlreadyAvailableThenSynchronizeToCreateOnlyOneNewDeviceCtx) {
833     auto device = this->pDevice;
834 
835     using ListenerT = LockListener<IGC::IgcOclDeviceCtxTagOCL, MockIgcOclDeviceCtx>;
836     ListenerT listenerData{device};
837     this->pCompilerInterface->lockListenerData = &listenerData;
838     this->pCompilerInterface->lockListener = ListenerT::listener;
839 
840     auto ret = this->pCompilerInterface->createIgcTranslationCtx(*device, IGC::CodeType::spirV, IGC::CodeType::oclGenBin);
841     EXPECT_NE(nullptr, ret.get());
842     ASSERT_EQ(1U, this->pCompilerInterface->getIgcDeviceContexts().size());
843     ASSERT_NE(this->pCompilerInterface->getIgcDeviceContexts().end(),
844               this->pCompilerInterface->getIgcDeviceContexts().find(device));
845     EXPECT_NE(nullptr, listenerData.createdDeviceCtx);
846     EXPECT_EQ(listenerData.createdDeviceCtx, this->pCompilerInterface->getIgcDeviceContexts()[device].get());
847 
848     WasLockedListener wasLockedListenerData;
849     this->pCompilerInterface->lockListenerData = &wasLockedListenerData;
850     this->pCompilerInterface->lockListener = WasLockedListener::listener;
851     ret = this->pCompilerInterface->createIgcTranslationCtx(*device, IGC::CodeType::spirV, IGC::CodeType::oclGenBin);
852     EXPECT_NE(nullptr, ret.get());
853     ASSERT_EQ(1U, this->pCompilerInterface->getIgcDeviceContexts().size());
854     EXPECT_TRUE(wasLockedListenerData.wasLocked);
855 }
856 
TEST_F(CompilerInterfaceTest,GivenRequestForNewIgcTranslationCtxWhenCouldNotPopulatePlatformInfoThenReturnNullptr)857 TEST_F(CompilerInterfaceTest, GivenRequestForNewIgcTranslationCtxWhenCouldNotPopulatePlatformInfoThenReturnNullptr) {
858     auto device = this->pDevice;
859 
860     auto prevDebugVars = getIgcDebugVars();
861 
862     for (uint32_t i = 1; i < (1 << 3); ++i) {
863         this->pCompilerInterface->getIgcDeviceContexts().clear();
864 
865         auto debugVars = prevDebugVars;
866         debugVars.failCreatePlatformInterface = (i & 1) != 0;
867         debugVars.failCreateIgcFeWaInterface = (i & (1 << 2)) != 0;
868         debugVars.failCreateGtSystemInfoInterface = (i & (1 << 1)) != 0;
869         setIgcDebugVars(debugVars);
870 
871         auto ret = pCompilerInterface->createIgcTranslationCtx(*device, IGC::CodeType::spirV, IGC::CodeType::oclGenBin);
872         EXPECT_EQ(nullptr, ret);
873     }
874 
875     setIgcDebugVars(prevDebugVars);
876 }
877 
TEST_F(CompilerInterfaceTest,givenNoDbgKeyForceUseDifferentPlatformWhenRequestForNewTranslationCtxThenUseDefaultPlatform)878 TEST_F(CompilerInterfaceTest, givenNoDbgKeyForceUseDifferentPlatformWhenRequestForNewTranslationCtxThenUseDefaultPlatform) {
879     auto device = this->pDevice;
880     auto retIgc = pCompilerInterface->createIgcTranslationCtx(*device, IGC::CodeType::spirV, IGC::CodeType::oclGenBin);
881     EXPECT_NE(nullptr, retIgc);
882     IGC::IgcOclDeviceCtxTagOCL *devCtx = pCompilerInterface->peekIgcDeviceCtx(device);
883     auto igcPlatform = devCtx->GetPlatformHandle();
884     auto igcSysInfo = devCtx->GetGTSystemInfoHandle();
885     EXPECT_EQ(device->getHardwareInfo().platform.eProductFamily, igcPlatform->GetProductFamily());
886     EXPECT_EQ(device->getHardwareInfo().platform.eRenderCoreFamily, igcPlatform->GetRenderCoreFamily());
887     EXPECT_EQ(device->getHardwareInfo().gtSystemInfo.SliceCount, igcSysInfo->GetSliceCount());
888     EXPECT_EQ(device->getHardwareInfo().gtSystemInfo.SubSliceCount, igcSysInfo->GetSubSliceCount());
889     EXPECT_EQ(device->getHardwareInfo().gtSystemInfo.EUCount, igcSysInfo->GetEUCount());
890     EXPECT_EQ(device->getHardwareInfo().gtSystemInfo.ThreadCount, igcSysInfo->GetThreadCount());
891 }
892 
TEST_F(CompilerInterfaceTest,givenDbgKeyForceUseDifferentPlatformWhenRequestForNewTranslationCtxThenUseDbgKeyPlatform)893 TEST_F(CompilerInterfaceTest, givenDbgKeyForceUseDifferentPlatformWhenRequestForNewTranslationCtxThenUseDbgKeyPlatform) {
894     DebugManagerStateRestore dbgRestore;
895     auto dbgProdFamily = DEFAULT_TEST_PLATFORM::hwInfo.platform.eProductFamily;
896     std::string dbgPlatformString(hardwarePrefix[dbgProdFamily]);
897     const PLATFORM dbgPlatform = hardwareInfoTable[dbgProdFamily]->platform;
898     const GT_SYSTEM_INFO dbgSystemInfo = hardwareInfoTable[dbgProdFamily]->gtSystemInfo;
899     DebugManager.flags.ForceCompilerUsePlatform.set(dbgPlatformString);
900 
901     auto device = this->pDevice;
902     auto retIgc = pCompilerInterface->createIgcTranslationCtx(*device, IGC::CodeType::spirV, IGC::CodeType::oclGenBin);
903     EXPECT_NE(nullptr, retIgc);
904     IGC::IgcOclDeviceCtxTagOCL *devCtx = pCompilerInterface->peekIgcDeviceCtx(device);
905     auto igcPlatform = devCtx->GetPlatformHandle();
906     auto igcSysInfo = devCtx->GetGTSystemInfoHandle();
907 
908     EXPECT_EQ(dbgPlatform.eProductFamily, igcPlatform->GetProductFamily());
909     EXPECT_EQ(dbgPlatform.eRenderCoreFamily, igcPlatform->GetRenderCoreFamily());
910     EXPECT_EQ(dbgSystemInfo.SliceCount, igcSysInfo->GetSliceCount());
911     EXPECT_EQ(dbgSystemInfo.SubSliceCount, igcSysInfo->GetSubSliceCount());
912     EXPECT_EQ(dbgSystemInfo.DualSubSliceCount, igcSysInfo->GetSubSliceCount());
913     EXPECT_EQ(dbgSystemInfo.EUCount, igcSysInfo->GetEUCount());
914     EXPECT_EQ(dbgSystemInfo.ThreadCount, igcSysInfo->GetThreadCount());
915 }
916 
TEST_F(CompilerInterfaceTest,GivenCompilerWhenGettingCompilerAvailabilityThenCompilerHasCorrectCapabilities)917 TEST_F(CompilerInterfaceTest, GivenCompilerWhenGettingCompilerAvailabilityThenCompilerHasCorrectCapabilities) {
918     ASSERT_TRUE(this->pCompilerInterface->igcMain && this->pCompilerInterface->fclMain);
919     EXPECT_TRUE(this->pCompilerInterface->isFclAvailable());
920     EXPECT_TRUE(this->pCompilerInterface->isIgcAvailable());
921     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::oclGenBin));
922     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::spirV));
923     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::llvmBc));
924     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::llvmLl));
925     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::spirV, IGC::CodeType::oclGenBin));
926     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin));
927     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::llvmLl, IGC::CodeType::oclGenBin));
928     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::elf, IGC::CodeType::llvmBc));
929     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::elf, IGC::CodeType::oclGenBin));
930 
931     auto befIgcImain = std::move(this->pCompilerInterface->igcMain);
932     EXPECT_TRUE(this->pCompilerInterface->isFclAvailable());
933     EXPECT_FALSE(this->pCompilerInterface->isIgcAvailable());
934     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::oclGenBin));
935     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::spirV));
936     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::llvmBc));
937     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::llvmLl));
938     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::spirV, IGC::CodeType::oclGenBin));
939     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin));
940     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::llvmLl, IGC::CodeType::oclGenBin));
941     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::elf, IGC::CodeType::llvmBc));
942     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::elf, IGC::CodeType::oclGenBin));
943     this->pCompilerInterface->igcMain = std::move(befIgcImain);
944 
945     auto befFclImain = std::move(this->pCompilerInterface->fclMain);
946     EXPECT_FALSE(this->pCompilerInterface->isFclAvailable());
947     EXPECT_TRUE(this->pCompilerInterface->isIgcAvailable());
948     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::oclGenBin));
949     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::spirV));
950     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::llvmBc));
951     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::llvmLl));
952     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::spirV, IGC::CodeType::oclGenBin));
953     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin));
954     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::llvmLl, IGC::CodeType::oclGenBin));
955     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::elf, IGC::CodeType::llvmBc));
956     EXPECT_TRUE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::elf, IGC::CodeType::oclGenBin));
957     this->pCompilerInterface->fclMain = std::move(befFclImain);
958 
959     befIgcImain = std::move(this->pCompilerInterface->igcMain);
960     befFclImain = std::move(this->pCompilerInterface->fclMain);
961     EXPECT_FALSE(this->pCompilerInterface->isFclAvailable());
962     EXPECT_FALSE(this->pCompilerInterface->isIgcAvailable());
963     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::oclGenBin));
964     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::spirV));
965     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::llvmBc));
966     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::oclC, IGC::CodeType::llvmLl));
967     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::spirV, IGC::CodeType::oclGenBin));
968     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin));
969     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::llvmLl, IGC::CodeType::oclGenBin));
970     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::elf, IGC::CodeType::llvmBc));
971     EXPECT_FALSE(this->pCompilerInterface->isCompilerAvailable(IGC::CodeType::elf, IGC::CodeType::oclGenBin));
972     this->pCompilerInterface->igcMain = std::move(befIgcImain);
973     this->pCompilerInterface->fclMain = std::move(befFclImain);
974 }
975 
TEST_F(CompilerInterfaceTest,whenCompilerIsNotAvailableThenGetSipKernelBinaryFailsGracefully)976 TEST_F(CompilerInterfaceTest, whenCompilerIsNotAvailableThenGetSipKernelBinaryFailsGracefully) {
977     pCompilerInterface->igcMain.reset();
978     std::vector<char> sipBinary;
979     std::vector<char> stateAreaHeader;
980     auto err = pCompilerInterface->getSipKernelBinary(*this->pDevice, SipKernelType::Csr, sipBinary, stateAreaHeader);
981     EXPECT_EQ(TranslationOutput::ErrorCode::CompilerNotAvailable, err);
982     EXPECT_EQ(0U, sipBinary.size());
983 }
984 
TEST_F(CompilerInterfaceTest,whenIgcReturnsErrorThenGetSipKernelBinaryFailsGracefully)985 TEST_F(CompilerInterfaceTest, whenIgcReturnsErrorThenGetSipKernelBinaryFailsGracefully) {
986     MockCompilerDebugVars igcDebugVars;
987     igcDebugVars.forceBuildFailure = true;
988     gEnvironment->igcPushDebugVars(igcDebugVars);
989 
990     std::vector<char> sipBinary;
991     std::vector<char> stateAreaHeader;
992     auto err = pCompilerInterface->getSipKernelBinary(*this->pDevice, SipKernelType::Csr, sipBinary, stateAreaHeader);
993     EXPECT_EQ(TranslationOutput::ErrorCode::UnknownError, err);
994     EXPECT_EQ(0U, sipBinary.size());
995 
996     gEnvironment->igcPopDebugVars();
997 }
998 
TEST_F(CompilerInterfaceTest,whenGetIgcDeviceCtxReturnsNullptrThenGetSipKernelBinaryFailsGracefully)999 TEST_F(CompilerInterfaceTest, whenGetIgcDeviceCtxReturnsNullptrThenGetSipKernelBinaryFailsGracefully) {
1000     pCompilerInterface->failGetIgcDeviceCtx = true;
1001 
1002     std::vector<char> sipBinary;
1003     std::vector<char> stateAreaHeader;
1004     auto err = pCompilerInterface->getSipKernelBinary(*this->pDevice, SipKernelType::Csr, sipBinary, stateAreaHeader);
1005     EXPECT_EQ(TranslationOutput::ErrorCode::UnknownError, err);
1006 }
1007 
TEST_F(CompilerInterfaceTest,whenEverythingIsOkThenGetSipKernelReturnsIgcsOutputAsSipBinary)1008 TEST_F(CompilerInterfaceTest, whenEverythingIsOkThenGetSipKernelReturnsIgcsOutputAsSipBinary) {
1009     MockCompilerDebugVars igcDebugVars;
1010     retrieveBinaryKernelFilename(igcDebugVars.fileName, "CopyBuffer_simd32_", ".bc");
1011     gEnvironment->igcPushDebugVars(igcDebugVars);
1012     std::vector<char> sipBinary;
1013     std::vector<char> stateAreaHeader;
1014     auto err = pCompilerInterface->getSipKernelBinary(*this->pDevice, SipKernelType::Csr, sipBinary, stateAreaHeader);
1015     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
1016     EXPECT_NE(0U, sipBinary.size());
1017 
1018     gEnvironment->igcPopDebugVars();
1019 }
1020 
TEST_F(CompilerInterfaceTest,whenRequestingSipKernelBinaryThenProperSystemRoutineIsSelectedFromCompiler)1021 TEST_F(CompilerInterfaceTest, whenRequestingSipKernelBinaryThenProperSystemRoutineIsSelectedFromCompiler) {
1022     MockCompilerDebugVars igcDebugVars;
1023     gEnvironment->igcPushDebugVars(igcDebugVars);
1024     std::vector<char> sipBinary;
1025     std::vector<char> stateAreaHeader;
1026     auto err = pCompilerInterface->getSipKernelBinary(*this->pDevice, SipKernelType::Csr, sipBinary, stateAreaHeader);
1027     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
1028     EXPECT_NE(0U, sipBinary.size());
1029     EXPECT_EQ(IGC::SystemRoutineType::contextSaveRestore, getIgcDebugVars().typeOfSystemRoutine);
1030 
1031     err = pCompilerInterface->getSipKernelBinary(*this->pDevice, SipKernelType::DbgCsr, sipBinary, stateAreaHeader);
1032     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
1033     EXPECT_NE(0U, sipBinary.size());
1034     EXPECT_EQ(IGC::SystemRoutineType::debug, getIgcDebugVars().typeOfSystemRoutine);
1035 
1036     err = pCompilerInterface->getSipKernelBinary(*this->pDevice, SipKernelType::DbgCsrLocal, sipBinary, stateAreaHeader);
1037     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
1038     EXPECT_NE(0U, sipBinary.size());
1039     EXPECT_EQ(IGC::SystemRoutineType::debugSlm, getIgcDebugVars().typeOfSystemRoutine);
1040 
1041     gEnvironment->igcPopDebugVars();
1042 }
1043 
TEST_F(CompilerInterfaceTest,WhenRequestingBindlessDebugSipThenProperSystemRoutineIsSelectedFromCompiler)1044 TEST_F(CompilerInterfaceTest, WhenRequestingBindlessDebugSipThenProperSystemRoutineIsSelectedFromCompiler) {
1045     MockCompilerDebugVars igcDebugVars;
1046     gEnvironment->igcPushDebugVars(igcDebugVars);
1047     std::vector<char> sipBinary;
1048     std::vector<char> stateAreaHeader;
1049     auto err = pCompilerInterface->getSipKernelBinary(*this->pDevice, SipKernelType::Csr, sipBinary, stateAreaHeader);
1050     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
1051     EXPECT_NE(0U, sipBinary.size());
1052     EXPECT_EQ(IGC::SystemRoutineType::contextSaveRestore, getIgcDebugVars().typeOfSystemRoutine);
1053     EXPECT_EQ(MockCompilerDebugVars::SipAddressingType::bindful, getIgcDebugVars().receivedSipAddressingType);
1054 
1055     err = pCompilerInterface->getSipKernelBinary(*this->pDevice, SipKernelType::DbgCsrLocal, sipBinary, stateAreaHeader);
1056     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
1057     EXPECT_NE(0U, sipBinary.size());
1058     EXPECT_EQ(IGC::SystemRoutineType::debugSlm, getIgcDebugVars().typeOfSystemRoutine);
1059     EXPECT_EQ(MockCompilerDebugVars::SipAddressingType::bindful, getIgcDebugVars().receivedSipAddressingType);
1060 
1061     err = pCompilerInterface->getSipKernelBinary(*this->pDevice, SipKernelType::DbgBindless, sipBinary, stateAreaHeader);
1062     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
1063     EXPECT_NE(0U, sipBinary.size());
1064     EXPECT_EQ(IGC::SystemRoutineType::debug, getIgcDebugVars().typeOfSystemRoutine);
1065     EXPECT_EQ(MockCompilerDebugVars::SipAddressingType::bindless, getIgcDebugVars().receivedSipAddressingType);
1066 
1067     gEnvironment->igcPopDebugVars();
1068 }
1069 
TEST_F(CompilerInterfaceTest,whenRequestingInvalidSipKernelBinaryThenErrorIsReturned)1070 TEST_F(CompilerInterfaceTest, whenRequestingInvalidSipKernelBinaryThenErrorIsReturned) {
1071     MockCompilerDebugVars igcDebugVars;
1072     gEnvironment->igcPushDebugVars(igcDebugVars);
1073     std::vector<char> sipBinary;
1074     std::vector<char> stateAreaHeader;
1075     auto err = pCompilerInterface->getSipKernelBinary(*this->pDevice, SipKernelType::COUNT, sipBinary, stateAreaHeader);
1076     EXPECT_EQ(TranslationOutput::ErrorCode::UnknownError, err);
1077     EXPECT_EQ(0U, sipBinary.size());
1078     EXPECT_EQ(IGC::SystemRoutineType::undefined, getIgcDebugVars().typeOfSystemRoutine);
1079 
1080     gEnvironment->igcPopDebugVars();
1081 }
1082 
TEST_F(CompilerInterfaceTest,whenCompilerIsNotAvailableThenGetSpecializationConstantsFails)1083 TEST_F(CompilerInterfaceTest, whenCompilerIsNotAvailableThenGetSpecializationConstantsFails) {
1084     pCompilerInterface->igcMain.reset();
1085     NEO::SpecConstantInfo sci;
1086     auto err = pCompilerInterface->getSpecConstantsInfo(*pDevice, ArrayRef<char>{}, sci);
1087     EXPECT_EQ(TranslationOutput::ErrorCode::CompilerNotAvailable, err);
1088 }
1089 
TEST_F(CompilerInterfaceTest,GivenRequestForNewFclTranslationCtxWhenInterfaceVersionAbove4ThenPopulatePlatformInfo)1090 TEST_F(CompilerInterfaceTest, GivenRequestForNewFclTranslationCtxWhenInterfaceVersionAbove4ThenPopulatePlatformInfo) {
1091     auto device = this->pDevice;
1092 
1093     auto prevDebugVars = getFclDebugVars();
1094 
1095     auto debugVars = prevDebugVars;
1096     debugVars.overrideFclDeviceCtxVersion = 5;
1097 
1098     setFclDebugVars(debugVars);
1099 
1100     auto ret = pCompilerInterface->createFclTranslationCtx(*device, IGC::CodeType::oclC, IGC::CodeType::spirV);
1101     ASSERT_NE(nullptr, ret);
1102     ASSERT_EQ(1U, pCompilerInterface->fclDeviceContexts.size());
1103     auto platform = pCompilerInterface->fclDeviceContexts.begin()->second->GetPlatformHandle();
1104     ASSERT_NE(nullptr, platform);
1105     EXPECT_EQ(device->getHardwareInfo().platform.eProductFamily, platform->GetProductFamily());
1106 
1107     setFclDebugVars(prevDebugVars);
1108 }
1109 
TEST_F(CompilerInterfaceTest,GivenRequestForNewFclTranslationCtxWhenCouldNotPopulatePlatformInfoAndInterfaceVersionAbove4ThenReturnNullptr)1110 TEST_F(CompilerInterfaceTest, GivenRequestForNewFclTranslationCtxWhenCouldNotPopulatePlatformInfoAndInterfaceVersionAbove4ThenReturnNullptr) {
1111     auto device = this->pDevice;
1112 
1113     auto prevDebugVars = getFclDebugVars();
1114 
1115     auto debugVars = prevDebugVars;
1116     debugVars.failCreatePlatformInterface = true;
1117     debugVars.overrideFclDeviceCtxVersion = 5;
1118 
1119     setFclDebugVars(debugVars);
1120 
1121     auto ret = pCompilerInterface->createFclTranslationCtx(*device, IGC::CodeType::oclC, IGC::CodeType::spirV);
1122     EXPECT_EQ(nullptr, ret);
1123 
1124     setFclDebugVars(prevDebugVars);
1125 }
1126 
TEST_F(CompilerInterfaceTest,GivenRequestForNewFclTranslationCtxWhenInterfaceVersion4ThenDontPopulatePlatformInfo)1127 TEST_F(CompilerInterfaceTest, GivenRequestForNewFclTranslationCtxWhenInterfaceVersion4ThenDontPopulatePlatformInfo) {
1128     auto device = this->pDevice;
1129 
1130     auto prevDebugVars = getFclDebugVars();
1131 
1132     auto debugVars = prevDebugVars;
1133     debugVars.failCreatePlatformInterface = true;
1134     debugVars.overrideFclDeviceCtxVersion = 4;
1135 
1136     setFclDebugVars(debugVars);
1137 
1138     auto ret = pCompilerInterface->createFclTranslationCtx(*device, IGC::CodeType::oclC, IGC::CodeType::spirV);
1139     EXPECT_NE(nullptr, ret);
1140 
1141     setFclDebugVars(prevDebugVars);
1142 }
1143 
1144 struct SpecConstantsTranslationCtxMock {
1145     bool returnFalse = false;
1146 
1147     CIF::Builtins::BufferSimple *receivedSrc = nullptr;
1148     CIF::Builtins::BufferSimple *receivedOutSpecConstantsIds = nullptr;
1149     CIF::Builtins::BufferSimple *receivedOutSpecConstantsSizes = nullptr;
1150 
GetSpecConstantsInfoImplSpecConstantsTranslationCtxMock1151     bool GetSpecConstantsInfoImpl(CIFBuffer *src, CIFBuffer *outSpecConstantsIds, CIFBuffer *outSpecConstantsSizes) { // NOLINT(readability-identifier-naming)
1152         this->receivedSrc = src;
1153         this->receivedOutSpecConstantsIds = outSpecConstantsIds;
1154         this->receivedOutSpecConstantsSizes = outSpecConstantsSizes;
1155         return !returnFalse;
1156     }
1157 };
1158 
TEST(GetSpecConstantsTest,givenNullptrTranslationContextAndBuffersWhenGetSpecializationConstantsThenErrorIsReturned)1159 TEST(GetSpecConstantsTest, givenNullptrTranslationContextAndBuffersWhenGetSpecializationConstantsThenErrorIsReturned) {
1160     EXPECT_FALSE(NEO::getSpecConstantsInfoImpl<SpecConstantsTranslationCtxMock>(nullptr, nullptr, nullptr, nullptr));
1161 }
1162 
TEST(GetSpecConstantsTest,whenGetSpecializationConstantsSuccedThenSuccessIsReturnedAndBuffersArePassed)1163 TEST(GetSpecConstantsTest, whenGetSpecializationConstantsSuccedThenSuccessIsReturnedAndBuffersArePassed) {
1164     SpecConstantsTranslationCtxMock tCtxMock;
1165 
1166     auto mockSrc = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
1167     auto mockIds = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
1168     auto mockSizes = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
1169 
1170     auto ret = NEO::getSpecConstantsInfoImpl(&tCtxMock, mockSrc.get(), mockIds.get(), mockSizes.get());
1171 
1172     EXPECT_TRUE(ret);
1173     EXPECT_EQ(mockSrc.get(), tCtxMock.receivedSrc);
1174     EXPECT_EQ(mockIds.get(), tCtxMock.receivedOutSpecConstantsIds);
1175     EXPECT_EQ(mockSizes.get(), tCtxMock.receivedOutSpecConstantsSizes);
1176 }
1177 
TEST(GetSpecConstantsTest,whenGetSpecializationConstantsFailThenErrorIsReturnedAndBuffersArePassed)1178 TEST(GetSpecConstantsTest, whenGetSpecializationConstantsFailThenErrorIsReturnedAndBuffersArePassed) {
1179     SpecConstantsTranslationCtxMock tCtxMock;
1180     tCtxMock.returnFalse = true;
1181 
1182     auto mockSrc = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
1183     auto mockIds = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
1184     auto mockSizes = CIF::RAII::UPtr_t<MockCIFBuffer>(new MockCIFBuffer());
1185 
1186     auto ret = NEO::getSpecConstantsInfoImpl(&tCtxMock, mockSrc.get(), mockIds.get(), mockSizes.get());
1187 
1188     EXPECT_FALSE(ret);
1189     EXPECT_EQ(mockSrc.get(), tCtxMock.receivedSrc);
1190     EXPECT_EQ(mockIds.get(), tCtxMock.receivedOutSpecConstantsIds);
1191     EXPECT_EQ(mockSizes.get(), tCtxMock.receivedOutSpecConstantsSizes);
1192 }
1193 
TEST_F(CompilerInterfaceTest,whenIgcTranlationContextCreationFailsThenErrorIsReturned)1194 TEST_F(CompilerInterfaceTest, whenIgcTranlationContextCreationFailsThenErrorIsReturned) {
1195     pCompilerInterface->failCreateIgcTranslationCtx = true;
1196     NEO::SpecConstantInfo specConstInfo;
1197     auto err = pCompilerInterface->getSpecConstantsInfo(*pDevice, inputArgs.src, specConstInfo);
1198     EXPECT_EQ(TranslationOutput::ErrorCode::UnknownError, err);
1199 }
1200 
TEST_F(CompilerInterfaceTest,givenCompilerInterfaceWhenGetSpecializationConstantsThenSuccesIsReturned)1201 TEST_F(CompilerInterfaceTest, givenCompilerInterfaceWhenGetSpecializationConstantsThenSuccesIsReturned) {
1202     TranslationOutput translationOutput;
1203     NEO::SpecConstantInfo specConstInfo;
1204     auto err = pCompilerInterface->getSpecConstantsInfo(*pDevice, inputArgs.src, specConstInfo);
1205     EXPECT_EQ(TranslationOutput::ErrorCode::Success, err);
1206 }
1207 
TEST(TranslationOutput,givenNonEmptyPointerAndSizeWhenMakingCopyThenCloneInputData)1208 TEST(TranslationOutput, givenNonEmptyPointerAndSizeWhenMakingCopyThenCloneInputData) {
1209     MockCIFBuffer src;
1210     src.data.assign({2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37});
1211 
1212     std::string dstString;
1213     TranslationOutput::makeCopy(dstString, &src);
1214     ASSERT_EQ(src.GetSize<char>(), dstString.size());
1215     EXPECT_EQ(0, memcmp(src.GetMemory<void>(), dstString.c_str(), dstString.size()));
1216 
1217     TranslationOutput::MemAndSize dstBuffer;
1218     TranslationOutput::makeCopy(dstBuffer, &src);
1219     ASSERT_EQ(src.GetSize<char>(), dstBuffer.size);
1220     ASSERT_NE(nullptr, dstBuffer.mem);
1221     EXPECT_EQ(0, memcmp(src.GetMemory<void>(), dstBuffer.mem.get(), dstBuffer.size));
1222 }
1223 
TEST(TranslationOutput,givenNullPointerWhenMakingCopyThenClearOutOutput)1224 TEST(TranslationOutput, givenNullPointerWhenMakingCopyThenClearOutOutput) {
1225     MockCIFBuffer src;
1226     src.data.assign({2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37});
1227 
1228     std::string dstString;
1229     TranslationOutput::makeCopy(dstString, &src);
1230 
1231     TranslationOutput::MemAndSize dstBuffer;
1232     TranslationOutput::makeCopy(dstBuffer, &src);
1233 
1234     EXPECT_NE(0U, dstString.size());
1235     TranslationOutput::makeCopy(dstString, nullptr);
1236     EXPECT_EQ(0U, dstString.size());
1237 
1238     EXPECT_NE(0U, dstBuffer.size);
1239     EXPECT_NE(nullptr, dstBuffer.mem);
1240     TranslationOutput::makeCopy(dstBuffer, nullptr);
1241     EXPECT_EQ(0U, dstBuffer.size);
1242     EXPECT_EQ(nullptr, dstBuffer.mem);
1243 }
1244 
TEST(TranslationOutput,givenZeroSizeWhenMakingCopyThenClearOutOutput)1245 TEST(TranslationOutput, givenZeroSizeWhenMakingCopyThenClearOutOutput) {
1246     MockCIFBuffer src;
1247     src.data.assign({2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37});
1248 
1249     std::string dstString;
1250     TranslationOutput::makeCopy(dstString, &src);
1251 
1252     TranslationOutput::MemAndSize dstBuffer;
1253     TranslationOutput::makeCopy(dstBuffer, &src);
1254 
1255     MockCIFBuffer emptySrc;
1256     EXPECT_NE(0U, dstString.size());
1257     TranslationOutput::makeCopy(dstString, &emptySrc);
1258     EXPECT_EQ(0U, dstString.size());
1259 
1260     EXPECT_NE(0U, dstBuffer.size);
1261     EXPECT_NE(nullptr, dstBuffer.mem);
1262     TranslationOutput::makeCopy(dstBuffer, &emptySrc);
1263     EXPECT_EQ(0U, dstBuffer.size);
1264     EXPECT_EQ(nullptr, dstBuffer.mem);
1265 }
1266