2020-02-07 14:06:50 +01:00
|
|
|
/*
|
2022-01-11 13:03:13 +00:00
|
|
|
* Copyright (C) 2020-2022 Intel Corporation
|
2020-02-07 14:06:50 +01:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "ocloc_arg_helper.h"
|
|
|
|
|
|
|
|
#include "shared/source/helpers/file_io.h"
|
2021-03-15 17:01:04 +01:00
|
|
|
#include "shared/source/helpers/hw_info.h"
|
2020-02-07 14:06:50 +01:00
|
|
|
#include "shared/source/helpers/string.h"
|
|
|
|
|
2021-03-15 17:01:04 +01:00
|
|
|
#include "hw_cmds.h"
|
|
|
|
|
2021-04-16 15:25:00 +02:00
|
|
|
#include <algorithm>
|
2020-02-07 14:06:50 +01:00
|
|
|
#include <cstring>
|
|
|
|
#include <sstream>
|
2020-03-05 11:49:46 +01:00
|
|
|
|
2020-02-07 14:06:50 +01:00
|
|
|
void Source::toVectorOfStrings(std::vector<std::string> &lines, bool replaceTabs) {
|
|
|
|
std::string line;
|
|
|
|
const char *file = reinterpret_cast<const char *>(data);
|
|
|
|
|
|
|
|
while (*file != '\0') {
|
|
|
|
if (replaceTabs && *file == '\t') {
|
|
|
|
line += ' ';
|
|
|
|
} else if (*file == '\n') {
|
|
|
|
lines.push_back(line);
|
|
|
|
line = "";
|
|
|
|
} else {
|
|
|
|
line += *file;
|
|
|
|
}
|
|
|
|
file++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Output::Output(const std::string &name, const void *data, const size_t &size)
|
|
|
|
: name(name), size(size) {
|
|
|
|
this->data = new uint8_t[size];
|
|
|
|
memcpy_s(reinterpret_cast<void *>(this->data), this->size, data, size);
|
|
|
|
};
|
|
|
|
|
|
|
|
OclocArgHelper::OclocArgHelper(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)
|
|
|
|
: numOutputs(numOutputs), nameOutputs(nameOutputs),
|
2022-01-11 13:03:13 +00:00
|
|
|
dataOutputs(dataOutputs), lenOutputs(lenOutputs), hasOutput(numOutputs != nullptr),
|
|
|
|
messagePrinter(hasOutput), deviceProductTable({
|
2021-03-15 17:01:04 +01:00
|
|
|
#define NAMEDDEVICE(devId, product, ignored_gtType, ignored_devName) {devId, NEO::hardwarePrefix[NEO::product::hwInfo.platform.eProductFamily]},
|
|
|
|
#define DEVICE(devId, product, ignored_gtType) {devId, NEO::hardwarePrefix[NEO::product::hwInfo.platform.eProductFamily]},
|
|
|
|
#include "devices.inl"
|
|
|
|
#undef DEVICE
|
|
|
|
#undef NAMEDDEVICE
|
2022-01-11 13:03:13 +00:00
|
|
|
{0u, std::string("")}}),
|
2021-08-27 20:32:03 +00:00
|
|
|
deviceMap({
|
|
|
|
#define DEVICE_CONFIG_REVISION(product, productConfig, revision_id) {product, &NEO::productConfig::hwInfo, NEO::productConfig::setupHardwareInfo, revision_id},
|
|
|
|
#define DEVICE_CONFIG(product, productConfig) {product, &NEO::productConfig::hwInfo, NEO::productConfig::setupHardwareInfo, NEO::productConfig::hwInfo.platform.usRevId},
|
|
|
|
#include "product_config.inl"
|
|
|
|
#undef DEVICE_CONFIG
|
|
|
|
#undef DEVICE_CONFIG_REVISION
|
|
|
|
{PRODUCT_CONFIG::UNKNOWN_ISA, {}, 0x0}}) {
|
2020-02-07 14:06:50 +01:00
|
|
|
for (uint32_t i = 0; i < numSources; ++i) {
|
2020-03-02 13:15:50 +01:00
|
|
|
inputs.push_back(Source(dataSources[i], static_cast<size_t>(lenSources[i]), nameSources[i]));
|
2020-02-07 14:06:50 +01:00
|
|
|
}
|
|
|
|
for (uint32_t i = 0; i < numInputHeaders; ++i) {
|
2020-03-02 13:15:50 +01:00
|
|
|
headers.push_back(Source(dataInputHeaders[i], static_cast<size_t>(lenInputHeaders[i]), nameInputHeaders[i]));
|
2020-02-07 14:06:50 +01:00
|
|
|
}
|
2021-04-16 15:25:00 +02:00
|
|
|
for (unsigned int i = 0; i < IGFX_MAX_CORE; ++i) {
|
|
|
|
if (NEO::familyName[i] == nullptr)
|
|
|
|
continue;
|
|
|
|
std::string gen = NEO::familyName[i];
|
|
|
|
std::transform(gen.begin(), gen.end(), gen.begin(), ::tolower);
|
|
|
|
genIGFXMap.insert({gen, i});
|
|
|
|
}
|
2020-02-07 14:06:50 +01:00
|
|
|
}
|
|
|
|
|
2021-03-31 11:28:14 +02:00
|
|
|
OclocArgHelper::OclocArgHelper() : OclocArgHelper(0, nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr) {}
|
|
|
|
|
2020-02-07 14:06:50 +01:00
|
|
|
OclocArgHelper::~OclocArgHelper() {
|
|
|
|
if (outputEnabled()) {
|
2020-03-05 11:49:46 +01:00
|
|
|
saveOutput(oclocStdoutLogName, messagePrinter.getLog());
|
2020-02-07 14:06:50 +01:00
|
|
|
moveOutputs();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OclocArgHelper::fileExists(const std::string &filename) const {
|
|
|
|
return sourceFileExists(filename) || ::fileExists(filename);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OclocArgHelper::moveOutputs() {
|
|
|
|
*numOutputs = static_cast<uint32_t>(outputs.size());
|
|
|
|
*nameOutputs = new char *[outputs.size()];
|
|
|
|
*dataOutputs = new uint8_t *[outputs.size()];
|
|
|
|
*lenOutputs = new uint64_t[outputs.size()];
|
|
|
|
for (size_t i = 0; i < outputs.size(); ++i) {
|
2020-03-02 13:15:50 +01:00
|
|
|
size_t size = outputs[i]->name.length() + 1;
|
|
|
|
(*nameOutputs)[i] = new char[size];
|
|
|
|
strncpy_s((*nameOutputs)[i], size, outputs[i]->name.c_str(), outputs[i]->name.length() + 1);
|
2020-02-07 14:06:50 +01:00
|
|
|
(*dataOutputs)[i] = outputs[i]->data;
|
|
|
|
(*lenOutputs)[i] = outputs[i]->size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Source *OclocArgHelper::findSourceFile(const std::string &filename) {
|
|
|
|
for (auto &source : inputs) {
|
|
|
|
if (filename == source.name) {
|
|
|
|
return &source;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OclocArgHelper::sourceFileExists(const std::string &filename) const {
|
|
|
|
for (auto &input : inputs) {
|
|
|
|
if (filename == input.name) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::string> OclocArgHelper::headersToVectorOfStrings() {
|
|
|
|
std::vector<std::string> lines;
|
|
|
|
for (auto &header : headers) {
|
|
|
|
header.toVectorOfStrings(lines, true);
|
|
|
|
}
|
|
|
|
return lines;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OclocArgHelper::readFileToVectorOfStrings(const std::string &filename, std::vector<std::string> &lines) {
|
|
|
|
if (Source *s = findSourceFile(filename)) {
|
|
|
|
s->toVectorOfStrings(lines);
|
|
|
|
} else {
|
|
|
|
::readFileToVectorOfStrings(lines, filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<char> OclocArgHelper::readBinaryFile(const std::string &filename) {
|
|
|
|
if (Source *s = findSourceFile(filename)) {
|
|
|
|
return s->toBinaryVector();
|
|
|
|
} else {
|
|
|
|
return ::readBinaryFile(filename);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<char[]> OclocArgHelper::loadDataFromFile(const std::string &filename, size_t &retSize) {
|
|
|
|
if (Source *s = findSourceFile(filename)) {
|
2020-03-02 13:15:50 +01:00
|
|
|
auto size = s->length;
|
|
|
|
std::unique_ptr<char[]> ret(new char[size]());
|
|
|
|
memcpy_s(ret.get(), size, s->data, s->length);
|
|
|
|
retSize = s->length;
|
2020-02-07 14:06:50 +01:00
|
|
|
return ret;
|
|
|
|
} else {
|
|
|
|
return ::loadDataFromFile(filename.c_str(), retSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-27 20:32:03 +00:00
|
|
|
void OclocArgHelper::setDeviceInfoForFatbinaryTarget(const DeviceMapping &device) {
|
|
|
|
deviceForFatbinary.hwInfo = device.hwInfo;
|
|
|
|
deviceForFatbinary.setupHardwareInfo = device.setupHardwareInfo;
|
|
|
|
deviceForFatbinary.revId = device.revId;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OclocArgHelper::setHwInfoForFatbinaryTarget(NEO::HardwareInfo &hwInfo) {
|
|
|
|
hwInfo = *deviceForFatbinary.hwInfo;
|
|
|
|
deviceForFatbinary.setupHardwareInfo(&hwInfo, true);
|
|
|
|
hwInfo.platform.usRevId = deviceForFatbinary.revId;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OclocArgHelper::getHwInfoForProductConfig(uint32_t config, NEO::HardwareInfo &hwInfo) {
|
|
|
|
bool retVal = false;
|
|
|
|
if (config == UNKNOWN_ISA) {
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
for (auto &deviceConfig : deviceMap) {
|
|
|
|
if (deviceConfig.config == config) {
|
|
|
|
hwInfo = *deviceConfig.hwInfo;
|
|
|
|
deviceConfig.setupHardwareInfo(&hwInfo, true);
|
|
|
|
hwInfo.platform.usRevId = deviceConfig.revId;
|
|
|
|
retVal = true;
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return retVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OclocArgHelper::getProductConfigsForGfxCoreFamily(GFXCORE_FAMILY core, std::vector<DeviceMapping> &out) {
|
|
|
|
for (auto &deviceConfig : deviceMap) {
|
|
|
|
if (deviceConfig.config == PRODUCT_CONFIG::UNKNOWN_ISA)
|
|
|
|
continue;
|
|
|
|
if (deviceConfig.hwInfo->platform.eRenderCoreFamily == core) {
|
|
|
|
out.push_back(deviceConfig);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-07 14:06:50 +01:00
|
|
|
void OclocArgHelper::saveOutput(const std::string &filename, const void *pData, const size_t &dataSize) {
|
|
|
|
if (outputEnabled()) {
|
|
|
|
addOutput(filename, pData, dataSize);
|
|
|
|
} else {
|
|
|
|
writeDataToFile(filename.c_str(), pData, dataSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-05 11:49:46 +01:00
|
|
|
void OclocArgHelper::saveOutput(const std::string &filename, const std::ostream &stream) {
|
2020-02-07 14:06:50 +01:00
|
|
|
std::stringstream ss;
|
|
|
|
ss << stream.rdbuf();
|
|
|
|
if (outputEnabled()) {
|
|
|
|
addOutput(filename, ss.str().c_str(), ss.str().length());
|
|
|
|
} else {
|
|
|
|
std::ofstream file(filename);
|
|
|
|
file << ss.str();
|
|
|
|
}
|
|
|
|
}
|
2021-03-15 17:01:04 +01:00
|
|
|
|
|
|
|
std::string OclocArgHelper::returnProductNameForDevice(unsigned short deviceId) {
|
|
|
|
std::string res = "";
|
|
|
|
for (int i = 0; deviceProductTable[i].deviceId != 0; i++) {
|
|
|
|
if (deviceProductTable[i].deviceId == deviceId) {
|
|
|
|
res = deviceProductTable[i].product;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
2021-04-16 15:25:00 +02:00
|
|
|
}
|
|
|
|
|
2021-08-27 20:32:03 +00:00
|
|
|
std::vector<DeviceMapping> OclocArgHelper::getAllSupportedDeviceConfigs() {
|
|
|
|
std::vector<DeviceMapping> allConfigs;
|
|
|
|
|
|
|
|
for (auto &deviceConfig : deviceMap) {
|
|
|
|
if (deviceConfig.config != PRODUCT_CONFIG::UNKNOWN_ISA) {
|
|
|
|
allConfigs.push_back(deviceConfig);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
std::sort(allConfigs.begin(), allConfigs.end(), compareConfigs);
|
|
|
|
return allConfigs;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string OclocArgHelper::parseProductConfigFromValue(PRODUCT_CONFIG config) {
|
|
|
|
auto configValue = static_cast<uint32_t>(config);
|
|
|
|
std::stringstream stringConfig;
|
|
|
|
uint32_t major = (configValue & 0xff0000) >> 16;
|
|
|
|
uint32_t minor = (configValue & 0x00ff00) >> 8;
|
|
|
|
uint32_t revision = configValue & 0x0000ff;
|
|
|
|
stringConfig << major << "." << minor << "." << revision;
|
|
|
|
return stringConfig.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<PRODUCT_CONFIG> OclocArgHelper::getAllSupportedProductConfigs() {
|
|
|
|
std::vector<PRODUCT_CONFIG> allConfigs;
|
|
|
|
for (auto &deviceConfig : deviceMap) {
|
|
|
|
if (deviceConfig.config != PRODUCT_CONFIG::UNKNOWN_ISA) {
|
|
|
|
allConfigs.push_back(deviceConfig.config);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
std::sort(allConfigs.begin(), allConfigs.end());
|
|
|
|
return allConfigs;
|
|
|
|
}
|
|
|
|
|
|
|
|
int OclocArgHelper::parseProductConfigFromString(const std::string &device, size_t begin, size_t end) {
|
|
|
|
if (begin == end) {
|
|
|
|
return CONFIG_STATUS::MISMATCHED_VALUE;
|
|
|
|
}
|
|
|
|
if (end == std::string::npos) {
|
|
|
|
if (!std::all_of(device.begin() + begin, device.end(), (::isdigit))) {
|
|
|
|
return CONFIG_STATUS::MISMATCHED_VALUE;
|
|
|
|
}
|
|
|
|
return std::stoi(device.substr(begin, device.size() - begin));
|
|
|
|
} else {
|
|
|
|
if (!std::all_of(device.begin() + begin, device.begin() + end, (::isdigit))) {
|
|
|
|
return CONFIG_STATUS::MISMATCHED_VALUE;
|
|
|
|
}
|
|
|
|
return std::stoi(device.substr(begin, end - begin));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<uint32_t> OclocArgHelper::getMajorMinorRevision(const std::string &device) {
|
|
|
|
std::vector<uint32_t> numeration;
|
|
|
|
auto major_pos = device.find(".");
|
|
|
|
auto major = parseProductConfigFromString(device, 0, major_pos);
|
|
|
|
if (major == CONFIG_STATUS::MISMATCHED_VALUE) {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
numeration.push_back(major);
|
|
|
|
if (major_pos == std::string::npos) {
|
|
|
|
return numeration;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto minor_pos = device.find(".", ++major_pos);
|
|
|
|
auto minor = parseProductConfigFromString(device, major_pos, minor_pos);
|
|
|
|
|
|
|
|
if (minor == CONFIG_STATUS::MISMATCHED_VALUE) {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
numeration.push_back(minor);
|
|
|
|
if (minor_pos == std::string::npos) {
|
|
|
|
return numeration;
|
|
|
|
}
|
|
|
|
auto revision = parseProductConfigFromString(device, minor_pos + 1, device.size());
|
|
|
|
if (revision == CONFIG_STATUS::MISMATCHED_VALUE) {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
numeration.push_back(revision);
|
|
|
|
return numeration;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t OclocArgHelper::getProductConfig(std::vector<uint32_t> &numeration) {
|
|
|
|
uint32_t config = 0x0;
|
|
|
|
|
|
|
|
config = numeration.at(0) << 16;
|
|
|
|
if (numeration.size() > 1) {
|
|
|
|
config |= (numeration.at(1) << 8);
|
|
|
|
}
|
|
|
|
if (numeration.size() > 2) {
|
|
|
|
config |= numeration.at(2);
|
|
|
|
}
|
|
|
|
|
|
|
|
return config;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t OclocArgHelper::getMaskForConfig(std::vector<uint32_t> &numeration) {
|
|
|
|
uint32_t mask = 0xffffff;
|
|
|
|
if (numeration.size() == 1) {
|
|
|
|
mask = 0xff0000;
|
|
|
|
} else if (numeration.size() == 2) {
|
|
|
|
mask = 0xffff00;
|
|
|
|
}
|
|
|
|
return mask;
|
|
|
|
}
|
|
|
|
|
2021-04-16 15:25:00 +02:00
|
|
|
bool OclocArgHelper::isGen(const std::string &device) {
|
|
|
|
std::string buf(device);
|
|
|
|
std::transform(buf.begin(), buf.end(), buf.begin(), ::tolower);
|
|
|
|
auto it = genIGFXMap.find(buf);
|
|
|
|
return it == genIGFXMap.end() ? false : true;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int OclocArgHelper::returnIGFXforGen(const std::string &device) {
|
|
|
|
std::string buf(device);
|
|
|
|
std::transform(buf.begin(), buf.end(), buf.begin(), ::tolower);
|
|
|
|
auto it = genIGFXMap.find(buf);
|
|
|
|
if (it == genIGFXMap.end())
|
|
|
|
return 0;
|
|
|
|
return it->second;
|
2021-08-27 20:32:03 +00:00
|
|
|
}
|
|
|
|
|
2021-12-16 17:43:11 +00:00
|
|
|
bool OclocArgHelper::areQuotesRequired(const std::string_view &argName) {
|
|
|
|
return argName == "-options" || argName == "-internal_options";
|
|
|
|
}
|
|
|
|
|
2021-08-27 20:32:03 +00:00
|
|
|
PRODUCT_CONFIG OclocArgHelper::findConfigMatch(const std::string &device, bool firstAppearance) {
|
|
|
|
auto numeration = getMajorMinorRevision(device);
|
|
|
|
if (numeration.empty()) {
|
|
|
|
return PRODUCT_CONFIG::UNKNOWN_ISA;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<PRODUCT_CONFIG> allMatchedConfigs;
|
|
|
|
std::vector<PRODUCT_CONFIG> allConfigs = getAllSupportedProductConfigs();
|
|
|
|
auto configValue = getProductConfig(numeration);
|
|
|
|
uint32_t mask = getMaskForConfig(numeration);
|
|
|
|
|
|
|
|
if (!firstAppearance) {
|
|
|
|
// find last appearance
|
|
|
|
std::reverse(allConfigs.begin(), allConfigs.end());
|
|
|
|
}
|
|
|
|
|
|
|
|
for (auto &productConfig : allConfigs) {
|
|
|
|
uint32_t value = static_cast<uint32_t>(productConfig) & mask;
|
|
|
|
if (value == configValue) {
|
|
|
|
return productConfig;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return PRODUCT_CONFIG::UNKNOWN_ISA;
|
|
|
|
}
|