Add multi command line option for ocloc

- now ocloc is able to make multi build, all options and parameters
of build are listed in separate .txt file, each line in this file
is new build.

Change-Id: Id74af826e8c1a4fe14c46ed6024efe2041a22fd0
Signed-off-by: Marcin Naczk <marcin.naczk@intel.com>
This commit is contained in:
Marcin Naczk
2019-05-14 16:47:35 +02:00
committed by sys_ocldev
parent 2d02435fb9
commit ce8d24d124
10 changed files with 582 additions and 78 deletions

View File

@@ -16,6 +16,8 @@ ${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/helper.h
${IGDRCL_SOURCE_DIR}/offline_compiler/helper.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/offline_compiler.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/offline_compiler.h
${IGDRCL_SOURCE_DIR}/offline_compiler/multi_command.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/multi_command.h
${IGDRCL_SOURCE_DIR}/offline_compiler/options.cpp
${IGDRCL_SOURCE_DIR}/runtime/compiler_interface/create_main.cpp
${IGDRCL_SOURCE_DIR}/runtime/helpers/abort.cpp

View File

@@ -5,14 +5,17 @@
*
*/
#include "offline_compiler/multi_command.h"
#include "offline_compiler/offline_compiler.h"
#include "offline_compiler/utilities/safety_caller.h"
#include "runtime/os_interface/os_library.h"
#include "decoder/binary_decoder.h"
#include "decoder/binary_encoder.h"
#include <CL/cl.h>
#include <fstream>
#include <iostream>
using namespace NEO;
int main(int numArgs, const char *argv[]) {
@@ -33,9 +36,20 @@ int main(int numArgs, const char *argv[]) {
} else {
return retVal;
}
} else if (numArgs > 1 && !strcmp(argv[1], "-multi")) {
int retValue = CL_SUCCESS;
auto pMulti = std::unique_ptr<MultiCommand>(MultiCommand::create(numArgs, argv, retValue));
return retValue;
} else {
int retVal = CL_SUCCESS;
OfflineCompiler *pCompiler = OfflineCompiler::create(numArgs, argv, retVal);
std::vector<std::string> allArgs;
if (numArgs > 1) {
allArgs.assign(argv, argv + numArgs);
}
OfflineCompiler *pCompiler = OfflineCompiler::create(numArgs, allArgs, retVal);
if (retVal == CL_SUCCESS) {
retVal = buildWithSafetyGuard(pCompiler);

View File

@@ -0,0 +1,226 @@
/*
* Copyright (C) 2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "offline_compiler/multi_command.h"
namespace NEO {
int MultiCommand::singleBuild(size_t numArgs, const std::vector<std::string> &allArgs) {
int retVal;
std::string buildLog;
OfflineCompiler *pCompiler = OfflineCompiler::create(numArgs, allArgs, retVal);
if (retVal == CL_SUCCESS) {
retVal = buildWithSafetyGuard(pCompiler);
buildLog = pCompiler->getBuildLog();
if (buildLog.empty() == false) {
printf("%s\n", buildLog.c_str());
}
if (retVal == CL_SUCCESS) {
if (!pCompiler->isQuiet())
printf("Build succeeded.\n");
} else {
printf("Build failed with error code: %d\n", retVal);
}
}
if (buildLog.empty() == false) {
singleBuilds.push_back(pCompiler);
} else {
delete pCompiler;
}
return retVal;
}
MultiCommand::MultiCommand() = default;
MultiCommand::~MultiCommand() {
deleteBuildsWithWarnigs();
}
void MultiCommand::deleteBuildsWithWarnigs() {
for (OfflineCompiler *pSingle : singleBuilds)
delete pSingle;
singleBuilds.clear();
}
MultiCommand *MultiCommand::create(int numArgs, const char *argv[], int &retVal) {
retVal = CL_SUCCESS;
auto pMultiCommand = new MultiCommand();
if (pMultiCommand) {
retVal = pMultiCommand->initialize(numArgs, argv);
}
if (retVal != CL_SUCCESS) {
delete pMultiCommand;
pMultiCommand = nullptr;
}
return pMultiCommand;
}
std::string MultiCommand::eraseExtensionFromPath(std::string &filePath) {
size_t extPos = filePath.find_last_of(".", filePath.size());
if (extPos == std::string::npos) {
extPos = filePath.size();
}
std::string fileName;
std::string fileTrunk = filePath.substr(0, extPos);
return fileTrunk;
}
void MultiCommand::addAdditionalOptionsToSingleCommandLine(std::vector<std::string> &singleLineWithArguments, int buildId) {
std::string OutFileName;
bool hasOutDir = false;
bool hasSpecificName = false;
for (auto arg : singleLineWithArguments) {
if (arg == "-out_dir") {
hasOutDir = true;
}
if (arg == "-output") {
hasSpecificName = true;
}
}
if (!hasOutDir) {
singleLineWithArguments.push_back("-out_dir");
OutDirForBuilds = eraseExtensionFromPath(pathToCMD);
singleLineWithArguments.push_back(OutDirForBuilds);
}
if (!hasSpecificName) {
singleLineWithArguments.push_back("-output");
OutFileName = "build_no_" + std::to_string(buildId + 1);
singleLineWithArguments.push_back(OutFileName);
}
if (quiet)
singleLineWithArguments.push_back("-q");
}
int MultiCommand::initialize(int numArgs, const char *argv[]) {
int retVal = CL_SUCCESS;
if (numArgs > 2)
pathToCMD = argv[2];
else {
printf("Lack of file with build arguments\n");
return INVALID_COMMAND_LINE;
}
if (numArgs > 3 && strcmp(argv[3], "-q") == 0)
quiet = true;
//save file with builds arguments to vector of strings, line by line
openFileWithBuildsArguments();
if (!lines.empty()) {
for (unsigned int i = 0; i < lines.size(); i++) {
std::vector<std::string> singleLineWithArguments;
unsigned int numberOfArg;
singleLineWithArguments.push_back(argv[0]);
retVal = splitLineInSeparateArgs(singleLineWithArguments, lines[i], i);
if (retVal != CL_SUCCESS) {
retValues.push_back(retVal);
continue;
}
addAdditionalOptionsToSingleCommandLine(singleLineWithArguments, i);
numberOfArg = static_cast<unsigned int>(singleLineWithArguments.size());
if (!quiet)
printf("\nCommand number %d: ", i + 1);
retVal = singleBuild(numberOfArg, singleLineWithArguments);
retValues.push_back(retVal);
}
return showResults();
} else
return INVALID_COMMAND_LINE;
}
int MultiCommand::splitLineInSeparateArgs(std::vector<std::string> &qargs, const std::string &command, int numberOfBuild) {
unsigned int len = static_cast<unsigned int>(command.length());
bool qot = false, sqot = false;
int arglen;
for (unsigned int i = 0; i < len; i++) {
int start = i;
if (command[i] == '\"') {
qot = true;
} else if (command[i] == '\'')
sqot = true;
if (qot) {
i++;
start++;
while (i < len && command[i] != '\"')
i++;
if (i < len)
qot = false;
arglen = i - start;
i++;
} else if (sqot) {
i++;
while (i < len && command[i] != '\'')
i++;
if (i < len)
sqot = false;
arglen = i - start;
i++;
} else {
while (i < len && command[i] != ' ')
i++;
arglen = i - start;
}
qargs.push_back(command.substr(start, arglen));
}
if (qot || sqot) {
printf("One of the quotes is open in build number %d\n", numberOfBuild + 1);
return INVALID_COMMAND_LINE;
}
return CL_SUCCESS;
}
void MultiCommand::openFileWithBuildsArguments() {
std::fstream multiCmdFile;
std::stringstream fileContent;
multiCmdFile.open(pathToCMD, std::fstream::in);
if (multiCmdFile.is_open()) {
std::string param;
fileContent << multiCmdFile.rdbuf();
multiCmdFile.close();
while (std::getline(fileContent, param, '\n')) {
param.erase(param.find_last_not_of(" \r\t") + 1);
param.erase(0, param.find_first_not_of(" \r\t"));
if (!param.empty()) {
lines.push_back(param);
}
}
} else {
printf("Can not open file with builds arguments\n");
}
}
int MultiCommand::showResults() {
int retValue = CL_SUCCESS;
int indexRetVal = 0;
for (int retVal : retValues) {
if (retVal != CL_SUCCESS) {
if (retValue == CL_SUCCESS)
retValue = retVal;
if (!quiet)
printf("Build %d: failed. Error code: %d\n", indexRetVal, retVal);
} else {
if (!quiet)
printf("Build %d: successful\n", indexRetVal);
}
indexRetVal++;
}
return retValue;
}
} // namespace NEO

View File

@@ -0,0 +1,50 @@
/*
* Copyright (C) 2019 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "offline_compiler/offline_compiler.h"
#include "offline_compiler/utilities/safety_caller.h"
#include "runtime/os_interface/os_library.h"
#include "decoder/binary_decoder.h"
#include "decoder/binary_encoder.h"
#include <CL/cl.h>
#include <fstream>
#include <iostream>
namespace NEO {
class MultiCommand {
public:
static MultiCommand *create(int numArgs, const char *argv[], int &retVal);
void deleteBuildsWithWarnigs();
std::vector<OfflineCompiler *> singleBuilds;
MultiCommand &operator=(const MultiCommand &) = delete;
MultiCommand(const MultiCommand &) = delete;
~MultiCommand();
std::string OutDirForBuilds;
protected:
int splitLineInSeparateArgs(std::vector<std::string> &qargs, const std::string &command, int numberOfBuild);
void openFileWithBuildsArguments();
void addAdditionalOptionsToSingleCommandLine(std::vector<std::string> &, int);
int initialize(int numArgs, const char *argv[]);
int showResults();
int singleBuild(size_t numArgs, const std::vector<std::string> &allArgs);
std::string eraseExtensionFromPath(std::string &filePath);
std::vector<int> retValues;
std::string pathToCMD;
std::vector<std::string> lines;
bool quiet = false;
MultiCommand();
};
} // namespace NEO

View File

@@ -55,6 +55,12 @@ bool stringsAreEqual(const char *string1, const char *string2) {
return (strcmp(string1, string2) == 0);
}
bool stringsAreEqual(std::string string1, std::string string2) {
if (string2.empty())
return false;
return (string1 == string2);
}
////////////////////////////////////////////////////////////////////////////////
// convertToPascalCase
////////////////////////////////////////////////////////////////////////////////
@@ -91,12 +97,12 @@ OfflineCompiler::~OfflineCompiler() {
////////////////////////////////////////////////////////////////////////////////
// Create
////////////////////////////////////////////////////////////////////////////////
OfflineCompiler *OfflineCompiler::create(size_t numArgs, const char *const *argv, int &retVal) {
OfflineCompiler *OfflineCompiler::create(size_t numArgs, const std::vector<std::string> &allArgs, int &retVal) {
retVal = CL_SUCCESS;
auto pOffCompiler = new OfflineCompiler();
if (pOffCompiler) {
retVal = pOffCompiler->initialize(numArgs, argv);
retVal = pOffCompiler->initialize(numArgs, allArgs);
}
if (retVal != CL_SUCCESS) {
@@ -270,13 +276,13 @@ std::string OfflineCompiler::getStringWithinDelimiters(const std::string &src) {
////////////////////////////////////////////////////////////////////////////////
// Initialize
////////////////////////////////////////////////////////////////////////////////
int OfflineCompiler::initialize(size_t numArgs, const char *const *argv) {
int OfflineCompiler::initialize(size_t numArgs, const std::vector<std::string> &allArgs) {
int retVal = CL_SUCCESS;
const char *pSource = nullptr;
void *pSourceFromFile = nullptr;
size_t sourceFromFileSize = 0;
retVal = parseCommandLine(numArgs, argv);
retVal = parseCommandLine(numArgs, allArgs);
if (retVal != CL_SUCCESS) {
return retVal;
}
@@ -434,7 +440,7 @@ int OfflineCompiler::initialize(size_t numArgs, const char *const *argv) {
////////////////////////////////////////////////////////////////////////////////
// ParseCommandLine
////////////////////////////////////////////////////////////////////////////////
int OfflineCompiler::parseCommandLine(size_t numArgs, const char *const *argv) {
int OfflineCompiler::parseCommandLine(size_t numArgs, const std::vector<std::string> &argv) {
int retVal = CL_SUCCESS;
bool compile32 = false;
bool compile64 = false;
@@ -493,7 +499,7 @@ int OfflineCompiler::parseCommandLine(size_t numArgs, const char *const *argv) {
printUsage();
retVal = PRINT_USAGE;
} else {
printf("Invalid option (arg %d): %s\n", argIndex, argv[argIndex]);
printf("Invalid option (arg %d): %s\n", argIndex, argv[argIndex].c_str());
retVal = INVALID_COMMAND_LINE;
break;
}
@@ -642,6 +648,13 @@ void OfflineCompiler::printUsage() {
printf(" -device <device_type> Indicates which device for which we will compile.\n");
printf(" <device_type> can be: %s\n", getDevicesTypes().c_str());
printf("\n");
printf(" -multi <filename> Indicates the txt file with multi commands\n");
printf(" where each line is a single build in format:\n");
printf(" '-file <filename> -device <device_type> [OPTIONS]'\n");
printf(" Argument '-multi' must be first argument. \n");
printf(" Result of builds will be output in directory named \n");
printf(" like .txt file with build commands.\n");
printf("\n");
printf(" -output <filename> Indicates output files core name.\n");
printf(" -out_dir <output_dir> Indicates the directory into which the compiled files\n");
printf(" will be placed.\n");

View File

@@ -33,7 +33,7 @@ std::string generateFilePath(const std::string &directory, const std::string &fi
class OfflineCompiler {
public:
static OfflineCompiler *create(size_t numArgs, const char *const *argv, int &retVal);
static OfflineCompiler *create(size_t numArgs, const std::vector<std::string> &allArgs, int &retVal);
int build();
std::string &getBuildLog();
void printUsage();
@@ -55,8 +55,8 @@ class OfflineCompiler {
int getHardwareInfo(const char *pDeviceName);
std::string getFileNameTrunk(std::string &filePath);
std::string getStringWithinDelimiters(const std::string &src);
int initialize(size_t numArgs, const char *const *argv);
int parseCommandLine(size_t numArgs, const char *const *argv);
int initialize(size_t numArgs, const std::vector<std::string> &allArgs);
int parseCommandLine(size_t numArgs, const std::vector<std::string> &allArgs);
void setStatelessToStatefullBufferOffsetFlag();
void parseDebugSettings();
void storeBinary(char *&pDst, size_t &dstSize, const void *pSrc, const size_t srcSize);

View File

@@ -1,11 +1,12 @@
#
# Copyright (C) 2018 Intel Corporation
# Copyright (C) 2018-2019 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
project(ocloc_tests)
set(IGDRCL_SRCS_cloc
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/binary_decoder.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/decoder/binary_encoder.cpp
@@ -18,6 +19,26 @@ ${CMAKE_CURRENT_SOURCE_DIR}/decoder/mock/mock_encoder.h
${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_offline_compiler.h
)
set(CLOC_SRCS_UTILITIES
${IGDRCL_SOURCE_DIR}/offline_compiler/utilities/safety_caller.h
)
if(WIN32)
list(APPEND CLOC_SRCS_UTILITIES
${IGDRCL_SOURCE_DIR}/offline_compiler/utilities/windows/safety_caller_windows.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/utilities/windows/safety_guard_windows.h
${IGDRCL_SOURCE_DIR}/offline_compiler/utilities/windows/seh_exception.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/utilities/windows/seh_exception.h
)
else()
list(APPEND CLOC_SRCS_UTILITIES
${IGDRCL_SOURCE_DIR}/offline_compiler/utilities/linux/safety_caller_linux.cpp
${IGDRCL_SOURCE_DIR}/offline_compiler/utilities/linux/safety_guard_linux.h
)
endif()
set(IGDRCL_SRCS_offline_compiler_tests
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/decoder/decoder_tests.cpp
@@ -34,6 +55,7 @@ set(IGDRCL_SRCS_offline_compiler_tests
${IGDRCL_SRCS_cloc}
${IGDRCL_SRCS_offline_compiler_mock}
${CLOC_SRCS_LIB}
${CLOC_SRCS_UTILITIES}
)
if(WIN32)
@@ -57,6 +79,10 @@ target_compile_definitions(ocloc_tests PUBLIC MOCKABLE_VIRTUAL=virtual $<TARGET_
target_link_libraries(ocloc_tests igdrcl_mocks gmock-gtest elflib)
if(WIN32)
target_link_libraries(ocloc_tests dbghelp)
endif()
if(UNIX)
target_link_libraries(ocloc_tests dl pthread)
endif()

View File

@@ -31,11 +31,11 @@ class MockOfflineCompiler : public OfflineCompiler {
MockOfflineCompiler() : OfflineCompiler() {
}
int initialize(size_t numArgs, const char *const *argv) {
int initialize(size_t numArgs, const std::vector<std::string> &argv) {
return OfflineCompiler::initialize(numArgs, argv);
}
int parseCommandLine(size_t numArgs, const char *const *argv) {
int parseCommandLine(size_t numArgs, const std::vector<std::string> &argv) {
return OfflineCompiler::parseCommandLine(numArgs, argv);
}

View File

@@ -19,6 +19,7 @@
#include "mock/mock_offline_compiler.h"
#include <algorithm>
#include <fstream>
extern Environment *gEnvironment;
@@ -41,24 +42,172 @@ void compilerOutputRemove(const std::string &fileName, const std::string &type)
std::remove(getCompilerOutputFileName(fileName, type).c_str());
}
TEST_F(MultiCommandTests, MultiCommandSuccessfulBuildTest) {
nameOfFileWithArgs = "test_files/ImAMulitiComandMinimalGoodFile.txt";
const char *argv[] = {
"ocloc",
"-multi",
nameOfFileWithArgs.c_str(),
"-q",
};
int argSize = 4;
std::vector<std::string> singleArgs = {
"-file",
"test_files/copybuffer.cl",
"-device",
gEnvironment->devicePrefix.c_str()};
int numOfBuild = 4;
createFileWithArgs(singleArgs, numOfBuild);
auto pMultiCommand = std::unique_ptr<MultiCommand>(MultiCommand::create(argSize, argv, retVal));
EXPECT_NE(nullptr, pMultiCommand);
EXPECT_EQ(CL_SUCCESS, retVal);
deleteFileWithArgs();
}
TEST_F(MultiCommandTests, MultiCommandSuccessfulBuildWithOutputFileTest) {
nameOfFileWithArgs = "test_files/ImAMulitiComandMinimalGoodFile.txt";
const char *argv[] = {
"ocloc",
"-multi",
nameOfFileWithArgs.c_str(),
"-q",
};
int argSize = 4;
std::vector<std::string> singleArgs = {
"-file",
"test_files/copybuffer.cl",
"-device",
gEnvironment->devicePrefix.c_str()};
int numOfBuild = 4;
createFileWithArgs(singleArgs, numOfBuild);
auto pMultiCommand = std::unique_ptr<MultiCommand>(MultiCommand::create(argSize, argv, retVal));
EXPECT_NE(nullptr, pMultiCommand);
EXPECT_EQ(CL_SUCCESS, retVal);
for (int i = 0; i < numOfBuild; i++) {
std::string outFileName = pMultiCommand->OutDirForBuilds + "/build_no_" + std::to_string(i + 1);
EXPECT_TRUE(compilerOutputExists(outFileName, "bc") || compilerOutputExists(outFileName, "spv"));
EXPECT_TRUE(compilerOutputExists(outFileName, "gen"));
EXPECT_TRUE(compilerOutputExists(outFileName, "bin"));
}
for (OfflineCompiler *pSingle : pMultiCommand->singleBuilds) {
std::string buildLog = pSingle->getBuildLog();
EXPECT_STREQ(buildLog.c_str(), "");
}
deleteFileWithArgs();
}
TEST_F(MultiCommandTests, GoodMultiBuildTestWithspecifiedOutputDir) {
nameOfFileWithArgs = "test_files/ImAMulitiComandMinimalGoodFile.txt";
const char *argv[] = {
"ocloc",
"-multi",
nameOfFileWithArgs.c_str(),
"-q",
};
int argSize = 4;
std::vector<std::string> singleArgs = {
"-file",
"test_files/copybuffer.cl",
"-device",
gEnvironment->devicePrefix.c_str(),
"-out_dir",
"offline_compiler_test"};
int numOfBuild = 4;
createFileWithArgs(singleArgs, numOfBuild);
pMultiCommand = MultiCommand::create(argSize, argv, retVal);
EXPECT_NE(nullptr, pMultiCommand);
EXPECT_EQ(CL_SUCCESS, retVal);
for (int i = 0; i < numOfBuild; i++) {
std::string outFileName = "offline_compiler_test/build_no_" + std::to_string(i + 1);
EXPECT_TRUE(compilerOutputExists(outFileName, "bc") || compilerOutputExists(outFileName, "spv"));
EXPECT_TRUE(compilerOutputExists(outFileName, "gen"));
EXPECT_TRUE(compilerOutputExists(outFileName, "bin"));
}
deleteFileWithArgs();
delete pMultiCommand;
}
TEST_F(MultiCommandTests, LackOfTxtFileWithArgsMultiTest) {
nameOfFileWithArgs = "test_files/ImANotExistedComandFile.txt";
const char *argv[] = {
"ocloc",
"-multi",
"test_files/ImANaughtyFile.txt",
"-q",
};
int argSize = 4;
testing::internal::CaptureStdout();
auto pMultiCommand = std::unique_ptr<MultiCommand>(MultiCommand::create(argSize, argv, retVal));
std::string output = testing::internal::GetCapturedStdout();
EXPECT_STRNE(output.c_str(), "");
EXPECT_EQ(nullptr, pMultiCommand);
EXPECT_EQ(INVALID_COMMAND_LINE, retVal);
DebugManager.flags.PrintDebugMessages.set(false);
}
TEST_F(MultiCommandTests, LackOfClFilePointedInTxtFileMultiTest) {
nameOfFileWithArgs = "test_files/ImAMulitiComandMinimalGoodFile.txt";
const char *argv[] = {
"ocloc",
"-multi",
nameOfFileWithArgs.c_str(),
"-q",
};
int argSize = 4;
std::vector<std::string> singleArgs = {
"-file",
"test_files/ImANaughtyFile.cl",
"-device",
gEnvironment->devicePrefix.c_str()};
int numOfBuild = 4;
createFileWithArgs(singleArgs, numOfBuild);
testing::internal::CaptureStdout();
auto pMultiCommand = std::unique_ptr<MultiCommand>(MultiCommand::create(argSize, argv, retVal));
std::string output = testing::internal::GetCapturedStdout();
EXPECT_STRNE(output.c_str(), "");
EXPECT_EQ(nullptr, pMultiCommand);
EXPECT_EQ(INVALID_FILE, retVal);
DebugManager.flags.PrintDebugMessages.set(false);
deleteFileWithArgs();
}
TEST_F(OfflineCompilerTests, GoodArgTest) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/copybuffer.cl",
"-device",
gEnvironment->devicePrefix.c_str()};
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv.begin(), retVal);
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv, retVal);
EXPECT_NE(nullptr, pOfflineCompiler);
EXPECT_EQ(CL_SUCCESS, retVal);
delete pOfflineCompiler;
}
TEST_F(OfflineCompilerTests, TestExtensions) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/copybuffer.cl",
@@ -67,20 +216,19 @@ TEST_F(OfflineCompilerTests, TestExtensions) {
auto mockOfflineCompiler = std::unique_ptr<MockOfflineCompiler>(new MockOfflineCompiler());
ASSERT_NE(nullptr, mockOfflineCompiler);
mockOfflineCompiler->parseCommandLine(argv.size(), argv.begin());
mockOfflineCompiler->parseCommandLine(argv.size(), argv);
std::string internalOptions = mockOfflineCompiler->getInternalOptions();
EXPECT_THAT(internalOptions, ::testing::HasSubstr(std::string("cl_khr_3d_image_writes")));
}
TEST_F(OfflineCompilerTests, GoodBuildTest) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/copybuffer.cl",
"-device",
gEnvironment->devicePrefix.c_str()};
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv.begin(), retVal);
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv, retVal);
EXPECT_NE(nullptr, pOfflineCompiler);
EXPECT_EQ(CL_SUCCESS, retVal);
@@ -98,9 +246,8 @@ TEST_F(OfflineCompilerTests, GoodBuildTest) {
delete pOfflineCompiler;
}
TEST_F(OfflineCompilerTests, GoodBuildTestWithLlvmText) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/copybuffer.cl",
@@ -108,7 +255,7 @@ TEST_F(OfflineCompilerTests, GoodBuildTestWithLlvmText) {
gEnvironment->devicePrefix.c_str(),
"-llvm_text"};
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv.begin(), retVal);
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv, retVal);
EXPECT_NE(nullptr, pOfflineCompiler);
EXPECT_EQ(CL_SUCCESS, retVal);
@@ -121,16 +268,15 @@ TEST_F(OfflineCompilerTests, GoodBuildTestWithLlvmText) {
delete pOfflineCompiler;
}
TEST_F(OfflineCompilerTests, GoodParseBinToCharArray) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/copybuffer.cl",
"-device",
gEnvironment->devicePrefix.c_str()};
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv.begin(), retVal);
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv, retVal);
// clang-format off
uint8_t binary[] = {
0x02, 0x23, 0x3, 0x40, 0x56, 0x7, 0x80, 0x90, 0x1, 0x03,
@@ -168,9 +314,8 @@ TEST_F(OfflineCompilerTests, GoodParseBinToCharArray) {
delete pOfflineCompiler;
}
TEST_F(OfflineCompilerTests, GoodBuildTestWithCppFile) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/copybuffer.cl",
@@ -178,7 +323,7 @@ TEST_F(OfflineCompilerTests, GoodBuildTestWithCppFile) {
gEnvironment->devicePrefix.c_str(),
"-cpp_file"};
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv.begin(), retVal);
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv, retVal);
EXPECT_NE(nullptr, pOfflineCompiler);
EXPECT_EQ(CL_SUCCESS, retVal);
@@ -192,9 +337,8 @@ TEST_F(OfflineCompilerTests, GoodBuildTestWithCppFile) {
delete pOfflineCompiler;
}
TEST_F(OfflineCompilerTests, GoodBuildTestWithOutputDir) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/copybuffer.cl",
@@ -203,7 +347,7 @@ TEST_F(OfflineCompilerTests, GoodBuildTestWithOutputDir) {
"-out_dir",
"offline_compiler_test"};
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv.begin(), retVal);
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv, retVal);
EXPECT_NE(nullptr, pOfflineCompiler);
EXPECT_EQ(CL_SUCCESS, retVal);
@@ -216,14 +360,13 @@ TEST_F(OfflineCompilerTests, GoodBuildTestWithOutputDir) {
delete pOfflineCompiler;
}
TEST_F(OfflineCompilerTests, PrintUsage) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-?"};
testing::internal::CaptureStdout();
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv.begin(), retVal);
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv, retVal);
std::string output = testing::internal::GetCapturedStdout();
EXPECT_EQ(nullptr, pOfflineCompiler);
EXPECT_STRNE("", output.c_str());
@@ -231,10 +374,9 @@ TEST_F(OfflineCompilerTests, PrintUsage) {
delete pOfflineCompiler;
}
TEST_F(OfflineCompilerTests, NaughtyArgTest_File) {
DebugManager.flags.PrintDebugMessages.set(true);
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/ImANaughtyFile.cl",
@@ -242,7 +384,7 @@ TEST_F(OfflineCompilerTests, NaughtyArgTest_File) {
gEnvironment->devicePrefix.c_str()};
testing::internal::CaptureStdout();
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv.begin(), retVal);
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv, retVal);
std::string output = testing::internal::GetCapturedStdout();
EXPECT_STRNE(output.c_str(), "");
EXPECT_EQ(nullptr, pOfflineCompiler);
@@ -252,7 +394,7 @@ TEST_F(OfflineCompilerTests, NaughtyArgTest_File) {
}
TEST_F(OfflineCompilerTests, NaughtyArgTest_Flag) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-n",
"test_files/ImANaughtyFile.cl",
@@ -260,7 +402,7 @@ TEST_F(OfflineCompilerTests, NaughtyArgTest_Flag) {
gEnvironment->devicePrefix.c_str()};
testing::internal::CaptureStdout();
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv.begin(), retVal);
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv, retVal);
std::string output = testing::internal::GetCapturedStdout();
EXPECT_STRNE(output.c_str(), "");
EXPECT_EQ(nullptr, pOfflineCompiler);
@@ -270,13 +412,13 @@ TEST_F(OfflineCompilerTests, NaughtyArgTest_Flag) {
}
TEST_F(OfflineCompilerTests, NaughtyArgTest_NumArgs) {
auto argvA = {
std::vector<std::string> argvA = {
"ocloc",
"-file",
};
testing::internal::CaptureStdout();
pOfflineCompiler = OfflineCompiler::create(argvA.size(), argvA.begin(), retVal);
pOfflineCompiler = OfflineCompiler::create(argvA.size(), argvA, retVal);
std::string output = testing::internal::GetCapturedStdout();
EXPECT_STRNE(output.c_str(), "");
@@ -285,13 +427,13 @@ TEST_F(OfflineCompilerTests, NaughtyArgTest_NumArgs) {
delete pOfflineCompiler;
auto argvB = {
std::vector<std::string> argvB = {
"ocloc",
"-file",
"test_files/ImANaughtyFile.cl",
"-device"};
testing::internal::CaptureStdout();
pOfflineCompiler = OfflineCompiler::create(argvB.size(), argvB.begin(), retVal);
pOfflineCompiler = OfflineCompiler::create(argvB.size(), argvB, retVal);
output = testing::internal::GetCapturedStdout();
EXPECT_STRNE(output.c_str(), "");
EXPECT_EQ(nullptr, pOfflineCompiler);
@@ -301,7 +443,7 @@ TEST_F(OfflineCompilerTests, NaughtyArgTest_NumArgs) {
}
TEST_F(OfflineCompilerTests, GivenNonexistantDeviceWhenCompilingThenExitWithErrorMsg) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/copybuffer.cl",
@@ -309,7 +451,7 @@ TEST_F(OfflineCompilerTests, GivenNonexistantDeviceWhenCompilingThenExitWithErro
"foobar"};
testing::internal::CaptureStdout();
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv.begin(), retVal);
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv, retVal);
std::string output = testing::internal::GetCapturedStdout();
EXPECT_STREQ(output.c_str(), "Error: Cannot get HW Info for device foobar.\n");
EXPECT_EQ(nullptr, pOfflineCompiler);
@@ -317,14 +459,14 @@ TEST_F(OfflineCompilerTests, GivenNonexistantDeviceWhenCompilingThenExitWithErro
}
TEST_F(OfflineCompilerTests, NaughtyKernelTest) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/shouldfail.cl",
"-device",
gEnvironment->devicePrefix.c_str()};
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv.begin(), retVal);
pOfflineCompiler = OfflineCompiler::create(argv.size(), argv, retVal);
EXPECT_NE(nullptr, pOfflineCompiler);
EXPECT_EQ(CL_SUCCESS, retVal);
@@ -347,7 +489,7 @@ TEST_F(OfflineCompilerTests, NaughtyKernelTest) {
}
TEST(OfflineCompilerTest, parseCmdLine) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-cl-intel-greater-than-4GB-buffer-required"};
@@ -355,7 +497,7 @@ TEST(OfflineCompilerTest, parseCmdLine) {
ASSERT_NE(nullptr, mockOfflineCompiler);
testing::internal::CaptureStdout();
mockOfflineCompiler->parseCommandLine(argv.size(), argv.begin());
mockOfflineCompiler->parseCommandLine(argv.size(), argv);
std::string output = testing::internal::GetCapturedStdout();
std::string internalOptions = mockOfflineCompiler->getInternalOptions();
@@ -516,14 +658,14 @@ TEST(OfflineCompilerTest, buildSourceCode) {
auto retVal = mockOfflineCompiler->buildSourceCode();
EXPECT_EQ(CL_INVALID_PROGRAM, retVal);
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/copybuffer.cl",
"-device",
gEnvironment->devicePrefix.c_str()};
retVal = mockOfflineCompiler->initialize(argv.size(), argv.begin());
retVal = mockOfflineCompiler->initialize(argv.size(), argv);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_EQ(nullptr, mockOfflineCompiler->getGenBinary());
@@ -543,14 +685,14 @@ TEST(OfflineCompilerTest, GivenKernelWhenNoCharAfterKernelSourceThenBuildWithSuc
auto retVal = mockOfflineCompiler->buildSourceCode();
EXPECT_EQ(CL_INVALID_PROGRAM, retVal);
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/emptykernel.cl",
"-device",
gEnvironment->devicePrefix.c_str()};
retVal = mockOfflineCompiler->initialize(argv.size(), argv.begin());
retVal = mockOfflineCompiler->initialize(argv.size(), argv);
EXPECT_EQ(CL_SUCCESS, retVal);
retVal = mockOfflineCompiler->buildSourceCode();
@@ -588,7 +730,7 @@ TEST(OfflineCompilerTest, generateElfBinary) {
}
TEST(OfflineCompilerTest, givenLlvmInputOptionPassedWhenCmdLineParsedThenInputFileLlvmIsSetTrue) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-llvm_input"};
@@ -596,7 +738,7 @@ TEST(OfflineCompilerTest, givenLlvmInputOptionPassedWhenCmdLineParsedThenInputFi
ASSERT_NE(nullptr, mockOfflineCompiler);
testing::internal::CaptureStdout();
mockOfflineCompiler->parseCommandLine(argv.size(), argv.begin());
mockOfflineCompiler->parseCommandLine(argv.size(), argv);
std::string output = testing::internal::GetCapturedStdout();
EXPECT_NE(0u, output.size());
@@ -614,12 +756,12 @@ TEST(OfflineCompilerTest, givenDefaultOfflineCompilerObjectWhenNoOptionsAreChang
}
TEST(OfflineCompilerTest, givenSpirvInputOptionPassedWhenCmdLineParsedThenInputFileSpirvIsSetTrue) {
auto argv = {"ocloc", "-spirv_input"};
std::vector<std::string> argv = {"ocloc", "-spirv_input"};
auto mockOfflineCompiler = std::unique_ptr<MockOfflineCompiler>(new MockOfflineCompiler());
testing::internal::CaptureStdout();
mockOfflineCompiler->parseCommandLine(argv.size(), argv.begin());
mockOfflineCompiler->parseCommandLine(argv.size(), argv);
std::string output = testing::internal::GetCapturedStdout();
EXPECT_NE(0u, output.size());
@@ -633,14 +775,14 @@ TEST(OfflineCompilerTest, givenDefaultOfflineCompilerObjectWhenNoOptionsAreChang
TEST(OfflineCompilerTest, givenIntermediatedRepresentationInputWhenBuildSourceCodeIsCalledThenProperTranslationContextIsUsed) {
MockOfflineCompiler mockOfflineCompiler;
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/emptykernel.cl",
"-device",
gEnvironment->devicePrefix.c_str()};
auto retVal = mockOfflineCompiler.initialize(argv.size(), argv.begin());
auto retVal = mockOfflineCompiler.initialize(argv.size(), argv);
auto mockIgcOclDeviceCtx = new NEO::MockIgcOclDeviceCtx();
mockOfflineCompiler.igcDeviceCtx = CIF::RAII::Pack<IGC::IgcOclDeviceCtxLatest>(mockIgcOclDeviceCtx);
ASSERT_EQ(CL_SUCCESS, retVal);
@@ -663,16 +805,16 @@ TEST(OfflineCompilerTest, givenIntermediatedRepresentationInputWhenBuildSourceCo
}
TEST(OfflineCompilerTest, givenBinaryInputThenDontTruncateSourceAtFirstZero) {
auto argvLlvm = {"ocloc", "-llvm_input", "-file", "test_files/binary_with_zeroes",
std::vector<std::string> argvLlvm = {"ocloc", "-llvm_input", "-file", "test_files/binary_with_zeroes",
"-device", gEnvironment->devicePrefix.c_str()};
auto mockOfflineCompiler = std::make_unique<MockOfflineCompiler>();
mockOfflineCompiler->initialize(argvLlvm.size(), argvLlvm.begin());
mockOfflineCompiler->initialize(argvLlvm.size(), argvLlvm);
EXPECT_LT(0U, mockOfflineCompiler->sourceCode.size());
auto argvSpirV = {"ocloc", "-spirv_input", "-file", "test_files/binary_with_zeroes",
std::vector<std::string> argvSpirV = {"ocloc", "-spirv_input", "-file", "test_files/binary_with_zeroes",
"-device", gEnvironment->devicePrefix.c_str()};
mockOfflineCompiler = std::make_unique<MockOfflineCompiler>();
mockOfflineCompiler->initialize(argvSpirV.size(), argvSpirV.begin());
mockOfflineCompiler->initialize(argvSpirV.size(), argvSpirV);
EXPECT_LT(0U, mockOfflineCompiler->sourceCode.size());
}
@@ -685,7 +827,7 @@ TEST(OfflineCompilerTest, givenSpirvInputFileWhenCmdLineHasOptionsThenCorrectOpt
NEO::setIgcDebugVars(igcDebugVars);
MockOfflineCompiler mockOfflineCompiler;
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/emptykernel.cl",
@@ -695,7 +837,7 @@ TEST(OfflineCompilerTest, givenSpirvInputFileWhenCmdLineHasOptionsThenCorrectOpt
"-options",
"test_options_passed"};
auto retVal = mockOfflineCompiler.initialize(argv.size(), argv.begin());
auto retVal = mockOfflineCompiler.initialize(argv.size(), argv);
auto mockIgcOclDeviceCtx = new NEO::MockIgcOclDeviceCtx();
mockOfflineCompiler.igcDeviceCtx = CIF::RAII::Pack<IGC::IgcOclDeviceCtxLatest>(mockIgcOclDeviceCtx);
ASSERT_EQ(CL_SUCCESS, retVal);
@@ -710,7 +852,7 @@ TEST(OfflineCompilerTest, givenSpirvInputFileWhenCmdLineHasOptionsThenCorrectOpt
}
TEST(OfflineCompilerTest, givenOutputFileOptionWhenSourceIsCompiledThenOutputFileHasCorrectName) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/copybuffer.cl",
@@ -722,7 +864,7 @@ TEST(OfflineCompilerTest, givenOutputFileOptionWhenSourceIsCompiledThenOutputFil
auto mockOfflineCompiler = std::unique_ptr<MockOfflineCompiler>(new MockOfflineCompiler());
ASSERT_NE(nullptr, mockOfflineCompiler);
int retVal = mockOfflineCompiler->initialize(argv.size(), argv.begin());
int retVal = mockOfflineCompiler->initialize(argv.size(), argv);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_FALSE(compilerOutputExists("myOutputFileName", "bc") || compilerOutputExists("myOutputFileName", "spv"));
@@ -743,7 +885,7 @@ TEST(OfflineCompilerTest, givenOutputFileOptionWhenSourceIsCompiledThenOutputFil
}
TEST(OfflineCompilerTest, givenDebugDataAvailableWhenSourceIsBuiltThenDebugDataFileIsCreated) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-file",
"test_files/copybuffer.cl",
@@ -762,7 +904,7 @@ TEST(OfflineCompilerTest, givenDebugDataAvailableWhenSourceIsBuiltThenDebugDataF
auto mockOfflineCompiler = std::unique_ptr<MockOfflineCompiler>(new MockOfflineCompiler());
ASSERT_NE(nullptr, mockOfflineCompiler);
int retVal = mockOfflineCompiler->initialize(argv.size(), argv.begin());
int retVal = mockOfflineCompiler->initialize(argv.size(), argv);
EXPECT_EQ(CL_SUCCESS, retVal);
EXPECT_FALSE(compilerOutputExists("myOutputFileName", "bc") || compilerOutputExists("myOutputFileName", "spv"));
@@ -788,7 +930,7 @@ TEST(OfflineCompilerTest, givenDebugDataAvailableWhenSourceIsBuiltThenDebugDataF
}
TEST(OfflineCompilerTest, givenInternalOptionsWhenCmdLineParsedThenOptionsAreAppendedToInternalOptionsString) {
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-internal_options",
"myInternalOptions"};
@@ -797,7 +939,7 @@ TEST(OfflineCompilerTest, givenInternalOptionsWhenCmdLineParsedThenOptionsAreApp
ASSERT_NE(nullptr, mockOfflineCompiler);
testing::internal::CaptureStdout();
mockOfflineCompiler->parseCommandLine(argv.size(), argv.begin());
mockOfflineCompiler->parseCommandLine(argv.size(), argv);
std::string output = testing::internal::GetCapturedStdout();
EXPECT_NE(0u, output.size());
@@ -813,7 +955,7 @@ TEST(OfflineCompilerTest, givenInputOptionsAndInternalOptionsFilesWhenOfflineCom
ASSERT_TRUE(fileExists("test_files/shouldfail_options.txt"));
ASSERT_TRUE(fileExists("test_files/shouldfail_internal_options.txt"));
auto argv = {
std::vector<std::string> argv = {
"ocloc",
"-q",
"-file",
@@ -821,7 +963,7 @@ TEST(OfflineCompilerTest, givenInputOptionsAndInternalOptionsFilesWhenOfflineCom
"-device",
gEnvironment->devicePrefix.c_str()};
int retVal = mockOfflineCompiler->initialize(argv.size(), argv.begin());
int retVal = mockOfflineCompiler->initialize(argv.size(), argv);
EXPECT_EQ(CL_SUCCESS, retVal);
auto &options = mockOfflineCompiler->getOptions();

View File

@@ -6,6 +6,7 @@
*/
#pragma once
#include "offline_compiler/multi_command.h"
#include "offline_compiler/offline_compiler.h"
#include "gtest/gtest.h"
@@ -26,4 +27,34 @@ class OfflineCompilerTests : public ::testing::Test {
int retVal;
};
class MultiCommandTests : public ::testing::Test {
public:
MultiCommandTests() : pMultiCommand(nullptr),
retVal(CL_SUCCESS) {
}
void createFileWithArgs(const std::vector<std::string> &, int numOfBuild);
void deleteFileWithArgs();
MultiCommand *pMultiCommand;
std::string nameOfFileWithArgs;
int retVal;
};
void MultiCommandTests::createFileWithArgs(const std::vector<std::string> &singleArgs, int numOfBuild) {
std::ofstream myfile(nameOfFileWithArgs);
if (myfile.is_open()) {
for (int i = 0; i < numOfBuild; i++) {
for (auto singleArg : singleArgs)
myfile << singleArg + " ";
myfile << std::endl;
}
myfile.close();
} else
printf("Unable to open file\n");
}
void MultiCommandTests::deleteFileWithArgs() {
if (remove(nameOfFileWithArgs.c_str()) != 0)
perror("Error deleting file");
}
} // namespace NEO