https://github.com/nmustakin updated https://github.com/llvm/llvm-project/pull/70667
>From 153c6d812939cd23bb71e53c71378117ed5b23c7 Mon Sep 17 00:00:00 2001 From: Nafis Mustakin <nmust...@ucr.edu> Date: Mon, 30 Oct 2023 07:50:59 -0700 Subject: [PATCH 1/6] Add memory diff dump for kernel record-replay --- .../PluginInterface/PluginInterface.cpp | 65 +++++++++++++++---- 1 file changed, 54 insertions(+), 11 deletions(-) diff --git a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp index 0243f0205dbf0e5..8469e8eaf1593cd 100644 --- a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp +++ b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp @@ -83,7 +83,7 @@ struct RecordReplayTy { return Plugin::success(); } - void dumpDeviceMemory(StringRef Filename) { + void dumpDeviceMemory(StringRef Filename, bool saveDiff) { ErrorOr<std::unique_ptr<WritableMemoryBuffer>> DeviceMemoryMB = WritableMemoryBuffer::getNewUninitMemBuffer(MemorySize); if (!DeviceMemoryMB) @@ -93,15 +93,58 @@ struct RecordReplayTy { MemoryStart, MemorySize, nullptr); if (Err) report_fatal_error("Error retrieving data for target pointer"); - - StringRef DeviceMemory(DeviceMemoryMB.get()->getBufferStart(), MemorySize); - std::error_code EC; - raw_fd_ostream OS(Filename, EC); - if (EC) + + std::error_code EC; + raw_fd_ostream OS(Filename, EC); + if(EC) report_fatal_error("Error dumping memory to file " + Filename + " :" + EC.message()); - OS << DeviceMemory; - OS.close(); + + if (saveDiff){ + //Get the pre-record memory filename + SmallString<128> InputFilename = {Filename.split('.').first, ".memory"}; + //read the pre-record memorydump + auto InputFileBuffer = MemoryBuffer::getFileOrSTDIN(InputFilename); + if(std::error_code EC = InputFileBuffer.getError()) + report_fatal_error("Error reading pre-record device memory"); + + StringRef InputBufferContents = (*InputFileBuffer)->getBuffer(); + if(InputBufferContents.size() != MemorySize) + report_fatal_error("Error: Pre-record device memory size mismatch"); + + //get current memory contents + StringRef DeviceMemoryContents(DeviceMemoryMB.get()->getBuffer().data(), + DeviceMemoryMB.get()->getBuffer().size()); + + //compare pre-record memorydump to current contents + size_t i = 0; + while(i < MemorySize){ + //if mismatch found, create a new diff line + //current format - location, size, differences ... + if(InputBufferContents[i] != DeviceMemoryContents[i]){ + OS << i << " "; //marks the start offset + SmallVector<uint8_t, 128> modified; + modified.push_back(DeviceMemoryContents[i]); + size_t j = 1; + //loop until next match is found + while(InputBufferContents[i+j] != DeviceMemoryContents[i+j]){ + modified.push_back(DeviceMemoryContents[i+j]); + j++; + } + OS << j << " "; //marks the length of the mismatching sequence + for(const auto &value : modified) + OS << value << " "; + OS << "\n"; + i+=j+1; + } + else i++; + } + } + else { + StringRef DeviceMemory(DeviceMemoryMB.get()->getBufferStart(), MemorySize); + OS << DeviceMemory; + } + OS.close(); } public: @@ -209,7 +252,7 @@ struct RecordReplayTy { JsonKernelInfo["ArgOffsets"] = json::Value(std::move(JsonArgOffsets)); SmallString<128> MemoryFilename = {Name, ".memory"}; - dumpDeviceMemory(MemoryFilename); + dumpDeviceMemory(MemoryFilename, false); SmallString<128> GlobalsFilename = {Name, ".globals"}; dumpGlobals(GlobalsFilename, Image); @@ -227,7 +270,7 @@ struct RecordReplayTy { void saveKernelOutputInfo(const char *Name) { SmallString<128> OutputFilename = { Name, (isRecording() ? ".original.output" : ".replay.output")}; - dumpDeviceMemory(OutputFilename); + dumpDeviceMemory(OutputFilename, true); } void *alloc(uint64_t Size) { @@ -1307,7 +1350,7 @@ Error GenericDeviceTy::launchKernel(void *EntryPtr, void **ArgPtrs, GenericKernel.getName(), GenericKernel.getImage(), ArgPtrs, ArgOffsets, KernelArgs.NumArgs, KernelArgs.NumTeams[0], KernelArgs.ThreadLimit[0], KernelArgs.Tripcount); - + if (RecordReplay.isRecording()) RecordReplay.saveImage(GenericKernel.getName(), GenericKernel.getImage()); >From 8daffad57074dd09287d321acd79c74a667eb65f Mon Sep 17 00:00:00 2001 From: Nafis Mustakin <nmust...@ucr.edu> Date: Mon, 30 Oct 2023 08:39:40 -0700 Subject: [PATCH 2/6] Fix clang-formatting issues, accept reviewed suggestions --- .../PluginInterface/PluginInterface.cpp | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp index ae279d436646d9d..745dacbe361afd3 100644 --- a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp +++ b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp @@ -140,58 +140,58 @@ struct RecordReplayTy { MemoryStart, MemorySize, nullptr); if (Err) report_fatal_error("Error retrieving data for target pointer"); - - std::error_code EC; - raw_fd_ostream OS(Filename, EC); - if(EC) + + std::error_code EC; + raw_fd_ostream OS(Filename, EC); + if (EC) report_fatal_error("Error dumping memory to file " + Filename + " :" + EC.message()); - - if (saveDiff){ - //Get the pre-record memory filename + + if (saveDiff) { + // Get the pre-record memory filename SmallString<128> InputFilename = {Filename.split('.').first, ".memory"}; - //read the pre-record memorydump - auto InputFileBuffer = MemoryBuffer::getFileOrSTDIN(InputFilename); - if(std::error_code EC = InputFileBuffer.getError()) + // read the pre-record memorydump + auto InputFileBuffer = MemoryBuffer::getFileOrSTDIN(InputFilename); + if (std::error_code EC = InputFileBuffer.getError()) report_fatal_error("Error reading pre-record device memory"); - - StringRef InputBufferContents = (*InputFileBuffer)->getBuffer(); - if(InputBufferContents.size() != MemorySize) + + StringRef InputBufferContents = (*InputFileBuffer)->getBuffer(); + if (InputBufferContents.size() != MemorySize) report_fatal_error("Error: Pre-record device memory size mismatch"); - - //get current memory contents + + // get current memory contents StringRef DeviceMemoryContents(DeviceMemoryMB.get()->getBuffer().data(), DeviceMemoryMB.get()->getBuffer().size()); - - //compare pre-record memorydump to current contents + + // compare pre-record memorydump to current contents size_t i = 0; - while(i < MemorySize){ - //if mismatch found, create a new diff line - //current format - location, size, differences ... - if(InputBufferContents[i] != DeviceMemoryContents[i]){ - OS << i << " "; //marks the start offset - SmallVector<uint8_t, 128> modified; + while (i < MemorySize) { + // if mismatch found, create a new diff line + // current format - location, size, differences ... + if (InputBufferContents[i] != DeviceMemoryContents[i]) { + OS << i << " "; // marks the start offset + SmallVector<uint8_t, 128> modified; modified.push_back(DeviceMemoryContents[i]); size_t j = 1; - //loop until next match is found - while(InputBufferContents[i+j] != DeviceMemoryContents[i+j]){ - modified.push_back(DeviceMemoryContents[i+j]); + // loop until next match is found + while (InputBufferContents[i + j] != DeviceMemoryContents[i + j]) { + modified.push_back(DeviceMemoryContents[i + j]); j++; } - OS << j << " "; //marks the length of the mismatching sequence - for(const auto &value : modified) + OS << j << " "; // marks the length of the mismatching sequence + for (const auto &value : modified) OS << value << " "; - OS << "\n"; - i+=j+1; - } - else i++; + OS << "\n"; + i += j + 1; + } else + i++; } - } - else { - StringRef DeviceMemory(DeviceMemoryMB.get()->getBufferStart(), MemorySize); + } else { + StringRef DeviceMemory(DeviceMemoryMB.get()->getBufferStart(), + MemorySize); OS << DeviceMemory; } - OS.close(); + OS.close(); } public: @@ -299,7 +299,7 @@ struct RecordReplayTy { JsonKernelInfo["ArgOffsets"] = json::Value(std::move(JsonArgOffsets)); SmallString<128> MemoryFilename = {Name, ".memory"}; - dumpDeviceMemory(MemoryFilename, false); + dumpDeviceMemory(MemoryFilename, /*saveDiff*/false); SmallString<128> GlobalsFilename = {Name, ".globals"}; dumpGlobals(GlobalsFilename, Image); @@ -317,7 +317,7 @@ struct RecordReplayTy { void saveKernelOutputInfo(const char *Name) { SmallString<128> OutputFilename = { Name, (isRecording() ? ".original.output" : ".replay.output")}; - dumpDeviceMemory(OutputFilename, true); + dumpDeviceMemory(OutputFilename, /*saveDiff*/true); } void *alloc(uint64_t Size) { @@ -1396,7 +1396,7 @@ Error GenericDeviceTy::launchKernel(void *EntryPtr, void **ArgPtrs, GenericKernel.getName(), GenericKernel.getImage(), ArgPtrs, ArgOffsets, KernelArgs.NumArgs, KernelArgs.NumTeams[0], KernelArgs.ThreadLimit[0], KernelArgs.Tripcount); - + if (RecordReplay.isRecording()) RecordReplay.saveImage(GenericKernel.getName(), GenericKernel.getImage()); >From 20a92632761639afd95496d2012c5cf8471d622e Mon Sep 17 00:00:00 2001 From: Nafis Mustakin <nmust...@ucr.edu> Date: Mon, 30 Oct 2023 10:34:32 -0700 Subject: [PATCH 3/6] Fix formatting issues --- .../common/PluginInterface/PluginInterface.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp index 745dacbe361afd3..2a7f354a2d5b030 100644 --- a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp +++ b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp @@ -118,7 +118,7 @@ struct RecordReplayTy { return Plugin::success(); } - + Error preallocateDeviceMemory(uint64_t DeviceMemorySize, void *ReqVAddr) { if (Device->supportVAManagement()) return preAllocateVAMemory(DeviceMemorySize, ReqVAddr); @@ -299,7 +299,7 @@ struct RecordReplayTy { JsonKernelInfo["ArgOffsets"] = json::Value(std::move(JsonArgOffsets)); SmallString<128> MemoryFilename = {Name, ".memory"}; - dumpDeviceMemory(MemoryFilename, /*saveDiff*/false); + dumpDeviceMemory(MemoryFilename, /*saveDiff*/ false); SmallString<128> GlobalsFilename = {Name, ".globals"}; dumpGlobals(GlobalsFilename, Image); @@ -317,7 +317,7 @@ struct RecordReplayTy { void saveKernelOutputInfo(const char *Name) { SmallString<128> OutputFilename = { Name, (isRecording() ? ".original.output" : ".replay.output")}; - dumpDeviceMemory(OutputFilename, /*saveDiff*/true); + dumpDeviceMemory(OutputFilename, /*saveDiff*/ true); } void *alloc(uint64_t Size) { >From 6eb4f55c875e1ba8fc0aa0235eddd52ed074976d Mon Sep 17 00:00:00 2001 From: Nafis Mustakin <nmust...@ucr.edu> Date: Wed, 1 Nov 2023 12:04:11 -0700 Subject: [PATCH 4/6] Refactor memory diff code to dumpDeviceMemoryDiff --- .../PluginInterface/PluginInterface.cpp | 115 +++++++++++------- 1 file changed, 70 insertions(+), 45 deletions(-) diff --git a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp index 2a7f354a2d5b030..120244ed44b7e8e 100644 --- a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp +++ b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp @@ -130,7 +130,7 @@ struct RecordReplayTy { return preAllocateHeuristic(DevMemSize, ReqVAddr); } - void dumpDeviceMemory(StringRef Filename, bool saveDiff) { + void dumpDeviceMemory(StringRef Filename) { ErrorOr<std::unique_ptr<WritableMemoryBuffer>> DeviceMemoryMB = WritableMemoryBuffer::getNewUninitMemBuffer(MemorySize); if (!DeviceMemoryMB) @@ -141,55 +141,80 @@ struct RecordReplayTy { if (Err) report_fatal_error("Error retrieving data for target pointer"); + StringRef DeviceMemory(DeviceMemoryMB.get()->getBufferStart(), MemorySize); std::error_code EC; raw_fd_ostream OS(Filename, EC); if (EC) report_fatal_error("Error dumping memory to file " + Filename + " :" + EC.message()); + OS << DeviceMemory; + OS.close(); + } + + void dumpDeviceMemoryDiff(StringRef Filename) { + ErrorOr<std::unique_ptr<WritableMemoryBuffer>> DeviceMemoryMB = + WritableMemoryBuffer::getNewUninitMemBuffer(MemorySize); + if (!DeviceMemoryMB) + report_fatal_error("Error creating MemoryBuffer for device memory"); + + auto Err = Device->dataRetrieve(DeviceMemoryMB.get()->getBufferStart(), + MemoryStart, MemorySize, nullptr); + if (Err) + report_fatal_error("Error retrieving data for target pointer"); + + // Get the pre-record memory filename + SmallString<128> InputFilename = {Filename.split('.').first, ".memory"}; + + // Read the pre-record memorydump + auto InputFileBuffer = MemoryBuffer::getFileOrSTDIN(InputFilename); + if (std::error_code EC = InputFileBuffer.getError()) + report_fatal_error("Error reading pre-record device memory"); + + StringRef InputBufferContents = (*InputFileBuffer)->getBuffer(); + if (InputBufferContents.size() != MemorySize) + report_fatal_error("Error: Pre-record device memory size mismatch"); - if (saveDiff) { - // Get the pre-record memory filename - SmallString<128> InputFilename = {Filename.split('.').first, ".memory"}; - // read the pre-record memorydump - auto InputFileBuffer = MemoryBuffer::getFileOrSTDIN(InputFilename); - if (std::error_code EC = InputFileBuffer.getError()) - report_fatal_error("Error reading pre-record device memory"); - - StringRef InputBufferContents = (*InputFileBuffer)->getBuffer(); - if (InputBufferContents.size() != MemorySize) - report_fatal_error("Error: Pre-record device memory size mismatch"); - - // get current memory contents - StringRef DeviceMemoryContents(DeviceMemoryMB.get()->getBuffer().data(), - DeviceMemoryMB.get()->getBuffer().size()); - - // compare pre-record memorydump to current contents - size_t i = 0; - while (i < MemorySize) { - // if mismatch found, create a new diff line - // current format - location, size, differences ... - if (InputBufferContents[i] != DeviceMemoryContents[i]) { - OS << i << " "; // marks the start offset - SmallVector<uint8_t, 128> modified; - modified.push_back(DeviceMemoryContents[i]); - size_t j = 1; - // loop until next match is found - while (InputBufferContents[i + j] != DeviceMemoryContents[i + j]) { - modified.push_back(DeviceMemoryContents[i + j]); - j++; - } - OS << j << " "; // marks the length of the mismatching sequence - for (const auto &value : modified) - OS << value << " "; - OS << "\n"; - i += j + 1; - } else - i++; + std::error_code EC; + raw_fd_ostream OS(Filename, EC); + if (EC) + report_fatal_error("Error dumping memory to file " + Filename + " :" + + EC.message()); + + // Get current memory contents + StringRef DeviceMemoryContents(DeviceMemoryMB.get()->getBuffer().data(), + DeviceMemoryMB.get()->getBuffer().size()); + + for (size_t I = 0; I < MemorySize; ++I) { + // If buffers are same, continue + if (InputBufferContents[I] == DeviceMemoryContents[I]) + continue; + + // If mismatch is found create a new diff line + // Current format: location, size, differences + OS << I << " "; // Marks the start offset + + SmallVector<uint8_t, 128> Modified; + Modified.push_back(DeviceMemoryContents[I]); + + size_t J; // Length of current diff line + // Loop until next match is found + for (J = 1; J < MemorySize - I; ++J) { + // If no more mismatch, break out of the loop + if (InputBufferContents[I + J] == DeviceMemoryContents[I + J]) + break; + + // If mismatch continues - push diff to Modified + Modified.push_back(DeviceMemoryContents[I + J]); } - } else { - StringRef DeviceMemory(DeviceMemoryMB.get()->getBufferStart(), - MemorySize); - OS << DeviceMemory; + + OS << J << " "; // Marks the length of the mismatching sequence + for (const auto &value : Modified) + OS << value << " "; + OS << "\n"; + + // Increment I by J to skip ahead to next + // matching sequence in the buffer + I += J; } OS.close(); } @@ -299,7 +324,7 @@ struct RecordReplayTy { JsonKernelInfo["ArgOffsets"] = json::Value(std::move(JsonArgOffsets)); SmallString<128> MemoryFilename = {Name, ".memory"}; - dumpDeviceMemory(MemoryFilename, /*saveDiff*/ false); + dumpDeviceMemory(MemoryFilename); SmallString<128> GlobalsFilename = {Name, ".globals"}; dumpGlobals(GlobalsFilename, Image); @@ -317,7 +342,7 @@ struct RecordReplayTy { void saveKernelOutputInfo(const char *Name) { SmallString<128> OutputFilename = { Name, (isRecording() ? ".original.output" : ".replay.output")}; - dumpDeviceMemory(OutputFilename, /*saveDiff*/ true); + dumpDeviceMemoryDiff(OutputFilename); } void *alloc(uint64_t Size) { >From 09ab2681e3687723898a3dd7cbed2b5f5ecf126d Mon Sep 17 00:00:00 2001 From: Nafis Mustakin <nmust...@ucr.edu> Date: Sat, 4 Nov 2023 12:50:59 -0700 Subject: [PATCH 5/6] Simplify Diff logic --- .../PluginInterface/PluginInterface.cpp | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp index 120244ed44b7e8e..22e8a6f70d03ec7 100644 --- a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp +++ b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp @@ -184,37 +184,31 @@ struct RecordReplayTy { StringRef DeviceMemoryContents(DeviceMemoryMB.get()->getBuffer().data(), DeviceMemoryMB.get()->getBuffer().size()); + // Loop over all memory locations + // If mismatch is found create a new diff line + // Diff format: location, size, differences for (size_t I = 0; I < MemorySize; ++I) { // If buffers are same, continue if (InputBufferContents[I] == DeviceMemoryContents[I]) continue; - // If mismatch is found create a new diff line - // Current format: location, size, differences OS << I << " "; // Marks the start offset SmallVector<uint8_t, 128> Modified; Modified.push_back(DeviceMemoryContents[I]); - size_t J; // Length of current diff line - // Loop until next match is found - for (J = 1; J < MemorySize - I; ++J) { + for (I += 1; I < MemorySize; ++I) { // If no more mismatch, break out of the loop - if (InputBufferContents[I + J] == DeviceMemoryContents[I + J]) + if (InputBufferContents[I] == DeviceMemoryContents[I]) break; - // If mismatch continues - push diff to Modified - Modified.push_back(DeviceMemoryContents[I + J]); + Modified.push_back(DeviceMemoryContents[I]); } - - OS << J << " "; // Marks the length of the mismatching sequence - for (const auto &value : Modified) - OS << value << " "; + OS << Modified.size() + << " "; // Marks the length of the mismatching sequence + for (const auto &Value : Modified) + OS << Value << " "; OS << "\n"; - - // Increment I by J to skip ahead to next - // matching sequence in the buffer - I += J; } OS.close(); } >From 121271deb2d7d6416b336a43b6b52e2d1d8c7d57 Mon Sep 17 00:00:00 2001 From: Nafis Mustakin <nmust...@ucr.edu> Date: Tue, 7 Nov 2023 09:52:39 -0800 Subject: [PATCH 6/6] Fix comment format --- .../PluginInterface/PluginInterface.cpp | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp index 22e8a6f70d03ec7..f9d1b51e40a8fe0 100644 --- a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp +++ b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp @@ -162,10 +162,10 @@ struct RecordReplayTy { if (Err) report_fatal_error("Error retrieving data for target pointer"); - // Get the pre-record memory filename + // Get the pre-record memory filename. SmallString<128> InputFilename = {Filename.split('.').first, ".memory"}; - // Read the pre-record memorydump + // Read the pre-record memorydump. auto InputFileBuffer = MemoryBuffer::getFileOrSTDIN(InputFilename); if (std::error_code EC = InputFileBuffer.getError()) report_fatal_error("Error reading pre-record device memory"); @@ -180,32 +180,33 @@ struct RecordReplayTy { report_fatal_error("Error dumping memory to file " + Filename + " :" + EC.message()); - // Get current memory contents + // Get current memory contents. StringRef DeviceMemoryContents(DeviceMemoryMB.get()->getBuffer().data(), DeviceMemoryMB.get()->getBuffer().size()); - // Loop over all memory locations - // If mismatch is found create a new diff line - // Diff format: location, size, differences + // Loop over all memory locations. + // If mismatch is found, create a new diff line. + // Diff format: location, size, differences. for (size_t I = 0; I < MemorySize; ++I) { // If buffers are same, continue if (InputBufferContents[I] == DeviceMemoryContents[I]) continue; - OS << I << " "; // Marks the start offset + // Mark the start offset + OS << I << " "; SmallVector<uint8_t, 128> Modified; Modified.push_back(DeviceMemoryContents[I]); for (I += 1; I < MemorySize; ++I) { - // If no more mismatch, break out of the loop + // If no more mismatch is found, break out of the loop. if (InputBufferContents[I] == DeviceMemoryContents[I]) break; - // If mismatch continues - push diff to Modified + // If mismatch continues - push diff to Modified. Modified.push_back(DeviceMemoryContents[I]); } - OS << Modified.size() - << " "; // Marks the length of the mismatching sequence + // Mark the length of the mismatching sequence. + OS << Modified.size() << " "; for (const auto &Value : Modified) OS << Value << " "; OS << "\n"; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits