diff --git a/opencl/test/unit_test/offline_compiler/ocloc_api_tests.cpp b/opencl/test/unit_test/offline_compiler/ocloc_api_tests.cpp index 6c4e1704b6..ac3b90e326 100644 --- a/opencl/test/unit_test/offline_compiler/ocloc_api_tests.cpp +++ b/opencl/test/unit_test/offline_compiler/ocloc_api_tests.cpp @@ -191,7 +191,7 @@ TEST(OclocApiTests, GivenNoQueryWhenQueryingThenErrorIsReturned) { std::string output = testing::internal::GetCapturedStdout(); EXPECT_EQ(retVal, OCLOC_INVALID_COMMAND_LINE); - EXPECT_STREQ("Error: Invalid command line. Expected ocloc query . See ocloc query --help\n", output.c_str()); + EXPECT_STREQ("Error: Invalid command line. Expected ocloc query . See ocloc query --help\nCommand was: ocloc query\n", output.c_str()); } TEST(OclocApiTests, GivenInvalidQueryWhenQueryingThenErrorIsReturned) { @@ -208,7 +208,7 @@ TEST(OclocApiTests, GivenInvalidQueryWhenQueryingThenErrorIsReturned) { std::string output = testing::internal::GetCapturedStdout(); EXPECT_EQ(retVal, OCLOC_INVALID_COMMAND_LINE); - EXPECT_STREQ("Error: Invalid command line.\nUnknown argument unknown_query\n", output.c_str()); + EXPECT_STREQ("Error: Invalid command line.\nUnknown argument unknown_query\nCommand was: ocloc query unknown_query\n", output.c_str()); } TEST(OclocApiTests, givenNoAcronymWhenIdsCommandIsInvokeThenErrorIsReported) { @@ -224,7 +224,7 @@ TEST(OclocApiTests, givenNoAcronymWhenIdsCommandIsInvokeThenErrorIsReported) { std::string output = testing::internal::GetCapturedStdout(); EXPECT_EQ(retVal, OCLOC_INVALID_COMMAND_LINE); - EXPECT_STREQ("Error: Invalid command line. Expected ocloc ids .\n", output.c_str()); + EXPECT_STREQ("Error: Invalid command line. Expected ocloc ids .\nCommand was: ocloc ids\n", output.c_str()); } TEST(OclocApiTests, givenUnknownAcronymWhenIdsCommandIsInvokeThenErrorIsReported) { @@ -241,7 +241,7 @@ TEST(OclocApiTests, givenUnknownAcronymWhenIdsCommandIsInvokeThenErrorIsReported std::string output = testing::internal::GetCapturedStdout(); EXPECT_EQ(retVal, OCLOC_INVALID_COMMAND_LINE); - EXPECT_STREQ("Error: Invalid command line. Unknown acronym unk.\n", output.c_str()); + EXPECT_STREQ("Error: Invalid command line. Unknown acronym unk.\nCommand was: ocloc ids unk\n", output.c_str()); } TEST(OclocApiTests, WhenGoodFamilyNameIsProvidedThenSuccessIsReturned) { @@ -732,7 +732,7 @@ TEST(OclocApiTests, GivenNonexistentFileWhenValidateIsInvokedThenErrorIsPrinted) const auto output = testing::internal::GetCapturedStdout(); EXPECT_EQ(-1, retVal); - const std::string expectedErrorMessage{"Error : Input file missing : some_special_nonexistent_file.gen\n"}; + const std::string expectedErrorMessage{"Error : Input file missing : some_special_nonexistent_file.gen\nCommand was: ocloc validate -file some_special_nonexistent_file.gen\n"}; EXPECT_EQ(expectedErrorMessage, output); } @@ -806,7 +806,7 @@ TEST(OclocApiTests, GivenInvalidParameterWhenLinkingThenErrorIsReturned) { EXPECT_EQ(OCLOC_INVALID_COMMAND_LINE, retVal); const std::string expectedInitError{"Invalid option (arg 2): --dummy_param\n"}; - const std::string expectedExecuteError{"Error: Linker cannot be executed due to unsuccessful initialization!\n"}; + const std::string expectedExecuteError{"Error: Linker cannot be executed due to unsuccessful initialization!\nCommand was: ocloc link --dummy_param\n"}; const std::string expectedErrorMessage = expectedInitError + expectedExecuteError; EXPECT_EQ(expectedErrorMessage, output); } @@ -824,7 +824,7 @@ TEST(OclocApiTests, GivenInvalidCommandLineWhenConcatenatingThenErrorIsReturned) std::string output = testing::internal::GetCapturedStdout(); EXPECT_EQ(OCLOC_INVALID_COMMAND_LINE, retVal); const std::string emptyCommandLineError = "No files to concatenate were provided.\n"; - const std::string expectedErrorMessage = emptyCommandLineError + NEO::OclocConcat::helpMessage.str(); + const std::string expectedErrorMessage = emptyCommandLineError + NEO::OclocConcat::helpMessage.str() + "Command was: ocloc concat\n"; EXPECT_EQ(expectedErrorMessage, output); } @@ -908,3 +908,26 @@ TEST(OclocApiTests, GivenValidCommandLineAndFatBinariesWhenConcatenatingThenNewF EXPECT_TRUE(hasFatBinary2); oclocFreeOutput(&numOutputs, &outputData, &outputLen, &outputName); } + +TEST(OclocApiTests, GivenVerboseModeWhenCompilingThenPrintCommandLine) { + std::string clFileName(clFiles + "copybuffer.cl"); + const char *argv[] = { + "ocloc", + "-file", + clFileName.c_str(), + "-device", + gEnvironment->devicePrefix.c_str(), + "-v"}; + unsigned int argc = sizeof(argv) / sizeof(const char *); + + testing::internal::CaptureStdout(); + int retVal = oclocInvoke(argc, argv, + 0, nullptr, nullptr, nullptr, + 0, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr); + std::string output = testing::internal::GetCapturedStdout(); + + EXPECT_EQ(retVal, OCLOC_SUCCESS); + EXPECT_NE(std::string::npos, output.find("Command was: ocloc -file "s + clFileName.c_str() + " -device "s + argv[4] + " -v")) << output; + EXPECT_NE(std::string::npos, output.find("Build succeeded.\n")); +} diff --git a/shared/offline_compiler/source/decoder/binary_decoder.cpp b/shared/offline_compiler/source/decoder/binary_decoder.cpp index fcbd697ce7..ffb79ee858 100644 --- a/shared/offline_compiler/source/decoder/binary_decoder.cpp +++ b/shared/offline_compiler/source/decoder/binary_decoder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2023 Intel Corporation + * Copyright (C) 2018-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -282,7 +282,7 @@ void BinaryDecoder::parseTokens() { } void BinaryDecoder::printHelp() { - argHelper->printf(R"===(Disassembles Intel Compute GPU device binary files. + argHelper->printf(R"OCLOC_HELP(Disassembles Intel Compute GPU device binary files. Output of such operation is a set of files that can be later used to reassemble back a valid Intel Compute GPU device binary (using ocloc 'asm' command). This set of files contains: @@ -325,12 +325,14 @@ Usage: ocloc disasm -file [-patch ] [-dump ] [ -ignore_isa_padding Ignores Kernel Heap padding - Kernel Heap binary will be saved without padding. + -v Verbose mode. + --help Print this usage message. Examples: Disassemble Intel Compute GPU device binary ocloc disasm -file source_file_Gen9core.bin -)===", +)OCLOC_HELP", argHelper->createStringForArgs(argHelper->productConfigHelper->getDeviceAcronyms()).c_str()); } @@ -551,6 +553,8 @@ int BinaryDecoder::validateInput(const std::vector &args) { } else if ("-q" == currArg) { argHelper->getPrinterRef().setSuppressMessages(true); iga->setMessagePrinter(argHelper->getPrinterRef()); + } else if ("-v" == currArg) { + argHelper->setVerbose(true); } else { argHelper->printf("Unknown argument %s\n", currArg.c_str()); return -1; diff --git a/shared/offline_compiler/source/decoder/binary_encoder.cpp b/shared/offline_compiler/source/decoder/binary_encoder.cpp index 1d3bcf5fb0..48d4a13c55 100644 --- a/shared/offline_compiler/source/decoder/binary_encoder.cpp +++ b/shared/offline_compiler/source/decoder/binary_encoder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2023 Intel Corporation + * Copyright (C) 2018-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -105,7 +105,7 @@ int BinaryEncoder::createElf(std::stringstream &deviceBinary) { } void BinaryEncoder::printHelp() { - argHelper->printf(R"===(Assembles Intel Compute GPU device binary from input files. + argHelper->printf(R"OCLOC_HELP(Assembles Intel Compute GPU device binary from input files. It's expected that input files were previously generated by 'ocloc disasm' command or are compatible with 'ocloc disasm' output (especially in terms of file naming scheme). See 'ocloc disasm --help' for additional info. @@ -128,12 +128,14 @@ Usage: ocloc asm -out [-dump ] [-device ] [-ig -ignore_isa_padding Ignores Kernel Heap padding - padding will not be added to Kernel Heap binary. + -v Verbose mode. + --help Print this usage message. Examples: Assemble to Intel Compute GPU device binary ocloc asm -out reassembled.bin -)===", +)OCLOC_HELP", argHelper->createStringForArgs(argHelper->productConfigHelper->getDeviceAcronyms()).c_str()); } @@ -326,6 +328,8 @@ int BinaryEncoder::validateInput(const std::vector &args) { } else if ("-q" == currArg) { argHelper->getPrinterRef().setSuppressMessages(true); iga->setMessagePrinter(argHelper->getPrinterRef()); + } else if ("-v" == currArg) { + argHelper->setVerbose(true); } else { argHelper->printf("Unknown argument %s\n", currArg.c_str()); return -1; diff --git a/shared/offline_compiler/source/decoder/zebin_manipulator.cpp b/shared/offline_compiler/source/decoder/zebin_manipulator.cpp index 774090d120..1ad7893b87 100644 --- a/shared/offline_compiler/source/decoder/zebin_manipulator.cpp +++ b/shared/offline_compiler/source/decoder/zebin_manipulator.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Intel Corporation + * Copyright (C) 2022-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -85,6 +85,8 @@ ErrorCode validateInput(const std::vector &args, IgaWrapper *iga, O } else if ("-q" == currArg) { argHelper->getPrinterRef().setSuppressMessages(true); iga->setMessagePrinter(argHelper->getPrinterRef()); + } else if ("-v" == currArg) { + argHelper->setVerbose(true); } else if ("-skip-asm-translation" == currArg) { outArguments.skipIGAdisassembly = true; } else { @@ -435,7 +437,7 @@ template void ZebinEncoder::printHelp(); template void ZebinEncoder::printHelp(); template void ZebinEncoder::printHelp() { - argHelper->printf(R"===(Assembles Zebin from input files. + argHelper->printf(R"OCLOC_HELP(Assembles Zebin from input files. It's expected that input files were previously generated by 'ocloc disasm' command or are compatible with 'ocloc disasm' output (especially in terms of file naming scheme). @@ -448,8 +450,10 @@ Usage: ocloc asm -file [-dump ] [-device ] [-skip- -device Optional. Target device of input binary. + -v Verbose mode. + --help Print this usage message. -)==="); +)OCLOC_HELP"); } template diff --git a/shared/offline_compiler/source/ocloc_api.cpp b/shared/offline_compiler/source/ocloc_api.cpp index 5d5ed1eb4c..d59aa66993 100644 --- a/shared/offline_compiler/source/ocloc_api.cpp +++ b/shared/offline_compiler/source/ocloc_api.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -20,7 +20,7 @@ int oclocInvoke(unsigned int numArgs, const char *argv[], const uint32_t numSources, const uint8_t **dataSources, const uint64_t *lenSources, const char **nameSources, const uint32_t numInputHeaders, const uint8_t **dataInputHeaders, const uint64_t *lenInputHeaders, const char **nameInputHeaders, uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs) { - auto helper = std::make_unique( + auto argHelper = std::make_unique( numSources, dataSources, lenSources, nameSources, numInputHeaders, dataInputHeaders, lenInputHeaders, nameInputHeaders, numOutputs, dataOutputs, lenOutputs, nameOutputs); @@ -28,32 +28,40 @@ int oclocInvoke(unsigned int numArgs, const char *argv[], try { if (numArgs <= 1 || NEO::ConstStringRef("-h") == args[1] || NEO::ConstStringRef("--help") == args[1]) { - printHelp(*helper); + printHelp(*argHelper); return OCLOC_SUCCESS; } auto &command = args[1]; + int retVal = -0; if (command == CommandNames::disassemble) { - return Commands::disassemble(helper.get(), args); + retVal = Commands::disassemble(argHelper.get(), args); } else if (command == CommandNames::assemble) { - return Commands::assemble(helper.get(), args); + retVal = Commands::assemble(argHelper.get(), args); } else if (command == CommandNames::multi) { - return Commands::multi(helper.get(), args); + retVal = Commands::multi(argHelper.get(), args); } else if (command == CommandNames::validate) { - return Commands::validate(helper.get(), args); + retVal = Commands::validate(argHelper.get(), args); } else if (command == CommandNames::query) { - return Commands::query(helper.get(), args); + retVal = Commands::query(argHelper.get(), args); } else if (command == CommandNames::ids) { - return Commands::ids(helper.get(), args); + retVal = Commands::ids(argHelper.get(), args); } else if (command == CommandNames::link) { - return Commands::link(helper.get(), args); + retVal = Commands::link(argHelper.get(), args); } else if (command == CommandNames::concat) { - return Commands::concat(helper.get(), args); + retVal = Commands::concat(argHelper.get(), args); } else { - return Commands::compile(helper.get(), args); + retVal = Commands::compile(argHelper.get(), args); } + + if (retVal != OCLOC_SUCCESS) { + printOclocCmdLine(*argHelper, args); + } else if (argHelper->isVerbose()) { + printOclocCmdLine(*argHelper, args); + } + return retVal; } catch (const std::exception &e) { - helper->printf("%s\n", e.what()); - printOclocCmdLine(*helper, args); + argHelper->printf("%s\n", e.what()); + printOclocCmdLine(*argHelper, args); return -1; } } diff --git a/shared/offline_compiler/source/ocloc_arg_helper.h b/shared/offline_compiler/source/ocloc_arg_helper.h index 711e70ea84..75af362440 100644 --- a/shared/offline_compiler/source/ocloc_arg_helper.h +++ b/shared/offline_compiler/source/ocloc_arg_helper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020-2023 Intel Corporation + * Copyright (C) 2020-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -63,6 +63,8 @@ class OclocArgHelper { outputs.push_back(std::make_unique(filename, data, size)); } + bool verbose = false; + public: OclocArgHelper(); OclocArgHelper(const uint32_t numSources, const uint8_t **dataSources, @@ -92,6 +94,14 @@ class OclocArgHelper { return headers; } + bool isVerbose() const { + return verbose; + } + + void setVerbose(bool verbose) { + this->verbose = verbose; + } + MOCKABLE_VIRTUAL void saveOutput(const std::string &filename, const void *pData, const size_t &dataSize); void saveOutput(const std::string &filename, const std::ostream &stream); diff --git a/shared/offline_compiler/source/ocloc_interface.cpp b/shared/offline_compiler/source/ocloc_interface.cpp index 8ef8ce65e5..a70d2267db 100644 --- a/shared/offline_compiler/source/ocloc_interface.cpp +++ b/shared/offline_compiler/source/ocloc_interface.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Intel Corporation + * Copyright (C) 2022-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -147,7 +147,6 @@ int compile(OclocArgHelper *argHelper, const std::vector &args) { if (retVal != OCLOC_SUCCESS) { printOclocOptionsReadFromFile(*argHelper, pCompiler.get()); - printOclocCmdLine(*argHelper, args); } return retVal; }; diff --git a/shared/offline_compiler/source/offline_compiler.cpp b/shared/offline_compiler/source/offline_compiler.cpp index 552afc1a19..0a10707258 100644 --- a/shared/offline_compiler/source/offline_compiler.cpp +++ b/shared/offline_compiler/source/offline_compiler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018-2023 Intel Corporation + * Copyright (C) 2018-2024 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -1014,6 +1014,8 @@ int OfflineCompiler::parseCommandLine(size_t numArgs, const std::vectorgetPrinterRef().setSuppressMessages(true); quiet = true; + } else if ("-v" == currArg) { + argHelper->setVerbose(true); } else if ("-spv_only" == currArg) { onlySpirV = true; } else if ("-output_no_suffix" == currArg) { @@ -1323,6 +1325,8 @@ Usage: ocloc [compile] -file -device [-output