SWDEV-354050 - Runtime support for HIP non hostcall printf

Relates to https://reviews.llvm.org/D150427,

Each printf call populates buffer with following data
1. Control DWord - contains info regarding stream, format string constness and size of data frame
   (see http://gerrit-git.amd.com/c/lightning/ec/device-libs/+/857722 for more info)
2. Hash of the format string (if constant) else the format string itself
3. Printf arguments (each aligned to 8 byte boundary)

Change-Id: I7e320deb343921b4b4cfaf08a2be2883e0bc1f65


[ROCm/clr commit: 7b6a8f1702]
Este commit está contenido en:
Vikram
2023-05-12 00:31:45 -04:00
padre b1266e557e
commit 5ba0fb5802
Se han modificado 5 ficheros con 223 adiciones y 11 borrados
@@ -31,6 +31,14 @@
#include <algorithm>
#include <cmath>
// Functions defined in devhcprintf.cpp
namespace amd {
void handlePrintfDelayed(const uint64_t *input, uint64_t len, uint64_t control);
bool populateFormatStringHashMap(
const std::vector<device::PrintfInfo> &printfInfo,
std::map<uint64_t, std::string> &strMap);
} // namespace amd
namespace roc {
PrintfDbg::PrintfDbg(Device& device, FILE* file)
@@ -435,6 +443,67 @@ bool PrintfDbg::output(VirtualGPU& gpu, bool printfEnabled,
uint sb = 0;
uint sbt = 0;
// Handle HIP nonhostcall printf here, However longterm goal
// should be to have common implementation for both HIP and OpenCL
if (amd::IS_HIP) {
// Map between 64 bit MD5 format string hash and
// actual format string
std::map<uint64_t, std::string> StrMap;
auto BufferForHIP = reinterpret_cast<uint32_t*>(dbgBufferPtr);
// Populate string map with hashes and actual
// format strings.
if(!amd::populateFormatStringHashMap(printfInfo, StrMap))
return false;
while (sbt < offsetSize)
{
auto controlDword = *BufferForHIP++;
auto PB = (uint64_t*)BufferForHIP;
uint64_t nextOffset = controlDword >> 2;
std::vector<uint8_t> PBuffer;
uint64_t BufferLen = 0;
if (controlDword & 2U) {
// Process the contsant format string case.
// The first value is the 64 bit format string hash
// and remaining values are printf arguments.
// Construct a temporary buffer with actual format
// string followed by arguments. The format string is
// obtained by querying StrMap populated before.
auto ArgsLen = nextOffset - 12;
auto Str = StrMap[*PB++];
auto StrLenWithNull = Str.size() + 1;
BufferLen = ArgsLen + amd::alignUp(StrLenWithNull, sizeof(uint64_t));
PBuffer.resize(BufferLen);
memcpy(PBuffer.data(), Str.c_str(), StrLenWithNull);
memset(PBuffer.data() + Str.size(), 0, 8 - (StrLenWithNull % 8 ));
memcpy(PBuffer.data() + amd::alignUp(StrLenWithNull, sizeof(uint64_t)),
PB, ArgsLen);
}
else {
// Process Non constant format string case.
// Here, The buffer itself contains the actual
// format string and hence just copy the contents
// of format string and arguments into a temporary
// buffer
BufferLen = nextOffset - /*ControlDWord*/4;
PBuffer.resize(BufferLen);
memcpy(PBuffer.data(), BufferForHIP, nextOffset);
}
// Handle printing
amd::handlePrintfDelayed((uint64_t*)PBuffer.data(), BufferLen / 8,
controlDword);
BufferForHIP += (nextOffset / 4) - /*ControlDWord*/1;
sbt += nextOffset;
}
return true;
}
// parse the debug buffer
while (sbt < offsetSize) {
if (*dbgBufferPtr >= printfInfo.size()) {