[compiler-rt] [flang] [libcxx] [clang] [openmp] [llvm] [clang-tools-extra] [lldb] [OpenMP] Add memory diff dump for kernel record-replay (PR #70667)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Nov 4 12:56:20 PDT 2023
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 <nmust004 at ucr.edu>
Date: Mon, 30 Oct 2023 07:50:59 -0700
Subject: [PATCH 1/5] 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 <nmust004 at ucr.edu>
Date: Mon, 30 Oct 2023 08:39:40 -0700
Subject: [PATCH 2/5] 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 <nmust004 at ucr.edu>
Date: Mon, 30 Oct 2023 10:34:32 -0700
Subject: [PATCH 3/5] 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 <nmust004 at ucr.edu>
Date: Wed, 1 Nov 2023 12:04:11 -0700
Subject: [PATCH 4/5] 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 <nmust004 at ucr.edu>
Date: Sat, 4 Nov 2023 12:50:59 -0700
Subject: [PATCH 5/5] 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();
}
More information about the cfe-commits
mailing list