[Openmp-commits] [openmp] [openmp] Add memory diff dump for kernel record-replay (PR #70667)

via Openmp-commits openmp-commits at lists.llvm.org
Mon Oct 30 08:05:02 PDT 2023


https://github.com/nmustakin created https://github.com/llvm/llvm-project/pull/70667

Dump memory diff instead of entire memory dump for openmp kernel record and replay. 
Diff outputs can be found in the .original.output for record and .replay.output for replay. 

Verification automatically compares the diff files. No change is required. 

>From 153c6d812939cd23bb71e53c71378117ed5b23c7 Mon Sep 17 00:00:00 2001
From: Nafis Mustakin <nmust004 at ucr.edu>
Date: Mon, 30 Oct 2023 07:50:59 -0700
Subject: [PATCH] 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());
 



More information about the Openmp-commits mailing list