Printf handler: ensure that long format uses always 64 bit integers

Related-To: NEO-7384
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski
2022-10-24 14:53:33 +00:00
committed by Compute-Runtime-Automation
parent 5446b9ca0d
commit 26144d38a6
3 changed files with 107 additions and 14 deletions

View File

@@ -113,6 +113,20 @@ void PrintFormatter::stripVectorTypeConversion(char *format) {
} }
} }
template <>
void PrintFormatter::adjustFormatString<int64_t>(std::string &formatString) {
auto longPosition = formatString.find('l');
if (longPosition == std::string::npos) {
return;
}
UNRECOVERABLE_IF(formatString.size() - 1 == longPosition);
if (formatString.at(longPosition + 1) != 'l') {
formatString.insert(longPosition, "l");
}
}
size_t PrintFormatter::printToken(char *output, size_t size, const char *formatString) { size_t PrintFormatter::printToken(char *output, size_t size, const char *formatString) {
PRINTF_DATA_TYPE type(PRINTF_DATA_TYPE::INVALID); PRINTF_DATA_TYPE type(PRINTF_DATA_TYPE::INVALID);
read(&type); read(&type);

View File

@@ -81,29 +81,35 @@ class PrintFormatter {
} }
template <class T> template <class T>
size_t typedPrintToken(char *output, size_t size, const char *formatString) { void adjustFormatString(std::string &formatString) {}
template <class T>
size_t typedPrintToken(char *output, size_t size, const char *inputFormatString) {
T value{0}; T value{0};
read(&value); read(&value);
constexpr auto offsetToBeDwordAligned = static_cast<uint32_t>(std::max(int64_t(sizeof(int) - sizeof(T)), int64_t(0))); currentOffset = alignUp(currentOffset, sizeof(uint32_t));
currentOffset += offsetToBeDwordAligned; std::string formatString(inputFormatString);
return simpleSprintf(output, size, formatString, value); adjustFormatString<T>(formatString);
return simpleSprintf(output, size, formatString.c_str(), value);
} }
template <class T> template <class T>
size_t typedPrintVectorToken(char *output, size_t size, const char *formatString) { size_t typedPrintVectorToken(char *output, size_t size, const char *inputFormatString) {
T value = {0}; T value = {0};
int valueCount = 0; int valueCount = 0;
read(&valueCount); read(&valueCount);
size_t charactersPrinted = 0; size_t charactersPrinted = 0;
char strippedFormat[1024]; char strippedFormat[1024]{};
stripVectorFormat(formatString, strippedFormat); stripVectorFormat(inputFormatString, strippedFormat);
stripVectorTypeConversion(strippedFormat); stripVectorTypeConversion(strippedFormat);
std::string formatString(strippedFormat);
adjustFormatString<T>(formatString);
for (int i = 0; i < valueCount; i++) { for (int i = 0; i < valueCount; i++) {
read(&value); read(&value);
charactersPrinted += simpleSprintf(output + charactersPrinted, size - charactersPrinted, strippedFormat, value); charactersPrinted += simpleSprintf(output + charactersPrinted, size - charactersPrinted, formatString.c_str(), value);
if (i < valueCount - 1) { if (i < valueCount - 1) {
charactersPrinted += simpleSprintf(output + charactersPrinted, size - charactersPrinted, "%c", ','); charactersPrinted += simpleSprintf(output + charactersPrinted, size - charactersPrinted, "%c", ',');
} }

View File

@@ -135,14 +135,21 @@ struct SingleValueTestParam {
T value; T value;
}; };
template <class T>
struct SingleValueTestParamWithHostFormat {
std::string format;
std::string hostFormat;
T value;
};
typedef SingleValueTestParam<int8_t> Int8Params; typedef SingleValueTestParam<int8_t> Int8Params;
typedef SingleValueTestParam<uint8_t> Uint8Params; typedef SingleValueTestParam<uint8_t> Uint8Params;
typedef SingleValueTestParam<int16_t> Int16Params; typedef SingleValueTestParam<int16_t> Int16Params;
typedef SingleValueTestParam<uint16_t> Uint16Params; typedef SingleValueTestParam<uint16_t> Uint16Params;
typedef SingleValueTestParam<int32_t> Int32Params; typedef SingleValueTestParam<int32_t> Int32Params;
typedef SingleValueTestParam<uint32_t> Uint32Params; typedef SingleValueTestParam<uint32_t> Uint32Params;
typedef SingleValueTestParam<int64_t> Int64Params; typedef SingleValueTestParamWithHostFormat<int64_t> Int64Params;
typedef SingleValueTestParam<uint64_t> Uint64Params; typedef SingleValueTestParamWithHostFormat<uint64_t> Uint64Params;
typedef SingleValueTestParam<float> FloatParams; typedef SingleValueTestParam<float> FloatParams;
typedef SingleValueTestParam<double> DoubleParams; typedef SingleValueTestParam<double> DoubleParams;
typedef SingleValueTestParam<std::string> StringParams; typedef SingleValueTestParam<std::string> StringParams;
@@ -271,6 +278,72 @@ INSTANTIATE_TEST_CASE_P(PrintfUint32Test,
PrintfUint32Test, PrintfUint32Test,
::testing::ValuesIn(uintValues)); ::testing::ValuesIn(uintValues));
Int64Params longValues[] = {
{"%lld", "%lld", INT64_MAX},
{"%ld", "%lld", INT64_MAX},
{"%ld", "%lld", INT64_MIN},
{"%lld", "%lld", INT64_MIN},
{"%llx", "%llx", INT64_MAX},
{"%lx", "%llx", INT64_MAX},
{"%lx", "%llx", INT64_MIN},
{"%llx", "%llx", INT64_MIN},
{"%d", "%d", INT32_MAX},
{"%x", "%x", INT32_MAX}};
class PrintfInt64Test : public PrintFormatterTest,
public ::testing::WithParamInterface<Int64Params> {};
TEST_P(PrintfInt64Test, GivenFormatContainingLongWhenPrintingThenValueIsInserted) {
auto input = GetParam();
auto stringIndex = injectFormatString(input.format);
storeData(stringIndex);
injectValue(input.value);
char referenceOutput[maxPrintfOutputLength];
char actualOutput[maxPrintfOutputLength];
printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength - 1); });
snprintf(referenceOutput, sizeof(referenceOutput), input.hostFormat.c_str(), input.value);
EXPECT_STREQ(referenceOutput, actualOutput);
}
INSTANTIATE_TEST_CASE_P(PrintfInt64Test,
PrintfInt64Test,
::testing::ValuesIn(longValues));
Uint64Params ulongValues[] = {
{"%llu", "%llu", UINT64_MAX},
{"%lu", "%llu", UINT64_MAX},
{"%llux", "%llux", UINT64_MAX},
{"%lux", "%llux", UINT64_MAX}};
class PrintfUint64Test : public PrintFormatterTest,
public ::testing::WithParamInterface<Uint64Params> {};
TEST_P(PrintfUint64Test, GivenFormatContainingUlongWhenPrintingThenValueIsInserted) {
auto input = GetParam();
auto stringIndex = injectFormatString(input.format);
storeData(stringIndex);
injectValue(input.value);
char referenceOutput[maxPrintfOutputLength];
char actualOutput[maxPrintfOutputLength];
printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength - 1); });
snprintf(referenceOutput, sizeof(referenceOutput), input.hostFormat.c_str(), input.value);
EXPECT_STREQ(referenceOutput, actualOutput);
}
INSTANTIATE_TEST_CASE_P(PrintfUint64Test,
PrintfUint64Test,
::testing::ValuesIn(ulongValues));
FloatParams floatValues[] = { FloatParams floatValues[] = {
{"%f", 10.3456f}, {"%f", 10.3456f},
{"%.1f", 10.3456f}, {"%.1f", 10.3456f},
@@ -719,21 +792,21 @@ TEST_F(PrintFormatterTest, GivenSpecialVectorWhenPrintingThenAllValuesAreInserte
TEST_F(PrintFormatterTest, GivenVectorOfLongsWhenPrintingThenAllValuesAreInserted) { TEST_F(PrintFormatterTest, GivenVectorOfLongsWhenPrintingThenAllValuesAreInserted) {
int channelCount = 2; int channelCount = 2;
auto stringIndex = injectFormatString("%v2lld"); auto stringIndex = injectFormatString("%v2ld");
storeData(stringIndex); storeData(stringIndex);
storeData(PRINTF_DATA_TYPE::VECTOR_LONG); storeData(PRINTF_DATA_TYPE::VECTOR_LONG);
// channel count // channel count
storeData(channelCount); storeData(channelCount);
storeData<int64_t>(1); storeData<int64_t>(100000000000000);
storeData<int64_t>(2); storeData<int64_t>(200000000000000);
char actualOutput[maxPrintfOutputLength]; char actualOutput[maxPrintfOutputLength];
printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength - 1); }); printFormatter->printKernelOutput([&actualOutput](char *str) { strncpy_s(actualOutput, maxPrintfOutputLength, str, maxPrintfOutputLength - 1); });
EXPECT_STREQ("1,2", actualOutput); EXPECT_STREQ("100000000000000,200000000000000", actualOutput);
} }
TEST_F(PrintFormatterTest, GivenVectorOfFloatsWhenPrintingThenAllValuesAreInserted) { TEST_F(PrintFormatterTest, GivenVectorOfFloatsWhenPrintingThenAllValuesAreInserted) {