diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/abstract_hardware_model.cc | 4 | ||||
| -rw-r--r-- | src/abstract_hardware_model.h | 9 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_ir.h | 10 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_loader.cc | 2 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_parser.cc | 4 | ||||
| -rw-r--r-- | src/gpgpu-sim/addrdec.cc | 4 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.cc | 7 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.h | 5 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 11 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.h | 7 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 54 | ||||
| -rw-r--r-- | src/gpgpusim_entrypoint.cc | 31 | ||||
| -rw-r--r-- | src/trace-driven/gpgpusim_trace_driven_main.cc | 356 | ||||
| -rw-r--r-- | src/trace-driven/trace_driven.h | 94 |
14 files changed, 563 insertions, 35 deletions
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index 07232ee..e8e4b51 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -729,7 +729,7 @@ kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info * //Jin: launch latency management m_launch_latency = entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency; - volta_cache_config_set=false; + cache_config_set=false; } /*A snapshot of the texture mappings needs to be stored in the kernel's info as @@ -754,7 +754,7 @@ kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info * //Jin: launch latency management m_launch_latency = entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency; - volta_cache_config_set=false; + cache_config_set=false; m_NameToCudaArray = nameToCudaArray; m_NameToTextureInfo = nameToTextureInfo; } diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 29e4a30..341e44c 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -67,6 +67,11 @@ enum FuncCache FuncCachePreferL1 = 2 }; +enum AdaptiveCache +{ + FIXED = 0, + VOLTA = 1 +}; #ifdef __cplusplus @@ -344,7 +349,7 @@ public: unsigned long long end_cycle; unsigned m_launch_latency; - mutable bool volta_cache_config_set; + mutable bool cache_config_set; }; class core_config { @@ -391,7 +396,7 @@ class core_config { unsigned gpgpu_max_insn_issue_per_warp; bool gmem_skip_L1D; // on = global memory access always skip the L1 cache - bool adaptive_volta_cache_config; + unsigned adaptive_cache_config; }; // bounded stack that implements simt reconvergence using pdom mechanism from MICRO'07 paper diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index f4c5c37..8ceb60b 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -1354,13 +1354,13 @@ public: void list_param( FILE *fout ) const; void ptx_jit_config(std::map<unsigned long long, size_t> mallocPtr_Size, memory_space *param_mem, gpgpu_t* gpu, dim3 gridDim, dim3 blockDim) ; - const struct gpgpu_ptx_sim_info* get_kernel_info () const + virtual const struct gpgpu_ptx_sim_info* get_kernel_info () const { assert (m_kernel_info.maxthreads == maxnt_id); return &m_kernel_info; } - const void set_kernel_info (const struct gpgpu_ptx_sim_info &info) { + virtual const void set_kernel_info (const struct gpgpu_ptx_sim_info &info) { m_kernel_info = info; m_kernel_info.ptx_version = 10*get_ptx_version().ver(); m_kernel_info.sm_target = get_ptx_version().target(); @@ -1401,6 +1401,10 @@ public: // backward pointer class gpgpu_context* gpgpu_ctx; +protected: + //Registers/shmem/etc. used (from ptxas -v), loaded from ___.ptxinfo along with ___.ptx + struct gpgpu_ptx_sim_info m_kernel_info; + private: unsigned maxnt_id; unsigned m_uid; @@ -1424,8 +1428,6 @@ private: std::map<std::string,unsigned> labels; unsigned num_reconvergence_pairs; - //Registers/shmem/etc. used (from ptxas -v), loaded from ___.ptxinfo along with ___.ptx - struct gpgpu_ptx_sim_info m_kernel_info; symbol_table *m_symtab; diff --git a/src/cuda-sim/ptx_loader.cc b/src/cuda-sim/ptx_loader.cc index 33bcf45..f06fefd 100644 --- a/src/cuda-sim/ptx_loader.cc +++ b/src/cuda-sim/ptx_loader.cc @@ -37,7 +37,7 @@ /// extern prototypes -extern int ptx_error( yyscan_t yyscanner, const char *s ); +extern int ptx_error( yyscan_t yyscanner, ptx_recognizer* recognizer, const char *s ); extern int ptx_lex_init(yyscan_t* scanner); extern void ptx_set_in(FILE * _in_str ,yyscan_t yyscanner ); extern int ptx_parse(yyscan_t scanner, ptx_recognizer* recognizer); diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc index a4f4a0c..24af3ad 100644 --- a/src/cuda-sim/ptx_parser.cc +++ b/src/cuda-sim/ptx_parser.cc @@ -35,7 +35,7 @@ typedef void * yyscan_t; extern int ptx_get_lineno (yyscan_t yyscanner ); extern YYSTYPE* ptx_get_lval (yyscan_t yyscanner ); -extern int ptx_error( yyscan_t yyscanner, const char *s ); +extern int ptx_error( yyscan_t yyscanner, ptx_recognizer* recognizer, const char *s ); extern int ptx_lex_init(yyscan_t* scanner); extern void ptx_set_in(FILE * _in_str ,yyscan_t yyscanner ); extern FILE *ptx_get_in (yyscan_t yyscanner ); @@ -226,7 +226,7 @@ void ptx_recognizer::parse_error_impl( const char *file, unsigned line, const ch g_error_detected = 1; printf("%s:%u: Parse error: %s (%s:%u)\n\n", gpgpu_ctx->g_filename, ptx_get_lineno(scanner), buf, file, line); - ptx_error(scanner, NULL); + ptx_error(scanner, this, NULL); abort(); exit(1); } diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc index e3713f3..f225933 100644 --- a/src/gpgpu-sim/addrdec.cc +++ b/src/gpgpu-sim/addrdec.cc @@ -124,8 +124,8 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_ * Rau, B. R et al. * ISCA 1991 * - * equations are adopted from: - * "Sacat: streaming-aware conflict-avoiding thrashing-resistant gpgpu cache management scheme." + * equations are corresponding to IPOLY(37) and are adopted from: + * "SACAT: streaming-aware conflict-avoiding thrashing-resistant gpgpu cache management scheme." * Khairy et al. * IEEE TPDS 2017. */ diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 1e99fec..65f2f6d 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -66,8 +66,13 @@ const char * cache_fail_status_str(enum cache_reservation_fail_reason status) unsigned l1d_cache_config::set_bank(new_addr_type addr) const{ - if(m_cache_type == SECTOR) + //For sector cache, we select one sector per bank (sector interleaving) + //This is what was found in Volta (one sector per bank, sector interleaving) + //otherwise, line interleaving + if(m_cache_type == SECTOR) { + //assert(l1_banks == SECTOR_CHUNCK_SIZE); return (addr >> m_sector_sz_log2) & (l1_banks-1); + } else return (addr >> m_line_sz_log2) & (l1_banks-1); } diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 6f39221..b7d0400 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -656,6 +656,11 @@ public: assert( m_valid ); return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER * m_nset * original_m_assoc; } + unsigned get_max_assoc() const + { + assert( m_valid ); + return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER * original_m_assoc; + } void print( FILE *fp ) const { fprintf( fp, "Size = %d B (%d Set x %d-way x %d byte line)\n", diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 56ea8c4..a70185e 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -305,7 +305,7 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_shmem_size", OPT_UINT32, &gpgpu_shmem_size, "Size of shared memory per shader core (default 16kB)", "16384"); - option_parser_register(opp, "-adaptive_cache_config", OPT_BOOL, &adaptive_volta_cache_config, + option_parser_register(opp, "-adaptive_cache_config", OPT_UINT32, &adaptive_cache_config, "adaptive_cache_config", "0"); option_parser_register(opp, "-gpgpu_shmem_sizeDefault", OPT_UINT32, &gpgpu_shmem_sizeDefault, @@ -560,6 +560,15 @@ void gpgpu_sim_config::reg_options(option_parser_t opp) option_parser_register(opp, "-gpgpu_cdp_enabled", OPT_BOOL, &(gpgpu_ctx->device_runtime->g_cdp_enabled), "Turn on CDP", "0"); + + //Trace driven mode parameters + option_parser_register(opp, "-trace_driven_mode", OPT_BOOL, + &trace_driven_mode, "Turn on trace_driven_mode", + "0"); + option_parser_register(opp, "-trace", OPT_CSTR, + &g_traces_filename, "traces kernel file" + "traces kernel file directory", + "./traces/kernelslist.g"); } ///////////////////////////////////////////////////////////////////////////// diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index fba770d..86d6206 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -348,6 +348,9 @@ public: size_t sync_depth_limit() const {return runtime_sync_depth_limit; } size_t pending_launch_count_limit() const {return runtime_pending_launch_count_limit;} + unsigned is_trace_driven_mode() const { return trace_driven_mode; } + char* get_traces_filename() const { return g_traces_filename; } + private: void init_clock_domains(void ); @@ -401,6 +404,10 @@ private: unsigned int gpgpu_compute_capability_minor; unsigned long long liveness_message_freq; + //trace driven mode options + bool trace_driven_mode; + char *g_traces_filename; + friend class gpgpu_sim; }; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 6a0e3d6..86508f6 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -2994,33 +2994,47 @@ unsigned int shader_core_config::max_cta( const kernel_info_t &k ) const abort(); } - if(adaptive_volta_cache_config && !k.volta_cache_config_set) { - //For Volta, we assign the remaining shared memory to L1 cache - //For more info, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x + if(adaptive_cache_config && !k.cache_config_set) { + //For more info about adaptive cache, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x unsigned total_shmed = kernel_info->smem * result; assert(total_shmed >=0 && total_shmed <= gpgpu_shmem_size); - assert(gpgpu_shmem_size == 98304); //Volta has 96 KB shared - assert(m_L1D_config.get_nset() == 4); //Volta L1 has four sets + //assert(gpgpu_shmem_size == 98304); //Volta has 96 KB shared + //assert(m_L1D_config.get_nset() == 4); //Volta L1 has four sets if(total_shmed < gpgpu_shmem_size){ - if(total_shmed == 0) - m_L1D_config.set_assoc(256); //L1 is 128KB ans shd=0 - else if(total_shmed > 0 && total_shmed <= 8192) - m_L1D_config.set_assoc(240); //L1 is 120KB ans shd=8KB - else if(total_shmed > 8192 && total_shmed <= 16384) - m_L1D_config.set_assoc(224); //L1 is 112KB ans shd=16KB - else if(total_shmed > 16384 && total_shmed <= 32768) - m_L1D_config.set_assoc(192); //L1 is 96KB ans shd=32KB - else if(total_shmed > 32768 && total_shmed <= 65536) - m_L1D_config.set_assoc(128); //L1 is 64KB ans shd=64KB - else if(total_shmed > 65536 && total_shmed <= gpgpu_shmem_size) - m_L1D_config.set_assoc(64); //L1 is 32KB and shd=96KB - else + switch (adaptive_cache_config) { + case FIXED: + break; + case VOLTA: { + //For Volta, we assign the remaining shared memory to L1 cache + //For more info about adaptive cache, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x + assert(gpgpu_shmem_size == 98304); //Volta has 96 KB shared + + //To Do: make it flexible and not tuned to 9KB share memory + unsigned max_assoc = m_L1D_config.get_max_assoc(); + if(total_shmed == 0) + m_L1D_config.set_assoc(max_assoc); //L1 is 128KB and shd=0 + else if(total_shmed > 0 && total_shmed <= 8192) + m_L1D_config.set_assoc(0.9375 * max_assoc); //L1 is 120KB and shd=8KB + else if(total_shmed > 8192 && total_shmed <= 16384) + m_L1D_config.set_assoc(0.875 * max_assoc); //L1 is 112KB and shd=16KB + else if(total_shmed > 16384 && total_shmed <= 32768) + m_L1D_config.set_assoc(0.75 * max_assoc); //L1 is 96KB and shd=32KB + else if(total_shmed > 32768 && total_shmed <= 65536) + m_L1D_config.set_assoc(0.5 * max_assoc); //L1 is 64KB and shd=64KB + else if(total_shmed > 65536 && total_shmed <= gpgpu_shmem_size) + m_L1D_config.set_assoc(0.25 * max_assoc); //L1 is 32KB and shd=96KB + else + assert(0); + break; + } + default: assert(0); + } - printf ("GPGPU-Sim: Reconfigure L1 cache in Volta Archi to %uKB\n", m_L1D_config.get_total_size_inKB()); + printf ("GPGPU-Sim: Reconfigure L1 cache to %uKB\n", m_L1D_config.get_total_size_inKB()); } - k.volta_cache_config_set = true; + k.cache_config_set = true; } return result; diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc index 846773d..69cc1b0 100644 --- a/src/gpgpusim_entrypoint.cc +++ b/src/gpgpusim_entrypoint.cc @@ -225,6 +225,37 @@ gpgpu_sim *gpgpu_context::gpgpu_ptx_sim_init_perf() return the_gpgpusim->g_the_gpu; } +gpgpu_sim *gpgpu_context::gpgpu_trace_sim_init_perf(int argc, const char *argv[]) +{ + srand(1); + print_splash(); + func_sim->read_sim_environment_variables(); + ptx_parser->read_parser_environment_variables(); + option_parser_t opp = option_parser_create(); + + ptx_reg_options(opp); + func_sim->ptx_opcocde_latency_options(opp); + + icnt_reg_options(opp); + the_gpgpusim->g_the_gpu_config = new gpgpu_sim_config(this); + the_gpgpusim->g_the_gpu_config->reg_options(opp); // register GPU microrachitecture options + + option_parser_cmdline(opp, argc, argv); // parse configuration options + fprintf(stdout, "GPGPU-Sim: Configuration options:\n\n"); + option_parser_print(opp, stdout); + // Set the Numeric locale to a standard locale where a decimal point is a "dot" not a "comma" + // so it does the parsing correctly independent of the system environment variables + assert(setlocale(LC_NUMERIC,"C")); + the_gpgpusim->g_the_gpu_config->init(); + + the_gpgpusim->g_the_gpu = new gpgpu_sim(*(the_gpgpusim->g_the_gpu_config), this); + the_gpgpusim->g_stream_manager = new stream_manager((the_gpgpusim->g_the_gpu), func_sim->g_cuda_launch_blocking); + + the_gpgpusim->g_simulation_starttime = time((time_t *)NULL); + + return the_gpgpusim->g_the_gpu; +} + void gpgpu_context::start_sim_thread(int api) { if( the_gpgpusim->g_sim_done ) { 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 |
