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