diff options
Diffstat (limited to 'src/trace-driven')
| -rw-r--r-- | src/trace-driven/gpgpusim_trace_driven_main.cc | 356 | ||||
| -rw-r--r-- | src/trace-driven/trace_driven.h | 94 |
2 files changed, 450 insertions, 0 deletions
diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc new file mode 100644 index 0000000..4f973cd --- /dev/null +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -0,0 +1,356 @@ +//developed by Mahmoud Khairy, Purdue Univ + +//#include "../abstract_hardware_model.h" +#include <time.h> +#include <stdio.h> +#include <vector> +#include <iostream> +#include <fstream> +#include <string> +#include <sstream> +#include <stdio.h> +#include <math.h> + + +//#include "../option_parser.h" +//#include "../cuda-sim/cuda-sim.h" +//#include "../cuda-sim/ptx_ir.h" +//#include "../cuda-sim/ptx_parser.h" +#include "../gpgpu-sim/gpu-sim.h" +//#include "../gpgpu-sim/icnt_wrapper.h" +//#include "../gpgpu-sim/icnt_wrapper.h" +#include "../../libcuda/gpgpu_context.h" +#include "trace_driven.h" + +//#include "../stream_manager.h" + + +void arguments_check(); + +int main ( int argc, const char **argv ) +{ + + gpgpu_context* m_gpgpu_context = GPGPU_Context(); + gpgpu_sim * m_gpgpu_sim = m_gpgpu_context->gpgpu_trace_sim_init_perf(argc,argv); + m_gpgpu_sim->init(); + + //for each kernel + //load file + //parse and create kernel info + //launch + //while loop till the end of the end kernel execution + //prints stats + + trace_parser tracer(m_gpgpu_sim->get_config().get_traces_filename(), m_gpgpu_sim, m_gpgpu_context); + + std::vector<std::string> kernellist = tracer.parse_kernellist_file(); + + for(unsigned i=0; i<kernellist.size(); ++i) { + + trace_kernel_info_t* kernel_info = tracer.parse_kernel_info(kernellist[i]); + m_gpgpu_sim->launch(kernel_info); + + bool active = false; + bool sim_cycles = false; + bool break_limit = false; + + do { + if(!m_gpgpu_sim->active()) + break; + + //performance simulation + if( m_gpgpu_sim->active() ) { + m_gpgpu_sim->cycle(); + sim_cycles = true; + m_gpgpu_sim->deadlock_check(); + }else { + if(m_gpgpu_sim->cycle_insn_cta_max_hit()){ + m_gpgpu_context->the_gpgpusim->g_stream_manager->stop_all_running_kernels(); + break_limit = true; + } + } + + active=m_gpgpu_sim->active() ; + + } while( active ); + + tracer.kernel_finalizer(kernel_info); + + m_gpgpu_sim->print_stats(); + + if(sim_cycles) { + m_gpgpu_sim->update_stats(); + m_gpgpu_context->print_simulation_time(); + } + + if(break_limit) { + printf("GPGPU-Sim: ** break due to reaching the maximum cycles (or instructions) **\n"); + fflush(stdout); + exit(1); + } + } + + return 1; +} + +trace_parser::trace_parser(const char* kernellist_filepath, gpgpu_sim * m_gpgpu_sim, gpgpu_context* m_gpgpu_context) +{ + + this->m_gpgpu_sim = m_gpgpu_sim; + this->m_gpgpu_context = m_gpgpu_context; + kernellist_filename = kernellist_filepath; +} + +std::vector<std::string> trace_parser::parse_kernellist_file() { + + ifs.open(kernellist_filename); + + if (!ifs.is_open()) { + std::cout << "Unable to open file: " <<kernellist_filename<<std::endl; + exit(1); + } + + std::string directory(kernellist_filename); + const size_t last_slash_idx = directory.rfind('/'); + if (std::string::npos != last_slash_idx) + { + directory = directory.substr(0, last_slash_idx); + } + + std::string line, filepath; + std::vector<std::string> kernellist; + while(!ifs.eof()) { + getline(ifs, line); + if(line.empty()) + continue; + filepath = directory+"/"+line; + kernellist.push_back(filepath); + } + + ifs.close(); + return kernellist; +} + + +trace_kernel_info_t* trace_parser::parse_kernel_info(const std::string& kerneltraces_filepath) { + + ifs.open(kerneltraces_filepath.c_str()); + + if (!ifs.is_open()) { + std::cout << "Unable to open file: " <<kerneltraces_filepath<<std::endl; + exit(1); + } + + std::cout << "Processing kernel " <<kerneltraces_filepath<<std::endl; + + unsigned grid_dim_x=0, grid_dim_y=0, grid_dim_z=0, tb_dim_x=0, tb_dim_y=0, tb_dim_z=0; + unsigned shmem=0, nregs=0, cuda_stream_id=0, kernel_id=0; + std::string line; + std::stringstream ss; + std::string string1, string2; + std::string kernel_name; + + while(!ifs.eof()) { + getline(ifs, line); + + if (line.length() == 0) { + continue; + } + else if(line[0] == '#'){ + //the trace format, ignore this and assume fixed format for now + break; //the begin of the instruction stream + } + else if(line[0] == '-') { + ss.str(line); + ss.ignore(); + ss>>string1>>string2; + if(string1 == "kernel" && string2 == "name") { + const size_t equal_idx = line.find('='); + kernel_name = line.substr(equal_idx+1); + } + else if(string1 == "kernel" && string2 == "id") { + sscanf(line.c_str(), "-kernel id = %d", &kernel_id); + } + else if(string1 == "grid" && string2 == "dim") { + sscanf(line.c_str(), "-grid dim = (%d,%d,%d)", &grid_dim_x, &grid_dim_y, &grid_dim_z); + } + else if (string1 == "block" && string2 == "dim") { + sscanf(line.c_str(), "-block dim = (%d,%d,%d)", &tb_dim_x, &tb_dim_y, &tb_dim_z); + } + else if (string1 == "shmem") { + sscanf(line.c_str(), "-shmem = %d", &shmem); + } + else if (string1 == "nregs") { + sscanf(line.c_str(), "-nregs = %d", &nregs); + } + else if (string1 == "cuda" && string2 == "stream") { + sscanf(line.c_str(), "-cuda stream id = %d", &cuda_stream_id); + } + continue; + } + } + + gpgpu_ptx_sim_info info; + info.smem = shmem; + info.regs = nregs; + dim3 gridDim(grid_dim_x, grid_dim_y, grid_dim_z); + dim3 blockDim(tb_dim_x, tb_dim_y, tb_dim_z); + trace_function_info* function_info = new trace_function_info(info, m_gpgpu_context); + function_info->set_name(kernel_name.c_str()); + trace_kernel_info_t* kernel_info = new trace_kernel_info_t(gridDim, blockDim, function_info, &ifs, m_gpgpu_sim); + + return kernel_info; +} + + +void trace_parser::kernel_finalizer(trace_kernel_info_t* kernel_info){ + if (ifs.is_open()) + ifs.close(); + + delete kernel_info->entry(); + delete kernel_info; +} + +bool trace_kernel_info_t::get_next_threadblock_traces(std::vector<std::vector<trace_warp_inst_t>>& threadblock_traces) { + + threadblock_traces.clear(); + unsigned warps_per_tb = ceil(float(threads_per_cta()/32)); + threadblock_traces.resize(warps_per_tb); + + unsigned block_id_x=0, block_id_y=0, block_id_z=0; + unsigned warp_id=0; + unsigned insts_num=0; + std::string line; + std::stringstream ss; + std::string string1, string2; + + bool start_of_tb_stream_found = false; + + while(!ifs->eof()) { + getline(*ifs, line); + + if (line.length() == 0) { + continue; + } + else { + ss.str(line); + ss>>string1>>string2; + if (string1 == "#BEGIN_TB") { + if(!start_of_tb_stream_found) + start_of_tb_stream_found=true; + else assert(0 && "Parsing error: thread block start before the previous one finish"); + } + else if (string1 == "#END_TB") { + assert(start_of_tb_stream_found); + break; //end of TB stream + } + else if(string1 == "thread" && string2 == "block") { + assert(start_of_tb_stream_found); + sscanf(line.c_str(), "thread block = %d,%d,%d", &block_id_x, &block_id_y, &block_id_z); + } + else if (string1 == "warp") { + //the start of new warp stream + assert(start_of_tb_stream_found); + sscanf(line.c_str(), "warp = %d", &warp_id); + } + else if (string1 == "insts") { + assert(start_of_tb_stream_found); + sscanf(line.c_str(), "insts = %d", &insts_num); + threadblock_traces[warp_id].resize(insts_num); + } + else { + assert(start_of_tb_stream_found); + trace_warp_inst_t inst(m_gpgpu_sim->getShaderCoreConfig()); + inst.parse_from_string(line); + threadblock_traces[warp_id].push_back(inst); + } + } + } + + return true; +} + + +bool trace_warp_inst_t::parse_from_string(std::string trace){ + + std::stringstream ss; + ss.str(trace); + + + std::string temp; + unsigned threadblock_x=0, threadblock_y=0, threadblock_z=0, warpid_tb=0, sm_id=0, warpid_sm=0; + unsigned long long m_pc=0; + unsigned mask=0; + unsigned reg_dest=0; + std::string opcode; + unsigned reg_srcs_num=0; + unsigned reg_srcs[4]; + unsigned mem_width=0; + unsigned long long mem_addresses[warp_size()]; + + ss>>std::dec>>threadblock_x>>threadblock_y>>threadblock_z>>warpid_tb>>sm_id>>warpid_sm; + + ss>>std::hex>>m_pc>>mask; + std::bitset<MAX_WARP_SIZE> mask_bits(mask); + + ss>>std::dec>>temp; + sscanf(temp.c_str(), "R%d", ®_dest); + + ss>>opcode; + ss>>reg_srcs_num; + + for(unsigned i=0; i<reg_srcs_num; ++i) { + ss>>temp; + sscanf(temp.c_str(), "R%d", ®_srcs[i]); + } + + ss>>mem_width; + if(mem_width > 0) //then it is a memory inst + { + for (int s = 0; s < warp_size(); s++) { + if(mask_bits.test(s)) + ss>>std::hex>>mem_addresses[s]; + else + mem_addresses[s]=0; + } + } + + //After parsing, fill the inst_t and warp_inst_t params + active_mask_t active_mask = mask_bits; + set_active( active_mask ); + + for(unsigned i=0; i<warp_size(); ++i) + set_addr(i, mem_addresses[i]); + + std::string opcode1 = opcode.substr(0, opcode.find(".")); + + m_decoded = true; + pc = m_pc; + isize = 16; //TO DO, change this + for(unsigned i=0; i<MAX_OUTPUT_VALUES; i++) { + out[i] = 0; + } + for(unsigned i=0; i<MAX_INPUT_VALUES; i++) { + in[i] = 0; + } + incount=0; + outcount=0; + is_vectorin = 0; + is_vectorout = 0; + + /* + switch(opcode1){ + case "MOV": + incount=1; + break; + default: + std::cout<<"unknown instruction: "<<opcode; + break; + } + */ + + return true; +} + + diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h new file mode 100644 index 0000000..091707a --- /dev/null +++ b/src/trace-driven/trace_driven.h @@ -0,0 +1,94 @@ +//developed by Mahmoud Khairy, Purdue Univ + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#ifndef TRACE_DRIVEN_H +#define TRACE_DRIVEN_H + +#include "../abstract_hardware_model.h" +#include "../gpgpu-sim/shader.h" + +class trace_function_info: public function_info { +public: + trace_function_info(const struct gpgpu_ptx_sim_info &info, gpgpu_context* m_gpgpu_context):function_info(0, m_gpgpu_context ) { + m_kernel_info = info; + } + + virtual const struct gpgpu_ptx_sim_info* get_kernel_info () const { + return &m_kernel_info; + } + + virtual const void set_kernel_info (const struct gpgpu_ptx_sim_info &info) { + m_kernel_info = info; + } + +private: + + +}; + +class trace_warp_inst_t: public warp_inst_t { +public: + + trace_warp_inst_t() { + + } + trace_warp_inst_t(const class core_config *config):warp_inst_t(config) { + } + + bool parse_from_string(std::string trace); + + +private: + + +}; + +class trace_kernel_info_t: public kernel_info_t { +public: + trace_kernel_info_t(dim3 gridDim, dim3 blockDim, trace_function_info* m_function_info, std::ifstream* inputstream, gpgpu_sim * gpgpu_sim):kernel_info_t(gridDim, blockDim, m_function_info) { + ifs = inputstream; + m_gpgpu_sim = gpgpu_sim; + } + + bool get_next_threadblock_traces(std::vector<std::vector<trace_warp_inst_t>>& threadblock_traces); + +private: + std::ifstream* ifs; + gpgpu_sim * m_gpgpu_sim; + +}; + + + +class trace_parser { +public: + trace_parser(const char* kernellist_filepath, gpgpu_sim * m_gpgpu_sim, gpgpu_context* m_gpgpu_context); + + std::vector<std::string> parse_kernellist_file(); + trace_kernel_info_t* parse_kernel_info(const std::string& kerneltraces_filepath); + void kernel_finalizer(trace_kernel_info_t* kernel_info); + +private: + + std::string kernellist_filename; + std::ifstream ifs; + gpgpu_sim * m_gpgpu_sim; + gpgpu_context* m_gpgpu_context; + +}; + +class trace_shd_warp_t: public shd_warp_t { +public: + trace_shd_warp_t(class shader_core_ctx *shader, unsigned warp_size):shd_warp_t(shader, warp_size) { + } + + bool get_next_threadblock_traces(std::vector<std::vector<trace_warp_inst_t>>& threadblock_traces); + +private: + +}; + +#endif |
