diff --git a/offline_compiler/offline_compiler.cpp b/offline_compiler/offline_compiler.cpp index fbe795f589..4d7089e874 100644 --- a/offline_compiler/offline_compiler.cpp +++ b/offline_compiler/offline_compiler.cpp @@ -135,8 +135,8 @@ int OfflineCompiler::buildSourceCode() { UNRECOVERABLE_IF(igcDeviceCtx == nullptr); CIF::RAII::UPtr_t igcOutput; - - if (!inputFileLlvm) { + bool inputIsIntermediateRepresentation = inputFileLlvm || inputFileSpirV; + if (false == inputIsIntermediateRepresentation) { IGC::CodeType::CodeType_t intermediateRepresentation = useLlvmText ? IGC::CodeType::llvmLl : preferredIntermediateRepresentation; // sourceCode.size() returns the number of characters without null terminated char auto fclSrc = CIF::Builtins::CreateConstBuffer(fclMain.get(), sourceCode.c_str(), sourceCode.size() + 1); @@ -181,7 +181,7 @@ int OfflineCompiler::buildSourceCode() { auto igcSrc = CIF::Builtins::CreateConstBuffer(igcMain.get(), sourceCode.c_str(), sourceCode.size()); auto igcOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), nullptr, 0); auto igcInternalOptions = CIF::Builtins::CreateConstBuffer(igcMain.get(), internalOptions.c_str(), internalOptions.size()); - auto igcTranslationCtx = igcDeviceCtx->CreateTranslationCtx(IGC::CodeType::llvmLl, IGC::CodeType::oclGenBin); + auto igcTranslationCtx = igcDeviceCtx->CreateTranslationCtx(inputFileSpirV ? IGC::CodeType::spirV : IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin); igcOutput = igcTranslationCtx->Translate(igcSrc.get(), igcOptions.get(), igcInternalOptions.get(), nullptr, 0); } if (igcOutput == nullptr) { @@ -469,6 +469,8 @@ int OfflineCompiler::parseCommandLine(uint32_t numArgs, const char **argv) { useLlvmText = true; } else if (stringsAreEqual(argv[argIndex], "-llvm_input")) { inputFileLlvm = true; + } else if (stringsAreEqual(argv[argIndex], "-spirv_input")) { + inputFileSpirV = true; } else if (stringsAreEqual(argv[argIndex], "-cpp_file")) { useCppFile = true; } else if ((stringsAreEqual(argv[argIndex], "-options")) && @@ -642,6 +644,7 @@ void OfflineCompiler::printUsage() { printf(" -llvm_text Readable LLVM text will be output in a .ll file instead of\n"); printf(" through the default lllvm binary (.bc) file.\n"); printf(" -llvm_input Indicates input file is llvm source\n"); + printf(" -spirv_input Indicates input file is a SpirV binary\n"); printf(" -options Compiler options.\n"); printf(" -options_name Add suffix with compile options to filename\n"); printf(" -q Be more quiet. print only warnings and errors.\n"); diff --git a/offline_compiler/offline_compiler.h b/offline_compiler/offline_compiler.h index 3162e827cc..d50d096989 100644 --- a/offline_compiler/offline_compiler.h +++ b/offline_compiler/offline_compiler.h @@ -102,6 +102,7 @@ class OfflineCompiler { bool useOptionsSuffix = false; bool quiet = false; bool inputFileLlvm = false; + bool inputFileSpirV = false; char *elfBinary = nullptr; size_t elfBinarySize = 0; diff --git a/unit_tests/mocks/mock_compilers.cpp b/unit_tests/mocks/mock_compilers.cpp index 5b8ef2cae5..7aee71db33 100644 --- a/unit_tests/mocks/mock_compilers.cpp +++ b/unit_tests/mocks/mock_compilers.cpp @@ -455,6 +455,7 @@ CIF::ICIF *MockIgcOclDeviceCtx::Create(CIF::InterfaceId_t intId, CIF::Version_t IGC::IgcOclTranslationCtxBase *MockIgcOclDeviceCtx::CreateTranslationCtxImpl(CIF::Version_t ver, IGC::CodeType::CodeType_t inType, IGC::CodeType::CodeType_t outType) { + requestedTranslationCtxs.emplace_back(inType, outType); return new MockIgcOclTranslationCtx; } diff --git a/unit_tests/mocks/mock_compilers.h b/unit_tests/mocks/mock_compilers.h index 443eb982f7..8da7772602 100644 --- a/unit_tests/mocks/mock_compilers.h +++ b/unit_tests/mocks/mock_compilers.h @@ -206,6 +206,9 @@ struct MockIgcOclDeviceCtx : MockCIF { MockGTSystemInfo *gtSystemInfo = nullptr; MockIgcFeaturesAndWorkarounds *igcFeWa = nullptr; MockCompilerDebugVars debugVars; + + using TranslationOpT = std::pair; + std::vector requestedTranslationCtxs; }; struct MockFclOclTranslationCtx : MockCIF { diff --git a/unit_tests/offline_compiler/mock/mock_offline_compiler.h b/unit_tests/offline_compiler/mock/mock_offline_compiler.h index 230019c784..2184d01e58 100644 --- a/unit_tests/offline_compiler/mock/mock_offline_compiler.h +++ b/unit_tests/offline_compiler/mock/mock_offline_compiler.h @@ -30,11 +30,14 @@ class MockOfflineCompiler : public OfflineCompiler { public: using OfflineCompiler::generateFilePathForIr; using OfflineCompiler::generateOptsSuffix; + using OfflineCompiler::igcDeviceCtx; using OfflineCompiler::inputFileLlvm; + using OfflineCompiler::inputFileSpirV; using OfflineCompiler::isSpirV; using OfflineCompiler::options; using OfflineCompiler::outputDirectory; using OfflineCompiler::outputFile; + using OfflineCompiler::sourceCode; using OfflineCompiler::useLlvmText; using OfflineCompiler::useOptionsSuffix; diff --git a/unit_tests/offline_compiler/offline_compiler_tests.cpp b/unit_tests/offline_compiler/offline_compiler_tests.cpp index cbdcbf56ce..c81eeb5dff 100644 --- a/unit_tests/offline_compiler/offline_compiler_tests.cpp +++ b/unit_tests/offline_compiler/offline_compiler_tests.cpp @@ -28,6 +28,7 @@ #include "runtime/helpers/options.h" #include "runtime/os_interface/debug_settings_manager.h" #include "unit_tests/helpers/debug_manager_state_restore.h" +#include "unit_tests/mocks/mock_compilers.h" #include "gmock/gmock.h" #include @@ -561,40 +562,53 @@ TEST(OfflineCompilerTest, givenDefaultOfflineCompilerObjectWhenNoOptionsAreChang EXPECT_FALSE(llvmFileOption); } -TEST(OfflineCompilerTest, givenLlvmInputFileAndLlvmInputFlagWhenBuildSourceCodeIsCalledThenGenBinaryIsProduced) { +TEST(OfflineCompilerTest, givenSpirvInputOptionPassedWhenCmdLineParsedThenInputFileSpirvIsSetTrue) { + const char *argv[] = {"cloc", "-spirv_input"}; + auto mockOfflineCompiler = std::unique_ptr(new MockOfflineCompiler()); - ASSERT_NE(nullptr, mockOfflineCompiler); - auto retVal = mockOfflineCompiler->buildSourceCode(); - EXPECT_EQ(CL_INVALID_PROGRAM, retVal); + testing::internal::CaptureStdout(); + mockOfflineCompiler->parseCommandLine(ARRAY_COUNT(argv), argv); + std::string output = testing::internal::GetCapturedStdout(); + EXPECT_NE(0u, output.size()); - std::string sipKernelFileName = "test_files/sip_dummy_kernel"; + EXPECT_TRUE(mockOfflineCompiler->inputFileSpirV); +} - if (sizeof(uintptr_t) == 8) { - sipKernelFileName += "_64.ll"; - } else { - sipKernelFileName += "_32.ll"; - } +TEST(OfflineCompilerTest, givenDefaultOfflineCompilerObjectWhenNoOptionsAreChangedThenSpirvInputFileIsFalse) { + auto mockOfflineCompiler = std::unique_ptr(new MockOfflineCompiler()); + EXPECT_FALSE(mockOfflineCompiler->inputFileSpirV); +} +TEST(OfflineCompilerTest, givenIntermediatedRepresentationInputWhenBuildSourceCodeIsCalledThenProperTranslationContextIsUed) { + MockOfflineCompiler mockOfflineCompiler; const char *argv[] = { "cloc", "-file", - sipKernelFileName.c_str(), - "-llvm_input", + "test_files/emptykernel.cl", "-device", gEnvironment->devicePrefix.c_str()}; - retVal = mockOfflineCompiler->initialize(ARRAY_COUNT(argv), argv); + auto retVal = mockOfflineCompiler.initialize(ARRAY_COUNT(argv), argv); + auto mockIgcOclDeviceCtx = new OCLRT::MockIgcOclDeviceCtx(); + mockOfflineCompiler.igcDeviceCtx = CIF::RAII::Pack(mockIgcOclDeviceCtx); + ASSERT_EQ(CL_SUCCESS, retVal); + + mockOfflineCompiler.inputFileSpirV = true; + retVal = mockOfflineCompiler.buildSourceCode(); EXPECT_EQ(CL_SUCCESS, retVal); + ASSERT_EQ(1U, mockIgcOclDeviceCtx->requestedTranslationCtxs.size()); + OCLRT::MockIgcOclDeviceCtx::TranslationOpT expectedTranslation = {IGC::CodeType::spirV, IGC::CodeType::oclGenBin}; + ASSERT_EQ(expectedTranslation, mockIgcOclDeviceCtx->requestedTranslationCtxs[0]); - EXPECT_EQ(nullptr, mockOfflineCompiler->getGenBinary()); - EXPECT_EQ(0u, mockOfflineCompiler->getGenBinarySize()); - - retVal = mockOfflineCompiler->buildSourceCode(); + mockOfflineCompiler.inputFileSpirV = false; + mockOfflineCompiler.inputFileLlvm = true; + mockIgcOclDeviceCtx->requestedTranslationCtxs.clear(); + retVal = mockOfflineCompiler.buildSourceCode(); EXPECT_EQ(CL_SUCCESS, retVal); - - EXPECT_NE(nullptr, mockOfflineCompiler->getGenBinary()); - EXPECT_NE(0u, mockOfflineCompiler->getGenBinarySize()); + ASSERT_EQ(1U, mockIgcOclDeviceCtx->requestedTranslationCtxs.size()); + expectedTranslation = {IGC::CodeType::llvmBc, IGC::CodeType::oclGenBin}; + ASSERT_EQ(expectedTranslation, mockIgcOclDeviceCtx->requestedTranslationCtxs[0]); } TEST(OfflineCompilerTest, givenOutputFileOptionWhenSourceIsCompiledThenOutputFileHasCorrectName) {