Add support for new acronyms in disasm

The "disasm" option in ocloc was not validate new acronyms.
despite handling them in "compile".
This PR is fixing the issue - ocloc disasm supports new & deprecated
acronyms.

https://github.com/intel/compute-runtime/issues/582

Signed-off-by: Daria Hinz <daria.hinz@intel.com>
Related-To: NEO-7509
This commit is contained in:
Daria Hinz
2022-11-15 15:24:52 +00:00
committed by Compute-Runtime-Automation
parent 4476e7ad76
commit 31deb4fd63
12 changed files with 184 additions and 35 deletions

View File

@ -7,9 +7,11 @@
#include "shared/offline_compiler/source/decoder/translate_platform_base.h"
#include "shared/source/helpers/array_count.h"
#include "shared/test/common/helpers/gtest_helpers.h"
#include "shared/test/common/helpers/test_files.h"
#include "shared/test/common/helpers/variable_backup.h"
#include "opencl/test/unit_test/offline_compiler/environment.h"
#include "opencl/test/unit_test/offline_compiler/mock/mock_argument_helper.h"
#include "opencl/test/unit_test/offline_compiler/stdout_capturer.h"
#include "opencl/test/unit_test/test_files/patch_list.h"
@ -25,6 +27,8 @@
#include <string>
#include <utility>
extern Environment *gEnvironment;
static void abortOclocExecutionMock(int code) {
throw std::runtime_error{"Exit called with code = " + std::to_string(code)};
}
@ -43,7 +47,6 @@ SKernelBinaryHeaderCommon createKernelBinaryHeaderCommon(const uint32_t kernelNa
}
namespace NEO {
TEST(DecoderTests, GivenArgHelperWithHeadersWhenLoadingPatchListThenHeadersAreReturned) {
const char input[] = "First\nSecond\nThird";
const auto inputLength{sizeof(input)};
@ -277,6 +280,80 @@ TEST(DecoderTests, GivenFlagsWhichRequireMoreArgsWithoutThemWhenParsingThenError
}
}
TEST(DecoderTests, givenUnknownDeviceNameWhenValidateInputThenCorrectWarningIsReported) {
const std::vector<std::string> args = {
"ocloc",
"disasm",
"-device",
"unk"};
constexpr auto suppressMessages{false};
MockDecoder decoder{suppressMessages};
::testing::internal::CaptureStdout();
const auto result = decoder.validateInput(args);
const auto output{::testing::internal::GetCapturedStdout()};
EXPECT_EQ(result, 0);
const std::string expectedWarningMessage{"Warning : missing or invalid -device parameter - results may be inaccurate\n"};
EXPECT_TRUE(hasSubstr(output, expectedWarningMessage));
}
TEST(DecoderTests, givenDeprecatedDeviceNamesWhenValidateInputThenCorrectWarningIsReported) {
constexpr auto suppressMessages{false};
MockDecoder decoder{suppressMessages};
auto deprecatedAcronyms = decoder.mockArgHelper->productConfigHelper->getDeprecatedAcronyms();
if (deprecatedAcronyms.empty()) {
GTEST_SKIP();
}
for (const auto &acronym : deprecatedAcronyms) {
const std::vector<std::string> args = {
"ocloc",
"disasm",
"-device",
acronym.str()};
::testing::internal::CaptureStdout();
const auto result = decoder.validateInput(args);
const auto output{::testing::internal::GetCapturedStdout()};
EXPECT_EQ(result, 0);
const std::string expectedWarningMessage{"Warning : Deprecated device name is being used.\n"};
EXPECT_TRUE(hasSubstr(output, expectedWarningMessage));
}
}
TEST(DecoderTests, givenDeviceNamesWhenValidateInputThenSuccessIsReturned) {
constexpr auto suppressMessages{false};
MockDecoder decoder{suppressMessages};
decoder.mockArgHelper->hasOutput = true;
auto supportedAcronyms = decoder.mockArgHelper->productConfigHelper->getAllProductAcronyms();
if (supportedAcronyms.empty()) {
GTEST_SKIP();
}
for (const auto &acronym : supportedAcronyms) {
const std::vector<std::string> args = {
"ocloc",
"disasm",
"-device",
acronym.str()};
::testing::internal::CaptureStdout();
const auto result = decoder.validateInput(args);
const auto output{::testing::internal::GetCapturedStdout()};
EXPECT_EQ(result, 0);
EXPECT_TRUE(output.empty());
}
decoder.mockArgHelper->hasOutput = false;
}
TEST(DecoderTests, GivenIgnoreIsaPaddingFlagWhenParsingValidListOfParametersThenReturnValueIsZeroAndInternalFlagIsSet) {
const std::vector<std::string> args = {
"ocloc",
@ -314,19 +391,21 @@ TEST(DecoderTests, GivenQuietModeFlagWhenParsingValidListOfParametersThenReturnV
}
TEST(DecoderTests, GivenMissingDumpFlagWhenParsingValidListOfParametersThenReturnValueIsZeroAndWarningAboutCreationOfDefaultDirectoryIsPrinted) {
if (gEnvironment->productConfig.empty()) {
GTEST_SKIP();
}
const std::vector<std::string> args = {
"ocloc",
"disasm",
"-file",
"test_files/binary.bin",
"-device",
"pvc",
gEnvironment->productConfig.c_str(),
"-patch",
"test_files/patch"};
constexpr auto suppressMessages{false};
MockDecoder decoder{suppressMessages};
decoder.getMockIga()->isKnownPlatformReturnValue = true;
::testing::internal::CaptureStdout();
const auto result = decoder.validateInput(args);
@ -335,32 +414,31 @@ TEST(DecoderTests, GivenMissingDumpFlagWhenParsingValidListOfParametersThenRetur
EXPECT_EQ(0, result);
const std::string expectedErrorMessage{"Warning : Path to dump folder not specificed - using ./dump as default.\n"};
EXPECT_EQ(expectedErrorMessage, output);
EXPECT_TRUE(hasSubstr(output, expectedErrorMessage));
}
TEST(DecoderTests, GivenMissingDumpFlagAndArgHelperOutputEnabledWhenParsingValidListOfParametersThenReturnValueIsZeroAndDefaultDirectoryWarningIsNotEmitted) {
if (gEnvironment->productConfig.empty()) {
GTEST_SKIP();
}
const std::vector<std::string> args = {
"ocloc",
"disasm",
"-file",
"test_files/binary.bin",
"-device",
"pvc",
gEnvironment->productConfig.c_str(),
"-patch",
"test_files/patch"};
constexpr auto suppressMessages{false};
MockDecoder decoder{suppressMessages};
decoder.mockArgHelper->hasOutput = true;
decoder.getMockIga()->isKnownPlatformReturnValue = true;
::testing::internal::CaptureStdout();
const auto result = decoder.validateInput(args);
const auto output{::testing::internal::GetCapturedStdout()};
EXPECT_EQ(0, result);
EXPECT_TRUE(output.empty()) << output;
decoder.mockArgHelper->hasOutput = false;
}
@ -549,30 +627,30 @@ TEST(DecoderTests, GivenValidBinaryWithoutPatchTokensWhenProcessingBinaryThenBin
TEST(DecoderTests, GivenValidBinaryWhenProcessingBinaryThenProgramAndKernelAndPatchTokensAreReadCorrectly) {
std::stringstream binarySS;
//ProgramBinaryHeader
// ProgramBinaryHeader
auto programHeader = createProgramBinaryHeader(1, 30);
binarySS.write(reinterpret_cast<const char *>(&programHeader), sizeof(SProgramBinaryHeader));
//PATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO
// PATCH_TOKEN_ALLOCATE_CONSTANT_MEMORY_SURFACE_PROGRAM_BINARY_INFO
SPatchAllocateConstantMemorySurfaceProgramBinaryInfo patchAllocateConstantMemory;
patchAllocateConstantMemory.Token = 42;
patchAllocateConstantMemory.Size = 16;
patchAllocateConstantMemory.ConstantBufferIndex = 0;
patchAllocateConstantMemory.InlineDataSize = 14;
binarySS.write(reinterpret_cast<const char *>(&patchAllocateConstantMemory), sizeof(patchAllocateConstantMemory));
//InlineData
// InlineData
for (uint8_t i = 0; i < 14; ++i) {
binarySS.write(reinterpret_cast<char *>(&i), sizeof(uint8_t));
}
//KernelBinaryHeader
// KernelBinaryHeader
std::string kernelName("ExampleKernel");
auto kernelHeader = createKernelBinaryHeaderCommon(static_cast<uint32_t>(kernelName.size() + 1), 12);
binarySS.write(reinterpret_cast<const char *>(&kernelHeader), sizeof(SKernelBinaryHeaderCommon));
binarySS.write(kernelName.c_str(), kernelHeader.KernelNameSize);
//PATCH_TOKEN_MEDIA_INTERFACE_DESCRIPTOR_LOAD
// PATCH_TOKEN_MEDIA_INTERFACE_DESCRIPTOR_LOAD
SPatchMediaInterfaceDescriptorLoad patchMediaInterfaceDescriptorLoad;
patchMediaInterfaceDescriptorLoad.Token = 19;
patchMediaInterfaceDescriptorLoad.Size = 12;

View File

@ -10,6 +10,8 @@
#include "shared/source/helpers/array_count.h"
#include "shared/test/common/helpers/test_files.h"
#include "opencl/test/unit_test/offline_compiler/environment.h"
#include "gtest/gtest.h"
#include "mock/mock_encoder.h"
@ -18,6 +20,8 @@
#include <fstream>
#include <sstream>
extern Environment *gEnvironment;
namespace NEO {
TEST(EncoderTests, WhenParsingValidListOfParametersThenReturnValueIsZero) {
@ -90,18 +94,21 @@ TEST(EncoderTests, GivenQuietModeFlagWhenParsingValidListOfParametersThenReturnV
}
TEST(EncoderTests, GivenMissingDumpFlagAndArgHelperOutputEnabledWhenParsingValidListOfParametersThenReturnValueIsZeroAndDefaultDirectoryIsNotUsedAsDumpPath) {
if (gEnvironment->productConfig.empty()) {
GTEST_SKIP();
}
const std::vector<std::string> args = {
"ocloc",
"asm",
"-out",
"test_files/binary_gen.bin",
"-device",
"pvc"};
gEnvironment->productConfig.c_str(),
};
constexpr auto suppressMessages{false};
MockEncoder encoder{suppressMessages};
encoder.mockArgHelper->hasOutput = true;
encoder.getMockIga()->isKnownPlatformReturnValue = true;
::testing::internal::CaptureStdout();
const auto result = encoder.validateInput(args);

View File

@ -31,13 +31,10 @@ struct MockIgaWrapper : public IgaWrapper {
}
void setProductFamily(PRODUCT_FAMILY product) override {
IgaWrapper::setProductFamily(product);
setProductFamilyWasCalled = true;
}
bool isKnownPlatform() const override {
return isKnownPlatformReturnValue;
}
bool tryLoadIga() override {
return true;
}
@ -49,7 +46,6 @@ struct MockIgaWrapper : public IgaWrapper {
bool disasmWasCalled = false;
bool asmWasCalled = false;
bool isKnownPlatformReturnValue = false;
bool setProductFamilyWasCalled = false;
bool setGfxCoreWasCalled = false;
};

View File

@ -17,8 +17,8 @@
class Environment : public ::testing::Environment {
public:
Environment(const std::string &devicePrefix, const std::string &familyNameWithType)
: devicePrefix(devicePrefix), familyNameWithType(familyNameWithType) {
Environment(const std::string &devicePrefix, const std::string productConfig, const std::string &familyNameWithType)
: devicePrefix(devicePrefix), productConfig(productConfig), familyNameWithType(familyNameWithType) {
}
void SetInputFileName( // NOLINT(readability-identifier-naming)
@ -52,5 +52,6 @@ class Environment : public ::testing::Environment {
NEO::MockIgaDllGuard mockIgaDllGuard;
const std::string devicePrefix;
const std::string productConfig;
const std::string familyNameWithType;
};

View File

@ -52,6 +52,7 @@ int main(int argc, char **argv) {
std::string devicePrefix("skl");
std::string familyNameWithType("Gen9core");
std::string revId("0");
std::string productConfig("");
#if defined(__linux__)
if (getenv("CLOC_SELFTEST") == nullptr) {
@ -67,7 +68,7 @@ int main(int argc, char **argv) {
}
execv(argv[0], argv);
//execv failed, we return with error
// execv failed, we return with error
printf("FATAL ERROR: cannot self-exec test!\n");
return -1;
}
@ -110,6 +111,16 @@ int main(int argc, char **argv) {
}
}
auto productConfigHelper = new ProductConfigHelper();
auto allEnabledDeviceConfigs = productConfigHelper->getDeviceAotInfo();
for (const auto &device : allEnabledDeviceConfigs) {
if (device.hwInfo->platform.eProductFamily == productFamily) {
productConfig = ProductConfigHelper::parseMajorMinorRevisionValue(device.aotConfig);
break;
}
}
// we look for test files always relative to binary location
// this simplifies multi-process execution and using different
// working directories
@ -149,7 +160,7 @@ int main(int argc, char **argv) {
}
listeners.Append(new NEO::VirtualFileSystemListener);
gEnvironment = reinterpret_cast<Environment *>(::testing::AddGlobalTestEnvironment(new Environment(devicePrefix, familyNameWithType)));
gEnvironment = reinterpret_cast<Environment *>(::testing::AddGlobalTestEnvironment(new Environment(devicePrefix, productConfig, familyNameWithType)));
int sigOut = setAlarm(enableAlarm);
if (sigOut != 0) {

View File

@ -513,7 +513,7 @@ int BinaryDecoder::validateInput(const std::vector<std::string> &args) {
if ("-file" == currArg && hasMoreArgs) {
binaryFile = args[++argIndex];
} else if ("-device" == currArg && hasMoreArgs) {
iga->setProductFamily(getProductFamilyFromDeviceName(args[++argIndex]));
setProductFamilyForIga(args[++argIndex], iga.get(), argHelper);
} else if ("-patch" == currArg && hasMoreArgs) {
pathToPatch = args[++argIndex];
addSlash(pathToPatch);

View File

@ -312,7 +312,7 @@ int BinaryEncoder::validateInput(const std::vector<std::string> &args) {
pathToDump = args[++argIndex];
addSlash(pathToDump);
} else if ("-device" == currArg && hasMoreArgs) {
iga->setProductFamily(getProductFamilyFromDeviceName(args[++argIndex]));
setProductFamilyForIga(args[++argIndex], iga.get(), argHelper);
} else if ("-out" == currArg && hasMoreArgs) {
elfName = args[++argIndex];
} else if ("--help" == currArg) {

View File

@ -7,6 +7,8 @@
#include "helper.h"
#include "shared/offline_compiler/source/decoder/iga_wrapper.h"
#include "shared/offline_compiler/source/ocloc_arg_helper.h"
#include "shared/source/helpers/hw_info.h"
#include "shared/source/os_interface/os_inc_base.h"
#include "shared/source/os_interface/os_library.h"
@ -91,3 +93,14 @@ PRODUCT_FAMILY getProductFamilyFromDeviceName(const std::string &deviceName) {
}
return IGFX_UNKNOWN;
}
void setProductFamilyForIga(const std::string &device, IgaWrapper *iga, OclocArgHelper *argHelper) {
auto productFamily = argHelper->productConfigHelper->getProductFamilyForAcronym(device);
if (productFamily == IGFX_UNKNOWN) {
productFamily = getProductFamilyFromDeviceName(device);
if (productFamily != IGFX_UNKNOWN) {
argHelper->printf("Warning : Deprecated device name is being used.\n");
}
}
iga->setProductFamily(productFamily);
}

View File

@ -16,6 +16,9 @@
#include <string>
#include <vector>
class OclocArgHelper;
struct IgaWrapper;
extern void (*abortOclocExecution)(int);
void abortOclocExecutionDefaultHandler(int errorCode);
@ -25,6 +28,7 @@ void addSlash(std::string &path);
std::vector<char> readBinaryFile(const std::string &fileName);
void readFileToVectorOfStrings(std::vector<std::string> &lines, const std::string &fileName, bool replaceTabs = false);
void setProductFamilyForIga(const std::string &device, IgaWrapper *iga, OclocArgHelper *argHelper);
size_t findPos(const std::vector<std::string> &lines, const std::string &whatToFind);

View File

@ -11,8 +11,6 @@
#include "hw_cmds.h"
#include "platforms.h"
#include <algorithm>
ProductConfigHelper::ProductConfigHelper() : deviceAotInfo({
#define DEVICE_CONFIG(productConfig, hwConfig, deviceIds, family, release) {{AOT::productConfig}, &NEO::hwConfig::hwInfo, &NEO::deviceIds, AOT::family, AOT::release},
#include "product_config.inl"
@ -152,23 +150,31 @@ std::vector<NEO::ConstStringRef> ProductConfigHelper::getAllProductAcronyms() {
return allSupportedAcronyms;
}
PRODUCT_FAMILY ProductConfigHelper::getProductFamilyForAcronym(const std::string &device) const {
std::vector<DeviceAotInfo>::const_iterator it;
if (device.find(".") != std::string::npos) {
it = std::find_if(deviceAotInfo.begin(), deviceAotInfo.end(), findProductConfig(getProductConfigForVersionValue(device)));
} else {
it = std::find_if(deviceAotInfo.begin(), deviceAotInfo.end(), findAcronym(device));
}
if (it != deviceAotInfo.end())
return it->hwInfo->platform.eProductFamily;
return IGFX_UNKNOWN;
}
std::vector<NEO::ConstStringRef> ProductConfigHelper::getDeprecatedAcronyms() {
std::vector<NEO::ConstStringRef> prefixes{}, deprecatedAcronyms{}, enabledAcronyms{};
std::vector<NEO::ConstStringRef> prefixes{}, deprecatedAcronyms{};
for (int j = 0; j < IGFX_MAX_PRODUCT; j++) {
if (NEO::hardwarePrefix[j] == nullptr)
continue;
prefixes.push_back(NEO::hardwarePrefix[j]);
}
for (const auto &device : deviceAotInfo) {
enabledAcronyms.insert(enabledAcronyms.end(), device.acronyms.begin(), device.acronyms.end());
}
for (const auto &prefix : prefixes) {
std::string prefixCopy = prefix.str();
ProductConfigHelper::adjustDeviceName(prefixCopy);
if (std::any_of(enabledAcronyms.begin(), enabledAcronyms.end(), ProductConfigHelper::findAcronymWithoutDash(prefixCopy)))
if (std::any_of(deviceAotInfo.begin(), deviceAotInfo.end(), findAcronym(prefixCopy)))
continue;
deprecatedAcronyms.push_back(prefix);
}

View File

@ -9,6 +9,9 @@
#include "shared/source/utilities/const_stringref.h"
#include "igfxfmid.h"
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
@ -87,6 +90,11 @@ struct ProductConfigHelper {
return [&lhs](const auto &rhs) { return lhs == rhs || rhs.isEqualWithoutSeparator('-', lhs.c_str()); };
}
template <typename EqComparableT>
static auto findAcronym(const EqComparableT &lhs) {
return [&lhs](const auto &rhs) { return std::any_of(rhs.acronyms.begin(), rhs.acronyms.end(), findAcronymWithoutDash(lhs)); };
}
template <typename EqComparableT>
static auto findFamily(const EqComparableT &lhs) {
return [&lhs](const auto &rhs) { return lhs == rhs.family; };
@ -114,6 +122,7 @@ struct ProductConfigHelper {
std::vector<NEO::ConstStringRef> getFamiliesAcronyms();
std::vector<NEO::ConstStringRef> getDeprecatedAcronyms();
std::vector<NEO::ConstStringRef> getAllProductAcronyms();
PRODUCT_FAMILY getProductFamilyForAcronym(const std::string &device) const;
protected:
std::vector<DeviceAotInfo> deviceAotInfo;

View File

@ -7,6 +7,7 @@
#include "shared/test/unit_test/helpers/product_config_helper_tests.h"
#include "shared/source/helpers/hw_info.h"
#include "shared/source/utilities/const_stringref.h"
#include "shared/test/common/helpers/default_hw_info.h"
#include "shared/test/common/test_macros/test.h"
@ -493,6 +494,29 @@ TEST_F(AotDeviceInfoTests, givenUnknownIsaWhenGetDeviceAotInfoThenFalseIsReturne
EXPECT_TRUE(aotInfo == emptyInfo);
}
TEST_F(AotDeviceInfoTests, givenDeviceAcronymsOrProductConfigWhenGetProductFamilyThenCorrectResultIsReturned) {
auto &enabledProducts = productConfigHelper->getDeviceAotInfo();
for (const auto &product : enabledProducts) {
auto config = ProductConfigHelper::parseMajorMinorRevisionValue(product.aotConfig);
auto productFamily = productConfigHelper->getProductFamilyForAcronym(config);
EXPECT_EQ(productFamily, product.hwInfo->platform.eProductFamily);
for (const auto &acronym : product.acronyms) {
productFamily = productConfigHelper->getProductFamilyForAcronym(acronym.str());
EXPECT_EQ(productFamily, product.hwInfo->platform.eProductFamily);
}
}
}
TEST_F(AotDeviceInfoTests, givenDeprecatedDeviceAcronymsWhenGetProductFamilyThenUnknownIsReturned) {
auto deprecatedAcronyms = productConfigHelper->getDeprecatedAcronyms();
for (const auto &acronym : deprecatedAcronyms) {
EXPECT_EQ(productConfigHelper->getProductFamilyForAcronym(acronym.str()), IGFX_UNKNOWN);
}
}
TEST_F(AotDeviceInfoTests, givenProductConfigHelperWhenGetDeviceAcronymsThenCorrectResultsAreReturned) {
auto acronyms = productConfigHelper->getDeviceAcronyms();