mirror of
https://github.com/intel/compute-runtime.git
synced 2025-12-20 00:24:58 +08:00
feature: Add support for older ocloc libraries to create fatbinary w/legacy devs
Related-To: NEO-9630 Signed-off-by: Krzysztof Sprzaczkowski <krzysztof.sprzaczkowski@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
7ee4f2d0aa
commit
07a858ffb9
@@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "shared/offline_compiler/source/ocloc_arg_helper.h"
|
||||
#include "shared/source/helpers/product_config_helper_former.h"
|
||||
#include "shared/source/helpers/string.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -15,6 +16,10 @@
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
int oclocInvokeWithHelper(
|
||||
OclocArgHelper *argHelper,
|
||||
unsigned int numArgs, const char *argv[]);
|
||||
|
||||
class MockOclocArgHelper : public OclocArgHelper {
|
||||
public:
|
||||
using OclocArgHelper::hasOutput;
|
||||
@@ -41,6 +46,10 @@ class MockOclocArgHelper : public OclocArgHelper {
|
||||
MockOclocArgHelper(FilesMap &filesMap) : OclocArgHelper(0, nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr),
|
||||
filesMap(filesMap){};
|
||||
|
||||
void setFormerProductConfigHelper(std::unique_ptr<FormerProductConfigHelper> helper) {
|
||||
formerProductConfigHelper = std::move(helper);
|
||||
}
|
||||
|
||||
void setAllCallBase(bool value) {
|
||||
callBaseFileExists = value;
|
||||
callBaseReadBinaryFile = value;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "environment.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "hw_cmds_default.h"
|
||||
#include "mock/mock_argument_helper.h"
|
||||
#include "neo_aot_platforms.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -41,13 +42,97 @@ extern Environment *gEnvironment;
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
Ocloc::SupportedDevicesHelper::SupportedDevicesData createMockFormerData() {
|
||||
Ocloc::SupportedDevicesHelper::SupportedDevicesData mockFormerData{
|
||||
// deviceIpVersions
|
||||
{
|
||||
0x2000000, 0x2400009, 0x2404009, 0x2408009, 0x240c000, 0x2410000, 0x2414000, 0x2418000, 0x241c000,
|
||||
0x2c00000, 0x2c04000, 0x2c08000},
|
||||
// deviceInfos
|
||||
{
|
||||
{0x1001, 0x01, 0x2000000},
|
||||
{0x1002, 0x02, 0x2400009},
|
||||
{0x1003, 0x03, 0x2404009},
|
||||
{0x1004, 0x04, 0x2408009}},
|
||||
// acronyms
|
||||
{
|
||||
{"bdw", 0x2000000},
|
||||
{"skl", 0x2400009},
|
||||
{"kbl", 0x2404009},
|
||||
{"cfl", 0x2408009},
|
||||
{"apl", 0x240c000},
|
||||
{"bxt", 0x240c000},
|
||||
{"glk", 0x2410000},
|
||||
{"whl", 0x2414000},
|
||||
{"aml", 0x2418000},
|
||||
{"cml", 0x241c000},
|
||||
{"icl", 0x2c00000},
|
||||
{"lkf", 0x2c04000},
|
||||
{"ehl", 0x2c08000},
|
||||
},
|
||||
// familyGroups
|
||||
{
|
||||
{"family8", {0x2000000}},
|
||||
{"family9", {0x2400009, 0x2404009, 0x2408009, 0x240c000, 0x2410000, 0x2414000, 0x2418000, 0x241c000}},
|
||||
{"family11", {0x2c00000, 0x2c04000, 0x2c08000}}},
|
||||
// releaseGroups
|
||||
{
|
||||
{"release8", {0x2000000}},
|
||||
{"release9", {0x2400009, 0x2404009, 0x2408009, 0x240c000, 0x2410000, 0x2414000, 0x2418000, 0x241c000}},
|
||||
{"release11", {0x2c00000, 0x2c04000, 0x2c08000}}}};
|
||||
|
||||
return mockFormerData;
|
||||
}
|
||||
|
||||
void mockedAbortOclocExecution(int errorCode) {
|
||||
throw std::runtime_error{"mockedAbortOclocExecution() called with error code = " + std::to_string(errorCode)};
|
||||
}
|
||||
|
||||
namespace OclocTestMocks {
|
||||
int mockOclocInvokeResult = ocloc_error_t::OCLOC_SUCCESS;
|
||||
}
|
||||
|
||||
int mockOclocInvoke(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);
|
||||
|
||||
int mockOclocInvoke(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) {
|
||||
|
||||
if (numOutputs && dataOutputs && lenOutputs && nameOutputs) {
|
||||
numOutputs[0] = 2;
|
||||
dataOutputs[0] = new uint8_t *[2];
|
||||
dataOutputs[0][0] = new uint8_t[1];
|
||||
dataOutputs[0][0][0] = 0xa;
|
||||
dataOutputs[0][1] = new uint8_t[2];
|
||||
dataOutputs[0][1][0] = 0x1;
|
||||
dataOutputs[0][1][1] = 0x4;
|
||||
lenOutputs[0] = new uint64_t[2];
|
||||
lenOutputs[0][0] = 1;
|
||||
lenOutputs[0][1] = 2;
|
||||
nameOutputs[0] = new char *[2];
|
||||
constexpr char outputName0[] = "out0";
|
||||
constexpr char outputName1[] = "out1";
|
||||
nameOutputs[0][0] = new char[sizeof(outputName0)];
|
||||
nameOutputs[0][1] = new char[sizeof(outputName1)];
|
||||
memcpy_s(nameOutputs[0][0], sizeof(outputName0), outputName0, sizeof(outputName0));
|
||||
memcpy_s(nameOutputs[0][1], sizeof(outputName1), outputName1, sizeof(outputName1));
|
||||
}
|
||||
|
||||
return OclocTestMocks::mockOclocInvokeResult;
|
||||
}
|
||||
|
||||
TEST(OclocApiTests, WhenOclocVersionIsCalledThenCurrentOclocVersionIsReturned) {
|
||||
EXPECT_EQ(ocloc_version_t::OCLOC_VERSION_CURRENT, oclocVersion());
|
||||
}
|
||||
|
||||
namespace Ocloc {
|
||||
extern std::string oclocFormerLibName;
|
||||
}
|
||||
|
||||
class OclocApiTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
@@ -64,9 +149,59 @@ class OclocApiTest : public ::testing::Test {
|
||||
writeDataToFile(clCopybufferFilename.c_str(), kernelSources);
|
||||
}
|
||||
|
||||
// Helper struct to reduce repetition of IoFunctions mocking
|
||||
struct IoFunctionsMockHelper {
|
||||
static inline std::vector<std::string> currentExpectedFiles{"copybuffer.cl"};
|
||||
static inline std::string currentKernelSource{"example_kernel(){}"};
|
||||
|
||||
VariableBackup<decltype(NEO::IoFunctions::fopenPtr)> mockFopen;
|
||||
VariableBackup<decltype(NEO::IoFunctions::fclosePtr)> mockFclose;
|
||||
VariableBackup<decltype(NEO::IoFunctions::fseekPtr)> mockFseek;
|
||||
VariableBackup<decltype(NEO::IoFunctions::ftellPtr)> mockFtell;
|
||||
VariableBackup<decltype(NEO::IoFunctions::freadPtr)> mockFread;
|
||||
|
||||
static FILE *mockFopenImpl(const char *filename, const char *mode) {
|
||||
std::filesystem::path filePath = filename;
|
||||
std::string fileNameWithExtension = filePath.filename().string();
|
||||
auto itr = std::find(currentExpectedFiles.begin(), currentExpectedFiles.end(), fileNameWithExtension);
|
||||
if (itr != currentExpectedFiles.end()) {
|
||||
return reinterpret_cast<FILE *>(0x40);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int mockFcloseImpl(FILE *stream) { return 0; }
|
||||
|
||||
static int mockFseekImpl(FILE *stream, long int offset, int origin) { return 0; }
|
||||
|
||||
static long int mockFtellImpl(FILE *stream) {
|
||||
std::stringstream fileStream(currentKernelSource);
|
||||
fileStream.seekg(0, std::ios::end);
|
||||
return static_cast<long int>(fileStream.tellg());
|
||||
}
|
||||
|
||||
static size_t mockFreadImpl(void *ptr, size_t size, size_t count, FILE *stream) {
|
||||
std::stringstream fileStream(currentKernelSource);
|
||||
size_t totalBytes = size * count;
|
||||
fileStream.read(static_cast<char *>(ptr), totalBytes);
|
||||
return static_cast<size_t>(fileStream.gcount() / size);
|
||||
}
|
||||
|
||||
IoFunctionsMockHelper(const std::vector<std::string> &expectedFiles = {"copybuffer.cl"},
|
||||
const std::string &kernelSource = "example_kernel(){}") : mockFopen(&NEO::IoFunctions::fopenPtr, mockFopenImpl),
|
||||
mockFclose(&NEO::IoFunctions::fclosePtr, mockFcloseImpl),
|
||||
mockFseek(&NEO::IoFunctions::fseekPtr, mockFseekImpl),
|
||||
mockFtell(&NEO::IoFunctions::ftellPtr, mockFtellImpl),
|
||||
mockFread(&NEO::IoFunctions::freadPtr, mockFreadImpl) {
|
||||
currentExpectedFiles = expectedFiles;
|
||||
currentKernelSource = kernelSource;
|
||||
}
|
||||
};
|
||||
|
||||
const std::string clCopybufferFilename = "some_kernel.cl";
|
||||
const std::string_view kernelSources = "example_kernel(){}";
|
||||
};
|
||||
|
||||
TEST_F(OclocApiTest, WhenGoodArgsAreGivenThenSuccessIsReturned) {
|
||||
VariableBackup<decltype(NEO::IoFunctions::fopenPtr)> mockFopen(&NEO::IoFunctions::fopenPtr, [](const char *filename, const char *mode) -> FILE * {
|
||||
std::filesystem::path filePath = filename;
|
||||
@@ -400,6 +535,7 @@ TEST_F(OclocApiTest, WhenGoodFamilyNameIsProvidedThenSuccessIsReturned) {
|
||||
0, nullptr, nullptr, nullptr,
|
||||
0, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr);
|
||||
|
||||
std::string output = capture.getCapturedStdout();
|
||||
|
||||
EXPECT_EQ(retVal, OCLOC_SUCCESS);
|
||||
@@ -558,11 +694,11 @@ TEST_F(OclocApiTest, GivenIncludeHeadersWhenCompilingThenPassesToFclHeadersPacke
|
||||
unsigned int argc = sizeof(argv) / sizeof(const char *);
|
||||
|
||||
const char *headerA = R"===(
|
||||
void foo() {}
|
||||
void foo() {}
|
||||
)===";
|
||||
|
||||
const char *headerB = R"===(
|
||||
void bar() {}
|
||||
void bar() {}
|
||||
)===";
|
||||
|
||||
const char *main = R"===(
|
||||
@@ -1196,6 +1332,386 @@ TEST_F(OclocApiTest, GivenVerboseModeWhenCompilingThenPrintCommandLine) {
|
||||
EXPECT_NE(std::string::npos, output.find("Build succeeded.\n"));
|
||||
}
|
||||
|
||||
TEST_F(OclocApiTest, GivenFormerDeviceNamesWhenCompilingThenFormerOclocIsUsedAndSuccessIsReturned) {
|
||||
IoFunctionsMockHelper mockIoFunctions;
|
||||
|
||||
std::string clFileName(clFiles + "copybuffer.cl");
|
||||
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{{clFileName, "example_kernel(){}"}};
|
||||
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
|
||||
auto formerHelper = std::make_unique<FormerProductConfigHelper>();
|
||||
|
||||
formerHelper->getData() = createMockFormerData();
|
||||
mockArgHelper.setFormerProductConfigHelper(std::move(formerHelper));
|
||||
|
||||
VariableBackup<std::string> oclocFormerNameBackup{&Ocloc::oclocFormerLibName};
|
||||
Ocloc::oclocFormerLibName = "oclocFormer";
|
||||
|
||||
static auto storedOriginalLoadFunc = NEO::OsLibrary::loadFunc;
|
||||
|
||||
auto selectiveLoadFunc = [](const NEO::OsLibraryCreateProperties &properties) -> NEO::OsLibrary * {
|
||||
if (properties.libraryName == "oclocFormer") {
|
||||
if (MockOsLibrary::loadLibraryNewObject) {
|
||||
auto ptr = MockOsLibrary::loadLibraryNewObject;
|
||||
MockOsLibrary::loadLibraryNewObject = nullptr;
|
||||
return ptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return storedOriginalLoadFunc(properties);
|
||||
};
|
||||
VariableBackup<decltype(NEO::OsLibrary::loadFunc)> funcBackup{&NEO::OsLibrary::loadFunc, +selectiveLoadFunc};
|
||||
|
||||
MockOsLibrary::loadLibraryNewObject = new MockOsLibraryCustom(nullptr, true);
|
||||
auto osLibrary = static_cast<MockOsLibraryCustom *>(MockOsLibrary::loadLibraryNewObject);
|
||||
osLibrary->procMap["oclocInvoke"] = reinterpret_cast<void *>(mockOclocInvoke);
|
||||
VariableBackup<int> retCodeBackup{&OclocTestMocks::mockOclocInvokeResult, ocloc_error_t::OCLOC_SUCCESS};
|
||||
|
||||
std::vector<std::string> deviceCombinations = {
|
||||
"8.0.0",
|
||||
"0x1001",
|
||||
"33554432",
|
||||
"bdw",
|
||||
"bdw,skl,icl",
|
||||
"bdw:icl",
|
||||
":icl"};
|
||||
|
||||
for (const auto &deviceArg : deviceCombinations) {
|
||||
const char *argv[] = {
|
||||
"ocloc",
|
||||
"-file",
|
||||
clFileName.c_str(),
|
||||
"-device",
|
||||
deviceArg.c_str()};
|
||||
unsigned int argc = sizeof(argv) / sizeof(const char *);
|
||||
|
||||
StreamCapture capture;
|
||||
capture.captureStdout();
|
||||
auto retVal = oclocInvokeWithHelper(&mockArgHelper, argc, argv);
|
||||
std::string output = capture.getCapturedStdout();
|
||||
|
||||
EXPECT_EQ(retVal, OCLOC_SUCCESS) << "Failed for device: " << deviceArg;
|
||||
EXPECT_EQ(std::string::npos, output.find("Command was: ocloc -file test_files/copybuffer.cl -device " + deviceArg)) << "Unexpected command output for device: " << deviceArg;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(OclocApiTest, GivenMixedFormerAndCurrentDeviceNamesWhenCompilingThenCorrectOclocIsUsedAndSuccessIsReturned) {
|
||||
IoFunctionsMockHelper mockIoFunctions;
|
||||
|
||||
std::string clFileName(clFiles + "copybuffer.cl");
|
||||
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{{clFileName, "example_kernel(){}"}};
|
||||
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
|
||||
auto formerHelper = std::make_unique<FormerProductConfigHelper>();
|
||||
|
||||
formerHelper->getData() = createMockFormerData();
|
||||
mockArgHelper.setFormerProductConfigHelper(std::move(formerHelper));
|
||||
|
||||
auto target = gEnvironment->devicePrefix;
|
||||
auto product = mockArgHelper.productConfigHelper->getProductConfigFromAcronym(target);
|
||||
if (product == AOT::UNKNOWN_ISA) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
VariableBackup<std::string> oclocFormerNameBackup{&Ocloc::oclocFormerLibName};
|
||||
Ocloc::oclocFormerLibName = "oclocFormer";
|
||||
|
||||
static auto storedOriginalLoadFunc = NEO::OsLibrary::loadFunc;
|
||||
|
||||
auto selectiveLoadFunc = [](const NEO::OsLibraryCreateProperties &properties) -> NEO::OsLibrary * {
|
||||
if (properties.libraryName == "oclocFormer") {
|
||||
if (MockOsLibrary::loadLibraryNewObject) {
|
||||
auto ptr = MockOsLibrary::loadLibraryNewObject;
|
||||
MockOsLibrary::loadLibraryNewObject = nullptr;
|
||||
return ptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return storedOriginalLoadFunc(properties);
|
||||
};
|
||||
VariableBackup<decltype(NEO::OsLibrary::loadFunc)> funcBackup{&NEO::OsLibrary::loadFunc, +selectiveLoadFunc};
|
||||
|
||||
MockOsLibrary::loadLibraryNewObject = new MockOsLibraryCustom(nullptr, true);
|
||||
auto osLibrary = static_cast<MockOsLibraryCustom *>(MockOsLibrary::loadLibraryNewObject);
|
||||
osLibrary->procMap["oclocInvoke"] = reinterpret_cast<void *>(mockOclocInvoke);
|
||||
VariableBackup<int> retCodeBackup{&OclocTestMocks::mockOclocInvokeResult, ocloc_error_t::OCLOC_SUCCESS};
|
||||
|
||||
std::vector<std::string> deviceCombinations = {
|
||||
"bdw,skl," + std::string(target.c_str()),
|
||||
"bdw:" + std::string(target.c_str()),
|
||||
":" + std::string(target.c_str())};
|
||||
|
||||
for (const auto &deviceArg : deviceCombinations) {
|
||||
const char *argv[] = {
|
||||
"ocloc",
|
||||
"-file",
|
||||
clFileName.c_str(),
|
||||
"-device",
|
||||
deviceArg.c_str()};
|
||||
unsigned int argc = sizeof(argv) / sizeof(const char *);
|
||||
|
||||
StreamCapture capture;
|
||||
capture.captureStdout();
|
||||
auto retVal = oclocInvokeWithHelper(&mockArgHelper, argc, argv);
|
||||
std::string output = capture.getCapturedStdout();
|
||||
|
||||
EXPECT_EQ(retVal, OCLOC_SUCCESS) << "Failed for device: " << deviceArg;
|
||||
EXPECT_EQ(std::string::npos, output.find("Command was: ocloc -file test_files/copybuffer.cl -device " + deviceArg)) << "Unexpected command output for device: " << deviceArg;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(OclocApiTest, GivenFormerFamilyNamesWhenCompilingThenFormerOclocIsUsedAndSuccessIsReturned) {
|
||||
IoFunctionsMockHelper mockIoFunctions;
|
||||
|
||||
std::string clFileName(clFiles + "copybuffer.cl");
|
||||
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{{clFileName, "example_kernel(){}"}};
|
||||
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
|
||||
auto formerHelper = std::make_unique<FormerProductConfigHelper>();
|
||||
|
||||
formerHelper->getData() = createMockFormerData();
|
||||
mockArgHelper.setFormerProductConfigHelper(std::move(formerHelper));
|
||||
|
||||
VariableBackup<std::string> oclocFormerNameBackup{&Ocloc::oclocFormerLibName};
|
||||
Ocloc::oclocFormerLibName = "oclocFormer";
|
||||
|
||||
static auto storedOriginalLoadFunc = NEO::OsLibrary::loadFunc;
|
||||
|
||||
auto selectiveLoadFunc = [](const NEO::OsLibraryCreateProperties &properties) -> NEO::OsLibrary * {
|
||||
if (properties.libraryName == "oclocFormer") {
|
||||
if (MockOsLibrary::loadLibraryNewObject) {
|
||||
auto ptr = MockOsLibrary::loadLibraryNewObject;
|
||||
MockOsLibrary::loadLibraryNewObject = nullptr;
|
||||
return ptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return storedOriginalLoadFunc(properties);
|
||||
};
|
||||
VariableBackup<decltype(NEO::OsLibrary::loadFunc)> funcBackup{&NEO::OsLibrary::loadFunc, +selectiveLoadFunc};
|
||||
|
||||
MockOsLibrary::loadLibraryNewObject = new MockOsLibraryCustom(nullptr, true);
|
||||
auto osLibrary = static_cast<MockOsLibraryCustom *>(MockOsLibrary::loadLibraryNewObject);
|
||||
osLibrary->procMap["oclocInvoke"] = reinterpret_cast<void *>(mockOclocInvoke);
|
||||
VariableBackup<int> retCodeBackup{&OclocTestMocks::mockOclocInvokeResult, ocloc_error_t::OCLOC_SUCCESS};
|
||||
|
||||
std::vector<std::string> familyCombinations = {
|
||||
"family8",
|
||||
"family8,family9,family11",
|
||||
"family8:family11",
|
||||
":family11"};
|
||||
|
||||
for (const auto &familyArg : familyCombinations) {
|
||||
const char *argv[] = {
|
||||
"ocloc",
|
||||
"-file",
|
||||
clFileName.c_str(),
|
||||
"-device",
|
||||
familyArg.c_str()};
|
||||
unsigned int argc = sizeof(argv) / sizeof(const char *);
|
||||
|
||||
StreamCapture capture;
|
||||
capture.captureStdout();
|
||||
auto retVal = oclocInvokeWithHelper(&mockArgHelper, argc, argv);
|
||||
std::string output = capture.getCapturedStdout();
|
||||
|
||||
EXPECT_EQ(retVal, OCLOC_SUCCESS) << "Failed for device: " << familyArg;
|
||||
EXPECT_EQ(std::string::npos, output.find("Command was: ocloc -file test_files/copybuffer.cl -device " + familyArg)) << "Unexpected command output for device: " << familyArg;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(OclocApiTest, GivenMixedFormerAndCurrentFamilyNamesWhenCompilingThenCorrectOclocIsUsedAndSuccessIsReturned) {
|
||||
IoFunctionsMockHelper mockIoFunctions;
|
||||
|
||||
std::string clFileName(clFiles + "copybuffer.cl");
|
||||
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{{clFileName, "example_kernel(){}"}};
|
||||
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
|
||||
auto formerHelper = std::make_unique<FormerProductConfigHelper>();
|
||||
|
||||
formerHelper->getData() = createMockFormerData();
|
||||
mockArgHelper.setFormerProductConfigHelper(std::move(formerHelper));
|
||||
|
||||
auto target = gEnvironment->devicePrefix;
|
||||
auto product = mockArgHelper.productConfigHelper->getProductConfigFromAcronym(target);
|
||||
if (product == AOT::UNKNOWN_ISA) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
auto &deviceAotInfo = mockArgHelper.productConfigHelper->getDeviceAotInfo();
|
||||
auto it = std::find_if(deviceAotInfo.begin(), deviceAotInfo.end(), ProductConfigHelper::findProductConfig(product));
|
||||
auto familyAcronym = mockArgHelper.productConfigHelper->getAcronymFromAFamily(it->family);
|
||||
|
||||
VariableBackup<std::string> oclocFormerNameBackup{&Ocloc::oclocFormerLibName};
|
||||
Ocloc::oclocFormerLibName = "oclocFormer";
|
||||
|
||||
static auto storedOriginalLoadFunc = NEO::OsLibrary::loadFunc;
|
||||
|
||||
auto selectiveLoadFunc = [](const NEO::OsLibraryCreateProperties &properties) -> NEO::OsLibrary * {
|
||||
if (properties.libraryName == "oclocFormer") {
|
||||
if (MockOsLibrary::loadLibraryNewObject) {
|
||||
auto ptr = MockOsLibrary::loadLibraryNewObject;
|
||||
MockOsLibrary::loadLibraryNewObject = nullptr;
|
||||
return ptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return storedOriginalLoadFunc(properties);
|
||||
};
|
||||
VariableBackup<decltype(NEO::OsLibrary::loadFunc)> funcBackup{&NEO::OsLibrary::loadFunc, +selectiveLoadFunc};
|
||||
|
||||
MockOsLibrary::loadLibraryNewObject = new MockOsLibraryCustom(nullptr, true);
|
||||
auto osLibrary = static_cast<MockOsLibraryCustom *>(MockOsLibrary::loadLibraryNewObject);
|
||||
osLibrary->procMap["oclocInvoke"] = reinterpret_cast<void *>(mockOclocInvoke);
|
||||
VariableBackup<int> retCodeBackup{&OclocTestMocks::mockOclocInvokeResult, ocloc_error_t::OCLOC_SUCCESS};
|
||||
|
||||
std::vector<std::string> familyCombinations = {
|
||||
"family8,family11," + std::string(familyAcronym.str().c_str()),
|
||||
"family8:" + std::string(familyAcronym.str().c_str()),
|
||||
":" + std::string(familyAcronym.str().c_str())};
|
||||
|
||||
for (const auto &familyArg : familyCombinations) {
|
||||
const char *argv[] = {
|
||||
"ocloc",
|
||||
"-file",
|
||||
clFileName.c_str(),
|
||||
"-device",
|
||||
familyArg.c_str()};
|
||||
unsigned int argc = sizeof(argv) / sizeof(const char *);
|
||||
|
||||
StreamCapture capture;
|
||||
capture.captureStdout();
|
||||
auto retVal = oclocInvokeWithHelper(&mockArgHelper, argc, argv);
|
||||
std::string output = capture.getCapturedStdout();
|
||||
|
||||
EXPECT_EQ(retVal, OCLOC_SUCCESS) << "Failed for device: " << familyArg;
|
||||
EXPECT_EQ(std::string::npos, output.find("Command was: ocloc -file test_files/copybuffer.cl -device " + familyArg)) << "Unexpected command output for device: " << familyArg;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(OclocApiTest, GivenFormerReleaseNamesWhenCompilingThenFormerOclocIsUsedAndSuccessIsReturned) {
|
||||
IoFunctionsMockHelper mockIoFunctions;
|
||||
|
||||
std::string clFileName(clFiles + "copybuffer.cl");
|
||||
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{{clFileName, "example_kernel(){}"}};
|
||||
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
|
||||
auto formerHelper = std::make_unique<FormerProductConfigHelper>();
|
||||
|
||||
formerHelper->getData() = createMockFormerData();
|
||||
mockArgHelper.setFormerProductConfigHelper(std::move(formerHelper));
|
||||
|
||||
VariableBackup<std::string> oclocFormerNameBackup{&Ocloc::oclocFormerLibName};
|
||||
Ocloc::oclocFormerLibName = "oclocFormer";
|
||||
|
||||
static auto storedOriginalLoadFunc = NEO::OsLibrary::loadFunc;
|
||||
|
||||
auto selectiveLoadFunc = [](const NEO::OsLibraryCreateProperties &properties) -> NEO::OsLibrary * {
|
||||
if (properties.libraryName == "oclocFormer") {
|
||||
if (MockOsLibrary::loadLibraryNewObject) {
|
||||
auto ptr = MockOsLibrary::loadLibraryNewObject;
|
||||
MockOsLibrary::loadLibraryNewObject = nullptr;
|
||||
return ptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return storedOriginalLoadFunc(properties);
|
||||
};
|
||||
VariableBackup<decltype(NEO::OsLibrary::loadFunc)> funcBackup{&NEO::OsLibrary::loadFunc, +selectiveLoadFunc};
|
||||
|
||||
MockOsLibrary::loadLibraryNewObject = new MockOsLibraryCustom(nullptr, true);
|
||||
auto osLibrary = static_cast<MockOsLibraryCustom *>(MockOsLibrary::loadLibraryNewObject);
|
||||
osLibrary->procMap["oclocInvoke"] = reinterpret_cast<void *>(mockOclocInvoke);
|
||||
VariableBackup<int> retCodeBackup{&OclocTestMocks::mockOclocInvokeResult, ocloc_error_t::OCLOC_SUCCESS};
|
||||
|
||||
std::vector<std::string> releaseCombinations = {
|
||||
"release8",
|
||||
"release8,release9,release11",
|
||||
"release8:release11",
|
||||
":release11"};
|
||||
|
||||
for (const auto &releaseArg : releaseCombinations) {
|
||||
const char *argv[] = {
|
||||
"ocloc",
|
||||
"-file",
|
||||
clFileName.c_str(),
|
||||
"-device",
|
||||
releaseArg.c_str()};
|
||||
unsigned int argc = sizeof(argv) / sizeof(const char *);
|
||||
|
||||
StreamCapture capture;
|
||||
capture.captureStdout();
|
||||
auto retVal = oclocInvokeWithHelper(&mockArgHelper, argc, argv);
|
||||
std::string output = capture.getCapturedStdout();
|
||||
|
||||
EXPECT_EQ(retVal, OCLOC_SUCCESS) << "Failed for device: " << releaseArg;
|
||||
EXPECT_EQ(std::string::npos, output.find("Command was: ocloc -file test_files/copybuffer.cl -device " + releaseArg)) << "Unexpected command output for device: " << releaseArg;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(OclocApiTest, GivenMixedFormerAndCurrentReleaseNamesWhenCompilingThenCorrectOclocIsUsedAndSuccessIsReturned) {
|
||||
IoFunctionsMockHelper mockIoFunctions;
|
||||
|
||||
std::string clFileName(clFiles + "copybuffer.cl");
|
||||
MockOclocArgHelper::FilesMap mockArgHelperFilesMap{{clFileName, "example_kernel(){}"}};
|
||||
MockOclocArgHelper mockArgHelper{mockArgHelperFilesMap};
|
||||
auto formerHelper = std::make_unique<FormerProductConfigHelper>();
|
||||
|
||||
formerHelper->getData() = createMockFormerData();
|
||||
mockArgHelper.setFormerProductConfigHelper(std::move(formerHelper));
|
||||
|
||||
auto target = gEnvironment->devicePrefix;
|
||||
auto product = mockArgHelper.productConfigHelper->getProductConfigFromAcronym(target);
|
||||
if (product == AOT::UNKNOWN_ISA) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
auto &deviceAotInfo = mockArgHelper.productConfigHelper->getDeviceAotInfo();
|
||||
auto it = std::find_if(deviceAotInfo.begin(), deviceAotInfo.end(), ProductConfigHelper::findProductConfig(product));
|
||||
auto releaseAcronym = mockArgHelper.productConfigHelper->getAcronymFromARelease(it->release);
|
||||
|
||||
VariableBackup<std::string> oclocFormerNameBackup{&Ocloc::oclocFormerLibName};
|
||||
Ocloc::oclocFormerLibName = "oclocFormer";
|
||||
|
||||
static auto storedOriginalLoadFunc = NEO::OsLibrary::loadFunc;
|
||||
|
||||
auto selectiveLoadFunc = [](const NEO::OsLibraryCreateProperties &properties) -> NEO::OsLibrary * {
|
||||
if (properties.libraryName == "oclocFormer") {
|
||||
if (MockOsLibrary::loadLibraryNewObject) {
|
||||
auto ptr = MockOsLibrary::loadLibraryNewObject;
|
||||
MockOsLibrary::loadLibraryNewObject = nullptr;
|
||||
return ptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
return storedOriginalLoadFunc(properties);
|
||||
};
|
||||
VariableBackup<decltype(NEO::OsLibrary::loadFunc)> funcBackup{&NEO::OsLibrary::loadFunc, +selectiveLoadFunc};
|
||||
|
||||
MockOsLibrary::loadLibraryNewObject = new MockOsLibraryCustom(nullptr, true);
|
||||
auto osLibrary = static_cast<MockOsLibraryCustom *>(MockOsLibrary::loadLibraryNewObject);
|
||||
osLibrary->procMap["oclocInvoke"] = reinterpret_cast<void *>(mockOclocInvoke);
|
||||
VariableBackup<int> retCodeBackup{&OclocTestMocks::mockOclocInvokeResult, ocloc_error_t::OCLOC_SUCCESS};
|
||||
|
||||
std::vector<std::string> releaseCombinations = {
|
||||
"release8,release11," + std::string(releaseAcronym.str().c_str()),
|
||||
"release8:" + std::string(releaseAcronym.str().c_str()),
|
||||
":" + std::string(releaseAcronym.str().c_str())};
|
||||
|
||||
for (const auto &releaseArg : releaseCombinations) {
|
||||
const char *argv[] = {
|
||||
"ocloc",
|
||||
"-file",
|
||||
clFileName.c_str(),
|
||||
"-device",
|
||||
releaseArg.c_str()};
|
||||
unsigned int argc = sizeof(argv) / sizeof(const char *);
|
||||
|
||||
StreamCapture capture;
|
||||
capture.captureStdout();
|
||||
auto retVal = oclocInvokeWithHelper(&mockArgHelper, argc, argv);
|
||||
std::string output = capture.getCapturedStdout();
|
||||
|
||||
EXPECT_EQ(retVal, OCLOC_SUCCESS) << "Failed for device: " << releaseArg;
|
||||
EXPECT_EQ(std::string::npos, output.find("Command was: ocloc -file test_files/copybuffer.cl -device " + releaseArg)) << "Unexpected command output for device: " << releaseArg;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(InvokeFormerOclocTest, givenEmptyOrInvalidFormerOclocNameWhenInvokeFormerOclocThenNulloptIsReturned) {
|
||||
const char *argv[] = {
|
||||
"ocloc",
|
||||
@@ -1220,10 +1736,6 @@ TEST(InvokeFormerOclocTest, givenEmptyOrInvalidFormerOclocNameWhenInvokeFormerOc
|
||||
EXPECT_FALSE(retVal.has_value());
|
||||
}
|
||||
|
||||
namespace Ocloc {
|
||||
extern std::string oclocFormerLibName;
|
||||
}
|
||||
|
||||
struct OclocFallbackTests : ::testing::Test {
|
||||
|
||||
int callOclocForInvalidDevice() {
|
||||
@@ -1289,143 +1801,3 @@ TEST_F(OclocFallbackTests, GivenNoFormerOclocNameWhenInvalidDeviceErrorIsReturne
|
||||
EXPECT_EQ(std::string::npos, capturedStdout.find("Couldn't load former ocloc"));
|
||||
EXPECT_TRUE(capturedStderr.empty());
|
||||
}
|
||||
|
||||
TEST_F(OclocFallbackTests, GivenInvalidFormerOclocNameWhenInvalidDeviceErrorIsReturnedThenFallbackButWithoutLoadingLib) {
|
||||
VariableBackup<decltype(NEO::IoFunctions::fopenPtr)> mockFopen(&NEO::IoFunctions::fopenPtr, [](const char *filename, const char *mode) -> FILE * { return NULL; });
|
||||
|
||||
Ocloc::oclocFormerLibName = "invalidName";
|
||||
|
||||
auto retVal = callOclocForInvalidDevice();
|
||||
|
||||
EXPECT_EQ(ocloc_error_t::OCLOC_INVALID_DEVICE, retVal);
|
||||
EXPECT_NE(std::string::npos, capturedStdout.find("Could not determine device target: invalid_device.\n"));
|
||||
EXPECT_NE(std::string::npos, capturedStdout.find("Error: Cannot get HW Info for device invalid_device.\n"));
|
||||
EXPECT_NE(std::string::npos, capturedStdout.find("Command was: ocloc -file kernel.cl -device invalid_device\n"));
|
||||
|
||||
EXPECT_NE(std::string::npos, capturedStdout.find("Couldn't load former ocloc invalidName"));
|
||||
EXPECT_NE(std::string::npos, capturedStdout.find("Invalid device error, trying to fallback to former ocloc invalidName"));
|
||||
EXPECT_TRUE(capturedStderr.empty());
|
||||
}
|
||||
|
||||
int mockOclocInvokeResult = ocloc_error_t::OCLOC_SUCCESS;
|
||||
|
||||
int mockOclocInvoke(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) {
|
||||
|
||||
if (numOutputs && dataOutputs && lenOutputs && nameOutputs) {
|
||||
numOutputs[0] = 2;
|
||||
dataOutputs[0] = new uint8_t *[2];
|
||||
dataOutputs[0][0] = new uint8_t[1];
|
||||
dataOutputs[0][0][0] = 0xa;
|
||||
dataOutputs[0][1] = new uint8_t[2];
|
||||
dataOutputs[0][1][0] = 0x1;
|
||||
dataOutputs[0][1][1] = 0x4;
|
||||
lenOutputs[0] = new uint64_t[2];
|
||||
lenOutputs[0][0] = 1;
|
||||
lenOutputs[0][1] = 2;
|
||||
nameOutputs[0] = new char *[2];
|
||||
constexpr char outputName0[] = "out0";
|
||||
constexpr char outputName1[] = "out1";
|
||||
nameOutputs[0][0] = new char[sizeof(outputName0)];
|
||||
nameOutputs[0][1] = new char[sizeof(outputName1)];
|
||||
memcpy_s(nameOutputs[0][0], sizeof(outputName0), outputName0, sizeof(outputName0));
|
||||
memcpy_s(nameOutputs[0][1], sizeof(outputName1), outputName1, sizeof(outputName1));
|
||||
}
|
||||
|
||||
return mockOclocInvokeResult;
|
||||
}
|
||||
|
||||
TEST_F(OclocFallbackTests, GivenValidFormerOclocNameWhenFormerOclocReturnsSuccessThenSuccessIsPropagatedAndCommandLineIsNotPrinted) {
|
||||
VariableBackup<decltype(NEO::IoFunctions::fopenPtr)> mockFopen(&NEO::IoFunctions::fopenPtr, [](const char *filename, const char *mode) -> FILE * { return NULL; });
|
||||
|
||||
Ocloc::oclocFormerLibName = "oclocFormer";
|
||||
VariableBackup<decltype(NEO::OsLibrary::loadFunc)> funcBackup{&NEO::OsLibrary::loadFunc, MockOsLibraryCustom::load};
|
||||
MockOsLibrary::loadLibraryNewObject = new MockOsLibraryCustom(nullptr, true);
|
||||
auto osLibrary = static_cast<MockOsLibraryCustom *>(MockOsLibrary::loadLibraryNewObject);
|
||||
|
||||
osLibrary->procMap["oclocInvoke"] = reinterpret_cast<void *>(mockOclocInvoke);
|
||||
|
||||
VariableBackup<int> retCodeBackup{&mockOclocInvokeResult, ocloc_error_t::OCLOC_SUCCESS};
|
||||
auto retVal = callOclocForInvalidDevice();
|
||||
|
||||
EXPECT_EQ(ocloc_error_t::OCLOC_SUCCESS, retVal);
|
||||
EXPECT_NE(std::string::npos, capturedStdout.find("Could not determine device target: invalid_device.\n"));
|
||||
EXPECT_NE(std::string::npos, capturedStdout.find("Error: Cannot get HW Info for device invalid_device.\n"));
|
||||
EXPECT_NE(std::string::npos, capturedStdout.find("Invalid device error, trying to fallback to former ocloc oclocFormer\n"));
|
||||
EXPECT_EQ(std::string::npos, capturedStdout.find("Command was: ocloc -file kernel.cl -device invalid_device\n"));
|
||||
EXPECT_TRUE(capturedStderr.empty());
|
||||
}
|
||||
|
||||
TEST_F(OclocFallbackTests, GivenValidFormerOclocNameWhenFormerOclocReturnsErrorThenErrorIsPropagated) {
|
||||
VariableBackup<decltype(NEO::IoFunctions::fopenPtr)> mockFopen(&NEO::IoFunctions::fopenPtr, [](const char *filename, const char *mode) -> FILE * { return NULL; });
|
||||
|
||||
Ocloc::oclocFormerLibName = "oclocFormer";
|
||||
VariableBackup<decltype(NEO::OsLibrary::loadFunc)> funcBackup{&NEO::OsLibrary::loadFunc, MockOsLibraryCustom::load};
|
||||
for (auto &error : {
|
||||
ocloc_error_t::OCLOC_OUT_OF_HOST_MEMORY,
|
||||
ocloc_error_t::OCLOC_BUILD_PROGRAM_FAILURE,
|
||||
ocloc_error_t::OCLOC_INVALID_DEVICE,
|
||||
ocloc_error_t::OCLOC_INVALID_PROGRAM,
|
||||
ocloc_error_t::OCLOC_INVALID_COMMAND_LINE,
|
||||
ocloc_error_t::OCLOC_INVALID_FILE,
|
||||
ocloc_error_t::OCLOC_COMPILATION_CRASH}) {
|
||||
|
||||
MockOsLibrary::loadLibraryNewObject = new MockOsLibraryCustom(nullptr, true);
|
||||
auto osLibrary = static_cast<MockOsLibraryCustom *>(MockOsLibrary::loadLibraryNewObject);
|
||||
|
||||
osLibrary->procMap["oclocInvoke"] = reinterpret_cast<void *>(mockOclocInvoke);
|
||||
|
||||
VariableBackup<int> retCodeBackup{&mockOclocInvokeResult, error};
|
||||
|
||||
auto retVal = callOclocForInvalidDevice();
|
||||
|
||||
EXPECT_EQ(error, retVal);
|
||||
EXPECT_NE(std::string::npos, capturedStdout.find("Could not determine device target: invalid_device.\n"));
|
||||
EXPECT_NE(std::string::npos, capturedStdout.find("Error: Cannot get HW Info for device invalid_device.\n"));
|
||||
EXPECT_NE(std::string::npos, capturedStdout.find("Invalid device error, trying to fallback to former ocloc oclocFormer\n"));
|
||||
EXPECT_NE(std::string::npos, capturedStdout.find("Command was: ocloc -file kernel.cl -device invalid_device\n"));
|
||||
EXPECT_TRUE(capturedStderr.empty());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(OclocFallbackTests, GivenValidFormerOclocNameWhenFormerOclocReturnsOutputsThenOutputIsPropagated) {
|
||||
VariableBackup<decltype(NEO::IoFunctions::fopenPtr)> mockFopen(&NEO::IoFunctions::fopenPtr, [](const char *filename, const char *mode) -> FILE * { return NULL; });
|
||||
|
||||
for (auto &expectedRetVal : {ocloc_error_t::OCLOC_SUCCESS,
|
||||
ocloc_error_t::OCLOC_OUT_OF_HOST_MEMORY,
|
||||
ocloc_error_t::OCLOC_BUILD_PROGRAM_FAILURE,
|
||||
ocloc_error_t::OCLOC_INVALID_DEVICE,
|
||||
ocloc_error_t::OCLOC_INVALID_PROGRAM,
|
||||
ocloc_error_t::OCLOC_INVALID_COMMAND_LINE,
|
||||
ocloc_error_t::OCLOC_INVALID_FILE,
|
||||
ocloc_error_t::OCLOC_COMPILATION_CRASH}) {
|
||||
|
||||
passOutputs = true;
|
||||
Ocloc::oclocFormerLibName = "oclocFormer";
|
||||
VariableBackup<decltype(NEO::OsLibrary::loadFunc)> funcBackup{&NEO::OsLibrary::loadFunc, MockOsLibraryCustom::load};
|
||||
MockOsLibrary::loadLibraryNewObject = new MockOsLibraryCustom(nullptr, true);
|
||||
auto osLibrary = static_cast<MockOsLibraryCustom *>(MockOsLibrary::loadLibraryNewObject);
|
||||
|
||||
osLibrary->procMap["oclocInvoke"] = reinterpret_cast<void *>(mockOclocInvoke);
|
||||
|
||||
VariableBackup<int> retCodeBackup{&mockOclocInvokeResult, expectedRetVal};
|
||||
auto retVal = callOclocForInvalidDevice();
|
||||
EXPECT_EQ(expectedRetVal, retVal);
|
||||
EXPECT_TRUE(capturedStdout.empty());
|
||||
EXPECT_TRUE(capturedStderr.empty());
|
||||
EXPECT_EQ(2u, numOutputs);
|
||||
EXPECT_STREQ("out0", nameOutputs[0]);
|
||||
EXPECT_STREQ("out1", nameOutputs[1]);
|
||||
EXPECT_EQ(1u, lenOutputs[0]);
|
||||
EXPECT_EQ(2u, lenOutputs[1]);
|
||||
|
||||
EXPECT_EQ(0xa, dataOutputs[0][0]);
|
||||
EXPECT_EQ(0x1, dataOutputs[1][0]);
|
||||
EXPECT_EQ(0x4, dataOutputs[1][1]);
|
||||
|
||||
oclocFreeOutput(&numOutputs, &dataOutputs, &lenOutputs, &nameOutputs);
|
||||
}
|
||||
passOutputs = false;
|
||||
}
|
||||
@@ -75,6 +75,8 @@ set(CLOC_LIB_SRCS_LIB
|
||||
${NEO_SHARED_DIRECTORY}/helpers/${BRANCH_DIR_SUFFIX}product_config_helper_extra.cpp
|
||||
${NEO_SHARED_DIRECTORY}/helpers/product_config_helper.cpp
|
||||
${NEO_SHARED_DIRECTORY}/helpers/product_config_helper.h
|
||||
${NEO_SHARED_DIRECTORY}/helpers/product_config_helper_former.cpp
|
||||
${NEO_SHARED_DIRECTORY}/helpers/product_config_helper_former.h
|
||||
${NEO_SHARED_DIRECTORY}/kernel/${BRANCH_DIR_SUFFIX}kernel_descriptor_ext.cpp
|
||||
${NEO_SHARED_DIRECTORY}/os_interface/os_library.cpp
|
||||
${NEO_SHARED_DIRECTORY}/os_interface/os_library.h
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Intel Corporation
|
||||
* Copyright (C) 2024-2025 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -85,7 +85,12 @@ std::string SupportedDevicesHelper::getDataFromFormerOcloc() const {
|
||||
break;
|
||||
}
|
||||
|
||||
oclocFreeOutput(&numOutputs, &dataOutputs, &ouputLengths, &outputNames);
|
||||
// Use formerOclocFree since memory was allocated by former ocloc
|
||||
auto freeResult = Commands::formerOclocFree(getOclocFormerLibName(), &numOutputs, &dataOutputs, &ouputLengths, &outputNames);
|
||||
if (!freeResult) {
|
||||
// Fallback to regular oclocFreeOutput if formerOclocFree fails
|
||||
oclocFreeOutput(&numOutputs, &dataOutputs, &ouputLengths, &outputNames);
|
||||
}
|
||||
return retData;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,17 +12,12 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
extern "C" {
|
||||
using namespace Ocloc;
|
||||
|
||||
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 argHelper = std::make_unique<OclocArgHelper>(
|
||||
numSources, dataSources, lenSources, nameSources,
|
||||
numInputHeaders, dataInputHeaders, lenInputHeaders, nameInputHeaders,
|
||||
numOutputs, dataOutputs, lenOutputs, nameOutputs);
|
||||
int oclocInvokeWithHelper(
|
||||
OclocArgHelper *argHelper,
|
||||
unsigned int numArgs, const char *argv[]) {
|
||||
|
||||
std::vector<std::string> args(argv, argv + numArgs);
|
||||
|
||||
try {
|
||||
@@ -33,34 +28,23 @@ int oclocInvoke(unsigned int numArgs, const char *argv[],
|
||||
auto &command = args[1];
|
||||
int retVal = -0;
|
||||
if (command == CommandNames::disassemble) {
|
||||
retVal = Commands::disassemble(argHelper.get(), args);
|
||||
retVal = Commands::disassemble(argHelper, args);
|
||||
} else if (command == CommandNames::assemble) {
|
||||
retVal = Commands::assemble(argHelper.get(), args);
|
||||
retVal = Commands::assemble(argHelper, args);
|
||||
} else if (command == CommandNames::multi) {
|
||||
retVal = Commands::multi(argHelper.get(), args);
|
||||
retVal = Commands::multi(argHelper, args);
|
||||
} else if (command == CommandNames::validate) {
|
||||
retVal = Commands::validate(argHelper.get(), args);
|
||||
retVal = Commands::validate(argHelper, args);
|
||||
} else if (command == CommandNames::query) {
|
||||
retVal = Commands::query(argHelper.get(), args);
|
||||
retVal = Commands::query(argHelper, args);
|
||||
} else if (command == CommandNames::ids) {
|
||||
retVal = Commands::ids(argHelper.get(), args);
|
||||
retVal = Commands::ids(argHelper, args);
|
||||
} else if (command == CommandNames::link) {
|
||||
retVal = Commands::link(argHelper.get(), args);
|
||||
retVal = Commands::link(argHelper, args);
|
||||
} else if (command == CommandNames::concat) {
|
||||
retVal = Commands::concat(argHelper.get(), args);
|
||||
retVal = Commands::concat(argHelper, args);
|
||||
} else {
|
||||
retVal = Commands::compile(argHelper.get(), args);
|
||||
}
|
||||
|
||||
if (retVal == ocloc_error_t::OCLOC_INVALID_DEVICE && !getOclocFormerLibName().empty()) {
|
||||
argHelper->printf("Invalid device error, trying to fallback to former ocloc %s\n", getOclocFormerLibName().c_str());
|
||||
auto retValFromFormerOcloc = Commands::invokeFormerOcloc(getOclocFormerLibName(), numArgs, argv, numSources, dataSources, lenSources, nameSources, numInputHeaders, dataInputHeaders, lenInputHeaders, nameInputHeaders, numOutputs, dataOutputs, lenOutputs, nameOutputs);
|
||||
if (retValFromFormerOcloc) {
|
||||
retVal = retValFromFormerOcloc.value();
|
||||
argHelper->dontSetupOutputs();
|
||||
} else {
|
||||
argHelper->printf("Couldn't load former ocloc %s\n", getOclocFormerLibName().c_str());
|
||||
}
|
||||
retVal = Commands::compile(argHelper, args);
|
||||
}
|
||||
|
||||
if (retVal != OCLOC_SUCCESS) {
|
||||
@@ -76,6 +60,18 @@ int oclocInvoke(unsigned int numArgs, const char *argv[],
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
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 argHelper = std::make_unique<OclocArgHelper>(
|
||||
numSources, dataSources, lenSources, nameSources,
|
||||
numInputHeaders, dataInputHeaders, lenInputHeaders, nameInputHeaders,
|
||||
numOutputs, dataOutputs, lenOutputs, nameOutputs);
|
||||
return oclocInvokeWithHelper(argHelper.get(), numArgs, argv);
|
||||
}
|
||||
|
||||
int oclocFreeOutput(uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs) {
|
||||
for (uint32_t i = 0; i < *numOutputs; i++) {
|
||||
delete[] (*dataOutputs)[i];
|
||||
|
||||
@@ -68,6 +68,7 @@ OclocArgHelper::OclocArgHelper(const uint32_t numSources, const uint8_t **dataSo
|
||||
}
|
||||
|
||||
productConfigHelper = std::make_unique<ProductConfigHelper>();
|
||||
formerProductConfigHelper = std::make_unique<FormerProductConfigHelper>();
|
||||
}
|
||||
|
||||
OclocArgHelper::OclocArgHelper() : OclocArgHelper(0, nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr) {}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
constexpr auto *oclocStdoutLogName = "stdout.log";
|
||||
|
||||
struct ProductConfigHelper;
|
||||
struct FormerProductConfigHelper;
|
||||
namespace NEO {
|
||||
class CompilerProductHelper;
|
||||
class ReleaseHelper;
|
||||
@@ -147,4 +148,5 @@ class OclocArgHelper {
|
||||
}
|
||||
|
||||
std::unique_ptr<ProductConfigHelper> productConfigHelper;
|
||||
std::unique_ptr<FormerProductConfigHelper> formerProductConfigHelper;
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "shared/offline_compiler/source/ocloc_api.h"
|
||||
#include "shared/offline_compiler/source/ocloc_arg_helper.h"
|
||||
#include "shared/offline_compiler/source/ocloc_interface.h"
|
||||
#include "shared/offline_compiler/source/offline_compiler.h"
|
||||
#include "shared/offline_compiler/source/utilities/safety_caller.h"
|
||||
#include "shared/source/compiler_interface/compiler_options.h"
|
||||
@@ -20,6 +21,7 @@
|
||||
#include "shared/source/helpers/file_io.h"
|
||||
#include "shared/source/helpers/hw_info.h"
|
||||
#include "shared/source/helpers/product_config_helper.h"
|
||||
#include "shared/source/helpers/product_config_helper_former.h"
|
||||
#include "shared/source/utilities/directory.h"
|
||||
|
||||
#include "neo_aot_platforms.h"
|
||||
@@ -33,22 +35,29 @@
|
||||
|
||||
namespace NEO {
|
||||
|
||||
using Position = FormerProductConfigHelper::Position;
|
||||
|
||||
bool isSpvOnly(const std::vector<std::string> &args) {
|
||||
return std::find(args.begin(), args.end(), "-spv_only") != args.end();
|
||||
}
|
||||
|
||||
bool requestedFatBinary(ConstStringRef deviceArg, OclocArgHelper *helper) {
|
||||
auto &prodHelper = *helper->productConfigHelper;
|
||||
auto &formerProdHelper = *helper->formerProductConfigHelper;
|
||||
auto deviceName = deviceArg.str();
|
||||
ProductConfigHelper::adjustDeviceName(deviceName);
|
||||
auto release = helper->productConfigHelper->getReleaseFromDeviceName(deviceName);
|
||||
auto family = helper->productConfigHelper->getFamilyFromDeviceName(deviceName);
|
||||
|
||||
auto release = prodHelper.getReleaseFromDeviceName(deviceName);
|
||||
auto family = prodHelper.getFamilyFromDeviceName(deviceName);
|
||||
auto retVal = deviceArg.contains("*");
|
||||
retVal |= deviceArg.contains(":");
|
||||
retVal |= deviceArg.contains(",");
|
||||
retVal |= family != AOT::UNKNOWN_FAMILY;
|
||||
retVal |= release != AOT::UNKNOWN_RELEASE;
|
||||
|
||||
retVal |= formerProdHelper.isSupportedTarget<AOT::FAMILY>(deviceName);
|
||||
retVal |= formerProdHelper.isSupportedTarget<AOT::RELEASE>(deviceName);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -65,7 +74,8 @@ bool requestedFatBinary(const std::vector<std::string> &args, OclocArgHelper *he
|
||||
|
||||
template <>
|
||||
void getProductsAcronymsForTarget<AOT::RELEASE>(std::vector<NEO::ConstStringRef> &out, AOT::RELEASE target, OclocArgHelper *argHelper) {
|
||||
auto &allSuppportedProducts = argHelper->productConfigHelper->getDeviceAotInfo();
|
||||
auto &prodHelper = *argHelper->productConfigHelper;
|
||||
auto &allSuppportedProducts = prodHelper.getDeviceAotInfo();
|
||||
auto hasDeviceAcronym = std::any_of(allSuppportedProducts.begin(), allSuppportedProducts.end(), ProductConfigHelper::findDeviceAcronymForRelease(target));
|
||||
for (const auto &device : allSuppportedProducts) {
|
||||
if (device.release == target) {
|
||||
@@ -88,7 +98,8 @@ void getProductsAcronymsForTarget<AOT::RELEASE>(std::vector<NEO::ConstStringRef>
|
||||
|
||||
template <>
|
||||
void getProductsAcronymsForTarget<AOT::FAMILY>(std::vector<NEO::ConstStringRef> &out, AOT::FAMILY target, OclocArgHelper *argHelper) {
|
||||
auto &allSuppportedProducts = argHelper->productConfigHelper->getDeviceAotInfo();
|
||||
auto &prodHelper = *argHelper->productConfigHelper;
|
||||
auto &allSuppportedProducts = prodHelper.getDeviceAotInfo();
|
||||
std::vector<AOT::RELEASE> releases{};
|
||||
for (const auto &device : allSuppportedProducts) {
|
||||
if (device.family == target && std::find(releases.begin(), releases.end(), device.release) == releases.end()) {
|
||||
@@ -115,9 +126,21 @@ std::vector<ConstStringRef> getProductsForTargetRange(T targetFrom, T targetTo,
|
||||
|
||||
std::vector<ConstStringRef> getProductsForRange(unsigned int productFrom, unsigned int productTo,
|
||||
OclocArgHelper *argHelper) {
|
||||
auto &prodHelper = *argHelper->productConfigHelper;
|
||||
auto &formerProdHelper = *argHelper->formerProductConfigHelper;
|
||||
std::vector<ConstStringRef> ret = {};
|
||||
auto &allSuppportedProducts = argHelper->productConfigHelper->getDeviceAotInfo();
|
||||
|
||||
auto &formerData = formerProdHelper.getData();
|
||||
uint32_t ipVersionAdded = 0;
|
||||
for (const auto &[acronym, ipVersion] : formerData.acronyms) {
|
||||
auto validAcronym = ipVersion >= productFrom;
|
||||
validAcronym &= ipVersion <= productTo;
|
||||
if (validAcronym && ipVersion != ipVersionAdded) {
|
||||
ret.push_back(acronym.c_str());
|
||||
ipVersionAdded = ipVersion;
|
||||
}
|
||||
}
|
||||
auto &allSuppportedProducts = prodHelper.getDeviceAotInfo();
|
||||
for (const auto &device : allSuppportedProducts) {
|
||||
auto validAcronym = device.aotConfig.value >= productFrom;
|
||||
validAcronym &= device.aotConfig.value <= productTo;
|
||||
@@ -133,122 +156,347 @@ std::vector<ConstStringRef> getProductsForRange(unsigned int productFrom, unsign
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<ConstStringRef> getProductForClosedRange(ConstStringRef rangeFrom, ConstStringRef rangeTo, OclocArgHelper *argHelper) {
|
||||
std::vector<ConstStringRef> requestedProducts = {};
|
||||
auto rangeToStr = rangeTo.str();
|
||||
auto rangeFromStr = rangeFrom.str();
|
||||
std::vector<ConstStringRef> getProductsForFamilyClosedRange(const std::string &fromStr, const std::string &toStr, OclocArgHelper *argHelper) {
|
||||
auto &prodHelper = *argHelper->productConfigHelper;
|
||||
auto &formerProdHelper = *argHelper->formerProductConfigHelper;
|
||||
|
||||
ProductConfigHelper::adjustDeviceName(rangeToStr);
|
||||
ProductConfigHelper::adjustDeviceName(rangeFromStr);
|
||||
argHelper->productConfigHelper->adjustClosedRangeDeviceLegacyAcronyms(rangeFromStr, rangeToStr);
|
||||
auto getFamilyConfigWithFallback = [&](const std::string &familyStr, FormerProductConfigHelper::Position pos) {
|
||||
auto family = prodHelper.getFamilyFromDeviceName(familyStr);
|
||||
AOT::PRODUCT_CONFIG config = AOT::UNKNOWN_ISA;
|
||||
if (family != AOT::UNKNOWN_FAMILY) {
|
||||
config = prodHelper.getLastProductConfigFromFamilyName(family);
|
||||
}
|
||||
if (config == AOT::UNKNOWN_ISA) {
|
||||
config = formerProdHelper.getProductConfigFromFamilyName(familyStr, pos);
|
||||
}
|
||||
return config;
|
||||
};
|
||||
|
||||
auto familyFrom = argHelper->productConfigHelper->getFamilyFromDeviceName(rangeFromStr);
|
||||
auto familyTo = argHelper->productConfigHelper->getFamilyFromDeviceName(rangeToStr);
|
||||
auto familyFrom = prodHelper.getFamilyFromDeviceName(fromStr);
|
||||
auto familyTo = prodHelper.getFamilyFromDeviceName(toStr);
|
||||
if (familyFrom != AOT::UNKNOWN_FAMILY && familyTo != AOT::UNKNOWN_FAMILY) {
|
||||
return getProductsForTargetRange(familyFrom, familyTo, argHelper, AOT::FAMILY_MAX);
|
||||
}
|
||||
AOT::PRODUCT_CONFIG prodConfigFrom = getFamilyConfigWithFallback(fromStr, Position::firstItem);
|
||||
AOT::PRODUCT_CONFIG prodConfigTo = getFamilyConfigWithFallback(toStr, Position::lastItem);
|
||||
if (prodConfigFrom != AOT::UNKNOWN_ISA && prodConfigTo != AOT::UNKNOWN_ISA) {
|
||||
return getProductsForRange(prodConfigFrom, prodConfigTo, argHelper);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
auto releaseFrom = argHelper->productConfigHelper->getReleaseFromDeviceName(rangeFromStr);
|
||||
auto releaseTo = argHelper->productConfigHelper->getReleaseFromDeviceName(rangeToStr);
|
||||
std::vector<ConstStringRef> getProductsForReleaseClosedRange(const std::string &fromStr, const std::string &toStr, OclocArgHelper *argHelper) {
|
||||
auto &prodHelper = *argHelper->productConfigHelper;
|
||||
auto &formerProdHelper = *argHelper->formerProductConfigHelper;
|
||||
|
||||
auto getReleaseConfigWithFallback = [&](const std::string &releaseStr, FormerProductConfigHelper::Position pos) {
|
||||
auto release = prodHelper.getReleaseFromDeviceName(releaseStr);
|
||||
auto config = prodHelper.getLastProductConfigFromReleaseName(release);
|
||||
if (config == AOT::UNKNOWN_ISA) {
|
||||
config = formerProdHelper.getProductConfigFromReleaseName(releaseStr, pos);
|
||||
}
|
||||
return config;
|
||||
};
|
||||
|
||||
auto releaseFrom = prodHelper.getReleaseFromDeviceName(fromStr);
|
||||
auto releaseTo = prodHelper.getReleaseFromDeviceName(toStr);
|
||||
if (releaseFrom != AOT::UNKNOWN_RELEASE && releaseTo != AOT::UNKNOWN_RELEASE) {
|
||||
return getProductsForTargetRange(releaseFrom, releaseTo, argHelper, AOT::RELEASE_MAX);
|
||||
}
|
||||
AOT::PRODUCT_CONFIG prodConfigFrom = getReleaseConfigWithFallback(fromStr, Position::firstItem);
|
||||
AOT::PRODUCT_CONFIG prodConfigTo = getReleaseConfigWithFallback(toStr, Position::lastItem);
|
||||
if (prodConfigFrom != AOT::UNKNOWN_ISA && prodConfigTo != AOT::UNKNOWN_ISA) {
|
||||
return getProductsForRange(prodConfigFrom, prodConfigTo, argHelper);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
auto prodConfigFrom = argHelper->productConfigHelper->getProductConfigFromDeviceName(rangeFromStr);
|
||||
auto prodConfigTo = argHelper->productConfigHelper->getProductConfigFromDeviceName(rangeToStr);
|
||||
std::vector<ConstStringRef> getProductsForProductClosedRange(const std::string &fromStr, const std::string &toStr, OclocArgHelper *argHelper) {
|
||||
auto &prodHelper = *argHelper->productConfigHelper;
|
||||
auto &formerProdHelper = *argHelper->formerProductConfigHelper;
|
||||
|
||||
auto getProductConfigWithFallback = [&](const std::string &deviceName) {
|
||||
auto config = prodHelper.getProductConfigFromDeviceName(deviceName);
|
||||
if (config == AOT::UNKNOWN_ISA) {
|
||||
config = formerProdHelper.getProductConfigFromDeviceName(deviceName);
|
||||
}
|
||||
return config;
|
||||
};
|
||||
|
||||
AOT::PRODUCT_CONFIG prodConfigFrom = getProductConfigWithFallback(fromStr);
|
||||
AOT::PRODUCT_CONFIG prodConfigTo = getProductConfigWithFallback(toStr);
|
||||
if (prodConfigFrom != AOT::UNKNOWN_ISA && prodConfigTo != AOT::UNKNOWN_ISA) {
|
||||
if (prodConfigFrom > prodConfigTo) {
|
||||
std::swap(prodConfigFrom, prodConfigTo);
|
||||
}
|
||||
return getProductsForRange(prodConfigFrom, prodConfigTo, argHelper);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<ConstStringRef> getProductForClosedRange(ConstStringRef rangeFrom, ConstStringRef rangeTo, OclocArgHelper *argHelper) {
|
||||
auto rangeFromStr = rangeFrom.str();
|
||||
auto rangeToStr = rangeTo.str();
|
||||
ProductConfigHelper::adjustDeviceName(rangeFromStr);
|
||||
ProductConfigHelper::adjustDeviceName(rangeToStr);
|
||||
|
||||
auto familyProducts = getProductsForFamilyClosedRange(rangeFromStr, rangeToStr, argHelper);
|
||||
if (!familyProducts.empty()) {
|
||||
return familyProducts;
|
||||
}
|
||||
auto releaseProducts = getProductsForReleaseClosedRange(rangeFromStr, rangeToStr, argHelper);
|
||||
if (!releaseProducts.empty()) {
|
||||
return releaseProducts;
|
||||
}
|
||||
auto productProducts = getProductsForProductClosedRange(rangeFromStr, rangeToStr, argHelper);
|
||||
if (!productProducts.empty()) {
|
||||
return productProducts;
|
||||
}
|
||||
|
||||
auto target = rangeFromStr + ":" + rangeToStr;
|
||||
argHelper->printf("Failed to parse target : %s.\n", target.c_str());
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<ConstStringRef> getProductForOpenRange(ConstStringRef openRange, OclocArgHelper *argHelper, bool rangeTo) {
|
||||
std::vector<ConstStringRef> requestedProducts = {};
|
||||
auto openRangeStr = openRange.str();
|
||||
ProductConfigHelper::adjustDeviceName(openRangeStr);
|
||||
auto mergeProducts = [](std::vector<ConstStringRef> &dst, std::vector<ConstStringRef> &&src) {
|
||||
for (auto &elem : src) {
|
||||
if (std::find(dst.begin(), dst.end(), elem) == dst.end()) {
|
||||
dst.push_back(std::move(elem));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
auto family = argHelper->productConfigHelper->getFamilyFromDeviceName(openRangeStr);
|
||||
std::vector<ConstStringRef> getProductsForFamilyOpenRange(const std::string &openRangeStr, OclocArgHelper *argHelper, bool rangeTo) {
|
||||
auto &prodHelper = *argHelper->productConfigHelper;
|
||||
auto &formerProdHelper = *argHelper->formerProductConfigHelper;
|
||||
|
||||
auto getFamilyConfigWithFallback = [&](const std::string &familyStr, FormerProductConfigHelper::Position pos) {
|
||||
auto family = prodHelper.getFamilyFromDeviceName(familyStr);
|
||||
AOT::PRODUCT_CONFIG config = AOT::UNKNOWN_ISA;
|
||||
if (family != AOT::UNKNOWN_FAMILY) {
|
||||
config = prodHelper.getLastProductConfigFromFamilyName(family);
|
||||
}
|
||||
if (config == AOT::UNKNOWN_ISA) {
|
||||
config = formerProdHelper.getProductConfigFromFamilyName(familyStr, pos);
|
||||
}
|
||||
return config;
|
||||
};
|
||||
|
||||
std::vector<ConstStringRef> requestedProducts;
|
||||
auto family = prodHelper.getFamilyFromDeviceName(openRangeStr);
|
||||
if (family != AOT::UNKNOWN_FAMILY) {
|
||||
if (rangeTo) {
|
||||
unsigned int familyFrom = AOT::UNKNOWN_FAMILY;
|
||||
++familyFrom;
|
||||
return getProductsForTargetRange(static_cast<AOT::FAMILY>(familyFrom), family, argHelper, AOT::FAMILY_MAX);
|
||||
auto prodConfigFrom = getFamilyConfigWithFallback(formerProdHelper.getFamilyName(Position::firstItem), Position::firstItem);
|
||||
auto prodConfigTo = getFamilyConfigWithFallback(formerProdHelper.getFamilyName(Position::lastItem), Position::lastItem);
|
||||
if (prodConfigFrom != AOT::UNKNOWN_ISA && prodConfigTo != AOT::UNKNOWN_ISA) {
|
||||
mergeProducts(requestedProducts, getProductsForRange(prodConfigFrom, prodConfigTo, argHelper));
|
||||
}
|
||||
unsigned int familyFrom = AOT::UNKNOWN_FAMILY + 1;
|
||||
mergeProducts(requestedProducts, getProductsForTargetRange(static_cast<AOT::FAMILY>(familyFrom), family, argHelper, AOT::FAMILY_MAX));
|
||||
return requestedProducts;
|
||||
} else {
|
||||
unsigned int familyTo = AOT::FAMILY_MAX;
|
||||
return getProductsForTargetRange(family, static_cast<AOT::FAMILY>(familyTo), argHelper, AOT::FAMILY_MAX);
|
||||
}
|
||||
} else if (formerProdHelper.isFamilyName(openRangeStr)) {
|
||||
if (rangeTo) {
|
||||
auto prodConfigFrom = getFamilyConfigWithFallback(formerProdHelper.getFamilyName(Position::firstItem), Position::firstItem);
|
||||
auto prodConfigTo = getFamilyConfigWithFallback(openRangeStr, Position::lastItem);
|
||||
if (prodConfigFrom != AOT::UNKNOWN_ISA && prodConfigTo != AOT::UNKNOWN_ISA) {
|
||||
return getProductsForRange(prodConfigFrom, prodConfigTo, argHelper);
|
||||
}
|
||||
} else {
|
||||
auto prodConfigFrom = getFamilyConfigWithFallback(openRangeStr, Position::firstItem);
|
||||
auto prodConfigTo = getFamilyConfigWithFallback(formerProdHelper.getFamilyName(Position::lastItem), Position::lastItem);
|
||||
if (prodConfigFrom != AOT::UNKNOWN_ISA && prodConfigTo != AOT::UNKNOWN_ISA) {
|
||||
mergeProducts(requestedProducts, getProductsForRange(prodConfigFrom, prodConfigTo, argHelper));
|
||||
}
|
||||
unsigned int familyFrom = AOT::UNKNOWN_FAMILY + 1;
|
||||
unsigned int familyTo = AOT::FAMILY_MAX;
|
||||
mergeProducts(requestedProducts, getProductsForTargetRange(static_cast<AOT::FAMILY>(familyFrom), static_cast<AOT::FAMILY>(familyTo), argHelper, AOT::FAMILY_MAX));
|
||||
return requestedProducts;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
auto release = argHelper->productConfigHelper->getReleaseFromDeviceName(openRangeStr);
|
||||
std::vector<ConstStringRef> getProductsForReleaseOpenRange(const std::string &openRangeStr, OclocArgHelper *argHelper, bool rangeTo) {
|
||||
auto &prodHelper = *argHelper->productConfigHelper;
|
||||
auto &formerProdHelper = *argHelper->formerProductConfigHelper;
|
||||
std::vector<ConstStringRef> requestedProducts;
|
||||
|
||||
auto getReleaseConfigWithFallback = [&](const std::string &releaseStr, FormerProductConfigHelper::Position pos) {
|
||||
auto release = prodHelper.getReleaseFromDeviceName(releaseStr);
|
||||
auto config = prodHelper.getLastProductConfigFromReleaseName(release);
|
||||
if (config == AOT::UNKNOWN_ISA) {
|
||||
config = formerProdHelper.getProductConfigFromReleaseName(releaseStr, pos);
|
||||
}
|
||||
return config;
|
||||
};
|
||||
|
||||
auto release = prodHelper.getReleaseFromDeviceName(openRangeStr);
|
||||
if (release != AOT::UNKNOWN_RELEASE) {
|
||||
if (rangeTo) {
|
||||
unsigned int releaseFrom = AOT::UNKNOWN_FAMILY;
|
||||
++releaseFrom;
|
||||
return getProductsForTargetRange(static_cast<AOT::RELEASE>(releaseFrom), release, argHelper, AOT::RELEASE_MAX);
|
||||
auto prodConfigFrom = getReleaseConfigWithFallback(formerProdHelper.getReleaseName(Position::firstItem), Position::firstItem);
|
||||
auto prodConfigTo = getReleaseConfigWithFallback(formerProdHelper.getReleaseName(Position::lastItem), Position::lastItem);
|
||||
if (prodConfigFrom != AOT::UNKNOWN_ISA && prodConfigTo != AOT::UNKNOWN_ISA) {
|
||||
mergeProducts(requestedProducts, getProductsForRange(prodConfigFrom, prodConfigTo, argHelper));
|
||||
}
|
||||
unsigned int releaseFrom = AOT::UNKNOWN_RELEASE + 1;
|
||||
mergeProducts(requestedProducts, getProductsForTargetRange(static_cast<AOT::RELEASE>(releaseFrom), release, argHelper, AOT::RELEASE_MAX));
|
||||
return requestedProducts;
|
||||
} else {
|
||||
unsigned int releaseTo = AOT::RELEASE_MAX;
|
||||
return getProductsForTargetRange(release, static_cast<AOT::RELEASE>(releaseTo), argHelper, AOT::RELEASE_MAX);
|
||||
}
|
||||
} else if (formerProdHelper.isReleaseName(openRangeStr)) {
|
||||
if (rangeTo) {
|
||||
auto prodConfigFrom = getReleaseConfigWithFallback(formerProdHelper.getReleaseName(Position::firstItem), Position::firstItem);
|
||||
auto prodConfigTo = getReleaseConfigWithFallback(openRangeStr, Position::lastItem);
|
||||
if (prodConfigFrom != AOT::UNKNOWN_ISA && prodConfigTo != AOT::UNKNOWN_ISA) {
|
||||
return getProductsForRange(prodConfigFrom, prodConfigTo, argHelper);
|
||||
}
|
||||
} else {
|
||||
auto prodConfigFrom = getReleaseConfigWithFallback(openRangeStr, Position::firstItem);
|
||||
auto prodConfigTo = getReleaseConfigWithFallback(formerProdHelper.getReleaseName(Position::lastItem), Position::lastItem);
|
||||
if (prodConfigFrom != AOT::UNKNOWN_ISA && prodConfigTo != AOT::UNKNOWN_ISA) {
|
||||
mergeProducts(requestedProducts, getProductsForRange(prodConfigFrom, prodConfigTo, argHelper));
|
||||
}
|
||||
unsigned int releaseFrom = AOT::UNKNOWN_RELEASE + 1;
|
||||
unsigned int releaseTo = AOT::RELEASE_MAX;
|
||||
mergeProducts(requestedProducts, getProductsForTargetRange(static_cast<AOT::RELEASE>(releaseFrom), static_cast<AOT::RELEASE>(releaseTo), argHelper, AOT::RELEASE_MAX));
|
||||
return requestedProducts;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
auto product = argHelper->productConfigHelper->getProductConfigFromDeviceName(openRangeStr);
|
||||
std::vector<ConstStringRef> getProductsForProductOpenRange(const std::string &openRangeStr, OclocArgHelper *argHelper, bool rangeTo) {
|
||||
auto &prodHelper = *argHelper->productConfigHelper;
|
||||
auto &formerProdHelper = *argHelper->formerProductConfigHelper;
|
||||
|
||||
auto getProductConfigWithFallback = [&](const std::string &deviceName) {
|
||||
auto config = prodHelper.getProductConfigFromDeviceName(deviceName);
|
||||
if (config == AOT::UNKNOWN_ISA) {
|
||||
config = formerProdHelper.getProductConfigFromDeviceName(deviceName);
|
||||
}
|
||||
return config;
|
||||
};
|
||||
|
||||
auto product = getProductConfigWithFallback(openRangeStr);
|
||||
if (product != AOT::UNKNOWN_ISA) {
|
||||
if (rangeTo) {
|
||||
unsigned int productFrom = AOT::UNKNOWN_ISA;
|
||||
++productFrom;
|
||||
unsigned int productFrom = formerProdHelper.getFirstProductConfig();
|
||||
if (productFrom == AOT::UNKNOWN_ISA) {
|
||||
++productFrom;
|
||||
}
|
||||
return getProductsForRange(productFrom, static_cast<unsigned int>(product), argHelper);
|
||||
} else {
|
||||
unsigned int productTo = AOT::getConfixMaxPlatform();
|
||||
--productTo;
|
||||
unsigned int productTo = AOT::getConfixMaxPlatform() - 1;
|
||||
return getProductsForRange(product, static_cast<AOT::PRODUCT_CONFIG>(productTo), argHelper);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<ConstStringRef> getProductForOpenRange(ConstStringRef openRange, OclocArgHelper *argHelper, bool rangeTo) {
|
||||
auto openRangeStr = openRange.str();
|
||||
ProductConfigHelper::adjustDeviceName(openRangeStr);
|
||||
|
||||
auto familyProducts = getProductsForFamilyOpenRange(openRangeStr, argHelper, rangeTo);
|
||||
if (!familyProducts.empty()) {
|
||||
return familyProducts;
|
||||
}
|
||||
auto releaseProducts = getProductsForReleaseOpenRange(openRangeStr, argHelper, rangeTo);
|
||||
if (!releaseProducts.empty()) {
|
||||
return releaseProducts;
|
||||
}
|
||||
auto productProducts = getProductsForProductOpenRange(openRangeStr, argHelper, rangeTo);
|
||||
if (!productProducts.empty()) {
|
||||
return productProducts;
|
||||
}
|
||||
|
||||
argHelper->printf("Failed to parse target : %s.\n", openRangeStr.c_str());
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<ConstStringRef> getProductForSpecificTarget(const CompilerOptions::TokenizedString &targets, OclocArgHelper *argHelper) {
|
||||
auto &prodHelper = *argHelper->productConfigHelper;
|
||||
auto &formerProdHelper = *argHelper->formerProductConfigHelper;
|
||||
std::vector<ConstStringRef> requestedConfigs;
|
||||
|
||||
auto getProductsAcronymsForFamilyWithFallback = [&](const std::string &targetStr) -> bool {
|
||||
auto family = prodHelper.getFamilyFromDeviceName(targetStr);
|
||||
if (family != AOT::UNKNOWN_FAMILY) {
|
||||
getProductsAcronymsForTarget(requestedConfigs, family, argHelper);
|
||||
return true;
|
||||
}
|
||||
if (formerProdHelper.isSupportedTarget<AOT::FAMILY>(targetStr)) {
|
||||
mergeProducts(requestedConfigs, formerProdHelper.getProductAcronymsFromFamilyGroup(targetStr));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
auto getProductsAcronymsForReleaseWithFallback = [&](const std::string &targetStr) -> bool {
|
||||
auto release = prodHelper.getReleaseFromDeviceName(targetStr);
|
||||
if (release != AOT::UNKNOWN_RELEASE) {
|
||||
getProductsAcronymsForTarget(requestedConfigs, release, argHelper);
|
||||
return true;
|
||||
}
|
||||
if (formerProdHelper.isSupportedTarget<AOT::RELEASE>(targetStr)) {
|
||||
mergeProducts(requestedConfigs, formerProdHelper.getProductAcronymsFromReleaseGroup(targetStr));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
auto getProductConfigWithFallback = [&](const ConstStringRef &target) -> bool {
|
||||
auto product = prodHelper.getProductConfigFromAcronym(target.str());
|
||||
if (product == AOT::UNKNOWN_ISA) {
|
||||
product = formerProdHelper.getProductConfigFromDeviceName(target.str());
|
||||
}
|
||||
if (product != AOT::UNKNOWN_ISA) {
|
||||
mergeProducts(requestedConfigs, std::vector<ConstStringRef>{target});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
for (const auto &target : targets) {
|
||||
auto targetStr = target.str();
|
||||
ProductConfigHelper::adjustDeviceName(targetStr);
|
||||
|
||||
auto family = argHelper->productConfigHelper->getFamilyFromDeviceName(targetStr);
|
||||
if (family != AOT::UNKNOWN_FAMILY) {
|
||||
getProductsAcronymsForTarget(requestedConfigs, family, argHelper);
|
||||
if (getProductsAcronymsForFamilyWithFallback(targetStr)) {
|
||||
continue;
|
||||
}
|
||||
auto release = argHelper->productConfigHelper->getReleaseFromDeviceName(targetStr);
|
||||
if (release != AOT::UNKNOWN_RELEASE) {
|
||||
getProductsAcronymsForTarget(requestedConfigs, release, argHelper);
|
||||
if (getProductsAcronymsForReleaseWithFallback(targetStr)) {
|
||||
continue;
|
||||
}
|
||||
auto product = argHelper->productConfigHelper->getProductConfigFromDeviceName(targetStr);
|
||||
if (product != AOT::UNKNOWN_ISA) {
|
||||
if (getProductConfigWithFallback(target)) {
|
||||
continue;
|
||||
}
|
||||
if (getHwInfoForDeprecatedAcronym(targetStr) != nullptr) {
|
||||
requestedConfigs.push_back(target);
|
||||
continue;
|
||||
}
|
||||
auto legacyAcronymHwInfo = getHwInfoForDeprecatedAcronym(targetStr);
|
||||
if (nullptr != legacyAcronymHwInfo) {
|
||||
requestedConfigs.push_back(target);
|
||||
continue;
|
||||
}
|
||||
argHelper->printf("Failed to parse target : %s - invalid device:\n", target.str().c_str());
|
||||
|
||||
argHelper->printf("Failed to parse target : %s - invalid device:\n", targetStr.c_str());
|
||||
return {};
|
||||
}
|
||||
|
||||
return requestedConfigs;
|
||||
}
|
||||
|
||||
std::vector<ConstStringRef> getTargetProductsForFatbinary(ConstStringRef deviceArg, OclocArgHelper *argHelper) {
|
||||
auto &prodHelper = *argHelper->productConfigHelper;
|
||||
auto &formerProdHelper = *argHelper->formerProductConfigHelper;
|
||||
std::vector<ConstStringRef> retVal;
|
||||
if (deviceArg == "*") {
|
||||
return argHelper->productConfigHelper->getRepresentativeProductAcronyms();
|
||||
retVal = prodHelper.getRepresentativeProductAcronyms();
|
||||
auto formerAcronyms = formerProdHelper.getRepresentativeProductAcronyms();
|
||||
retVal.insert(retVal.begin(), formerAcronyms.begin(), formerAcronyms.end());
|
||||
return retVal;
|
||||
} else {
|
||||
auto sets = CompilerOptions::tokenize(deviceArg, ',');
|
||||
if (sets[0].contains(":")) {
|
||||
@@ -283,6 +531,7 @@ int getDeviceArgValueIdx(const std::vector<std::string> &args) {
|
||||
|
||||
int buildFatBinaryForTarget(int retVal, const std::vector<std::string> &argsCopy, std::string pointerSize, Ar::ArEncoder &fatbinary,
|
||||
OfflineCompiler *pCompiler, OclocArgHelper *argHelper, const std::string &product) {
|
||||
auto &prodHelper = *argHelper->productConfigHelper;
|
||||
|
||||
if (retVal == 0) {
|
||||
retVal = buildWithSafetyGuard(pCompiler);
|
||||
@@ -311,10 +560,11 @@ int buildFatBinaryForTarget(int retVal, const std::vector<std::string> &argsCopy
|
||||
if (product.find(".") != std::string::npos) {
|
||||
entryName = product;
|
||||
} else {
|
||||
auto productConfig = argHelper->productConfigHelper->getProductConfigFromDeviceName(product);
|
||||
auto genericIdAcronymIt = std::find_if(AOT::genericIdAcronyms.begin(), AOT::genericIdAcronyms.end(), [product](const std::pair<std::string, AOT::PRODUCT_CONFIG> &genericIdAcronym) {
|
||||
return product == genericIdAcronym.first;
|
||||
});
|
||||
auto productConfig = prodHelper.getProductConfigFromDeviceName(product);
|
||||
auto genericIdAcronymIt = std::find_if(AOT::genericIdAcronyms.begin(), AOT::genericIdAcronyms.end(),
|
||||
[product](const std::pair<std::string, AOT::PRODUCT_CONFIG> &genericIdAcronym) {
|
||||
return product == genericIdAcronym.first;
|
||||
});
|
||||
if (AOT::UNKNOWN_ISA != productConfig && genericIdAcronymIt == AOT::genericIdAcronyms.end()) {
|
||||
entryName = ProductConfigHelper::parseMajorMinorRevisionValue(productConfig);
|
||||
} else {
|
||||
@@ -326,6 +576,74 @@ int buildFatBinaryForTarget(int retVal, const std::vector<std::string> &argsCopy
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int buildFatBinaryForFormerTarget(int retVal, const std::vector<std::string> &argsCopy, std::string pointerSize, Ar::ArEncoder &fatbinary,
|
||||
OclocArgHelper *argHelper, const std::string &product) {
|
||||
auto &formerProdHelper = *argHelper->formerProductConfigHelper;
|
||||
uint32_t numOutputs = 0u;
|
||||
unsigned char **dataOutputs = nullptr;
|
||||
uint64_t *lenOutputs = nullptr;
|
||||
char **nameOutputs = nullptr;
|
||||
|
||||
if (retVal == 0) {
|
||||
std::vector<const char *> argvPtrs;
|
||||
argvPtrs.reserve(argsCopy.size());
|
||||
for (const auto &arg : argsCopy) {
|
||||
argvPtrs.push_back(arg.c_str());
|
||||
}
|
||||
auto retValFormerOcloc = Ocloc::Commands::invokeFormerOcloc(Ocloc::getOclocFormerLibName(),
|
||||
static_cast<unsigned int>(argvPtrs.size()),
|
||||
argvPtrs.data(),
|
||||
0, nullptr, nullptr, nullptr,
|
||||
0, nullptr, nullptr, nullptr,
|
||||
&numOutputs, &dataOutputs,
|
||||
&lenOutputs, &nameOutputs);
|
||||
if (retValFormerOcloc) {
|
||||
retVal = retValFormerOcloc.value();
|
||||
argHelper->dontSetupOutputs();
|
||||
// Check if the actual return code indicates success
|
||||
if (retVal == 0) {
|
||||
argHelper->printf("Build succeeded for : %s.\n", product.c_str());
|
||||
} else {
|
||||
argHelper->printf("Build failed for : %s with error code: %d\n", product.c_str(), retVal);
|
||||
argHelper->printf("Command was:");
|
||||
for (const auto &arg : argsCopy) {
|
||||
argHelper->printf(" %s", arg.c_str());
|
||||
}
|
||||
argHelper->printf("\n");
|
||||
return retVal;
|
||||
}
|
||||
} else {
|
||||
// Former ocloc couldn't be invoked at all
|
||||
argHelper->printf("Build failed for : %s - could not invoke former ocloc\n", product.c_str());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < numOutputs; ++i) {
|
||||
std::string name = nameOutputs[i];
|
||||
if (name.find(".bin") != std::string::npos) {
|
||||
const ArrayRef<const uint8_t> fileData(dataOutputs[i], static_cast<size_t>(lenOutputs[i]));
|
||||
|
||||
std::string entryName("");
|
||||
if (product.find(".") != std::string::npos) {
|
||||
entryName = product;
|
||||
} else {
|
||||
auto productConfig = formerProdHelper.getProductConfigFromAcronym(product);
|
||||
entryName = ProductConfigHelper::parseMajorMinorRevisionValue(productConfig);
|
||||
}
|
||||
fatbinary.appendFileEntry(pointerSize + "." + entryName, fileData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use formerOclocFree since memory was allocated by former ocloc
|
||||
auto freeResult = Ocloc::Commands::formerOclocFree(Ocloc::getOclocFormerLibName(), &numOutputs, &dataOutputs, &lenOutputs, &nameOutputs);
|
||||
if (!freeResult) {
|
||||
// Fallback to regular oclocFreeOutput if formerOclocFree fails
|
||||
oclocFreeOutput(&numOutputs, &dataOutputs, &lenOutputs, &nameOutputs);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int buildFatBinary(const std::vector<std::string> &args, OclocArgHelper *argHelper) {
|
||||
std::string pointerSizeInBits = (sizeof(void *) == 4) ? "32" : "64";
|
||||
size_t deviceArgIndex = -1;
|
||||
@@ -393,23 +711,34 @@ int buildFatBinary(const std::vector<std::string> &args, OclocArgHelper *argHelp
|
||||
argHelper->printf("Warning! -device_options set for non-compiled device: %s\n", deviceAcronym.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
std::string optionsForIr;
|
||||
for (const auto &product : targetProducts) {
|
||||
int retVal = 0;
|
||||
int retVal = OCLOC_SUCCESS;
|
||||
argsCopy[deviceArgIndex] = product.str();
|
||||
|
||||
std::unique_ptr<OfflineCompiler> pCompiler{OfflineCompiler::create(argsCopy.size(), argsCopy, false, retVal, argHelper)};
|
||||
if (OCLOC_SUCCESS != retVal) {
|
||||
argHelper->printf("Error! Couldn't create OfflineCompiler. Exiting.\n");
|
||||
return retVal;
|
||||
}
|
||||
auto &formerProdHelper = *argHelper->formerProductConfigHelper;
|
||||
auto formerProduct = formerProdHelper.getProductConfigFromDeviceName(product.str().c_str());
|
||||
auto formerProductFallback = formerProdHelper.isSupportedProductConfig(formerProduct);
|
||||
if (formerProductFallback) {
|
||||
retVal = buildFatBinaryForFormerTarget(retVal, argsCopy, pointerSizeInBits, fatbinary, argHelper, product.str());
|
||||
if (retVal) {
|
||||
return retVal;
|
||||
}
|
||||
} else {
|
||||
std::unique_ptr<OfflineCompiler> pCompiler{OfflineCompiler::create(argsCopy.size(), argsCopy, false, retVal, argHelper)};
|
||||
if (OCLOC_SUCCESS != retVal) {
|
||||
argHelper->printf("Error! Couldn't create OfflineCompiler. Exiting.\n");
|
||||
return retVal;
|
||||
}
|
||||
|
||||
retVal = buildFatBinaryForTarget(retVal, argsCopy, pointerSizeInBits, fatbinary, pCompiler.get(), argHelper, product.str());
|
||||
if (retVal) {
|
||||
return retVal;
|
||||
}
|
||||
if (optionsForIr.empty()) {
|
||||
optionsForIr = pCompiler->getOptions();
|
||||
retVal = buildFatBinaryForTarget(retVal, argsCopy, pointerSizeInBits, fatbinary, pCompiler.get(), argHelper, product.str());
|
||||
if (retVal) {
|
||||
return retVal;
|
||||
}
|
||||
if (optionsForIr.empty()) {
|
||||
optionsForIr = pCompiler->getOptions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,11 @@
|
||||
#include "shared/offline_compiler/source/offline_linker.h"
|
||||
#include "shared/offline_compiler/source/utilities/safety_caller.h"
|
||||
#include "shared/source/device_binary_format/elf/elf_decoder.h"
|
||||
#include "shared/source/helpers/product_config_helper_former.h"
|
||||
#include "shared/source/os_interface/os_library.h"
|
||||
|
||||
#include "neo_aot_platforms.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Ocloc {
|
||||
@@ -127,14 +130,23 @@ const std::string &getOclocFormerLibName() { return oclocFormerLibName; }
|
||||
|
||||
namespace Commands {
|
||||
|
||||
bool isDeviceArgProvided(const std::vector<std::string> &args) {
|
||||
for (size_t argIndex = 0; argIndex + 1 < args.size(); ++argIndex) {
|
||||
if (ConstStringRef("-device") == args[argIndex]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int compile(OclocArgHelper *argHelper, const std::vector<std::string> &args) {
|
||||
std::vector<std::string> argsCopy(args);
|
||||
int deviceArgIndex = NEO::getDeviceArgValueIdx(args);
|
||||
|
||||
if (NEO::requestedFatBinary(args, argHelper)) {
|
||||
bool onlySpirV = NEO::isSpvOnly(args);
|
||||
|
||||
if (onlySpirV) {
|
||||
int deviceArgIndex = NEO::getDeviceArgValueIdx(args);
|
||||
UNRECOVERABLE_IF(deviceArgIndex < 0);
|
||||
std::vector<ConstStringRef> targetProducts = NEO::getTargetProductsForFatbinary(ConstStringRef(args[deviceArgIndex]), argHelper);
|
||||
ConstStringRef firstDevice = targetProducts.front();
|
||||
@@ -145,31 +157,59 @@ int compile(OclocArgHelper *argHelper, const std::vector<std::string> &args) {
|
||||
}
|
||||
|
||||
int retVal = OCLOC_SUCCESS;
|
||||
std::unique_ptr<OfflineCompiler> pCompiler{OfflineCompiler::create(argsCopy.size(), argsCopy, true, retVal, argHelper)};
|
||||
auto formerProductFallback = false;
|
||||
|
||||
if (retVal == OCLOC_SUCCESS) {
|
||||
if (pCompiler->showHelpOnly()) {
|
||||
return retVal;
|
||||
if (isDeviceArgProvided(argsCopy)) {
|
||||
UNRECOVERABLE_IF(deviceArgIndex < 0);
|
||||
auto &formerProdHelper = *argHelper->formerProductConfigHelper;
|
||||
auto product = formerProdHelper.getProductConfigFromDeviceName(argsCopy[deviceArgIndex]);
|
||||
formerProductFallback = formerProdHelper.isSupportedProductConfig(product);
|
||||
}
|
||||
|
||||
if (formerProductFallback) {
|
||||
std::vector<const char *> argvPtrs;
|
||||
argvPtrs.reserve(argsCopy.size());
|
||||
for (const auto &arg : argsCopy) {
|
||||
argvPtrs.push_back(arg.c_str());
|
||||
}
|
||||
retVal = buildWithSafetyGuard(pCompiler.get());
|
||||
|
||||
std::string buildLog = pCompiler->getBuildLog();
|
||||
if (buildLog.empty() == false) {
|
||||
argHelper->printf("%s\n", buildLog.c_str());
|
||||
}
|
||||
|
||||
if (retVal == OCLOC_SUCCESS) {
|
||||
if (!pCompiler->isQuiet()) {
|
||||
argHelper->printf("Build succeeded.\n");
|
||||
}
|
||||
auto retValFormerOcloc = Ocloc::Commands::invokeFormerOcloc(Ocloc::getOclocFormerLibName(),
|
||||
static_cast<unsigned int>(argvPtrs.size()),
|
||||
argvPtrs.data(),
|
||||
0, nullptr, nullptr, nullptr,
|
||||
0, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr);
|
||||
if (retValFormerOcloc) {
|
||||
retVal = retValFormerOcloc.value();
|
||||
argHelper->dontSetupOutputs();
|
||||
} else {
|
||||
argHelper->printf("Build failed with error code: %d\n", retVal);
|
||||
}
|
||||
} else {
|
||||
std::unique_ptr<OfflineCompiler> pCompiler{OfflineCompiler::create(argsCopy.size(), argsCopy, true, retVal, argHelper)};
|
||||
if (retVal == OCLOC_SUCCESS) {
|
||||
if (pCompiler->showHelpOnly()) {
|
||||
return retVal;
|
||||
}
|
||||
retVal = buildWithSafetyGuard(pCompiler.get());
|
||||
|
||||
std::string buildLog = pCompiler->getBuildLog();
|
||||
if (buildLog.empty() == false) {
|
||||
argHelper->printf("%s\n", buildLog.c_str());
|
||||
}
|
||||
|
||||
if (retVal == OCLOC_SUCCESS) {
|
||||
if (!pCompiler->isQuiet()) {
|
||||
argHelper->printf("Build succeeded.\n");
|
||||
}
|
||||
} else {
|
||||
argHelper->printf("Build failed with error code: %d\n", retVal);
|
||||
}
|
||||
}
|
||||
if (retVal != OCLOC_SUCCESS) {
|
||||
printOclocOptionsReadFromFile(*argHelper, pCompiler.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (retVal != OCLOC_SUCCESS) {
|
||||
printOclocOptionsReadFromFile(*argHelper, pCompiler.get());
|
||||
}
|
||||
return retVal;
|
||||
};
|
||||
|
||||
@@ -284,5 +324,26 @@ std::optional<int> invokeFormerOcloc(const std::string &formerOclocName, unsigne
|
||||
return oclocInvokeFunc(numArgs, argv, numSources, dataSources, lenSources, nameSources, numInputHeaders, dataInputHeaders, lenInputHeaders, nameInputHeaders, numOutputs, dataOutputs, lenOutputs, nameOutputs);
|
||||
}
|
||||
|
||||
std::optional<int> formerOclocFree(const std::string &formerOclocName, uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs) {
|
||||
if (formerOclocName.empty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unique_ptr<OsLibrary> oclocLib(OsLibrary::loadFunc(formerOclocName));
|
||||
|
||||
if (!oclocLib) {
|
||||
return {};
|
||||
}
|
||||
|
||||
typedef int (*pOclocFreeOutput)(uint32_t * numOutputs, uint8_t * **dataOutputs, uint64_t * *lenOutputs, char ***nameOutputs);
|
||||
auto oclocFreeFunc = reinterpret_cast<pOclocFreeOutput>(oclocLib->getProcAddress("oclocFreeOutput"));
|
||||
|
||||
if (!oclocFreeFunc) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return oclocFreeFunc(numOutputs, dataOutputs, lenOutputs, nameOutputs);
|
||||
}
|
||||
|
||||
} // namespace Commands
|
||||
} // namespace Ocloc
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2022-2024 Intel Corporation
|
||||
* Copyright (C) 2022-2025 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -47,5 +47,6 @@ std::optional<int> invokeFormerOcloc(const std::string &formerOclocName, unsigne
|
||||
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);
|
||||
std::optional<int> formerOclocFree(const std::string &formerOclocName, uint32_t *numOutputs, uint8_t ***dataOutputs, uint64_t **lenOutputs, char ***nameOutputs);
|
||||
} // namespace Commands
|
||||
} // namespace Ocloc
|
||||
|
||||
@@ -63,6 +63,18 @@ SupportedDevicesHelper::SupportedDevicesData SupportedDevicesHelper::collectSupp
|
||||
return data;
|
||||
}
|
||||
|
||||
SupportedDevicesHelper::SupportedDevicesData SupportedDevicesHelper::collectFormerSupportedDevicesData() const {
|
||||
std::string formerSupportedDevices = getDataFromFormerOcloc();
|
||||
SupportedDevicesData formerData;
|
||||
|
||||
if (formerSupportedDevices.empty()) {
|
||||
return formerData;
|
||||
}
|
||||
|
||||
auto formerDataDeserialized = deserialize(formerSupportedDevices);
|
||||
return formerDataDeserialized[getFormerOclocName()];
|
||||
}
|
||||
|
||||
std::string SupportedDevicesHelper::serialize(std::string_view oclocName, const SupportedDevicesData &data) const {
|
||||
std::ostringstream oss;
|
||||
oss << oclocName << ":\n";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Intel Corporation
|
||||
* Copyright (C) 2024-2025 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
@@ -57,6 +57,7 @@ class SupportedDevicesHelper {
|
||||
|
||||
std::string getCurrentOclocOutputFilename() const;
|
||||
SupportedDevicesData collectSupportedDevicesData(const std::vector<DeviceAotInfo> &enabledDevices) const;
|
||||
SupportedDevicesData collectFormerSupportedDevicesData() const;
|
||||
|
||||
std::string serialize(std::string_view oclocName, const SupportedDevicesData &data) const;
|
||||
std::map<std::string, SupportedDevicesData> deserialize(std::string_view yamlString) const;
|
||||
|
||||
@@ -132,6 +132,8 @@ set(NEO_CORE_HELPERS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${BRANCH_DIR_SUFFIX}product_config_helper_extra.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/product_config_helper.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/product_config_helper.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/product_config_helper_former.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/product_config_helper_former.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ptr_math.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ray_tracing_helper.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/register_offsets.h
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "shared/source/helpers/hw_mapper.h"
|
||||
#include "shared/source/helpers/product_config_helper.h"
|
||||
#include "shared/source/helpers/product_config_helper_former.h"
|
||||
#include "shared/source/utilities/stackvec.h"
|
||||
|
||||
#include "neo_igfxfmid.h"
|
||||
|
||||
@@ -79,6 +79,26 @@ void ProductConfigHelper::adjustClosedRangeDeviceLegacyAcronyms(std::string &ran
|
||||
}
|
||||
}
|
||||
|
||||
AOT::PRODUCT_CONFIG ProductConfigHelper::getLastProductConfigFromFamilyName(AOT::FAMILY family) {
|
||||
uint32_t lastProduct = AOT::UNKNOWN_ISA;
|
||||
for (const auto &device : deviceAotInfo) {
|
||||
if (device.family == family) {
|
||||
lastProduct = device.aotConfig.value;
|
||||
}
|
||||
}
|
||||
return static_cast<AOT::PRODUCT_CONFIG>(lastProduct);
|
||||
}
|
||||
|
||||
AOT::PRODUCT_CONFIG ProductConfigHelper::getLastProductConfigFromReleaseName(AOT::RELEASE release) {
|
||||
uint32_t lastProduct = AOT::UNKNOWN_ISA;
|
||||
for (const auto &device : deviceAotInfo) {
|
||||
if (device.release == release) {
|
||||
lastProduct = device.aotConfig.value;
|
||||
}
|
||||
}
|
||||
return static_cast<AOT::PRODUCT_CONFIG>(lastProduct);
|
||||
}
|
||||
|
||||
NEO::ConstStringRef ProductConfigHelper::getAcronymFromAFamily(AOT::FAMILY family) {
|
||||
for (const auto &[acronym, value] : AOT::familyAcronyms) {
|
||||
if (value == family) {
|
||||
|
||||
@@ -60,6 +60,8 @@ struct ProductConfigHelper {
|
||||
}
|
||||
|
||||
static std::vector<NEO::ConstStringRef> getDeviceAcronyms();
|
||||
AOT::PRODUCT_CONFIG getLastProductConfigFromFamilyName(AOT::FAMILY family);
|
||||
AOT::PRODUCT_CONFIG getLastProductConfigFromReleaseName(AOT::RELEASE release);
|
||||
static NEO::ConstStringRef getAcronymFromAFamily(AOT::FAMILY family);
|
||||
static NEO::ConstStringRef getAcronymFromARelease(AOT::RELEASE release);
|
||||
static uint32_t getProductConfigFromVersionValue(const std::string &device);
|
||||
|
||||
170
shared/source/helpers/product_config_helper_former.cpp
Normal file
170
shared/source/helpers/product_config_helper_former.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/helpers/product_config_helper_former.h"
|
||||
|
||||
#include "shared/source/helpers/hw_info.h"
|
||||
|
||||
#include "device_ids_configs.h"
|
||||
#include "hw_cmds.h"
|
||||
#include "neo_aot_platforms.h"
|
||||
|
||||
FormerProductConfigHelper::FormerProductConfigHelper()
|
||||
: helper(Ocloc::SupportedDevicesMode::concat, nullptr) {
|
||||
data = helper.collectFormerSupportedDevicesData();
|
||||
}
|
||||
|
||||
Ocloc::SupportedDevicesHelper::SupportedDevicesData &FormerProductConfigHelper::getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool FormerProductConfigHelper::isSupportedTarget<AOT::FAMILY>(const std::string &target) const {
|
||||
return std::any_of(
|
||||
data.familyGroups.begin(), data.familyGroups.end(),
|
||||
[&](const auto &pair) { return pair.first == target; });
|
||||
}
|
||||
|
||||
template <>
|
||||
bool FormerProductConfigHelper::isSupportedTarget<AOT::RELEASE>(const std::string &target) const {
|
||||
return std::any_of(
|
||||
data.releaseGroups.begin(), data.releaseGroups.end(),
|
||||
[&](const auto &pair) { return pair.first == target; });
|
||||
}
|
||||
|
||||
bool FormerProductConfigHelper::isSupportedProductConfig(uint32_t config) const {
|
||||
if (config == AOT::UNKNOWN_ISA) {
|
||||
return false;
|
||||
}
|
||||
return std::any_of(data.deviceIpVersions.begin(), data.deviceIpVersions.end(),
|
||||
[config](uint32_t v) { return v == config; });
|
||||
}
|
||||
|
||||
std::vector<NEO::ConstStringRef> FormerProductConfigHelper::getProductAcronymsFromFamilyGroup(const std::string &groupName) const {
|
||||
return getProductAcronymsFromGroup(groupName, data.familyGroups);
|
||||
}
|
||||
|
||||
std::vector<NEO::ConstStringRef> FormerProductConfigHelper::getProductAcronymsFromReleaseGroup(const std::string &groupName) const {
|
||||
return getProductAcronymsFromGroup(groupName, data.releaseGroups);
|
||||
}
|
||||
|
||||
AOT::PRODUCT_CONFIG FormerProductConfigHelper::getProductConfigFromDeviceName(const std::string &device) {
|
||||
uint32_t config = AOT::UNKNOWN_ISA;
|
||||
char hexPrefixLength = 2;
|
||||
if (device.find(".") != std::string::npos) {
|
||||
config = ProductConfigHelper::getProductConfigFromVersionValue(device);
|
||||
} else if (std::all_of(device.begin(), device.end(), (::isdigit))) {
|
||||
config = static_cast<uint32_t>(std::stoul(device));
|
||||
} else if (device.substr(0, hexPrefixLength) == "0x" && std::all_of(device.begin() + hexPrefixLength, device.end(), (::isxdigit))) {
|
||||
auto deviceId = static_cast<unsigned short>(std::stoi(device, 0, 16));
|
||||
config = getProductConfigFromDeviceId(deviceId);
|
||||
} else {
|
||||
config = getProductConfigFromAcronym(device);
|
||||
}
|
||||
return static_cast<AOT::PRODUCT_CONFIG>(config);
|
||||
}
|
||||
|
||||
AOT::PRODUCT_CONFIG FormerProductConfigHelper::getProductConfigFromAcronym(const std::string &device) {
|
||||
auto it = std::find_if(
|
||||
data.acronyms.begin(), data.acronyms.end(),
|
||||
[&](const auto &pair) { return pair.first == device; });
|
||||
if (it != data.acronyms.end()) {
|
||||
return static_cast<AOT::PRODUCT_CONFIG>(it->second);
|
||||
}
|
||||
return AOT::UNKNOWN_ISA;
|
||||
}
|
||||
|
||||
AOT::PRODUCT_CONFIG FormerProductConfigHelper::getProductConfigFromDeviceId(const uint32_t &deviceId) {
|
||||
auto it = std::find_if(
|
||||
data.deviceInfos.begin(), data.deviceInfos.end(),
|
||||
[&](const auto &deviceInfo) { return deviceInfo.deviceId == deviceId; });
|
||||
if (it != data.deviceInfos.end()) {
|
||||
return static_cast<AOT::PRODUCT_CONFIG>(it->ipVersion);
|
||||
}
|
||||
return AOT::UNKNOWN_ISA;
|
||||
}
|
||||
|
||||
AOT::PRODUCT_CONFIG FormerProductConfigHelper::getFirstProductConfig() {
|
||||
uint32_t firstProduct = AOT::UNKNOWN_ISA;
|
||||
if (!data.acronyms.empty()) {
|
||||
auto &firstProductPair = data.acronyms.front();
|
||||
firstProduct = firstProductPair.second;
|
||||
}
|
||||
return static_cast<AOT::PRODUCT_CONFIG>(firstProduct);
|
||||
}
|
||||
|
||||
bool FormerProductConfigHelper::isFamilyName(const std::string &family) {
|
||||
return std::any_of(
|
||||
data.familyGroups.begin(), data.familyGroups.end(),
|
||||
[&family](const auto &pair) {
|
||||
return pair.first == family;
|
||||
});
|
||||
}
|
||||
|
||||
bool FormerProductConfigHelper::isReleaseName(const std::string &release) {
|
||||
return std::any_of(
|
||||
data.releaseGroups.begin(), data.releaseGroups.end(),
|
||||
[&release](const auto &pair) {
|
||||
return pair.first == release;
|
||||
});
|
||||
}
|
||||
|
||||
std::string FormerProductConfigHelper::getFamilyName(Position pos) {
|
||||
if (data.familyGroups.empty()) {
|
||||
return "";
|
||||
}
|
||||
if (pos == Position::firstItem) {
|
||||
return data.familyGroups.front().first;
|
||||
} else {
|
||||
return data.familyGroups.back().first;
|
||||
}
|
||||
}
|
||||
|
||||
std::string FormerProductConfigHelper::getReleaseName(Position pos) {
|
||||
if (data.releaseGroups.empty()) {
|
||||
return "";
|
||||
}
|
||||
if (pos == Position::firstItem) {
|
||||
return data.releaseGroups.front().first;
|
||||
} else {
|
||||
return data.releaseGroups.back().first;
|
||||
}
|
||||
}
|
||||
|
||||
AOT::PRODUCT_CONFIG FormerProductConfigHelper::getProductConfigFromFamilyName(const std::string &family, Position pos) {
|
||||
for (const auto &[acronym, value] : data.familyGroups) {
|
||||
if (acronym == family && !value.empty()) {
|
||||
if (pos == Position::firstItem) {
|
||||
return static_cast<AOT::PRODUCT_CONFIG>(value.front());
|
||||
} else {
|
||||
return static_cast<AOT::PRODUCT_CONFIG>(value.back());
|
||||
}
|
||||
}
|
||||
}
|
||||
return AOT::UNKNOWN_ISA;
|
||||
}
|
||||
|
||||
AOT::PRODUCT_CONFIG FormerProductConfigHelper::getProductConfigFromReleaseName(const std::string &release, Position pos) {
|
||||
for (const auto &[acronym, value] : data.releaseGroups) {
|
||||
if (acronym == release && !value.empty()) {
|
||||
if (pos == Position::firstItem) {
|
||||
return static_cast<AOT::PRODUCT_CONFIG>(value.front());
|
||||
} else {
|
||||
return static_cast<AOT::PRODUCT_CONFIG>(value.back());
|
||||
}
|
||||
}
|
||||
}
|
||||
return AOT::UNKNOWN_ISA;
|
||||
}
|
||||
|
||||
std::vector<NEO::ConstStringRef> FormerProductConfigHelper::getRepresentativeProductAcronyms() {
|
||||
std::vector<NEO::ConstStringRef> enabledAcronyms{};
|
||||
for (const auto &[acronym, ipVersion] : data.acronyms) {
|
||||
enabledAcronyms.push_back(acronym.c_str());
|
||||
}
|
||||
return enabledAcronyms;
|
||||
}
|
||||
75
shared/source/helpers/product_config_helper_former.h
Normal file
75
shared/source/helpers/product_config_helper_former.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared/offline_compiler/source/ocloc_api.h"
|
||||
#include "shared/offline_compiler/source/ocloc_interface.h"
|
||||
#include "shared/offline_compiler/source/ocloc_supported_devices_helper.h"
|
||||
#include "shared/source/helpers/hw_ip_version.h"
|
||||
#include "shared/source/helpers/product_config_helper.h"
|
||||
#include "shared/source/utilities/const_stringref.h"
|
||||
|
||||
#include "neo_igfxfmid.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct ProductConfigHelper;
|
||||
struct FormerProductConfigHelper {
|
||||
public:
|
||||
enum class Position { firstItem,
|
||||
lastItem };
|
||||
|
||||
FormerProductConfigHelper();
|
||||
|
||||
Ocloc::SupportedDevicesHelper::SupportedDevicesData &getData();
|
||||
|
||||
template <typename T>
|
||||
bool isSupportedTarget(const std::string &target) const;
|
||||
bool isSupportedProductConfig(uint32_t config) const;
|
||||
std::vector<NEO::ConstStringRef> getProductAcronymsFromFamilyGroup(const std::string &groupName) const;
|
||||
std::vector<NEO::ConstStringRef> getProductAcronymsFromReleaseGroup(const std::string &groupName) const;
|
||||
AOT::PRODUCT_CONFIG getProductConfigFromDeviceName(const std::string &device);
|
||||
AOT::PRODUCT_CONFIG getProductConfigFromAcronym(const std::string &device);
|
||||
AOT::PRODUCT_CONFIG getProductConfigFromDeviceId(const uint32_t &deviceId);
|
||||
AOT::PRODUCT_CONFIG getFirstProductConfig();
|
||||
bool isFamilyName(const std::string &family);
|
||||
bool isReleaseName(const std::string &release);
|
||||
std::string getFamilyName(Position pos);
|
||||
std::string getReleaseName(Position pos);
|
||||
AOT::PRODUCT_CONFIG getProductConfigFromFamilyName(const std::string &family, Position pos);
|
||||
AOT::PRODUCT_CONFIG getProductConfigFromReleaseName(const std::string &release, Position pos);
|
||||
std::vector<NEO::ConstStringRef> getRepresentativeProductAcronyms();
|
||||
|
||||
protected:
|
||||
template <typename GroupT>
|
||||
std::vector<NEO::ConstStringRef> getProductAcronymsFromGroup(const std::string &groupName, const GroupT &groups) const;
|
||||
Ocloc::SupportedDevicesHelper helper;
|
||||
Ocloc::SupportedDevicesHelper::SupportedDevicesData data;
|
||||
};
|
||||
|
||||
template <typename GroupT>
|
||||
std::vector<NEO::ConstStringRef> FormerProductConfigHelper::getProductAcronymsFromGroup(const std::string &groupName, const GroupT &groups) const {
|
||||
std::vector<NEO::ConstStringRef> enabledAcronyms{};
|
||||
for (const auto &[name, ipVersions] : groups) {
|
||||
if (name == groupName) {
|
||||
for (const auto &ipVersion : ipVersions) {
|
||||
auto it = std::find_if(data.acronyms.begin(), data.acronyms.end(),
|
||||
[&ipVersion](const std::pair<std::string, uint32_t> &pair) {
|
||||
return pair.second == ipVersion;
|
||||
});
|
||||
if (it != data.acronyms.end()) {
|
||||
enabledAcronyms.push_back(it->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return enabledAcronyms;
|
||||
}
|
||||
Reference in New Issue
Block a user