Add ids command to ocloc

New command usage: ocloc ids <acronym>.
It will allow the user to query all matched
<major>.<minor>.<revision> for the specified acronym.
E.g.
ocloc ids dg1
Matched ids:
12.10.0

Signed-off-by: Daria Hinz <daria.hinz@intel.com>
Related-To: NEO-7159
This commit is contained in:
Daria Hinz
2022-07-05 14:24:35 +02:00
committed by Compute-Runtime-Automation
parent d68dedba3b
commit ea2edbef3d
9 changed files with 299 additions and 65 deletions

View File

@ -179,6 +179,39 @@ TEST(OclocApiTests, GivenInvalidQueryWhenQueryingThenErrorIsReturned) {
EXPECT_STREQ("Error: Invalid command line. Uknown argument unknown_query.", output.c_str());
}
TEST(OclocApiTests, givenNoAcronymWhenIdsCommandIsInvokeThenErrorIsReported) {
const char *argv[] = {
"ocloc",
"ids"};
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, NEO::OclocErrorCode::INVALID_COMMAND_LINE);
EXPECT_STREQ("Error: Invalid command line. Expected ocloc ids <acronym>.\n", output.c_str());
}
TEST(OclocApiTests, givenUnknownAcronymWhenIdsCommandIsInvokeThenErrorIsReported) {
const char *argv[] = {
"ocloc",
"ids",
"unk"};
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, NEO::OclocErrorCode::INVALID_COMMAND_LINE);
EXPECT_STREQ("Error: Invalid command line. Uknown acronym unk.\n", output.c_str());
}
TEST(OclocApiTests, WhenGoodFamilyNameIsProvidedThenSuccessIsReturned) {
std::string clFileName(clFiles + "copybuffer.cl");
std::unique_ptr<OclocArgHelper> argHelper = std::make_unique<OclocArgHelper>();

View File

@ -702,6 +702,133 @@ TEST_F(OfflineCompilerTests, GivenHelpOptionOnQueryThenSuccessIsReturned) {
EXPECT_EQ(OclocErrorCode::SUCCESS, retVal);
}
TEST_F(OfflineCompilerTests, GivenHelpOptionOnIdsThenSuccessIsReturned) {
std::vector<ConstStringRef> helpFlags = {"-h", "--help"};
for (const auto &helpFlag : helpFlags) {
std::vector<std::string> argv = {
"ocloc",
"ids",
helpFlag.str()};
testing::internal::CaptureStdout();
int retVal = OfflineCompiler::queryAcronymIds(argv.size(), argv, oclocArgHelperWithoutInput.get());
std::string output = testing::internal::GetCapturedStdout();
std::stringstream expectedOutput;
expectedOutput << R"===(
Depending on <acronym> will return all
matched versions (<major>.<minor>.<revision>)
that correspond to the given name.
All supported acronyms: )===";
expectedOutput << getSupportedDevices(oclocArgHelperWithoutInput.get()) << ".\n";
EXPECT_STREQ(output.c_str(), expectedOutput.str().c_str());
EXPECT_EQ(OclocErrorCode::SUCCESS, retVal);
}
}
TEST_F(OfflineCompilerTests, givenFamilyAcronymWhenIdsCommandIsInvokeThenSuccessAndCorrectIdsAreReturned) {
auto enabledFamilies = oclocArgHelperWithoutInput->getEnabledFamiliesAcronyms();
if (enabledFamilies.empty()) {
GTEST_SKIP();
}
auto supportedDevicesConfigs = oclocArgHelperWithoutInput->getAllSupportedDeviceConfigs();
for (const auto &familyAcronym : enabledFamilies) {
std::vector<std::string> expected{};
auto family = ProductConfigHelper::returnFamilyForAcronym(familyAcronym.str());
for (const auto &device : supportedDevicesConfigs) {
if (device.family == family) {
auto config = ProductConfigHelper::parseMajorMinorRevisionValue(device.aotConfig);
expected.push_back(config);
}
}
std::vector<std::string> argv = {
"ocloc",
"ids",
familyAcronym.str()};
std::stringstream expectedOutput;
testing::internal::CaptureStdout();
int retVal = OfflineCompiler::queryAcronymIds(argv.size(), argv, oclocArgHelperWithoutInput.get());
std::string output = testing::internal::GetCapturedStdout();
expectedOutput << "Matched ids:";
for (const auto &prefix : expected) {
expectedOutput << "\n" + prefix;
}
EXPECT_STREQ(expectedOutput.str().c_str(), output.c_str());
EXPECT_EQ(OclocErrorCode::SUCCESS, retVal);
}
}
TEST_F(OfflineCompilerTests, givenReleaseAcronymWhenIdsCommandIsInvokeThenSuccessAndCorrectIdsAreReturned) {
auto enabledReleases = oclocArgHelperWithoutInput->getEnabledReleasesAcronyms();
if (enabledReleases.empty()) {
GTEST_SKIP();
}
auto supportedDevicesConfigs = oclocArgHelperWithoutInput->getAllSupportedDeviceConfigs();
for (const auto &releaseAcronym : enabledReleases) {
std::vector<std::string> expected{};
auto release = ProductConfigHelper::returnReleaseForAcronym(releaseAcronym.str());
for (const auto &device : supportedDevicesConfigs) {
if (device.release == release) {
auto config = ProductConfigHelper::parseMajorMinorRevisionValue(device.aotConfig);
expected.push_back(config);
}
}
std::vector<std::string> argv = {
"ocloc",
"ids",
releaseAcronym.str()};
std::stringstream expectedOutput;
testing::internal::CaptureStdout();
int retVal = OfflineCompiler::queryAcronymIds(argv.size(), argv, oclocArgHelperWithoutInput.get());
std::string output = testing::internal::GetCapturedStdout();
expectedOutput << "Matched ids:";
for (const auto &prefix : expected) {
expectedOutput << "\n" + prefix;
}
EXPECT_STREQ(expectedOutput.str().c_str(), output.c_str());
EXPECT_EQ(OclocErrorCode::SUCCESS, retVal);
}
}
TEST_F(OfflineCompilerTests, givenProductAcronymWhenIdsCommandIsInvokeThenSuccessAndCorrectIdsAreReturned) {
auto enabledProducts = oclocArgHelperWithoutInput->getEnabledProductAcronyms();
if (enabledProducts.empty()) {
GTEST_SKIP();
}
auto supportedDevicesConfigs = oclocArgHelperWithoutInput->getAllSupportedDeviceConfigs();
for (const auto &productAcronym : enabledProducts) {
std::vector<std::string> expected{};
auto product = ProductConfigHelper::returnProductConfigForAcronym(productAcronym.str());
for (const auto &device : supportedDevicesConfigs) {
if (device.aotConfig.ProductConfig == product) {
auto config = ProductConfigHelper::parseMajorMinorRevisionValue(device.aotConfig);
expected.push_back(config);
}
}
std::vector<std::string> argv = {
"ocloc",
"ids",
productAcronym.str()};
std::stringstream expectedOutput;
testing::internal::CaptureStdout();
int retVal = OfflineCompiler::queryAcronymIds(argv.size(), argv, oclocArgHelperWithoutInput.get());
std::string output = testing::internal::GetCapturedStdout();
expectedOutput << "Matched ids:";
for (const auto &prefix : expected) {
expectedOutput << "\n" + prefix;
}
EXPECT_STREQ(expectedOutput.str().c_str(), output.c_str());
EXPECT_EQ(OclocErrorCode::SUCCESS, retVal);
}
}
TEST_F(OfflineCompilerTests, GivenFlagsWhichRequireMoreArgsWithoutThemWhenParsingThenErrorIsReported) {
const std::array<std::string, 8> flagsToTest = {
"-file", "-output", "-device", "-options", "-internal_options", "-out_dir", "-revision_id", "-config"};

View File

@ -99,7 +99,7 @@ const void *BinaryDecoder::getDevBinary() {
std::string decoderWarnings;
auto input = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(binary.data()), binary.size());
auto elf = NEO::Elf::decodeElf<NEO::Elf::EI_CLASS_64>(input, decoderErrors, decoderWarnings);
for (const auto &sectionHeader : elf.sectionHeaders) { //Finding right section
for (const auto &sectionHeader : elf.sectionHeaders) { // Finding right section
auto sectionData = ArrayRef<const char>(reinterpret_cast<const char *>(sectionHeader.data.begin()), sectionHeader.data.size());
switch (sectionHeader.header->type) {
case NEO::Elf::SHT_OPENCL_LLVM_BINARY: {
@ -210,7 +210,7 @@ std::vector<std::string> BinaryDecoder::loadPatchList() {
}
void BinaryDecoder::parseTokens() {
//Creating patchlist definitions
// Creating patchlist definitions
auto patchList = loadPatchList();
size_t pos = findPos(patchList, "struct SProgramBinaryHeader");
@ -274,11 +274,11 @@ void BinaryDecoder::parseTokens() {
patchTokens[static_cast<uint8_t>(patchNo)] = std::move(patchTokenPtr);
}
//Finding and reading Program Binary Header
// Finding and reading Program Binary Header
size_t structPos = findPos(patchList, "struct SProgramBinaryHeader") + 1;
programHeader.size = readStructFields(patchList, structPos, programHeader.fields);
//Finding and reading Kernel Binary Header
// Finding and reading Kernel Binary Header
structPos = findPos(patchList, "struct SKernelBinaryHeader") + 1;
kernelHeader.size = readStructFields(patchList, structPos, kernelHeader.fields);
@ -336,7 +336,7 @@ Examples:
Disassemble Intel Compute GPU device binary
ocloc disasm -file source_file_Gen9core.bin
)===",
argHelper->getAllSupportedAcronyms().c_str());
argHelper->createStringForArgs(argHelper->getAllSupportedProductAcronyms()).c_str());
}
int BinaryDecoder::processBinary(const void *&ptr, std::ostream &ptmFile) {
@ -359,7 +359,7 @@ int BinaryDecoder::processBinary(const void *&ptr, std::ostream &ptmFile) {
readPatchTokens(ptr, patchListSize, ptmFile);
iga->setGfxCore(static_cast<GFXCORE_FAMILY>(device));
//Reading Kernels
// Reading Kernels
for (uint32_t i = 0; i < numberOfKernels; ++i) {
ptmFile << "Kernel #" << i << '\n';
processKernel(ptr, ptmFile);

View File

@ -69,7 +69,7 @@ bool BinaryEncoder::copyBinaryToBinary(const std::string &srcFileName, std::ostr
int BinaryEncoder::createElf(std::stringstream &deviceBinary) {
NEO::Elf::ElfEncoder<NEO::Elf::EI_CLASS_64> elfEncoder;
elfEncoder.getElfFileHeader().type = NEO::Elf::ET_OPENCL_EXECUTABLE;
//Build Options
// Build Options
if (argHelper->fileExists(pathToDump + "build.bin")) {
auto binary = argHelper->readBinaryFile(pathToDump + "build.bin");
elfEncoder.appendSection(NEO::Elf::SHT_OPENCL_OPTIONS, "BuildOptions",
@ -77,7 +77,7 @@ int BinaryEncoder::createElf(std::stringstream &deviceBinary) {
} else {
argHelper->printf("Warning! Missing build section.\n");
}
//LLVM or SPIRV
// LLVM or SPIRV
if (argHelper->fileExists(pathToDump + "llvm.bin")) {
auto binary = argHelper->readBinaryFile(pathToDump + "llvm.bin");
elfEncoder.appendSection(NEO::Elf::SHT_OPENCL_LLVM_BINARY, "Intel(R) OpenCL LLVM Object",
@ -90,13 +90,13 @@ int BinaryEncoder::createElf(std::stringstream &deviceBinary) {
argHelper->printf("Warning! Missing llvm/spirv section.\n");
}
//Device Binary
// Device Binary
auto deviceBinaryStr = deviceBinary.str();
std::vector<char> binary(deviceBinaryStr.begin(), deviceBinaryStr.end());
elfEncoder.appendSection(NEO::Elf::SHT_OPENCL_DEV_BINARY, "Intel(R) OpenCL Device Binary",
ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(binary.data()), binary.size()));
//Resolve Elf Binary
// Resolve Elf Binary
auto elfBinary = elfEncoder.encode();
argHelper->saveOutput(elfName, elfBinary.data(), elfBinary.size());
@ -133,7 +133,7 @@ Examples:
Assemble to Intel Compute GPU device binary
ocloc asm -out reassembled.bin
)===",
argHelper->getAllSupportedAcronyms().c_str());
argHelper->createStringForArgs(argHelper->getAllSupportedProductAcronyms()).c_str());
}
int BinaryEncoder::encode() {

View File

@ -157,6 +157,8 @@ int oclocInvoke(unsigned int numArgs, const char *argv[],
return NEO::Ocloc::validate(allArgs, helper.get());
} else if (numArgs > 1 && ConstStringRef("query") == allArgs[1]) {
return OfflineCompiler::query(numArgs, allArgs, helper.get());
} else if (numArgs > 1 && ConstStringRef("ids") == allArgs[1]) {
return OfflineCompiler::queryAcronymIds(numArgs, allArgs, helper.get());
} else if (numArgs > 1 && ConstStringRef("link") == allArgs[1]) {
int createResult{OclocErrorCode::SUCCESS};
const auto linker{OfflineLinker::create(numArgs, allArgs, createResult, helper.get())};

View File

@ -233,16 +233,12 @@ void OclocArgHelper::saveOutput(const std::string &filename, const std::ostream
}
}
std::string OclocArgHelper::getAllSupportedAcronyms() {
std::ostringstream os;
std::vector<NEO::ConstStringRef> OclocArgHelper::getAllSupportedProductAcronyms() {
std::vector<NEO::ConstStringRef> allEnabledAcronyms{};
for (const auto &device : deviceMap) {
for (const auto &acronym : device.acronyms) {
if (os.tellp())
os << ", ";
os << acronym.str();
}
allEnabledAcronyms.insert(allEnabledAcronyms.end(), device.acronyms.begin(), device.acronyms.end());
}
return os.str();
return allEnabledAcronyms;
}
std::vector<NEO::ConstStringRef> OclocArgHelper::getEnabledProductAcronyms() {

View File

@ -15,6 +15,7 @@
#include "device_ids_configs.h"
#include "platforms.h"
#include <algorithm>
#include <cctype>
#include <fstream>
#include <map>
@ -120,10 +121,10 @@ class OclocArgHelper {
std::vector<NEO::ConstStringRef> getEnabledProductAcronyms();
std::vector<NEO::ConstStringRef> getEnabledReleasesAcronyms();
std::vector<NEO::ConstStringRef> getEnabledFamiliesAcronyms();
std::vector<NEO::ConstStringRef> getDeprecatedAcronyms();
std::vector<NEO::ConstStringRef> getAllSupportedProductAcronyms();
std::string getAllSupportedAcronyms();
AOT::PRODUCT_CONFIG getProductConfigForVersionValue(const std::string &device);
std::vector<NEO::ConstStringRef> getDeprecatedAcronyms();
bool setAcronymForDeviceId(std::string &device);
std::vector<std::string> headersToVectorOfStrings();
MOCKABLE_VIRTUAL void readFileToVectorOfStrings(const std::string &filename, std::vector<std::string> &lines);
@ -151,6 +152,36 @@ class OclocArgHelper {
void printf(const char *format, Args... args) {
messagePrinter.printf(format, std::forward<Args>(args)...);
}
template <typename EqComparableT>
static auto findDuplicate(const EqComparableT &lhs) {
return [&lhs](const auto &rhs) { return lhs == rhs; };
}
template <typename... Args>
static auto getArgsWithoutDuplicate(Args... args) {
std::vector<NEO::ConstStringRef> out{};
for (const auto &acronyms : {args...}) {
for (const auto &acronym : acronyms) {
if (!std::any_of(out.begin(), out.end(), findDuplicate(acronym))) {
out.push_back(acronym);
}
}
}
return out;
}
template <typename... Args>
static auto createStringForArgs(Args... args) {
std::ostringstream os;
for (const auto &acronyms : {args...}) {
for (const auto &acronym : acronyms) {
if (os.tellp())
os << ", ";
os << acronym.str();
}
}
return os.str();
}
bool isRelease(const std::string &device);
bool isFamily(const std::string &device);

View File

@ -72,6 +72,20 @@ std::string convertToPascalCase(const std::string &inString) {
return outString;
}
std::string getDeprecatedDevices(OclocArgHelper *helper) {
auto acronyms = helper->getDeprecatedAcronyms();
return helper->createStringForArgs(acronyms);
}
std::string getSupportedDevices(OclocArgHelper *helper) {
auto devices = helper->getAllSupportedProductAcronyms();
auto families = helper->getEnabledFamiliesAcronyms();
auto releases = helper->getEnabledReleasesAcronyms();
auto familiesAndReleases = helper->getArgsWithoutDuplicate(families, releases);
return helper->createStringForArgs(devices, familiesAndReleases);
}
OfflineCompiler::OfflineCompiler() = default;
OfflineCompiler::~OfflineCompiler() {
pBuildInfo.reset();
@ -128,6 +142,67 @@ int OfflineCompiler::query(size_t numArgs, const std::vector<std::string> &allAr
return retVal;
}
void printAcronymIdsHelp(OclocArgHelper *helper) {
helper->printf(OfflineCompiler::idsHelp.data(), getSupportedDevices(helper).c_str());
}
int OfflineCompiler::queryAcronymIds(size_t numArgs, const std::vector<std::string> &allArgs, OclocArgHelper *helper) {
const size_t numArgRequested = 3u;
auto retVal = SUCCESS;
if (numArgs != numArgRequested) {
helper->printf("Error: Invalid command line. Expected ocloc ids <acronym>.\n");
retVal = INVALID_COMMAND_LINE;
return retVal;
} else if ((ConstStringRef("-h") == allArgs[2] || ConstStringRef("--help") == allArgs[2])) {
printAcronymIdsHelp(helper);
return retVal;
}
std::string queryAcronym = allArgs[2];
ProductConfigHelper::adjustDeviceName(queryAcronym);
auto enabledDevices = helper->getAllSupportedDeviceConfigs();
std::vector<std::string> matchedVersions{};
if (helper->isFamily(queryAcronym)) {
auto family = ProductConfigHelper::returnFamilyForAcronym(queryAcronym);
for (const auto &device : enabledDevices) {
if (device.family == family) {
matchedVersions.push_back(ProductConfigHelper::parseMajorMinorRevisionValue(device.aotConfig));
}
}
} else if (helper->isRelease(queryAcronym)) {
auto release = ProductConfigHelper::returnReleaseForAcronym(queryAcronym);
for (const auto &device : enabledDevices) {
if (device.release == release) {
matchedVersions.push_back(ProductConfigHelper::parseMajorMinorRevisionValue(device.aotConfig));
}
}
} else if (helper->isProductConfig(queryAcronym)) {
auto product = ProductConfigHelper::returnProductConfigForAcronym(queryAcronym);
for (const auto &device : enabledDevices) {
if (device.aotConfig.ProductConfig == product) {
matchedVersions.push_back(ProductConfigHelper::parseMajorMinorRevisionValue(device.aotConfig));
}
}
} else {
helper->printf("Error: Invalid command line. Uknown acronym %s.\n", allArgs[2].c_str());
retVal = INVALID_COMMAND_LINE;
return retVal;
}
std::ostringstream os;
for (const auto &prefix : matchedVersions) {
if (os.tellp())
os << "\n";
os << prefix;
}
helper->printf("Matched ids:\n%s", os.str().c_str());
return retVal;
}
struct OfflineCompiler::buildInfo {
std::unique_ptr<CIF::Builtins::BufferLatest, CIF::RAII::ReleaseHelper<CIF::Builtins::BufferLatest>> fclOptions;
std::unique_ptr<CIF::Builtins::BufferLatest, CIF::RAII::ReleaseHelper<CIF::Builtins::BufferLatest>> fclInternalOptions;
@ -770,44 +845,6 @@ std::string OfflineCompiler::getFileNameTrunk(std::string &filePath) {
return fileTrunk;
}
template <typename EqComparableT>
auto findDuplicate(const EqComparableT &lhs) {
return [&lhs](const auto &rhs) { return lhs == rhs; };
}
std::string OfflineCompiler::getDeprecatedDevicesTypes() {
auto acronyms = argHelper->getDeprecatedAcronyms();
std::ostringstream os;
for (const auto &acronym : acronyms) {
if (os.tellp())
os << ", ";
os << acronym.str();
}
return os.str();
}
std::string OfflineCompiler::getDevicesReleasesAndFamilies() {
auto acronyms = argHelper->getEnabledReleasesAcronyms();
auto familiesAcronyms = argHelper->getEnabledFamiliesAcronyms();
for (const auto &family : familiesAcronyms) {
if (!std::any_of(acronyms.begin(), acronyms.end(), findDuplicate(family))) {
acronyms.push_back(family);
}
}
std::ostringstream os;
for (const auto &acronym : acronyms) {
if (os.tellp())
os << ", ";
os << acronym.str();
}
return os.str();
}
void OfflineCompiler::printUsage() {
argHelper->printf(R"===(Compiles input file to Intel Compute GPU device binary (*.bin).
Additionally, outputs intermediate representation (e.g. spirV).
@ -820,7 +857,8 @@ Usage: ocloc [compile] -file <filename> -device <device_type> [-output <filename
OpenCL C kernel language).
-device <device_type> Target device.
<device_type> can be: %s, %s, version or hexadecimal value with 0x prefix - can be single or multiple target devices.
<device_type> can be: %s, version or hexadecimal value with 0x prefix
- can be single or multiple target devices.
The version is a representation of the
<major>.<minor>.<revision> value.
The hexadecimal value represents device ID.
@ -952,9 +990,8 @@ Examples :
Compile file to Intel Compute GPU device binary (out = source_file_Gen9core.bin)
ocloc -file source_file.cl -device skl
)===",
argHelper->getAllSupportedAcronyms().c_str(),
getDevicesReleasesAndFamilies().c_str(),
getDeprecatedDevicesTypes().c_str());
getSupportedDevices(argHelper).c_str(),
getDeprecatedDevices(argHelper).c_str());
}
void OfflineCompiler::storeBinary(

View File

@ -29,17 +29,18 @@ class OsLibrary;
std::string convertToPascalCase(const std::string &inString);
std::string generateFilePath(const std::string &directory, const std::string &fileNameBase, const char *extension);
std::string getSupportedDevices(OclocArgHelper *helper);
class OfflineCompiler {
public:
static int query(size_t numArgs, const std::vector<std::string> &allArgs, OclocArgHelper *helper);
static int queryAcronymIds(size_t numArgs, const std::vector<std::string> &allArgs, OclocArgHelper *helper);
static OfflineCompiler *create(size_t numArgs, const std::vector<std::string> &allArgs, bool dumpFiles, int &retVal, OclocArgHelper *helper);
MOCKABLE_VIRTUAL int build();
std::string &getBuildLog();
void printUsage();
std::string getDevicesReleasesAndFamilies();
std::string getDeprecatedDevicesTypes();
static constexpr ConstStringRef queryHelp =
"Depending on <query_option> will generate file\n"
@ -53,6 +54,13 @@ class OfflineCompiler {
" Extract driver version\n"
" ocloc query OCL_DRIVER_VERSION\n";
static constexpr ConstStringRef idsHelp = R"===(
Depending on <acronym> will return all
matched versions (<major>.<minor>.<revision>)
that correspond to the given name.
All supported acronyms: %s.
)===";
OfflineCompiler &operator=(const OfflineCompiler &) = delete;
OfflineCompiler(const OfflineCompiler &) = delete;
MOCKABLE_VIRTUAL ~OfflineCompiler();