From 41f91c6be0ecba862f32d065864e4e6383620032 Mon Sep 17 00:00:00 2001 From: vikhegde Date: Thu, 17 Jul 2025 20:30:52 +0530 Subject: [PATCH] SWDEV-516613 - Fixes for OpenCL printf conformance test failures --- rocclr/device/pal/palprintf.cpp | 28 +++++++++++++++------------- rocclr/device/rocm/rocprintf.cpp | 31 +++++++++++++++++-------------- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/rocclr/device/pal/palprintf.cpp b/rocclr/device/pal/palprintf.cpp index 1acd71061e..2e21cccfb7 100644 --- a/rocclr/device/pal/palprintf.cpp +++ b/rocclr/device/pal/palprintf.cpp @@ -212,6 +212,10 @@ int PrintfDbg::checkVectorSpecifier(const std::string& fmt, size_t startPos, siz else if ((curPos >= 5) && (fmt[curPos - 5] == 'v')) { size = 4; } + // modifier is "hh" or "hl" with vec size 16 + else if ((curPos >= 6) && (fmt[curPos - 6] == 'v')) { + size = 5; + } if (size > 0) { curPos = size; pos -= curPos; @@ -255,11 +259,9 @@ size_t PrintfDbg::outputArgument(const std::string& fmt, bool printFloat, size_t if (checkString(fmt.c_str())) { // copiedBytes should be as number of printed chars copiedBytes = 0; - //(null) should be printed if (*(reinterpret_cast(argument)) == 0) { - amd::Os::printf(fmt.data(), 0); - // copiedBytes = strlen("(null)") - copiedBytes = 6; + // accounts for null character + copiedBytes = 1; } else { const unsigned char* argumentStr = reinterpret_cast(argument); amd::Os::printf(fmt.data(), argumentStr); @@ -294,7 +296,7 @@ size_t PrintfDbg::outputArgument(const std::string& fmt, bool printFloat, size_t const float fArg = size == 2 ? amd::half2float(*(reinterpret_cast(argument))) : *(reinterpret_cast(argument)); - static const char* fSpecifiers = "eEfgGa"; + static const char* fSpecifiers = "eEfFgGaA"; std::string fmtF = fmt; size_t posS = fmtF.find_first_of("%"); size_t posE = fmtF.find_first_of(fSpecifiers); @@ -322,13 +324,7 @@ size_t PrintfDbg::outputArgument(const std::string& fmt, bool printFloat, size_t } else { bool hhModifier = (strstr(fmt.c_str(), "hh") != nullptr); if (hhModifier) { - // current implementation of printf in gcc 4.5.2 runtime libraries, doesn`t recognize - // "hh" modifier ==> - // argument should be explicitly converted to unsigned char (uchar) before printing and - // fmt should be updated not to contain "hh" modifier - std::string hhFmt = fmt; - hhFmt.erase(hhFmt.find_first_of("h"), 2); - amd::Os::printf(hhFmt.data(), *(reinterpret_cast(argument))); + amd::Os::printf(fmt.data(), *(reinterpret_cast(argument))); } else if (hlModifier) { amd::Os::printf(hlFmt.data(), size == 2 ? *(reinterpret_cast(argument)): @@ -370,7 +366,7 @@ size_t PrintfDbg::outputArgument(const std::string& fmt, bool printFloat, size_t void PrintfDbg::outputDbgBuffer(const device::PrintfInfo& info, const uint32_t* workitemData, size_t& i) const { - static const char* specifiers = "cdieEfgGaosuxXp"; + static const char* specifiers = "cdieEfFgGaAosuxXp"; static const char* modifiers = "hl"; static const char* special = "%n"; static const std::string sepStr = "%s"; @@ -485,8 +481,14 @@ void PrintfDbg::outputDbgBuffer(const device::PrintfInfo& info, const uint32_t* } } + // handle '%%' escapes if (pos != std::string::npos) { fmt = str.substr(pos, str.size() - pos); + size_t P = fmt.find("%%"); + while (P != std::string::npos) { + fmt.replace(P, 2, "%"); + P = fmt.find("%%", P); + } outputArgument(sepStr, false, ConstStr, fmt.data()); } } diff --git a/rocclr/device/rocm/rocprintf.cpp b/rocclr/device/rocm/rocprintf.cpp index b9dc820f98..7bae3907ba 100644 --- a/rocclr/device/rocm/rocprintf.cpp +++ b/rocclr/device/rocm/rocprintf.cpp @@ -66,9 +66,11 @@ bool PrintfDbg::checkFloat(const std::string& fmt) const { case 'e': case 'E': case 'f': + case 'F': case 'g': case 'G': case 'a': + case 'A': return true; break; default: @@ -101,6 +103,10 @@ int PrintfDbg::checkVectorSpecifier(const std::string& fmt, size_t startPos, siz else if ((curPos >= 5) && (fmt[curPos - 5] == 'v')) { size = 4; } + // modifier is "hh" or "hl" with vec size 16 + else if ((curPos >= 6) && (fmt[curPos - 6] == 'v')) { + size = 5; + } if (size > 0) { curPos = size; pos -= curPos; @@ -143,11 +149,9 @@ size_t PrintfDbg::outputArgument(const std::string& fmt, bool printFloat, size_t if (checkString(fmt.c_str())) { // copiedBytes should be as number of printed chars copiedBytes = 0; - //(null) should be printed if (*(reinterpret_cast(argument)) == 0) { - amd::Os::printf(fmt.data(), 0); - // copiedBytes = strlen("(null)") - copiedBytes = 6; + // accounts for null character + copiedBytes = 1; } else { const unsigned char* argumentStr = reinterpret_cast(argument); amd::Os::printf(fmt.data(), argumentStr); @@ -182,7 +186,7 @@ size_t PrintfDbg::outputArgument(const std::string& fmt, bool printFloat, size_t const float fArg = size == 2 ? amd::half2float(*(reinterpret_cast(argument))) : *(reinterpret_cast(argument)); - static const char* fSpecifiers = "eEfgGa"; + static const char* fSpecifiers = "eEfFgGaA"; std::string fmtF = fmt; size_t posS = fmtF.find_first_of("%"); size_t posE = fmtF.find_first_of(fSpecifiers); @@ -210,14 +214,7 @@ size_t PrintfDbg::outputArgument(const std::string& fmt, bool printFloat, size_t } else { bool hhModifier = (strstr(fmt.c_str(), "hh") != nullptr); if (hhModifier) { - // current implementation of printf in gcc 4.5.2 runtime libraries, - // doesn`t recognize "hh" modifier ==> - // argument should be explicitly converted to unsigned char (uchar) - // before printing and - // fmt should be updated not to contain "hh" modifier - std::string hhFmt = fmt; - hhFmt.erase(hhFmt.find_first_of("h"), 2); - amd::Os::printf(hhFmt.data(), *(reinterpret_cast(argument))); + amd::Os::printf(fmt.data(), *(reinterpret_cast(argument))); } else if (hlModifier) { amd::Os::printf(hlFmt.data(), size == 2 ? *(reinterpret_cast(argument)): @@ -259,7 +256,7 @@ size_t PrintfDbg::outputArgument(const std::string& fmt, bool printFloat, size_t void PrintfDbg::outputDbgBuffer(const device::PrintfInfo& info, const uint32_t* workitemData, size_t& i) const { - static const char* specifiers = "cdieEfgGaosuxXp"; + static const char* specifiers = "cdieEfFgGaAosuxXp"; static const char* modifiers = "hl"; static const char* special = "%n"; static const std::string sepStr = "%s"; @@ -384,8 +381,14 @@ void PrintfDbg::outputDbgBuffer(const device::PrintfInfo& info, const uint32_t* } } + // handle '%%' escapes if (pos != std::string::npos) { fmt = str.substr(pos, str.size() - pos); + size_t P = fmt.find("%%", P); + while (P != std::string::npos) { + fmt.replace(P, 2, "%"); + P = fmt.find("%%", P); + } outputArgument(sepStr, false, ConstStr, reinterpret_cast(fmt.data())); } }