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
This commit is contained in:
Vikram
2023-05-12 00:31:45 -04:00
förälder 2cda949920
incheckning 7b6a8f1702
5 ändrade filer med 223 tillägg och 11 borttagningar
+73
Visa fil
@@ -30,6 +30,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 pal {
PrintfDbg::PrintfDbg(Device& device, FILE* file)
@@ -599,6 +607,11 @@ bool PrintfDbgHSA::output(VirtualGPU& gpu, bool printfEnabled,
size_t bufSize = dev().xferRead().bufSize();
size_t copySize = offsetSize;
// Map between 64 bit MD5 format string hash and
// actual format string
std::map<uint64_t, std::string> StrMap;
while (copySize != 0) {
// Copy the buffer data (i.e., the printfID followed by the
// argument data for each printf call in th kernel) to the staged buffer
@@ -617,6 +630,66 @@ bool PrintfDbgHSA::output(VirtualGPU& gpu, bool printfEnabled,
uint sb = 0;
uint sbt = 0;
// Handle HIP nonhostcall printf here,
if (amd::IS_HIP) {
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 < copySize) {
auto controlDword = *BufferForHIP++;
uint64_t nextOffset = controlDword >> 2;
if (sbt + nextOffset > bufSize) {
break; // Need new portion of data in staging buffer
}
auto PB = (uint64_t*)BufferForHIP;
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;
}
copySize -= sbt;
xferBufRead_->unmap(&gpu);
continue;
}
// parse the debug buffer
while (sbt < copySize) {
if (*dbgBufferPtr >= printfInfo.size()) {