Skip to content

Commit

Permalink
Merge pull request #265 from FJShen/compressed_trace_2
Browse files Browse the repository at this point in the history
Support for xz-compressed traces
  • Loading branch information
JRPan authored Jan 24, 2024
2 parents 86f4430 + a066be6 commit c1a12bc
Show file tree
Hide file tree
Showing 5 changed files with 304 additions and 59 deletions.
72 changes: 63 additions & 9 deletions gpu-simulator/trace-parser/trace_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#include <string>
#include <vector>

#include <errno.h>
#include <unistd.h>
#include <signal.h>

#include "trace_parser.h"

bool is_number(const std::string &s) {
Expand Down Expand Up @@ -280,19 +284,65 @@ kernel_trace_t *trace_parser::parse_kernel_info(
const std::string &kerneltraces_filepath) {
kernel_trace_t *kernel_info = new kernel_trace_t;
kernel_info->enable_lineinfo = 0; // default disabled
kernel_info->ifs = new std::ifstream;
std::ifstream *ifs = kernel_info->ifs;
ifs->open(kerneltraces_filepath.c_str());

if (!ifs->is_open()) {
std::cout << "Unable to open file: " << kerneltraces_filepath << std::endl;
std::string read_trace_cmd;
int _l = kerneltraces_filepath.length();
if(_l > 3 && kerneltraces_filepath.substr(_l-3, 3) == ".xz"){
// this is xz-compressed trace
read_trace_cmd = "xz -dc " + kerneltraces_filepath;
} else if(_l > 7 && kerneltraces_filepath.substr(_l-7, 7) == ".traceg"){
// this is plain text trace
read_trace_cmd ="cat " + kerneltraces_filepath;
} else {
std::cerr << "Can't read trace. Only .xz and plain text are supported: "
<< kerneltraces_filepath <<"\n";
exit(1);
}

// Create an interprocess channel, and fork out a data source process. The
// data source process reads trace from disk, write to the channel, and the
// simulator process read from the channel.
int *pipefd = kernel_info->pipefd;
if(pipe(pipefd) != 0){
std::cerr << "Failed to create interprocess channel\n";
perror("pipe");
exit(1);
}

pid_t pid = fork();
if(pid == 0){
// The child process is the data source. Redirect its
// stdout to the write end of the pipe.
close(pipefd[0]);
dup2(pipefd[1], STDOUT_FILENO);

// When using GDB, sending Ctrl+C to the simulator will send a SIGINT signal
// to the child process as well, subsequently causing it to terminate. To
// avoid this, we let the child process ignore (SIG_IGN) the SIGINT signal.
// Reference:
// https://stackoverflow.com/questions/38404925/gdb-interrupt-running-process-without-killing-child-processes
signal(SIGINT, SIG_IGN);

execle("/bin/sh", "sh", "-c", read_trace_cmd.c_str(), NULL, environ);
perror("execle"); // the child process shouldn't reach here if all is well.
exit(1);
} else {
// parent (simulator)
close(pipefd[1]);
dup2(pipefd[0], STDIN_FILENO);
}

// Parent continues from here.
kernel_info->ifs = &std::cin;
std::istream *ifs = kernel_info->ifs;

std::cout << "Processing kernel " << kerneltraces_filepath << std::endl;

std::string line;

// Important to clear the istream. Otherwise, the eofbit from the last
// kernel may be carried over to this kernel
ifs->clear();
while (!ifs->eof()) {
getline(*ifs, line);

Expand Down Expand Up @@ -362,15 +412,19 @@ kernel_trace_t *trace_parser::parse_kernel_info(

void trace_parser::kernel_finalizer(kernel_trace_t *trace_info) {
assert(trace_info);
assert(trace_info->ifs);
if (trace_info->ifs->is_open()) trace_info->ifs->close();
delete trace_info->ifs;

// The pipe read/write end file descriptors held by the child process would
// have been automatically closed when it terminated. But the parent
// process may read an arbitrary amount of trace files, so it has to close
// all file descriptors.
close(trace_info->pipefd[0]);
close(trace_info->pipefd[1]);
delete trace_info;
}

void trace_parser::get_next_threadblock_traces(
std::vector<std::vector<inst_trace_t> *> threadblock_traces,
unsigned trace_version, unsigned enable_lineinfo, std::ifstream *ifs) {
unsigned trace_version, unsigned enable_lineinfo, std::istream *ifs) {
for (unsigned i = 0; i < threadblock_traces.size(); ++i) {
threadblock_traces[i]->clear();
}
Expand Down
7 changes: 5 additions & 2 deletions gpu-simulator/trace-parser/trace_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ struct kernel_trace_t {
unsigned long long shmem_base_addr;
unsigned long long local_base_addr;
// Reference to open filestream
std::ifstream *ifs;
std::istream *ifs;
// Anonymous pipe through which the trace is transmitted from a trace reader
// process to the simulator process
int pipefd[2]={};
};

class trace_parser {
Expand All @@ -112,7 +115,7 @@ class trace_parser {

void get_next_threadblock_traces(
std::vector<std::vector<inst_trace_t> *> threadblock_traces,
unsigned trace_version, unsigned enable_lineinfo, std::ifstream *ifs);
unsigned trace_version, unsigned enable_lineinfo, std::istream *ifs);

void kernel_finalizer(kernel_trace_t *trace_info);

Expand Down
25 changes: 19 additions & 6 deletions util/tracer_nvbit/tracer_tool/tracer_tool.cu
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ bool active_region = true;
int terminate_after_limit_number_of_kernels_reached = 0;
int user_defined_folders = 0;

/* Use xz to compress the *.trace file */
int xz_compress_trace = 0;

/* opcode to id map and reverse map */
std::map<std::string, int> opcode_to_id_map;
std::map<int, std::string> id_to_opcode_map;
Expand Down Expand Up @@ -105,6 +108,8 @@ void nvbit_at_init() {
"Stop the process once the current kernel > DYNAMIC_KERNEL_LIMIT_END");
GET_VAR_INT(user_defined_folders, "USER_DEFINED_FOLDERS", 0, "Uses the user defined "
"folder TRACES_FOLDER path environment");
GET_VAR_INT(xz_compress_trace, "TRACE_FILE_COMPRESS", 0, "Create xz-compressed trace"
"file");
std::string pad(100, '-');
printf("%s\n", pad.c_str());

Expand Down Expand Up @@ -388,9 +393,15 @@ void nvbit_at_cuda_event(CUcontext ctx, int is_exit, nvbit_api_cuda_t cbid,
sprintf(buffer, std::string(traces_location+"/kernel-%d.trace").c_str(), kernelid);

if (!stop_report) {
resultsFile = fopen(buffer, "w");

printf("Writing results to %s\n", buffer);
if(!xz_compress_trace){
resultsFile = fopen(buffer, "w");
printf("Writing results to %s\n", buffer);
} else {
char cmd_buffer[1039];
sprintf(cmd_buffer, "xz -1 -T0 > %s.xz", buffer);
resultsFile = popen(cmd_buffer, "w");
printf("Writing results to %s.xz\n", buffer);
}

fprintf(resultsFile, "-kernel name = %s\n",
nvbit_get_func_name(ctx, p->f, true));
Expand Down Expand Up @@ -421,7 +432,7 @@ void nvbit_at_cuda_event(CUcontext ctx, int is_exit, nvbit_api_cuda_t cbid,

kernelsFile = fopen(kernelslist_location.c_str(), "a");
// This will be a relative path to the traces file
sprintf(buffer,"kernel-%d.trace", kernelid);
sprintf(buffer,"kernel-%d.trace%s", kernelid, xz_compress_trace?".xz":"");
if (!stop_report) {
fprintf(kernelsFile, buffer);
fprintf(kernelsFile, "\n");
Expand Down Expand Up @@ -480,8 +491,10 @@ void nvbit_at_cuda_event(CUcontext ctx, int is_exit, nvbit_api_cuda_t cbid,
fprintf(statsFile, "\n");
fclose(statsFile);

if (!stop_report)
fclose(resultsFile);
if (!stop_report){
if(!xz_compress_trace){fclose(resultsFile);}
else{pclose(resultsFile);}
}

if (active_from_start && dynamic_kernel_limit_end && kernelid > dynamic_kernel_limit_end)
active_region = false;
Expand Down
2 changes: 1 addition & 1 deletion util/tracer_nvbit/tracer_tool/traces-processing/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
TARGET := post-traces-processing

$(TARGET): post-traces-processing.cpp
g++ -std=c++11 -o $@ $^
g++ -std=c++14 -O3 -g -o $@ $^

run: $(TARGET)
./$(TARGET)
Expand Down
Loading

0 comments on commit c1a12bc

Please sign in to comment.