From 5adbc9c4afad276a5d8590f3c53b789003ae4dcf Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Fri, 22 Jun 2018 16:50:50 -0400 Subject: adding the main file --- src/trace-driven/gpgpusim_trace_driven_main.cc | 138 +++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 src/trace-driven/gpgpusim_trace_driven_main.cc (limited to 'src') 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..6553fd7 --- /dev/null +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -0,0 +1,138 @@ +//developed by Mahmoud Khairy, Purdue Univ +//abdallm@purdue.edu + +#include "../abstract_hardware_model.h" +#include +#include + +#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 "../stream_manager.h" + + + +gpgpu_sim_config g_the_gpu_config; +gpgpu_sim *g_the_gpu; +time_t g_simulation_starttime; + +#define MAX(a,b) (((a)>(b))?(a):(b)) + +static void print_simulation_time(); + + +int main ( int argc, char **argv ) +{ + srand(1); + + option_parser_t opp = option_parser_create(); + + icnt_reg_options(opp); + g_the_gpu_config.reg_options(opp); // register GPU microrachitecture options + ptx_reg_options(opp); + ptx_opcocde_latency_options(opp); + + //ptx_opcocde_latency_options(opp); //do this for trace driven + + fprintf(stdout, "I am here:\n\n"); + option_parser_cmdline(opp, argc, (const char **)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")); + g_the_gpu_config.init(); + + g_the_gpu = new gpgpu_sim(g_the_gpu_config); + //g_stream_manager = new stream_manager(g_the_gpu,g_cuda_launch_blocking); + + //load file + //create kernel info + //launch + //while loop till the end + //prints stats + //g_the_gpu->launch(grid); + + g_simulation_starttime = time((time_t *)NULL); + + bool active = false; + bool sim_cycles = false; + bool break_limit = false; + + g_the_gpu->init(); + do { + // check if a kernel has completed + // launch operation on device if one is pending and can be run + + // Need to break this loop when a kernel completes. This was a + // source of non-deterministic behaviour in GPGPU-Sim (bug 147). + // If another stream operation is available, g_the_gpu remains active, + // causing this loop to not break. If the next operation happens to be + // another kernel, the gpu is not re-initialized and the inter-kernel + // behaviour may be incorrect. Check that a kernel has finished and + // no other kernel is currently running. + if(!g_the_gpu->active()) + break; + + //performance simulation + if( g_the_gpu->active() ) { + g_the_gpu->cycle(); + sim_cycles = true; + g_the_gpu->deadlock_check(); + }else { + if(g_the_gpu->cycle_insn_cta_max_hit()){ + g_stream_manager->stop_all_running_kernels(); + break_limit = true; + } + } + + active=g_the_gpu->active() ; + + } while( active ); + + printf("GPGPU-Sim: ** STOP simulation thread (no work) **\n"); + fflush(stdout); + + g_the_gpu->print_stats(); + + if(sim_cycles) { + g_the_gpu->update_stats(); + print_simulation_time(); + } + + + printf("GPGPU-Sim: *** simulation thread exiting ***\n"); + fflush(stdout); + + if(break_limit) { + printf("GPGPU-Sim: ** break due to reaching the maximum cycles (or instructions) **\n"); + exit(1); + } + + return 1; +} + +void print_simulation_time() +{ + time_t current_time, difference, d, h, m, s; + current_time = time((time_t *)NULL); + difference = MAX(current_time - g_simulation_starttime, 1); + + d = difference/(3600*24); + h = difference/3600 - 24*d; + m = difference/60 - 60*(h + 24*d); + s = difference - 60*(m + 60*(h + 24*d)); + + fflush(stderr); + printf("\n\ngpgpu_simulation_time = %u days, %u hrs, %u min, %u sec (%u sec)\n", + (unsigned)d, (unsigned)h, (unsigned)m, (unsigned)s, (unsigned)difference ); + printf("gpgpu_simulation_rate = %u (inst/sec)\n", (unsigned)(g_the_gpu->gpu_tot_sim_insn / difference) ); + printf("gpgpu_simulation_rate = %u (cycle/sec)\n", (unsigned)(gpu_tot_sim_cycle / difference) ); + fflush(stdout); +} + + -- cgit v1.3 From eb3b077cddb24a734bb72f5c1588dee4034214a7 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 4 Sep 2019 21:38:57 -0400 Subject: adding trace class and parss kernel info --- Makefile | 4 +- libcuda/gpgpu_context.h | 1 + src/cuda-sim/ptx_ir.h | 10 +- src/cuda-sim/ptx_loader.cc | 2 +- src/cuda-sim/ptx_parser.cc | 4 +- src/gpgpu-sim/gpu-sim.cc | 9 + src/gpgpu-sim/gpu-sim.h | 7 + src/gpgpusim_entrypoint.cc | 32 ++- src/gpgpusim_entrypoint.h | 2 + src/trace-driven/gpgpusim_trace_driven_main.cc | 305 +++++++++++++++---------- src/trace-driven/trace_driven.h | 71 ++++++ 11 files changed, 322 insertions(+), 125 deletions(-) create mode 100644 src/trace-driven/trace_driven.h (limited to 'src') diff --git a/Makefile b/Makefile index caf0a17..5cd3101 100644 --- a/Makefile +++ b/Makefile @@ -144,7 +144,7 @@ no_opencl_support: @echo "Warning: gpgpu-sim is building without opencl support. Make sure NVOPENCL_LIBDIR and NVOPENCL_INCDIR are set" $(SIM_LIB_DIR)/libcudart.so: makedirs $(LIBS) cudalib - g++ -shared -Wl,-soname,libcudart_$(GPGPUSIM_BUILD).so -Wl,--version-script=linux-so-version.txt\ + g++ -shared -Wl,-soname,libcudart.so -Wl,--version-script=linux-so-version.txt\ $(SIM_OBJ_FILES_DIR)/libcuda/*.o \ $(SIM_OBJ_FILES_DIR)/cuda-sim/*.o \ $(SIM_OBJ_FILES_DIR)/cuda-sim/decuda_pred_table/*.o \ @@ -171,7 +171,7 @@ $(SIM_LIB_DIR)/libcudart.so: makedirs $(LIBS) cudalib $(SIM_LIB_DIR)/gpgpusim.out: makedirs $(LIBS) cudalib $(SIM_LIB_DIR)/libcudart.so - g++ -std=c++0x -L$(SIM_LIB_DIR) -lcudart -o $(SIM_LIB_DIR)/gpgpusim.out src/trace-driven/gpgpusim_trace_driven_main.cc + g++ -std=c++0x -L$(SIM_LIB_DIR) -I$(CUDA_INSTALL_PATH)/include -lcudart -o $(SIM_LIB_DIR)/gpgpusim.out src/trace-driven/gpgpusim_trace_driven_main.cc $(SIM_LIB_DIR)/libcudart.dylib: makedirs $(LIBS) cudalib g++ -dynamiclib -Wl,-headerpad_max_install_names,-undefined,dynamic_lookup,-compatibility_version,1.1,-current_version,1.1\ diff --git a/libcuda/gpgpu_context.h b/libcuda/gpgpu_context.h index 45c5cdd..d3c5d74 100644 --- a/libcuda/gpgpu_context.h +++ b/libcuda/gpgpu_context.h @@ -65,6 +65,7 @@ class gpgpu_context { const ptx_instruction* pc_to_instruction(unsigned pc); const warp_inst_t *ptx_fetch_inst( address_type pc ); unsigned translate_pc_to_ptxlineno(unsigned pc); + class gpgpu_sim *gpgpu_trace_sim_init_perf(int argc, const char *argv[]); }; gpgpu_context* GPGPU_Context(); 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 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 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 dca3cec..207fa1f 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 81b70af..9e9d500 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/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index a151379..234a8d6 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -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 76c7a06..6b57bd8 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/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc index 816159f..4da74c0 100644 --- a/src/gpgpusim_entrypoint.cc +++ b/src/gpgpusim_entrypoint.cc @@ -60,7 +60,6 @@ class stream_manager* g_stream_manager() { return GPGPUsim_ctx_ptr()->g_stream_manager; } -static void print_simulation_time(); void *gpgpu_sim_thread_sequential(void*) { @@ -242,6 +241,37 @@ gpgpu_sim *gpgpu_context::gpgpu_ptx_sim_init_perf() return GPGPUsim_ctx_ptr()->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); + GPGPUsim_ctx_ptr()->g_the_gpu_config = new gpgpu_sim_config(this); + GPGPUsim_ctx_ptr()->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")); + GPGPUsim_ctx_ptr()->g_the_gpu_config->init(); + + GPGPUsim_ctx_ptr()->g_the_gpu = new gpgpu_sim(*(GPGPUsim_ctx_ptr()->g_the_gpu_config), this); + GPGPUsim_ctx_ptr()->g_stream_manager = new stream_manager((GPGPUsim_ctx_ptr()->g_the_gpu), func_sim->g_cuda_launch_blocking); + + GPGPUsim_ctx_ptr()->g_simulation_starttime = time((time_t *)NULL); + + return GPGPUsim_ctx_ptr()->g_the_gpu; +} + void start_sim_thread(int api) { if( GPGPUsim_ctx_ptr()->g_sim_done ) { diff --git a/src/gpgpusim_entrypoint.h b/src/gpgpusim_entrypoint.h index 887b3c8..4a8d796 100644 --- a/src/gpgpusim_entrypoint.h +++ b/src/gpgpusim_entrypoint.h @@ -84,4 +84,6 @@ class stream_manager* g_stream_manager(); int gpgpu_opencl_ptx_sim_main_perf( kernel_info_t *grid ); +void print_simulation_time(); + #endif diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 6553fd7..881e351 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -1,138 +1,213 @@ //developed by Mahmoud Khairy, Purdue Univ //abdallm@purdue.edu -#include "../abstract_hardware_model.h" +//#include "../abstract_hardware_model.h" #include #include +#include +#include +#include +#include +#include +#include +#include + -#include "../option_parser.h" -#include "../cuda-sim/cuda-sim.h" -#include "../cuda-sim/ptx_ir.h" -#include "../cuda-sim/ptx_parser.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 "../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 kernellist; + tracer.parse_kernellist_file(kernellist); + + for(unsigned i=0; ilaunch(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()){ + g_stream_manager()->stop_all_running_kernels(); + break_limit = true; + } + } + + active=m_gpgpu_sim->active() ; + + } while( active ); -gpgpu_sim_config g_the_gpu_config; -gpgpu_sim *g_the_gpu; -time_t g_simulation_starttime; + tracer.kernel_finalizer(kernel_info); -#define MAX(a,b) (((a)>(b))?(a):(b)) + m_gpgpu_sim->print_stats(); -static void print_simulation_time(); + if(sim_cycles) { + m_gpgpu_sim->update_stats(); + print_simulation_time(); + } + if(break_limit) { + printf("GPGPU-Sim: ** break due to reaching the maximum cycles (or instructions) **\n"); + fflush(stdout); + exit(1); + } + } -int main ( int argc, char **argv ) + return 1; +} + +trace_parser::trace_parser(const char* kernellist_filepath, gpgpu_sim * m_gpgpu_sim, gpgpu_context* m_gpgpu_context) { - srand(1); - - option_parser_t opp = option_parser_create(); - - icnt_reg_options(opp); - g_the_gpu_config.reg_options(opp); // register GPU microrachitecture options - ptx_reg_options(opp); - ptx_opcocde_latency_options(opp); - - //ptx_opcocde_latency_options(opp); //do this for trace driven - - fprintf(stdout, "I am here:\n\n"); - option_parser_cmdline(opp, argc, (const char **)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")); - g_the_gpu_config.init(); - - g_the_gpu = new gpgpu_sim(g_the_gpu_config); - //g_stream_manager = new stream_manager(g_the_gpu,g_cuda_launch_blocking); - - //load file - //create kernel info - //launch - //while loop till the end - //prints stats - //g_the_gpu->launch(grid); - - g_simulation_starttime = time((time_t *)NULL); - - bool active = false; - bool sim_cycles = false; - bool break_limit = false; - - g_the_gpu->init(); - do { - // check if a kernel has completed - // launch operation on device if one is pending and can be run - - // Need to break this loop when a kernel completes. This was a - // source of non-deterministic behaviour in GPGPU-Sim (bug 147). - // If another stream operation is available, g_the_gpu remains active, - // causing this loop to not break. If the next operation happens to be - // another kernel, the gpu is not re-initialized and the inter-kernel - // behaviour may be incorrect. Check that a kernel has finished and - // no other kernel is currently running. - if(!g_the_gpu->active()) - break; - - //performance simulation - if( g_the_gpu->active() ) { - g_the_gpu->cycle(); - sim_cycles = true; - g_the_gpu->deadlock_check(); - }else { - if(g_the_gpu->cycle_insn_cta_max_hit()){ - g_stream_manager->stop_all_running_kernels(); - break_limit = true; - } - } - - active=g_the_gpu->active() ; - - } while( active ); - - printf("GPGPU-Sim: ** STOP simulation thread (no work) **\n"); - fflush(stdout); - - g_the_gpu->print_stats(); - - if(sim_cycles) { - g_the_gpu->update_stats(); - print_simulation_time(); - } - - - printf("GPGPU-Sim: *** simulation thread exiting ***\n"); - fflush(stdout); - - if(break_limit) { - printf("GPGPU-Sim: ** break due to reaching the maximum cycles (or instructions) **\n"); + + this->m_gpgpu_sim = m_gpgpu_sim; + this->m_gpgpu_context = m_gpgpu_context; + kernellist_filename = kernellist_filepath; +} + +void trace_parser::parse_kernellist_file(std::vector& kernellist) { + + ifs.open(kernellist_filename); + + if (!ifs.is_open()) { + std::cout << "Unable to open file: " <>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); + trace_kernel_info_t* kernel_info = new trace_kernel_info_t(gridDim, blockDim, function_info, kerneltraces_filepath); + + return kernel_info; } -void print_simulation_time() -{ - time_t current_time, difference, d, h, m, s; - current_time = time((time_t *)NULL); - difference = MAX(current_time - g_simulation_starttime, 1); - - d = difference/(3600*24); - h = difference/3600 - 24*d; - m = difference/60 - 60*(h + 24*d); - s = difference - 60*(m + 60*(h + 24*d)); - - fflush(stderr); - printf("\n\ngpgpu_simulation_time = %u days, %u hrs, %u min, %u sec (%u sec)\n", - (unsigned)d, (unsigned)h, (unsigned)m, (unsigned)s, (unsigned)difference ); - printf("gpgpu_simulation_rate = %u (inst/sec)\n", (unsigned)(g_the_gpu->gpu_tot_sim_insn / difference) ); - printf("gpgpu_simulation_rate = %u (cycle/sec)\n", (unsigned)(gpu_tot_sim_cycle / difference) ); - fflush(stdout); + +void trace_parser::kernel_finalizer(trace_kernel_info_t* kernel_info){ + if (ifs.is_open()) + ifs.close(); + + delete kernel_info->entry(); + delete kernel_info; } + diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h new file mode 100644 index 0000000..91ff90b --- /dev/null +++ b/src/trace-driven/trace_driven.h @@ -0,0 +1,71 @@ +//developed by Mahmoud Khairy, Purdue Univ + +#include +#include +#include + +#ifndef TRACE_DRIVEN_H +#define TRACE_DRIVEN_H + +#include "../abstract_hardware_model.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_kernel_info_t: public kernel_info_t { +public: + trace_kernel_info_t(dim3 gridDim, dim3 blockDim, trace_function_info* m_function_info, const std::string& filepath):kernel_info_t(gridDim, blockDim, m_function_info) { + traces_filepath = filepath; + } + +private: + std::string traces_filepath; + +}; + +class trace_warp_inst_t: public warp_inst_t { +public: + + trace_warp_inst_t() { + } + +private: + + +}; + +class trace_parser { +public: + trace_parser(const char* kernellist_filepath, gpgpu_sim * m_gpgpu_sim, gpgpu_context* m_gpgpu_context); + + void parse_kernellist_file(std::vector& kernellist); + 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; + +}; + +#endif -- cgit v1.3 From 6ce5e06d2389cad5041b495d5516b503ec7d2cd2 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Thu, 12 Sep 2019 18:14:02 -0400 Subject: parsing insts from traces --- src/trace-driven/gpgpusim_trace_driven_main.cc | 151 ++++++++++++++++++++++++- src/trace-driven/trace_driven.h | 43 +++++-- 2 files changed, 180 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 881e351..3b9851e 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -44,8 +44,7 @@ int main ( int argc, const char **argv ) trace_parser tracer(m_gpgpu_sim->get_config().get_traces_filename(), m_gpgpu_sim, m_gpgpu_context); - std::vector kernellist; - tracer.parse_kernellist_file(kernellist); + std::vector kernellist = tracer.parse_kernellist_file(); for(unsigned i=0; i& kernellist) { +std::vector trace_parser::parse_kernellist_file() { ifs.open(kernellist_filename); @@ -120,6 +119,7 @@ void trace_parser::parse_kernellist_file(std::vector& kernellist) { } std::string line, filepath; + std::vector kernellist; while(!ifs.eof()) { getline(ifs, line); if(line.empty()) @@ -129,6 +129,7 @@ void trace_parser::parse_kernellist_file(std::vector& kernellist) { } ifs.close(); + return kernellist; } @@ -157,6 +158,7 @@ trace_kernel_info_t* trace_parser::parse_kernel_info(const std::string& kerneltr 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] == '-') { @@ -195,7 +197,8 @@ trace_kernel_info_t* trace_parser::parse_kernel_info(const std::string& kerneltr 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); - trace_kernel_info_t* kernel_info = new trace_kernel_info_t(gridDim, blockDim, function_info, kerneltraces_filepath); + 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; } @@ -209,5 +212,145 @@ void trace_parser::kernel_finalizer(trace_kernel_info_t* kernel_info){ delete kernel_info; } +bool trace_kernel_info_t::get_next_threadblock_traces(std::vector>& 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 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>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>& 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); - void parse_kernellist_file(std::vector& kernellist); + std::vector parse_kernellist_file(); trace_kernel_info_t* parse_kernel_info(const std::string& kerneltraces_filepath); void kernel_finalizer(trace_kernel_info_t* kernel_info); @@ -68,4 +80,15 @@ private: }; +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>& threadblock_traces); + +private: + +}; + #endif -- cgit v1.3 From 44a614b24d2e647d1f145b5ee9bcbc2996b0f741 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Fri, 13 Sep 2019 20:45:22 -0400 Subject: adding the traces parsing --- src/trace-driven/gpgpusim_trace_driven_main.cc | 191 ++++++++++++++++++++-- src/trace-driven/trace_driven.h | 11 +- src/trace-driven/trace_opcode.h | 217 +++++++++++++++++++++++++ 3 files changed, 401 insertions(+), 18 deletions(-) create mode 100644 src/trace-driven/trace_opcode.h (limited to 'src') diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 4f973cd..c61810f 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -1,7 +1,6 @@ //developed by Mahmoud Khairy, Purdue Univ //abdallm@purdue.edu -//#include "../abstract_hardware_model.h" #include #include #include @@ -12,7 +11,7 @@ #include #include - +//#include "../abstract_hardware_model.h" //#include "../option_parser.h" //#include "../cuda-sim/cuda-sim.h" //#include "../cuda-sim/ptx_ir.h" @@ -22,6 +21,7 @@ //#include "../gpgpu-sim/icnt_wrapper.h" #include "../../libcuda/gpgpu_context.h" #include "trace_driven.h" +#include "trace_opcode.h" //#include "../stream_manager.h" @@ -198,7 +198,7 @@ trace_kernel_info_t* trace_parser::parse_kernel_info(const std::string& kerneltr 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); + trace_kernel_info_t* kernel_info = new trace_kernel_info_t(gridDim, blockDim, function_info, &ifs, m_gpgpu_sim, m_gpgpu_context); return kernel_info; } @@ -261,7 +261,7 @@ bool trace_kernel_info_t::get_next_threadblock_traces(std::vectorgetShaderCoreConfig()); + trace_warp_inst_t inst(m_gpgpu_sim->getShaderCoreConfig(), m_gpgpu_context); inst.parse_from_string(line); threadblock_traces[warp_id].push_back(inst); } @@ -317,14 +317,15 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ } //After parsing, fill the inst_t and warp_inst_t params + + //fill active mask active_mask_t active_mask = mask_bits; set_active( active_mask ); - for(unsigned i=0; i::const_iterator it= OpcodeMap.find(opcode1.c_str()); + if (it != OpcodeMap.end()) { + m_opcode = it->second.opcode; + op = (op_type)(it->second.opcode_category); + } + else + assert(0 && "undefined instruction"); + + + //fill latency and initl + set_latency(op); + + //fill addresses + if(mem_width > 0) { + for(unsigned i=0; i0); + data_size = mem_width; + memory_op = memory_load; + if(m_opcode == OP_LDL) + space.set_type(local_space); + else + space.set_type(global_space); break; - default: - std::cout<<"unknown instruction: "<0); + data_size = mem_width; + memory_op = memory_store; + if(m_opcode == OP_STL) + space.set_type(local_space); + else + space.set_type(global_space); + + if(m_opcode == OP_ATOM || m_opcode == OP_ATOMG || m_opcode == OP_RED) + m_isatomic = true; break; + case OP_LDS: + case OP_STS: + case OP_ATOMS: + assert(mem_width>0); + data_size = mem_width; + space.set_type(shared_space); + break; + + default: + break; } - */ return true; } +void trace_warp_inst_t::set_latency(unsigned category) +{ + unsigned int_latency[5]; + unsigned fp_latency[5]; + unsigned dp_latency[5]; + unsigned sfu_latency; + unsigned tensor_latency; + unsigned int_init[5]; + unsigned fp_init[5]; + unsigned dp_init[5]; + unsigned sfu_init; + unsigned tensor_init; + + /* + * [0] ADD,SUB + * [1] MAX,Min + * [2] MUL + * [3] MAD + * [4] DIV + */ + sscanf(m_gpgpu_context->func_sim->opcode_latency_int, "%u,%u,%u,%u,%u", + &int_latency[0],&int_latency[1],&int_latency[2], + &int_latency[3],&int_latency[4]); + sscanf(m_gpgpu_context->func_sim->opcode_latency_fp, "%u,%u,%u,%u,%u", + &fp_latency[0],&fp_latency[1],&fp_latency[2], + &fp_latency[3],&fp_latency[4]); + sscanf(m_gpgpu_context->func_sim->opcode_latency_dp, "%u,%u,%u,%u,%u", + &dp_latency[0],&dp_latency[1],&dp_latency[2], + &dp_latency[3],&dp_latency[4]); + sscanf(m_gpgpu_context->func_sim->opcode_latency_sfu, "%u", + &sfu_latency); + sscanf(m_gpgpu_context->func_sim->opcode_latency_tensor, "%u", + &tensor_latency); + sscanf(m_gpgpu_context->func_sim->opcode_initiation_int, "%u,%u,%u,%u,%u", + &int_init[0],&int_init[1],&int_init[2], + &int_init[3],&int_init[4]); + sscanf(m_gpgpu_context->func_sim->opcode_initiation_fp, "%u,%u,%u,%u,%u", + &fp_init[0],&fp_init[1],&fp_init[2], + &fp_init[3],&fp_init[4]); + sscanf(m_gpgpu_context->func_sim->opcode_initiation_dp, "%u,%u,%u,%u,%u", + &dp_init[0],&dp_init[1],&dp_init[2], + &dp_init[3],&dp_init[4]); + sscanf(m_gpgpu_context->func_sim->opcode_initiation_sfu, "%u", + &sfu_init); + sscanf(m_gpgpu_context->func_sim->opcode_initiation_tensor, "%u", + &tensor_init); + sscanf(m_gpgpu_context->func_sim->cdp_latency_str, "%u,%u,%u,%u,%u", + &m_gpgpu_context->func_sim->cdp_latency[0], + &m_gpgpu_context->func_sim->cdp_latency[1], + &m_gpgpu_context->func_sim->cdp_latency[2], + &m_gpgpu_context->func_sim->cdp_latency[3], + &m_gpgpu_context->func_sim->cdp_latency[4]); + + initiation_interval = latency = 1; + + switch(category){ + case ALU_OP: + case INTP_OP: + case BRANCH_OP: + case CALL_OPS: + case RET_OPS: + latency = int_latency[0]; + initiation_interval = int_init[0]; + break; + case SP_OP: + latency = fp_latency[0]; + initiation_interval = fp_latency[0]; + break; + case DP_OP: + latency = dp_latency[0]; + initiation_interval = dp_latency[0]; + break; + case SFU_OP: + latency = sfu_latency; + initiation_interval = sfu_init; + break; + case TENSOR_CORE_OP: + latency = tensor_latency; + initiation_interval = tensor_init; + break; + default: + break; + } + +} + diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index 091707a..fbf7a1e 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -35,7 +35,9 @@ public: trace_warp_inst_t() { } - trace_warp_inst_t(const class core_config *config):warp_inst_t(config) { + trace_warp_inst_t(const class core_config *config, gpgpu_context* gpgpu_context ):warp_inst_t(config) { + m_gpgpu_context = gpgpu_context; + m_opcode=0; } bool parse_from_string(std::string trace); @@ -43,14 +45,18 @@ public: private: + void set_latency(unsigned cat); + gpgpu_context* m_gpgpu_context; + unsigned m_opcode; }; 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) { + trace_kernel_info_t(dim3 gridDim, dim3 blockDim, trace_function_info* m_function_info, std::ifstream* inputstream, gpgpu_sim * gpgpu_sim, gpgpu_context* gpgpu_context):kernel_info_t(gridDim, blockDim, m_function_info) { ifs = inputstream; m_gpgpu_sim = gpgpu_sim; + m_gpgpu_context = gpgpu_context; } bool get_next_threadblock_traces(std::vector>& threadblock_traces); @@ -58,6 +64,7 @@ public: private: std::ifstream* ifs; gpgpu_sim * m_gpgpu_sim; + gpgpu_context* m_gpgpu_context; }; diff --git a/src/trace-driven/trace_opcode.h b/src/trace-driven/trace_opcode.h new file mode 100644 index 0000000..f809238 --- /dev/null +++ b/src/trace-driven/trace_opcode.h @@ -0,0 +1,217 @@ + + +#ifndef TRACE_OPCODE_H +#define TRACE_OPCODE_H + +#include "../abstract_hardware_model.h" +#include + + +enum TraceInstrOpcode { + OP_FADD = 1, OP_FADD32I, OP_FCHK, OP_FFMA32I, OP_FFMA, OP_FMNMX, OP_FMUL, OP_FMUL32I, OP_FSEL, OP_FSET, OP_FSETP, + OP_FSWZADD, OP_MUFU, OP_HADD2, OP_HADD2_32I, OP_HFMA2, OP_HFMA2_32I, OP_HMUL2, OP_HMUL2_32I, OP_HSET2, OP_HSETP2, + OP_HMMA, OP_DADD, OP_DFMA, OP_DMUL, OP_DSETP, + OP_BMSK, OP_BREV, OP_FLO, OP_IABS, OP_IADD, OP_IADD3, OP_IADD32I, OP_IDP, OP_IDP4A, OP_IMAD, OP_IMMA, OP_IMNMX, + OP_IMUL, OP_IMUL32I, OP_ISCADD, OP_ISCADD32I, OP_ISETP, OP_LEA, OP_LOP, OP_LOP3, OP_LOP32I, OP_POPC, OP_SHF, OP_SHR, + OP_VABSDIFF, OP_VABSDIFF4, + OP_F2F, OP_F2I, OP_I2F, OP_I2I, OP_I2IP, OP_FRND, OP_MOV, OP_MOV32I, OP_PRMT, OP_SEL, OP_SGXT, OP_SHFL, OP_PLOP3, + OP_PSETP, OP_P2R, OP_R2P, OP_LD, OP_LDC, OP_LDG, OP_LDL, OP_LDS, OP_ST, OP_STG, OP_STL, OP_STS, OP_MATCH, OP_QSPC, + OP_ATOM, OP_ATOMS, OP_ATOMG, OP_RED, OP_CCTL, OP_CCTLL, OP_ERRBAR, OP_MEMBAR, OP_CCTLT, + OP_TEX, OP_TLD, OP_TLD4, + OP_TMML, OP_TXD, OP_TXQ, OP_BMOV, OP_BPT, OP_BRA, OP_BREAK, OP_BRX, OP_BSSY, OP_BSYNC, OP_CALL, OP_EXIT, OP_JMP, OP_JMX, + OP_KILL, OP_NANOSLEEP, OP_RET, OP_RPCMOV, OP_RTT, OP_WARPSYNC, OP_YIELD, OP_B2R, OP_BAR, OP_CS2R, OP_CSMTEST, OP_DEPBAR, + OP_GETLMEMBASE, OP_LEPC, OP_NOP, OP_PMTRIG, OP_R2B, OP_S2R, OP_SETCTAID, OP_SETLMEMBASE, OP_VOTE, OP_VOTE_VTG, + SASS_NUM_OPCODES /* The total number of opcodes. */ +}; +typedef enum TraceInstrOpcode sass_op_type; + +/* +enum uarch_op_t { + NO_OP=-1, + ALU_OP=1, + SFU_OP, + TENSOR_CORE_OP, + DP_OP, + SP_OP, + INTP_OP, + ALU_SFU_OP, + LOAD_OP, + TENSOR_CORE_LOAD_OP, + TENSOR_CORE_STORE_OP, + STORE_OP, + BRANCH_OP, + BARRIER_OP, + MEMORY_BARRIER_OP, + CALL_OPS, + RET_OPS +}; +typedef enum uarch_op_t op_type; + */ + +struct OpcodeChar +{ + OpcodeChar(unsigned m_opcode, unsigned m_opcode_category) { + opcode = m_opcode; + opcode_category = m_opcode_category; + } + unsigned opcode; + unsigned opcode_category; +}; + +///Volta SM_70 ISA +//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html +static const std::unordered_map OpcodeMap = { + //Floating Point 32 Instructions + {"FADD", OpcodeChar(OP_FADD, SP_OP)}, + {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, + {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, + {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, + {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, + {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, + {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, + {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, + {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, + {"FSET", OpcodeChar(OP_FSET, SP_OP)}, + {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, + {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, + {"MUFU", OpcodeChar(OP_MUFU, SP_OP)}, + + //Floating Point 16 Instructions + {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, + {"HADD2_32I", OpcodeChar(OP_HADD2_32I, SP_OP)}, + {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, + {"HFMA2_32I", OpcodeChar(OP_HFMA2_32I, SP_OP)}, + {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, + {"HMUL2_32I", OpcodeChar(OP_HMUL2_32I, SP_OP)}, + {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, + {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, + + //Tensor Core Instructions + {"HMMA", OpcodeChar(OP_HMMA, TENSOR_CORE_OP)}, + + //Double Point Instructions + {"DADD", OpcodeChar(OP_DADD, DP_OP)}, + {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, + {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, + {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, + + //Integer Instructions + {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, + {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, + {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, + {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, + {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, + {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, + {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, + {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, + {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, + {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, + {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, + {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, + {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, + {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, + {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, + {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, + {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, + {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, + {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, + {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, + {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, + {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, + {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, + {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, + {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, + {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, + + //Conversion Instructions + {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, + {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, + {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, + {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, + {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, + {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, + + //Movement Instructions + {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, + {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, + {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, + {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, + {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, + {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, + + //Predicate Instructions + {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, + {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, + {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, + {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, + + //Load/Store Instructions + {"LD", OpcodeChar(OP_LD, LOAD_OP)}, + {"LDC", OpcodeChar(OP_LDC, LOAD_OP)}, + {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, + {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, + {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, + {"ST", OpcodeChar(OP_ST, STORE_OP)}, + {"STG", OpcodeChar(OP_STG, STORE_OP)}, + {"STL", OpcodeChar(OP_STL, STORE_OP)}, + {"STS", OpcodeChar(OP_STS, STORE_OP)}, + {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, + {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, + {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, + {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, + {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, + {"RED", OpcodeChar(OP_RED, STORE_OP)}, + {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, + {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, + {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, + {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, + {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, + + //Texture Instructions + {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, + {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, + {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, + {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, + {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, + {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, + + //Control Instructions + {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, + {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, + {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, + {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, + {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, + {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, + {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, + {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, + {"EXIT", OpcodeChar(OP_EXIT, BRANCH_OP)}, + {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, + {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, + {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, + {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, + {"RET", OpcodeChar(OP_RET, RET_OPS)}, + {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, + {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, + {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, + {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, + + //Miscellaneous Instructions + {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, + {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, + {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, + {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, + {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, + {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, + {"LEPC", OpcodeChar(OP_LEPC ,ALU_OP)}, + {"NOP", OpcodeChar(OP_NOP ,ALU_OP)}, + {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, + {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, + {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, + {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, + {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, + {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, + {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, + +}; + +#endif -- cgit v1.3 From de903552c8d716e6b2bd6d0c816063523e35c6c5 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 16 Sep 2019 10:14:28 -0400 Subject: updating the parser --- src/trace-driven/gpgpusim_trace_driven_main.cc | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index c61810f..2560338 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -342,14 +342,21 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ ar2 = 0; memory_op = no_memory_op; data_size = 0; - - num_regs = reg_srcs_num+1; - num_operands = num_regs; op = ALU_OP; mem_op= NOT_TEX; + //get opcode and category + std::unordered_map::const_iterator it= OpcodeMap.find(opcode1.c_str()); + if (it != OpcodeMap.end()) { + m_opcode = it->second.opcode; + op = (op_type)(it->second.opcode_category); + } + else + assert(0 && "undefined instruction"); //fill regs information + num_regs = reg_srcs_num+1; + num_operands = num_regs; outcount=1; out[0]=reg_dest; arch_reg.dst[0]=reg_dest; @@ -362,16 +369,6 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ //handle: vector, store insts have no output, double inst and hmma, and 64 bit address - //get opcode and category - std::unordered_map::const_iterator it= OpcodeMap.find(opcode1.c_str()); - if (it != OpcodeMap.end()) { - m_opcode = it->second.opcode; - op = (op_type)(it->second.opcode_category); - } - else - assert(0 && "undefined instruction"); - - //fill latency and initl set_latency(op); @@ -381,6 +378,9 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ set_addr(i, mem_addresses[i]); } + // barrier_type bar_type; + // reduction_type red_type; + //fill memory space switch(m_opcode){ case OP_LD: -- cgit v1.3 From 5db69b3e5b058c030075c066db64922bf1e6af02 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Thu, 19 Sep 2019 22:06:15 -0400 Subject: support trace-driven and changing the shader.cc --- Makefile | 10 +- src/abstract_hardware_model.cc | 7 +- src/gpgpu-sim/gpu-sim.cc | 10 +- src/gpgpu-sim/mem_latency_stat.cc | 5 +- src/gpgpu-sim/shader.cc | 170 +++++++++++------ src/gpgpu-sim/shader.h | 7 +- src/trace-driven/gpgpusim_trace_driven_main.cc | 253 +++++++++++++++++++------ src/trace-driven/trace_driven.h | 53 +++++- src/trace-driven/trace_opcode.h | 3 +- 9 files changed, 386 insertions(+), 132 deletions(-) (limited to 'src') diff --git a/Makefile b/Makefile index 5cd3101..73f22c6 100644 --- a/Makefile +++ b/Makefile @@ -171,7 +171,15 @@ $(SIM_LIB_DIR)/libcudart.so: makedirs $(LIBS) cudalib $(SIM_LIB_DIR)/gpgpusim.out: makedirs $(LIBS) cudalib $(SIM_LIB_DIR)/libcudart.so - g++ -std=c++0x -L$(SIM_LIB_DIR) -I$(CUDA_INSTALL_PATH)/include -lcudart -o $(SIM_LIB_DIR)/gpgpusim.out src/trace-driven/gpgpusim_trace_driven_main.cc + ar rvs $(SIM_LIB_DIR)/libcudart_static.a\ + $(SIM_OBJ_FILES_DIR)/libcuda/*.o \ + $(SIM_OBJ_FILES_DIR)/cuda-sim/*.o \ + $(SIM_OBJ_FILES_DIR)/cuda-sim/decuda_pred_table/*.o \ + $(SIM_OBJ_FILES_DIR)/gpgpu-sim/*.o \ + $(SIM_OBJ_FILES_DIR)/$(INTERSIM)/*.o \ + $(SIM_OBJ_FILES_DIR)/*.o \ + $(MCPAT) + g++ -std=c++0x -L$(SIM_LIB_DIR) -I$(CUDA_INSTALL_PATH)/include -lcudart -lm -lz -lGL -pthread -o $(SIM_LIB_DIR)/gpgpusim.out src/trace-driven/gpgpusim_trace_driven_main.cc $(SIM_LIB_DIR)/libcudart.dylib: makedirs $(LIBS) cudalib g++ -dynamiclib -Wl,-headerpad_max_install_names,-undefined,dynamic_lookup,-compatibility_version,1.1,-current_version,1.1\ diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index e8e4b51..063aa8d 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -471,7 +471,8 @@ void warp_inst_t::generate_mem_accesses() } if ( space.get_type() == global_space ) { - m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_uncoalesced_gmem( pc, m_accessq.size() - starting_queue_size ); + //TO DO: check here + // m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_uncoalesced_gmem( pc, m_accessq.size() - starting_queue_size ); } m_mem_accesses_created=true; } @@ -706,7 +707,9 @@ void warp_inst_t::completed( unsigned long long cycle ) const { unsigned long long latency = cycle - issue_cycle; assert(latency <= cycle); // underflow detection - m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_latency(pc, latency * active_count()); + //check the trace mode here + //TO DO + //m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_latency(pc, latency * active_count()); } diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index a70185e..ed96d42 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -66,6 +66,7 @@ #include "stats.h" #include "../cuda-sim/cuda_device_runtime.h" #include "../../libcuda/gpgpu_context.h" +#include "../trace-driven/trace_driven.h" #ifdef GPGPUSIM_POWER_MODEL #include "power_interface.h" @@ -1482,7 +1483,12 @@ void shader_core_ctx::issue_block2core( kernel_info_t &kernel ) for (unsigned i = start_thread; iwarp_size; - nthreads_in_block += ptx_sim_init_thread(kernel,&m_thread[i],m_sid,i,cta_size-(i-start_thread),m_config->n_thread_per_shader,this,free_cta_hw_id,warp_id,m_cluster->get_gpu()); + if(m_gpu->get_config().is_trace_driven_mode()) { + trace_shader_core_ctx* trace_core = static_cast (this); + nthreads_in_block += trace_core->trace_sim_inc_thread(kernel); + } + else + nthreads_in_block += ptx_sim_init_thread(kernel,&m_thread[i],m_sid,i,cta_size-(i-start_thread),m_config->n_thread_per_shader,this,free_cta_hw_id,warp_id,m_cluster->get_gpu()); m_threadState[i].m_active = true; // load thread local memory and register file if(m_gpu->resume_option == 1 && kernel.get_uid() == m_gpu->resume_kernel && ctaid >= m_gpu->resume_CTA && ctaid < m_gpu->checkpoint_CTA_t ) @@ -1512,7 +1518,7 @@ void shader_core_ctx::issue_block2core( kernel_info_t &kernel ) m_barriers.allocate_barrier(free_cta_hw_id,warps); // initialize the SIMT stacks and fetch hardware - init_warps( free_cta_hw_id, start_thread, end_thread, ctaid, cta_size, kernel.get_uid()); + init_warps( free_cta_hw_id, start_thread, end_thread, ctaid, cta_size, kernel); m_n_active_cta++; shader_CTA_count_log(m_sid, 1); diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc index a1b43a8..1980a3b 100644 --- a/src/gpgpu-sim/mem_latency_stat.cc +++ b/src/gpgpu-sim/mem_latency_stat.cc @@ -195,8 +195,9 @@ void memory_stats_t::memlatstat_dram_access(mem_fetch *mf) } mem_access_type_stats[mf->get_access_type()][dram_id][bank]++; } - if (mf->get_pc() != (unsigned)-1) - m_gpu->gpgpu_ctx->stats->ptx_file_line_stats_add_dram_traffic(mf->get_pc(), mf->get_data_size()); + //TO DO: check here + //if (mf->get_pc() != (unsigned)-1) + // m_gpu->gpgpu_ctx->stats->ptx_file_line_stats_add_dram_traffic(mf->get_pc(), mf->get_data_size()); } void memory_stats_t::memlatstat_icnt2mem_pop(mem_fetch *mf) diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 86508f6..8dddc36 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -46,6 +46,7 @@ #include "traffic_breakdown.h" #include "shader_trace.h" #include "../../libcuda/gpgpu_context.h" +#include "../trace-driven/trace_driven.h" #define PRIORITIZE_MSHR_OVER_WB 1 #define MAX(a,b) (((a)>(b))?(a):(b)) @@ -453,9 +454,11 @@ void shader_core_ctx::reinit(unsigned start_thread, unsigned end_thread, bool re } } -void shader_core_ctx::init_warps( unsigned cta_id, unsigned start_thread, unsigned end_thread, unsigned ctaid, int cta_size, unsigned kernel_id ) +void shader_core_ctx::init_warps( unsigned cta_id, unsigned start_thread, unsigned end_thread, unsigned ctaid, int cta_size, kernel_info_t &kernel ) { + // address_type start_pc = next_pc(start_thread); + unsigned kernel_id = kernel.get_uid(); if (m_config->model == POST_DOMINATOR) { unsigned start_warp = start_thread / m_config->warp_size; unsigned warp_per_cta = cta_size / m_config->warp_size; @@ -482,8 +485,10 @@ void shader_core_ctx::init_warps( unsigned cta_id, unsigned start_thread, unsign m_simt_stack[i]->resume(fname); m_simt_stack[i]->get_pdom_stack_top_info(&pc,&rpc); for (unsigned t = 0; t < m_config->warp_size; t++) { - m_thread[i * m_config->warp_size + t]->set_npc(pc); - m_thread[i * m_config->warp_size + t]->update_pc(); + if(m_thread != NULL) { + m_thread[i * m_config->warp_size + t]->set_npc(pc); + m_thread[i * m_config->warp_size + t]->update_pc(); + } } start_pc=pc; } @@ -493,6 +498,11 @@ void shader_core_ctx::init_warps( unsigned cta_id, unsigned start_thread, unsign m_not_completed += n_active; ++m_active_warps; } + + if(m_gpu->get_config().is_trace_driven_mode()){ + trace_shader_core_ctx* trace_core = static_cast (this); + trace_core->init_traces( start_warp, end_warp, kernel ); + } } } @@ -741,33 +751,45 @@ void shader_core_stats::visualizer_print( gzFile visualizer_file ) other memory spaces */ void shader_core_ctx::decode() { - if( m_inst_fetch_buffer.m_valid ) { - // decode 1 or 2 instructions and place them into ibuffer - address_type pc = m_inst_fetch_buffer.m_pc; - const warp_inst_t* pI1 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc); - m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(0,pI1); - m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline(); - if( pI1 ) { - m_stats->m_num_decoded_insn[m_sid]++; - if(pI1->oprnd_type==INT_OP){ - m_stats->m_num_INTdecoded_insn[m_sid]++; - }else if(pI1->oprnd_type==FP_OP) { - m_stats->m_num_FPdecoded_insn[m_sid]++; - } - const warp_inst_t* pI2 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc+pI1->isize); - if( pI2 ) { - m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(1,pI2); - m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline(); - m_stats->m_num_decoded_insn[m_sid]++; - if(pI2->oprnd_type==INT_OP){ - m_stats->m_num_INTdecoded_insn[m_sid]++; - }else if(pI2->oprnd_type==FP_OP) { - m_stats->m_num_FPdecoded_insn[m_sid]++; - } - } - } - m_inst_fetch_buffer.m_valid = false; - } + if( m_inst_fetch_buffer.m_valid ) { + // decode 1 or 2 instructions and place them into ibuffer + address_type pc = m_inst_fetch_buffer.m_pc; + const warp_inst_t* pI1; + if(m_gpu->get_config().is_trace_driven_mode()){ + trace_shader_core_ctx* trace_core = static_cast (this); + pI1 = trace_core->m_trace_warp[m_inst_fetch_buffer.m_warp_id].get_next_inst(); + } + else + pI1 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc); + m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(0,pI1); + m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline(); + if( pI1 ) { + m_stats->m_num_decoded_insn[m_sid]++; + if(pI1->oprnd_type==INT_OP){ + m_stats->m_num_INTdecoded_insn[m_sid]++; + }else if(pI1->oprnd_type==FP_OP) { + m_stats->m_num_FPdecoded_insn[m_sid]++; + } + const warp_inst_t* pI2; + if(m_gpu->get_config().is_trace_driven_mode()){ + trace_shader_core_ctx* trace_core = static_cast (this); + pI2 = trace_core->m_trace_warp[m_inst_fetch_buffer.m_warp_id].get_next_inst(); + } + else + pI2 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc+pI1->isize); + if( pI2 ) { + m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(1,pI2); + m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline(); + m_stats->m_num_decoded_insn[m_sid]++; + if(pI2->oprnd_type==INT_OP){ + m_stats->m_num_INTdecoded_insn[m_sid]++; + }else if(pI2->oprnd_type==FP_OP) { + m_stats->m_num_FPdecoded_insn[m_sid]++; + } + } + } + m_inst_fetch_buffer.m_valid = false; + } } void shader_core_ctx::fetch() @@ -778,7 +800,12 @@ void shader_core_ctx::fetch() mem_fetch *mf = m_L1I->next_access(); m_warp[mf->get_wid()].clear_imiss_pending(); m_inst_fetch_buffer = ifetch_buffer_t(m_warp[mf->get_wid()].get_pc(), mf->get_access_size(), mf->get_wid()); - assert( m_warp[mf->get_wid()].get_pc() == (mf->get_addr()-PROGRAM_MEM_START)); // Verify that we got the instruction we were expecting. + if(m_gpu->get_config().is_trace_driven_mode()){ + trace_shader_core_ctx* trace_core = static_cast (this); + assert( trace_core->m_trace_warp[mf->get_wid()].get_pc() == (address_type)(mf->get_addr()-PROGRAM_MEM_START)); + } + else + assert( m_warp[mf->get_wid()].get_pc() == (mf->get_addr()-PROGRAM_MEM_START)); // Verify that we got the instruction we were expecting. m_inst_fetch_buffer.m_valid = true; m_warp[mf->get_wid()].set_last_fetch(m_gpu->gpu_sim_cycle); delete mf; @@ -797,10 +824,14 @@ void shader_core_ctx::fetch() if( m_threadState[tid].m_active == true ) { m_threadState[tid].m_active = false; unsigned cta_id = m_warp[warp_id].get_cta_id(); - register_cta_thread_exit(cta_id, &(m_thread[tid]->get_kernel())); + if(m_gpu->get_config().is_trace_driven_mode()) { + register_cta_thread_exit(cta_id, m_kernel); + } + else + register_cta_thread_exit(cta_id, &(m_thread[tid]->get_kernel())); m_not_completed -= 1; m_active_threads.reset(tid); - assert( m_thread[tid]!= NULL ); + if(!m_gpu->get_config().is_trace_driven_mode()) assert( m_thread[tid]!= NULL ); did_exit=true; } } @@ -812,9 +843,15 @@ void shader_core_ctx::fetch() // this code fetches instructions from the i-cache or generates memory requests if( !m_warp[warp_id].functional_done() && !m_warp[warp_id].imiss_pending() && m_warp[warp_id].ibuffer_empty() ) { - address_type pc = m_warp[warp_id].get_pc(); + address_type pc; + if(m_gpu->get_config().is_trace_driven_mode()){ + trace_shader_core_ctx* trace_core = static_cast (this); + pc = trace_core->m_trace_warp[warp_id].get_pc(); + } + else + pc = m_warp[warp_id].get_pc(); address_type ppc = pc + PROGRAM_MEM_START; - unsigned nbytes=16; + unsigned nbytes= m_gpu->get_config().is_trace_driven_mode()? 32 : 16; unsigned offset_in_block = pc & (m_config->m_L1I_config.get_line_sz()-1); if( (offset_in_block+nbytes) > m_config->m_L1I_config.get_line_sz() ) nbytes = (m_config->m_L1I_config.get_line_sz()-offset_in_block); @@ -869,25 +906,29 @@ void shader_core_ctx::func_exec_inst( warp_inst_t &inst ) void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t* next_inst, const active_mask_t &active_mask, unsigned warp_id, unsigned sch_id ) { warp_inst_t** pipe_reg = pipe_reg_set.get_free(m_config->sub_core_model, sch_id); - assert(pipe_reg); - - m_warp[warp_id].ibuffer_free(); - assert(next_inst->valid()); - **pipe_reg = *next_inst; // static instruction information - (*pipe_reg)->issue( active_mask, warp_id, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, m_warp[warp_id].get_dynamic_warp_id(), sch_id ); // dynamic instruction information - m_stats->shader_cycle_distro[2+(*pipe_reg)->active_count()]++; - func_exec_inst( **pipe_reg ); - if( next_inst->op == BARRIER_OP ){ - m_warp[warp_id].store_info_of_last_inst_at_barrier(*pipe_reg); - m_barriers.warp_reaches_barrier(m_warp[warp_id].get_cta_id(),warp_id,const_cast (next_inst)); - - }else if( next_inst->op == MEMORY_BARRIER_OP ){ - m_warp[warp_id].set_membar(); - } + assert(pipe_reg); + + m_warp[warp_id].ibuffer_free(); + assert(next_inst->valid()); + **pipe_reg = *next_inst; // static instruction information + (*pipe_reg)->issue( active_mask, warp_id, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, m_warp[warp_id].get_dynamic_warp_id(), sch_id ); // dynamic instruction information + m_stats->shader_cycle_distro[2+(*pipe_reg)->active_count()]++; + func_exec_inst( **pipe_reg ); + + if( next_inst->op == BARRIER_OP ){ + m_warp[warp_id].store_info_of_last_inst_at_barrier(*pipe_reg); + m_barriers.warp_reaches_barrier(m_warp[warp_id].get_cta_id(),warp_id,const_cast (next_inst)); + + }else if( next_inst->op == MEMORY_BARRIER_OP ){ + m_warp[warp_id].set_membar(); + } + + if(!m_gpu->get_config().is_trace_driven_mode()) //No SIMT-stack in trace-driven mode + updateSIMTStack(warp_id,*pipe_reg); + + m_scoreboard->reserveRegisters(*pipe_reg); + m_warp[warp_id].set_next_pc(next_inst->pc + next_inst->isize); - updateSIMTStack(warp_id,*pipe_reg); - m_scoreboard->reserveRegisters(*pipe_reg); - m_warp[warp_id].set_next_pc(next_inst->pc + next_inst->isize); } void shader_core_ctx::issue(){ @@ -1034,7 +1075,11 @@ void scheduler_unit::cycle() bool valid = warp(warp_id).ibuffer_next_valid(); bool warp_inst_issued = false; unsigned pc,rpc; - m_simt_stack[warp_id]->get_pdom_stack_top_info(&pc,&rpc); + if(m_shader->m_gpu->get_config().is_trace_driven_mode()) + pc = pI->pc; //assume no control hazard in trace mode. TO DO: to be fixed + else + m_simt_stack[warp_id]->get_pdom_stack_top_info(&pc,&rpc); + SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) has valid instruction (%s)\n", (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id(), m_shader->m_config->gpgpu_ctx->func_sim->ptx_get_insn_str( pc).c_str() ); @@ -1052,7 +1097,11 @@ void scheduler_unit::cycle() SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) passes scoreboard\n", (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id() ); ready_inst = true; - const active_mask_t &active_mask = m_simt_stack[warp_id]->get_active_mask(); + + //For Trace-driven, the active mask already set in from traces, so just read it from the inst + const active_mask_t &active_mask = m_shader->m_gpu->get_config().is_trace_driven_mode()? + pI->get_active_mask() : m_simt_stack[warp_id]->get_active_mask(); + assert( warp(warp_id).inst_in_pipeline() ); if ( (pI->op == LOAD_OP) || (pI->op == STORE_OP) || (pI->op == MEMORY_BARRIER_OP)||(pI->op==TENSOR_CORE_LOAD_OP)||(pI->op==TENSOR_CORE_STORE_OP) ) { @@ -3241,6 +3290,10 @@ void barrier_set_t::deallocate_barrier( unsigned cta_id ) warp_set_t at_barrier = warps & m_warp_at_barrier; assert( at_barrier.any() == false ); // no warps stuck at barrier warp_set_t active = warps & m_warp_active; + std::cout<n_simt_cores_per_cluster ]; for( unsigned i=0; i < config->n_simt_cores_per_cluster; i++ ) { unsigned sid = m_config->cid_to_sid(i,m_cluster_id); - m_core[i] = new shader_core_ctx(gpu,this,sid,m_cluster_id,config,mem_config,stats); + if(gpu->get_config().is_trace_driven_mode()) + m_core[i] = new trace_shader_core_ctx(gpu,this,sid,m_cluster_id,config,mem_config,stats); + else + m_core[i] = new shader_core_ctx(gpu,this,sid,m_cluster_id,config,mem_config,stats); m_core_sim_order.push_back(i); } } @@ -4158,3 +4214,5 @@ void shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned } } + + diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 667cb2d..ae88b7d 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1947,7 +1947,7 @@ public: } int test_res_bus(int latency); - void init_warps(unsigned cta_id, unsigned start_thread, unsigned end_thread,unsigned ctaid, int cta_size, unsigned kernel_id); + void init_warps(unsigned cta_id, unsigned start_thread, unsigned end_thread,unsigned ctaid, int cta_size, kernel_info_t &kernel); virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid); address_type next_pc( int tid ) const; void fetch(); @@ -1960,7 +1960,7 @@ public: friend class TwoLevelScheduler; friend class LooseRoundRobbinScheduler; void issue_warp( register_set& warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id, unsigned sch_id ); - void func_exec_inst( warp_inst_t &inst ); + virtual void func_exec_inst( warp_inst_t &inst ); // Returns numbers of addresses in translated_addrs unsigned translate_local_memaddr( address_type localaddr, unsigned tid, unsigned num_shader, unsigned datasize, new_addr_type* translated_addrs ); @@ -2052,7 +2052,8 @@ private: std::bitset m_occupied_hwtid; std::map m_occupied_cta_to_hwtid; - + //Trace-driven simulation + friend class trace_shader_core_ctx; }; class simt_core_cluster { diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 2560338..fea56c1 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -8,30 +8,32 @@ #include #include #include -#include #include -//#include "../abstract_hardware_model.h" -//#include "../option_parser.h" -//#include "../cuda-sim/cuda-sim.h" -//#include "../cuda-sim/ptx_ir.h" -//#include "../cuda-sim/ptx_parser.h" +#include "../abstract_hardware_model.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 "trace_opcode.h" +#include "../gpgpusim_entrypoint.h" +//#include "gpgpu_context.h" //#include "../stream_manager.h" void arguments_check(); + int main ( int argc, const char **argv ) { - gpgpu_context* m_gpgpu_context = GPGPU_Context(); + gpgpu_context* m_gpgpu_context = new gpgpu_context(); gpgpu_sim * m_gpgpu_sim = m_gpgpu_context->gpgpu_trace_sim_init_perf(argc,argv); m_gpgpu_sim->init(); @@ -187,6 +189,7 @@ trace_kernel_info_t* trace_parser::parse_kernel_info(const std::string& kerneltr else if (string1 == "cuda" && string2 == "stream") { sscanf(line.c_str(), "-cuda stream id = %d", &cuda_stream_id); } + std::cout << line << std::endl; continue; } } @@ -212,22 +215,49 @@ void trace_parser::kernel_finalizer(trace_kernel_info_t* kernel_info){ delete kernel_info; } -bool trace_kernel_info_t::get_next_threadblock_traces(std::vector>& threadblock_traces) { +const trace_warp_inst_t* trace_shd_warp_t::get_next_inst(){ + return &warp_traces[trace_pc++]; +} + +void trace_shd_warp_t::clear() { + trace_pc=0; + warp_traces.clear(); +} + +bool trace_shd_warp_t::trace_done() { + return trace_pc==warp_traces.size(); +} - threadblock_traces.clear(); - unsigned warps_per_tb = ceil(float(threads_per_cta()/32)); - threadblock_traces.resize(warps_per_tb); +address_type trace_shd_warp_t::get_start_pc(){ + assert(warp_traces.size() > 0); + return warp_traces[0].pc; +} + +address_type trace_shd_warp_t::get_pc(){ + assert(warp_traces.size() > 0); + return warp_traces[trace_pc].pc; +} + +bool trace_kernel_info_t::get_next_threadblock_traces(std::vector*> threadblock_traces) { + + for(unsigned i=0; iclear(); + } + //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()) { + std::string line; + std::stringstream ss; + std::string string1, string2; + getline(*ifs, line); if (line.length() == 0) { @@ -238,32 +268,41 @@ bool trace_kernel_info_t::get_next_threadblock_traces(std::vector>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 + assert(0 && "Parsing error: thread block start before the previous one finish"); + std::cout<reserve(insts_num); + //std::cout << line << std::endl; } else { assert(start_of_tb_stream_found); trace_warp_inst_t inst(m_gpgpu_sim->getShaderCoreConfig(), m_gpgpu_context); + //std::cout<push_back(inst); } } } @@ -282,8 +321,9 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ 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; + unsigned reg_dest[4]; std::string opcode; + unsigned reg_dsts_num=0; unsigned reg_srcs_num=0; unsigned reg_srcs[4]; unsigned mem_width=0; @@ -292,20 +332,30 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ ss>>std::dec>>threadblock_x>>threadblock_y>>threadblock_z>>warpid_tb>>sm_id>>warpid_sm; ss>>std::hex>>m_pc>>mask; + //std::cout<<"m_pc= "<>reg_dsts_num; + + for(unsigned i=0; i>std::dec>>temp; + sscanf(temp.c_str(), "R%d", ®_dest[i]); + } ss>>opcode; + ss>>reg_srcs_num; for(unsigned i=0; i>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++) { @@ -327,7 +377,9 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ //fill and initialize common params m_decoded = true; - pc = m_pc; + pc = (address_type)m_pc; //we will lose the high 32 bits from casting long to unsigned, it should be okay! + //std::cout<<"pc= "<::const_iterator it= OpcodeMap.find(opcode1.c_str()); + std::unordered_map::const_iterator it= OpcodeMap.find(opcode1); if (it != OpcodeMap.end()) { m_opcode = it->second.opcode; op = (op_type)(it->second.opcode_category); } - else + else { + std::cout<<"ERROR: undefined instruction : "<0); data_size = mem_width; memory_op = memory_load; + cache_op = CACHE_ALL; if(m_opcode == OP_LDL) space.set_type(local_space); else @@ -403,6 +460,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ assert(mem_width>0); data_size = mem_width; memory_op = memory_store; + cache_op = CACHE_ALL; if(m_opcode == OP_STL) space.set_type(local_space); else @@ -410,6 +468,14 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ if(m_opcode == OP_ATOM || m_opcode == OP_ATOMG || m_opcode == OP_RED) m_isatomic = true; + + for(unsigned m=0; m*> threadblock_traces; + for (unsigned i = start_warp; i < end_warp; ++i) { + threadblock_traces.push_back(&(m_trace_warp[i].warp_traces)); + } + trace_kernel_info_t& trace_kernel = static_cast (kernel); + trace_kernel.get_next_threadblock_traces(threadblock_traces); + + //set pc + for (unsigned i = start_warp; i < end_warp; ++i) { + m_warp[i].set_next_pc(m_trace_warp[i].get_start_pc()); + } +} + + +void trace_shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid) +{ + if(inst.isatomic()) + m_warp[inst.warp_id()].inc_n_atomic(); + + if ( m_trace_warp[inst.warp_id()].trace_done() ) { + m_warp[inst.warp_id()].set_completed(t); + m_warp[inst.warp_id()].ibuffer_flush(); + } + +} + +void trace_shader_core_ctx::func_exec_inst( warp_inst_t &inst ) +{ + //here, we generate memory acessess and set the status if thread (done?) + if( inst.is_load() || inst.is_store() ) + { + inst.generate_mem_accesses(); + } + for ( unsigned t=0; t < m_warp_size; t++ ) { + if( inst.active(t) ) { + unsigned warpId = inst.warp_id(); + unsigned tid=m_warp_size*warpId+t; + + //virtual function + checkExecutionStatusAndUpdate(inst,t,tid); + } + } + if(m_trace_warp[inst.warp_id()].trace_done() ) + m_barriers.warp_exit( inst.warp_id() ); +} diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index fbf7a1e..2f97958 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -24,6 +24,10 @@ public: m_kernel_info = info; } + virtual ~trace_function_info() { + + } + private: @@ -33,21 +37,23 @@ class trace_warp_inst_t: public warp_inst_t { public: trace_warp_inst_t() { - + m_gpgpu_context=NULL; + m_opcode=0; } + trace_warp_inst_t(const class core_config *config, gpgpu_context* gpgpu_context ):warp_inst_t(config) { m_gpgpu_context = gpgpu_context; m_opcode=0; } bool parse_from_string(std::string trace); - + unsigned m_opcode; private: void set_latency(unsigned cat); gpgpu_context* m_gpgpu_context; - unsigned m_opcode; + }; @@ -59,7 +65,7 @@ public: m_gpgpu_context = gpgpu_context; } - bool get_next_threadblock_traces(std::vector>& threadblock_traces); + bool get_next_threadblock_traces(std::vector*> threadblock_traces); private: std::ifstream* ifs; @@ -87,15 +93,48 @@ private: }; -class trace_shd_warp_t: public shd_warp_t { +class trace_shd_warp_t { public: - trace_shd_warp_t(class shader_core_ctx *shader, unsigned warp_size):shd_warp_t(shader, warp_size) { + trace_shd_warp_t() { + trace_pc=0; } - bool get_next_threadblock_traces(std::vector>& threadblock_traces); + std::vector warp_traces; + const trace_warp_inst_t* get_next_inst(); + void clear(); + bool trace_done(); + address_type get_start_pc(); + address_type get_pc(); + unsigned trace_pc; private: + +}; + +class trace_shader_core_ctx: public shader_core_ctx { + +public: + trace_shader_core_ctx(class gpgpu_sim *gpu, + class simt_core_cluster *cluster, + unsigned shader_id, + unsigned tpc_id, + const shader_core_config *config, + const memory_config *mem_config, + shader_core_stats *stats):shader_core_ctx(gpu, cluster, shader_id, tpc_id, config, mem_config, stats) { + + m_trace_warp.resize(get_config()->max_warps_per_shader); + } + + virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid); + void init_traces( unsigned start_warp, unsigned end_warp, kernel_info_t &kernel ); + unsigned trace_sim_inc_thread( kernel_info_t &kernel); + virtual void func_exec_inst( warp_inst_t &inst ); + std::vector m_trace_warp; + +private: + + }; #endif diff --git a/src/trace-driven/trace_opcode.h b/src/trace-driven/trace_opcode.h index f809238..827c32c 100644 --- a/src/trace-driven/trace_opcode.h +++ b/src/trace-driven/trace_opcode.h @@ -5,6 +5,7 @@ #include "../abstract_hardware_model.h" #include +#include enum TraceInstrOpcode { @@ -60,7 +61,7 @@ struct OpcodeChar ///Volta SM_70 ISA //see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map OpcodeMap = { +static const std::unordered_map OpcodeMap = { //Floating Point 32 Instructions {"FADD", OpcodeChar(OP_FADD, SP_OP)}, {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, -- cgit v1.3 From 177afa15266ddcc87cc60ecda552717e07197eaa Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Fri, 20 Sep 2019 15:17:56 -0400 Subject: removing some comments and refectoring the code --- src/abstract_hardware_model.cc | 7 ++--- src/cuda-sim/ptx-stats.cc | 24 +++++++++------ src/gpgpu-sim/mem_latency_stat.cc | 6 ++-- src/gpgpu-sim/shader.cc | 4 --- src/trace-driven/gpgpusim_trace_driven_main.cc | 41 +++++--------------------- src/trace-driven/trace_driven.h | 16 +++------- 6 files changed, 32 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index 063aa8d..758ec00 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -471,8 +471,7 @@ void warp_inst_t::generate_mem_accesses() } if ( space.get_type() == global_space ) { - //TO DO: check here - // m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_uncoalesced_gmem( pc, m_accessq.size() - starting_queue_size ); + m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_uncoalesced_gmem( pc, m_accessq.size() - starting_queue_size ); } m_mem_accesses_created=true; } @@ -707,9 +706,7 @@ void warp_inst_t::completed( unsigned long long cycle ) const { unsigned long long latency = cycle - issue_cycle; assert(latency <= cycle); // underflow detection - //check the trace mode here - //TO DO - //m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_latency(pc, latency * active_count()); + m_config->gpgpu_ctx->stats->ptx_file_line_stats_add_latency(pc, latency * active_count()); } diff --git a/src/cuda-sim/ptx-stats.cc b/src/cuda-sim/ptx-stats.cc index 22517df..2af65e5 100644 --- a/src/cuda-sim/ptx-stats.cc +++ b/src/cuda-sim/ptx-stats.cc @@ -154,8 +154,9 @@ void ptx_file_line_stats_add_exec_count(const ptx_instruction *pInsn) void ptx_stats::ptx_file_line_stats_add_latency(unsigned pc, unsigned latency) { const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); - - ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), pInsn->source_line())].latency += latency; + + if(pInsn != NULL) + ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), pInsn->source_line())].latency += latency; } // attribute dram traffic to this ptx instruction (specified by the pc) @@ -164,7 +165,8 @@ void ptx_stats::ptx_file_line_stats_add_dram_traffic(unsigned pc, unsigned dram_ { const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); - ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), pInsn->source_line())].dram_traffic += dram_traffic; + if(pInsn != NULL) + ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), pInsn->source_line())].dram_traffic += dram_traffic; } // attribute the number of shared memory access cycles to a ptx instruction @@ -173,9 +175,11 @@ void ptx_stats::ptx_file_line_stats_add_smem_bank_conflict(unsigned pc, unsigned { const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); - ptx_file_line_stats& line_stats = ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), pInsn->source_line())]; - line_stats.smem_n_way_bank_conflict_total += n_way_bkconflict; - line_stats.smem_warp_count += 1; + if(pInsn != NULL) { + ptx_file_line_stats& line_stats = ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), pInsn->source_line())]; + line_stats.smem_n_way_bank_conflict_total += n_way_bkconflict; + line_stats.smem_warp_count += 1; + } } // attribute a non-coalesced mem access to a ptx instruction @@ -184,9 +188,11 @@ void ptx_stats::ptx_file_line_stats_add_uncoalesced_gmem(unsigned pc, unsigned n { const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); - ptx_file_line_stats& line_stats = ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), pInsn->source_line())]; - line_stats.gmem_n_access_total += n_access; - line_stats.gmem_warp_count += 1; + if(pInsn != NULL) { + ptx_file_line_stats& line_stats = ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), pInsn->source_line())]; + line_stats.gmem_n_access_total += n_access; + line_stats.gmem_warp_count += 1; + } } // a class that tracks the inflight memory instructions of a shader core diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc index 1980a3b..2141e10 100644 --- a/src/gpgpu-sim/mem_latency_stat.cc +++ b/src/gpgpu-sim/mem_latency_stat.cc @@ -195,9 +195,9 @@ void memory_stats_t::memlatstat_dram_access(mem_fetch *mf) } mem_access_type_stats[mf->get_access_type()][dram_id][bank]++; } - //TO DO: check here - //if (mf->get_pc() != (unsigned)-1) - // m_gpu->gpgpu_ctx->stats->ptx_file_line_stats_add_dram_traffic(mf->get_pc(), mf->get_data_size()); + + if (mf->get_pc() != (unsigned)-1) + m_gpu->gpgpu_ctx->stats->ptx_file_line_stats_add_dram_traffic(mf->get_pc(), mf->get_data_size()); } void memory_stats_t::memlatstat_icnt2mem_pop(mem_fetch *mf) diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 8dddc36..cc85f3f 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3290,10 +3290,6 @@ void barrier_set_t::deallocate_barrier( unsigned cta_id ) warp_set_t at_barrier = warps & m_warp_at_barrier; assert( at_barrier.any() == false ); // no warps stuck at barrier warp_set_t active = warps & m_warp_active; - std::cout<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; @@ -273,11 +263,9 @@ bool trace_kernel_info_t::get_next_threadblock_traces(std::vectorreserve(insts_num); - //std::cout << line << std::endl; } else { assert(start_of_tb_stream_found); trace_warp_inst_t inst(m_gpgpu_sim->getShaderCoreConfig(), m_gpgpu_context); - //std::cout<push_back(inst); } @@ -329,16 +314,15 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ unsigned mem_width=0; unsigned long long mem_addresses[warp_size()]; + //Start Parsing ss>>std::dec>>threadblock_x>>threadblock_y>>threadblock_z>>warpid_tb>>sm_id>>warpid_sm; - ss>>std::hex>>m_pc>>mask; - //std::cout<<"m_pc= "<>opcode; ss>>reg_srcs_num; - for(unsigned i=0; i>temp; sscanf(temp.c_str(), "R%d", ®_srcs[i]); @@ -365,7 +348,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ mem_addresses[s]=0; } } - + //Finish Parsing //After parsing, fill the inst_t and warp_inst_t params //fill active mask @@ -378,7 +361,6 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ //fill and initialize common params m_decoded = true; pc = (address_type)m_pc; //we will lose the high 32 bits from casting long to unsigned, it should be okay! - //std::cout<<"pc= "< m_trace_warp; + friend class shader_core_ctx; private: - + std::vector m_trace_warp; }; -- cgit v1.3 From f0c49462c773613155bb40febb75f807336edb3b Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Tue, 24 Sep 2019 12:43:49 -0400 Subject: adding traces generator --- src/trace-driven/gpgpusim_trace_driven_main.cc | 8 +- src/trace-driven/trace_opcode.h | 3 +- .../traces-generator/Gbit_tool/Makefile | 23 + .../traces-generator/Gbit_tool/traceall.cu | 646 +++++++++++++++++++++ src/trace-driven/traces-generator/README | 1 + .../traces-post-processing/Makefile | 11 + .../post-traces-processing.cpp | 195 +++++++ 7 files changed, 882 insertions(+), 5 deletions(-) create mode 100644 src/trace-driven/traces-generator/Gbit_tool/Makefile create mode 100644 src/trace-driven/traces-generator/Gbit_tool/traceall.cu create mode 100644 src/trace-driven/traces-generator/README create mode 100755 src/trace-driven/traces-generator/traces-post-processing/Makefile create mode 100644 src/trace-driven/traces-generator/traces-post-processing/post-traces-processing.cpp (limited to 'src') diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 76c2cda..82f284c 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -394,14 +394,14 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ num_operands = num_regs; outcount=reg_dsts_num; for(unsigned m=0; m OpcodeMap = { {"FSET", OpcodeChar(OP_FSET, SP_OP)}, {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, - {"MUFU", OpcodeChar(OP_MUFU, SP_OP)}, + //SFU + {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, //Floating Point 16 Instructions {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, diff --git a/src/trace-driven/traces-generator/Gbit_tool/Makefile b/src/trace-driven/traces-generator/Gbit_tool/Makefile new file mode 100644 index 0000000..fc0209a --- /dev/null +++ b/src/trace-driven/traces-generator/Gbit_tool/Makefile @@ -0,0 +1,23 @@ +NVCC=nvcc -ccbin=`which gcc` -D_FORCE_INLINES +NVBIT_PATH=../../core +INCLUDES=-I$(NVBIT_PATH) +LIBS=-L$(NVBIT_PATH) -lnvbit +NVCC_PATH=-L $(subst bin/nvcc,lib64,$(shell which nvcc | tr -s /)) +SOURCES=$(wildcard *.cu) +OBJECTS=$(SOURCES:.cu=.o) +ARCH=35 + +mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) +current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) + +all: $(OBJECTS) $(NVBIT_PATH)/libnvbit.a + $(NVCC) -arch=sm_$(ARCH) -O3 *.o $(LIBS) $(NVCC_PATH) -lcuda -lcudart_static -shared -o ${current_dir}.so + +%.o: %.cu + $(NVCC) -dc -c -std=c++11 $(INCLUDES) -Xptxas -cloning=no -maxrregcount=16 -Xcompiler -Wall -arch=sm_$(ARCH) -O3 -Xcompiler -fPIC $< -o $@ + +$(NVBIT_PATH)/libnvbit.a: + make -C $(NVBIT_PATH) + +clean: + rm -f *.so *.o diff --git a/src/trace-driven/traces-generator/Gbit_tool/traceall.cu b/src/trace-driven/traces-generator/Gbit_tool/traceall.cu new file mode 100644 index 0000000..1426528 --- /dev/null +++ b/src/trace-driven/traces-generator/Gbit_tool/traceall.cu @@ -0,0 +1,646 @@ +/* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of NVIDIA CORPORATION nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Author: Oreste Villa, ovilla@nvidia.com - 2018 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* every tool needs to include this once */ +#include "nvbit_tool.h" + +/* nvbit interface file */ +#include "nvbit.h" + +/* for channel */ +#include "utils/channel.hpp" + +/* for _cuda_safe and GET_VAR* macros */ +#include "macros.h" + +/* Channel used to communicate from GPU to CPU receiving thread */ +#define CHANNEL_SIZE (1l << 20) +static __managed__ ChannelDev channel_dev; +static ChannelHost channel_host; + +/* receiving thread and its control variables */ +pthread_t recv_thread; +volatile bool recv_thread_started = false; +volatile bool recv_thread_receiving = false; + +/* skip flag used to avoid re-entry on the nvbit_callback when issuing + * flush_channel kernel call */ +bool skip_flag = false; + +/* global control variables for this tool */ +uint32_t instr_begin_interval = 0; +uint32_t instr_end_interval = UINT32_MAX; +int verbose = 0; + +/* opcode to id map and reverse map */ +std::map opcode_to_id_map; +std::map id_to_opcode_map; + +/* kernel instruction counter, updated by the GPU */ +static __managed__ uint64_t total_dynamic_instr_counter = 0; +static __managed__ uint64_t reported_dynamic_instr_counter = 0; +static __managed__ uint64_t dynamic_instr_limit = 0; +uint64_t dynamic_instr_limit_input = 0; //0 means no limit + +#define MAX_SRC 4 +/* information collected in the instrumentation function */ +typedef struct { + int cta_id_x; + int cta_id_y; + int cta_id_z; + int warpid_tb; + int warpid_sm; + int sm_id; + int opcode_id; + uint64_t addrs[32]; + uint32_t vpc; + bool is_mem; + int32_t GPRDst; + int32_t GPRSrcs[MAX_SRC]; + int32_t numSrcs; + int32_t width; + uint32_t active_mask; + +} mem_access_t; + +/* Instrumentation function that we want to inject, please note the use of + * 1. extern "C" __device__ __noinline__ + * To prevent "dead"-code elimination by the compiler. + * 2. NVBIT_EXPORT_FUNC(dev_func) + * To notify nvbit the name of the function we want to inject. + * This name must match exactly the function name. + */ +extern "C" __device__ __noinline__ void instrument_mem(int pred, int opcode_id, int32_t vpc, + uint32_t reg_high, + uint32_t reg_low, + int32_t imm, + int32_t srcReg1, int32_t srcReg2, int32_t desReg, int32_t width) { + if (!pred) { + return; + } + + uint32_t active_mask = __ballot(1); + const int laneid = get_laneid(); + const int first_laneid = __ffs(active_mask) - 1; + + if (dynamic_instr_limit && total_dynamic_instr_counter >= dynamic_instr_limit) + if (first_laneid == laneid) { + atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); + return; + } + + mem_access_t ma; + + /* collect memory address information */ + int64_t base_addr = (((uint64_t)reg_high) << 32) | ((uint64_t)reg_low); + uint64_t addr = base_addr + imm; + for (int i = 0; i < 32; i++) { + ma.addrs[i] = __shfl(addr, i); + } + + int4 cta = get_ctaid(); + int uniqe_threadId = threadIdx.z * blockDim.y * blockDim.x + threadIdx.y * blockDim.x + threadIdx.x; + ma.warpid_tb = uniqe_threadId/32; + + ma.cta_id_x = cta.x; + ma.cta_id_y = cta.y; + ma.cta_id_z = cta.z; + ma.warpid_sm = get_warpid(); + ma.opcode_id = opcode_id; + ma.is_mem = true; + ma.vpc = vpc; + ma.width = width; + ma.GPRDst = desReg; + ma.GPRSrcs[0] = srcReg1; + ma.GPRSrcs[1] = srcReg2; + ma.GPRSrcs[2] = -1; + ma.GPRSrcs[3] = -1; + ma.numSrcs = 2; + ma.active_mask = active_mask; + ma.sm_id = get_smid(); + + /* first active lane pushes information on the channel */ + if (first_laneid == laneid) { + channel_dev.push(&ma, sizeof(mem_access_t)); + atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); + atomicAdd((unsigned long long*)&reported_dynamic_instr_counter, 1); + } +} +NVBIT_EXPORT_FUNC(instrument_mem); + + +extern "C" __device__ __noinline__ void instrument_inst(int pred, int opcode_id, + uint32_t vpc, int desReg, int srcReg1, int srcReg2, int srcReg3, int srcReg4, int srcNum) { + if (!pred) { + return; + } + + int active_mask = __ballot(1); + const int laneid = get_laneid(); + const int first_laneid = __ffs(active_mask) - 1; + + if (dynamic_instr_limit && total_dynamic_instr_counter >= dynamic_instr_limit) + if (first_laneid == laneid) { + atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); + return; + } + + + mem_access_t ma; + + int4 cta = get_ctaid(); + int uniqe_threadId = threadIdx.z * blockDim.y * blockDim.x + threadIdx.y * blockDim.x + threadIdx.x; + ma.warpid_tb = uniqe_threadId/32; + + ma.cta_id_x = cta.x; + ma.cta_id_y = cta.y; + ma.cta_id_z = cta.z; + ma.warpid_sm = get_warpid(); + ma.opcode_id = opcode_id; + ma.is_mem = false; + ma.vpc = vpc; + + ma.GPRDst = desReg; + ma.numSrcs = srcNum; //this is the total src number including the register and others + ma.GPRSrcs[0] = srcReg1; + ma.GPRSrcs[1] = srcReg2; + ma.GPRSrcs[2] = srcReg3; + ma.GPRSrcs[3] = srcReg4; + + ma.active_mask = active_mask; + ma.sm_id = get_smid(); + + /* first active lane pushes information on the channel */ + if (first_laneid == laneid) { + channel_dev.push(&ma, sizeof(mem_access_t)); + atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); + atomicAdd((unsigned long long*)&reported_dynamic_instr_counter, 1); + } +} + +NVBIT_EXPORT_FUNC(instrument_inst); + +void nvbit_at_init() { + setenv("CUDA_MANAGED_FORCE_DEVICE_ALLOC", "1", 1); + GET_VAR_INT( + instr_begin_interval, "INSTR_BEGIN", 0, + "Beginning of the instruction interval where to apply instrumentation"); + GET_VAR_INT( + instr_end_interval, "INSTR_END", UINT32_MAX, + "End of the instruction interval where to apply instrumentation"); + GET_VAR_LONG( + dynamic_instr_limit_input, "DYNAMIC_INSTR_LIMIT", 0, + "Limit of the number instructions to be printed, 0 means no limit"); + GET_VAR_INT(verbose, "TOOL_VERBOSE", 0, "Enable verbosity inside the tool"); + std::string pad(100, '-'); + printf("%s\n", pad.c_str()); +} + +/* instrument each memory instruction adding a call to the above instrumentation + * function */ +void nvbit_at_function_first_load(CUcontext ctx, CUfunction f) { + + dynamic_instr_limit = dynamic_instr_limit_input; + + const std::vector &instrs = nvbit_get_instrs(ctx, f); + if (verbose) { + printf("Inspecting function %s at address 0x%lx\n", + nvbit_get_func_name(ctx, f), nvbit_get_func_addr(f)); + } + + uint32_t cnt = 0; + /* iterate on all the static instructions in the function */ + for (auto instr : instrs) { + if (cnt < instr_begin_interval || cnt >= instr_end_interval ) { + cnt++; + continue; + } + //if (verbose) { + instr->printDecoded(); + //} + + if (opcode_to_id_map.find(instr->getOpcode()) == + opcode_to_id_map.end()) { + int opcode_id = opcode_to_id_map.size(); + opcode_to_id_map[instr->getOpcode()] = opcode_id; + id_to_opcode_map[opcode_id] = instr->getOpcode(); + } + + int opcode_id = opcode_to_id_map[instr->getOpcode()]; + + //TO DO: handle generic and TEX memory space + if(instr->isLoad() && !instr->isStore() && instr->getMemOpType() != Instr::CONSTANT) { //Mem load inst //ignore constant for now + assert(instr->getNumOperands() == 2); + + /* get the operand */ + const Instr::operand_t *dst = instr->getOperand(0); + const Instr::operand_t *src = instr->getOperand(1); + + assert(dst->type == Instr::REG); + assert(src->type == Instr::MREF); + + /* insert call to the instrumentation function with its + * arguments */ + nvbit_insert_call(instr, "instrument_mem", IPOINT_BEFORE); + nvbit_add_call_arg_pred_val(instr); + nvbit_add_call_arg_const_val32(instr, opcode_id); + nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); + if (instr->isExtended()) { + nvbit_add_call_arg_reg_val(instr, (int)src->value[0] + 1); + } else { + nvbit_add_call_arg_reg_val(instr, (int)Instr::RZ); + } + nvbit_add_call_arg_reg_val(instr, (int)src->value[0]); + nvbit_add_call_arg_const_val32(instr, (int)src->value[1]); + nvbit_add_call_arg_const_val32(instr, (int)src->value[0]); + nvbit_add_call_arg_const_val32(instr, -1); + nvbit_add_call_arg_const_val32(instr, (int)dst->value[0]); + nvbit_add_call_arg_const_val32(instr, (int)instr->getSize()); + } + else if(instr->isStore() && !instr->isLoad() && instr->getMemOpType() != Instr::CONSTANT) { //Mem store inst //ignore constant for now + assert(instr->getNumOperands() == 2); + + /* get the operand */ + const Instr::operand_t *dst = instr->getOperand(0); + const Instr::operand_t *src = instr->getOperand(1); + + assert(dst->type == Instr::MREF); + assert(src->type == Instr::REG); + + /* insert call to the instrumentation function with its + * arguments */ + nvbit_insert_call(instr, "instrument_mem", IPOINT_BEFORE); + nvbit_add_call_arg_pred_val(instr); + nvbit_add_call_arg_const_val32(instr, opcode_id); + nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); + if (instr->isExtended()) { + nvbit_add_call_arg_reg_val(instr, (int)dst->value[0] + 1); + } else { + nvbit_add_call_arg_reg_val(instr, (int)Instr::RZ); + } + nvbit_add_call_arg_reg_val(instr, (int)dst->value[0]); + nvbit_add_call_arg_const_val32(instr, (int)dst->value[1]); + nvbit_add_call_arg_const_val32(instr, (int)dst->value[0]); + nvbit_add_call_arg_const_val32(instr, (int)src->value[0]); + nvbit_add_call_arg_const_val32(instr, -1); + nvbit_add_call_arg_const_val32(instr, (int)instr->getSize()); + } + else if(instr->isLoad() && instr->isStore() && instr->getMemOpType() != Instr::CONSTANT) { //if it is load and store i.e. atomic inst + assert(instr->getNumOperands() == 2); + + /* get the operand */ + const Instr::operand_t *dst = instr->getOperand(0); + const Instr::operand_t *src = instr->getOperand(1); + + assert(dst->type == Instr::MREF); + assert(src->type == Instr::REG); + + /* insert call to the instrumentation function with its + * arguments */ + nvbit_insert_call(instr, "instrument_mem", IPOINT_BEFORE); + nvbit_add_call_arg_pred_val(instr); + nvbit_add_call_arg_const_val32(instr, opcode_id); + nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); + if (instr->isExtended()) { + nvbit_add_call_arg_reg_val(instr, (int)dst->value[0] + 1); + } else { + nvbit_add_call_arg_reg_val(instr, (int)Instr::RZ); + } + nvbit_add_call_arg_reg_val(instr, (int)dst->value[0]); + nvbit_add_call_arg_const_val32(instr, (int)dst->value[1]); + nvbit_add_call_arg_const_val32(instr, (int)dst->value[0]); + nvbit_add_call_arg_const_val32(instr, (int)src->value[0]); + nvbit_add_call_arg_const_val32(instr, -1); + nvbit_add_call_arg_const_val32(instr, (int)instr->getSize()); + } + else //Other ALU, FP, DP insts + { + + nvbit_insert_call(instr, "instrument_inst", IPOINT_BEFORE); + nvbit_add_call_arg_pred_val(instr); + nvbit_add_call_arg_const_val32(instr, opcode_id); + nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); + int srcNum = 0; + for (int i = 0; i < MAX_SRC+1; i++) { + /* get the operand "i" */ + if(i < instr->getNumOperands()) { + const Instr::operand_t *op = instr->getOperand(i); + if (op->type == Instr::REG) + nvbit_add_call_arg_const_val32(instr, (int)op->value[0]); + else + nvbit_add_call_arg_const_val32(instr, -1); + + srcNum++; + } + else + nvbit_add_call_arg_const_val32(instr, -1); + } + nvbit_add_call_arg_const_val32(instr, srcNum); + } + cnt++; + } +} + +__global__ void flush_channel() { + /* push memory access with negative cta id to communicate the kernel is + * completed */ + mem_access_t ma; + ma.cta_id_x = -1; + channel_dev.push(&ma, sizeof(mem_access_t)); + + /* flush channel */ + channel_dev.flush(); +} + +static FILE *resultsFile = NULL; +static FILE *kernelsFile= NULL; +static FILE *statsFile= NULL; +static int kernelid = 1; + +unsigned old_total_insts = 0; +unsigned old_total_reported_insts = 0; + + +void nvbit_at_cuda_event(CUcontext ctx, int is_exit, nvbit_api_cuda_t cbid, + const char *name, void *params, CUresult *pStatus) { + if (skip_flag) return; + + if (cbid == API_CUDA_cuLaunchKernel_ptsz || + cbid == API_CUDA_cuLaunchKernel) { + cuLaunchKernel_params *p = (cuLaunchKernel_params *)params; + + if (!is_exit) { + + + if (mkdir("traces", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) { + if( errno == EEXIST ) { + // alredy exists + } else { + // something else + std::cout << "cannot create folder error:" << strerror(errno) << std::endl; + return; + } + } + + int nregs; + _cuda_safe( + cuFuncGetAttribute(&nregs, CU_FUNC_ATTRIBUTE_NUM_REGS, p->f)); + + int shmem_static_nbytes; + _cuda_safe(cuFuncGetAttribute(&shmem_static_nbytes, + CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES, + p->f)); + + + + std::string func_name(nvbit_get_func_name(ctx, p->f)); + std::string::size_type end_pos = func_name.find('('); + if (end_pos != std::string::npos) + { + // std::string::size_type pos = func_name.find('<'); + //if (pos != std::string::npos) + // end_pos = pos; + + //std::string::size_type start_pos = func_name.find(' '); + //if (start_pos == std::string::npos) + // start_pos = 0; + //else + // start_pos++; + + func_name = func_name.substr(0, end_pos); + } + + char buffer[1024]; + sprintf (buffer, "./traces/%d-%s.trace", kernelid, func_name.c_str()); + + resultsFile = fopen(buffer, "w"); + + printf("Writing results to %s\n", buffer); + + fprintf(resultsFile, "-kernel name = %s", nvbit_get_func_name(ctx, p->f)); + fprintf(resultsFile, "\n"); + fprintf(resultsFile, "-kernel id = %d", kernelid); + fprintf(resultsFile, "\n"); + fprintf(resultsFile, "-grid dim = (%d,%d,%d)", p->gridDimX, p->gridDimY, p->gridDimZ); + fprintf(resultsFile, "\n"); + fprintf(resultsFile, "-block dim = (%d,%d,%d)", p->blockDimX, p->blockDimY, p->blockDimZ); + fprintf(resultsFile, "\n"); + fprintf(resultsFile, "-shmem = %d", shmem_static_nbytes + p->sharedMemBytes); + fprintf(resultsFile, "\n"); + fprintf(resultsFile, "-nregs = %d", nregs); + fprintf(resultsFile, "\n"); + fprintf(resultsFile, "-cuda stream id = %d", (uint64_t)p->hStream); + fprintf(resultsFile, "\n\n"); + + fprintf(resultsFile, "#traces format = threadblock_x threadblock_y threadblock_z warpid_tb sm_id warpid_sm PC mask dest_num reg_dests opcode src_num reg_srcs mem_width mem_addresses"); + fprintf(resultsFile, "\n"); + + if (kernelid == 1) { + kernelsFile = fopen("./traces/kernelslist", "w"); + statsFile = fopen("./traces/stats.csv", "w"); + fprintf(statsFile, "kernel name,total_insts,total_reported_insts\n"); + } + else { + kernelsFile = fopen("./traces/kernelslist", "a"); + statsFile = fopen("./traces/stats.csv", "a"); + } + + sprintf (buffer, "%d-%s.trace", kernelid, func_name.c_str()); + fprintf(kernelsFile, buffer); + fprintf(kernelsFile, "\n"); + fclose(kernelsFile); + + fprintf(statsFile, buffer); + fprintf(statsFile, ","); + + kernelid++; + recv_thread_receiving = true; + + } else { + /* make sure current kernel is completed */ + cudaDeviceSynchronize(); + assert(cudaGetLastError() == cudaSuccess); + + /* make sure we prevent re-entry on the nvbit_callback when issuing + * the flush_channel kernel */ + skip_flag = true; + + /* issue flush of channel so we are sure all the memory accesses + * have been pushed */ + flush_channel<<<1, 1>>>(); + cudaDeviceSynchronize(); + assert(cudaGetLastError() == cudaSuccess); + + /* unset the skip flag */ + skip_flag = false; + + /* wait here until the receiving thread has not finished with the + * current kernel */ + while (recv_thread_receiving) { + pthread_yield(); + } + + unsigned total_insts_per_kernel = total_dynamic_instr_counter - old_total_insts; + old_total_insts = total_dynamic_instr_counter; + + unsigned reported_insts_per_kernel = reported_dynamic_instr_counter - old_total_reported_insts; + old_total_reported_insts = reported_dynamic_instr_counter; + + fprintf(statsFile, ""); + fprintf(statsFile, "%d,%d",total_insts_per_kernel,reported_insts_per_kernel); + fprintf(statsFile, "\n"); + + + fclose(resultsFile); + fclose(statsFile); + } + } +} + +bool is_number(const std::string& s) +{ + std::string::const_iterator it = s.begin(); + while (it != s.end() && std::isdigit(*it)) ++it; + return !s.empty() && it == s.end(); +} + +void *recv_thread_fun(void *) { + char *recv_buffer = (char *)malloc(CHANNEL_SIZE); + + while (recv_thread_started) { + uint32_t num_recv_bytes = 0; + if (recv_thread_receiving && + (num_recv_bytes = channel_host.recv(recv_buffer, CHANNEL_SIZE)) > + 0) { + uint32_t num_processed_bytes = 0; + while (num_processed_bytes < num_recv_bytes) { + mem_access_t *ma = + (mem_access_t *)&recv_buffer[num_processed_bytes]; + + /* when we get this cta_id_x it means the kernel has completed + */ + if (ma->cta_id_x == -1) { + recv_thread_receiving = false; + break; + } + + fprintf(resultsFile, "%d ", ma->cta_id_x); + fprintf(resultsFile, "%d ", ma->cta_id_y); + fprintf(resultsFile, "%d ", ma->cta_id_z); + fprintf(resultsFile, "%d ", ma->warpid_tb); + fprintf(resultsFile, "%d ", ma->sm_id); + fprintf(resultsFile, "%d ", ma->warpid_sm); + fprintf(resultsFile, "0x%016lx ", ma->vpc); // Print the virtual PC. + fprintf(resultsFile, "%-8.8" PRIx32 " ", ma->active_mask); + if(ma->GPRDst >= 0) { + fprintf(resultsFile, "1 "); + fprintf(resultsFile, "R%d ", ma->GPRDst); + } + else + fprintf(resultsFile, "0 "); + + // Print the opcode. + fprintf(resultsFile, "%s ", id_to_opcode_map[ma->opcode_id].c_str()); + unsigned src_count=0; + for (int s = 0; s < MAX_SRC; s++) // GPR srcs count. + if(ma->GPRSrcs[s] >= 0) src_count++; + fprintf(resultsFile, "%d ", src_count); + + for (int s = 0; s < MAX_SRC; s++) // GPR srcs. + if(ma->GPRSrcs[s] >= 0) fprintf(resultsFile, "R%d ", ma->GPRSrcs[s]); + + //print addresses + std::bitset<32> mask(ma->active_mask); + if(ma->is_mem) { + //fprintf(resultsFile, "%d ", ma->width); + std::istringstream iss(id_to_opcode_map[ma->opcode_id]); + std::vector tokens; + std::string token; + while (std::getline(iss, token, '.')) { + if (!token.empty()) + tokens.push_back(token); + } + if (tokens.size()>=3){ + if (is_number(tokens[2])){ + fprintf(resultsFile, "%d ", (std::stoi(tokens[2],nullptr)/8)); + } + else{ + fprintf(resultsFile, "%d ", 4); + } + } + else{ + fprintf(resultsFile, "%d ", 4); + } + + for (int s = 0; s < 32; s++) + if(mask.test(s)) + fprintf(resultsFile, "0x%016lx ", ma->addrs[s]); + } + else + { + fprintf(resultsFile, "0 "); + } + + fprintf(resultsFile, "\n"); + + num_processed_bytes += sizeof(mem_access_t); + } + } + } + free(recv_buffer); + return NULL; +} + +void nvbit_at_ctx_init(CUcontext ctx) { + recv_thread_started = true; + channel_host.init(0, CHANNEL_SIZE, &channel_dev, NULL); + pthread_create(&recv_thread, NULL, recv_thread_fun, NULL); +} + +void nvbit_at_ctx_term(CUcontext ctx) { + if (recv_thread_started) { + recv_thread_started = false; + pthread_join(recv_thread, NULL); + } +} diff --git a/src/trace-driven/traces-generator/README b/src/trace-driven/traces-generator/README new file mode 100644 index 0000000..d79d075 --- /dev/null +++ b/src/trace-driven/traces-generator/README @@ -0,0 +1 @@ +TO DO diff --git a/src/trace-driven/traces-generator/traces-post-processing/Makefile b/src/trace-driven/traces-generator/traces-post-processing/Makefile new file mode 100755 index 0000000..63c3f38 --- /dev/null +++ b/src/trace-driven/traces-generator/traces-post-processing/Makefile @@ -0,0 +1,11 @@ +TARGET := post-traces-processing + +$(TARGET): post-traces-processing.cpp + g++ -o $@ $^ + +run: $(TARGET) + ./$(TARGET) + +clean: + rm -f $(TARGET) *.o + diff --git a/src/trace-driven/traces-generator/traces-post-processing/post-traces-processing.cpp b/src/trace-driven/traces-generator/traces-post-processing/post-traces-processing.cpp new file mode 100644 index 0000000..0dbb4e1 --- /dev/null +++ b/src/trace-driven/traces-generator/traces-post-processing/post-traces-processing.cpp @@ -0,0 +1,195 @@ +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +struct threadblock_info +{ + bool initialized; + unsigned tb_id_x, tb_id_y, tb_id_z; + vector< vector< string > > warp_insts_array; + threadblock_info() { + initialized = false; + tb_id_x = tb_id_y = tb_id_z = 0; + } +}; + +void group_per_block(const char* filepath); +void group_per_core(const char* filepath); + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +int main(int argc, char** argv) +{ + + string kernellist_filepath; + bool is_per_core; + if(argc == 1) + { + cout << "File path is missing\n"; + return 0; + } else if(argc == 2) + { + kernellist_filepath = argv[1]; + is_per_core = true; + + } else if(argc == 3) { + kernellist_filepath = argv[1]; + is_per_core = bool(argv[2]); + } + else { + cout << "Too Many Arguemnts!\n"; + return 0; + } + + ifstream ifs; + ofstream ofs; + + ifs.open(kernellist_filepath.c_str()); + ofs.open((string(kernellist_filepath) + ".g").c_str()); + + if (!ifs.is_open()) { + cout << "Unable to open file: " < insts; + unsigned grid_dim_x, grid_dim_y, grid_dim_z, tb_dim_x, tb_dim_y, tb_dim_z; + unsigned tb_id_x, tb_id_y, tb_id_z, tb_id, warpid_tb; + string line; + stringstream ss; + string string1, string2; + bool found_grid_dim = false, found_block_dim = false; + + while(!ifs.eof()) { + getline(ifs, line); + + if (line.length() == 0 || line[0] == '#') { + ofs<>string1>>string2; + if(string1 == "grid" && string2 == "dim") { + sscanf(line.c_str(), "-grid dim = (%d,%d,%d)", &grid_dim_x, &grid_dim_y, &grid_dim_z); + found_grid_dim = true; + } + else if (string1 == "block" && string2 == "dim") { + sscanf(line.c_str(), "-block dim = (%d,%d,%d)", &tb_dim_x, &tb_dim_y, &tb_dim_z); + found_block_dim = true; + } + + if(found_grid_dim && found_block_dim) { + insts.resize(grid_dim_x*grid_dim_y*grid_dim_z); + for(unsigned i = 0; i>tb_id_x>>tb_id_y>>tb_id_z>>warpid_tb; + tb_id = tb_id_z * grid_dim_y * grid_dim_x + tb_id_y * grid_dim_x + tb_id_x; + if(!insts[tb_id].initialized) { + insts[tb_id].tb_id_x = tb_id_x; + insts[tb_id].tb_id_y = tb_id_y; + insts[tb_id].tb_id_z = tb_id_z; + insts[tb_id].initialized = true; + } + insts[tb_id].warp_insts_array[warpid_tb].push_back(line); + } + + } + + + for(unsigned i=0; i 0) { + ofs< Date: Fri, 27 Sep 2019 17:41:53 -0400 Subject: cleat the traces PC bug --- src/trace-driven/gpgpusim_trace_driven_main.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 82f284c..56e493c 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -208,7 +208,10 @@ void trace_parser::kernel_finalizer(trace_kernel_info_t* kernel_info){ } const trace_warp_inst_t* trace_shd_warp_t::get_next_inst(){ - return &warp_traces[trace_pc++]; + if(trace_pc < warp_traces.size()) + return &warp_traces[trace_pc++]; + else + return NULL; } void trace_shd_warp_t::clear() { @@ -217,7 +220,7 @@ void trace_shd_warp_t::clear() { } bool trace_shd_warp_t::trace_done() { - return trace_pc==warp_traces.size(); + return trace_pc==(warp_traces.size()); } address_type trace_shd_warp_t::get_start_pc(){ @@ -226,7 +229,8 @@ address_type trace_shd_warp_t::get_start_pc(){ } address_type trace_shd_warp_t::get_pc(){ - assert(warp_traces.size() > 0); + assert(warp_traces.size() > 0 ); + assert(trace_pc < warp_traces.size()); return warp_traces[trace_pc].pc; } @@ -581,6 +585,7 @@ void trace_shader_core_ctx::init_traces( unsigned start_warp, unsigned end_warp, std::vector*> threadblock_traces; for (unsigned i = start_warp; i < end_warp; ++i) { + m_trace_warp[i].clear(); threadblock_traces.push_back(&(m_trace_warp[i].warp_traces)); } trace_kernel_info_t& trace_kernel = static_cast (kernel); -- cgit v1.3 From a113dfbbd5393146e778acd66d37ac1dd84bf0ec Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 30 Sep 2019 10:52:51 -0400 Subject: fixing the execution-driven linking error --- Makefile | 5 +- src/trace-driven/gpgpusim_trace_driven_main.cc | 545 ------------------------- 2 files changed, 3 insertions(+), 547 deletions(-) (limited to 'src') diff --git a/Makefile b/Makefile index bebe6f2..acef015 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,7 @@ endif $(shell mkdir -p $(SIM_OBJ_FILES_DIR)/libcuda && echo "const char *g_gpgpusim_build_string=\"$(GPGPUSIM_BUILD)\";" > $(SIM_OBJ_FILES_DIR)/detailed_version) -LIBS = cuda-sim gpgpu-sim_uarch $(INTERSIM) gpgpusimlib +LIBS = cuda-sim gpgpu-sim_uarch $(INTERSIM) gpgpusimlib trace-driven TARGETS = @@ -150,6 +150,7 @@ $(SIM_LIB_DIR)/libcudart.so: makedirs $(LIBS) cudalib $(SIM_OBJ_FILES_DIR)/cuda-sim/decuda_pred_table/*.o \ $(SIM_OBJ_FILES_DIR)/gpgpu-sim/*.o \ $(SIM_OBJ_FILES_DIR)/$(INTERSIM)/*.o \ + $(SIM_OBJ_FILES_DIR)/trace-driven/*.o \ $(SIM_OBJ_FILES_DIR)/*.o -lm -lz -lGL -pthread \ $(MCPAT) \ -o $(SIM_LIB_DIR)/libcudart.so @@ -220,7 +221,7 @@ cuda-sim: makedirs $(MAKE) -C ./src/cuda-sim/ trace-driven: makedirs - g++ -std=c++0x -c src/trace-driven/gpgpusim_trace_driven_main.cc + g++ -fPIC -std=c++0x -I$(CUDA_INSTALL_PATH)/include -c src/trace-driven/trace_driven.cc -o $(SIM_OBJ_FILES_DIR)/trace-driven/trace_driven.o gpgpu-sim_uarch: makedirs cuda-sim $(MAKE) -C ./src/gpgpu-sim/ depend diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 56e493c..642b91a 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -13,8 +13,6 @@ #include "../abstract_hardware_model.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 "../../libcuda/gpgpu_context.h" #include "trace_driven.h" @@ -87,546 +85,3 @@ int main ( int argc, const char **argv ) 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 trace_parser::parse_kernellist_file() { - - ifs.open(kernellist_filename); - - if (!ifs.is_open()) { - std::cout << "Unable to open file: " < 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: " <>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); - } - std::cout << line << std::endl; - 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, m_gpgpu_context); - - 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; -} - -const trace_warp_inst_t* trace_shd_warp_t::get_next_inst(){ - if(trace_pc < warp_traces.size()) - return &warp_traces[trace_pc++]; - else - return NULL; -} - -void trace_shd_warp_t::clear() { - trace_pc=0; - warp_traces.clear(); -} - -bool trace_shd_warp_t::trace_done() { - return trace_pc==(warp_traces.size()); -} - -address_type trace_shd_warp_t::get_start_pc(){ - assert(warp_traces.size() > 0); - return warp_traces[0].pc; -} - -address_type trace_shd_warp_t::get_pc(){ - assert(warp_traces.size() > 0 ); - assert(trace_pc < warp_traces.size()); - return warp_traces[trace_pc].pc; -} - -bool trace_kernel_info_t::get_next_threadblock_traces(std::vector*> threadblock_traces) { - - for(unsigned i=0; iclear(); - } - - unsigned block_id_x=0, block_id_y=0, block_id_z=0; - unsigned warp_id=0; - unsigned insts_num=0; - - - bool start_of_tb_stream_found = false; - - while(!ifs->eof()) { - std::string line; - std::stringstream ss; - std::string string1, string2; - - 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); - std::cout << line << std::endl; - } - 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]->reserve(insts_num); - } - else { - assert(start_of_tb_stream_found); - trace_warp_inst_t inst(m_gpgpu_sim->getShaderCoreConfig(), m_gpgpu_context); - 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[4]; - std::string opcode; - unsigned reg_dsts_num=0; - unsigned reg_srcs_num=0; - unsigned reg_srcs[4]; - unsigned mem_width=0; - unsigned long long mem_addresses[warp_size()]; - - //Start Parsing - ss>>std::dec>>threadblock_x>>threadblock_y>>threadblock_z>>warpid_tb>>sm_id>>warpid_sm; - - ss>>std::hex>>m_pc; - ss>>std::hex>>mask; - - std::bitset mask_bits(mask); - - ss>>std::dec>>reg_dsts_num; - for(unsigned i=0; i>std::dec>>temp; - sscanf(temp.c_str(), "R%d", ®_dest[i]); - } - - ss>>opcode; - - ss>>reg_srcs_num; - for(unsigned i=0; i>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; - } - } - //Finish Parsing - //After parsing, fill the inst_t and warp_inst_t params - - //fill active mask - active_mask_t active_mask = mask_bits; - set_active( active_mask ); - - //get the opcode - std::string opcode1 = opcode.substr(0, opcode.find(".")); - - //fill and initialize common params - m_decoded = true; - pc = (address_type)m_pc; //we will lose the high 32 bits from casting long to unsigned, it should be okay! - - isize = 16; //TO DO, change this - for(unsigned i=0; i::const_iterator it= OpcodeMap.find(opcode1); - if (it != OpcodeMap.end()) { - m_opcode = it->second.opcode; - op = (op_type)(it->second.opcode_category); - } - else { - std::cout<<"ERROR: undefined instruction : "< 0) { - for(unsigned i=0; i0); - data_size = mem_width; - memory_op = memory_load; - cache_op = CACHE_ALL; - if(m_opcode == OP_LDL) - space.set_type(local_space); - else - space.set_type(global_space); - break; - case OP_ST: - case OP_STG: - case OP_STL: - case OP_ATOM: - case OP_ATOMG: - case OP_RED: - assert(mem_width>0); - data_size = mem_width; - memory_op = memory_store; - cache_op = CACHE_ALL; - if(m_opcode == OP_STL) - space.set_type(local_space); - else - space.set_type(global_space); - - if(m_opcode == OP_ATOM || m_opcode == OP_ATOMG || m_opcode == OP_RED) - m_isatomic = true; - - break; - case OP_LDS: - case OP_STS: - case OP_ATOMS: - assert(mem_width>0); - data_size = mem_width; - space.set_type(shared_space); - break; - case OP_BAR: - //TO DO fill this correctly - bar_id = 0; - bar_count = (unsigned)-1; - bar_type = SYNC; - //TO DO - //if bar_type = RED; - //set bar_type - // barrier_type bar_type; - // reduction_type red_type; - break; - default: - break; - } - - return true; -} - -void trace_warp_inst_t::set_latency(unsigned category) -{ - unsigned int_latency[5]; - unsigned fp_latency[5]; - unsigned dp_latency[5]; - unsigned sfu_latency; - unsigned tensor_latency; - unsigned int_init[5]; - unsigned fp_init[5]; - unsigned dp_init[5]; - unsigned sfu_init; - unsigned tensor_init; - - /* - * [0] ADD,SUB - * [1] MAX,Min - * [2] MUL - * [3] MAD - * [4] DIV - */ - sscanf(m_gpgpu_context->func_sim->opcode_latency_int, "%u,%u,%u,%u,%u", - &int_latency[0],&int_latency[1],&int_latency[2], - &int_latency[3],&int_latency[4]); - sscanf(m_gpgpu_context->func_sim->opcode_latency_fp, "%u,%u,%u,%u,%u", - &fp_latency[0],&fp_latency[1],&fp_latency[2], - &fp_latency[3],&fp_latency[4]); - sscanf(m_gpgpu_context->func_sim->opcode_latency_dp, "%u,%u,%u,%u,%u", - &dp_latency[0],&dp_latency[1],&dp_latency[2], - &dp_latency[3],&dp_latency[4]); - sscanf(m_gpgpu_context->func_sim->opcode_latency_sfu, "%u", - &sfu_latency); - sscanf(m_gpgpu_context->func_sim->opcode_latency_tensor, "%u", - &tensor_latency); - sscanf(m_gpgpu_context->func_sim->opcode_initiation_int, "%u,%u,%u,%u,%u", - &int_init[0],&int_init[1],&int_init[2], - &int_init[3],&int_init[4]); - sscanf(m_gpgpu_context->func_sim->opcode_initiation_fp, "%u,%u,%u,%u,%u", - &fp_init[0],&fp_init[1],&fp_init[2], - &fp_init[3],&fp_init[4]); - sscanf(m_gpgpu_context->func_sim->opcode_initiation_dp, "%u,%u,%u,%u,%u", - &dp_init[0],&dp_init[1],&dp_init[2], - &dp_init[3],&dp_init[4]); - sscanf(m_gpgpu_context->func_sim->opcode_initiation_sfu, "%u", - &sfu_init); - sscanf(m_gpgpu_context->func_sim->opcode_initiation_tensor, "%u", - &tensor_init); - sscanf(m_gpgpu_context->func_sim->cdp_latency_str, "%u,%u,%u,%u,%u", - &m_gpgpu_context->func_sim->cdp_latency[0], - &m_gpgpu_context->func_sim->cdp_latency[1], - &m_gpgpu_context->func_sim->cdp_latency[2], - &m_gpgpu_context->func_sim->cdp_latency[3], - &m_gpgpu_context->func_sim->cdp_latency[4]); - - initiation_interval = latency = 1; - - switch(category){ - case ALU_OP: - case INTP_OP: - case BRANCH_OP: - case CALL_OPS: - case RET_OPS: - latency = int_latency[0]; - initiation_interval = int_init[0]; - break; - case SP_OP: - latency = fp_latency[0]; - initiation_interval = fp_latency[0]; - break; - case DP_OP: - latency = dp_latency[0]; - initiation_interval = dp_latency[0]; - break; - case SFU_OP: - latency = sfu_latency; - initiation_interval = sfu_init; - break; - case TENSOR_CORE_OP: - latency = tensor_latency; - initiation_interval = tensor_init; - break; - default: - break; - } - -} - -unsigned trace_shader_core_ctx::trace_sim_inc_thread( kernel_info_t &kernel) -{ - - if ( kernel.no_more_ctas_to_run() ) { - return 0; //finished! - } - - if( kernel.more_threads_in_cta() ) { - kernel.increment_thread_id(); - } - - if( !kernel.more_threads_in_cta() ) - kernel.increment_cta_id(); - - return 1; -} - -void trace_shader_core_ctx::init_traces( unsigned start_warp, unsigned end_warp, kernel_info_t &kernel ) { - - std::vector*> threadblock_traces; - for (unsigned i = start_warp; i < end_warp; ++i) { - m_trace_warp[i].clear(); - threadblock_traces.push_back(&(m_trace_warp[i].warp_traces)); - } - trace_kernel_info_t& trace_kernel = static_cast (kernel); - trace_kernel.get_next_threadblock_traces(threadblock_traces); - - //set pc - for (unsigned i = start_warp; i < end_warp; ++i) { - m_warp[i].set_next_pc(m_trace_warp[i].get_start_pc()); - } -} - - -void trace_shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid) -{ - if(inst.isatomic()) - m_warp[inst.warp_id()].inc_n_atomic(); - - if ( m_trace_warp[inst.warp_id()].trace_done() ) { - m_warp[inst.warp_id()].set_completed(t); - m_warp[inst.warp_id()].ibuffer_flush(); - } - -} - -void trace_shader_core_ctx::func_exec_inst( warp_inst_t &inst ) -{ - //here, we generate memory acessess and set the status if thread (done?) - if( inst.is_load() || inst.is_store() ) - { - inst.generate_mem_accesses(); - } - for ( unsigned t=0; t < m_warp_size; t++ ) { - if( inst.active(t) ) { - unsigned warpId = inst.warp_id(); - unsigned tid=m_warp_size*warpId+t; - - //virtual function - checkExecutionStatusAndUpdate(inst,t,tid); - } - } - if(m_trace_warp[inst.warp_id()].trace_done() ) - m_barriers.warp_exit( inst.warp_id() ); -} - -- cgit v1.3 From 7d9d7f330af172a73a77203dc7b0154f45988f00 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 30 Sep 2019 10:53:45 -0400 Subject: changing traces directory name --- .../traces-generator/Gbit_tool/Makefile | 23 - .../traces-generator/Gbit_tool/traceall.cu | 646 --------------------- .../traces-generator/NVbit_tool/Makefile | 23 + .../traces-generator/NVbit_tool/traceall.cu | 646 +++++++++++++++++++++ 4 files changed, 669 insertions(+), 669 deletions(-) delete mode 100644 src/trace-driven/traces-generator/Gbit_tool/Makefile delete mode 100644 src/trace-driven/traces-generator/Gbit_tool/traceall.cu create mode 100644 src/trace-driven/traces-generator/NVbit_tool/Makefile create mode 100644 src/trace-driven/traces-generator/NVbit_tool/traceall.cu (limited to 'src') diff --git a/src/trace-driven/traces-generator/Gbit_tool/Makefile b/src/trace-driven/traces-generator/Gbit_tool/Makefile deleted file mode 100644 index fc0209a..0000000 --- a/src/trace-driven/traces-generator/Gbit_tool/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -NVCC=nvcc -ccbin=`which gcc` -D_FORCE_INLINES -NVBIT_PATH=../../core -INCLUDES=-I$(NVBIT_PATH) -LIBS=-L$(NVBIT_PATH) -lnvbit -NVCC_PATH=-L $(subst bin/nvcc,lib64,$(shell which nvcc | tr -s /)) -SOURCES=$(wildcard *.cu) -OBJECTS=$(SOURCES:.cu=.o) -ARCH=35 - -mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) -current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) - -all: $(OBJECTS) $(NVBIT_PATH)/libnvbit.a - $(NVCC) -arch=sm_$(ARCH) -O3 *.o $(LIBS) $(NVCC_PATH) -lcuda -lcudart_static -shared -o ${current_dir}.so - -%.o: %.cu - $(NVCC) -dc -c -std=c++11 $(INCLUDES) -Xptxas -cloning=no -maxrregcount=16 -Xcompiler -Wall -arch=sm_$(ARCH) -O3 -Xcompiler -fPIC $< -o $@ - -$(NVBIT_PATH)/libnvbit.a: - make -C $(NVBIT_PATH) - -clean: - rm -f *.so *.o diff --git a/src/trace-driven/traces-generator/Gbit_tool/traceall.cu b/src/trace-driven/traces-generator/Gbit_tool/traceall.cu deleted file mode 100644 index 1426528..0000000 --- a/src/trace-driven/traces-generator/Gbit_tool/traceall.cu +++ /dev/null @@ -1,646 +0,0 @@ -/* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of NVIDIA CORPORATION nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Author: Oreste Villa, ovilla@nvidia.com - 2018 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* every tool needs to include this once */ -#include "nvbit_tool.h" - -/* nvbit interface file */ -#include "nvbit.h" - -/* for channel */ -#include "utils/channel.hpp" - -/* for _cuda_safe and GET_VAR* macros */ -#include "macros.h" - -/* Channel used to communicate from GPU to CPU receiving thread */ -#define CHANNEL_SIZE (1l << 20) -static __managed__ ChannelDev channel_dev; -static ChannelHost channel_host; - -/* receiving thread and its control variables */ -pthread_t recv_thread; -volatile bool recv_thread_started = false; -volatile bool recv_thread_receiving = false; - -/* skip flag used to avoid re-entry on the nvbit_callback when issuing - * flush_channel kernel call */ -bool skip_flag = false; - -/* global control variables for this tool */ -uint32_t instr_begin_interval = 0; -uint32_t instr_end_interval = UINT32_MAX; -int verbose = 0; - -/* opcode to id map and reverse map */ -std::map opcode_to_id_map; -std::map id_to_opcode_map; - -/* kernel instruction counter, updated by the GPU */ -static __managed__ uint64_t total_dynamic_instr_counter = 0; -static __managed__ uint64_t reported_dynamic_instr_counter = 0; -static __managed__ uint64_t dynamic_instr_limit = 0; -uint64_t dynamic_instr_limit_input = 0; //0 means no limit - -#define MAX_SRC 4 -/* information collected in the instrumentation function */ -typedef struct { - int cta_id_x; - int cta_id_y; - int cta_id_z; - int warpid_tb; - int warpid_sm; - int sm_id; - int opcode_id; - uint64_t addrs[32]; - uint32_t vpc; - bool is_mem; - int32_t GPRDst; - int32_t GPRSrcs[MAX_SRC]; - int32_t numSrcs; - int32_t width; - uint32_t active_mask; - -} mem_access_t; - -/* Instrumentation function that we want to inject, please note the use of - * 1. extern "C" __device__ __noinline__ - * To prevent "dead"-code elimination by the compiler. - * 2. NVBIT_EXPORT_FUNC(dev_func) - * To notify nvbit the name of the function we want to inject. - * This name must match exactly the function name. - */ -extern "C" __device__ __noinline__ void instrument_mem(int pred, int opcode_id, int32_t vpc, - uint32_t reg_high, - uint32_t reg_low, - int32_t imm, - int32_t srcReg1, int32_t srcReg2, int32_t desReg, int32_t width) { - if (!pred) { - return; - } - - uint32_t active_mask = __ballot(1); - const int laneid = get_laneid(); - const int first_laneid = __ffs(active_mask) - 1; - - if (dynamic_instr_limit && total_dynamic_instr_counter >= dynamic_instr_limit) - if (first_laneid == laneid) { - atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); - return; - } - - mem_access_t ma; - - /* collect memory address information */ - int64_t base_addr = (((uint64_t)reg_high) << 32) | ((uint64_t)reg_low); - uint64_t addr = base_addr + imm; - for (int i = 0; i < 32; i++) { - ma.addrs[i] = __shfl(addr, i); - } - - int4 cta = get_ctaid(); - int uniqe_threadId = threadIdx.z * blockDim.y * blockDim.x + threadIdx.y * blockDim.x + threadIdx.x; - ma.warpid_tb = uniqe_threadId/32; - - ma.cta_id_x = cta.x; - ma.cta_id_y = cta.y; - ma.cta_id_z = cta.z; - ma.warpid_sm = get_warpid(); - ma.opcode_id = opcode_id; - ma.is_mem = true; - ma.vpc = vpc; - ma.width = width; - ma.GPRDst = desReg; - ma.GPRSrcs[0] = srcReg1; - ma.GPRSrcs[1] = srcReg2; - ma.GPRSrcs[2] = -1; - ma.GPRSrcs[3] = -1; - ma.numSrcs = 2; - ma.active_mask = active_mask; - ma.sm_id = get_smid(); - - /* first active lane pushes information on the channel */ - if (first_laneid == laneid) { - channel_dev.push(&ma, sizeof(mem_access_t)); - atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); - atomicAdd((unsigned long long*)&reported_dynamic_instr_counter, 1); - } -} -NVBIT_EXPORT_FUNC(instrument_mem); - - -extern "C" __device__ __noinline__ void instrument_inst(int pred, int opcode_id, - uint32_t vpc, int desReg, int srcReg1, int srcReg2, int srcReg3, int srcReg4, int srcNum) { - if (!pred) { - return; - } - - int active_mask = __ballot(1); - const int laneid = get_laneid(); - const int first_laneid = __ffs(active_mask) - 1; - - if (dynamic_instr_limit && total_dynamic_instr_counter >= dynamic_instr_limit) - if (first_laneid == laneid) { - atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); - return; - } - - - mem_access_t ma; - - int4 cta = get_ctaid(); - int uniqe_threadId = threadIdx.z * blockDim.y * blockDim.x + threadIdx.y * blockDim.x + threadIdx.x; - ma.warpid_tb = uniqe_threadId/32; - - ma.cta_id_x = cta.x; - ma.cta_id_y = cta.y; - ma.cta_id_z = cta.z; - ma.warpid_sm = get_warpid(); - ma.opcode_id = opcode_id; - ma.is_mem = false; - ma.vpc = vpc; - - ma.GPRDst = desReg; - ma.numSrcs = srcNum; //this is the total src number including the register and others - ma.GPRSrcs[0] = srcReg1; - ma.GPRSrcs[1] = srcReg2; - ma.GPRSrcs[2] = srcReg3; - ma.GPRSrcs[3] = srcReg4; - - ma.active_mask = active_mask; - ma.sm_id = get_smid(); - - /* first active lane pushes information on the channel */ - if (first_laneid == laneid) { - channel_dev.push(&ma, sizeof(mem_access_t)); - atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); - atomicAdd((unsigned long long*)&reported_dynamic_instr_counter, 1); - } -} - -NVBIT_EXPORT_FUNC(instrument_inst); - -void nvbit_at_init() { - setenv("CUDA_MANAGED_FORCE_DEVICE_ALLOC", "1", 1); - GET_VAR_INT( - instr_begin_interval, "INSTR_BEGIN", 0, - "Beginning of the instruction interval where to apply instrumentation"); - GET_VAR_INT( - instr_end_interval, "INSTR_END", UINT32_MAX, - "End of the instruction interval where to apply instrumentation"); - GET_VAR_LONG( - dynamic_instr_limit_input, "DYNAMIC_INSTR_LIMIT", 0, - "Limit of the number instructions to be printed, 0 means no limit"); - GET_VAR_INT(verbose, "TOOL_VERBOSE", 0, "Enable verbosity inside the tool"); - std::string pad(100, '-'); - printf("%s\n", pad.c_str()); -} - -/* instrument each memory instruction adding a call to the above instrumentation - * function */ -void nvbit_at_function_first_load(CUcontext ctx, CUfunction f) { - - dynamic_instr_limit = dynamic_instr_limit_input; - - const std::vector &instrs = nvbit_get_instrs(ctx, f); - if (verbose) { - printf("Inspecting function %s at address 0x%lx\n", - nvbit_get_func_name(ctx, f), nvbit_get_func_addr(f)); - } - - uint32_t cnt = 0; - /* iterate on all the static instructions in the function */ - for (auto instr : instrs) { - if (cnt < instr_begin_interval || cnt >= instr_end_interval ) { - cnt++; - continue; - } - //if (verbose) { - instr->printDecoded(); - //} - - if (opcode_to_id_map.find(instr->getOpcode()) == - opcode_to_id_map.end()) { - int opcode_id = opcode_to_id_map.size(); - opcode_to_id_map[instr->getOpcode()] = opcode_id; - id_to_opcode_map[opcode_id] = instr->getOpcode(); - } - - int opcode_id = opcode_to_id_map[instr->getOpcode()]; - - //TO DO: handle generic and TEX memory space - if(instr->isLoad() && !instr->isStore() && instr->getMemOpType() != Instr::CONSTANT) { //Mem load inst //ignore constant for now - assert(instr->getNumOperands() == 2); - - /* get the operand */ - const Instr::operand_t *dst = instr->getOperand(0); - const Instr::operand_t *src = instr->getOperand(1); - - assert(dst->type == Instr::REG); - assert(src->type == Instr::MREF); - - /* insert call to the instrumentation function with its - * arguments */ - nvbit_insert_call(instr, "instrument_mem", IPOINT_BEFORE); - nvbit_add_call_arg_pred_val(instr); - nvbit_add_call_arg_const_val32(instr, opcode_id); - nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); - if (instr->isExtended()) { - nvbit_add_call_arg_reg_val(instr, (int)src->value[0] + 1); - } else { - nvbit_add_call_arg_reg_val(instr, (int)Instr::RZ); - } - nvbit_add_call_arg_reg_val(instr, (int)src->value[0]); - nvbit_add_call_arg_const_val32(instr, (int)src->value[1]); - nvbit_add_call_arg_const_val32(instr, (int)src->value[0]); - nvbit_add_call_arg_const_val32(instr, -1); - nvbit_add_call_arg_const_val32(instr, (int)dst->value[0]); - nvbit_add_call_arg_const_val32(instr, (int)instr->getSize()); - } - else if(instr->isStore() && !instr->isLoad() && instr->getMemOpType() != Instr::CONSTANT) { //Mem store inst //ignore constant for now - assert(instr->getNumOperands() == 2); - - /* get the operand */ - const Instr::operand_t *dst = instr->getOperand(0); - const Instr::operand_t *src = instr->getOperand(1); - - assert(dst->type == Instr::MREF); - assert(src->type == Instr::REG); - - /* insert call to the instrumentation function with its - * arguments */ - nvbit_insert_call(instr, "instrument_mem", IPOINT_BEFORE); - nvbit_add_call_arg_pred_val(instr); - nvbit_add_call_arg_const_val32(instr, opcode_id); - nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); - if (instr->isExtended()) { - nvbit_add_call_arg_reg_val(instr, (int)dst->value[0] + 1); - } else { - nvbit_add_call_arg_reg_val(instr, (int)Instr::RZ); - } - nvbit_add_call_arg_reg_val(instr, (int)dst->value[0]); - nvbit_add_call_arg_const_val32(instr, (int)dst->value[1]); - nvbit_add_call_arg_const_val32(instr, (int)dst->value[0]); - nvbit_add_call_arg_const_val32(instr, (int)src->value[0]); - nvbit_add_call_arg_const_val32(instr, -1); - nvbit_add_call_arg_const_val32(instr, (int)instr->getSize()); - } - else if(instr->isLoad() && instr->isStore() && instr->getMemOpType() != Instr::CONSTANT) { //if it is load and store i.e. atomic inst - assert(instr->getNumOperands() == 2); - - /* get the operand */ - const Instr::operand_t *dst = instr->getOperand(0); - const Instr::operand_t *src = instr->getOperand(1); - - assert(dst->type == Instr::MREF); - assert(src->type == Instr::REG); - - /* insert call to the instrumentation function with its - * arguments */ - nvbit_insert_call(instr, "instrument_mem", IPOINT_BEFORE); - nvbit_add_call_arg_pred_val(instr); - nvbit_add_call_arg_const_val32(instr, opcode_id); - nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); - if (instr->isExtended()) { - nvbit_add_call_arg_reg_val(instr, (int)dst->value[0] + 1); - } else { - nvbit_add_call_arg_reg_val(instr, (int)Instr::RZ); - } - nvbit_add_call_arg_reg_val(instr, (int)dst->value[0]); - nvbit_add_call_arg_const_val32(instr, (int)dst->value[1]); - nvbit_add_call_arg_const_val32(instr, (int)dst->value[0]); - nvbit_add_call_arg_const_val32(instr, (int)src->value[0]); - nvbit_add_call_arg_const_val32(instr, -1); - nvbit_add_call_arg_const_val32(instr, (int)instr->getSize()); - } - else //Other ALU, FP, DP insts - { - - nvbit_insert_call(instr, "instrument_inst", IPOINT_BEFORE); - nvbit_add_call_arg_pred_val(instr); - nvbit_add_call_arg_const_val32(instr, opcode_id); - nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); - int srcNum = 0; - for (int i = 0; i < MAX_SRC+1; i++) { - /* get the operand "i" */ - if(i < instr->getNumOperands()) { - const Instr::operand_t *op = instr->getOperand(i); - if (op->type == Instr::REG) - nvbit_add_call_arg_const_val32(instr, (int)op->value[0]); - else - nvbit_add_call_arg_const_val32(instr, -1); - - srcNum++; - } - else - nvbit_add_call_arg_const_val32(instr, -1); - } - nvbit_add_call_arg_const_val32(instr, srcNum); - } - cnt++; - } -} - -__global__ void flush_channel() { - /* push memory access with negative cta id to communicate the kernel is - * completed */ - mem_access_t ma; - ma.cta_id_x = -1; - channel_dev.push(&ma, sizeof(mem_access_t)); - - /* flush channel */ - channel_dev.flush(); -} - -static FILE *resultsFile = NULL; -static FILE *kernelsFile= NULL; -static FILE *statsFile= NULL; -static int kernelid = 1; - -unsigned old_total_insts = 0; -unsigned old_total_reported_insts = 0; - - -void nvbit_at_cuda_event(CUcontext ctx, int is_exit, nvbit_api_cuda_t cbid, - const char *name, void *params, CUresult *pStatus) { - if (skip_flag) return; - - if (cbid == API_CUDA_cuLaunchKernel_ptsz || - cbid == API_CUDA_cuLaunchKernel) { - cuLaunchKernel_params *p = (cuLaunchKernel_params *)params; - - if (!is_exit) { - - - if (mkdir("traces", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) { - if( errno == EEXIST ) { - // alredy exists - } else { - // something else - std::cout << "cannot create folder error:" << strerror(errno) << std::endl; - return; - } - } - - int nregs; - _cuda_safe( - cuFuncGetAttribute(&nregs, CU_FUNC_ATTRIBUTE_NUM_REGS, p->f)); - - int shmem_static_nbytes; - _cuda_safe(cuFuncGetAttribute(&shmem_static_nbytes, - CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES, - p->f)); - - - - std::string func_name(nvbit_get_func_name(ctx, p->f)); - std::string::size_type end_pos = func_name.find('('); - if (end_pos != std::string::npos) - { - // std::string::size_type pos = func_name.find('<'); - //if (pos != std::string::npos) - // end_pos = pos; - - //std::string::size_type start_pos = func_name.find(' '); - //if (start_pos == std::string::npos) - // start_pos = 0; - //else - // start_pos++; - - func_name = func_name.substr(0, end_pos); - } - - char buffer[1024]; - sprintf (buffer, "./traces/%d-%s.trace", kernelid, func_name.c_str()); - - resultsFile = fopen(buffer, "w"); - - printf("Writing results to %s\n", buffer); - - fprintf(resultsFile, "-kernel name = %s", nvbit_get_func_name(ctx, p->f)); - fprintf(resultsFile, "\n"); - fprintf(resultsFile, "-kernel id = %d", kernelid); - fprintf(resultsFile, "\n"); - fprintf(resultsFile, "-grid dim = (%d,%d,%d)", p->gridDimX, p->gridDimY, p->gridDimZ); - fprintf(resultsFile, "\n"); - fprintf(resultsFile, "-block dim = (%d,%d,%d)", p->blockDimX, p->blockDimY, p->blockDimZ); - fprintf(resultsFile, "\n"); - fprintf(resultsFile, "-shmem = %d", shmem_static_nbytes + p->sharedMemBytes); - fprintf(resultsFile, "\n"); - fprintf(resultsFile, "-nregs = %d", nregs); - fprintf(resultsFile, "\n"); - fprintf(resultsFile, "-cuda stream id = %d", (uint64_t)p->hStream); - fprintf(resultsFile, "\n\n"); - - fprintf(resultsFile, "#traces format = threadblock_x threadblock_y threadblock_z warpid_tb sm_id warpid_sm PC mask dest_num reg_dests opcode src_num reg_srcs mem_width mem_addresses"); - fprintf(resultsFile, "\n"); - - if (kernelid == 1) { - kernelsFile = fopen("./traces/kernelslist", "w"); - statsFile = fopen("./traces/stats.csv", "w"); - fprintf(statsFile, "kernel name,total_insts,total_reported_insts\n"); - } - else { - kernelsFile = fopen("./traces/kernelslist", "a"); - statsFile = fopen("./traces/stats.csv", "a"); - } - - sprintf (buffer, "%d-%s.trace", kernelid, func_name.c_str()); - fprintf(kernelsFile, buffer); - fprintf(kernelsFile, "\n"); - fclose(kernelsFile); - - fprintf(statsFile, buffer); - fprintf(statsFile, ","); - - kernelid++; - recv_thread_receiving = true; - - } else { - /* make sure current kernel is completed */ - cudaDeviceSynchronize(); - assert(cudaGetLastError() == cudaSuccess); - - /* make sure we prevent re-entry on the nvbit_callback when issuing - * the flush_channel kernel */ - skip_flag = true; - - /* issue flush of channel so we are sure all the memory accesses - * have been pushed */ - flush_channel<<<1, 1>>>(); - cudaDeviceSynchronize(); - assert(cudaGetLastError() == cudaSuccess); - - /* unset the skip flag */ - skip_flag = false; - - /* wait here until the receiving thread has not finished with the - * current kernel */ - while (recv_thread_receiving) { - pthread_yield(); - } - - unsigned total_insts_per_kernel = total_dynamic_instr_counter - old_total_insts; - old_total_insts = total_dynamic_instr_counter; - - unsigned reported_insts_per_kernel = reported_dynamic_instr_counter - old_total_reported_insts; - old_total_reported_insts = reported_dynamic_instr_counter; - - fprintf(statsFile, ""); - fprintf(statsFile, "%d,%d",total_insts_per_kernel,reported_insts_per_kernel); - fprintf(statsFile, "\n"); - - - fclose(resultsFile); - fclose(statsFile); - } - } -} - -bool is_number(const std::string& s) -{ - std::string::const_iterator it = s.begin(); - while (it != s.end() && std::isdigit(*it)) ++it; - return !s.empty() && it == s.end(); -} - -void *recv_thread_fun(void *) { - char *recv_buffer = (char *)malloc(CHANNEL_SIZE); - - while (recv_thread_started) { - uint32_t num_recv_bytes = 0; - if (recv_thread_receiving && - (num_recv_bytes = channel_host.recv(recv_buffer, CHANNEL_SIZE)) > - 0) { - uint32_t num_processed_bytes = 0; - while (num_processed_bytes < num_recv_bytes) { - mem_access_t *ma = - (mem_access_t *)&recv_buffer[num_processed_bytes]; - - /* when we get this cta_id_x it means the kernel has completed - */ - if (ma->cta_id_x == -1) { - recv_thread_receiving = false; - break; - } - - fprintf(resultsFile, "%d ", ma->cta_id_x); - fprintf(resultsFile, "%d ", ma->cta_id_y); - fprintf(resultsFile, "%d ", ma->cta_id_z); - fprintf(resultsFile, "%d ", ma->warpid_tb); - fprintf(resultsFile, "%d ", ma->sm_id); - fprintf(resultsFile, "%d ", ma->warpid_sm); - fprintf(resultsFile, "0x%016lx ", ma->vpc); // Print the virtual PC. - fprintf(resultsFile, "%-8.8" PRIx32 " ", ma->active_mask); - if(ma->GPRDst >= 0) { - fprintf(resultsFile, "1 "); - fprintf(resultsFile, "R%d ", ma->GPRDst); - } - else - fprintf(resultsFile, "0 "); - - // Print the opcode. - fprintf(resultsFile, "%s ", id_to_opcode_map[ma->opcode_id].c_str()); - unsigned src_count=0; - for (int s = 0; s < MAX_SRC; s++) // GPR srcs count. - if(ma->GPRSrcs[s] >= 0) src_count++; - fprintf(resultsFile, "%d ", src_count); - - for (int s = 0; s < MAX_SRC; s++) // GPR srcs. - if(ma->GPRSrcs[s] >= 0) fprintf(resultsFile, "R%d ", ma->GPRSrcs[s]); - - //print addresses - std::bitset<32> mask(ma->active_mask); - if(ma->is_mem) { - //fprintf(resultsFile, "%d ", ma->width); - std::istringstream iss(id_to_opcode_map[ma->opcode_id]); - std::vector tokens; - std::string token; - while (std::getline(iss, token, '.')) { - if (!token.empty()) - tokens.push_back(token); - } - if (tokens.size()>=3){ - if (is_number(tokens[2])){ - fprintf(resultsFile, "%d ", (std::stoi(tokens[2],nullptr)/8)); - } - else{ - fprintf(resultsFile, "%d ", 4); - } - } - else{ - fprintf(resultsFile, "%d ", 4); - } - - for (int s = 0; s < 32; s++) - if(mask.test(s)) - fprintf(resultsFile, "0x%016lx ", ma->addrs[s]); - } - else - { - fprintf(resultsFile, "0 "); - } - - fprintf(resultsFile, "\n"); - - num_processed_bytes += sizeof(mem_access_t); - } - } - } - free(recv_buffer); - return NULL; -} - -void nvbit_at_ctx_init(CUcontext ctx) { - recv_thread_started = true; - channel_host.init(0, CHANNEL_SIZE, &channel_dev, NULL); - pthread_create(&recv_thread, NULL, recv_thread_fun, NULL); -} - -void nvbit_at_ctx_term(CUcontext ctx) { - if (recv_thread_started) { - recv_thread_started = false; - pthread_join(recv_thread, NULL); - } -} diff --git a/src/trace-driven/traces-generator/NVbit_tool/Makefile b/src/trace-driven/traces-generator/NVbit_tool/Makefile new file mode 100644 index 0000000..fc0209a --- /dev/null +++ b/src/trace-driven/traces-generator/NVbit_tool/Makefile @@ -0,0 +1,23 @@ +NVCC=nvcc -ccbin=`which gcc` -D_FORCE_INLINES +NVBIT_PATH=../../core +INCLUDES=-I$(NVBIT_PATH) +LIBS=-L$(NVBIT_PATH) -lnvbit +NVCC_PATH=-L $(subst bin/nvcc,lib64,$(shell which nvcc | tr -s /)) +SOURCES=$(wildcard *.cu) +OBJECTS=$(SOURCES:.cu=.o) +ARCH=35 + +mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) +current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) + +all: $(OBJECTS) $(NVBIT_PATH)/libnvbit.a + $(NVCC) -arch=sm_$(ARCH) -O3 *.o $(LIBS) $(NVCC_PATH) -lcuda -lcudart_static -shared -o ${current_dir}.so + +%.o: %.cu + $(NVCC) -dc -c -std=c++11 $(INCLUDES) -Xptxas -cloning=no -maxrregcount=16 -Xcompiler -Wall -arch=sm_$(ARCH) -O3 -Xcompiler -fPIC $< -o $@ + +$(NVBIT_PATH)/libnvbit.a: + make -C $(NVBIT_PATH) + +clean: + rm -f *.so *.o diff --git a/src/trace-driven/traces-generator/NVbit_tool/traceall.cu b/src/trace-driven/traces-generator/NVbit_tool/traceall.cu new file mode 100644 index 0000000..1426528 --- /dev/null +++ b/src/trace-driven/traces-generator/NVbit_tool/traceall.cu @@ -0,0 +1,646 @@ +/* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of NVIDIA CORPORATION nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Author: Oreste Villa, ovilla@nvidia.com - 2018 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* every tool needs to include this once */ +#include "nvbit_tool.h" + +/* nvbit interface file */ +#include "nvbit.h" + +/* for channel */ +#include "utils/channel.hpp" + +/* for _cuda_safe and GET_VAR* macros */ +#include "macros.h" + +/* Channel used to communicate from GPU to CPU receiving thread */ +#define CHANNEL_SIZE (1l << 20) +static __managed__ ChannelDev channel_dev; +static ChannelHost channel_host; + +/* receiving thread and its control variables */ +pthread_t recv_thread; +volatile bool recv_thread_started = false; +volatile bool recv_thread_receiving = false; + +/* skip flag used to avoid re-entry on the nvbit_callback when issuing + * flush_channel kernel call */ +bool skip_flag = false; + +/* global control variables for this tool */ +uint32_t instr_begin_interval = 0; +uint32_t instr_end_interval = UINT32_MAX; +int verbose = 0; + +/* opcode to id map and reverse map */ +std::map opcode_to_id_map; +std::map id_to_opcode_map; + +/* kernel instruction counter, updated by the GPU */ +static __managed__ uint64_t total_dynamic_instr_counter = 0; +static __managed__ uint64_t reported_dynamic_instr_counter = 0; +static __managed__ uint64_t dynamic_instr_limit = 0; +uint64_t dynamic_instr_limit_input = 0; //0 means no limit + +#define MAX_SRC 4 +/* information collected in the instrumentation function */ +typedef struct { + int cta_id_x; + int cta_id_y; + int cta_id_z; + int warpid_tb; + int warpid_sm; + int sm_id; + int opcode_id; + uint64_t addrs[32]; + uint32_t vpc; + bool is_mem; + int32_t GPRDst; + int32_t GPRSrcs[MAX_SRC]; + int32_t numSrcs; + int32_t width; + uint32_t active_mask; + +} mem_access_t; + +/* Instrumentation function that we want to inject, please note the use of + * 1. extern "C" __device__ __noinline__ + * To prevent "dead"-code elimination by the compiler. + * 2. NVBIT_EXPORT_FUNC(dev_func) + * To notify nvbit the name of the function we want to inject. + * This name must match exactly the function name. + */ +extern "C" __device__ __noinline__ void instrument_mem(int pred, int opcode_id, int32_t vpc, + uint32_t reg_high, + uint32_t reg_low, + int32_t imm, + int32_t srcReg1, int32_t srcReg2, int32_t desReg, int32_t width) { + if (!pred) { + return; + } + + uint32_t active_mask = __ballot(1); + const int laneid = get_laneid(); + const int first_laneid = __ffs(active_mask) - 1; + + if (dynamic_instr_limit && total_dynamic_instr_counter >= dynamic_instr_limit) + if (first_laneid == laneid) { + atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); + return; + } + + mem_access_t ma; + + /* collect memory address information */ + int64_t base_addr = (((uint64_t)reg_high) << 32) | ((uint64_t)reg_low); + uint64_t addr = base_addr + imm; + for (int i = 0; i < 32; i++) { + ma.addrs[i] = __shfl(addr, i); + } + + int4 cta = get_ctaid(); + int uniqe_threadId = threadIdx.z * blockDim.y * blockDim.x + threadIdx.y * blockDim.x + threadIdx.x; + ma.warpid_tb = uniqe_threadId/32; + + ma.cta_id_x = cta.x; + ma.cta_id_y = cta.y; + ma.cta_id_z = cta.z; + ma.warpid_sm = get_warpid(); + ma.opcode_id = opcode_id; + ma.is_mem = true; + ma.vpc = vpc; + ma.width = width; + ma.GPRDst = desReg; + ma.GPRSrcs[0] = srcReg1; + ma.GPRSrcs[1] = srcReg2; + ma.GPRSrcs[2] = -1; + ma.GPRSrcs[3] = -1; + ma.numSrcs = 2; + ma.active_mask = active_mask; + ma.sm_id = get_smid(); + + /* first active lane pushes information on the channel */ + if (first_laneid == laneid) { + channel_dev.push(&ma, sizeof(mem_access_t)); + atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); + atomicAdd((unsigned long long*)&reported_dynamic_instr_counter, 1); + } +} +NVBIT_EXPORT_FUNC(instrument_mem); + + +extern "C" __device__ __noinline__ void instrument_inst(int pred, int opcode_id, + uint32_t vpc, int desReg, int srcReg1, int srcReg2, int srcReg3, int srcReg4, int srcNum) { + if (!pred) { + return; + } + + int active_mask = __ballot(1); + const int laneid = get_laneid(); + const int first_laneid = __ffs(active_mask) - 1; + + if (dynamic_instr_limit && total_dynamic_instr_counter >= dynamic_instr_limit) + if (first_laneid == laneid) { + atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); + return; + } + + + mem_access_t ma; + + int4 cta = get_ctaid(); + int uniqe_threadId = threadIdx.z * blockDim.y * blockDim.x + threadIdx.y * blockDim.x + threadIdx.x; + ma.warpid_tb = uniqe_threadId/32; + + ma.cta_id_x = cta.x; + ma.cta_id_y = cta.y; + ma.cta_id_z = cta.z; + ma.warpid_sm = get_warpid(); + ma.opcode_id = opcode_id; + ma.is_mem = false; + ma.vpc = vpc; + + ma.GPRDst = desReg; + ma.numSrcs = srcNum; //this is the total src number including the register and others + ma.GPRSrcs[0] = srcReg1; + ma.GPRSrcs[1] = srcReg2; + ma.GPRSrcs[2] = srcReg3; + ma.GPRSrcs[3] = srcReg4; + + ma.active_mask = active_mask; + ma.sm_id = get_smid(); + + /* first active lane pushes information on the channel */ + if (first_laneid == laneid) { + channel_dev.push(&ma, sizeof(mem_access_t)); + atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); + atomicAdd((unsigned long long*)&reported_dynamic_instr_counter, 1); + } +} + +NVBIT_EXPORT_FUNC(instrument_inst); + +void nvbit_at_init() { + setenv("CUDA_MANAGED_FORCE_DEVICE_ALLOC", "1", 1); + GET_VAR_INT( + instr_begin_interval, "INSTR_BEGIN", 0, + "Beginning of the instruction interval where to apply instrumentation"); + GET_VAR_INT( + instr_end_interval, "INSTR_END", UINT32_MAX, + "End of the instruction interval where to apply instrumentation"); + GET_VAR_LONG( + dynamic_instr_limit_input, "DYNAMIC_INSTR_LIMIT", 0, + "Limit of the number instructions to be printed, 0 means no limit"); + GET_VAR_INT(verbose, "TOOL_VERBOSE", 0, "Enable verbosity inside the tool"); + std::string pad(100, '-'); + printf("%s\n", pad.c_str()); +} + +/* instrument each memory instruction adding a call to the above instrumentation + * function */ +void nvbit_at_function_first_load(CUcontext ctx, CUfunction f) { + + dynamic_instr_limit = dynamic_instr_limit_input; + + const std::vector &instrs = nvbit_get_instrs(ctx, f); + if (verbose) { + printf("Inspecting function %s at address 0x%lx\n", + nvbit_get_func_name(ctx, f), nvbit_get_func_addr(f)); + } + + uint32_t cnt = 0; + /* iterate on all the static instructions in the function */ + for (auto instr : instrs) { + if (cnt < instr_begin_interval || cnt >= instr_end_interval ) { + cnt++; + continue; + } + //if (verbose) { + instr->printDecoded(); + //} + + if (opcode_to_id_map.find(instr->getOpcode()) == + opcode_to_id_map.end()) { + int opcode_id = opcode_to_id_map.size(); + opcode_to_id_map[instr->getOpcode()] = opcode_id; + id_to_opcode_map[opcode_id] = instr->getOpcode(); + } + + int opcode_id = opcode_to_id_map[instr->getOpcode()]; + + //TO DO: handle generic and TEX memory space + if(instr->isLoad() && !instr->isStore() && instr->getMemOpType() != Instr::CONSTANT) { //Mem load inst //ignore constant for now + assert(instr->getNumOperands() == 2); + + /* get the operand */ + const Instr::operand_t *dst = instr->getOperand(0); + const Instr::operand_t *src = instr->getOperand(1); + + assert(dst->type == Instr::REG); + assert(src->type == Instr::MREF); + + /* insert call to the instrumentation function with its + * arguments */ + nvbit_insert_call(instr, "instrument_mem", IPOINT_BEFORE); + nvbit_add_call_arg_pred_val(instr); + nvbit_add_call_arg_const_val32(instr, opcode_id); + nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); + if (instr->isExtended()) { + nvbit_add_call_arg_reg_val(instr, (int)src->value[0] + 1); + } else { + nvbit_add_call_arg_reg_val(instr, (int)Instr::RZ); + } + nvbit_add_call_arg_reg_val(instr, (int)src->value[0]); + nvbit_add_call_arg_const_val32(instr, (int)src->value[1]); + nvbit_add_call_arg_const_val32(instr, (int)src->value[0]); + nvbit_add_call_arg_const_val32(instr, -1); + nvbit_add_call_arg_const_val32(instr, (int)dst->value[0]); + nvbit_add_call_arg_const_val32(instr, (int)instr->getSize()); + } + else if(instr->isStore() && !instr->isLoad() && instr->getMemOpType() != Instr::CONSTANT) { //Mem store inst //ignore constant for now + assert(instr->getNumOperands() == 2); + + /* get the operand */ + const Instr::operand_t *dst = instr->getOperand(0); + const Instr::operand_t *src = instr->getOperand(1); + + assert(dst->type == Instr::MREF); + assert(src->type == Instr::REG); + + /* insert call to the instrumentation function with its + * arguments */ + nvbit_insert_call(instr, "instrument_mem", IPOINT_BEFORE); + nvbit_add_call_arg_pred_val(instr); + nvbit_add_call_arg_const_val32(instr, opcode_id); + nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); + if (instr->isExtended()) { + nvbit_add_call_arg_reg_val(instr, (int)dst->value[0] + 1); + } else { + nvbit_add_call_arg_reg_val(instr, (int)Instr::RZ); + } + nvbit_add_call_arg_reg_val(instr, (int)dst->value[0]); + nvbit_add_call_arg_const_val32(instr, (int)dst->value[1]); + nvbit_add_call_arg_const_val32(instr, (int)dst->value[0]); + nvbit_add_call_arg_const_val32(instr, (int)src->value[0]); + nvbit_add_call_arg_const_val32(instr, -1); + nvbit_add_call_arg_const_val32(instr, (int)instr->getSize()); + } + else if(instr->isLoad() && instr->isStore() && instr->getMemOpType() != Instr::CONSTANT) { //if it is load and store i.e. atomic inst + assert(instr->getNumOperands() == 2); + + /* get the operand */ + const Instr::operand_t *dst = instr->getOperand(0); + const Instr::operand_t *src = instr->getOperand(1); + + assert(dst->type == Instr::MREF); + assert(src->type == Instr::REG); + + /* insert call to the instrumentation function with its + * arguments */ + nvbit_insert_call(instr, "instrument_mem", IPOINT_BEFORE); + nvbit_add_call_arg_pred_val(instr); + nvbit_add_call_arg_const_val32(instr, opcode_id); + nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); + if (instr->isExtended()) { + nvbit_add_call_arg_reg_val(instr, (int)dst->value[0] + 1); + } else { + nvbit_add_call_arg_reg_val(instr, (int)Instr::RZ); + } + nvbit_add_call_arg_reg_val(instr, (int)dst->value[0]); + nvbit_add_call_arg_const_val32(instr, (int)dst->value[1]); + nvbit_add_call_arg_const_val32(instr, (int)dst->value[0]); + nvbit_add_call_arg_const_val32(instr, (int)src->value[0]); + nvbit_add_call_arg_const_val32(instr, -1); + nvbit_add_call_arg_const_val32(instr, (int)instr->getSize()); + } + else //Other ALU, FP, DP insts + { + + nvbit_insert_call(instr, "instrument_inst", IPOINT_BEFORE); + nvbit_add_call_arg_pred_val(instr); + nvbit_add_call_arg_const_val32(instr, opcode_id); + nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); + int srcNum = 0; + for (int i = 0; i < MAX_SRC+1; i++) { + /* get the operand "i" */ + if(i < instr->getNumOperands()) { + const Instr::operand_t *op = instr->getOperand(i); + if (op->type == Instr::REG) + nvbit_add_call_arg_const_val32(instr, (int)op->value[0]); + else + nvbit_add_call_arg_const_val32(instr, -1); + + srcNum++; + } + else + nvbit_add_call_arg_const_val32(instr, -1); + } + nvbit_add_call_arg_const_val32(instr, srcNum); + } + cnt++; + } +} + +__global__ void flush_channel() { + /* push memory access with negative cta id to communicate the kernel is + * completed */ + mem_access_t ma; + ma.cta_id_x = -1; + channel_dev.push(&ma, sizeof(mem_access_t)); + + /* flush channel */ + channel_dev.flush(); +} + +static FILE *resultsFile = NULL; +static FILE *kernelsFile= NULL; +static FILE *statsFile= NULL; +static int kernelid = 1; + +unsigned old_total_insts = 0; +unsigned old_total_reported_insts = 0; + + +void nvbit_at_cuda_event(CUcontext ctx, int is_exit, nvbit_api_cuda_t cbid, + const char *name, void *params, CUresult *pStatus) { + if (skip_flag) return; + + if (cbid == API_CUDA_cuLaunchKernel_ptsz || + cbid == API_CUDA_cuLaunchKernel) { + cuLaunchKernel_params *p = (cuLaunchKernel_params *)params; + + if (!is_exit) { + + + if (mkdir("traces", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) { + if( errno == EEXIST ) { + // alredy exists + } else { + // something else + std::cout << "cannot create folder error:" << strerror(errno) << std::endl; + return; + } + } + + int nregs; + _cuda_safe( + cuFuncGetAttribute(&nregs, CU_FUNC_ATTRIBUTE_NUM_REGS, p->f)); + + int shmem_static_nbytes; + _cuda_safe(cuFuncGetAttribute(&shmem_static_nbytes, + CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES, + p->f)); + + + + std::string func_name(nvbit_get_func_name(ctx, p->f)); + std::string::size_type end_pos = func_name.find('('); + if (end_pos != std::string::npos) + { + // std::string::size_type pos = func_name.find('<'); + //if (pos != std::string::npos) + // end_pos = pos; + + //std::string::size_type start_pos = func_name.find(' '); + //if (start_pos == std::string::npos) + // start_pos = 0; + //else + // start_pos++; + + func_name = func_name.substr(0, end_pos); + } + + char buffer[1024]; + sprintf (buffer, "./traces/%d-%s.trace", kernelid, func_name.c_str()); + + resultsFile = fopen(buffer, "w"); + + printf("Writing results to %s\n", buffer); + + fprintf(resultsFile, "-kernel name = %s", nvbit_get_func_name(ctx, p->f)); + fprintf(resultsFile, "\n"); + fprintf(resultsFile, "-kernel id = %d", kernelid); + fprintf(resultsFile, "\n"); + fprintf(resultsFile, "-grid dim = (%d,%d,%d)", p->gridDimX, p->gridDimY, p->gridDimZ); + fprintf(resultsFile, "\n"); + fprintf(resultsFile, "-block dim = (%d,%d,%d)", p->blockDimX, p->blockDimY, p->blockDimZ); + fprintf(resultsFile, "\n"); + fprintf(resultsFile, "-shmem = %d", shmem_static_nbytes + p->sharedMemBytes); + fprintf(resultsFile, "\n"); + fprintf(resultsFile, "-nregs = %d", nregs); + fprintf(resultsFile, "\n"); + fprintf(resultsFile, "-cuda stream id = %d", (uint64_t)p->hStream); + fprintf(resultsFile, "\n\n"); + + fprintf(resultsFile, "#traces format = threadblock_x threadblock_y threadblock_z warpid_tb sm_id warpid_sm PC mask dest_num reg_dests opcode src_num reg_srcs mem_width mem_addresses"); + fprintf(resultsFile, "\n"); + + if (kernelid == 1) { + kernelsFile = fopen("./traces/kernelslist", "w"); + statsFile = fopen("./traces/stats.csv", "w"); + fprintf(statsFile, "kernel name,total_insts,total_reported_insts\n"); + } + else { + kernelsFile = fopen("./traces/kernelslist", "a"); + statsFile = fopen("./traces/stats.csv", "a"); + } + + sprintf (buffer, "%d-%s.trace", kernelid, func_name.c_str()); + fprintf(kernelsFile, buffer); + fprintf(kernelsFile, "\n"); + fclose(kernelsFile); + + fprintf(statsFile, buffer); + fprintf(statsFile, ","); + + kernelid++; + recv_thread_receiving = true; + + } else { + /* make sure current kernel is completed */ + cudaDeviceSynchronize(); + assert(cudaGetLastError() == cudaSuccess); + + /* make sure we prevent re-entry on the nvbit_callback when issuing + * the flush_channel kernel */ + skip_flag = true; + + /* issue flush of channel so we are sure all the memory accesses + * have been pushed */ + flush_channel<<<1, 1>>>(); + cudaDeviceSynchronize(); + assert(cudaGetLastError() == cudaSuccess); + + /* unset the skip flag */ + skip_flag = false; + + /* wait here until the receiving thread has not finished with the + * current kernel */ + while (recv_thread_receiving) { + pthread_yield(); + } + + unsigned total_insts_per_kernel = total_dynamic_instr_counter - old_total_insts; + old_total_insts = total_dynamic_instr_counter; + + unsigned reported_insts_per_kernel = reported_dynamic_instr_counter - old_total_reported_insts; + old_total_reported_insts = reported_dynamic_instr_counter; + + fprintf(statsFile, ""); + fprintf(statsFile, "%d,%d",total_insts_per_kernel,reported_insts_per_kernel); + fprintf(statsFile, "\n"); + + + fclose(resultsFile); + fclose(statsFile); + } + } +} + +bool is_number(const std::string& s) +{ + std::string::const_iterator it = s.begin(); + while (it != s.end() && std::isdigit(*it)) ++it; + return !s.empty() && it == s.end(); +} + +void *recv_thread_fun(void *) { + char *recv_buffer = (char *)malloc(CHANNEL_SIZE); + + while (recv_thread_started) { + uint32_t num_recv_bytes = 0; + if (recv_thread_receiving && + (num_recv_bytes = channel_host.recv(recv_buffer, CHANNEL_SIZE)) > + 0) { + uint32_t num_processed_bytes = 0; + while (num_processed_bytes < num_recv_bytes) { + mem_access_t *ma = + (mem_access_t *)&recv_buffer[num_processed_bytes]; + + /* when we get this cta_id_x it means the kernel has completed + */ + if (ma->cta_id_x == -1) { + recv_thread_receiving = false; + break; + } + + fprintf(resultsFile, "%d ", ma->cta_id_x); + fprintf(resultsFile, "%d ", ma->cta_id_y); + fprintf(resultsFile, "%d ", ma->cta_id_z); + fprintf(resultsFile, "%d ", ma->warpid_tb); + fprintf(resultsFile, "%d ", ma->sm_id); + fprintf(resultsFile, "%d ", ma->warpid_sm); + fprintf(resultsFile, "0x%016lx ", ma->vpc); // Print the virtual PC. + fprintf(resultsFile, "%-8.8" PRIx32 " ", ma->active_mask); + if(ma->GPRDst >= 0) { + fprintf(resultsFile, "1 "); + fprintf(resultsFile, "R%d ", ma->GPRDst); + } + else + fprintf(resultsFile, "0 "); + + // Print the opcode. + fprintf(resultsFile, "%s ", id_to_opcode_map[ma->opcode_id].c_str()); + unsigned src_count=0; + for (int s = 0; s < MAX_SRC; s++) // GPR srcs count. + if(ma->GPRSrcs[s] >= 0) src_count++; + fprintf(resultsFile, "%d ", src_count); + + for (int s = 0; s < MAX_SRC; s++) // GPR srcs. + if(ma->GPRSrcs[s] >= 0) fprintf(resultsFile, "R%d ", ma->GPRSrcs[s]); + + //print addresses + std::bitset<32> mask(ma->active_mask); + if(ma->is_mem) { + //fprintf(resultsFile, "%d ", ma->width); + std::istringstream iss(id_to_opcode_map[ma->opcode_id]); + std::vector tokens; + std::string token; + while (std::getline(iss, token, '.')) { + if (!token.empty()) + tokens.push_back(token); + } + if (tokens.size()>=3){ + if (is_number(tokens[2])){ + fprintf(resultsFile, "%d ", (std::stoi(tokens[2],nullptr)/8)); + } + else{ + fprintf(resultsFile, "%d ", 4); + } + } + else{ + fprintf(resultsFile, "%d ", 4); + } + + for (int s = 0; s < 32; s++) + if(mask.test(s)) + fprintf(resultsFile, "0x%016lx ", ma->addrs[s]); + } + else + { + fprintf(resultsFile, "0 "); + } + + fprintf(resultsFile, "\n"); + + num_processed_bytes += sizeof(mem_access_t); + } + } + } + free(recv_buffer); + return NULL; +} + +void nvbit_at_ctx_init(CUcontext ctx) { + recv_thread_started = true; + channel_host.init(0, CHANNEL_SIZE, &channel_dev, NULL); + pthread_create(&recv_thread, NULL, recv_thread_fun, NULL); +} + +void nvbit_at_ctx_term(CUcontext ctx) { + if (recv_thread_started) { + recv_thread_started = false; + pthread_join(recv_thread, NULL); + } +} -- cgit v1.3 From de311c1eb49ebfe33232fdf0724ec775fcae2767 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 30 Sep 2019 10:54:16 -0400 Subject: adding trace-driven.cc missing file --- src/trace-driven/trace_driven.cc | 566 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 566 insertions(+) create mode 100644 src/trace-driven/trace_driven.cc (limited to 'src') diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc new file mode 100644 index 0000000..b73f6cd --- /dev/null +++ b/src/trace-driven/trace_driven.cc @@ -0,0 +1,566 @@ +//developed by Mahmoud Khairy, Purdue Univ +//abdallm@purdue.edu + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../abstract_hardware_model.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 "../../libcuda/gpgpu_context.h" +#include "trace_driven.h" +#include "trace_opcode.h" +#include "../gpgpusim_entrypoint.h" + + +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 trace_parser::parse_kernellist_file() { + + ifs.open(kernellist_filename); + + if (!ifs.is_open()) { + std::cout << "Unable to open file: " < 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: " <>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); + } + std::cout << line << std::endl; + 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, m_gpgpu_context); + + 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; +} + +const trace_warp_inst_t* trace_shd_warp_t::get_next_inst(){ + if(trace_pc < warp_traces.size()) + return &warp_traces[trace_pc++]; + else + return NULL; +} + +void trace_shd_warp_t::clear() { + trace_pc=0; + warp_traces.clear(); +} + +bool trace_shd_warp_t::trace_done() { + return trace_pc==(warp_traces.size()); +} + +address_type trace_shd_warp_t::get_start_pc(){ + assert(warp_traces.size() > 0); + return warp_traces[0].pc; +} + +address_type trace_shd_warp_t::get_pc(){ + assert(warp_traces.size() > 0 ); + assert(trace_pc < warp_traces.size()); + return warp_traces[trace_pc].pc; +} + +bool trace_kernel_info_t::get_next_threadblock_traces(std::vector*> threadblock_traces) { + + for(unsigned i=0; iclear(); + } + + unsigned block_id_x=0, block_id_y=0, block_id_z=0; + unsigned warp_id=0; + unsigned insts_num=0; + + + bool start_of_tb_stream_found = false; + + while(!ifs->eof()) { + std::string line; + std::stringstream ss; + std::string string1, string2; + + 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); + std::cout << line << std::endl; + } + 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]->reserve(insts_num); + } + else { + assert(start_of_tb_stream_found); + trace_warp_inst_t inst(m_gpgpu_sim->getShaderCoreConfig(), m_gpgpu_context); + 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[4]; + std::string opcode; + unsigned reg_dsts_num=0; + unsigned reg_srcs_num=0; + unsigned reg_srcs[4]; + unsigned mem_width=0; + unsigned long long mem_addresses[warp_size()]; + + //Start Parsing + ss>>std::dec>>threadblock_x>>threadblock_y>>threadblock_z>>warpid_tb>>sm_id>>warpid_sm; + + ss>>std::hex>>m_pc; + ss>>std::hex>>mask; + + std::bitset mask_bits(mask); + + ss>>std::dec>>reg_dsts_num; + for(unsigned i=0; i>std::dec>>temp; + sscanf(temp.c_str(), "R%d", ®_dest[i]); + } + + ss>>opcode; + + ss>>reg_srcs_num; + for(unsigned i=0; i>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; + } + } + //Finish Parsing + //After parsing, fill the inst_t and warp_inst_t params + + //fill active mask + active_mask_t active_mask = mask_bits; + set_active( active_mask ); + + //get the opcode + std::string opcode1 = opcode.substr(0, opcode.find(".")); + + //fill and initialize common params + m_decoded = true; + pc = (address_type)m_pc; //we will lose the high 32 bits from casting long to unsigned, it should be okay! + + isize = 16; //TO DO, change this + for(unsigned i=0; i::const_iterator it= OpcodeMap.find(opcode1); + if (it != OpcodeMap.end()) { + m_opcode = it->second.opcode; + op = (op_type)(it->second.opcode_category); + } + else { + std::cout<<"ERROR: undefined instruction : "< 0) { + for(unsigned i=0; i0); + data_size = mem_width; + memory_op = memory_load; + cache_op = CACHE_ALL; + if(m_opcode == OP_LDL) + space.set_type(local_space); + else + space.set_type(global_space); + break; + case OP_ST: + case OP_STG: + case OP_STL: + case OP_ATOM: + case OP_ATOMG: + case OP_RED: + assert(mem_width>0); + data_size = mem_width; + memory_op = memory_store; + cache_op = CACHE_ALL; + if(m_opcode == OP_STL) + space.set_type(local_space); + else + space.set_type(global_space); + + if(m_opcode == OP_ATOM || m_opcode == OP_ATOMG || m_opcode == OP_RED) + m_isatomic = true; + + break; + case OP_LDS: + case OP_STS: + case OP_ATOMS: + assert(mem_width>0); + data_size = mem_width; + space.set_type(shared_space); + break; + case OP_BAR: + //TO DO fill this correctly + bar_id = 0; + bar_count = (unsigned)-1; + bar_type = SYNC; + //TO DO + //if bar_type = RED; + //set bar_type + // barrier_type bar_type; + // reduction_type red_type; + break; + default: + break; + } + + return true; +} + +void trace_warp_inst_t::set_latency(unsigned category) +{ + unsigned int_latency[5]; + unsigned fp_latency[5]; + unsigned dp_latency[5]; + unsigned sfu_latency; + unsigned tensor_latency; + unsigned int_init[5]; + unsigned fp_init[5]; + unsigned dp_init[5]; + unsigned sfu_init; + unsigned tensor_init; + + /* + * [0] ADD,SUB + * [1] MAX,Min + * [2] MUL + * [3] MAD + * [4] DIV + */ + sscanf(m_gpgpu_context->func_sim->opcode_latency_int, "%u,%u,%u,%u,%u", + &int_latency[0],&int_latency[1],&int_latency[2], + &int_latency[3],&int_latency[4]); + sscanf(m_gpgpu_context->func_sim->opcode_latency_fp, "%u,%u,%u,%u,%u", + &fp_latency[0],&fp_latency[1],&fp_latency[2], + &fp_latency[3],&fp_latency[4]); + sscanf(m_gpgpu_context->func_sim->opcode_latency_dp, "%u,%u,%u,%u,%u", + &dp_latency[0],&dp_latency[1],&dp_latency[2], + &dp_latency[3],&dp_latency[4]); + sscanf(m_gpgpu_context->func_sim->opcode_latency_sfu, "%u", + &sfu_latency); + sscanf(m_gpgpu_context->func_sim->opcode_latency_tensor, "%u", + &tensor_latency); + sscanf(m_gpgpu_context->func_sim->opcode_initiation_int, "%u,%u,%u,%u,%u", + &int_init[0],&int_init[1],&int_init[2], + &int_init[3],&int_init[4]); + sscanf(m_gpgpu_context->func_sim->opcode_initiation_fp, "%u,%u,%u,%u,%u", + &fp_init[0],&fp_init[1],&fp_init[2], + &fp_init[3],&fp_init[4]); + sscanf(m_gpgpu_context->func_sim->opcode_initiation_dp, "%u,%u,%u,%u,%u", + &dp_init[0],&dp_init[1],&dp_init[2], + &dp_init[3],&dp_init[4]); + sscanf(m_gpgpu_context->func_sim->opcode_initiation_sfu, "%u", + &sfu_init); + sscanf(m_gpgpu_context->func_sim->opcode_initiation_tensor, "%u", + &tensor_init); + sscanf(m_gpgpu_context->func_sim->cdp_latency_str, "%u,%u,%u,%u,%u", + &m_gpgpu_context->func_sim->cdp_latency[0], + &m_gpgpu_context->func_sim->cdp_latency[1], + &m_gpgpu_context->func_sim->cdp_latency[2], + &m_gpgpu_context->func_sim->cdp_latency[3], + &m_gpgpu_context->func_sim->cdp_latency[4]); + + initiation_interval = latency = 1; + + switch(category){ + case ALU_OP: + case INTP_OP: + case BRANCH_OP: + case CALL_OPS: + case RET_OPS: + latency = int_latency[0]; + initiation_interval = int_init[0]; + break; + case SP_OP: + latency = fp_latency[0]; + initiation_interval = fp_latency[0]; + break; + case DP_OP: + latency = dp_latency[0]; + initiation_interval = dp_latency[0]; + break; + case SFU_OP: + latency = sfu_latency; + initiation_interval = sfu_init; + break; + case TENSOR_CORE_OP: + latency = tensor_latency; + initiation_interval = tensor_init; + break; + default: + break; + } + +} + +unsigned trace_shader_core_ctx::trace_sim_inc_thread( kernel_info_t &kernel) +{ + + if ( kernel.no_more_ctas_to_run() ) { + return 0; //finished! + } + + if( kernel.more_threads_in_cta() ) { + kernel.increment_thread_id(); + } + + if( !kernel.more_threads_in_cta() ) + kernel.increment_cta_id(); + + return 1; +} + +void trace_shader_core_ctx::init_traces( unsigned start_warp, unsigned end_warp, kernel_info_t &kernel ) { + + std::vector*> threadblock_traces; + for (unsigned i = start_warp; i < end_warp; ++i) { + m_trace_warp[i].clear(); + threadblock_traces.push_back(&(m_trace_warp[i].warp_traces)); + } + trace_kernel_info_t& trace_kernel = static_cast (kernel); + trace_kernel.get_next_threadblock_traces(threadblock_traces); + + //set pc + for (unsigned i = start_warp; i < end_warp; ++i) { + m_warp[i].set_next_pc(m_trace_warp[i].get_start_pc()); + } +} + + +void trace_shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid) +{ + if(inst.isatomic()) + m_warp[inst.warp_id()].inc_n_atomic(); + + if ( m_trace_warp[inst.warp_id()].trace_done() ) { + m_warp[inst.warp_id()].set_completed(t); + m_warp[inst.warp_id()].ibuffer_flush(); + } + +} + +void trace_shader_core_ctx::func_exec_inst( warp_inst_t &inst ) +{ + //here, we generate memory acessess and set the status if thread (done?) + if( inst.is_load() || inst.is_store() ) + { + inst.generate_mem_accesses(); + } + for ( unsigned t=0; t < m_warp_size; t++ ) { + if( inst.active(t) ) { + unsigned warpId = inst.warp_id(); + unsigned tid=m_warp_size*warpId+t; + + //virtual function + checkExecutionStatusAndUpdate(inst,t,tid); + } + } + if(m_trace_warp[inst.warp_id()].trace_done() ) + m_barriers.warp_exit( inst.warp_id() ); +} + -- cgit v1.3 From a0aa4823f46b7040f0458d0d84d085b47ece8c8d Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 30 Sep 2019 18:34:34 -0400 Subject: trace driven static linking and fixing the inst count bug --- Makefile | 13 ++++++++++--- src/abstract_hardware_model.h | 3 ++- src/gpgpu-sim/shader.cc | 5 +++-- src/trace-driven/trace_driven.cc | 9 +++++---- src/trace-driven/trace_opcode.h | 2 +- 5 files changed, 21 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/Makefile b/Makefile index acef015..ee48514 100644 --- a/Makefile +++ b/Makefile @@ -172,15 +172,16 @@ $(SIM_LIB_DIR)/libcudart.so: makedirs $(LIBS) cudalib $(SIM_LIB_DIR)/gpgpusim.out: makedirs $(LIBS) cudalib $(SIM_LIB_DIR)/libcudart.so - ar rvs $(SIM_LIB_DIR)/libcudart_static.a\ + ar rvs $(SIM_LIB_DIR)/libgpgpusim_static.a\ $(SIM_OBJ_FILES_DIR)/libcuda/*.o \ $(SIM_OBJ_FILES_DIR)/cuda-sim/*.o \ $(SIM_OBJ_FILES_DIR)/cuda-sim/decuda_pred_table/*.o \ $(SIM_OBJ_FILES_DIR)/gpgpu-sim/*.o \ $(SIM_OBJ_FILES_DIR)/$(INTERSIM)/*.o \ + $(SIM_OBJ_FILES_DIR)/trace-driven/*.o \ $(SIM_OBJ_FILES_DIR)/*.o \ $(MCPAT) - g++ -std=c++0x -L$(SIM_LIB_DIR) -I$(CUDA_INSTALL_PATH)/include -lcudart -lm -lz -lGL -pthread -o $(SIM_LIB_DIR)/gpgpusim.out src/trace-driven/gpgpusim_trace_driven_main.cc + g++ -std=c++0x -o $(SIM_LIB_DIR)/gpgpusim.out src/trace-driven/gpgpusim_trace_driven_main.cc -L$(SIM_LIB_DIR) -I$(CUDA_INSTALL_PATH)/include -lgpgpusim_static -lm -lz -lGL -pthread $(SIM_LIB_DIR)/libcudart.dylib: makedirs $(LIBS) cudalib g++ -dynamiclib -Wl,-headerpad_max_install_names,-undefined,dynamic_lookup,-compatibility_version,1.1,-current_version,1.1\ @@ -220,8 +221,14 @@ cuda-sim: makedirs $(MAKE) -C ./src/cuda-sim/ depend $(MAKE) -C ./src/cuda-sim/ +TFLAGS = -std=c++0x -I$(CUDA_INSTALL_PATH)/include +ifneq ($(DEBUG),1) + TFLAGS += -O3 +endif +TFLAGS += -g3 -fPIC + trace-driven: makedirs - g++ -fPIC -std=c++0x -I$(CUDA_INSTALL_PATH)/include -c src/trace-driven/trace_driven.cc -o $(SIM_OBJ_FILES_DIR)/trace-driven/trace_driven.o + g++ $(TFLAGS) -c src/trace-driven/trace_driven.cc -o $(SIM_OBJ_FILES_DIR)/trace-driven/trace_driven.o gpgpu-sim_uarch: makedirs cuda-sim $(MAKE) -C ./src/gpgpu-sim/ depend diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 341e44c..a267d38 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -103,7 +103,8 @@ enum uarch_op_t { BARRIER_OP, MEMORY_BARRIER_OP, CALL_OPS, - RET_OPS + RET_OPS, + EXIT_OPS }; typedef enum uarch_op_t op_type; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index cc85f3f..e5a1e7d 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -1083,6 +1083,7 @@ void scheduler_unit::cycle() SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) has valid instruction (%s)\n", (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id(), m_shader->m_config->gpgpu_ctx->func_sim->ptx_get_insn_str( pc).c_str() ); + if( pI ) { assert(valid); if( pc != pI->pc ) { @@ -1559,8 +1560,8 @@ void shader_core_ctx::warp_inst_complete(const warp_inst_t &inst) { #if 0 - printf("[warp_inst_complete] uid=%u core=%u warp=%u pc=%#x @ time=%llu issued@%llu\n", - inst.get_uid(), m_sid, inst.warp_id(), inst.pc, gpu_tot_sim_cycle + gpu_sim_cycle, inst.get_issue_cycle()); + printf("[warp_inst_complete] uid=%u core=%u warp=%u pc=%#x @ time=%llu \n", + inst.get_uid(), m_sid, inst.warp_id(), inst.pc, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle); #endif if(inst.op_pipe==SP__OP) diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index b73f6cd..8ebc5ca 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -153,6 +153,7 @@ void trace_shd_warp_t::clear() { warp_traces.clear(); } +//functional_done bool trace_shd_warp_t::trace_done() { return trace_pc==(warp_traces.size()); } @@ -537,10 +538,8 @@ void trace_shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, uns if(inst.isatomic()) m_warp[inst.warp_id()].inc_n_atomic(); - if ( m_trace_warp[inst.warp_id()].trace_done() ) { + if ( inst.op == EXIT_OPS ) m_warp[inst.warp_id()].set_completed(t); - m_warp[inst.warp_id()].ibuffer_flush(); - } } @@ -560,7 +559,9 @@ void trace_shader_core_ctx::func_exec_inst( warp_inst_t &inst ) checkExecutionStatusAndUpdate(inst,t,tid); } } - if(m_trace_warp[inst.warp_id()].trace_done() ) + if(m_trace_warp[inst.warp_id()].trace_done() && m_warp[inst.warp_id()].functional_done()) { + m_warp[inst.warp_id()].ibuffer_flush(); m_barriers.warp_exit( inst.warp_id() ); + } } diff --git a/src/trace-driven/trace_opcode.h b/src/trace-driven/trace_opcode.h index e74dec4..2138e1c 100644 --- a/src/trace-driven/trace_opcode.h +++ b/src/trace-driven/trace_opcode.h @@ -186,7 +186,7 @@ static const std::unordered_map OpcodeMap = { {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, - {"EXIT", OpcodeChar(OP_EXIT, BRANCH_OP)}, + {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, -- cgit v1.3 From 1198a9ada24307c3001f9b4e37adac2c47cd6d1f Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 7 Oct 2019 18:17:52 -0400 Subject: adding the exit message in trace-driven mode --- src/trace-driven/gpgpusim_trace_driven_main.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 642b91a..6ac7142 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -83,5 +83,8 @@ int main ( int argc, const char **argv ) } } + //we print this message to inofrm the gpgpu-simulation stats_collect that we are done + printf("GPGPU-Sim: *** simulation thread exiting ***\n"); + return 1; } -- cgit v1.3 From 9d845da65a4b60d78e1a57dd081a6a155be78edd Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 16 Oct 2019 15:25:56 -0400 Subject: adding the exit message in trace-driven mode --- src/trace-driven/gpgpusim_trace_driven_main.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 6ac7142..81fdc0f 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -83,8 +83,9 @@ int main ( int argc, const char **argv ) } } - //we print this message to inofrm the gpgpu-simulation stats_collect that we are done + //we print this message to inform the gpgpu-simulation stats_collect script that we are done printf("GPGPU-Sim: *** simulation thread exiting ***\n"); + printf("GPGPU-Sim: *** exit detected ***\n"); return 1; } -- cgit v1.3 From 998bbc82176e1579c8500aa0c01bb00395da74dc Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 16 Oct 2019 15:30:22 -0400 Subject: adding kernel latency --- src/abstract_hardware_model.cc | 4 ++++ src/abstract_hardware_model.h | 4 +++- src/cuda-sim/cuda_device_runtime.h | 1 + src/gpgpu-sim/gpu-sim.cc | 19 +++++++++++++++++-- src/gpgpu-sim/gpu-sim.h | 1 + 5 files changed, 26 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index 758ec00..fa5bca2 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -729,6 +729,8 @@ 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; + m_kernel_TB_latency = entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency + num_blocks() * entry->gpgpu_ctx->device_runtime->g_TB_launch_latency; + cache_config_set=false; } @@ -754,6 +756,8 @@ 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; + m_kernel_TB_latency = entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency + num_blocks() * entry->gpgpu_ctx->device_runtime->g_TB_launch_latency; + 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 a267d38..135b03b 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -348,9 +348,11 @@ public: unsigned long long launch_cycle; unsigned long long start_cycle; unsigned long long end_cycle; - unsigned m_launch_latency; + unsigned m_launch_latency; //this used for CDP kernel latency mutable bool cache_config_set; + + unsigned m_kernel_TB_latency; //this used for any CPU-GPU kernel latency and counted in the gpu_cycle }; class core_config { diff --git a/src/cuda-sim/cuda_device_runtime.h b/src/cuda-sim/cuda_device_runtime.h index 7f7a0ca..9647730 100644 --- a/src/cuda-sim/cuda_device_runtime.h +++ b/src/cuda-sim/cuda_device_runtime.h @@ -50,6 +50,7 @@ class cuda_device_runtime { std::map g_cuda_device_launch_param_map; std::list g_cuda_device_launch_op; unsigned g_kernel_launch_latency; + unsigned g_TB_launch_latency; unsigned long long g_max_total_param_size; bool g_cdp_enabled; diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index ed96d42..a9462f5 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -562,6 +562,10 @@ void gpgpu_sim_config::reg_options(option_parser_t opp) &(gpgpu_ctx->device_runtime->g_cdp_enabled), "Turn on CDP", "0"); + option_parser_register(opp, "-gpgpu_TB_launch_latency", OPT_INT32, + &(gpgpu_ctx->device_runtime->g_TB_launch_latency), "thread block launch latency in cycles. Default: 0", + "0"); + //Trace driven mode parameters option_parser_register(opp, "-trace_driven_mode", OPT_BOOL, &trace_driven_mode, "Turn on trace_driven_mode", @@ -648,10 +652,19 @@ bool gpgpu_sim::get_more_cta_left() const return false; } +void gpgpu_sim::decrement_kernel_latency() +{ + for(unsigned n=0; n < m_running_kernels.size(); n++ ) { + if( m_running_kernels[n] && m_running_kernels[n]->m_kernel_TB_latency ) + m_running_kernels[n]->m_kernel_TB_latency--; + } +} + kernel_info_t *gpgpu_sim::select_kernel() { if(m_running_kernels[m_last_issued_kernel] && - !m_running_kernels[m_last_issued_kernel]->no_more_ctas_to_run()) { + !m_running_kernels[m_last_issued_kernel]->no_more_ctas_to_run() && + !m_running_kernels[m_last_issued_kernel]->m_kernel_TB_latency) { unsigned launch_uid = m_running_kernels[m_last_issued_kernel]->get_uid(); if(std::find(m_executed_kernel_uids.begin(), m_executed_kernel_uids.end(), launch_uid) == m_executed_kernel_uids.end()) { m_running_kernels[m_last_issued_kernel]->start_cycle = gpu_sim_cycle + gpu_tot_sim_cycle; @@ -663,7 +676,8 @@ kernel_info_t *gpgpu_sim::select_kernel() for(unsigned n=0; n < m_running_kernels.size(); n++ ) { unsigned idx = (n+m_last_issued_kernel+1)%m_config.max_concurrent_kernel; - if( kernel_more_cta_left(m_running_kernels[idx]) ){ + if( kernel_more_cta_left(m_running_kernels[idx]) && + !m_running_kernels[idx]->m_kernel_TB_latency){ m_last_issued_kernel=idx; m_running_kernels[idx]->start_cycle = gpu_sim_cycle + gpu_tot_sim_cycle; // record this kernel for stat print if it is the first time this kernel is selected for execution @@ -1693,6 +1707,7 @@ void gpgpu_sim::cycle() #endif issue_block2core(); + decrement_kernel_latency(); // Depending on configuration, invalidate the caches once all of threads are completed. int all_threads_complete = 1; diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 86d6206..9fb928a 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -502,6 +502,7 @@ public: bool kernel_more_cta_left(kernel_info_t *kernel) const; bool hit_max_cta_count() const; kernel_info_t *select_kernel(); + void decrement_kernel_latency(); const gpgpu_sim_config &get_config() const { return m_config; } void gpu_print_stat(); -- cgit v1.3 From bce4e08d51e3f5817f174f639c56f34104b6efe1 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 16 Oct 2019 15:33:11 -0400 Subject: adding new stats, verbose, granting arbit in the local xbar --- src/gpgpu-sim/icnt_wrapper.cc | 3 + src/gpgpu-sim/local_interconnect.cc | 139 ++++++++++++++++++++++++++++-------- src/gpgpu-sim/local_interconnect.h | 11 ++- 3 files changed, 121 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/icnt_wrapper.cc b/src/gpgpu-sim/icnt_wrapper.cc index 67724d0..e449bf1 100644 --- a/src/gpgpu-sim/icnt_wrapper.cc +++ b/src/gpgpu-sim/icnt_wrapper.cc @@ -183,6 +183,9 @@ void icnt_reg_options( class OptionParser * opp ) option_parser_register(opp, "-inct_out_buffer_limit", OPT_UINT32, &g_inct_config.out_buffer_limit, "out_buffer_limit", "64"); option_parser_register(opp, "-inct_subnets", OPT_UINT32, &g_inct_config.subnets, "subnets", "2"); option_parser_register(opp, "-arbiter_algo", OPT_UINT32, &g_inct_config.arbiter_algo, "arbiter_algo", "1"); + option_parser_register(opp, "-inct_verbose", OPT_UINT32, &g_inct_config.verbose, "inct_verbose", "0"); + option_parser_register(opp, "-inct_grant_cycles", OPT_UINT32, &g_inct_config.grant_cycles, "grant_cycles", "1"); + } diff --git a/src/gpgpu-sim/local_interconnect.cc b/src/gpgpu-sim/local_interconnect.cc index c70477c..93a2e6e 100644 --- a/src/gpgpu-sim/local_interconnect.cc +++ b/src/gpgpu-sim/local_interconnect.cc @@ -36,19 +36,22 @@ #include "local_interconnect.h" #include "mem_fetch.h" -xbar_router::xbar_router(unsigned router_id, enum Interconnect_type m_type, unsigned n_shader, unsigned n_mem, unsigned m_in_buffer_limit, unsigned m_out_buffer_limit, enum Arbiteration_type m_arbit_type) +xbar_router::xbar_router(unsigned router_id, enum Interconnect_type m_type, unsigned n_shader, unsigned n_mem, const struct inct_config& m_localinct_config) { m_id=router_id; router_type=m_type; _n_mem = n_mem; _n_shader = n_shader; total_nodes = n_shader+n_mem; + verbose=m_localinct_config.verbose; + grant_cycles = m_localinct_config.grant_cycles; + grant_cycles_count = m_localinct_config.grant_cycles; in_buffers.resize(total_nodes); out_buffers.resize(total_nodes); next_node.resize(total_nodes,0); - in_buffer_limit = m_in_buffer_limit; - out_buffer_limit = m_out_buffer_limit; - arbit_type = m_arbit_type; + in_buffer_limit = m_localinct_config.in_buffer_limit; + out_buffer_limit = m_localinct_config.out_buffer_limit; + arbit_type = m_localinct_config.arbiter_algo; next_node_id=0; if(m_type == REQ_NET) { active_in_buffers=n_shader; @@ -66,6 +69,9 @@ xbar_router::xbar_router(unsigned router_id, enum Interconnect_type m_type, unsi out_buffer_util=0; in_buffer_util=0; packets_num=0; + conflicts_util=0; + cycles_util=0; + reqs_util=0; } @@ -123,14 +129,18 @@ void xbar_router::Advance() { } void xbar_router::RR_Advance() { - cycles++; + bool active = false; vector issued(total_nodes, false); + unsigned conflict_sub =0 ; + unsigned reqs =0 ; + for(unsigned i=0; i node_tmp; + bool active = false; + + unsigned conflict_sub =0 ; + unsigned reqs =0 ; - //calcaulte how many conflicts are there for stats + //calculate how many conflicts are there for stats for (unsigned i=0; i(i), m_n_shader, m_n_mem, m_inct_config.in_buffer_limit, m_inct_config.out_buffer_limit,m_inct_config.arbiter_algo); + net[i] = new xbar_router( i, static_cast(i), m_n_shader, m_n_mem, m_inct_config); } } @@ -341,24 +414,28 @@ bool LocalInterconnect::HasBuffer(unsigned deviceID, unsigned int size) const{ void LocalInterconnect::DisplayStats() const{ - cout<<"Req_Network_injected_packets_num = "<packets_num<packets_num); + printf("Req_Network_cycles = %lld\n", net[REQ_NET]->cycles); + printf("Req_Network_injected_packets_per_cycle = %12.4f \n", (float)(net[REQ_NET]->packets_num) / (net[REQ_NET]->cycles)); + printf("Req_Network_conflicts_per_cycle = %12.4f\n", (float)(net[REQ_NET]->conflicts) / (net[REQ_NET]->cycles)); + printf("Req_Network_conflicts_per_cycle_util = %12.4f\n", (float)(net[REQ_NET]->conflicts_util) / (net[REQ_NET]->cycles_util)); + printf("Req_Bank_Level_Parallism = %12.4f\n", (float)(net[REQ_NET]->reqs_util) / (net[REQ_NET]->cycles_util)); + printf("Req_Network_in_buffer_full_per_cycle = %12.4f\n", (float)(net[REQ_NET]->in_buffer_full) / (net[REQ_NET]->cycles)); + printf("Req_Network_in_buffer_avg_util = %12.4f\n", ((float)(net[REQ_NET]->in_buffer_util) / (net[REQ_NET]->cycles) / net[REQ_NET]->active_in_buffers)); + printf("Req_Network_out_buffer_full_per_cycle = %12.4f\n", (float)(net[REQ_NET]->out_buffer_full) / (net[REQ_NET]->cycles)); + printf("Req_Network_out_buffer_avg_util = %12.4f\n", ((float)(net[REQ_NET]->out_buffer_util) / (net[REQ_NET]->cycles) / net[REQ_NET]->active_out_buffers)); + + printf("\n"); + printf("Reply_Network_injected_packets_num = %lld\n", net[REPLY_NET]->packets_num); + printf("Reply_Network_cycles = %lld\n", net[REPLY_NET]->cycles); + printf("Reply_Network_injected_packets_per_cycle = %12.4f\n", (float)(net[REPLY_NET]->packets_num) / (net[REPLY_NET]->cycles)); + printf("Reply_Network_conflicts_per_cycle = %12.4f\n", (float)(net[REPLY_NET]->conflicts) / (net[REPLY_NET]->cycles)); + printf("Reply_Network_conflicts_per_cycle_util = %12.4f\n", (float)(net[REPLY_NET]->conflicts_util) / (net[REPLY_NET]->cycles_util)); + printf("Reply_Bank_Level_Parallism = %12.4f\n", (float)(net[REPLY_NET]->reqs_util) / (net[REPLY_NET]->cycles_util)); + printf("Reply_Network_in_buffer_full_per_cycle = %12.4f\n", (float)(net[REPLY_NET]->in_buffer_full) / (net[REPLY_NET]->cycles)); + printf("Reply_Network_in_buffer_avg_util = %12.4f\n", ((float)(net[REPLY_NET]->in_buffer_util) / (net[REPLY_NET]->cycles) / net[REPLY_NET]->active_in_buffers)); + printf("Reply_Network_out_buffer_full_per_cycle = %12.4f\n", (float)(net[REPLY_NET]->out_buffer_full) / (net[REPLY_NET]->cycles)); + printf("Reply_Network_out_buffer_avg_util = %12.4f\n", ((float)(net[REPLY_NET]->out_buffer_util) / (net[REPLY_NET]->cycles) / net[REPLY_NET]->active_out_buffers)); } diff --git a/src/gpgpu-sim/local_interconnect.h b/src/gpgpu-sim/local_interconnect.h index a784da8..f431013 100644 --- a/src/gpgpu-sim/local_interconnect.h +++ b/src/gpgpu-sim/local_interconnect.h @@ -52,12 +52,14 @@ struct inct_config unsigned out_buffer_limit; unsigned subnets; Arbiteration_type arbiter_algo; + unsigned verbose; + unsigned grant_cycles; }; class xbar_router { public: - xbar_router(unsigned router_id, enum Interconnect_type m_type, unsigned n_shader, unsigned n_mem, unsigned m_in_buffer_limit, unsigned m_out_buffer_limit, enum Arbiteration_type m_arbit_type); + xbar_router(unsigned router_id, enum Interconnect_type m_type, unsigned n_shader, unsigned n_mem, const struct inct_config& m_localinct_config); ~xbar_router(); void Push(unsigned input_deviceID, unsigned output_deviceID, void* data, unsigned int size); void* Pop(unsigned ouput_deviceID); @@ -71,6 +73,9 @@ public: //some stats unsigned long long cycles; unsigned long long conflicts; + unsigned long long conflicts_util; + unsigned long long cycles_util; + unsigned long long reqs_util; unsigned long long out_buffer_full; unsigned long long out_buffer_util; unsigned long long in_buffer_full; @@ -99,6 +104,10 @@ private: enum Interconnect_type router_type; unsigned active_in_buffers,active_out_buffers; Arbiteration_type arbit_type; + unsigned verbose; + + unsigned grant_cycles; + unsigned grant_cycles_count; friend class LocalInterconnect; -- cgit v1.3 From 2f2ee7256ffd03e9bce838f74651254c1588cb39 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 16 Oct 2019 15:35:04 -0400 Subject: fixing the IPOLY L2 and Dram indexing --- src/gpgpu-sim/addrdec.cc | 73 ++++++++++++++++++++++++++++++++++++++++++------ src/gpgpu-sim/addrdec.h | 2 ++ src/gpgpu-sim/dram.cc | 25 ++++++++++++++++- src/gpgpu-sim/dram.h | 1 + 4 files changed, 91 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc index f225933..670bd61 100644 --- a/src/gpgpu-sim/addrdec.cc +++ b/src/gpgpu-sim/addrdec.cc @@ -29,6 +29,7 @@ #include #include "addrdec.h" #include "gpu-sim.h" +#include #include "../option_parser.h" @@ -84,19 +85,23 @@ new_addr_type linear_to_raw_address_translation::partition_address( new_addr_typ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_t *tlx) const { - unsigned long long int addr_for_chip,rest_of_addr; + unsigned long long int addr_for_chip, rest_of_addr, rest_of_addr_high_bits; if (!gap) { tlx->chip = addrdec_packbits(addrdec_mask[CHIP], addr, addrdec_mkhigh[CHIP], addrdec_mklow[CHIP]); tlx->bk = addrdec_packbits(addrdec_mask[BK], addr, addrdec_mkhigh[BK], addrdec_mklow[BK]); tlx->row = addrdec_packbits(addrdec_mask[ROW], addr, addrdec_mkhigh[ROW], addrdec_mklow[ROW]); tlx->col = addrdec_packbits(addrdec_mask[COL], addr, addrdec_mkhigh[COL], addrdec_mklow[COL]); tlx->burst= addrdec_packbits(addrdec_mask[BURST], addr, addrdec_mkhigh[BURST], addrdec_mklow[BURST]); + + rest_of_addr_high_bits = (addr>>(ADDR_CHIP_S+(log2channel+log2sub_partition))); + } else { // Split the given address at ADDR_CHIP_S into (MSBs,LSBs) // - extract chip address using modulus of MSBs // - recreate the rest of the address by stitching the quotient of MSBs and the LSBs addr_for_chip = (addr>>ADDR_CHIP_S) % m_n_channel; rest_of_addr = ( (addr>>ADDR_CHIP_S) / m_n_channel) << ADDR_CHIP_S; + rest_of_addr_high_bits = ((addr>>ADDR_CHIP_S) / m_n_channel); rest_of_addr |= addr & ((1 << ADDR_CHIP_S) - 1); tlx->chip = addr_for_chip; @@ -113,7 +118,7 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_ case BITWISE_PERMUTATION: { assert(!gap); - tlx->chip = (tlx->chip) ^ (tlx->row & (m_n_channel-1)); + tlx->chip = (tlx->chip) ^ (rest_of_addr_high_bits & (m_n_channel-1)); assert(tlx->chip < m_n_channel); break; } @@ -123,14 +128,29 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_ * Set Indexing function from "Pseudo-randomly interleaved memory." * Rau, B. R et al. * ISCA 1991 + * http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=348DEA37A3E440473B3C075EAABC63B6?doi=10.1.1.12.7149&rep=rep1&type=pdf * - * 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. + * + * equations for 32 banks are corresponding to IPOLY(37) + * equations for 64 banks are corresponding to IPOLY(67) + * To see all the IPOLY equations for all the degrees, see + * http://wireless-systems.ece.gatech.edu/6604/handouts/Peterson's%20Table.pdf + * + * We generate these equations using GF(2) arithmetic: + * http://www.ee.unb.ca/cgi-bin/tervo/calc.pl?num=&den=&f=d&e=1&m=1 + * + * We go through all the strides 128 (10000000), 256 (100000000),... and do modular arithmetic in GF(2) + * Then, we create the H-matrix and group each bit together, for more info read the ISCA 1991 paper + * + * IPOLY hashing guarantees conflict-free for all 2^n strides which widely exit in GPGPU applications + * and also show good performance for other strides. */ - if(m_n_channel == 32) { - std::bitset<64> a(tlx->row); + assert(!gap); + if(m_n_channel == 32 && m_n_sub_partition_in_channel == 1) { + std::bitset<64> a( rest_of_addr_high_bits); std::bitset<5> chip(tlx->chip); chip[0] = a[13]^a[12]^a[11]^a[10]^a[9]^a[6]^a[5]^a[3]^a[0]^chip[0]; chip[1] = a[14]^a[13]^a[12]^a[11]^a[10]^a[7]^a[6]^a[4]^a[1]^chip[1]; @@ -138,11 +158,42 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_ chip[3] = a[11]^a[10]^a[9]^a[8]^a[7]^a[4]^a[3]^a[1]^chip[3]; chip[4] = a[12]^a[11]^a[10]^a[9]^a[8]^a[5]^a[4]^a[2]^chip[4]; tlx->chip = chip.to_ulong(); - + break; + } else if (m_n_channel == 16 && m_n_sub_partition_in_channel==2) { + std::bitset<64> a( rest_of_addr_high_bits); + std::bitset<4> chip(tlx->chip); + std::bitset<32> bk(tlx->bk); + chip[0] = a[13]^a[12]^a[11]^a[10]^a[9]^a[6]^a[5]^a[3]^a[0]^chip[0]; + chip[1] = a[14]^a[13]^a[12]^a[11]^a[10]^a[7]^a[6]^a[4]^a[1]^chip[1]; + chip[2] = a[14]^a[10]^a[9]^a[8]^a[7]^a[6]^a[3]^a[2]^a[0]^chip[2]; + chip[3] = a[11]^a[10]^a[9]^a[8]^a[7]^a[4]^a[3]^a[1]^chip[3]; + tlx->chip = chip.to_ulong(); + unsigned par_id = a[12]^a[11]^a[10]^a[9]^a[8]^a[5]^a[4]^a[2]^bk[0]; + tlx->sub_partition = tlx->chip * m_n_sub_partition_in_channel + par_id; + assert(tlx->chip < m_n_channel); + assert(tlx->sub_partition < m_n_channel * m_n_sub_partition_in_channel); + return; + break; + } else if (m_n_channel == 32 && m_n_sub_partition_in_channel==2) { + std::bitset<64> a( rest_of_addr_high_bits); + std::bitset<5> chip(tlx->chip); + std::bitset<32> bk(tlx->bk); + chip[0] = a[18]^a[17]^a[16]^a[15]^a[12]^a[10]^a[6]^a[5]^a[0]^chip[0]; + chip[1] = a[15]^a[13]^a[12]^a[11]^a[10]^a[7]^a[5]^a[1]^a[0]^chip[1]; + chip[2] = a[16]^a[14]^a[13]^a[12]^a[11]^a[8]^a[6]^a[2]^a[1]^chip[2]; + chip[3] = a[17]^a[15]^a[14]^a[13]^a[12]^a[9]^a[7]^a[3]^a[2]^chip[3]; + chip[4] = a[18]^a[16]^a[15]^a[14]^a[13]^a[10]^a[8]^a[4]^a[3]^chip[4]; + tlx->chip = chip.to_ulong(); + unsigned par_id = a[17]^a[16]^a[15]^a[14]^a[11]^a[9]^a[5]^a[4]^bk[0]; + tlx->sub_partition = tlx->chip * m_n_sub_partition_in_channel + par_id; + assert(tlx->chip < m_n_channel); + assert(tlx->sub_partition < m_n_channel * m_n_sub_partition_in_channel); + return; + break; } else{ /* Else incorrect number of channels for the hashing function */ - assert("\nGPGPU-Sim memory_partition_indexing error: The number of channels should be " - "32 for the hashing IPOLY index function.\n" && 0); + assert("\nGPGPU-Sim memory_partition_indexing error: The number of banks should be " + "32 or 64 for the hashing IPOLY index function.\n" && 0); } assert(tlx->chip < m_n_channel); break; @@ -153,6 +204,7 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_ //random selected bits from the page and bank bits //similar to //Liu, Yuxi, et al. "Get Out of the Valley: Power-Efficient Address Mapping for GPUs." ISCA 2018 + assert(!gap); std::bitset<64> a(tlx->row); std::bitset<5> chip(tlx->chip); std::bitset<4> b(tlx->bk); @@ -169,7 +221,8 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_ { //This is an unrealistic hashing using software hashtable //we generate a random set for each memory address and save the value in a big hashtable for future reuse - new_addr_type chip_address = (addr>>ADDR_CHIP_S); + assert(!gap); + new_addr_type chip_address = (addr>>(ADDR_CHIP_S-log2sub_partition)); tr1_hash_map::const_iterator got = address_random_interleaving.find (chip_address); if ( got == address_random_interleaving.end() ) { unsigned new_chip_id = rand() % (m_n_channel*m_n_sub_partition_in_channel); @@ -258,6 +311,8 @@ void linear_to_raw_address_translation::init(unsigned int n_channel, unsigned in unsigned i; unsigned long long int mask; unsigned int nchipbits = ::LOGB2_32(n_channel); + log2channel = nchipbits; + log2sub_partition = ::LOGB2_32(n_sub_partition_in_channel); m_n_channel = n_channel; m_n_sub_partition_in_channel = n_sub_partition_in_channel; diff --git a/src/gpgpu-sim/addrdec.h b/src/gpgpu-sim/addrdec.h index c9a1420..12123f5 100644 --- a/src/gpgpu-sim/addrdec.h +++ b/src/gpgpu-sim/addrdec.h @@ -94,6 +94,8 @@ private: unsigned int gap; unsigned m_n_channel; int m_n_sub_partition_in_channel; + unsigned log2channel; + unsigned log2sub_partition; }; diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc index 9c33822..a056371 100644 --- a/src/gpgpu-sim/dram.cc +++ b/src/gpgpu-sim/dram.cc @@ -210,10 +210,33 @@ dram_req_t::dram_req_t( class mem_fetch *mf, unsigned banks, unsigned dram_bnk_i case BITWISE_XORING_BK_INDEX: { //xoring bank bits with lower bits of the page - int lbank = log2(banks); + int lbank = LOGB2(banks); bk = tlx.bk ^ (tlx.row & ((1< a(tlx.row); + std::bitset<4> b(tlx.bk); + b[0] = a[11]^a[10]^a[9]^a[8]^a[6]^a[4]^a[3]^a[0]^b[0]; + b[1] = a[12]^a[8]^a[7]^a[6]^a[5]^a[3]^a[1]^a[0]^b[1]; + b[2] = a[9]^a[8]^a[7]^a[6]^a[4]^a[2]^a[1]^b[2]; + b[3] = a[10]^a[9]^a[8]^a[7]^a[5]^a[3]^a[2]^b[3]; + bk = b.to_ulong(); + assert(bk < banks); + } + else{ /* Else incorrect number of channels for the hashing function */ + assert("\nGPGPU-Sim memory_banking indexing error: The number of banks should be " + "16 for the hashing IPOLY index function.\n" && 0); + } + break; + } case CUSTOM_BK_INDEX: /* No custom set function implemented */ //Do you custom index here diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h index 0bd9725..df7379e 100644 --- a/src/gpgpu-sim/dram.h +++ b/src/gpgpu-sim/dram.h @@ -97,6 +97,7 @@ struct bank_t enum bank_index_function{ LINEAR_BK_INDEX = 0, BITWISE_XORING_BK_INDEX, + IPOLY_BK_INDEX, CUSTOM_BK_INDEX }; -- cgit v1.3 From 48d13eea4b03bd07e383e6991be437a9e5395a51 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 16 Oct 2019 16:34:27 -0400 Subject: adding perfect inst and const support --- src/gpgpu-sim/gpu-sim.cc | 3 +++ src/gpgpu-sim/mem_fetch.cc | 4 ++++ src/gpgpu-sim/shader.cc | 22 ++++++++++++++++++++-- src/gpgpu-sim/shader.h | 2 +- 4 files changed, 28 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index a9462f5..7f9985e 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -467,6 +467,9 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_concurrent_kernel_sm", OPT_BOOL, &gpgpu_concurrent_kernel_sm, "Support concurrent kernels on a SM (default = disabled)", "0"); + option_parser_register(opp, "-perfect_inst_const_cache", OPT_BOOL, &perfect_inst_const_cache, + "perfect inst and const cache mode, so all inst and const hits in the cache(default = disabled)", + "0"); } diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc index 6a00889..c6ef1ec 100644 --- a/src/gpgpu-sim/mem_fetch.cc +++ b/src/gpgpu-sim/mem_fetch.cc @@ -67,6 +67,10 @@ mem_fetch::mem_fetch( const mem_access_t &access, icnt_flit_size = config->icnt_flit_size; original_mf = m_original_mf; original_wr_mf = m_original_wr_mf; + if(m_original_mf){ + m_raw_addr.chip=m_original_mf->get_tlx_addr().chip; + m_raw_addr.sub_partition=m_original_mf->get_tlx_addr().sub_partition; + } } mem_fetch::~mem_fetch() diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index e5a1e7d..acf40e5 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -869,7 +869,12 @@ void shader_core_ctx::fetch() m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle ); std::list events; - enum cache_request_status status = m_L1I->access( (new_addr_type)ppc, mf, m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle,events); + enum cache_request_status status; + if(m_config->perfect_inst_const_cache) + status = HIT; + else + status = m_L1I->access( (new_addr_type)ppc, mf, m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle,events); + if( status == MISS ) { m_last_warp_fetched=warp_id; m_warp[warp_id].set_imiss_pending(); @@ -1826,7 +1831,20 @@ bool ldst_unit::constant_cycle( warp_inst_t &inst, mem_stage_stall_type &rc_fail return true; if( inst.active_count() == 0 ) return true; - mem_stage_stall_type fail = process_memory_access_queue(m_L1C,inst); + + mem_stage_stall_type fail; + if(m_config->perfect_inst_const_cache) { + fail = NO_RC_FAIL; + while(inst.accessq_count() > 0) inst.accessq_pop_back(); + if ( inst.is_load() ) { + for ( unsigned r=0; r < MAX_OUTPUT_VALUES; r++) + if (inst.out[r] > 0) + m_pending_writes[inst.warp_id()][inst.out[r]]--; + } + } else { + fail = process_memory_access_queue(m_L1C,inst); + } + if (fail != NO_RC_FAIL){ rc_fail = fail; //keep other fails if this didn't fail. fail_type = C_MEM; diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index ae88b7d..d41c220 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1523,7 +1523,7 @@ class shader_core_config : public core_config //Jin: concurrent kernel on sm bool gpgpu_concurrent_kernel_sm; - bool adpative_volta_cache_config; + bool perfect_inst_const_cache; }; -- cgit v1.3 From 5cd99867e2274334c5d409d0c498518f3b6b28d3 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 16 Oct 2019 18:04:33 -0400 Subject: fixing the UX load from the traces --- src/trace-driven/trace_driven.cc | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 8ebc5ca..2ea6ef6 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -295,6 +295,14 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ set_active( active_mask ); //get the opcode + std::istringstream iss(opcode); + std::vector opcode_tokens; + std::string token; + while (std::getline(iss, token, '.')) { + if (!token.empty()) + opcode_tokens.push_back(token); + } + std::string opcode1 = opcode.substr(0, opcode.find(".")); //fill and initialize common params @@ -361,7 +369,14 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ case OP_LDG: case OP_LDL: assert(mem_width>0); - data_size = mem_width; + //handle the U* case + if (opcode_tokens.size() >= 3 && opcode_tokens[2][0] == 'U'){ + unsigned bytes; + sscanf(opcode_tokens[2].c_str(), "U%u",&bytes); + data_size=bytes/8; + } + else + data_size = mem_width; memory_op = memory_load; cache_op = CACHE_ALL; if(m_opcode == OP_LDL) @@ -376,7 +391,13 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ case OP_ATOMG: case OP_RED: assert(mem_width>0); - data_size = mem_width; + if (opcode_tokens.size() >= 3 && opcode_tokens[2][0] == 'U'){ + unsigned bytes; + sscanf(opcode_tokens[2].c_str(), "U%u",&bytes); + data_size=bytes/8; + } + else + data_size = mem_width; memory_op = memory_store; cache_op = CACHE_ALL; if(m_opcode == OP_STL) -- cgit v1.3 From 60b3d3ea5aeaacfcf3ca8c6f9deb7d75181e262d Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Tue, 22 Oct 2019 17:34:35 -0400 Subject: fixing LDC inst in trace-driven mode --- src/trace-driven/trace_opcode.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/trace-driven/trace_opcode.h b/src/trace-driven/trace_opcode.h index 2138e1c..f0172e1 100644 --- a/src/trace-driven/trace_opcode.h +++ b/src/trace-driven/trace_opcode.h @@ -149,7 +149,8 @@ static const std::unordered_map OpcodeMap = { //Load/Store Instructions {"LD", OpcodeChar(OP_LD, LOAD_OP)}, - {"LDC", OpcodeChar(OP_LDC, LOAD_OP)}, + //For now, we ignore constant loads, consider it as ALU_OP, TO DO + {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, @@ -170,6 +171,7 @@ static const std::unordered_map OpcodeMap = { {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, //Texture Instructions + //For now, we ignore texture loads, consider it as ALU_OP {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, -- cgit v1.3 From 16d2d900d8500aa5423f53a58c260e325113dcf5 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 23 Oct 2019 17:26:20 -0400 Subject: fixing the write-back L2 req in 64byte interleaving --- src/gpgpu-sim/gpu-cache.cc | 15 +++++++++++++++ src/gpgpu-sim/mem_fetch.h | 2 ++ 2 files changed, 17 insertions(+) (limited to 'src') diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index 65f2f6d..e1e0614 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -1293,6 +1293,9 @@ data_cache::wr_miss_wa_naive( new_addr_type addr, assert(status == MISS); //SECTOR_MISS and HIT_RESERVED should not send write back mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle); + //the evicted block may have wrong chip id when advanced L2 hashing is used, so set the right chip address from the original mf + wb->set_chip(mf->get_tlx_addr().chip); + wb->set_parition(mf->get_tlx_addr().sub_partition); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } return MISS; @@ -1337,6 +1340,9 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr, if( wb && (m_config.m_write_policy != WRITE_THROUGH) ) { mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle); + //the evicted block may have wrong chip id when advanced L2 hashing is used, so set the right chip address from the original mf + wb->set_chip(mf->get_tlx_addr().chip); + wb->set_parition(mf->get_tlx_addr().sub_partition); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } return MISS; @@ -1414,6 +1420,9 @@ data_cache::wr_miss_wa_fetch_on_write( new_addr_type addr, if(wb && (m_config.m_write_policy != WRITE_THROUGH) ){ mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle); + //the evicted block may have wrong chip id when advanced L2 hashing is used, so set the right chip address from the original mf + wb->set_chip(mf->get_tlx_addr().chip); + wb->set_parition(mf->get_tlx_addr().sub_partition); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } return MISS; @@ -1465,6 +1474,9 @@ data_cache::wr_miss_wa_lazy_fetch_on_read( new_addr_type addr, if( wb && (m_config.m_write_policy != WRITE_THROUGH) ) { mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle); + //the evicted block may have wrong chip id when advanced L2 hashing is used, so set the right chip address from the original mf + wb->set_chip(mf->get_tlx_addr().chip); + wb->set_parition(mf->get_tlx_addr().sub_partition); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } return MISS; @@ -1550,6 +1562,9 @@ data_cache::rd_miss_base( new_addr_type addr, if(wb && (m_config.m_write_policy != WRITE_THROUGH) ){ mem_fetch *wb = m_memfetch_creator->alloc(evicted.m_block_addr, m_wrbk_type,evicted.m_modified_size,true,m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle); + //the evicted block may have wrong chip id when advanced L2 hashing is used, so set the right chip address from the original mf + wb->set_chip(mf->get_tlx_addr().chip); + wb->set_parition(mf->get_tlx_addr().sub_partition); send_write_request(wb, WRITE_BACK_REQUEST_SENT, time, events); } return MISS; diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h index 1cab9f2..1c3f93b 100644 --- a/src/gpgpu-sim/mem_fetch.h +++ b/src/gpgpu-sim/mem_fetch.h @@ -79,6 +79,8 @@ public: void print( FILE *fp, bool print_inst = true ) const; const addrdec_t &get_tlx_addr() const { return m_raw_addr; } + void set_chip(unsigned chip_id) { m_raw_addr.chip = chip_id; } + void set_parition(unsigned sub_partition_id) { m_raw_addr.sub_partition = sub_partition_id; } unsigned get_data_size() const { return m_data_size; } void set_data_size( unsigned size ) { m_data_size=size; } unsigned get_ctrl_size() const { return m_ctrl_size; } -- cgit v1.3 From 51ef2c4ad87a46c7a640245cca9238514ccd15b8 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Thu, 24 Oct 2019 18:43:28 -0400 Subject: read addresses as base+stride in trace-driven mode --- src/trace-driven/trace_driven.cc | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 2ea6ef6..bcfa4eb 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -252,6 +252,9 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ unsigned reg_srcs[4]; unsigned mem_width=0; unsigned long long mem_addresses[warp_size()]; + unsigned address_mode=0; + unsigned long long base_address=0; + int stride=0; //Start Parsing ss>>std::dec>>threadblock_x>>threadblock_y>>threadblock_z>>warpid_tb>>sm_id>>warpid_sm; @@ -280,11 +283,37 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ 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; + ss>>std:dec>>address_mode; + if(address_mode==0){ + //read addresses one by one from the file + for (int s = 0; s < warp_size(); s++) { + if(mask_bits.test(s)) + ss>>std::hex>>mem_addresses[s]; + else + mem_addresses[s]=0; + } + } + else if(address_mode==1){ + //read addresses as base address and stride + ss>>std::hex>>base_address; + ss>>std::dec>>stride; + bool first_bit1_found=false; + bool last_bit1_found=false; + unsigned long long addra=base_address; + for (int s = 0; s < warp_size(); s++) { + if(mask_bits.test(s) && !first_bit1_found){ + first_bit1_found=true; + mem_addresses[s]=base_address; + } else if(first_bit1_found && !last_bit1_found) { + if(mask_bits.test(s)) { + addra += stride; + mem_addresses[s] = addra; + } else + last_bit1_found=true; + } + else + mem_addresses[s]=0; + } } } //Finish Parsing -- cgit v1.3 From 55cb268d854b448107ce9d7eea8b221a68f449cb Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Fri, 25 Oct 2019 12:51:05 -0400 Subject: adding binary version and remove core id from the trace parsing --- src/trace-driven/trace_driven.cc | 39 +++++++-- src/trace-driven/trace_driven.h | 11 ++- src/trace-driven/trace_opcode.h | 158 ----------------------------------- src/trace-driven/turing_opcode.h | 24 ++++++ src/trace-driven/volta_opcode.h | 175 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 234 insertions(+), 173 deletions(-) create mode 100644 src/trace-driven/turing_opcode.h create mode 100644 src/trace-driven/volta_opcode.h (limited to 'src') diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index bcfa4eb..423019b 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -19,6 +19,8 @@ #include "../../libcuda/gpgpu_context.h" #include "trace_driven.h" #include "trace_opcode.h" +#include "volta_opcode.h" +#include "turing_opcode.h" #include "../gpgpusim_entrypoint.h" @@ -73,7 +75,7 @@ trace_kernel_info_t* trace_parser::parse_kernel_info(const std::string& kerneltr std::cout << "Processing kernel " <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, m_gpgpu_context); + trace_kernel_info_t* kernel_info = new trace_kernel_info_t(gridDim, blockDim, binary_verion, function_info, &ifs, m_gpgpu_sim, m_gpgpu_context); return kernel_info; } @@ -169,6 +174,19 @@ address_type trace_shd_warp_t::get_pc(){ return warp_traces[trace_pc].pc; } +trace_kernel_info_t::trace_kernel_info_t(dim3 gridDim, dim3 blockDim, unsigned m_binary_verion, trace_function_info* m_function_info, std::ifstream* inputstream, gpgpu_sim * gpgpu_sim, gpgpu_context* gpgpu_context):kernel_info_t(gridDim, blockDim, m_function_info) { + ifs = inputstream; + m_gpgpu_sim = gpgpu_sim; + m_gpgpu_context = gpgpu_context; + binary_verion = m_binary_verion; + + //resolve the binary version + if(m_binary_verion == VOLTA_BINART_VERSION) + OpcodeMap = &Volta_OpcodeMap; + else + assert(0 && "unsupported binary version"); +} + bool trace_kernel_info_t::get_next_threadblock_traces(std::vector*> threadblock_traces) { for(unsigned i=0; igetShaderCoreConfig(), m_gpgpu_context); - inst.parse_from_string(line); + inst.parse_from_string(line, OpcodeMap); threadblock_traces[warp_id]->push_back(inst); } } @@ -235,7 +253,7 @@ bool trace_kernel_info_t::get_next_threadblock_traces(std::vector* OpcodeMap){ std::stringstream ss; ss.str(trace); @@ -257,7 +275,10 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ int stride=0; //Start Parsing - ss>>std::dec>>threadblock_x>>threadblock_y>>threadblock_z>>warpid_tb>>sm_id>>warpid_sm; + ss>>std::dec>>threadblock_x>>threadblock_y>>threadblock_z>>warpid_tb; + + //ignore core id + //ss>>std::dec>>sm_id>>warpid_sm; ss>>std::hex>>m_pc; ss>>std::hex>>mask; @@ -283,7 +304,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ if(mem_width > 0) //then it is a memory inst { - ss>>std:dec>>address_mode; + ss>>std::dec>>address_mode; if(address_mode==0){ //read addresses one by one from the file for (int s = 0; s < warp_size(); s++) { @@ -332,7 +353,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ opcode_tokens.push_back(token); } - std::string opcode1 = opcode.substr(0, opcode.find(".")); + std::string opcode1 = opcode_tokens[0]; //fill and initialize common params m_decoded = true; @@ -355,8 +376,8 @@ bool trace_warp_inst_t::parse_from_string(std::string trace){ op = ALU_OP; mem_op= NOT_TEX; - std::unordered_map::const_iterator it= OpcodeMap.find(opcode1); - if (it != OpcodeMap.end()) { + std::unordered_map::const_iterator it= OpcodeMap->find(opcode1); + if (it != OpcodeMap->end()) { m_opcode = it->second.opcode; op = (op_type)(it->second.opcode_category); } diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index 5e11448..47b7b30 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -9,6 +9,7 @@ #include "../abstract_hardware_model.h" #include "../gpgpu-sim/shader.h" +#include "trace_opcode.h" class trace_function_info: public function_info { public: @@ -43,7 +44,7 @@ public: m_opcode=0; } - bool parse_from_string(std::string trace); + bool parse_from_string(std::string trace, const std::unordered_map* OpcodeMap); private: void set_latency(unsigned cat); @@ -53,11 +54,7 @@ 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, gpgpu_context* gpgpu_context):kernel_info_t(gridDim, blockDim, m_function_info) { - ifs = inputstream; - m_gpgpu_sim = gpgpu_sim; - m_gpgpu_context = gpgpu_context; - } + trace_kernel_info_t(dim3 gridDim, dim3 blockDim, unsigned m_binary_verion, trace_function_info* m_function_info, std::ifstream* inputstream, gpgpu_sim * gpgpu_sim, gpgpu_context* gpgpu_context); bool get_next_threadblock_traces(std::vector*> threadblock_traces); @@ -65,6 +62,8 @@ private: std::ifstream* ifs; gpgpu_sim * m_gpgpu_sim; gpgpu_context* m_gpgpu_context; + unsigned binary_verion; + const std::unordered_map* OpcodeMap; }; diff --git a/src/trace-driven/trace_opcode.h b/src/trace-driven/trace_opcode.h index f0172e1..4e4abc7 100644 --- a/src/trace-driven/trace_opcode.h +++ b/src/trace-driven/trace_opcode.h @@ -59,163 +59,5 @@ struct OpcodeChar unsigned opcode_category; }; -///Volta SM_70 ISA -//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map OpcodeMap = { - //Floating Point 32 Instructions - {"FADD", OpcodeChar(OP_FADD, SP_OP)}, - {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, - {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, - {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, - {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, - {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, - {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, - {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, - {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, - {"FSET", OpcodeChar(OP_FSET, SP_OP)}, - {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, - {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, - //SFU - {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, - - //Floating Point 16 Instructions - {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, - {"HADD2_32I", OpcodeChar(OP_HADD2_32I, SP_OP)}, - {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, - {"HFMA2_32I", OpcodeChar(OP_HFMA2_32I, SP_OP)}, - {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, - {"HMUL2_32I", OpcodeChar(OP_HMUL2_32I, SP_OP)}, - {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, - {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, - - //Tensor Core Instructions - {"HMMA", OpcodeChar(OP_HMMA, TENSOR_CORE_OP)}, - - //Double Point Instructions - {"DADD", OpcodeChar(OP_DADD, DP_OP)}, - {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, - {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, - {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, - - //Integer Instructions - {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, - {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, - {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, - {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, - {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, - {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, - {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, - {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, - {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, - {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, - {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, - {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, - {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, - {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, - {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, - {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, - {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, - {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, - {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, - {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, - {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, - {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, - {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, - {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, - {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, - {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, - - //Conversion Instructions - {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, - {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, - {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, - {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, - {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, - {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, - - //Movement Instructions - {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, - {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, - {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, - {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, - {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, - {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, - - //Predicate Instructions - {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, - {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, - {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, - {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, - - //Load/Store Instructions - {"LD", OpcodeChar(OP_LD, LOAD_OP)}, - //For now, we ignore constant loads, consider it as ALU_OP, TO DO - {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, - {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, - {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, - {"ST", OpcodeChar(OP_ST, STORE_OP)}, - {"STG", OpcodeChar(OP_STG, STORE_OP)}, - {"STL", OpcodeChar(OP_STL, STORE_OP)}, - {"STS", OpcodeChar(OP_STS, STORE_OP)}, - {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, - {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, - {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, - {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, - {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, - {"RED", OpcodeChar(OP_RED, STORE_OP)}, - {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, - {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, - {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, - {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, - {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, - - //Texture Instructions - //For now, we ignore texture loads, consider it as ALU_OP - {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, - {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, - {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, - {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, - {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, - {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, - - //Control Instructions - {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, - {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, - {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, - {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, - {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, - {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, - {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, - {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, - {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, - {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, - {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, - {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, - {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, - {"RET", OpcodeChar(OP_RET, RET_OPS)}, - {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, - {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, - {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, - {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, - - //Miscellaneous Instructions - {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, - {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, - {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, - {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, - {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, - {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, - {"LEPC", OpcodeChar(OP_LEPC ,ALU_OP)}, - {"NOP", OpcodeChar(OP_NOP ,ALU_OP)}, - {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, - {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, - {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, - {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, - {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, - {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, - {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, - -}; #endif diff --git a/src/trace-driven/turing_opcode.h b/src/trace-driven/turing_opcode.h new file mode 100644 index 0000000..5fe9740 --- /dev/null +++ b/src/trace-driven/turing_opcode.h @@ -0,0 +1,24 @@ + + +#ifndef TURING_OPCODE_H +#define TURING_OPCODE_H + +#include "../abstract_hardware_model.h" +#include "trace_opcode.h" +#include +#include + +//TO DO: moving this to a yml or def files + + +#define TURING_BINART_VERSION 72 + +///Tuing SM_72 ISA +//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html +static const std::unordered_map Turing_OpcodeMap = { + +//TO fill + +}; + +#endif diff --git a/src/trace-driven/volta_opcode.h b/src/trace-driven/volta_opcode.h new file mode 100644 index 0000000..8de0775 --- /dev/null +++ b/src/trace-driven/volta_opcode.h @@ -0,0 +1,175 @@ + + +#ifndef VOLTA_OPCODE_H +#define VOLTA_OPCODE_H + +#include "../abstract_hardware_model.h" +#include "trace_opcode.h" +#include +#include + +#define VOLTA_BINART_VERSION 70 + + +//TO DO: moving this to a yml or def files + +///Volta SM_70 ISA +//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html +static const std::unordered_map Volta_OpcodeMap = { + //Floating Point 32 Instructions + {"FADD", OpcodeChar(OP_FADD, SP_OP)}, + {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, + {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, + {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, + {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, + {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, + {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, + {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, + {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, + {"FSET", OpcodeChar(OP_FSET, SP_OP)}, + {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, + {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, + //SFU + {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, + + //Floating Point 16 Instructions + {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, + {"HADD2_32I", OpcodeChar(OP_HADD2_32I, SP_OP)}, + {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, + {"HFMA2_32I", OpcodeChar(OP_HFMA2_32I, SP_OP)}, + {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, + {"HMUL2_32I", OpcodeChar(OP_HMUL2_32I, SP_OP)}, + {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, + {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, + + //Tensor Core Instructions + {"HMMA", OpcodeChar(OP_HMMA, TENSOR_CORE_OP)}, + + //Double Point Instructions + {"DADD", OpcodeChar(OP_DADD, DP_OP)}, + {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, + {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, + {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, + + //Integer Instructions + {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, + {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, + {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, + {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, + {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, + {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, + {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, + {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, + {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, + {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, + {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, + {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, + {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, + {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, + {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, + {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, + {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, + {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, + {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, + {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, + {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, + {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, + {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, + {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, + {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, + {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, + + //Conversion Instructions + {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, + {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, + {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, + {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, + {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, + {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, + + //Movement Instructions + {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, + {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, + {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, + {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, + {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, + {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, + + //Predicate Instructions + {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, + {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, + {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, + {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, + + //Load/Store Instructions + {"LD", OpcodeChar(OP_LD, LOAD_OP)}, + //For now, we ignore constant loads, consider it as ALU_OP, TO DO + {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, + {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, + {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, + {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, + {"ST", OpcodeChar(OP_ST, STORE_OP)}, + {"STG", OpcodeChar(OP_STG, STORE_OP)}, + {"STL", OpcodeChar(OP_STL, STORE_OP)}, + {"STS", OpcodeChar(OP_STS, STORE_OP)}, + {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, + {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, + {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, + {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, + {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, + {"RED", OpcodeChar(OP_RED, STORE_OP)}, + {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, + {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, + {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, + {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, + {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, + + //Texture Instructions + //For now, we ignore texture loads, consider it as ALU_OP + {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, + {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, + {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, + {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, + {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, + {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, + + //Control Instructions + {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, + {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, + {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, + {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, + {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, + {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, + {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, + {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, + {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, + {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, + {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, + {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, + {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, + {"RET", OpcodeChar(OP_RET, RET_OPS)}, + {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, + {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, + {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, + {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, + + //Miscellaneous Instructions + {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, + {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, + {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, + {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, + {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, + {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, + {"LEPC", OpcodeChar(OP_LEPC ,ALU_OP)}, + {"NOP", OpcodeChar(OP_NOP ,ALU_OP)}, + {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, + {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, + {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, + {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, + {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, + {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, + {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, + +}; + +#endif -- cgit v1.3 From 7e309565313e8f00baba46269afeaf613ce66307 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 11 Nov 2019 18:38:43 -0500 Subject: adding special cases for traces --- src/trace-driven/trace_driven.cc | 33 ++++++++++++++++++++++++++++----- src/trace-driven/trace_driven.h | 1 + 2 files changed, 29 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 423019b..b4ccf48 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -252,6 +252,14 @@ bool trace_kernel_info_t::get_next_threadblock_traces(std::vector opcode, std::string param) +{ + for(unsigned i=0; i* OpcodeMap){ @@ -413,7 +421,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere } - //fill memory space + //handle special cases and fill memory space switch(m_opcode){ case OP_LD: case OP_LDG: @@ -433,6 +441,10 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere space.set_type(local_space); else space.set_type(global_space); + //check the cache scope, if its strong GPU, then bypass L1 + if(check_opcode_contain( opcode_tokens , "STRONG") && check_opcode_contain( opcode_tokens , "GPU")) { + cache_op = CACHE_GLOBAL; + } break; case OP_ST: case OP_STG: @@ -455,8 +467,10 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere else space.set_type(global_space); - if(m_opcode == OP_ATOM || m_opcode == OP_ATOMG || m_opcode == OP_RED) + if(m_opcode == OP_ATOM || m_opcode == OP_ATOMG || m_opcode == OP_RED){ m_isatomic = true; + cache_op = CACHE_GLOBAL; + } break; case OP_LDS: @@ -467,7 +481,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere space.set_type(shared_space); break; case OP_BAR: - //TO DO fill this correctly + //TO DO: fill this correctly bar_id = 0; bar_count = (unsigned)-1; bar_type = SYNC; @@ -477,6 +491,15 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere // barrier_type bar_type; // reduction_type red_type; break; + case OP_HADD2: + case OP_HADD2_32I: + case OP_HFMA2: + case OP_HFMA2_32I: + case OP_HMUL2_32I: + case OP_HSET2: + case OP_HSETP2: + initiation_interval = initiation_interval/2; //FP16 has 2X throughput than FP32 + break; default: break; } @@ -550,11 +573,11 @@ void trace_warp_inst_t::set_latency(unsigned category) break; case SP_OP: latency = fp_latency[0]; - initiation_interval = fp_latency[0]; + initiation_interval = fp_init[0]; break; case DP_OP: latency = dp_latency[0]; - initiation_interval = dp_latency[0]; + initiation_interval = dp_init[0]; break; case SFU_OP: latency = sfu_latency; diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index 47b7b30..f370109 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -50,6 +50,7 @@ private: void set_latency(unsigned cat); gpgpu_context* m_gpgpu_context; unsigned m_opcode; + bool check_opcode_contain(std::vector opcode, std::string param); }; class trace_kernel_info_t: public kernel_info_t { -- cgit v1.3 From a009318f6ffae0c71b5735c3e6b49b5a0bd09029 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Tue, 12 Nov 2019 18:48:46 -0500 Subject: handling the atomics in trace-driven and add the missing two instructions of Nvbits --- src/gpgpu-sim/l2cache.cc | 2 +- src/gpgpu-sim/shader.cc | 3 ++- src/trace-driven/trace_driven.cc | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index fb4ce32..8bbe91c 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -755,7 +755,7 @@ mem_fetch* memory_sub_partition::pop() { mem_fetch* mf = m_L2_icnt_queue->pop(); m_request_tracker.erase(mf); - if ( mf && mf->isatomic() ) + if ( mf && mf->isatomic() && !m_gpu->get_config().is_trace_driven_mode() ) mf->do_atomic(); if( mf && (mf->get_access_type() == L2_WRBK_ACC || mf->get_access_type() == L1_WRBK_ACC) ) { delete mf; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index acf40e5..de33026 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -2311,7 +2311,8 @@ void ldst_unit::writeback() if( !m_pipeline_reg[0]->empty() ) { m_next_wb = *m_pipeline_reg[0]; if(m_next_wb.isatomic()) { - m_next_wb.do_atomic(); + if(!m_core->get_gpu()->get_config().is_trace_driven_mode()) + m_next_wb.do_atomic(); m_core->decrement_atomic_count(m_next_wb.warp_id(), m_next_wb.active_count()); } m_core->dec_inst_in_pipeline(m_pipeline_reg[0]->warp_id()); diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index b4ccf48..3cedd5c 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -632,8 +632,12 @@ void trace_shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, uns if(inst.isatomic()) m_warp[inst.warp_id()].inc_n_atomic(); - if ( inst.op == EXIT_OPS ) + if ( inst.op == EXIT_OPS ) { m_warp[inst.warp_id()].set_completed(t); + //We did that because the Nvbit misses two instruction to report at the end of the kernel after the EXIT instruction + //so we add them here to have better correlation with HW counters + m_stats->m_num_sim_winsn[m_sid] += 2; + } } -- cgit v1.3 From 3ca1a6ac9a9774b25a2dbeba6c55a04206f8cdca Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Thu, 14 Nov 2019 19:11:02 -0500 Subject: fixing the missing instruction bug in trace-driven mode --- src/gpgpu-sim/shader.cc | 3 +++ src/trace-driven/trace_driven.cc | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index de33026..926453a 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -1635,6 +1635,9 @@ bool ldst_unit::shared_cycle( warp_inst_t &inst, mem_stage_stall_type &rc_fail, if( inst.space.get_type() != shared_space ) return true; + if( inst.active_count() == 0 ) + return true; + if(inst.has_dispatch_delay()){ m_stats->gpgpu_n_shmem_bank_access[m_sid]++; } diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 3cedd5c..8a9d3f2 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -288,7 +288,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere //ignore core id //ss>>std::dec>>sm_id>>warpid_sm; - ss>>std::hex>>m_pc; + ss>>std::dec>>m_pc; ss>>std::hex>>mask; std::bitset mask_bits(mask); @@ -634,9 +634,6 @@ void trace_shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, uns if ( inst.op == EXIT_OPS ) { m_warp[inst.warp_id()].set_completed(t); - //We did that because the Nvbit misses two instruction to report at the end of the kernel after the EXIT instruction - //so we add them here to have better correlation with HW counters - m_stats->m_num_sim_winsn[m_sid] += 2; } } -- cgit v1.3 From a68d678b0d82c2b1cb485cc3f8741f97b8862b17 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Fri, 15 Nov 2019 20:02:07 -0500 Subject: fixing memory width bug in trace-driven mode --- src/trace-driven/trace_driven.cc | 52 ++++++++++++++++++++++++---------------- src/trace-driven/trace_driven.h | 3 ++- 2 files changed, 34 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 8a9d3f2..f48cf5b 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include "../abstract_hardware_model.h" #include "../option_parser.h" @@ -23,7 +24,6 @@ #include "turing_opcode.h" #include "../gpgpusim_entrypoint.h" - trace_parser::trace_parser(const char* kernellist_filepath, gpgpu_sim * m_gpgpu_sim, gpgpu_context* m_gpgpu_context) { @@ -252,7 +252,7 @@ bool trace_kernel_info_t::get_next_threadblock_traces(std::vector opcode, std::string param) +bool trace_warp_inst_t::check_opcode_contain(const std::vector& opcode, std::string param) { for(unsigned i=0; i opcode, st return false; } +bool is_number(const std::string& s) +{ + std::string::const_iterator it = s.begin(); + while (it != s.end() && std::isdigit(*it)) ++it; + return !s.empty() && it == s.end(); +} + +unsigned trace_warp_inst_t::get_datawidth_from_opcode(const std::vector& opcode) +{ + for(unsigned i=0; i* OpcodeMap){ std::stringstream ss; @@ -288,7 +312,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere //ignore core id //ss>>std::dec>>sm_id>>warpid_sm; - ss>>std::dec>>m_pc; + ss>>std::hex>>m_pc; ss>>std::hex>>mask; std::bitset mask_bits(mask); @@ -408,8 +432,8 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere in[m]=reg_srcs[m]+1; //Increment by one because GPGPU-sim starts from R1, while SASS starts from R0 arch_reg.src[m]=reg_srcs[m]+1; } - //handle: vector, store insts have no output, double inst and hmma, and 64 bit address - + //TO DO: handle: vector, store insts have no output, double inst and hmma, and 64 bit address + //remove redundant registers //fill latency and initl set_latency(op); @@ -427,14 +451,8 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere case OP_LDG: case OP_LDL: assert(mem_width>0); - //handle the U* case - if (opcode_tokens.size() >= 3 && opcode_tokens[2][0] == 'U'){ - unsigned bytes; - sscanf(opcode_tokens[2].c_str(), "U%u",&bytes); - data_size=bytes/8; - } - else - data_size = mem_width; + //Nvbit reports incorrect data width, and we have to parse the opcode to get the correct data width + data_size = get_datawidth_from_opcode(opcode_tokens); memory_op = memory_load; cache_op = CACHE_ALL; if(m_opcode == OP_LDL) @@ -453,13 +471,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere case OP_ATOMG: case OP_RED: assert(mem_width>0); - if (opcode_tokens.size() >= 3 && opcode_tokens[2][0] == 'U'){ - unsigned bytes; - sscanf(opcode_tokens[2].c_str(), "U%u",&bytes); - data_size=bytes/8; - } - else - data_size = mem_width; + data_size = get_datawidth_from_opcode(opcode_tokens); memory_op = memory_store; cache_op = CACHE_ALL; if(m_opcode == OP_STL) diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index f370109..8917502 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -50,7 +50,8 @@ private: void set_latency(unsigned cat); gpgpu_context* m_gpgpu_context; unsigned m_opcode; - bool check_opcode_contain(std::vector opcode, std::string param); + bool check_opcode_contain(const std::vector& opcode, std::string param); + unsigned get_datawidth_from_opcode(const std::vector& opcode); }; class trace_kernel_info_t: public kernel_info_t { -- cgit v1.3 From a760eb1c93dd272373089752a821fc8f3eaa9ed3 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Fri, 15 Nov 2019 20:02:50 -0500 Subject: adding some comments --- src/trace-driven/gpgpusim_trace_driven_main.cc | 13 +++++++++++++ src/trace-driven/trace_opcode.h | 3 ++- src/trace-driven/turing_opcode.h | 3 ++- src/trace-driven/volta_opcode.h | 3 ++- 4 files changed, 19 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 81fdc0f..2f5d04d 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -19,6 +19,19 @@ #include "trace_opcode.h" #include "../gpgpusim_entrypoint.h" +/* TO DO: + * NOTE: the current version of trace-driven is functionally working fine, + * but we still need to improve traces compression and simulation speed. + * This includes: + * 1- Prefetch concurrent thread that prefetches traces from disk (to not be limited by disk speed) + * 2- traces compression format + * a. cfg format and remove thread/block Id from the head + * b. using zlib library to save in binary format + * + * 3- Efficient memory improvement (save string not objects - parse only 10 in the buffer) + * 4- Seeking capability - thread scheduler (save tb index and warp index info in the traces header) + * 5- Get rid off traces intermediate files - change the tracer + */ int main ( int argc, const char **argv ) { diff --git a/src/trace-driven/trace_opcode.h b/src/trace-driven/trace_opcode.h index 4e4abc7..7f13ed8 100644 --- a/src/trace-driven/trace_opcode.h +++ b/src/trace-driven/trace_opcode.h @@ -1,4 +1,5 @@ - +//developed by Mahmoud Khairy, Purdue Univ +//abdallm@purdue.edu #ifndef TRACE_OPCODE_H #define TRACE_OPCODE_H diff --git a/src/trace-driven/turing_opcode.h b/src/trace-driven/turing_opcode.h index 5fe9740..f872070 100644 --- a/src/trace-driven/turing_opcode.h +++ b/src/trace-driven/turing_opcode.h @@ -1,4 +1,5 @@ - +//developed by Mahmoud Khairy, Purdue Univ +//abdallm@purdue.edu #ifndef TURING_OPCODE_H #define TURING_OPCODE_H diff --git a/src/trace-driven/volta_opcode.h b/src/trace-driven/volta_opcode.h index 8de0775..23f0bd7 100644 --- a/src/trace-driven/volta_opcode.h +++ b/src/trace-driven/volta_opcode.h @@ -1,4 +1,5 @@ - +//developed by Mahmoud Khairy, Purdue Univ +//abdallm@purdue.edu #ifndef VOLTA_OPCODE_H #define VOLTA_OPCODE_H -- cgit v1.3 From d3316efe70f6007d15f81f828bb5fc82bc5c86d4 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Fri, 15 Nov 2019 20:03:18 -0500 Subject: invalidate l1 cache at membar --- src/gpgpu-sim/shader.cc | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 926453a..19f8e72 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3470,6 +3470,14 @@ bool shader_core_ctx::warp_waiting_at_mem_barrier( unsigned warp_id ) return false; if( !m_scoreboard->pendingWrites(warp_id) ) { m_warp[warp_id].clear_membar(); + if (m_gpu->get_config().gpgpu_flush_l1_cache) { + //invalidate L1 cache + //Based on Nvidia Doc, at MEM barrier, we have to + //(1) wait for all pending writes till they are acked + //(2) invalidate L1 cache to ensure coherence and avoid reading stall data + cache_invalidate(); + //TO DO: you need to stall the SM for 5k cycles. + } return false; } return true; -- cgit v1.3 From 4702017e7597fc31cb4f2337aa5d9e8ba8287418 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Fri, 15 Nov 2019 20:08:28 -0500 Subject: invalidate l1 cache at membar - fixing --- src/gpgpu-sim/gpu-sim.h | 2 ++ src/gpgpu-sim/shader.cc | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 9fb928a..1ac4fdb 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -350,6 +350,8 @@ public: unsigned is_trace_driven_mode() const { return trace_driven_mode; } char* get_traces_filename() const { return g_traces_filename; } + bool flush_l1() const { return gpgpu_flush_l1_cache; } + private: void init_clock_domains(void ); diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 19f8e72..0ea819d 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3470,8 +3470,9 @@ bool shader_core_ctx::warp_waiting_at_mem_barrier( unsigned warp_id ) return false; if( !m_scoreboard->pendingWrites(warp_id) ) { m_warp[warp_id].clear_membar(); - if (m_gpu->get_config().gpgpu_flush_l1_cache) { - //invalidate L1 cache + if (m_gpu->get_config().flush_l1()) { + //Mahmoud fixed this on Nov 2019 + //Invalidate L1 cache //Based on Nvidia Doc, at MEM barrier, we have to //(1) wait for all pending writes till they are acked //(2) invalidate L1 cache to ensure coherence and avoid reading stall data -- cgit v1.3 From 689316eff10035a1171e6b4917ce0616ecb3e938 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 20 Nov 2019 19:51:20 -0500 Subject: fixing atomic bug in trace-driven mode --- src/gpgpu-sim/l2cache.cc | 3 ++- src/gpgpu-sim/shader.cc | 3 ++- src/trace-driven/trace_driven.cc | 26 +++++++++++++++++++++++--- 3 files changed, 27 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index 8bbe91c..4a312d1 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -755,8 +755,9 @@ mem_fetch* memory_sub_partition::pop() { mem_fetch* mf = m_L2_icnt_queue->pop(); m_request_tracker.erase(mf); - if ( mf && mf->isatomic() && !m_gpu->get_config().is_trace_driven_mode() ) + if ( mf && mf->isatomic() && !m_gpu->get_config().is_trace_driven_mode() ){ mf->do_atomic(); + } if( mf && (mf->get_access_type() == L2_WRBK_ACC || mf->get_access_type() == L1_WRBK_ACC) ) { delete mf; mf = NULL; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 0ea819d..de6d975 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -2342,8 +2342,9 @@ void ldst_unit::writeback() case 3: // global/local if( m_next_global ) { m_next_wb = m_next_global->get_inst(); - if( m_next_global->isatomic() ) + if( m_next_global->isatomic() ) { m_core->decrement_atomic_count(m_next_global->get_wid(),m_next_global->get_access_warp_mask().count()); + } delete m_next_global; m_next_global = NULL; serviced_client = next_client; diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index f48cf5b..594f306 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -148,7 +148,9 @@ void trace_parser::kernel_finalizer(trace_kernel_info_t* kernel_info){ const trace_warp_inst_t* trace_shd_warp_t::get_next_inst(){ if(trace_pc < warp_traces.size()) + { return &warp_traces[trace_pc++]; + } else return NULL; } @@ -290,7 +292,6 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere 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; @@ -391,7 +392,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere m_decoded = true; pc = (address_type)m_pc; //we will lose the high 32 bits from casting long to unsigned, it should be okay! - isize = 16; //TO DO, change this + isize = 16; //starting from MAXWELL isize=16 bytes (including the control bytes) for(unsigned i=0; i0); data_size = mem_width; space.set_type(shared_space); + if(m_opcode == OP_ATOMS ) { + //m_isatomic = true; + + op=LOAD_OP; + memory_op = memory_load; + + } break; case OP_BAR: //TO DO: fill this correctly -- cgit v1.3 From 1353e4322328f369bd4c23bf228790f34984d860 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Thu, 21 Nov 2019 01:35:38 -0500 Subject: fixing the access alignment in trace-driven mode --- src/abstract_hardware_model.cc | 21 +++++++++++++++++++-- src/gpgpu-sim/shader.cc | 4 +++- 2 files changed, 22 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index fa5bca2..3d3d2f3 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -536,13 +536,30 @@ void warp_inst_t::memory_coalescing_arch( bool is_write, mem_access_type access_ transaction_info &info = subwarp_transactions[block_address]; // can only write to one segment - assert(block_address == line_size_based_tag_func(addr+data_size_coales-1,segment_size)); + //it seems like in trace driven, a thread can write to more than one segment + //assert(block_address == line_size_based_tag_func(addr+data_size_coales-1,segment_size)); info.chunks.set(chunk); info.active.set(thread); unsigned idx = (addr&127); for( unsigned i=0; i < data_size_coales; i++ ) - info.bytes.set(idx+i); + if((idx+i) < MAX_MEMORY_ACCESS_SIZE) + info.bytes.set(idx+i); + + //it seems like in trace driven, a thread can write to more than one segment + //handle this special case + if(block_address != line_size_based_tag_func(addr+data_size_coales-1,segment_size)) { + addr = addr+data_size_coales-1; + unsigned block_address = line_size_based_tag_func(addr,segment_size); + unsigned chunk = (addr&127)/32; + transaction_info &info = subwarp_transactions[block_address]; + info.chunks.set(chunk); + info.active.set(thread); + unsigned idx = (addr&127); + for( unsigned i=0; i < data_size_coales; i++ ) + if((idx+i) < MAX_MEMORY_ACCESS_SIZE) + info.bytes.set(idx+i); + } } } diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index de6d975..23050d3 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -1881,7 +1881,9 @@ bool ldst_unit::memory_cycle( warp_inst_t &inst, mem_stage_stall_type &stall_rea return true; if( inst.active_count() == 0 ) return true; - assert( !inst.accessq_empty() ); + if( inst.accessq_empty() ) + return true; + mem_stage_stall_type stall_cond = NO_RC_FAIL; const mem_access_t &access = inst.accessq_back(); -- cgit v1.3 From 0dae88ce0e247acd12259fb57362d9600c05c18b Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Thu, 21 Nov 2019 21:43:12 -0500 Subject: adding pascal code and fixing atomic bug --- src/trace-driven/pascal_opcode.h | 196 +++++++++++++++++++++++++++++++++++++++ src/trace-driven/trace_driven.cc | 27 ++++-- src/trace-driven/trace_opcode.h | 2 + src/trace-driven/volta_opcode.h | 2 +- 4 files changed, 217 insertions(+), 10 deletions(-) create mode 100644 src/trace-driven/pascal_opcode.h (limited to 'src') diff --git a/src/trace-driven/pascal_opcode.h b/src/trace-driven/pascal_opcode.h new file mode 100644 index 0000000..d4f787d --- /dev/null +++ b/src/trace-driven/pascal_opcode.h @@ -0,0 +1,196 @@ +//developed by Mahmoud Khairy, Purdue Univ +//abdallm@purdue.edu + +#ifndef PASCAL_OPCODE_H +#define PASCAL_OPCODE_H + +#include "../abstract_hardware_model.h" +#include "trace_opcode.h" +#include +#include + +#define PASCAL_TITANX_BINART_VERSION 61 +#define PASCAL_P100_BINART_VERSION 60 + +#define PASCAL_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 + +//TO DO: moving this to a yml or def files + +///Pascal SM_61 ISA +//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html +static const std::unordered_map Pascal_OpcodeMap = { + //Floating Point 32 Instructions + {"FADD", OpcodeChar(OP_FADD, SP_OP)}, + {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, + {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, + {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, + {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, + {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, + {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, + {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, + {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, + {"FSET", OpcodeChar(OP_FSET, SP_OP)}, + {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, + {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, + {"RRO", OpcodeChar(OP_RRO, SP_OP)}, + + //SFU + {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, + + //Floating Point 16 Instructions + {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, + {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, + {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, + {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, + {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, + + //Double Point Instructions + {"DADD", OpcodeChar(OP_DADD, DP_OP)}, + {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, + {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, + {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, + {"DMNMX", OpcodeChar(OP_DMNMX, DP_OP)}, + {"DSET", OpcodeChar(OP_DSET, DP_OP)}, + + //Integer Instructions + {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, + {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, + {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, + {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, + {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, + {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, + {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, + {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, + {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, + {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, + {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, + {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, + {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, + {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, + {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, + {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, + {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, + {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, + {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, + {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, + {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, + {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, + {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, + {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, + {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, + {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, + {"BFE", OpcodeChar(OP_BFE, INTP_OP)}, + {"BFI", OpcodeChar(OP_BFI, INTP_OP)}, + {"ICMP", OpcodeChar(OP_ICMP, INTP_OP)}, + {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, + {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, + {"XMAD", OpcodeChar(OP_XMAD, INTP_OP)}, + + //Conversion Instructions + {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, + {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, + {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, + {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, + {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, + {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, + + //Movement Instructions + {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, + {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, + {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, + {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, + {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, + {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, + + //Predicate Instructions + {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, + {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, + {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, + {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, + {"CSET", OpcodeChar(OP_CSET, ALU_OP)}, + {"CSETP", OpcodeChar(OP_CSETP, ALU_OP)}, + {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, + + //Load/Store Instructions + {"LD", OpcodeChar(OP_LD, LOAD_OP)}, + //For now, we ignore constant loads, consider it as ALU_OP, TO DO + {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, + {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, + {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, + {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, + {"ST", OpcodeChar(OP_ST, STORE_OP)}, + {"STG", OpcodeChar(OP_STG, STORE_OP)}, + {"STL", OpcodeChar(OP_STL, STORE_OP)}, + {"STS", OpcodeChar(OP_STS, STORE_OP)}, + {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, + {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, + {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, + {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, + {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, + {"RED", OpcodeChar(OP_RED, STORE_OP)}, + {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, + {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, + {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, + {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, + {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, + + //Texture Instructions + //For now, we ignore texture loads, consider it as ALU_OP + {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, + {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, + {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, + {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, + {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, + {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, + {"TEXS", OpcodeChar(OP_TEXS, ALU_OP)}, + {"TLD4S", OpcodeChar(OP_TLD4S, ALU_OP)}, + {"TLDS", OpcodeChar(OP_TLDS, ALU_OP)}, + + //Control Instructions + {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, + {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, + {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, + {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, + {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, + {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, + {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, + {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, + {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, + {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, + {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, + {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, + {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, + {"RET", OpcodeChar(OP_RET, RET_OPS)}, + {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, + {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, + {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, + {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, + {"CAL", OpcodeChar(OP_CAL, CALL_OPS)}, + {"JCAL", OpcodeChar(OP_JCAL, CALL_OPS)}, + {"PRET", OpcodeChar(OP_PRET, CALL_OPS)}, + {"BRK", OpcodeChar(OP_BRK, CALL_OPS)}, + {"PBK", OpcodeChar(OP_PBK, CALL_OPS)}, + {"CONT", OpcodeChar(OP_CONT, CALL_OPS)}, + {"PCNT", OpcodeChar(OP_PCNT, CALL_OPS)}, + {"PEXIT", OpcodeChar(OP_PEXIT, CALL_OPS)}, + + //Miscellaneous Instructions + {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, + {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, + {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, + {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, + {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, + {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, + {"LEPC", OpcodeChar(OP_LEPC ,ALU_OP)}, + {"NOP", OpcodeChar(OP_NOP ,ALU_OP)}, + {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, + {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, + {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, + {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, + {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, + {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, + {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, + +}; + +#endif diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 594f306..48ba0f6 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -22,6 +22,7 @@ #include "trace_opcode.h" #include "volta_opcode.h" #include "turing_opcode.h" +#include "pascal_opcode.h" #include "../gpgpusim_entrypoint.h" trace_parser::trace_parser(const char* kernellist_filepath, gpgpu_sim * m_gpgpu_sim, gpgpu_context* m_gpgpu_context) @@ -185,6 +186,8 @@ trace_kernel_info_t::trace_kernel_info_t(dim3 gridDim, dim3 blockDim, unsigned m //resolve the binary version if(m_binary_verion == VOLTA_BINART_VERSION) OpcodeMap = &Volta_OpcodeMap; + else if(m_binary_verion == PASCAL_TITANX_BINART_VERSION || m_binary_verion == PASCAL_P100_BINART_VERSION) + OpcodeMap = &Pascal_OpcodeMap; else assert(0 && "unsupported binary version"); } @@ -448,7 +451,6 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere //handle special cases and fill memory space switch(m_opcode){ - case OP_LD: case OP_LDG: case OP_LDL: assert(mem_width>0); @@ -465,12 +467,11 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere cache_op = CACHE_GLOBAL; } break; - case OP_ST: case OP_STG: case OP_STL: - case OP_ATOM: case OP_ATOMG: case OP_RED: + case OP_ATOM: assert(mem_width>0); data_size = get_datawidth_from_opcode(opcode_tokens); memory_op = memory_store; @@ -480,10 +481,8 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere else space.set_type(global_space); - if(m_opcode == OP_ATOM || m_opcode == OP_ATOMG || m_opcode == OP_RED){ + if(m_opcode == OP_ATOMG || m_opcode == OP_ATOM || m_opcode == OP_RED){ m_isatomic = true; - //memory_op = no_memory_op; - memory_op = memory_load; op=LOAD_OP; cache_op = CACHE_GLOBAL; @@ -504,14 +503,24 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere assert(mem_width>0); data_size = mem_width; space.set_type(shared_space); - if(m_opcode == OP_ATOMS ) { + if(m_opcode == OP_ATOMS || m_opcode == OP_LDS) { //m_isatomic = true; - op=LOAD_OP; memory_op = memory_load; - } break; + case OP_ST: + case OP_LD: + //TO DO: set generic load based on the address + //right now, we consider all loads are shared. + assert(mem_width>0); + data_size = get_datawidth_from_opcode(opcode_tokens); + space.set_type(shared_space); + if(m_opcode == OP_LD) + memory_op = memory_load; + else + memory_op = memory_store; + break; case OP_BAR: //TO DO: fill this correctly bar_id = 0; diff --git a/src/trace-driven/trace_opcode.h b/src/trace-driven/trace_opcode.h index 7f13ed8..2b40ace 100644 --- a/src/trace-driven/trace_opcode.h +++ b/src/trace-driven/trace_opcode.h @@ -23,6 +23,8 @@ enum TraceInstrOpcode { OP_TMML, OP_TXD, OP_TXQ, OP_BMOV, OP_BPT, OP_BRA, OP_BREAK, OP_BRX, OP_BSSY, OP_BSYNC, OP_CALL, OP_EXIT, OP_JMP, OP_JMX, OP_KILL, OP_NANOSLEEP, OP_RET, OP_RPCMOV, OP_RTT, OP_WARPSYNC, OP_YIELD, OP_B2R, OP_BAR, OP_CS2R, OP_CSMTEST, OP_DEPBAR, OP_GETLMEMBASE, OP_LEPC, OP_NOP, OP_PMTRIG, OP_R2B, OP_S2R, OP_SETCTAID, OP_SETLMEMBASE, OP_VOTE, OP_VOTE_VTG, + OP_RRO, OP_DMNMX, OP_DSET, OP_BFE, OP_BFI, OP_ICMP, OP_IMADSP, OP_SHL, OP_XMAD, OP_CSET, OP_CSETP, + OP_TEXS, OP_TLD4S, OP_TLDS, OP_CAL, OP_JCAL, OP_PRET, OP_BRK, OP_PBK, OP_CONT, OP_PCNT, OP_PEXIT, SASS_NUM_OPCODES /* The total number of opcodes. */ }; typedef enum TraceInstrOpcode sass_op_type; diff --git a/src/trace-driven/volta_opcode.h b/src/trace-driven/volta_opcode.h index 23f0bd7..3d03201 100644 --- a/src/trace-driven/volta_opcode.h +++ b/src/trace-driven/volta_opcode.h @@ -10,7 +10,7 @@ #include #define VOLTA_BINART_VERSION 70 - +#define VOLTA_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 //TO DO: moving this to a yml or def files -- cgit v1.3 From b9cff5a53d576f1b2b953b3ce41b281128708787 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 25 Dec 2019 16:25:21 -0500 Subject: adding memcpy traces --- src/trace-driven/gpgpusim_trace_driven_main.cc | 18 +++++++++--- src/trace-driven/trace_driven.cc | 40 ++++++++++++++++++++++---- src/trace-driven/trace_driven.h | 2 ++ 3 files changed, 50 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 2f5d04d..58239b8 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -49,12 +49,22 @@ int main ( int argc, const char **argv ) trace_parser tracer(m_gpgpu_sim->get_config().get_traces_filename(), m_gpgpu_sim, m_gpgpu_context); - std::vector kernellist = tracer.parse_kernellist_file(); + std::vector commandlist = tracer.parse_kernellist_file(); - for(unsigned i=0; ilaunch(kernel_info); + trace_kernel_info_t* kernel_info; + if(commandlist[i].substr(0,6) == "Memcpy") { + + size_t addre, Bcount; + tracer.parse_memcpy_info(commandlist[i], addre, Bcount); + m_gpgpu_sim->perf_memcpy_to_gpu(addre, Bcount); + continue; + } + else if(commandlist[i].substr(0,6) == "kernel") { + kernel_info = tracer.parse_kernel_info(commandlist[i]); + m_gpgpu_sim->launch(kernel_info); + } bool active = false; bool sim_cycles = false; diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 48ba0f6..fb8afdd 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -25,6 +25,23 @@ #include "pascal_opcode.h" #include "../gpgpusim_entrypoint.h" + +bool is_number(const std::string& s) +{ + std::string::const_iterator it = s.begin(); + while (it != s.end() && std::isdigit(*it)) ++it; + return !s.empty() && it == s.end(); +} + +void split(const std::string& str, std::vector& cont, char delimi = ' ') +{ + std::stringstream ss(str); + std::string token; + while (std::getline(ss, token, delimi)) { + cont.push_back(token); + } +} + trace_parser::trace_parser(const char* kernellist_filepath, gpgpu_sim * m_gpgpu_sim, gpgpu_context* m_gpgpu_context) { @@ -55,14 +72,30 @@ std::vector trace_parser::parse_kernellist_file() { getline(ifs, line); if(line.empty()) continue; + else if(line.substr(0,6) == "Memcpy") { + kernellist.push_back(line); + } + else if(line.substr(0,6) == "kernel") { filepath = directory+"/"+line; kernellist.push_back(filepath); + } } ifs.close(); return kernellist; } +void trace_parser::parse_memcpy_info(const std::string& memcpy_command, size_t& address, size_t& count) { + std::vector params; + split(memcpy_command, params, ','); + assert(params.size() == 3); + std::stringstream ss; + ss.str(params[1]); + ss>>std::hex>>address; + ss.clear(); + ss.str(params[2]); + ss>>std::dec>>count; +} trace_kernel_info_t* trace_parser::parse_kernel_info(const std::string& kerneltraces_filepath) { @@ -266,12 +299,7 @@ bool trace_warp_inst_t::check_opcode_contain(const std::vector& opc return false; } -bool is_number(const std::string& s) -{ - std::string::const_iterator it = s.begin(); - while (it != s.end() && std::isdigit(*it)) ++it; - return !s.empty() && it == s.end(); -} + unsigned trace_warp_inst_t::get_datawidth_from_opcode(const std::vector& opcode) { diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index 8917502..33f4baf 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -77,6 +77,8 @@ public: std::vector parse_kernellist_file(); trace_kernel_info_t* parse_kernel_info(const std::string& kerneltraces_filepath); + void parse_memcpy_info(const std::string& memcpy_command, size_t& add, size_t& count); + void kernel_finalizer(trace_kernel_info_t* kernel_info); private: -- cgit v1.3 From efbc51f171ab79d831a296e1b6b09a704e6e9fd5 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 6 Jan 2020 17:44:48 -0500 Subject: fixing the dram read/write count --- src/gpgpu-sim/mem_latency_stat.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc index 2141e10..fcc1d18 100644 --- a/src/gpgpu-sim/mem_latency_stat.cc +++ b/src/gpgpu-sim/mem_latency_stat.cc @@ -41,6 +41,8 @@ #include #include #include +#include + #include "../../libcuda/gpgpu_context.h" memory_stats_t::memory_stats_t( unsigned n_shader, const shader_core_config *shader_config, const memory_config *mem_config, const class gpgpu_sim* gpu ) @@ -187,13 +189,13 @@ void memory_stats_t::memlatstat_dram_access(mem_fetch *mf) bankwrites[mf->get_sid()][dram_id][bank]++; shader_mem_acc_log( mf->get_sid(), dram_id, bank, 'w'); } - totalbankwrites[dram_id][bank]++; + totalbankwrites[dram_id][bank] += ceil(mf->get_data_size() / m_memory_config->dram_atom_size); } else { bankreads[mf->get_sid()][dram_id][bank]++; shader_mem_acc_log( mf->get_sid(), dram_id, bank, 'r'); - totalbankreads[dram_id][bank]++; + totalbankreads[dram_id][bank] += ceil(mf->get_data_size() / m_memory_config->dram_atom_size); } - mem_access_type_stats[mf->get_access_type()][dram_id][bank]++; + mem_access_type_stats[mf->get_access_type()][dram_id][bank] += ceil(mf->get_data_size() / m_memory_config->dram_atom_size); } if (mf->get_pc() != (unsigned)-1) -- cgit v1.3 From dd1f4f5788ad4b990803ac906ed82b3198799879 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 8 Jan 2020 18:08:28 -0500 Subject: fixing the memcpy assertion --- src/trace-driven/gpgpusim_trace_driven_main.cc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 58239b8..68b2ff7 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -53,15 +53,17 @@ int main ( int argc, const char **argv ) for(unsigned i=0; iperf_memcpy_to_gpu(addre, Bcount); continue; } - else if(commandlist[i].substr(0,6) == "kernel") { + else { kernel_info = tracer.parse_kernel_info(commandlist[i]); m_gpgpu_sim->launch(kernel_info); } @@ -90,9 +92,10 @@ int main ( int argc, const char **argv ) } while( active ); - tracer.kernel_finalizer(kernel_info); - - m_gpgpu_sim->print_stats(); + if(kernel_info) { + tracer.kernel_finalizer(kernel_info); + m_gpgpu_sim->print_stats(); + } if(sim_cycles) { m_gpgpu_sim->update_stats(); -- cgit v1.3 From b2def455d573f66fbc38dabda4adbc3a56225910 Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Sun, 9 Feb 2020 20:39:22 -0500 Subject: adding kepler sass, skip-first-kernel and update config file --- .../SM3_KEPLER_TITAN/config_kepler_islip.icnt | 73 ++++++++ .../tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config | 186 ++++++++++++++++++++ configs/tested-cfgs/SM6_TITANX/gpgpusim.config | 34 ++-- configs/tested-cfgs/SM6_TITANX/gpgpusim_old.config | 192 +++++++++++++++++++++ configs/tested-cfgs/SM7_QV100/gpgpusim.config | 2 +- configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config | 3 +- .../Turing_RTX2060/config_pascal_islip.icnt | 73 ++++++++ configs/tested-cfgs/Turing_RTX2060/gpgpusim.config | 186 ++++++++++++++++++++ src/gpgpu-sim/gpu-sim.cc | 3 + src/gpgpu-sim/gpu-sim.h | 4 +- src/trace-driven/gpgpusim_trace_driven_main.cc | 6 + src/trace-driven/kepler_opcode.h | 141 +++++++++++++++ src/trace-driven/pascal_opcode.h | 8 +- src/trace-driven/trace_driven.cc | 5 + src/trace-driven/trace_opcode.h | 7 +- 15 files changed, 899 insertions(+), 24 deletions(-) create mode 100644 configs/tested-cfgs/SM3_KEPLER_TITAN/config_kepler_islip.icnt create mode 100644 configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config create mode 100644 configs/tested-cfgs/SM6_TITANX/gpgpusim_old.config create mode 100644 configs/tested-cfgs/Turing_RTX2060/config_pascal_islip.icnt create mode 100644 configs/tested-cfgs/Turing_RTX2060/gpgpusim.config create mode 100644 src/trace-driven/kepler_opcode.h (limited to 'src') diff --git a/configs/tested-cfgs/SM3_KEPLER_TITAN/config_kepler_islip.icnt b/configs/tested-cfgs/SM3_KEPLER_TITAN/config_kepler_islip.icnt new file mode 100644 index 0000000..2fe3b53 --- /dev/null +++ b/configs/tested-cfgs/SM3_KEPLER_TITAN/config_kepler_islip.icnt @@ -0,0 +1,73 @@ +//21*1 fly with 32 flits per packet under gpgpusim injection mode +use_map = 0; +flit_size = 40; + +// currently we do not use this, see subnets below +network_count = 2; + +// Topology +topology = fly; +k = 38; +n = 1; + +// Routing + +routing_function = dest_tag; + +// Flow control + +num_vcs = 1; +vc_buf_size = 64; +input_buffer_size = 256; +ejection_buffer_size = 64; +boundary_buffer_size = 64; + +wait_for_tail_credit = 0; + +// Router architecture + +vc_allocator = islip; //separable_input_first; +sw_allocator = islip; //separable_input_first; +alloc_iters = 1; + +credit_delay = 0; +routing_delay = 0; +vc_alloc_delay = 1; +sw_alloc_delay = 1; + +input_speedup = 1; +output_speedup = 1; +internal_speedup = 2.0; + +// Traffic, GPGPU-Sim does not use this + +traffic = uniform; +packet_size ={{1,2,3,4},{10,20}}; +packet_size_rate={{1,1,1,1},{2,1}}; + +// Simulation - Don't change + +sim_type = gpgpusim; +//sim_type = latency; +injection_rate = 0.1; + +subnets = 2; + +// Always use read and write no matter following line +//use_read_write = 1; + + +read_request_subnet = 0; +read_reply_subnet = 1; +write_request_subnet = 0; +write_reply_subnet = 1; + +read_request_begin_vc = 0; +read_request_end_vc = 0; +write_request_begin_vc = 0; +write_request_end_vc = 0; +read_reply_begin_vc = 0; +read_reply_end_vc = 0; +write_reply_begin_vc = 0; +write_reply_end_vc = 0; + diff --git a/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config b/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config new file mode 100644 index 0000000..323d2d9 --- /dev/null +++ b/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config @@ -0,0 +1,186 @@ +# This config models the KEPLER (TITAN) +# For more info about this card, see Nvidia White paper +# https://wr0.wr.inf.h-brs.de/wr/hardware/nodes3/nvidia/NVIDIA-Kepler-GK110-Architecture-Whitepaper.pdf + +# functional simulator specification +-gpgpu_ptx_instruction_classification 0 +-gpgpu_ptx_sim_mode 0 +-gpgpu_ptx_force_max_capability 35 +-gpgpu_ignore_resources_limitation 1 + +# Device Limits +-gpgpu_stack_size_limit 1024 +-gpgpu_heap_size_limit 8388608 +-gpgpu_runtime_sync_depth_limit 2 +-gpgpu_runtime_pending_launch_count_limit 2048 + +# Compute Capability +-gpgpu_compute_capability_major 3 +-gpgpu_compute_capability_minor 5 + +# SASS execution (only supported with CUDA >= 4.0) +-gpgpu_ptx_convert_to_ptxplus 0 +-gpgpu_ptx_save_converted_ptxplus 0 + +# high level architecture configuration +# P102 has two semi-indp scheds per core, and two cores per cluster +-gpgpu_n_clusters 14 +-gpgpu_n_cores_per_cluster 1 +-gpgpu_n_mem 12 +-gpgpu_n_sub_partition_per_mchannel 2 + +# Kepler clock domains +#-gpgpu_clock_domains ::: +# Kepler NVIDIA TITAN clock domains are adopted from +# https://en.wikipedia.org/wiki/GeForce_700_series +-gpgpu_clock_domains 837.0:837.0:837.0:1502.0 + +# shader core pipeline config +-gpgpu_shader_registers 65536 +-gpgpu_occupancy_sm_number 62 + +# This implies a maximum of 32 warps/SM +-gpgpu_shader_core_pipeline 2048:32 +-gpgpu_shader_cta 16 +-gpgpu_simd_model 1 + +# Pipeline widths and number of FUs +# ID_OC_SP,ID_OC_DP,ID_OC_INT,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_INT,OC_EX_SFU,OC_EX_MEM,EX_WB +## Kepler has 6 SP SIMD units and 2 SFU units per SM. +# There is no int unit in kepler +## we need to scale the number of pipeline registers to be equal to the number of SP units +-gpgpu_pipeline_widths 6,4,0,2,1,6,4,0,2,1,12 +-gpgpu_num_sp_units 6 +-gpgpu_num_sfu_units 2 +-gpgpu_num_dp_units 4 + + +# Instruction latencies and initiation intervals +# "ADD,MAX,MUL,MAD,DIV" +# All Div operations are executed on SFU unit +# Throughput (initiation latency) are adopted from CUDA SDK document V8, section 5.4.1, Table 2 +-ptx_opcode_latency_int 4,13,4,5,145 +-ptx_opcode_initiation_int 1,1,1,1,4 +-ptx_opcode_latency_fp 4,13,4,5,39 +-ptx_opcode_initiation_fp 1,2,1,1,4 +-ptx_opcode_latency_dp 8,19,8,8,330 +-ptx_opcode_initiation_dp 2,8,8,8,130 +-ptx_opcode_initiation_sfu 2 +-ptx_opcode_latency_sfu 200 + +# ::,::::,::,:** +# ** Optional parameter - Required when mshr_type==Texture Fifo +# Note: Hashing set index function (H) only applies to a set size of 32 or 64. +# The defulat is to disable the L1 cache, unless cache modifieres are used +-gpgpu_cache:dl1 S:4:128:32,L:L:s:N:L,A:256:8,16:0,32 +-gpgpu_cache:dl1PrefL1 S:4:128:96,L:L:s:N:L,A:256:8,16:0,32 +-gpgpu_cache:dl1PrefShared S:4:128:32,L:L:s:N:L,A:256:8,16:0,32 +-gpgpu_shmem_size 49152 +-gpgpu_shmem_sizeDefault 49152 +-gpgpu_shmem_size_PrefL1 16384 +-gpgpu_shmem_size_PrefShared 49152 +# By default, L1 cache is disabled in Kepler P102 and only enabled for local memory +# requests with .nc modifier or __ldg mehtod will be cached in L1 cache even with gmem_skip_L1D=1 +-gmem_skip_L1D 1 +-icnt_flit_size 40 +-gpgpu_n_cluster_ejection_buffer_size 32 +-l1_latency 82 +-smem_latency 24 +-gpgpu_flush_l1_cache 1 + +# 32 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives 1.5MB L2 cache +-gpgpu_cache:dl2 S:32:128:16,L:B:m:L:L,A:256:64,16:0,32 +-gpgpu_cache:dl2_texture_only 0 +-gpgpu_dram_partition_queues 32:32:32:32 +-perf_sim_memcpy 1 +-memory_partition_indexing 0 + +# 4 KB Inst. +-gpgpu_cache:il1 N:8:128:4,L:R:f:N:L,S:2:48,4 +# 48 KB Tex +-gpgpu_tex_cache:l1 N:16:128:24,L:R:m:N:L,T:128:4,128:2 +# 12 KB Const +-gpgpu_const_cache:l1 N:128:64:2,L:R:f:N:L,S:2:64,4 + +# enable operand collector +-gpgpu_operand_collector_num_units_sp 12 +-gpgpu_operand_collector_num_units_sfu 6 +-gpgpu_operand_collector_num_units_mem 8 +-gpgpu_operand_collector_num_units_dp 6 +-gpgpu_operand_collector_num_in_ports_sp 2 +-gpgpu_operand_collector_num_out_ports_sp 2 +-gpgpu_operand_collector_num_in_ports_sfu 2 +-gpgpu_operand_collector_num_out_ports_sfu 2 +-gpgpu_operand_collector_num_in_ports_mem 1 +-gpgpu_operand_collector_num_out_ports_mem 1 +-gpgpu_operand_collector_num_in_ports_dp 1 +-gpgpu_operand_collector_num_out_ports_dp 1 +-gpgpu_num_reg_banks 32 + +# shared memory bankconflict detection +-gpgpu_shmem_num_banks 32 +-gpgpu_shmem_limited_broadcast 0 +-gpgpu_shmem_warp_parts 1 +# Use kepler Coalsce arhitetecture +-gpgpu_coalesce_arch 35 + +## In Kepler, a warp scheduler can issue 2 insts per cycle +-gpgpu_max_insn_issue_per_warp 2 +-gpgpu_dual_issue_diff_exec_units 0 + +# interconnection +-network_mode 1 +-inter_config_file config_kepler_islip.icnt + +# memory partition latency config +-rop_latency 120 +-dram_latency 100 + +# dram model config +-gpgpu_dram_scheduler 1 +-gpgpu_frfcfs_dram_sched_queue_size 64 +-gpgpu_dram_return_queue_size 64 + +# for NVIDIA TITAN, bus width is 384bits (12 DRAM chips x 32 bits) +# 12 memory paritions, 4 bytes (1 DRAM chip) per memory partition +# the atom size of GDDR5X (the smallest read request) is 32 bytes +-gpgpu_n_mem_per_ctrlr 1 +-gpgpu_dram_buswidth 4 +-gpgpu_dram_burst_length 8 +-dram_data_command_freq_ratio 4 # GDDR5X is QDR +-gpgpu_mem_address_mask 1 +-gpgpu_mem_addr_mapping dramid@8;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBCCCC.BCCSSSSS + +# Use the same GDDR5 timing, scaled to 2500MHZ +-gpgpu_dram_timing_opt "nbk=16:CCD=2:RRD=8:RCD=16:RAS=37:RP=16:RC=52: + CL=16:WL=6:CDLR=7:WR=16:nbkgrp=4:CCDL=4:RTPL=3" + +-dram_bnk_indexing_policy 0 +-dram_bnkgrp_indexing_policy 1 + +#-Seperate_Write_Queue_Enable 1 +#-Write_Queue_Size 64:56:32 + +# Kepler TITAN has four schedulers per core +-gpgpu_num_sched_per_core 4 +# Two Level Scheduler with active and pending pools +#-gpgpu_scheduler two_level_active:6:0:1 +# Loose round robbin scheduler +#-gpgpu_scheduler lrr +# Greedy then oldest scheduler +-gpgpu_scheduler gto + +# stat collection +-gpgpu_memlatency_stat 14 +-gpgpu_runtime_stat 500 +-enable_ptx_file_line_stats 1 +-visualizer_enabled 0 + +# power model configs, disable it untill we create a real energy model for Kepler +-power_simulation_enabled 0 + +# tracing functionality +#-trace_enabled 1 +#-trace_components WARP_SCHEDULER,SCOREBOARD +#-trace_sampling_core 0 + diff --git a/configs/tested-cfgs/SM6_TITANX/gpgpusim.config b/configs/tested-cfgs/SM6_TITANX/gpgpusim.config index e6d8f1d..f8689c2 100644 --- a/configs/tested-cfgs/SM6_TITANX/gpgpusim.config +++ b/configs/tested-cfgs/SM6_TITANX/gpgpusim.config @@ -25,7 +25,7 @@ # high level architecture configuration # P102 has two semi-indp scheds per core, and two cores per cluster -gpgpu_n_clusters 28 --gpgpu_n_cores_per_cluster 2 +-gpgpu_n_cores_per_cluster 1 -gpgpu_n_mem 12 -gpgpu_n_sub_partition_per_mchannel 2 @@ -36,12 +36,12 @@ -gpgpu_clock_domains 1417.0:1417.0:1417.0:2500.0 # shader core pipeline config --gpgpu_shader_registers 32768 +-gpgpu_shader_registers 65536 -gpgpu_occupancy_sm_number 62 # This implies a maximum of 32 warps/SM --gpgpu_shader_core_pipeline 1024:32 --gpgpu_shader_cta 16 +-gpgpu_shader_core_pipeline 2048:32 +-gpgpu_shader_cta 32 -gpgpu_simd_model 1 # Pipeline widths and number of FUs @@ -49,9 +49,9 @@ ## Pascal GP102 has 4 SP SIMD units and 4 SFU units per SM. In this config, we split SM into two shader cores, each has 2 SPs and 2 SFUs # There is no int unit in Pascal ## we need to scale the number of pipeline registers to be equal to the number of SP units --gpgpu_pipeline_widths 2,1,0,2,1,2,1,0,2,1,5 --gpgpu_num_sp_units 2 --gpgpu_num_sfu_units 2 +-gpgpu_pipeline_widths 4,1,0,4,1,4,1,0,4,1,9 +-gpgpu_num_sp_units 4 +-gpgpu_num_sfu_units 4 -gpgpu_num_dp_units 1 @@ -74,16 +74,14 @@ # ::,::::,::,:** # ** Optional parameter - Required when mshr_type==Texture Fifo # Note: Hashing set index function (H) only applies to a set size of 32 or 64. -# Pascal GP102 has 96KB Shared memory divided over 2 cores, each has 48KB -# Pascal GP102 has 2 banks L1 cache, where each is 24KB L1 cache # The defulat is to disable the L1 cache, unless cache modifieres are used --gpgpu_cache:dl1 S:4:128:48,L:L:s:N:L,A:256:8,16:0,32 --gpgpu_cache:dl1PrefL1 S:4:128:48,L:L:s:N:L,A:256:8,16:0,32 --gpgpu_cache:dl1PrefShared S:4:128:48,L:L:s:N:L,A:256:8,16:0,32 --gpgpu_shmem_size 49152 --gpgpu_shmem_sizeDefault 49152 --gpgpu_shmem_size_PrefL1 49152 --gpgpu_shmem_size_PrefShared 49152 +-gpgpu_cache:dl1 S:4:128:96,L:L:s:N:L,A:256:8,16:0,32 +-gpgpu_cache:dl1PrefL1 S:4:128:96,L:L:s:N:L,A:256:8,16:0,32 +-gpgpu_cache:dl1PrefShared S:4:128:96,L:L:s:N:L,A:256:8,16:0,32 +-gpgpu_shmem_size 98304 +-gpgpu_shmem_sizeDefault 98304 +-gpgpu_shmem_size_PrefL1 98304 +-gpgpu_shmem_size_PrefShared 98304 # By default, L1 cache is disabled in Pascal P102. # requests with .nc modifier or __ldg mehtod will be cached in L1 cache even with gmem_skip_L1D=1 -gmem_skip_L1D 1 @@ -136,7 +134,7 @@ # interconnection -network_mode 1 --inter_config_file config_fermi_islip.icnt +-inter_config_file config_pascal_islip.icnt # memory partition latency config -rop_latency 120 @@ -168,7 +166,7 @@ #-Write_Queue_Size 64:56:32 # Pascal 102 has four schedulers per core --gpgpu_num_sched_per_core 2 +-gpgpu_num_sched_per_core 4 # Two Level Scheduler with active and pending pools #-gpgpu_scheduler two_level_active:6:0:1 # Loose round robbin scheduler diff --git a/configs/tested-cfgs/SM6_TITANX/gpgpusim_old.config b/configs/tested-cfgs/SM6_TITANX/gpgpusim_old.config new file mode 100644 index 0000000..17ad779 --- /dev/null +++ b/configs/tested-cfgs/SM6_TITANX/gpgpusim_old.config @@ -0,0 +1,192 @@ +# This config models the Pascal GP102 (NVIDIA TITAN X) +# For more info about this card, see Nvidia White paper +# http://international.download.nvidia.com/geforce-com/international/pdfs/GeForce_GTX_1080_Whitepaper_FINAL.pdf + +# functional simulator specification +-gpgpu_ptx_instruction_classification 0 +-gpgpu_ptx_sim_mode 0 +-gpgpu_ptx_force_max_capability 61 +-gpgpu_ignore_resources_limitation 1 + +# Device Limits +-gpgpu_stack_size_limit 1024 +-gpgpu_heap_size_limit 8388608 +-gpgpu_runtime_sync_depth_limit 2 +-gpgpu_runtime_pending_launch_count_limit 2048 + +# Compute Capability +-gpgpu_compute_capability_major 6 +-gpgpu_compute_capability_minor 1 + +# SASS execution (only supported with CUDA >= 4.0) +-gpgpu_ptx_convert_to_ptxplus 0 +-gpgpu_ptx_save_converted_ptxplus 0 + +# high level architecture configuration +# P102 has two semi-indp scheds per core, and two cores per cluster +-gpgpu_n_clusters 28 +-gpgpu_n_cores_per_cluster 2 +-gpgpu_n_mem 12 +-gpgpu_n_sub_partition_per_mchannel 2 + +# Pascal clock domains +#-gpgpu_clock_domains ::: +# Pascal NVIDIA TITAN X clock domains are adopted from +# https://en.wikipedia.org/wiki/GeForce_10_series +-gpgpu_clock_domains 1417.0:1417.0:1417.0:2500.0 + +# shader core pipeline config +-gpgpu_shader_registers 32768 +-gpgpu_occupancy_sm_number 62 + +# This implies a maximum of 32 warps/SM +-gpgpu_shader_core_pipeline 1024:32 +-gpgpu_shader_cta 16 +-gpgpu_simd_model 1 + +# Pipeline widths and number of FUs +# ID_OC_SP,ID_OC_DP,ID_OC_INT,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_INT,OC_EX_SFU,OC_EX_MEM,EX_WB +## Pascal GP102 has 4 SP SIMD units and 4 SFU units per SM. In this config, we split SM into two shader cores, each has 2 SPs and 2 SFUs +# There is no int unit in Pascal +## we need to scale the number of pipeline registers to be equal to the number of SP units +-gpgpu_pipeline_widths 2,1,0,2,1,2,1,0,2,1,5 +-gpgpu_num_sp_units 2 +-gpgpu_num_sfu_units 2 +-gpgpu_num_dp_units 1 + + +# Instruction latencies and initiation intervals +# "ADD,MAX,MUL,MAD,DIV" +# All Div operations are executed on SFU unit +# Throughput (initiation latency) are adopted from CUDA SDK document V8, section 5.4.1, Table 2 +-ptx_opcode_latency_int 4,13,4,5,145 +-ptx_opcode_initiation_int 1,1,1,1,4 +-ptx_opcode_latency_fp 4,13,4,5,39 +-ptx_opcode_initiation_fp 1,2,1,1,4 +-ptx_opcode_latency_dp 8,19,8,8,330 +-ptx_opcode_initiation_dp 8,8,8,8,130 +-ptx_opcode_initiation_sfu 4 +-ptx_opcode_latency_sfu 8 + + +# latencies and cache configs are adopted from: +# https://arxiv.org/pdf/1804.06826.pdf +# ::,::::,::,:** +# ** Optional parameter - Required when mshr_type==Texture Fifo +# Note: Hashing set index function (H) only applies to a set size of 32 or 64. +# Pascal GP102 has 96KB Shared memory divided over 2 cores, each has 48KB +# Pascal GP102 has 2 banks L1 cache, where each is 24KB L1 cache +# The defulat is to disable the L1 cache, unless cache modifieres are used +-gpgpu_cache:dl1 S:4:128:48,L:L:s:N:L,A:256:8,16:0,32 +-gpgpu_cache:dl1PrefL1 S:4:128:48,L:L:s:N:L,A:256:8,16:0,32 +-gpgpu_cache:dl1PrefShared S:4:128:48,L:L:s:N:L,A:256:8,16:0,32 +-gpgpu_shmem_size 49152 +-gpgpu_shmem_sizeDefault 49152 +-gpgpu_shmem_size_PrefL1 49152 +-gpgpu_shmem_size_PrefShared 49152 +# By default, L1 cache is disabled in Pascal P102. +# requests with .nc modifier or __ldg mehtod will be cached in L1 cache even with gmem_skip_L1D=1 +-gmem_skip_L1D 1 +-icnt_flit_size 40 +-gpgpu_n_cluster_ejection_buffer_size 32 +-l1_latency 82 +-smem_latency 24 +-gpgpu_flush_l1_cache 1 + +# 64 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives 3MB L2 cache +-gpgpu_cache:dl2 S:64:128:16,L:B:m:L:L,A:256:64,16:0,32 +-gpgpu_cache:dl2_texture_only 0 +-gpgpu_dram_partition_queues 32:32:32:32 +-perf_sim_memcpy 1 +-memory_partition_indexing 0 + +# 4 KB Inst. +-gpgpu_cache:il1 N:8:128:4,L:R:f:N:L,S:2:48,4 +# 48 KB Tex +# Note, TEX is deprected in Pascal, It is used for legacy apps only. Use L1D cache instead with .nc modifier or __ldg mehtod +-gpgpu_tex_cache:l1 N:16:128:24,L:R:m:N:L,T:128:4,128:2 +# 12 KB Const +-gpgpu_const_cache:l1 N:128:64:2,L:R:f:N:L,S:2:64,4 + +# enable operand collector +-gpgpu_operand_collector_num_units_sp 12 +-gpgpu_operand_collector_num_units_sfu 6 +-gpgpu_operand_collector_num_units_mem 8 +-gpgpu_operand_collector_num_units_dp 6 +-gpgpu_operand_collector_num_in_ports_sp 2 +-gpgpu_operand_collector_num_out_ports_sp 2 +-gpgpu_operand_collector_num_in_ports_sfu 2 +-gpgpu_operand_collector_num_out_ports_sfu 2 +-gpgpu_operand_collector_num_in_ports_mem 1 +-gpgpu_operand_collector_num_out_ports_mem 1 +-gpgpu_operand_collector_num_in_ports_dp 1 +-gpgpu_operand_collector_num_out_ports_dp 1 +-gpgpu_num_reg_banks 32 + +# shared memory bankconflict detection +-gpgpu_shmem_num_banks 32 +-gpgpu_shmem_limited_broadcast 0 +-gpgpu_shmem_warp_parts 1 +# Use Pascal Coalsce arhitetecture +-gpgpu_coalesce_arch 61 + +## In Pascal, a warp scheduler can issue 2 insts per cycle using 2 diff execution units +-gpgpu_max_insn_issue_per_warp 2 +-gpgpu_dual_issue_diff_exec_units 1 + +# interconnection +-network_mode 1 +-inter_config_file config_pascal_islip.icnt + +# memory partition latency config +-rop_latency 120 +-dram_latency 100 + +# dram model config +-gpgpu_dram_scheduler 1 +-gpgpu_frfcfs_dram_sched_queue_size 64 +-gpgpu_dram_return_queue_size 64 + +# for NVIDIA TITAN X, bus width is 384bits (12 DRAM chips x 32 bits) +# 12 memory paritions, 4 bytes (1 DRAM chip) per memory partition +# the atom size of GDDR5X (the smallest read request) is 32 bytes +-gpgpu_n_mem_per_ctrlr 1 +-gpgpu_dram_buswidth 4 +-gpgpu_dram_burst_length 8 +-dram_data_command_freq_ratio 4 # GDDR5X is QDR +-gpgpu_mem_address_mask 1 +-gpgpu_mem_addr_mapping dramid@8;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBCCCC.BCCSSSSS + +# Use the same GDDR5 timing, scaled to 2500MHZ +-gpgpu_dram_timing_opt "nbk=16:CCD=2:RRD=8:RCD=16:RAS=37:RP=16:RC=52: + CL=16:WL=6:CDLR=7:WR=16:nbkgrp=4:CCDL=4:RTPL=3" + +-dram_bnk_indexing_policy 0 +-dram_bnkgrp_indexing_policy 1 + +#-Seperate_Write_Queue_Enable 1 +#-Write_Queue_Size 64:56:32 + +# Pascal 102 has four schedulers per core +-gpgpu_num_sched_per_core 2 +# Two Level Scheduler with active and pending pools +#-gpgpu_scheduler two_level_active:6:0:1 +# Loose round robbin scheduler +#-gpgpu_scheduler lrr +# Greedy then oldest scheduler +-gpgpu_scheduler gto + +# stat collection +-gpgpu_memlatency_stat 14 +-gpgpu_runtime_stat 500 +-enable_ptx_file_line_stats 1 +-visualizer_enabled 0 + +# power model configs, disable it untill we create a real energy model for Pascal 102 +-power_simulation_enabled 0 + +# tracing functionality +#-trace_enabled 1 +#-trace_components WARP_SCHEDULER,SCOREBOARD +#-trace_sampling_core 0 + diff --git a/configs/tested-cfgs/SM7_QV100/gpgpusim.config b/configs/tested-cfgs/SM7_QV100/gpgpusim.config index 584ef8d..41aea78 100644 --- a/configs/tested-cfgs/SM7_QV100/gpgpusim.config +++ b/configs/tested-cfgs/SM7_QV100/gpgpusim.config @@ -165,7 +165,7 @@ -gpgpu_dram_burst_length 2 -dram_data_command_freq_ratio 2 # HBM is DDR -gpgpu_mem_address_mask 1 --gpgpu_mem_addr_mapping dramid@6;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBCCCC.CBCSSSSS +-gpgpu_mem_addr_mapping dramid@8;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBCCCB.CCCSSSSS # HBM timing are adopted from hynix JESD235 standered and nVidia HPCA 2017 paper (http://www.cs.utah.edu/~nil/pubs/hpca17.pdf) # Timing for 1 GHZ diff --git a/configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config b/configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config index 0d4a812..ba50287 100644 --- a/configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config +++ b/configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config @@ -20,7 +20,6 @@ -gpgpu_runtime_sync_depth_limit 2 -gpgpu_runtime_pending_launch_count_limit 2048 -gpgpu_kernel_launch_latency 5000 --gpgpu_TB_launch_latency 0 # Compute Capability -gpgpu_compute_capability_major 7 @@ -166,7 +165,7 @@ -gpgpu_dram_burst_length 2 -dram_data_command_freq_ratio 2 # HBM is DDR -gpgpu_mem_address_mask 1 --gpgpu_mem_addr_mapping dramid@6;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBCCCC.CBCSSSSS +-gpgpu_mem_addr_mapping dramid@8;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBCCCB.CCCSSSSS # HBM timing are adopted from hynix JESD235 standered and nVidia HPCA 2017 paper (http://www.cs.utah.edu/~nil/pubs/hpca17.pdf) # Timing for 1 GHZ diff --git a/configs/tested-cfgs/Turing_RTX2060/config_pascal_islip.icnt b/configs/tested-cfgs/Turing_RTX2060/config_pascal_islip.icnt new file mode 100644 index 0000000..dec4789 --- /dev/null +++ b/configs/tested-cfgs/Turing_RTX2060/config_pascal_islip.icnt @@ -0,0 +1,73 @@ +//21*1 fly with 32 flits per packet under gpgpusim injection mode +use_map = 0; +flit_size = 40; + +// currently we do not use this, see subnets below +network_count = 2; + +// Topology +topology = fly; +k = 52; +n = 1; + +// Routing + +routing_function = dest_tag; + +// Flow control + +num_vcs = 1; +vc_buf_size = 64; +input_buffer_size = 256; +ejection_buffer_size = 64; +boundary_buffer_size = 64; + +wait_for_tail_credit = 0; + +// Router architecture + +vc_allocator = islip; //separable_input_first; +sw_allocator = islip; //separable_input_first; +alloc_iters = 1; + +credit_delay = 0; +routing_delay = 0; +vc_alloc_delay = 1; +sw_alloc_delay = 1; + +input_speedup = 1; +output_speedup = 1; +internal_speedup = 2.0; + +// Traffic, GPGPU-Sim does not use this + +traffic = uniform; +packet_size ={{1,2,3,4},{10,20}}; +packet_size_rate={{1,1,1,1},{2,1}}; + +// Simulation - Don't change + +sim_type = gpgpusim; +//sim_type = latency; +injection_rate = 0.1; + +subnets = 2; + +// Always use read and write no matter following line +//use_read_write = 1; + + +read_request_subnet = 0; +read_reply_subnet = 1; +write_request_subnet = 0; +write_reply_subnet = 1; + +read_request_begin_vc = 0; +read_request_end_vc = 0; +write_request_begin_vc = 0; +write_request_end_vc = 0; +read_reply_begin_vc = 0; +read_reply_end_vc = 0; +write_reply_begin_vc = 0; +write_reply_end_vc = 0; + diff --git a/configs/tested-cfgs/Turing_RTX2060/gpgpusim.config b/configs/tested-cfgs/Turing_RTX2060/gpgpusim.config new file mode 100644 index 0000000..ab324d8 --- /dev/null +++ b/configs/tested-cfgs/Turing_RTX2060/gpgpusim.config @@ -0,0 +1,186 @@ +# functional simulator specification +-gpgpu_ptx_instruction_classification 0 +-gpgpu_ptx_sim_mode 0 +-gpgpu_ptx_force_max_capability 70 + +# Device Limits +-gpgpu_stack_size_limit 1024 +-gpgpu_heap_size_limit 8388608 +-gpgpu_runtime_sync_depth_limit 2 +-gpgpu_runtime_pending_launch_count_limit 2048 +-gpgpu_kernel_launch_latency 5000 +-gpgpu_TB_launch_latency 0 + +# Compute Capability +-gpgpu_compute_capability_major 7 +-gpgpu_compute_capability_minor 0 + +# SASS execution (only supported with CUDA >= 4.0) +-gpgpu_ptx_convert_to_ptxplus 0 +-gpgpu_ptx_save_converted_ptxplus 0 + +# high level architecture configuration +-gpgpu_n_clusters 30 +-gpgpu_n_cores_per_cluster 1 +-gpgpu_n_mem 12 +-gpgpu_n_sub_partition_per_mchannel 2 + +# volta clock domains +#-gpgpu_clock_domains ::: +# Turing clock domains are adopted from +# https://en.wikipedia.org/wiki/GeForce_20_series +-gpgpu_clock_domains 1365.0:1365.0:1365.0:3500.0 +# boost mode +# -gpgpu_clock_domains 1680.0:1680.0:1680.0:3500.0 + +# shader core pipeline config +-gpgpu_shader_registers 65536 +-gpgpu_registers_per_block 65536 +-gpgpu_occupancy_sm_number 70 + +# This implies a maximum of 64 warps/SM +-gpgpu_shader_core_pipeline 2048:32 +-gpgpu_shader_cta 32 +-gpgpu_simd_model 1 + +# Pipeline widths and number of FUs +# ID_OC_SP,ID_OC_DP,ID_OC_INT,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_INT,OC_EX_SFU,OC_EX_MEM,EX_WB,ID_OC_TENSOR_CORE,OC_EX_TENSOR_CORE +## Volta GV100 has 4 SP SIMD units, 4 SFU units, 4 DP units per core, 4 Tensor core units +## we need to scale the number of pipeline registers to be equal to the number of SP units +-gpgpu_pipeline_widths 4,4,4,4,4,4,4,4,4,4,8,4,4 +-gpgpu_num_sp_units 4 +-gpgpu_num_sfu_units 4 +-gpgpu_num_dp_units 4 +-gpgpu_num_int_units 4 +-gpgpu_tensor_core_avail 1 +-gpgpu_num_tensor_core_units 4 + +# Instruction latencies and initiation intervals +# "ADD,MAX,MUL,MAD,DIV" +# All Div operations are executed on SFU unit +# Throughput (initiation latency) are adopted from +# http://on-demand.gputechconf.com/gtc/2018/presentation/s8122-dissecting-the-volta-gpu-architecture-through-microbenchmarking.pdf +-ptx_opcode_latency_int 4,13,4,5,145 +-ptx_opcode_initiation_int 2,2,2,2,8 +-ptx_opcode_latency_fp 4,13,4,5,39 +-ptx_opcode_initiation_fp 2,2,2,2,4 +-ptx_opcode_latency_dp 8,19,8,8,330 +-ptx_opcode_initiation_dp 4,4,4,4,130 +-ptx_opcode_latency_sfu 100 +-ptx_opcode_initiation_sfu 8 +-ptx_opcode_latency_tesnor 64 +-ptx_opcode_initiation_tensor 64 + +# ::,::::,::,:** +# ** Optional parameter - Required when mshr_type==Texture Fifo +-adaptive_cache_config 0 +-l1_banks 4 +-gpgpu_cache:dl1 S:1:128:512,L:L:s:N:L,A:256:8,16:0,32 +-gpgpu_shmem_size 65536 +-gpgpu_shmem_sizeDefault 65536 +-gpgpu_shmem_per_block 65536 +-gmem_skip_L1D 0 +-icnt_flit_size 40 +-gpgpu_n_cluster_ejection_buffer_size 32 +-l1_latency 20 +-smem_latency 20 +-gpgpu_flush_l1_cache 1 + +# 32 sets, each 128 bytes 32-way for each memory sub partition (96 KB per memory sub partition). This gives us 6MB L2 cache +-gpgpu_cache:dl2 S:32:128:32,L:B:m:L:L,A:192:4,32:0,32 +-gpgpu_cache:dl2_texture_only 0 +-gpgpu_dram_partition_queues 64:64:64:64 +-perf_sim_memcpy 1 +-memory_partition_indexing 0 + +# 128 KB Inst. +-gpgpu_cache:il1 N:64:128:16,L:R:f:N:L,S:2:48,4 +# 128 KB Tex +# Note, TEX is deprected in Volta, It is used for legacy apps only. Use L1D cache instead with .nc modifier or __ldg mehtod +-gpgpu_tex_cache:l1 N:4:128:256,L:R:m:N:L,T:512:8,128:2 +# 64 KB Const +-gpgpu_const_cache:l1 N:128:64:8,L:R:f:N:L,S:2:64,4 +-perfect_inst_const_cache 1 + +# i.e. schedulers are isolated +-sub_core_model 1 +# disable specialized operand collectors and use generic operand collectors instead +-enable_specialized_operand_collector 0 +-gpgpu_operand_collector_num_units_gen 32 +-gpgpu_operand_collector_num_in_ports_gen 8 +-gpgpu_operand_collector_num_out_ports_gen 8 +# volta has 8 banks, 4 schedulers, two banks per scheduler +-gpgpu_num_reg_banks 32 + +# shared memory bankconflict detection +-gpgpu_shmem_num_banks 32 +-gpgpu_shmem_limited_broadcast 0 +-gpgpu_shmem_warp_parts 1 +-gpgpu_coalesce_arch 60 + +## In Volta, a warp scheduler can issue 1 inst per cycle +-gpgpu_max_insn_issue_per_warp 1 +-gpgpu_dual_issue_diff_exec_units 1 + +# interconnection +#-network_mode 1 +#-inter_config_file config_volta_islip.icnt +# for local xbar, use: +-network_mode 2 +-inct_in_buffer_limit 512 +-inct_out_buffer_limit 512 +-inct_subnets 2 +-arbiter_algo 1 + +# memory partition latency config +-rop_latency 160 +-dram_latency 100 + +# dram model config +-gpgpu_dram_scheduler 1 +-gpgpu_frfcfs_dram_sched_queue_size 64 +-gpgpu_dram_return_queue_size 192 + +# GDDR6 +# http://monitorinsider.com/GDDR6.html +-gpgpu_n_mem_per_ctrlr 1 +-gpgpu_dram_buswidth 2 +-gpgpu_dram_burst_length 16 +-dram_data_command_freq_ratio 4 # GDDR6 is QDR +-gpgpu_mem_address_mask 1 +-gpgpu_mem_addr_mapping dramid@8;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBCCCC.BCCSSSSS + +# Use the same GDDR5 timing, scaled to 3500MHZ +-gpgpu_dram_timing_opt "nbk=16:CCD=4:RRD=10:RCD=20:RAS=50:RP=20:RC=62: + CL=20:WL=8:CDLR=9:WR=20:nbkgrp=4:CCDL=4:RTPL=4" + +# select lower bits for bnkgrp to increase bnkgrp parallelism +-dram_bnk_indexing_policy 0 +-dram_bnkgrp_indexing_policy 1 + +#-Seperate_Write_Queue_Enable 1 +#-Write_Queue_Size 64:56:32 + +# Volta has four schedulers per core +-gpgpu_num_sched_per_core 4 +# Two Level Scheduler with active and pending pools +#-gpgpu_scheduler two_level_active:6:0:1 +# Loose round robbin scheduler +#-gpgpu_scheduler lrr +# Greedy then oldest scheduler +-gpgpu_scheduler gto + +# stat collection +-gpgpu_memlatency_stat 14 +-gpgpu_runtime_stat 500 +-enable_ptx_file_line_stats 1 +-visualizer_enabled 0 + +# power model configs, disable it untill we create a real energy model for Volta +-power_simulation_enabled 0 + +# tracing functionality +#-trace_enabled 1 +#-trace_components WARP_SCHEDULER,SCOREBOARD +#-trace_sampling_core 0 + diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 7f9985e..4e38f67 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -573,6 +573,9 @@ void gpgpu_sim_config::reg_options(option_parser_t opp) option_parser_register(opp, "-trace_driven_mode", OPT_BOOL, &trace_driven_mode, "Turn on trace_driven_mode", "0"); + option_parser_register(opp, "-trace_skip_first_kernel", OPT_BOOL, + &trace_skip_first_kernel, "skip first intiliztion kernel in trace mode", + "0"); option_parser_register(opp, "-trace", OPT_CSTR, &g_traces_filename, "traces kernel file" "traces kernel file directory", diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 1ac4fdb..abc905e 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -348,7 +348,8 @@ 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; } + bool is_trace_driven_mode() const { return trace_driven_mode; } + bool is_skip_first_kernel() const { return trace_skip_first_kernel; } char* get_traces_filename() const { return g_traces_filename; } bool flush_l1() const { return gpgpu_flush_l1_cache; } @@ -408,6 +409,7 @@ private: //trace driven mode options bool trace_driven_mode; + bool trace_skip_first_kernel; char *g_traces_filename; friend class gpgpu_sim; diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 68b2ff7..0e3aced 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -50,6 +50,7 @@ int main ( int argc, const char **argv ) trace_parser tracer(m_gpgpu_sim->get_config().get_traces_filename(), m_gpgpu_sim, m_gpgpu_context); std::vector commandlist = tracer.parse_kernellist_file(); + bool first_kernel=true; for(unsigned i=0; iget_config().is_skip_first_kernel() && first_kernel) { + first_kernel = false; + continue; + } kernel_info = tracer.parse_kernel_info(commandlist[i]); m_gpgpu_sim->launch(kernel_info); } diff --git a/src/trace-driven/kepler_opcode.h b/src/trace-driven/kepler_opcode.h new file mode 100644 index 0000000..f85346f --- /dev/null +++ b/src/trace-driven/kepler_opcode.h @@ -0,0 +1,141 @@ +//developed by Mahmoud Khairy, Purdue Univ +//abdallm@purdue.edu + +#ifndef KEPLER_OPCODE_H +#define KEPLER_OPCODE_H + +#include "../abstract_hardware_model.h" +#include "trace_opcode.h" +#include +#include + +#define KEPLER_BINART_VERSION 35 +#define KEPLER_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 + +//TO DO: moving this to a yml or def files + +///Kepler ISA +//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html +static const std::unordered_map Kepler_OpcodeMap = { + //Floating Point 32 Instructions + {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, + {"FADD", OpcodeChar(OP_FADD, SP_OP)}, + {"FCMP", OpcodeChar(OP_FCMP, SP_OP)}, + {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, + {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, + {"FSWZ", OpcodeChar(OP_FSWZ, SP_OP)}, + {"FSET", OpcodeChar(OP_FSET, SP_OP)}, + {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, + {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, + {"RRO", OpcodeChar(OP_RRO, SP_OP)}, + //SFU + {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, + + + //Double Point Instructions + {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, + {"DADD", OpcodeChar(OP_DADD, DP_OP)}, + {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, + {"DMNMX", OpcodeChar(OP_DMNMX, DP_OP)}, + {"DSET", OpcodeChar(OP_DSET, DP_OP)}, + {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, + + //Integer Instructions + {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, + {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, + {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, + {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, + {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, + {"ISAD", OpcodeChar(OP_ISAD, INTP_OP)}, + {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, + {"BFE", OpcodeChar(OP_BFE, INTP_OP)}, + {"BFI", OpcodeChar(OP_BFI, INTP_OP)}, + {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, + {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, + {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, + {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, + {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, + {"ISET", OpcodeChar(OP_ISET, INTP_OP)}, + {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, + {"ICMP", OpcodeChar(OP_ICMP, INTP_OP)}, + {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, + + //Conversion Instructions + {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, + {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, + {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, + {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, + + //Movement Instructions + {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, + {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, + {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, + {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, + {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, + + //Predicate Instructions + {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, + {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, + {"CSET", OpcodeChar(OP_CSET, ALU_OP)}, + {"CSETP", OpcodeChar(OP_CSETP, ALU_OP)}, + {"PSET", OpcodeChar(OP_PSET, ALU_OP)}, + {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, + + //Texture Instructions + //For now, we ignore texture loads, consider it as ALU_OP + {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, + {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, + {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, + {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, + + //Load/Store Instructions + //For now, we ignore constant loads, consider it as ALU_OP, TO DO + {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, + {"LD", OpcodeChar(OP_LD, LOAD_OP)}, + {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, + {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, + {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, + {"LDSLK", OpcodeChar(OP_LDSLK, LOAD_OP)}, + {"ST", OpcodeChar(OP_ST, STORE_OP)}, + {"STL", OpcodeChar(OP_STL, STORE_OP)}, + {"STS", OpcodeChar(OP_STS, STORE_OP)}, + {"STSCUL", OpcodeChar(OP_STSCUL, STORE_OP)}, + {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, + {"RED", OpcodeChar(OP_RED, STORE_OP)}, + {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, + {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, + {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, + + //surface memory instructions + {"SUCLAMP", OpcodeChar(OP_SUCLAMP, LOAD_OP)}, + {"SUBFM", OpcodeChar(OP_SUBFM, LOAD_OP)}, + {"SUEAU", OpcodeChar(OP_SUEAU, LOAD_OP)}, + {"SULDGA", OpcodeChar(OP_SULDGA, LOAD_OP)}, + {"SUSTGA", OpcodeChar(OP_SUSTGA, STORE_OP)}, + + //Control Instructions + {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, + {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, + {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, + {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, + {"CAL", OpcodeChar(OP_CAL, CALL_OPS)}, + {"JCAL", OpcodeChar(OP_JCAL, CALL_OPS)}, + {"RET", OpcodeChar(OP_RET, RET_OPS)}, + {"BRK", OpcodeChar(OP_BRK, RET_OPS)}, + {"CONT", OpcodeChar(OP_CONT, RET_OPS)}, + {"SSY", OpcodeChar(OP_SSY, RET_OPS)}, + {"PBK", OpcodeChar(OP_PBK, RET_OPS)}, + {"PCNT", OpcodeChar(OP_PCNT, RET_OPS)}, + {"PRET", OpcodeChar(OP_PRET, RET_OPS)}, + {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, + {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, + + //Miscellaneous Instructions + {"NOP", OpcodeChar(OP_NOP, ALU_OP)}, + {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, + {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, + {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, + {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, +}; + +#endif diff --git a/src/trace-driven/pascal_opcode.h b/src/trace-driven/pascal_opcode.h index d4f787d..2cacb28 100644 --- a/src/trace-driven/pascal_opcode.h +++ b/src/trace-driven/pascal_opcode.h @@ -70,6 +70,7 @@ static const std::unordered_map Pascal_OpcodeMap = { {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, + {"ISET", OpcodeChar(OP_ISET, INTP_OP)}, {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, @@ -85,6 +86,8 @@ static const std::unordered_map Pascal_OpcodeMap = { {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, {"XMAD", OpcodeChar(OP_XMAD, INTP_OP)}, + {"VMNMX", OpcodeChar(OP_VMNMX, INTP_OP)}, + //Conversion Instructions {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, @@ -109,7 +112,8 @@ static const std::unordered_map Pascal_OpcodeMap = { {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, {"CSET", OpcodeChar(OP_CSET, ALU_OP)}, {"CSETP", OpcodeChar(OP_CSETP, ALU_OP)}, - {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, + {"PSET", OpcodeChar(OP_PSET, ALU_OP)}, + //Load/Store Instructions {"LD", OpcodeChar(OP_LD, LOAD_OP)}, @@ -157,6 +161,8 @@ static const std::unordered_map Pascal_OpcodeMap = { {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, + {"SSY", OpcodeChar(OP_SSY, BRANCH_OP)}, + {"SYNC", OpcodeChar(OP_SYNC, BRANCH_OP)}, {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index fb8afdd..7b5c523 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -23,6 +23,7 @@ #include "volta_opcode.h" #include "turing_opcode.h" #include "pascal_opcode.h" +#include "kepler_opcode.h" #include "../gpgpusim_entrypoint.h" @@ -221,6 +222,10 @@ trace_kernel_info_t::trace_kernel_info_t(dim3 gridDim, dim3 blockDim, unsigned m OpcodeMap = &Volta_OpcodeMap; else if(m_binary_verion == PASCAL_TITANX_BINART_VERSION || m_binary_verion == PASCAL_P100_BINART_VERSION) OpcodeMap = &Pascal_OpcodeMap; + else if(m_binary_verion == KEPLER_BINART_VERSION) + OpcodeMap = &Kepler_OpcodeMap; + else if(m_binary_verion == TURING_BINART_VERSION) + OpcodeMap = &Turing_OpcodeMap; else assert(0 && "unsupported binary version"); } diff --git a/src/trace-driven/trace_opcode.h b/src/trace-driven/trace_opcode.h index 2b40ace..d60d0ae 100644 --- a/src/trace-driven/trace_opcode.h +++ b/src/trace-driven/trace_opcode.h @@ -10,6 +10,7 @@ enum TraceInstrOpcode { + //volta (common insts for others cards as well) OP_FADD = 1, OP_FADD32I, OP_FCHK, OP_FFMA32I, OP_FFMA, OP_FMNMX, OP_FMUL, OP_FMUL32I, OP_FSEL, OP_FSET, OP_FSETP, OP_FSWZADD, OP_MUFU, OP_HADD2, OP_HADD2_32I, OP_HFMA2, OP_HFMA2_32I, OP_HMUL2, OP_HMUL2_32I, OP_HSET2, OP_HSETP2, OP_HMMA, OP_DADD, OP_DFMA, OP_DMUL, OP_DSETP, @@ -23,8 +24,12 @@ enum TraceInstrOpcode { OP_TMML, OP_TXD, OP_TXQ, OP_BMOV, OP_BPT, OP_BRA, OP_BREAK, OP_BRX, OP_BSSY, OP_BSYNC, OP_CALL, OP_EXIT, OP_JMP, OP_JMX, OP_KILL, OP_NANOSLEEP, OP_RET, OP_RPCMOV, OP_RTT, OP_WARPSYNC, OP_YIELD, OP_B2R, OP_BAR, OP_CS2R, OP_CSMTEST, OP_DEPBAR, OP_GETLMEMBASE, OP_LEPC, OP_NOP, OP_PMTRIG, OP_R2B, OP_S2R, OP_SETCTAID, OP_SETLMEMBASE, OP_VOTE, OP_VOTE_VTG, + //unique insts for pascal OP_RRO, OP_DMNMX, OP_DSET, OP_BFE, OP_BFI, OP_ICMP, OP_IMADSP, OP_SHL, OP_XMAD, OP_CSET, OP_CSETP, - OP_TEXS, OP_TLD4S, OP_TLDS, OP_CAL, OP_JCAL, OP_PRET, OP_BRK, OP_PBK, OP_CONT, OP_PCNT, OP_PEXIT, + OP_TEXS, OP_TLD4S, OP_TLDS, OP_CAL, OP_JCAL, OP_PRET, OP_BRK, OP_PBK, OP_CONT, OP_PCNT, OP_PEXIT, OP_SSY, OP_SYNC, OP_PSET + , OP_VMNMX, OP_ISET, + //unique insts for kepler + OP_FCMP, OP_FSWZ, OP_ISAD, OP_LDSLK, OP_STSCUL, OP_SUCLAMP, OP_SUBFM, OP_SUEAU, OP_SULDGA, OP_SUSTGA, SASS_NUM_OPCODES /* The total number of opcodes. */ }; typedef enum TraceInstrOpcode sass_op_type; -- cgit v1.3 From 7d56112add643f9178753750efb97e12e1e5524c Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Sun, 9 Feb 2020 20:59:18 -0500 Subject: adding missing kepler insts --- src/trace-driven/kepler_opcode.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/trace-driven/kepler_opcode.h b/src/trace-driven/kepler_opcode.h index f85346f..0805c12 100644 --- a/src/trace-driven/kepler_opcode.h +++ b/src/trace-driven/kepler_opcode.h @@ -19,9 +19,12 @@ static const std::unordered_map Kepler_OpcodeMap = { //Floating Point 32 Instructions {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, + {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, {"FADD", OpcodeChar(OP_FADD, SP_OP)}, + {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, {"FCMP", OpcodeChar(OP_FCMP, SP_OP)}, {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, + {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, {"FSWZ", OpcodeChar(OP_FSWZ, SP_OP)}, {"FSET", OpcodeChar(OP_FSET, SP_OP)}, @@ -44,8 +47,11 @@ static const std::unordered_map Kepler_OpcodeMap = { {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, + {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, + {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, + {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, {"ISAD", OpcodeChar(OP_ISAD, INTP_OP)}, {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, {"BFE", OpcodeChar(OP_BFE, INTP_OP)}, @@ -54,6 +60,7 @@ static const std::unordered_map Kepler_OpcodeMap = { {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, + {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, {"ISET", OpcodeChar(OP_ISET, INTP_OP)}, {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, -- cgit v1.3 From 79bc1ca604153be11878b24b3a8d670860011762 Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Mon, 10 Feb 2020 19:09:54 -0500 Subject: fixing kepler load in sass --- src/trace-driven/trace_driven.cc | 11 +++++++---- src/trace-driven/trace_driven.h | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 7b5c523..35e953e 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -286,7 +286,7 @@ bool trace_kernel_info_t::get_next_threadblock_traces(std::vectorgetShaderCoreConfig(), m_gpgpu_context); - inst.parse_from_string(line, OpcodeMap); + inst.parse_from_string(line, OpcodeMap, binary_verion); threadblock_traces[warp_id]->push_back(inst); } } @@ -323,7 +323,7 @@ unsigned trace_warp_inst_t::get_datawidth_from_opcode(const std::vector* OpcodeMap){ +bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordered_map* OpcodeMap, unsigned binary_verion){ std::stringstream ss; ss.str(trace); @@ -546,9 +546,12 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere case OP_LD: //TO DO: set generic load based on the address //right now, we consider all loads are shared. - assert(mem_width>0); + assert(mem_width>0); data_size = get_datawidth_from_opcode(opcode_tokens); - space.set_type(shared_space); + if(binary_verion == KEPLER_BINART_VERSION) + space.set_type(global_space); + else + space.set_type(shared_space); if(m_opcode == OP_LD) memory_op = memory_load; else diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index 33f4baf..9539e6d 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -44,7 +44,7 @@ public: m_opcode=0; } - bool parse_from_string(std::string trace, const std::unordered_map* OpcodeMap); + bool parse_from_string(std::string trace, const std::unordered_map* OpcodeMap, unsigned binary_verion); private: void set_latency(unsigned cat); -- cgit v1.3 From 221cbdadf6b54cd75aaecd89d93a9c6f9f8c7dad Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Mon, 10 Feb 2020 19:18:14 -0500 Subject: fixing the kepler stats --- src/trace-driven/kepler_opcode.h | 1 + src/trace-driven/trace_opcode.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/trace-driven/kepler_opcode.h b/src/trace-driven/kepler_opcode.h index 0805c12..f2bbc90 100644 --- a/src/trace-driven/kepler_opcode.h +++ b/src/trace-driven/kepler_opcode.h @@ -50,6 +50,7 @@ static const std::unordered_map Kepler_OpcodeMap = { {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, + {"ISUB", OpcodeChar(OP_ISUB, INTP_OP)}, {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, {"ISAD", OpcodeChar(OP_ISAD, INTP_OP)}, diff --git a/src/trace-driven/trace_opcode.h b/src/trace-driven/trace_opcode.h index d60d0ae..3492fd3 100644 --- a/src/trace-driven/trace_opcode.h +++ b/src/trace-driven/trace_opcode.h @@ -29,7 +29,7 @@ enum TraceInstrOpcode { OP_TEXS, OP_TLD4S, OP_TLDS, OP_CAL, OP_JCAL, OP_PRET, OP_BRK, OP_PBK, OP_CONT, OP_PCNT, OP_PEXIT, OP_SSY, OP_SYNC, OP_PSET , OP_VMNMX, OP_ISET, //unique insts for kepler - OP_FCMP, OP_FSWZ, OP_ISAD, OP_LDSLK, OP_STSCUL, OP_SUCLAMP, OP_SUBFM, OP_SUEAU, OP_SULDGA, OP_SUSTGA, + OP_FCMP, OP_FSWZ, OP_ISAD, OP_LDSLK, OP_STSCUL, OP_SUCLAMP, OP_SUBFM, OP_SUEAU, OP_SULDGA, OP_SUSTGA, OP_ISUB, SASS_NUM_OPCODES /* The total number of opcodes. */ }; typedef enum TraceInstrOpcode sass_op_type; -- cgit v1.3 From 1d3ccd32e70c6a6c524abbe8ff0ac450481290d4 Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Mon, 10 Feb 2020 21:28:09 -0500 Subject: removing assertion in random hashing --- src/gpgpu-sim/addrdec.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc index 670bd61..c34cb32 100644 --- a/src/gpgpu-sim/addrdec.cc +++ b/src/gpgpu-sim/addrdec.cc @@ -221,7 +221,7 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_ { //This is an unrealistic hashing using software hashtable //we generate a random set for each memory address and save the value in a big hashtable for future reuse - assert(!gap); + //assert(!gap); new_addr_type chip_address = (addr>>(ADDR_CHIP_S-log2sub_partition)); tr1_hash_map::const_iterator got = address_random_interleaving.find (chip_address); if ( got == address_random_interleaving.end() ) { -- cgit v1.3 From 5221ed98c5a7f0ceec3eb96216f4449635a74b22 Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Thu, 13 Feb 2020 12:32:39 -0500 Subject: fixing pascal --- src/gpgpu-sim/shader.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 23050d3..7fc31f3 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -106,7 +106,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, } if(m_config->sub_core_model) { //in subcore model, each scheduler should has its own issue register, so num scheduler = reg width - assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_SP].get_size() ); + //assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_SP].get_size() ); assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_SFU].get_size() ); assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_MEM].get_size() ); if(m_config->gpgpu_tensor_core_avail) -- cgit v1.3 From 024cb02ecadc58c401b9cbeb558774c6ba7415aa Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Thu, 26 Mar 2020 14:11:10 -0400 Subject: fixing core fetch bw --- src/gpgpu-sim/shader.cc | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 7fc31f3..e206d9c 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -889,7 +889,7 @@ void shader_core_ctx::fetch() assert( status == RESERVATION_FAIL ); delete mf; } - break; + //break; } } } @@ -1067,7 +1067,18 @@ void scheduler_unit::cycle() exec_unit_type_t previous_issued_inst_exec_type = exec_unit_type_t::NONE; unsigned max_issue = m_shader->m_config->gpgpu_max_insn_issue_per_warp; bool diff_exec_units = m_shader->m_config->gpgpu_dual_issue_diff_exec_units; //In tis mode, we only allow dual issue to diff execution units (as in Maxwell and Pascal) - + + if(warp(warp_id).ibuffer_empty()) + SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) fails as ibuffer_empty\n", + (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id() ); + + if(warp(warp_id).waiting()) + SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) fails as waiting for barrier\n", + (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id() ); + + if((*iter)->get_warp_id() ==2 ) + printf(" Hello! I am here! \n "); + while( !warp(warp_id).waiting() && !warp(warp_id).ibuffer_empty() && (checked < max_issue) && (checked <= issued) && (issued < max_issue) ) { const warp_inst_t *pI = warp(warp_id).ibuffer_next_inst(); //Jin: handle cdp latency; @@ -1120,13 +1131,13 @@ void scheduler_unit::cycle() } } else { - bool sp_pipe_avail = m_sp_out->has_free(m_shader->m_config->sub_core_model, m_id); - bool sfu_pipe_avail = m_sfu_out->has_free(m_shader->m_config->sub_core_model, m_id); - bool tensor_core_pipe_avail = m_tensor_core_out->has_free(m_shader->m_config->sub_core_model, m_id); - bool dp_pipe_avail = m_dp_out->has_free(m_shader->m_config->sub_core_model, m_id); - bool int_pipe_avail = m_int_out->has_free(m_shader->m_config->sub_core_model, m_id); + bool sp_pipe_avail = (m_shader->m_config->gpgpu_num_sp_units > 0) && m_sp_out->has_free(m_shader->m_config->sub_core_model, m_id); + bool sfu_pipe_avail = (m_shader->m_config->gpgpu_num_sfu_units > 0) && m_sfu_out->has_free(m_shader->m_config->sub_core_model, m_id); + bool tensor_core_pipe_avail = (m_shader->m_config->gpgpu_num_tensor_core_units > 0) && m_tensor_core_out->has_free(m_shader->m_config->sub_core_model, m_id); + bool dp_pipe_avail = (m_shader->m_config->gpgpu_num_dp_units > 0) && m_dp_out->has_free(m_shader->m_config->sub_core_model, m_id); + bool int_pipe_avail = (m_shader->m_config->gpgpu_num_int_units > 0) && m_int_out->has_free(m_shader->m_config->sub_core_model, m_id); - //This code need to be refactored + //This code needs to be refactored if(pI->op != TENSOR_CORE_OP && pI->op != SFU_OP && pI->op != DP_OP) { bool execute_on_SP = false; @@ -1196,7 +1207,7 @@ void scheduler_unit::cycle() previous_issued_inst_exec_type = exec_unit_type_t::SFU; } } - else if ( (pI->op == TENSOR_CORE_OP) && !(diff_exec_units && previous_issued_inst_exec_type == exec_unit_type_t::SP) ) { + else if ( (pI->op == TENSOR_CORE_OP) && !(diff_exec_units && previous_issued_inst_exec_type == exec_unit_type_t::TENSOR) ) { if( tensor_core_pipe_avail ) { m_shader->issue_warp(*m_tensor_core_out,pI,active_mask,warp_id,m_id); issued++; -- cgit v1.3 From 38a5c4d70539cdacf1ce20394027d9b705ff9c76 Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Thu, 26 Mar 2020 18:18:17 -0400 Subject: increase inst fetch thoughput --- src/gpgpu-sim/shader.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index e206d9c..a2850d0 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -106,7 +106,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, } if(m_config->sub_core_model) { //in subcore model, each scheduler should has its own issue register, so num scheduler = reg width - //assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_SP].get_size() ); + assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_SP].get_size() ); assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_SFU].get_size() ); assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_MEM].get_size() ); if(m_config->gpgpu_tensor_core_avail) @@ -889,7 +889,7 @@ void shader_core_ctx::fetch() assert( status == RESERVATION_FAIL ); delete mf; } - //break; + break; } } } @@ -1074,10 +1074,7 @@ void scheduler_unit::cycle() if(warp(warp_id).waiting()) SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) fails as waiting for barrier\n", - (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id() ); - - if((*iter)->get_warp_id() ==2 ) - printf(" Hello! I am here! \n "); + (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id() ); while( !warp(warp_id).waiting() && !warp(warp_id).ibuffer_empty() && (checked < max_issue) && (checked <= issued) && (issued < max_issue) ) { const warp_inst_t *pI = warp(warp_id).ibuffer_next_inst(); @@ -3178,8 +3175,11 @@ void shader_core_ctx::cycle() execute(); read_operands(); issue(); + for(int i=0; i<8; ++i) { decode(); fetch(); + printf("Hello! \n"); + } } // Flushes all content of the cache to memory -- cgit v1.3 From ed97d2a5b0096fb8afa4bc83fe2df515b2a2399c Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Tue, 31 Mar 2020 13:00:34 -0400 Subject: adding inst fetch throughput --- src/gpgpu-sim/gpu-sim.cc | 4 +++- src/gpgpu-sim/shader.cc | 9 +++++---- src/gpgpu-sim/shader.h | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 4e38f67..4ef9a7d 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -470,7 +470,9 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-perfect_inst_const_cache", OPT_BOOL, &perfect_inst_const_cache, "perfect inst and const cache mode, so all inst and const hits in the cache(default = disabled)", "0"); - + option_parser_register(opp, "-inst_fetch_throughput", OPT_INT32, &inst_fetch_throughput, + "the number of fetched intruction per warp each cycle", + "1"); } void gpgpu_sim_config::reg_options(option_parser_t opp) diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index a2850d0..297f3bc 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3175,10 +3175,9 @@ void shader_core_ctx::cycle() execute(); read_operands(); issue(); - for(int i=0; i<8; ++i) { - decode(); - fetch(); - printf("Hello! \n"); + for(int i=0; i< m_config->inst_fetch_throughput; ++i) { + decode(); + fetch(); } } @@ -3235,6 +3234,7 @@ std::list opndcoll_rfu_t::arbiter_t::allocate_reads() ///// wavefront allocator from booksim... ---> // Loop through diagonals of request matrix + printf("####\n"); for ( int p = 0; p < _square; ++p ) { output = ( _pri + p ) % _square; @@ -3250,6 +3250,7 @@ std::list opndcoll_rfu_t::arbiter_t::allocate_reads() // Grant! _inmatch[input] = output; _outmatch[output] = input; + printf("Register File: granting banks %d to OC % \n", input, output); } output = ( output + 1 ) % _square; diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index d41c220..43c448b 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1524,6 +1524,7 @@ class shader_core_config : public core_config bool gpgpu_concurrent_kernel_sm; bool perfect_inst_const_cache; + unsigned inst_fetch_throughput; }; -- cgit v1.3 From eb618e6bbe0bac135ba800a5880f18040f35acf8 Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Tue, 31 Mar 2020 13:33:42 -0400 Subject: adding some RF stats --- src/gpgpu-sim/shader.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 297f3bc..afd63e8 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3250,7 +3250,7 @@ std::list opndcoll_rfu_t::arbiter_t::allocate_reads() // Grant! _inmatch[input] = output; _outmatch[output] = input; - printf("Register File: granting banks %d to OC % \n", input, output); + printf("Register File: granting bank %d to OC %d, schedid %d, warpid %d, Regid %d\n", input, output, (m_queue[output].front()).get_sid(), (m_queue[output].front()).get_wid(), (m_queue[output].front()).get_reg()); } output = ( output + 1 ) % _square; -- cgit v1.3 From cc5d6636df7388e44c5203e5580a2aa50c0fd6b1 Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Tue, 31 Mar 2020 16:38:14 -0400 Subject: fixing the RF assertion --- src/gpgpu-sim/shader.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index afd63e8..d9f7b94 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3237,7 +3237,7 @@ std::list opndcoll_rfu_t::arbiter_t::allocate_reads() printf("####\n"); for ( int p = 0; p < _square; ++p ) { - output = ( _pri + p ) % _square; + output = ( _pri + p ) % _outputs; // Step through the current diagonal for ( input = 0; input < _inputs; ++input ) { @@ -3250,15 +3250,15 @@ std::list opndcoll_rfu_t::arbiter_t::allocate_reads() // Grant! _inmatch[input] = output; _outmatch[output] = input; - printf("Register File: granting bank %d to OC %d, schedid %d, warpid %d, Regid %d\n", input, output, (m_queue[output].front()).get_sid(), (m_queue[output].front()).get_wid(), (m_queue[output].front()).get_reg()); + printf("Register File: granting bank %d to OC %d, schedid %d, warpid %d, Regid %d\n", input, output, (m_queue[input].front()).get_sid(), (m_queue[input].front()).get_wid(), (m_queue[input].front()).get_reg()); } - output = ( output + 1 ) % _square; + output = ( output + 1 ) % _outputs; } } // Round-robin the priority diagonal - _pri = ( _pri + 1 ) % _square; + _pri = ( _pri + 1 ) % _outputs; /// <--- end code from booksim -- cgit v1.3 From 3633eacca183608fe1a666212ba468b787c063a5 Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Tue, 31 Mar 2020 20:43:41 -0400 Subject: adding new comments --- src/gpgpu-sim/gpu-sim.cc | 3 +++ src/gpgpu-sim/shader.cc | 13 +++++++------ src/gpgpu-sim/shader.h | 1 + 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 4ef9a7d..94ea6d2 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -473,6 +473,9 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-inst_fetch_throughput", OPT_INT32, &inst_fetch_throughput, "the number of fetched intruction per warp each cycle", "1"); + option_parser_register(opp, "-gpgpu_reg_file_port_throughput", OPT_INT32, ®_file_port_throughput, + "the number ports of the register file", + "1"); } void gpgpu_sim_config::reg_options(option_parser_t opp) diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index d9f7b94..ed0c25e 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -384,12 +384,12 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_fu.push_back(new dp_unit( &m_pipeline_reg[EX_WB], m_config, this )); m_dispatch_port.push_back(ID_OC_DP); m_issue_port.push_back(OC_EX_DP); - } + } for (int k = 0; k < m_config->gpgpu_num_int_units; k++) { m_fu.push_back(new int_unit( &m_pipeline_reg[EX_WB], m_config, this )); m_dispatch_port.push_back(ID_OC_INT); m_issue_port.push_back(OC_EX_INT); - } + } for (int k = 0; k < m_config->gpgpu_num_sfu_units; k++) { m_fu.push_back(new sfu( &m_pipeline_reg[EX_WB], m_config, this )); @@ -2413,7 +2413,8 @@ void ldst_unit::issue( register_set ®_set ) void ldst_unit::cycle() { writeback(); - m_operand_collector->step(); + for(int i=0; i< m_config->reg_file_port_throughput; ++i) + m_operand_collector->step(); for( unsigned stage=0; (stage+1)empty() && !m_pipeline_reg[stage+1]->empty() ) move_warp(m_pipeline_reg[stage], m_pipeline_reg[stage+1]); @@ -3234,7 +3235,7 @@ std::list opndcoll_rfu_t::arbiter_t::allocate_reads() ///// wavefront allocator from booksim... ---> // Loop through diagonals of request matrix - printf("####\n"); + // printf("####\n"); for ( int p = 0; p < _square; ++p ) { output = ( _pri + p ) % _outputs; @@ -3245,12 +3246,12 @@ std::list opndcoll_rfu_t::arbiter_t::allocate_reads() assert( output < _outputs ); if ( ( output < _outputs ) && ( _inmatch[input] == -1 ) && - ( _outmatch[output] == -1 ) && + //( _outmatch[output] == -1 ) && //allow OC to read multiple reg banks at the same cycle ( _request[input][output]/*.label != -1*/ ) ) { // Grant! _inmatch[input] = output; _outmatch[output] = input; - printf("Register File: granting bank %d to OC %d, schedid %d, warpid %d, Regid %d\n", input, output, (m_queue[input].front()).get_sid(), (m_queue[input].front()).get_wid(), (m_queue[input].front()).get_reg()); + // printf("Register File: granting bank %d to OC %d, schedid %d, warpid %d, Regid %d\n", input, output, (m_queue[input].front()).get_sid(), (m_queue[input].front()).get_wid(), (m_queue[input].front()).get_reg()); } output = ( output + 1 ) % _outputs; diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 43c448b..665e3a5 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1525,6 +1525,7 @@ class shader_core_config : public core_config bool perfect_inst_const_cache; unsigned inst_fetch_throughput; + unsigned reg_file_port_throughput; }; -- cgit v1.3 From bd647361e2b8eb2d72f0055df851fcdee53e94cc Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Tue, 31 Mar 2020 20:54:44 -0400 Subject: fixing the tensor unit failing --- src/gpgpu-sim/gpu-sim.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 94ea6d2..e5b9c9d 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -453,7 +453,7 @@ void shader_core_config::reg_options(class OptionParser * opp) "1"); option_parser_register(opp, "-gpgpu_num_tensor_core_units", OPT_INT32, &gpgpu_num_tensor_core_units, "Number of tensor_core units (default=1)", - "1"); + "0"); option_parser_register(opp, "-gpgpu_num_mem_units", OPT_INT32, &gpgpu_num_mem_units, "Number if ldst units (default=1) WARNING: not hooked up to anything", "1"); -- cgit v1.3 From 52204ff08a9c9a21a99fee3f976d2a419c014fec Mon Sep 17 00:00:00 2001 From: "Mahmoud Khairy A. Abdallah" Date: Mon, 18 May 2020 21:49:34 -0400 Subject: fixing some failing apps --- configs/tested-cfgs/SM75_RTX2060/gpgpusim.config | 6 +++--- configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config | 4 ++-- src/gpgpu-sim/gpu-sim.cc | 3 ++- src/gpgpu-sim/shader.cc | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config index e8329dd..b89971e 100644 --- a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config +++ b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config @@ -33,9 +33,9 @@ # volta clock domains #-gpgpu_clock_domains ::: --gpgpu_clock_domains 1365.0:1365.0:1365.0:7000.0 +-gpgpu_clock_domains 1365.0:1365.0:1365.0:3500.0 # boost mode -# -gpgpu_clock_domains 1680.0:1680.0:1680.0:7000.0 +# -gpgpu_clock_domains 1680.0:1680.0:1680.0:3500.0 # shader core pipeline config -gpgpu_shader_registers 65536 @@ -156,7 +156,7 @@ -gpgpu_n_mem_per_ctrlr 1 -gpgpu_dram_buswidth 2 -gpgpu_dram_burst_length 16 --dram_data_command_freq_ratio 2 # GDDR6 is configured as DDR in Turing +-dram_data_command_freq_ratio 4 -gpgpu_mem_address_mask 1 -gpgpu_mem_addr_mapping dramid@8;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBCCCC.BCCSSSSS diff --git a/configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config b/configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config index 0255f76..0df3eec 100644 --- a/configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config +++ b/configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config @@ -74,8 +74,8 @@ -ptx_opcode_initiation_dp 4,4,4,4,130 -ptx_opcode_latency_sfu 100 -ptx_opcode_initiation_sfu 8 --ptx_opcode_latency_tesnor 6 --ptx_opcode_initiation_tensor 2 +-ptx_opcode_latency_tesnor 8 +-ptx_opcode_initiation_tensor 4 # Volta has sub core model, in which each scheduler has its own register file and EUs # i.e. schedulers are isolated diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index e5b9c9d..cd5fa56 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -1828,7 +1828,8 @@ void shader_core_ctx::dump_warp_state( FILE *fout ) const void gpgpu_sim::perf_memcpy_to_gpu( size_t dst_start_addr, size_t count ) { if (m_memory_config->m_perf_sim_memcpy) { - assert (dst_start_addr % 32 == 0); + //if(!m_config.trace_driven_mode) //in trace-driven mode, CUDA runtime can start nre data structure at any position + // assert (dst_start_addr % 32 == 0); for ( unsigned counter = 0; counter < count; counter += 32 ) { const unsigned wr_addr = dst_start_addr + counter; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index ed0c25e..65ec113 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3091,7 +3091,7 @@ unsigned int shader_core_config::max_cta( const kernel_info_t &k ) const 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 + //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(); -- cgit v1.3 From 9122b45726d55a21a68d143083eae2ded0c2ac8c Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 20 May 2020 20:45:21 -0400 Subject: rmoving repeated line --- src/trace-driven/gpgpusim_trace_driven_main.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'src') diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 68b2ff7..0385f51 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -54,7 +54,6 @@ int main ( int argc, const char **argv ) for(unsigned i=0; i Date: Fri, 22 May 2020 20:16:04 -0400 Subject: code reformatting --- configs/tested-cfgs/SM2_GTX480/gpgpusim.config | 12 +- .../tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config | 21 ++- configs/tested-cfgs/SM6_TITANX/gpgpusim.config | 35 ++-- configs/tested-cfgs/SM6_TITANX/gpgpusim_old.config | 192 ------------------- configs/tested-cfgs/SM75_RTX2060/gpgpusim.config | 73 ++++---- configs/tested-cfgs/SM7_QV100/gpgpusim.config | 61 +++--- .../SM7_QV100_SASS/config_volta_islip.icnt | 74 -------- configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config | 206 --------------------- .../tested-cfgs/SM7_TITANV/config_volta_islip.icnt | 74 -------- configs/tested-cfgs/SM7_TITANV/gpgpusim.config | 205 -------------------- src/abstract_hardware_model.h | 2 +- src/gpgpu-sim/addrdec.cc | 2 +- src/gpgpu-sim/gpu-sim.cc | 51 +++-- src/gpgpu-sim/icnt_wrapper.cc | 12 +- src/gpgpu-sim/shader.cc | 2 +- src/gpgpu-sim/shader.h | 7 + src/trace-driven/gpgpusim_trace_driven_main.cc | 3 +- src/trace-driven/kepler_opcode.h | 5 +- src/trace-driven/trace_driven.cc | 104 ++++------- src/trace-driven/trace_driven.h | 28 ++- 20 files changed, 225 insertions(+), 944 deletions(-) delete mode 100644 configs/tested-cfgs/SM6_TITANX/gpgpusim_old.config delete mode 100644 configs/tested-cfgs/SM7_QV100_SASS/config_volta_islip.icnt delete mode 100644 configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config delete mode 100644 configs/tested-cfgs/SM7_TITANV/config_volta_islip.icnt delete mode 100644 configs/tested-cfgs/SM7_TITANV/gpgpusim.config (limited to 'src') diff --git a/configs/tested-cfgs/SM2_GTX480/gpgpusim.config b/configs/tested-cfgs/SM2_GTX480/gpgpusim.config index 4a7a3c3..5a12e2e 100644 --- a/configs/tested-cfgs/SM2_GTX480/gpgpusim.config +++ b/configs/tested-cfgs/SM2_GTX480/gpgpusim.config @@ -63,10 +63,10 @@ -gpgpu_shmem_size 49152 -gpgpu_shmem_sizeDefault 49152 -icnt_flit_size 40 --gmem_skip_L1D 0 +-gpgpu_gmem_skip_L1D 0 -gpgpu_n_cluster_ejection_buffer_size 32 --l1_latency 35 --smem_latency 26 +-gpgpu_l1_latency 35 +-gpgpu_smem_latency 26 -gpgpu_flush_l1_cache 1 # The alternative configuration for fermi in case cudaFuncCachePreferL1 is selected @@ -77,8 +77,8 @@ -gpgpu_cache:dl2 S:64:128:8,L:B:m:L:L,A:256:4,4:0,32 -gpgpu_cache:dl2_texture_only 0 -gpgpu_dram_partition_queues 64:64:64:64 --perf_sim_memcpy 1 --memory_partition_indexing 0 +-gpgpu_perf_sim_memcpy 1 +-gpgpu_memory_partition_indexing 0 -gpgpu_cache:il1 N:4:128:4,L:R:f:N:L,S:2:32,4 -gpgpu_tex_cache:l1 N:4:128:24,L:R:m:N:L,T:128:4,128:2 @@ -104,7 +104,7 @@ -inter_config_file config_fermi_islip.icnt # memory partition latency config --rop_latency 120 +-gpgpu_l2_rop_latency 120 -dram_latency 100 # dram model config diff --git a/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config b/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config index 77617d6..b7c0edc 100644 --- a/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config +++ b/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config @@ -67,6 +67,11 @@ -ptx_opcode_initiation_sfu 2 -ptx_opcode_latency_sfu 200 +-trace_opcode_latency_initiation_int 4,1 +-trace_opcode_latency_initiation_sp 4,1 +-trace_opcode_latency_initiation_dp 20,2 +-trace_opcode_latency_initiation_sfu 200,2 + # enable operand collector -gpgpu_operand_collector_num_units_sp 12 -gpgpu_operand_collector_num_units_sfu 6 @@ -112,10 +117,10 @@ -gpgpu_shmem_size_PrefShared 49152 # By default, L1 cache is disabled in Kepler P102 and only enabled for local memory # requests with .nc modifier or __ldg mehtod will be cached in L1 cache even with gmem_skip_L1D=1 --gmem_skip_L1D 1 +-gpgpu_gmem_skip_L1D 1 -icnt_flit_size 40 -gpgpu_n_cluster_ejection_buffer_size 32 --l1_latency 82 +-gpgpu_l1_latency 82 -smem_latency 24 -gpgpu_flush_l1_cache 1 @@ -123,12 +128,12 @@ -gpgpu_cache:dl2 S:32:128:16,L:B:m:L:L,A:256:64,16:0,32 -gpgpu_cache:dl2_texture_only 0 -gpgpu_dram_partition_queues 32:32:32:32 --perf_sim_memcpy 1 --memory_partition_indexing 0 +-gpgpu_perf_sim_memcpy 1 +-gpgpu_memory_partition_indexing 0 # 4 KB Inst. -gpgpu_cache:il1 N:8:128:4,L:R:f:N:L,S:2:48,4 --inst_fetch_throughput 8 +-gpgpu_inst_fetch_throughput 8 # 48 KB Tex -gpgpu_tex_cache:l1 N:16:128:24,L:R:m:N:L,T:128:4,128:2 # 12 KB Const @@ -139,7 +144,7 @@ -inter_config_file config_kepler_islip.icnt # memory partition latency config --rop_latency 120 +-gpgpu_l2_rop_latency 120 -dram_latency 100 # dram model config @@ -164,8 +169,8 @@ -dram_bnk_indexing_policy 0 -dram_bnkgrp_indexing_policy 1 -#-Seperate_Write_Queue_Enable 1 -#-Write_Queue_Size 64:56:32 +#-dram_seperate_write_queue_enable 1 +#-dram_write_queue_size 64:56:32 # stat collection -gpgpu_memlatency_stat 14 diff --git a/configs/tested-cfgs/SM6_TITANX/gpgpusim.config b/configs/tested-cfgs/SM6_TITANX/gpgpusim.config index d54b7d4..adbf66c 100644 --- a/configs/tested-cfgs/SM6_TITANX/gpgpusim.config +++ b/configs/tested-cfgs/SM6_TITANX/gpgpusim.config @@ -22,6 +22,8 @@ # SASS execution (only supported with CUDA >= 4.0) -gpgpu_ptx_convert_to_ptxplus 0 -gpgpu_ptx_save_converted_ptxplus 0 +# SASS trace-driven mode execution +#-trace_driven_mode 1 # high level architecture configuration -gpgpu_n_clusters 28 @@ -62,13 +64,18 @@ -ptx_opcode_latency_dp 8,19,8,8,330 -ptx_opcode_initiation_dp 8,8,8,8,130 -ptx_opcode_initiation_sfu 4 --ptx_opcode_latency_sfu 8 +-ptx_opcode_latency_sfu 20 + +-trace_opcode_latency_initiation_int 4,1 +-trace_opcode_latency_initiation_sp 4,1 +-trace_opcode_latency_initiation_dp 20,8 +-trace_opcode_latency_initiation_sfu 20,4 # in sub_core_model, schedulers are isolated, each scheduler has its own register file and EUs --sub_core_model 1 +-gpgpu_sub_core_model 1 # enable operand collector # disable specialized operand collectors and use generic operand collectors instead --enable_specialized_operand_collector 0 +-gpgpu_enable_specialized_operand_collector 0 -gpgpu_operand_collector_num_units_gen 8 -gpgpu_operand_collector_num_in_ports_gen 8 -gpgpu_operand_collector_num_out_ports_gen 8 @@ -97,7 +104,7 @@ # ** Optional parameter - Required when mshr_type==Texture Fifo # Note: Hashing set index function (H) only applies to a set size of 32 or 64. # The defulat is to disable the L1 cache, unless cache modifieres are used --l1_banks 2 +-gpgpu_l1_banks 2 -gpgpu_cache:dl1 S:4:128:96,L:L:s:N:L,A:256:8,16:0,32 -gpgpu_cache:dl1PrefL1 S:4:128:96,L:L:s:N:L,A:256:8,16:0,32 -gpgpu_cache:dl1PrefShared S:4:128:96,L:L:s:N:L,A:256:8,16:0,32 @@ -107,36 +114,36 @@ -gpgpu_shmem_size_PrefShared 98304 # By default, L1 cache is disabled in Pascal P102. # requests with .nc modifier or __ldg mehtod will be cached in L1 cache even with gmem_skip_L1D=1 --gmem_skip_L1D 1 +-gpgpu_gmem_skip_L1D 1 -icnt_flit_size 40 -gpgpu_n_cluster_ejection_buffer_size 32 --l1_latency 82 --smem_latency 24 +-gpgpu_l1_latency 82 +-gpgpu_smem_latency 24 -gpgpu_flush_l1_cache 1 # 64 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives 3MB L2 cache -gpgpu_cache:dl2 S:1:128:1024,L:B:m:L:L,A:256:64,16:0,32 -gpgpu_cache:dl2_texture_only 0 -gpgpu_dram_partition_queues 32:32:32:32 --perf_sim_memcpy 1 --memory_partition_indexing 4 +-gpgpu_perf_sim_memcpy 1 +-gpgpu_memory_partition_indexing 4 # 4 KB Inst. -gpgpu_cache:il1 N:8:128:4,L:R:f:N:L,S:2:48,4 --inst_fetch_throughput 8 +-gpgpu_inst_fetch_throughput 8 # 48 KB Tex # Note, TEX is deprected in Pascal, It is used for legacy apps only. Use L1D cache instead with .nc modifier or __ldg mehtod -gpgpu_tex_cache:l1 N:16:128:24,L:R:m:N:L,T:128:4,128:2 # 12 KB Const -gpgpu_const_cache:l1 N:128:64:2,L:R:f:N:L,S:2:64,4 --perfect_inst_const_cache 1 +-gpgpu_perfect_inst_const_cache 1 # interconnection -network_mode 1 -inter_config_file config_pascal_islip.icnt # memory partition latency config --rop_latency 120 +-gpgpu_l2_rop_latency 120 -dram_latency 100 # dram model config @@ -161,8 +168,8 @@ -dram_bnk_indexing_policy 0 -dram_bnkgrp_indexing_policy 1 -#-Seperate_Write_Queue_Enable 1 -#-Write_Queue_Size 64:56:32 +#-dram_seperate_write_queue_enable 1 +#-dram_write_queue_size 64:56:32 # stat collection -gpgpu_memlatency_stat 14 diff --git a/configs/tested-cfgs/SM6_TITANX/gpgpusim_old.config b/configs/tested-cfgs/SM6_TITANX/gpgpusim_old.config deleted file mode 100644 index 17ad779..0000000 --- a/configs/tested-cfgs/SM6_TITANX/gpgpusim_old.config +++ /dev/null @@ -1,192 +0,0 @@ -# This config models the Pascal GP102 (NVIDIA TITAN X) -# For more info about this card, see Nvidia White paper -# http://international.download.nvidia.com/geforce-com/international/pdfs/GeForce_GTX_1080_Whitepaper_FINAL.pdf - -# functional simulator specification --gpgpu_ptx_instruction_classification 0 --gpgpu_ptx_sim_mode 0 --gpgpu_ptx_force_max_capability 61 --gpgpu_ignore_resources_limitation 1 - -# Device Limits --gpgpu_stack_size_limit 1024 --gpgpu_heap_size_limit 8388608 --gpgpu_runtime_sync_depth_limit 2 --gpgpu_runtime_pending_launch_count_limit 2048 - -# Compute Capability --gpgpu_compute_capability_major 6 --gpgpu_compute_capability_minor 1 - -# SASS execution (only supported with CUDA >= 4.0) --gpgpu_ptx_convert_to_ptxplus 0 --gpgpu_ptx_save_converted_ptxplus 0 - -# high level architecture configuration -# P102 has two semi-indp scheds per core, and two cores per cluster --gpgpu_n_clusters 28 --gpgpu_n_cores_per_cluster 2 --gpgpu_n_mem 12 --gpgpu_n_sub_partition_per_mchannel 2 - -# Pascal clock domains -#-gpgpu_clock_domains ::: -# Pascal NVIDIA TITAN X clock domains are adopted from -# https://en.wikipedia.org/wiki/GeForce_10_series --gpgpu_clock_domains 1417.0:1417.0:1417.0:2500.0 - -# shader core pipeline config --gpgpu_shader_registers 32768 --gpgpu_occupancy_sm_number 62 - -# This implies a maximum of 32 warps/SM --gpgpu_shader_core_pipeline 1024:32 --gpgpu_shader_cta 16 --gpgpu_simd_model 1 - -# Pipeline widths and number of FUs -# ID_OC_SP,ID_OC_DP,ID_OC_INT,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_INT,OC_EX_SFU,OC_EX_MEM,EX_WB -## Pascal GP102 has 4 SP SIMD units and 4 SFU units per SM. In this config, we split SM into two shader cores, each has 2 SPs and 2 SFUs -# There is no int unit in Pascal -## we need to scale the number of pipeline registers to be equal to the number of SP units --gpgpu_pipeline_widths 2,1,0,2,1,2,1,0,2,1,5 --gpgpu_num_sp_units 2 --gpgpu_num_sfu_units 2 --gpgpu_num_dp_units 1 - - -# Instruction latencies and initiation intervals -# "ADD,MAX,MUL,MAD,DIV" -# All Div operations are executed on SFU unit -# Throughput (initiation latency) are adopted from CUDA SDK document V8, section 5.4.1, Table 2 --ptx_opcode_latency_int 4,13,4,5,145 --ptx_opcode_initiation_int 1,1,1,1,4 --ptx_opcode_latency_fp 4,13,4,5,39 --ptx_opcode_initiation_fp 1,2,1,1,4 --ptx_opcode_latency_dp 8,19,8,8,330 --ptx_opcode_initiation_dp 8,8,8,8,130 --ptx_opcode_initiation_sfu 4 --ptx_opcode_latency_sfu 8 - - -# latencies and cache configs are adopted from: -# https://arxiv.org/pdf/1804.06826.pdf -# ::,::::,::,:** -# ** Optional parameter - Required when mshr_type==Texture Fifo -# Note: Hashing set index function (H) only applies to a set size of 32 or 64. -# Pascal GP102 has 96KB Shared memory divided over 2 cores, each has 48KB -# Pascal GP102 has 2 banks L1 cache, where each is 24KB L1 cache -# The defulat is to disable the L1 cache, unless cache modifieres are used --gpgpu_cache:dl1 S:4:128:48,L:L:s:N:L,A:256:8,16:0,32 --gpgpu_cache:dl1PrefL1 S:4:128:48,L:L:s:N:L,A:256:8,16:0,32 --gpgpu_cache:dl1PrefShared S:4:128:48,L:L:s:N:L,A:256:8,16:0,32 --gpgpu_shmem_size 49152 --gpgpu_shmem_sizeDefault 49152 --gpgpu_shmem_size_PrefL1 49152 --gpgpu_shmem_size_PrefShared 49152 -# By default, L1 cache is disabled in Pascal P102. -# requests with .nc modifier or __ldg mehtod will be cached in L1 cache even with gmem_skip_L1D=1 --gmem_skip_L1D 1 --icnt_flit_size 40 --gpgpu_n_cluster_ejection_buffer_size 32 --l1_latency 82 --smem_latency 24 --gpgpu_flush_l1_cache 1 - -# 64 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives 3MB L2 cache --gpgpu_cache:dl2 S:64:128:16,L:B:m:L:L,A:256:64,16:0,32 --gpgpu_cache:dl2_texture_only 0 --gpgpu_dram_partition_queues 32:32:32:32 --perf_sim_memcpy 1 --memory_partition_indexing 0 - -# 4 KB Inst. --gpgpu_cache:il1 N:8:128:4,L:R:f:N:L,S:2:48,4 -# 48 KB Tex -# Note, TEX is deprected in Pascal, It is used for legacy apps only. Use L1D cache instead with .nc modifier or __ldg mehtod --gpgpu_tex_cache:l1 N:16:128:24,L:R:m:N:L,T:128:4,128:2 -# 12 KB Const --gpgpu_const_cache:l1 N:128:64:2,L:R:f:N:L,S:2:64,4 - -# enable operand collector --gpgpu_operand_collector_num_units_sp 12 --gpgpu_operand_collector_num_units_sfu 6 --gpgpu_operand_collector_num_units_mem 8 --gpgpu_operand_collector_num_units_dp 6 --gpgpu_operand_collector_num_in_ports_sp 2 --gpgpu_operand_collector_num_out_ports_sp 2 --gpgpu_operand_collector_num_in_ports_sfu 2 --gpgpu_operand_collector_num_out_ports_sfu 2 --gpgpu_operand_collector_num_in_ports_mem 1 --gpgpu_operand_collector_num_out_ports_mem 1 --gpgpu_operand_collector_num_in_ports_dp 1 --gpgpu_operand_collector_num_out_ports_dp 1 --gpgpu_num_reg_banks 32 - -# shared memory bankconflict detection --gpgpu_shmem_num_banks 32 --gpgpu_shmem_limited_broadcast 0 --gpgpu_shmem_warp_parts 1 -# Use Pascal Coalsce arhitetecture --gpgpu_coalesce_arch 61 - -## In Pascal, a warp scheduler can issue 2 insts per cycle using 2 diff execution units --gpgpu_max_insn_issue_per_warp 2 --gpgpu_dual_issue_diff_exec_units 1 - -# interconnection --network_mode 1 --inter_config_file config_pascal_islip.icnt - -# memory partition latency config --rop_latency 120 --dram_latency 100 - -# dram model config --gpgpu_dram_scheduler 1 --gpgpu_frfcfs_dram_sched_queue_size 64 --gpgpu_dram_return_queue_size 64 - -# for NVIDIA TITAN X, bus width is 384bits (12 DRAM chips x 32 bits) -# 12 memory paritions, 4 bytes (1 DRAM chip) per memory partition -# the atom size of GDDR5X (the smallest read request) is 32 bytes --gpgpu_n_mem_per_ctrlr 1 --gpgpu_dram_buswidth 4 --gpgpu_dram_burst_length 8 --dram_data_command_freq_ratio 4 # GDDR5X is QDR --gpgpu_mem_address_mask 1 --gpgpu_mem_addr_mapping dramid@8;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBCCCC.BCCSSSSS - -# Use the same GDDR5 timing, scaled to 2500MHZ --gpgpu_dram_timing_opt "nbk=16:CCD=2:RRD=8:RCD=16:RAS=37:RP=16:RC=52: - CL=16:WL=6:CDLR=7:WR=16:nbkgrp=4:CCDL=4:RTPL=3" - --dram_bnk_indexing_policy 0 --dram_bnkgrp_indexing_policy 1 - -#-Seperate_Write_Queue_Enable 1 -#-Write_Queue_Size 64:56:32 - -# Pascal 102 has four schedulers per core --gpgpu_num_sched_per_core 2 -# Two Level Scheduler with active and pending pools -#-gpgpu_scheduler two_level_active:6:0:1 -# Loose round robbin scheduler -#-gpgpu_scheduler lrr -# Greedy then oldest scheduler --gpgpu_scheduler gto - -# stat collection --gpgpu_memlatency_stat 14 --gpgpu_runtime_stat 500 --enable_ptx_file_line_stats 1 --visualizer_enabled 0 - -# power model configs, disable it untill we create a real energy model for Pascal 102 --power_simulation_enabled 0 - -# tracing functionality -#-trace_enabled 1 -#-trace_components WARP_SCHEDULER,SCOREBOARD -#-trace_sampling_core 0 - diff --git a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config index b89971e..75b3c99 100644 --- a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config +++ b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config @@ -72,11 +72,31 @@ -ptx_opcode_latency_tesnor 64 -ptx_opcode_initiation_tensor 64 +-trace_opcode_latency_initiation_int 4,2 +-trace_opcode_latency_initiation_sp 4,2 +-trace_opcode_latency_initiation_dp 8,4 +-trace_opcode_latency_initiation_sfu 20,8 +-trace_opcode_latency_initiation_tensor 8,4 + +# Turing has four schedulers per core +-gpgpu_num_sched_per_core 4 +# Greedy then oldest scheduler +-gpgpu_scheduler gto +## In Turing, a warp scheduler can issue 1 inst per cycle +-gpgpu_max_insn_issue_per_warp 1 +-gpgpu_dual_issue_diff_exec_units 1 + +# shared memory bankconflict detection +-gpgpu_shmem_num_banks 32 +-gpgpu_shmem_limited_broadcast 0 +-gpgpu_shmem_warp_parts 1 +-gpgpu_coalesce_arch 75 + # Trung has sub core model, in which each scheduler has its own register file and EUs # i.e. schedulers are isolated --sub_core_model 1 +-gpgpu_sub_core_model 1 # disable specialized operand collectors and use generic operand collectors instead --enable_specialized_operand_collector 0 +-gpgpu_enable_specialized_operand_collector 0 -gpgpu_operand_collector_num_units_gen 8 -gpgpu_operand_collector_num_in_ports_gen 8 -gpgpu_operand_collector_num_out_ports_gen 8 @@ -85,65 +105,50 @@ -gpgpu_num_reg_banks 16 -gpgpu_reg_file_port_throughput 2 -# shared memory bankconflict detection --gpgpu_shmem_num_banks 32 --gpgpu_shmem_limited_broadcast 0 --gpgpu_shmem_warp_parts 1 --gpgpu_coalesce_arch 75 - -## In Turing, a warp scheduler can issue 1 inst per cycle --gpgpu_max_insn_issue_per_warp 1 --gpgpu_dual_issue_diff_exec_units 1 - -# Turing has four schedulers per core --gpgpu_num_sched_per_core 4 -# Greedy then oldest scheduler --gpgpu_scheduler gto - # ::,::::,::,:** # ** Optional parameter - Required when mshr_type==Texture Fifo --adaptive_cache_config 0 --l1_banks 4 +-gpgpu_adaptive_cache_config 0 +-gpgpu_l1_banks 4 -gpgpu_cache:dl1 S:1:128:512,L:L:s:N:L,A:256:8,16:0,32 -gpgpu_shmem_size 65536 -gpgpu_shmem_sizeDefault 65536 -gpgpu_shmem_per_block 65536 --gmem_skip_L1D 0 --icnt_flit_size 40 +-gpgpu_gmem_skip_L1D 0 -gpgpu_n_cluster_ejection_buffer_size 32 --l1_latency 20 --smem_latency 20 +-gpgpu_l1_latency 20 +-gpgpu_smem_latency 20 -gpgpu_flush_l1_cache 1 # 32 sets, each 128 bytes 32-way for each memory sub partition (96 KB per memory sub partition). This gives us 6MB L2 cache -gpgpu_cache:dl2 S:32:128:32,L:B:m:L:L,A:192:4,32:0,32 -gpgpu_cache:dl2_texture_only 0 -gpgpu_dram_partition_queues 64:64:64:64 --perf_sim_memcpy 1 --memory_partition_indexing 0 +-gpgpu_perf_sim_memcpy 1 +-gpgpu_memory_partition_indexing 0 # 128 KB Inst. -gpgpu_cache:il1 N:64:128:16,L:R:f:N:L,S:2:48,4 --inst_fetch_throughput 4 +-gpgpu_inst_fetch_throughput 4 # 128 KB Tex # Note, TEX is deprected in Volta, It is used for legacy apps only. Use L1D cache instead with .nc modifier or __ldg mehtod -gpgpu_tex_cache:l1 N:4:128:256,L:R:m:N:L,T:512:8,128:2 # 64 KB Const -gpgpu_const_cache:l1 N:128:64:8,L:R:f:N:L,S:2:64,4 --perfect_inst_const_cache 1 +-gpgpu_perfect_inst_const_cache 1 # interconnection #-network_mode 1 #-inter_config_file config_turing_islip.icnt # use built-in local xbar -network_mode 2 --inct_in_buffer_limit 512 --inct_out_buffer_limit 512 --inct_subnets 2 --arbiter_algo 1 +-icnt_in_buffer_limit 512 +-icnt_out_buffer_limit 512 +-icnt_subnets 2 +-icnt_arbiter_algo 1 +-icnt_flit_size 40 # memory partition latency config --rop_latency 160 +-gpgpu_l2_rop_latency 160 -dram_latency 100 # dram model config @@ -168,8 +173,8 @@ -dram_bnk_indexing_policy 0 -dram_bnkgrp_indexing_policy 1 -#-Seperate_Write_Queue_Enable 1 -#-Write_Queue_Size 64:56:32 +#-dram_seperate_write_queue_enable 1 +#-dram_write_queue_size 64:56:32 # stat collection -gpgpu_memlatency_stat 14 diff --git a/configs/tested-cfgs/SM7_QV100/gpgpusim.config b/configs/tested-cfgs/SM7_QV100/gpgpusim.config index 1ed4fb2..30b7d13 100644 --- a/configs/tested-cfgs/SM7_QV100/gpgpusim.config +++ b/configs/tested-cfgs/SM7_QV100/gpgpusim.config @@ -28,6 +28,8 @@ # PTX execution-driven -gpgpu_ptx_convert_to_ptxplus 0 -gpgpu_ptx_save_converted_ptxplus 0 +# SASS trace-driven mode support +#-trace_driven_mode 1 # high level architecture configuration -gpgpu_n_clusters 80 @@ -77,11 +79,17 @@ -ptx_opcode_latency_tesnor 64 -ptx_opcode_initiation_tensor 64 +-trace_opcode_latency_initiation_int 4,2 +-trace_opcode_latency_initiation_sp 4,2 +-trace_opcode_latency_initiation_dp 8,4 +-trace_opcode_latency_initiation_sfu 20,8 +-trace_opcode_latency_initiation_tensor 8,4 + # Volta has sub core model, in which each scheduler has its own register file and EUs # i.e. schedulers are isolated --sub_core_model 1 +-gpgpu_sub_core_model 1 # disable specialized operand collectors and use generic operand collectors instead --enable_specialized_operand_collector 0 +-gpgpu_enable_specialized_operand_collector 0 -gpgpu_operand_collector_num_units_gen 8 -gpgpu_operand_collector_num_in_ports_gen 8 -gpgpu_operand_collector_num_out_ports_gen 8 @@ -96,6 +104,10 @@ -gpgpu_shmem_warp_parts 1 -gpgpu_coalesce_arch 60 +# Volta has four schedulers per core +-gpgpu_num_sched_per_core 4 +# Greedy then oldest scheduler +-gpgpu_scheduler gto ## In Volta, a warp scheduler can issue 1 inst per cycle -gpgpu_max_insn_issue_per_warp 1 -gpgpu_dual_issue_diff_exec_units 1 @@ -108,49 +120,49 @@ # if the assigned shd mem = 0, then L1 cache = 128KB # For more info, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x # disable this mode in case of multi kernels/apps execution --adaptive_cache_config 1 +-gpgpu_adaptive_cache_config 1 # Volta unified cache has four banks --l1_banks 4 +-gpgpu_l1_banks 4 -gpgpu_cache:dl1 S:1:128:256,L:L:s:N:L,A:256:8,16:0,32 -gpgpu_shmem_size 98304 -gpgpu_shmem_sizeDefault 98304 -gpgpu_shmem_per_block 65536 --gmem_skip_L1D 0 --icnt_flit_size 40 +-gpgpu_gmem_skip_L1D 0 -gpgpu_n_cluster_ejection_buffer_size 32 --l1_latency 20 --smem_latency 20 +-gpgpu_l1_latency 20 +-gpgpu_smem_latency 20 -gpgpu_flush_l1_cache 1 # 32 sets, each 128 bytes 24-way for each memory sub partition (96 KB per memory sub partition). This gives us 6MB L2 cache -gpgpu_cache:dl2 S:32:128:24,L:B:m:L:L,A:192:4,32:0,32 -gpgpu_cache:dl2_texture_only 0 -gpgpu_dram_partition_queues 64:64:64:64 --perf_sim_memcpy 1 --memory_partition_indexing 2 +-gpgpu_perf_sim_memcpy 1 +-gpgpu_memory_partition_indexing 2 # 128 KB Inst. -gpgpu_cache:il1 N:64:128:16,L:R:f:N:L,S:2:48,4 --inst_fetch_throughput 4 +-gpgpu_inst_fetch_throughput 4 # 128 KB Tex # Note, TEX is deprected in Volta, It is used for legacy apps only. Use L1D cache instead with .nc modifier or __ldg mehtod -gpgpu_tex_cache:l1 N:4:128:256,L:R:m:N:L,T:512:8,128:2 # 64 KB Const -gpgpu_const_cache:l1 N:128:64:8,L:R:f:N:L,S:2:64,4 --perfect_inst_const_cache 1 +-gpgpu_perfect_inst_const_cache 1 # interconnection #-network_mode 1 #-inter_config_file config_volta_islip.icnt # use built-in local xbar -network_mode 2 --inct_in_buffer_limit 512 --inct_out_buffer_limit 512 --inct_subnets 2 --arbiter_algo 1 +-icnt_in_buffer_limit 512 +-icnt_out_buffer_limit 512 +-icnt_subnets 2 +-icnt_flit_size 40 +-icnt_arbiter_algo 1 # memory partition latency config --rop_latency 160 +-gpgpu_l2_rop_latency 160 -dram_latency 100 # dram model config @@ -177,22 +189,13 @@ CL=12:WL=2:CDLR=3:WR=10:nbkgrp=4:CCDL=2:RTPL=3" # HBM has dual bus interface, in which it can issue two col and row commands at a time --dual_bus_interface 1 +-dram_dual_bus_interface 1 # select lower bits for bnkgrp to increase bnkgrp parallelism -dram_bnk_indexing_policy 0 -dram_bnkgrp_indexing_policy 1 -#-Seperate_Write_Queue_Enable 1 -#-Write_Queue_Size 64:56:32 - -# Volta has four schedulers per core --gpgpu_num_sched_per_core 4 -# Two Level Scheduler with active and pending pools -#-gpgpu_scheduler two_level_active:6:0:1 -# Loose round robbin scheduler -#-gpgpu_scheduler lrr -# Greedy then oldest scheduler --gpgpu_scheduler gto +#-dram_seperate_write_queue_enable 1 +#-dram_write_queue_size 64:56:32 # stat collection -gpgpu_memlatency_stat 14 diff --git a/configs/tested-cfgs/SM7_QV100_SASS/config_volta_islip.icnt b/configs/tested-cfgs/SM7_QV100_SASS/config_volta_islip.icnt deleted file mode 100644 index 5ad7ecd..0000000 --- a/configs/tested-cfgs/SM7_QV100_SASS/config_volta_islip.icnt +++ /dev/null @@ -1,74 +0,0 @@ -//21*1 fly with 32 flits per packet under gpgpusim injection mode -use_map = 0; -flit_size = 40; - -// currently we do not use this, see subnets below -network_count = 2; - -// Topology -topology = fly; -k = 144; -n = 1; - -// Routing - -routing_function = dest_tag; - - -// Flow control - -num_vcs = 1; -vc_buf_size = 256; -input_buffer_size = 256; -ejection_buffer_size = 256; -boundary_buffer_size = 256; - -wait_for_tail_credit = 0; - -// Router architecture - -vc_allocator = islip; //separable_input_first; -sw_allocator = islip; //separable_input_first; -alloc_iters = 1; - -credit_delay = 0; -routing_delay = 0; -vc_alloc_delay = 1; -sw_alloc_delay = 1; - -input_speedup = 1; -output_speedup = 1; -internal_speedup = 2.0; - -// Traffic, GPGPU-Sim does not use this - -traffic = uniform; -packet_size ={{1,2,3,4},{10,20}}; -packet_size_rate={{1,1,1,1},{2,1}}; - -// Simulation - Don't change - -sim_type = gpgpusim; -//sim_type = latency; -injection_rate = 0.1; - -subnets = 2; - -// Always use read and write no matter following line -//use_read_write = 1; - - -read_request_subnet = 0; -read_reply_subnet = 1; -write_request_subnet = 0; -write_reply_subnet = 1; - -read_request_begin_vc = 0; -read_request_end_vc = 0; -write_request_begin_vc = 0; -write_request_end_vc = 0; -read_reply_begin_vc = 0; -read_reply_end_vc = 0; -write_reply_begin_vc = 0; -write_reply_end_vc = 0; - diff --git a/configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config b/configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config deleted file mode 100644 index 0df3eec..0000000 --- a/configs/tested-cfgs/SM7_QV100_SASS/gpgpusim.config +++ /dev/null @@ -1,206 +0,0 @@ -# This config models the Volta -# For more info about volta architecture: -# http://images.nvidia.com/content/volta-architecture/pdf/volta-architecture-whitepaper.pdf -# https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8344474&tag=1# -# http://on-demand.gputechconf.com/gtc/2018/presentation/s8122-dissecting-the-volta-gpu-architecture-through-microbenchmarking.pdf -# https://en.wikipedia.org/wiki/Volta_(microarchitecture) -# https://www.hotchips.org/wp-content/uploads/hc_archives/hc29/HC29.21-Monday-Pub/HC29.21.10-GPU-Gaming-Pub/HC29.21.132-Volta-Choquette-NVIDIA-Final3.pdf -# https://devblogs.nvidia.com/inside-volta/ -# http://on-demand.gputechconf.com/gtc/2017/presentation/s7798-luke-durant-inside-volta.pdf - -# functional simulator specification --gpgpu_ptx_instruction_classification 0 --gpgpu_ptx_sim_mode 0 --gpgpu_ptx_force_max_capability 70 - -# Device Limits --gpgpu_stack_size_limit 1024 --gpgpu_heap_size_limit 8388608 --gpgpu_runtime_sync_depth_limit 2 --gpgpu_runtime_pending_launch_count_limit 2048 --gpgpu_kernel_launch_latency 5000 - -# Compute Capability --gpgpu_compute_capability_major 7 --gpgpu_compute_capability_minor 0 - -# SASS trace-driven mode support --trace_driven_mode 1 --gpgpu_ptx_convert_to_ptxplus 0 --gpgpu_ptx_save_converted_ptxplus 0 - -# high level architecture configuration --gpgpu_n_clusters 80 --gpgpu_n_cores_per_cluster 1 --gpgpu_n_mem 32 --gpgpu_n_sub_partition_per_mchannel 2 - -# volta clock domains -#-gpgpu_clock_domains ::: --gpgpu_clock_domains 1132.0:1132.0:1132.0:850.0 -# boost mode -# -gpgpu_clock_domains 1628.0:1628.0:1628.0:850.0 - -# shader core pipeline config --gpgpu_shader_registers 65536 --gpgpu_registers_per_block 65536 --gpgpu_occupancy_sm_number 70 - -# This implies a maximum of 64 warps/SM --gpgpu_shader_core_pipeline 2048:32 --gpgpu_shader_cta 32 --gpgpu_simd_model 1 - -# Pipeline widths and number of FUs -# ID_OC_SP,ID_OC_DP,ID_OC_INT,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_INT,OC_EX_SFU,OC_EX_MEM,EX_WB,ID_OC_TENSOR_CORE,OC_EX_TENSOR_CORE -## Volta GV100 has 4 SP SIMD units, 4 SFU units, 4 DP units per core, 4 Tensor core units -## we need to scale the number of pipeline registers to be equal to the number of SP units --gpgpu_pipeline_widths 4,4,4,4,4,4,4,4,4,4,8,4,4 --gpgpu_num_sp_units 4 --gpgpu_num_sfu_units 4 --gpgpu_num_dp_units 4 --gpgpu_num_int_units 4 --gpgpu_tensor_core_avail 1 --gpgpu_num_tensor_core_units 4 - -# Instruction latencies and initiation intervals -# "ADD,MAX,MUL,MAD,DIV" -# All Div operations are executed on SFU unit --ptx_opcode_latency_int 4,13,4,5,145 --ptx_opcode_initiation_int 2,2,2,2,8 --ptx_opcode_latency_fp 4,13,4,5,39 --ptx_opcode_initiation_fp 2,2,2,2,4 --ptx_opcode_latency_dp 8,19,8,8,330 --ptx_opcode_initiation_dp 4,4,4,4,130 --ptx_opcode_latency_sfu 100 --ptx_opcode_initiation_sfu 8 --ptx_opcode_latency_tesnor 8 --ptx_opcode_initiation_tensor 4 - -# Volta has sub core model, in which each scheduler has its own register file and EUs -# i.e. schedulers are isolated --sub_core_model 1 -# disable specialized operand collectors and use generic operand collectors instead --enable_specialized_operand_collector 0 --gpgpu_operand_collector_num_units_gen 8 --gpgpu_operand_collector_num_in_ports_gen 8 --gpgpu_operand_collector_num_out_ports_gen 8 -# volta has 8 banks, 4 schedulers, two banks per scheduler -# we increase #banks to 16 to mitigate the effect of Regisrer File Cache (RFC) which we do not implement in the current version --gpgpu_num_reg_banks 16 --gpgpu_reg_file_port_throughput 2 - -# shared memory bankconflict detection --gpgpu_shmem_num_banks 32 --gpgpu_shmem_limited_broadcast 0 --gpgpu_shmem_warp_parts 1 --gpgpu_coalesce_arch 60 - -## In Volta, a warp scheduler can issue 1 inst per cycle --gpgpu_max_insn_issue_per_warp 1 --gpgpu_dual_issue_diff_exec_units 1 - -# Volta has four schedulers per core --gpgpu_num_sched_per_core 4 -# Greedy then oldest scheduler --gpgpu_scheduler gto - -## L1/shared memory configuration -# ::,::::,::,:** -# ** Optional parameter - Required when mshr_type==Texture Fifo -# Defualt config is 32KB DL1 and 96KB shared memory -# In Volta, we assign the remaining shared memory to L1 cache -# if the assigned shd mem = 0, then L1 cache = 128KB -# For more info, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x -# disable this mode in case of multi kernels/apps execution --adaptive_cache_config 1 -# Volta unified cache has four banks --l1_banks 4 --gpgpu_cache:dl1 S:1:128:256,L:L:s:N:L,A:256:8,16:0,32 --gpgpu_shmem_size 98304 --gpgpu_shmem_sizeDefault 98304 --gpgpu_shmem_per_block 65536 --gmem_skip_L1D 0 --icnt_flit_size 40 --gpgpu_n_cluster_ejection_buffer_size 32 --l1_latency 20 --smem_latency 20 --gpgpu_flush_l1_cache 1 - -# 32 sets, each 128 bytes 24-way for each memory sub partition (96 KB per memory sub partition). This gives us 6MB L2 cache --gpgpu_cache:dl2 S:32:128:24,L:B:m:L:L,A:192:4,32:0,32 --gpgpu_cache:dl2_texture_only 0 --gpgpu_dram_partition_queues 64:64:64:64 --perf_sim_memcpy 1 --memory_partition_indexing 2 - -# 128 KB Inst. --gpgpu_cache:il1 N:64:128:16,L:R:f:N:L,S:2:48,4 --inst_fetch_throughput 4 -# 128 KB Tex -# Note, TEX is deprected in Volta, It is used for legacy apps only. Use L1D cache instead with .nc modifier or __ldg mehtod --gpgpu_tex_cache:l1 N:4:128:256,L:R:m:N:L,T:512:8,128:2 -# 64 KB Const --gpgpu_const_cache:l1 N:128:64:8,L:R:f:N:L,S:2:64,4 --perfect_inst_const_cache 1 - -# interconnection -#-network_mode 1 -#-inter_config_file config_volta_islip.icnt -# use built-in local xbar --network_mode 2 --inct_in_buffer_limit 512 --inct_out_buffer_limit 512 --inct_subnets 2 --arbiter_algo 1 - -# memory partition latency config --rop_latency 160 --dram_latency 100 - -# dram model config --gpgpu_dram_scheduler 1 --gpgpu_frfcfs_dram_sched_queue_size 64 --gpgpu_dram_return_queue_size 192 - -# for HBM, three stacks, 24 channles, each (128 bits) 16 bytes width --gpgpu_n_mem_per_ctrlr 1 --gpgpu_dram_buswidth 16 --gpgpu_dram_burst_length 2 --dram_data_command_freq_ratio 2 # HBM is DDR --gpgpu_mem_address_mask 1 --gpgpu_mem_addr_mapping dramid@8;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBCCCB.CCCSSSSS - -# HBM timing are adopted from hynix JESD235 standered and nVidia HPCA 2017 paper (http://www.cs.utah.edu/~nil/pubs/hpca17.pdf) -# Timing for 1 GHZ -# tRRDl and tWTR are missing, need to be added -#-gpgpu_dram_timing_opt "nbk=16:CCD=1:RRD=4:RCD=14:RAS=33:RP=14:RC=47: -# CL=14:WL=2:CDLR=3:WR=12:nbkgrp=4:CCDL=2:RTPL=4" - -# Timing for 850 MHZ, V100 HBM runs at 850 MHZ --gpgpu_dram_timing_opt "nbk=16:CCD=1:RRD=3:RCD=12:RAS=28:RP=12:RC=40: - CL=12:WL=2:CDLR=3:WR=10:nbkgrp=4:CCDL=2:RTPL=3" - -# HBM has dual bus interface, in which it can issue two col and row commands at a time --dual_bus_interface 1 -# select lower bits for bnkgrp to increase bnkgrp parallelism --dram_bnk_indexing_policy 0 --dram_bnkgrp_indexing_policy 1 - -#-Seperate_Write_Queue_Enable 1 -#-Write_Queue_Size 64:56:32 - -# stat collection --gpgpu_memlatency_stat 14 --gpgpu_runtime_stat 500 --enable_ptx_file_line_stats 1 --visualizer_enabled 0 - -# power model configs, disable it untill we create a real energy model for Volta --power_simulation_enabled 0 - -# tracing functionality -#-trace_enabled 1 -#-trace_components WARP_SCHEDULER,SCOREBOARD -#-trace_sampling_core 0 - diff --git a/configs/tested-cfgs/SM7_TITANV/config_volta_islip.icnt b/configs/tested-cfgs/SM7_TITANV/config_volta_islip.icnt deleted file mode 100644 index 615d0a9..0000000 --- a/configs/tested-cfgs/SM7_TITANV/config_volta_islip.icnt +++ /dev/null @@ -1,74 +0,0 @@ -//21*1 fly with 32 flits per packet under gpgpusim injection mode -use_map = 0; -flit_size = 40; - -// currently we do not use this, see subnets below -network_count = 2; - -// Topology -topology = fly; -k = 88; -n = 1; - -// Routing - -routing_function = dest_tag; - - -// Flow control - -num_vcs = 1; -vc_buf_size = 256; -input_buffer_size = 256; -ejection_buffer_size = 256; -boundary_buffer_size = 256; - -wait_for_tail_credit = 0; - -// Router architecture - -vc_allocator = islip; //separable_input_first; -sw_allocator = islip; //separable_input_first; -alloc_iters = 1; - -credit_delay = 0; -routing_delay = 0; -vc_alloc_delay = 1; -sw_alloc_delay = 1; - -input_speedup = 1; -output_speedup = 1; -internal_speedup = 2.0; - -// Traffic, GPGPU-Sim does not use this - -traffic = uniform; -packet_size ={{1,2,3,4},{10,20}}; -packet_size_rate={{1,1,1,1},{2,1}}; - -// Simulation - Don't change - -sim_type = gpgpusim; -//sim_type = latency; -injection_rate = 0.1; - -subnets = 2; - -// Always use read and write no matter following line -//use_read_write = 1; - - -read_request_subnet = 0; -read_reply_subnet = 1; -write_request_subnet = 0; -write_reply_subnet = 1; - -read_request_begin_vc = 0; -read_request_end_vc = 0; -write_request_begin_vc = 0; -write_request_end_vc = 0; -read_reply_begin_vc = 0; -read_reply_end_vc = 0; -write_reply_begin_vc = 0; -write_reply_end_vc = 0; - diff --git a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config deleted file mode 100644 index 0339b0d..0000000 --- a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config +++ /dev/null @@ -1,205 +0,0 @@ -# This config models the Volta Titan V -# For more info about volta architecture: -# http://images.nvidia.com/content/volta-architecture/pdf/volta-architecture-whitepaper.pdf -# https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8344474&tag=1# -# http://on-demand.gputechconf.com/gtc/2018/presentation/s8122-dissecting-the-volta-gpu-architecture-through-microbenchmarking.pdf -# https://en.wikipedia.org/wiki/Volta_(microarchitecture) -# https://www.hotchips.org/wp-content/uploads/hc_archives/hc29/HC29.21-Monday-Pub/HC29.21.10-GPU-Gaming-Pub/HC29.21.132-Volta-Choquette-NVIDIA-Final3.pdf -# https://devblogs.nvidia.com/inside-volta/ -# http://on-demand.gputechconf.com/gtc/2017/presentation/s7798-luke-durant-inside-volta.pdf - -# functional simulator specification --gpgpu_ptx_instruction_classification 0 --gpgpu_ptx_sim_mode 0 --gpgpu_ptx_force_max_capability 70 - - -# Device Limits --gpgpu_stack_size_limit 1024 --gpgpu_heap_size_limit 8388608 --gpgpu_runtime_sync_depth_limit 2 --gpgpu_runtime_pending_launch_count_limit 2048 - -# Compute Capability --gpgpu_compute_capability_major 7 --gpgpu_compute_capability_minor 0 - -# SASS execution (only supported with CUDA >= 4.0) --gpgpu_ptx_convert_to_ptxplus 0 --gpgpu_ptx_save_converted_ptxplus 0 - -# high level architecture configuration --gpgpu_n_clusters 40 --gpgpu_n_cores_per_cluster 2 --gpgpu_n_mem 24 --gpgpu_n_sub_partition_per_mchannel 2 - -# volta clock domains -#-gpgpu_clock_domains ::: -# Volta NVIDIA TITANV clock domains are adopted from -# https://en.wikipedia.org/wiki/Volta_(microarchitecture) --gpgpu_clock_domains 1200.0:1200.0:1200.0:850.0 -# boost mode -# -gpgpu_clock_domains 1455.0:1455.0:1455.0:850.0 - -# shader core pipeline config --gpgpu_shader_registers 65536 --gpgpu_registers_per_block 65536 --gpgpu_occupancy_sm_number 70 - -# This implies a maximum of 64 warps/SM --gpgpu_shader_core_pipeline 2048:32 --gpgpu_shader_cta 32 --gpgpu_simd_model 1 - -# Pipeline widths and number of FUs -# ID_OC_SP,ID_OC_DP,ID_OC_INT,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_INT,OC_EX_SFU,OC_EX_MEM,EX_WB,ID_OC_TENSOR_CORE,OC_EX_TENSOR_CORE -## Volta TITANV has 4 SP SIMD units, 4 INT units, 4 SFU units, 4 DP units per core, 4 Tensor core units -## we need to scale the number of pipeline registers to be equal to the number of SP units --gpgpu_pipeline_widths 4,4,4,4,4,4,4,4,4,4,8,4,4 --gpgpu_num_sp_units 4 --gpgpu_num_sfu_units 4 --gpgpu_num_dp_units 4 --gpgpu_num_int_units 4 --gpgpu_tensor_core_avail 1 --gpgpu_num_tensor_core_units 4 - -# Instruction latencies and initiation intervals -# "ADD,MAX,MUL,MAD,DIV" -# All Div operations are executed on SFU unit -# Throughput (initiation latency) are adopted from -# http://on-demand.gputechconf.com/gtc/2018/presentation/s8122-dissecting-the-volta-gpu-architecture-through-microbenchmarking.pdf --ptx_opcode_latency_int 4,13,4,5,145 --ptx_opcode_initiation_int 2,2,2,2,8 --ptx_opcode_latency_fp 4,13,4,5,39 --ptx_opcode_initiation_fp 2,2,2,2,4 --ptx_opcode_latency_dp 8,19,8,8,330 --ptx_opcode_initiation_dp 4,4,4,4,130 --ptx_opcode_latency_sfu 100 --ptx_opcode_initiation_sfu 8 --ptx_opcode_latency_tesnor 64 --ptx_opcode_initiation_tensor 64 - -# ::,::::,::,:** -# ** Optional parameter - Required when mshr_type==Texture Fifo -# Defualt config is 32KB DL1 and 96KB shared memory -# In Volta, we assign the remaining shared memory to L1 cache -# if the assigned shd mem = 0, then L1 cache = 128KB -# For more info, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x -# disable this mode in case of multi kernels/apps execution --adaptive_cache_config 1 -# Volta unified cache has four banks --l1_banks 4 -#-mem_unit_ports 4 --gpgpu_cache:dl1 S:1:128:256,L:L:s:N:L,A:256:8,16:0,32 --gpgpu_shmem_size 98304 --gpgpu_shmem_sizeDefault 98304 --gpgpu_shmem_per_block 65536 --gmem_skip_L1D 0 --icnt_flit_size 40 --gpgpu_n_cluster_ejection_buffer_size 32 --l1_latency 20 --smem_latency 20 --gpgpu_flush_l1_cache 1 - -# 32 sets, each 128 bytes 24-way for each memory sub partition (96 KB per memory sub partition). This gives us 4.5MB L2 cache --gpgpu_cache:dl2 S:32:128:24,L:B:m:L:L,A:192:4,32:0,32 --gpgpu_cache:dl2_texture_only 0 --gpgpu_dram_partition_queues 64:64:64:64 --perf_sim_memcpy 1 --memory_partition_indexing 4 - -# 128 KB Inst. --gpgpu_cache:il1 N:64:128:16,L:R:f:N:L,S:2:48,4 -# 48 KB Tex -# Note, TEX is deprected in Volta, It is used for legacy apps only. Use L1D cache instead with .nc modifier or __ldg mehtod --gpgpu_tex_cache:l1 N:4:128:256,L:R:m:N:L,T:512:8,128:2 -# 64 KB Const --gpgpu_const_cache:l1 N:128:64:8,L:R:f:N:L,S:2:64,4 - -# Volta has sub core model, in which each scheduler has its own register file and EUs -# i.e. schedulers are isolated --sub_core_model 1 -# disable specialized operand collectors and use generic operand collectors instead --enable_specialized_operand_collector 0 --gpgpu_operand_collector_num_units_gen 8 --gpgpu_operand_collector_num_in_ports_gen 8 --gpgpu_operand_collector_num_out_ports_gen 8 -# volta has 8 banks, 4 schedulers, two banks per scheduler --gpgpu_num_reg_banks 8 - -# shared memory bankconflict detection --gpgpu_shmem_num_banks 32 --gpgpu_shmem_limited_broadcast 0 --gpgpu_shmem_warp_parts 1 --gpgpu_coalesce_arch 60 - -## In Volta, a warp scheduler can issue 1 inst per cycle --gpgpu_max_insn_issue_per_warp 1 --gpgpu_dual_issue_diff_exec_units 1 - -# interconnection --network_mode 1 --inter_config_file config_volta_islip.icnt -# for local xbar, use: -# "-network_mode 2 -inct_in_buffer_limit 512 -inct_out_buffer_limit 512 -inct_subnets 2" - -# memory partition latency config --rop_latency 160 --dram_latency 100 - -# dram model config --gpgpu_dram_scheduler 1 --gpgpu_frfcfs_dram_sched_queue_size 64 --gpgpu_dram_return_queue_size 192 - -# for HBM, three stacks, 24 channles, each (128 bits) 16 bytes width --gpgpu_n_mem_per_ctrlr 1 --gpgpu_dram_buswidth 16 --gpgpu_dram_burst_length 2 --dram_data_command_freq_ratio 2 # HBM is DDR --gpgpu_mem_address_mask 1 --gpgpu_mem_addr_mapping dramid@8;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBCCCB.CCCSSSSS - -# HBM timing are adopted from hynix JESD235 standered and nVidia HPCA 2017 paper (http://www.cs.utah.edu/~nil/pubs/hpca17.pdf) -# Timing for 1 GHZ -# tRRDl and tWTR are missing, need to be added -#-gpgpu_dram_timing_opt "nbk=16:CCD=1:RRD=4:RCD=14:RAS=33:RP=14:RC=47: -# CL=14:WL=2:CDLR=3:WR=12:nbkgrp=4:CCDL=2:RTPL=4" - -# Timing for 850 MHZ, TITANV HBM runs at 850 MHZ --gpgpu_dram_timing_opt "nbk=16:CCD=1:RRD=3:RCD=12:RAS=28:RP=12:RC=40: - CL=12:WL=2:CDLR=3:WR=10:nbkgrp=4:CCDL=2:RTPL=3" - -# HBM has dual bus interface, in which it can issue two col and row commands at a time --dual_bus_interface 1 -# select lower bits for bnkgrp to increase bnkgrp parallelism --dram_bnk_indexing_policy 0 --dram_bnkgrp_indexing_policy 1 - -#-Seperate_Write_Queue_Enable 1 -#-Write_Queue_Size 64:56:32 - -# Volta has four schedulers per core --gpgpu_num_sched_per_core 4 -# Two Level Scheduler with active and pending pools -#-gpgpu_scheduler two_level_active:6:0:1 -# Loose round robbin scheduler -#-gpgpu_scheduler lrr -# Greedy then oldest scheduler --gpgpu_scheduler gto - -# stat collection --gpgpu_memlatency_stat 14 --gpgpu_runtime_stat 500 --enable_ptx_file_line_stats 1 --visualizer_enabled 0 - -# power model configs, disable it untill we create a real energy model for Volta --power_simulation_enabled 0 - -# tracing functionality -#-trace_enabled 1 -#-trace_components WARP_SCHEDULER,SCOREBOARD -#-trace_sampling_core 0 - diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 135b03b..6c19e2d 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -70,7 +70,7 @@ enum FuncCache enum AdaptiveCache { FIXED = 0, - VOLTA = 1 + ADAPTIVE_VOLTA = 1 }; #ifdef __cplusplus diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc index c34cb32..d430568 100644 --- a/src/gpgpu-sim/addrdec.cc +++ b/src/gpgpu-sim/addrdec.cc @@ -63,7 +63,7 @@ void linear_to_raw_address_translation::addrdec_setoption(option_parser_t opp) option_parser_register(opp, "-gpgpu_mem_address_mask", OPT_INT32, &gpgpu_mem_address_mask, "0 = old addressing mask, 1 = new addressing mask, 2 = new add. mask + flipped bank sel and chip sel bits", "0"); - option_parser_register(opp, "-memory_partition_indexing", OPT_UINT32, &memory_partition_indexing, + option_parser_register(opp, "-gpgpu_memory_partition_indexing", OPT_UINT32, &memory_partition_indexing, "0 = no indexing, 1 = bitwise xoring, 2 = IPoly, 3 = custom indexing", "0"); } diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index cd5fa56..641ddbc 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -137,9 +137,9 @@ void power_config::reg_options(class OptionParser * opp) void memory_config::reg_options(class OptionParser * opp) { - option_parser_register(opp, "-perf_sim_memcpy", OPT_BOOL, &m_perf_sim_memcpy, + option_parser_register(opp, "-gpgpu_perf_sim_memcpy", OPT_BOOL, &m_perf_sim_memcpy, "Fill the L2 cache on memcpy", "1"); - option_parser_register(opp, "-simple_dram_model", OPT_BOOL, &simple_dram_model, + option_parser_register(opp, "-gpgpu_simple_dram_model", OPT_BOOL, &simple_dram_model, "simple_dram_model with fixed latency and BW", "0"); option_parser_register(opp, "-gpgpu_dram_scheduler", OPT_INT32, &scheduler_type, "0 = fifo, 1 = FR-FCFS (defaul)", "1"); @@ -187,13 +187,13 @@ void memory_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_dram_timing_opt", OPT_CSTR, &gpgpu_dram_timing_opt, "DRAM timing parameters = {nbk:tCCD:tRRD:tRCD:tRAS:tRP:tRC:CL:WL:tCDLR:tWR:nbkgrp:tCCDL:tRTPL}", "4:2:8:12:21:13:34:9:4:5:13:1:0:0"); - option_parser_register(opp, "-rop_latency", OPT_UINT32, &rop_latency, + option_parser_register(opp, "-gpgpu_l2_rop_latency", OPT_UINT32, &rop_latency, "ROP queue latency (default 85)", "85"); option_parser_register(opp, "-dram_latency", OPT_UINT32, &dram_latency, "DRAM latency (default 30)", "30"); - option_parser_register(opp, "-dual_bus_interface", OPT_UINT32, &dual_bus_interface, + option_parser_register(opp, "-dram_dual_bus_interface", OPT_UINT32, &dual_bus_interface, "dual_bus_interface (default = 0) ", "0"); option_parser_register(opp, "-dram_bnk_indexing_policy", OPT_UINT32, &dram_bnk_indexing_policy, @@ -202,13 +202,13 @@ void memory_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-dram_bnkgrp_indexing_policy", OPT_UINT32, &dram_bnkgrp_indexing_policy, "dram_bnkgrp_indexing_policy (0 = take higher bits, 1 = take lower bits) (Default = 0)", "0"); - option_parser_register(opp, "-Seperate_Write_Queue_Enable", OPT_BOOL, &seperate_write_queue_enabled, + option_parser_register(opp, "-dram_seperate_write_queue_enable", OPT_BOOL, &seperate_write_queue_enabled, "Seperate_Write_Queue_Enable", "0"); - option_parser_register(opp, "-Write_Queue_Size", OPT_CSTR, &write_queue_size_opt, + option_parser_register(opp, "-dram_write_queue_size", OPT_CSTR, &write_queue_size_opt, "Write_Queue_Size", "32:28:16"); - option_parser_register(opp, "-Elimnate_rw_turnaround", OPT_BOOL, &elimnate_rw_turnaround, + option_parser_register(opp, "-dram_elimnate_rw_turnaround", OPT_BOOL, &elimnate_rw_turnaround, "elimnate_rw_turnaround i.e set tWTR and tRTW = 0", "0"); option_parser_register(opp, "-icnt_flit_size", OPT_UINT32, &icnt_flit_size, @@ -240,13 +240,13 @@ void shader_core_config::reg_options(class OptionParser * opp) "per-shader L1 data cache config " " {::,:::,::, | none}", "none" ); - option_parser_register(opp, "-l1_banks", OPT_UINT32, &m_L1D_config.l1_banks, + option_parser_register(opp, "-gpgpu_l1_banks", OPT_UINT32, &m_L1D_config.l1_banks, "The number of L1 cache banks", "1"); - option_parser_register(opp, "-l1_latency", OPT_UINT32, &m_L1D_config.l1_latency, + option_parser_register(opp, "-gpgpu_l1_latency", OPT_UINT32, &m_L1D_config.l1_latency, "L1 Hit Latency", "1"); - option_parser_register(opp, "-smem_latency", OPT_UINT32, &smem_latency, + option_parser_register(opp, "-gpgpu_smem_latency", OPT_UINT32, &smem_latency, "smem Latency", "3"); option_parser_register(opp, "-gpgpu_cache:dl1PrefL1", OPT_CSTR, &m_L1D_config.m_config_stringPrefL1, @@ -257,7 +257,7 @@ void shader_core_config::reg_options(class OptionParser * opp) "per-shader L1 data cache config " " {::,:::,::, | none}", "none" ); - option_parser_register(opp, "-gmem_skip_L1D", OPT_BOOL, &gmem_skip_L1D, + option_parser_register(opp, "-gpgpu_gmem_skip_L1D", OPT_BOOL, &gmem_skip_L1D, "global memory access skip L1D cache (implements -Xptxas -dlcm=cg, default=no skip)", "0"); @@ -306,7 +306,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_UINT32, &adaptive_cache_config, + option_parser_register(opp, "-gpgpu_adaptive_cache_config", OPT_UINT32, &adaptive_cache_config, "adaptive_cache_config", "0"); option_parser_register(opp, "-gpgpu_shmem_sizeDefault", OPT_UINT32, &gpgpu_shmem_sizeDefault, @@ -327,7 +327,7 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_shmem_warp_parts", OPT_INT32, &mem_warp_parts, "Number of portions a warp is divided into for shared memory bank conflict check ", "2"); - option_parser_register(opp, "-mem_unit_ports", OPT_INT32, &mem_unit_ports, + option_parser_register(opp, "-gpgpu_mem_unit_ports", OPT_INT32, &mem_unit_ports, "The number of memory transactions allowed per core cycle", "1"); option_parser_register(opp, "-gpgpu_shmem_warp_parts", OPT_INT32, &mem_warp_parts, @@ -348,10 +348,10 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_reg_bank_use_warp_id", OPT_BOOL, &gpgpu_reg_bank_use_warp_id, "Use warp ID in mapping registers to banks (default = off)", "0"); - option_parser_register(opp, "-sub_core_model", OPT_BOOL, &sub_core_model, + option_parser_register(opp, "-gpgpu_sub_core_model", OPT_BOOL, &sub_core_model, "Sub Core Volta/Pascal model (default = off)", "0"); - option_parser_register(opp, "-enable_specialized_operand_collector", OPT_BOOL, &enable_specialized_operand_collector, + option_parser_register(opp, "-gpgpu_enable_specialized_operand_collector", OPT_BOOL, &enable_specialized_operand_collector, "enable_specialized_operand_collector", "1"); option_parser_register(opp, "-gpgpu_operand_collector_num_units_sp", OPT_INT32, &gpgpu_operand_collector_num_units_sp, @@ -467,15 +467,32 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_concurrent_kernel_sm", OPT_BOOL, &gpgpu_concurrent_kernel_sm, "Support concurrent kernels on a SM (default = disabled)", "0"); - option_parser_register(opp, "-perfect_inst_const_cache", OPT_BOOL, &perfect_inst_const_cache, + option_parser_register(opp, "-gpgpu_perfect_inst_const_cache", OPT_BOOL, &perfect_inst_const_cache, "perfect inst and const cache mode, so all inst and const hits in the cache(default = disabled)", "0"); - option_parser_register(opp, "-inst_fetch_throughput", OPT_INT32, &inst_fetch_throughput, + option_parser_register(opp, "-gpgpu_inst_fetch_throughput", OPT_INT32, &inst_fetch_throughput, "the number of fetched intruction per warp each cycle", "1"); option_parser_register(opp, "-gpgpu_reg_file_port_throughput", OPT_INT32, ®_file_port_throughput, "the number ports of the register file", "1"); + + //used for trace-driven mode + option_parser_register(opp, "-trace_opcode_latency_initiation_int", OPT_CSTR, &trace_opcode_latency_initiation_int, + "Opcode latencies and initiation for integers in trace driven mode ", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_sp", OPT_CSTR, &trace_opcode_latency_initiation_sp, + "Opcode latencies and initiation for sp in trace driven mode ", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_dp", OPT_CSTR, &trace_opcode_latency_initiation_dp, + "Opcode latencies and initiation for dp in trace driven mode ", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_sfu", OPT_CSTR, &trace_opcode_latency_initiation_sfu, + "Opcode latencies and initiation for sfu in trace driven mode ", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_tensor", OPT_CSTR, &trace_opcode_latency_initiation_tensor, + "Opcode latencies and initiation for tensor in trace driven mode ", + "4,1"); } void gpgpu_sim_config::reg_options(option_parser_t opp) diff --git a/src/gpgpu-sim/icnt_wrapper.cc b/src/gpgpu-sim/icnt_wrapper.cc index e449bf1..6e3e596 100644 --- a/src/gpgpu-sim/icnt_wrapper.cc +++ b/src/gpgpu-sim/icnt_wrapper.cc @@ -179,12 +179,12 @@ void icnt_reg_options( class OptionParser * opp ) //parameters for local xbar - option_parser_register(opp, "-inct_in_buffer_limit", OPT_UINT32, &g_inct_config.in_buffer_limit, "in_buffer_limit", "64"); - option_parser_register(opp, "-inct_out_buffer_limit", OPT_UINT32, &g_inct_config.out_buffer_limit, "out_buffer_limit", "64"); - option_parser_register(opp, "-inct_subnets", OPT_UINT32, &g_inct_config.subnets, "subnets", "2"); - option_parser_register(opp, "-arbiter_algo", OPT_UINT32, &g_inct_config.arbiter_algo, "arbiter_algo", "1"); - option_parser_register(opp, "-inct_verbose", OPT_UINT32, &g_inct_config.verbose, "inct_verbose", "0"); - option_parser_register(opp, "-inct_grant_cycles", OPT_UINT32, &g_inct_config.grant_cycles, "grant_cycles", "1"); + option_parser_register(opp, "-icnt_in_buffer_limit", OPT_UINT32, &g_inct_config.in_buffer_limit, "in_buffer_limit", "64"); + option_parser_register(opp, "-icnt_out_buffer_limit", OPT_UINT32, &g_inct_config.out_buffer_limit, "out_buffer_limit", "64"); + option_parser_register(opp, "-icnt_subnets", OPT_UINT32, &g_inct_config.subnets, "subnets", "2"); + option_parser_register(opp, "-icnt_arbiter_algo", OPT_UINT32, &g_inct_config.arbiter_algo, "arbiter_algo", "1"); + option_parser_register(opp, "-icnt_verbose", OPT_UINT32, &g_inct_config.verbose, "inct_verbose", "0"); + option_parser_register(opp, "-icnt_grant_cycles", OPT_UINT32, &g_inct_config.grant_cycles, "grant_cycles", "1"); diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 65ec113..900ec90 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -3088,7 +3088,7 @@ unsigned int shader_core_config::max_cta( const kernel_info_t &k ) const switch (adaptive_cache_config) { case FIXED: break; - case VOLTA: { + case ADAPTIVE_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 diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 665e3a5..ca85903 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1527,6 +1527,13 @@ class shader_core_config : public core_config unsigned inst_fetch_throughput; unsigned reg_file_port_throughput; + char* trace_opcode_latency_initiation_int; + char* trace_opcode_latency_initiation_sp; + char* trace_opcode_latency_initiation_dp; + char* trace_opcode_latency_initiation_sfu; + char* trace_opcode_latency_initiation_tensor; + + }; struct shader_core_stats_pod { diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index bedac4c..5e07ace 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -48,6 +48,7 @@ int main ( int argc, const char **argv ) //prints stats trace_parser tracer(m_gpgpu_sim->get_config().get_traces_filename(), m_gpgpu_sim, m_gpgpu_context); + trace_config config(m_gpgpu_sim); std::vector commandlist = tracer.parse_kernellist_file(); bool first_kernel=true; @@ -69,7 +70,7 @@ int main ( int argc, const char **argv ) first_kernel = false; continue; } - kernel_info = tracer.parse_kernel_info(commandlist[i]); + kernel_info = tracer.parse_kernel_info(commandlist[i], &config); m_gpgpu_sim->launch(kernel_info); } diff --git a/src/trace-driven/kepler_opcode.h b/src/trace-driven/kepler_opcode.h index f2bbc90..4aa8e0f 100644 --- a/src/trace-driven/kepler_opcode.h +++ b/src/trace-driven/kepler_opcode.h @@ -99,12 +99,13 @@ static const std::unordered_map Kepler_OpcodeMap = { //Load/Store Instructions //For now, we ignore constant loads, consider it as ALU_OP, TO DO {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, - {"LD", OpcodeChar(OP_LD, LOAD_OP)}, + //in Kepler, LD is load global so set it to LDG + {"LD", OpcodeChar(OP_LDG, LOAD_OP)}, {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, {"LDSLK", OpcodeChar(OP_LDSLK, LOAD_OP)}, - {"ST", OpcodeChar(OP_ST, STORE_OP)}, + {"ST", OpcodeChar(OP_STG, STORE_OP)}, {"STL", OpcodeChar(OP_STL, STORE_OP)}, {"STS", OpcodeChar(OP_STS, STORE_OP)}, {"STSCUL", OpcodeChar(OP_STSCUL, STORE_OP)}, diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 35e953e..22c527e 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -98,7 +98,7 @@ void trace_parser::parse_memcpy_info(const std::string& memcpy_command, size_t& ss>>std::dec>>count; } -trace_kernel_info_t* trace_parser::parse_kernel_info(const std::string& kerneltraces_filepath) { +trace_kernel_info_t* trace_parser::parse_kernel_info(const std::string& kerneltraces_filepath, trace_config* config) { ifs.open(kerneltraces_filepath.c_str()); @@ -167,7 +167,7 @@ trace_kernel_info_t* trace_parser::parse_kernel_info(const std::string& kerneltr 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, binary_verion, function_info, &ifs, m_gpgpu_sim, m_gpgpu_context); + trace_kernel_info_t* kernel_info = new trace_kernel_info_t(gridDim, blockDim, binary_verion, function_info, &ifs, m_gpgpu_sim, m_gpgpu_context, config); return kernel_info; } @@ -211,11 +211,12 @@ address_type trace_shd_warp_t::get_pc(){ return warp_traces[trace_pc].pc; } -trace_kernel_info_t::trace_kernel_info_t(dim3 gridDim, dim3 blockDim, unsigned m_binary_verion, trace_function_info* m_function_info, std::ifstream* inputstream, gpgpu_sim * gpgpu_sim, gpgpu_context* gpgpu_context):kernel_info_t(gridDim, blockDim, m_function_info) { +trace_kernel_info_t::trace_kernel_info_t(dim3 gridDim, dim3 blockDim, unsigned m_binary_verion, trace_function_info* m_function_info, std::ifstream* inputstream, gpgpu_sim * gpgpu_sim, gpgpu_context* gpgpu_context, class trace_config* config):kernel_info_t(gridDim, blockDim, m_function_info) { ifs = inputstream; m_gpgpu_sim = gpgpu_sim; m_gpgpu_context = gpgpu_context; binary_verion = m_binary_verion; + m_tconfig = config; //resolve the binary version if(m_binary_verion == VOLTA_BINART_VERSION) @@ -285,8 +286,8 @@ bool trace_kernel_info_t::get_next_threadblock_traces(std::vectorgetShaderCoreConfig(), m_gpgpu_context); - inst.parse_from_string(line, OpcodeMap, binary_verion); + trace_warp_inst_t inst(m_gpgpu_sim->getShaderCoreConfig(), m_gpgpu_context, m_tconfig); + inst.parse_from_string(line, OpcodeMap); threadblock_traces[warp_id]->push_back(inst); } } @@ -323,7 +324,7 @@ unsigned trace_warp_inst_t::get_datawidth_from_opcode(const std::vector* OpcodeMap, unsigned binary_verion){ +bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordered_map* OpcodeMap){ std::stringstream ss; ss.str(trace); @@ -473,7 +474,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere //remove redundant registers //fill latency and initl - set_latency(op); + m_tconfig->set_latency(op, latency, initiation_interval); //fill addresses if(mem_width > 0) { @@ -548,10 +549,7 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere //right now, we consider all loads are shared. assert(mem_width>0); data_size = get_datawidth_from_opcode(opcode_tokens); - if(binary_verion == KEPLER_BINART_VERSION) - space.set_type(global_space); - else - space.set_type(shared_space); + space.set_type(shared_space); if(m_opcode == OP_LD) memory_op = memory_load; else @@ -584,59 +582,29 @@ bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordere return true; } -void trace_warp_inst_t::set_latency(unsigned category) +trace_config::trace_config(gpgpu_sim* m_gpgpu_sim){ + + this->m_gpgpu_sim=m_gpgpu_sim; + parse_config(); +} + +void trace_config::parse_config() { - unsigned int_latency[5]; - unsigned fp_latency[5]; - unsigned dp_latency[5]; - unsigned sfu_latency; - unsigned tensor_latency; - unsigned int_init[5]; - unsigned fp_init[5]; - unsigned dp_init[5]; - unsigned sfu_init; - unsigned tensor_init; - - /* - * [0] ADD,SUB - * [1] MAX,Min - * [2] MUL - * [3] MAD - * [4] DIV - */ - sscanf(m_gpgpu_context->func_sim->opcode_latency_int, "%u,%u,%u,%u,%u", - &int_latency[0],&int_latency[1],&int_latency[2], - &int_latency[3],&int_latency[4]); - sscanf(m_gpgpu_context->func_sim->opcode_latency_fp, "%u,%u,%u,%u,%u", - &fp_latency[0],&fp_latency[1],&fp_latency[2], - &fp_latency[3],&fp_latency[4]); - sscanf(m_gpgpu_context->func_sim->opcode_latency_dp, "%u,%u,%u,%u,%u", - &dp_latency[0],&dp_latency[1],&dp_latency[2], - &dp_latency[3],&dp_latency[4]); - sscanf(m_gpgpu_context->func_sim->opcode_latency_sfu, "%u", - &sfu_latency); - sscanf(m_gpgpu_context->func_sim->opcode_latency_tensor, "%u", - &tensor_latency); - sscanf(m_gpgpu_context->func_sim->opcode_initiation_int, "%u,%u,%u,%u,%u", - &int_init[0],&int_init[1],&int_init[2], - &int_init[3],&int_init[4]); - sscanf(m_gpgpu_context->func_sim->opcode_initiation_fp, "%u,%u,%u,%u,%u", - &fp_init[0],&fp_init[1],&fp_init[2], - &fp_init[3],&fp_init[4]); - sscanf(m_gpgpu_context->func_sim->opcode_initiation_dp, "%u,%u,%u,%u,%u", - &dp_init[0],&dp_init[1],&dp_init[2], - &dp_init[3],&dp_init[4]); - sscanf(m_gpgpu_context->func_sim->opcode_initiation_sfu, "%u", - &sfu_init); - sscanf(m_gpgpu_context->func_sim->opcode_initiation_tensor, "%u", - &tensor_init); - sscanf(m_gpgpu_context->func_sim->cdp_latency_str, "%u,%u,%u,%u,%u", - &m_gpgpu_context->func_sim->cdp_latency[0], - &m_gpgpu_context->func_sim->cdp_latency[1], - &m_gpgpu_context->func_sim->cdp_latency[2], - &m_gpgpu_context->func_sim->cdp_latency[3], - &m_gpgpu_context->func_sim->cdp_latency[4]); + sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_int, "%u,%u", + &int_latency,&int_init); + sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_sp, "%u,%u", + &fp_latency,&fp_init); + sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_dp, "%u,%u", + &dp_latency,&dp_init); + sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_sfu, "%u,%u", + &sfu_latency,&sfu_init); + sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_tensor, "%u,%u", + &tensor_latency,&tensor_init); + +} +void trace_config::set_latency(unsigned category, unsigned& latency, unsigned& initiation_interval) +{ initiation_interval = latency = 1; switch(category){ @@ -645,16 +613,16 @@ void trace_warp_inst_t::set_latency(unsigned category) case BRANCH_OP: case CALL_OPS: case RET_OPS: - latency = int_latency[0]; - initiation_interval = int_init[0]; + latency = int_latency; + initiation_interval = int_init; break; case SP_OP: - latency = fp_latency[0]; - initiation_interval = fp_init[0]; + latency = fp_latency; + initiation_interval = fp_init; break; case DP_OP: - latency = dp_latency[0]; - initiation_interval = dp_init[0]; + latency = dp_latency; + initiation_interval = dp_init; break; case SFU_OP: latency = sfu_latency; diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index 9539e6d..2888f86 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -37,18 +37,20 @@ public: trace_warp_inst_t() { m_gpgpu_context=NULL; m_opcode=0; + m_tconfig=NULL; } - trace_warp_inst_t(const class core_config *config, gpgpu_context* gpgpu_context ):warp_inst_t(config) { + trace_warp_inst_t(const class core_config *config, gpgpu_context* gpgpu_context, class trace_config* tconfig ):warp_inst_t(config) { m_gpgpu_context = gpgpu_context; m_opcode=0; + m_tconfig=tconfig; } - bool parse_from_string(std::string trace, const std::unordered_map* OpcodeMap, unsigned binary_verion); + bool parse_from_string(std::string trace, const std::unordered_map* OpcodeMap); private: - void set_latency(unsigned cat); gpgpu_context* m_gpgpu_context; + class trace_config* m_tconfig; unsigned m_opcode; bool check_opcode_contain(const std::vector& opcode, std::string param); unsigned get_datawidth_from_opcode(const std::vector& opcode); @@ -56,7 +58,7 @@ private: class trace_kernel_info_t: public kernel_info_t { public: - trace_kernel_info_t(dim3 gridDim, dim3 blockDim, unsigned m_binary_verion, trace_function_info* m_function_info, std::ifstream* inputstream, gpgpu_sim * gpgpu_sim, gpgpu_context* gpgpu_context); + trace_kernel_info_t(dim3 gridDim, dim3 blockDim, unsigned m_binary_verion, trace_function_info* m_function_info, std::ifstream* inputstream, gpgpu_sim * gpgpu_sim, gpgpu_context* gpgpu_context, class trace_config* config); bool get_next_threadblock_traces(std::vector*> threadblock_traces); @@ -64,19 +66,35 @@ private: std::ifstream* ifs; gpgpu_sim * m_gpgpu_sim; gpgpu_context* m_gpgpu_context; + trace_config* m_tconfig; unsigned binary_verion; const std::unordered_map* OpcodeMap; }; +class trace_config { +public: + trace_config(gpgpu_sim * m_gpgpu_sim); + + void set_latency(unsigned category, unsigned& latency, unsigned& initiation_interval); + void parse_config(); + + +private: + + unsigned int_latency, fp_latency, dp_latency, sfu_latency, tensor_latency; + unsigned int_init, fp_init, dp_init, sfu_init, tensor_init; + 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 parse_kernellist_file(); - trace_kernel_info_t* parse_kernel_info(const std::string& kerneltraces_filepath); + trace_kernel_info_t* parse_kernel_info(const std::string& kerneltraces_filepath, trace_config* config); void parse_memcpy_info(const std::string& memcpy_command, size_t& add, size_t& count); void kernel_finalizer(trace_kernel_info_t* kernel_info); -- cgit v1.3 From 6cedd3ef4973f3785757413db89a7c5d0ee2b58b Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Fri, 22 May 2020 20:29:21 -0400 Subject: moving ISA def files to new folder --- src/trace-driven/ISA_Def/kepler_opcode.h | 149 +++++ src/trace-driven/ISA_Def/pascal_opcode.h | 201 +++++++ src/trace-driven/ISA_Def/trace_opcode.h | 71 +++ src/trace-driven/ISA_Def/turing_opcode.h | 24 + src/trace-driven/ISA_Def/volta_opcode.h | 175 ++++++ src/trace-driven/gpgpusim_trace_driven_main.cc | 2 +- src/trace-driven/kepler_opcode.h | 150 ----- src/trace-driven/pascal_opcode.h | 202 ------- src/trace-driven/trace_driven.cc | 10 +- src/trace-driven/trace_driven.h | 2 +- src/trace-driven/trace_opcode.h | 71 --- .../traces-generator/NVbit_tool/Makefile | 23 - .../traces-generator/NVbit_tool/traceall.cu | 646 --------------------- src/trace-driven/traces-generator/README | 1 - .../traces-post-processing/Makefile | 11 - .../post-traces-processing.cpp | 195 ------- src/trace-driven/turing_opcode.h | 25 - src/trace-driven/volta_opcode.h | 176 ------ 18 files changed, 627 insertions(+), 1507 deletions(-) create mode 100644 src/trace-driven/ISA_Def/kepler_opcode.h create mode 100644 src/trace-driven/ISA_Def/pascal_opcode.h create mode 100644 src/trace-driven/ISA_Def/trace_opcode.h create mode 100644 src/trace-driven/ISA_Def/turing_opcode.h create mode 100644 src/trace-driven/ISA_Def/volta_opcode.h delete mode 100644 src/trace-driven/kepler_opcode.h delete mode 100644 src/trace-driven/pascal_opcode.h delete mode 100644 src/trace-driven/trace_opcode.h delete mode 100644 src/trace-driven/traces-generator/NVbit_tool/Makefile delete mode 100644 src/trace-driven/traces-generator/NVbit_tool/traceall.cu delete mode 100644 src/trace-driven/traces-generator/README delete mode 100755 src/trace-driven/traces-generator/traces-post-processing/Makefile delete mode 100644 src/trace-driven/traces-generator/traces-post-processing/post-traces-processing.cpp delete mode 100644 src/trace-driven/turing_opcode.h delete mode 100644 src/trace-driven/volta_opcode.h (limited to 'src') diff --git a/src/trace-driven/ISA_Def/kepler_opcode.h b/src/trace-driven/ISA_Def/kepler_opcode.h new file mode 100644 index 0000000..675ea6c --- /dev/null +++ b/src/trace-driven/ISA_Def/kepler_opcode.h @@ -0,0 +1,149 @@ +//developed by Mahmoud Khairy, Purdue Univ +//abdallm@purdue.edu + +#ifndef KEPLER_OPCODE_H +#define KEPLER_OPCODE_H + +#include "trace_opcode.h" +#include +#include + +#define KEPLER_BINART_VERSION 35 +#define KEPLER_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 + +//TO DO: moving this to a yml or def files + +///Kepler ISA +//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html +static const std::unordered_map Kepler_OpcodeMap = { + //Floating Point 32 Instructions + {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, + {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, + {"FADD", OpcodeChar(OP_FADD, SP_OP)}, + {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, + {"FCMP", OpcodeChar(OP_FCMP, SP_OP)}, + {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, + {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, + {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, + {"FSWZ", OpcodeChar(OP_FSWZ, SP_OP)}, + {"FSET", OpcodeChar(OP_FSET, SP_OP)}, + {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, + {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, + {"RRO", OpcodeChar(OP_RRO, SP_OP)}, + //SFU + {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, + + + //Double Point Instructions + {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, + {"DADD", OpcodeChar(OP_DADD, DP_OP)}, + {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, + {"DMNMX", OpcodeChar(OP_DMNMX, DP_OP)}, + {"DSET", OpcodeChar(OP_DSET, DP_OP)}, + {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, + + //Integer Instructions + {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, + {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, + {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, + {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, + {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, + {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, + {"ISUB", OpcodeChar(OP_ISUB, INTP_OP)}, + {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, + {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, + {"ISAD", OpcodeChar(OP_ISAD, INTP_OP)}, + {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, + {"BFE", OpcodeChar(OP_BFE, INTP_OP)}, + {"BFI", OpcodeChar(OP_BFI, INTP_OP)}, + {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, + {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, + {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, + {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, + {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, + {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, + {"ISET", OpcodeChar(OP_ISET, INTP_OP)}, + {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, + {"ICMP", OpcodeChar(OP_ICMP, INTP_OP)}, + {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, + + //Conversion Instructions + {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, + {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, + {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, + {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, + + //Movement Instructions + {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, + {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, + {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, + {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, + {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, + + //Predicate Instructions + {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, + {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, + {"CSET", OpcodeChar(OP_CSET, ALU_OP)}, + {"CSETP", OpcodeChar(OP_CSETP, ALU_OP)}, + {"PSET", OpcodeChar(OP_PSET, ALU_OP)}, + {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, + + //Texture Instructions + //For now, we ignore texture loads, consider it as ALU_OP + {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, + {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, + {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, + {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, + + //Load/Store Instructions + //For now, we ignore constant loads, consider it as ALU_OP, TO DO + {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, + //in Kepler, LD is load global so set it to LDG + {"LD", OpcodeChar(OP_LDG, LOAD_OP)}, + {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, + {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, + {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, + {"LDSLK", OpcodeChar(OP_LDSLK, LOAD_OP)}, + {"ST", OpcodeChar(OP_STG, STORE_OP)}, + {"STL", OpcodeChar(OP_STL, STORE_OP)}, + {"STS", OpcodeChar(OP_STS, STORE_OP)}, + {"STSCUL", OpcodeChar(OP_STSCUL, STORE_OP)}, + {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, + {"RED", OpcodeChar(OP_RED, STORE_OP)}, + {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, + {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, + {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, + + //surface memory instructions + {"SUCLAMP", OpcodeChar(OP_SUCLAMP, LOAD_OP)}, + {"SUBFM", OpcodeChar(OP_SUBFM, LOAD_OP)}, + {"SUEAU", OpcodeChar(OP_SUEAU, LOAD_OP)}, + {"SULDGA", OpcodeChar(OP_SULDGA, LOAD_OP)}, + {"SUSTGA", OpcodeChar(OP_SUSTGA, STORE_OP)}, + + //Control Instructions + {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, + {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, + {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, + {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, + {"CAL", OpcodeChar(OP_CAL, CALL_OPS)}, + {"JCAL", OpcodeChar(OP_JCAL, CALL_OPS)}, + {"RET", OpcodeChar(OP_RET, RET_OPS)}, + {"BRK", OpcodeChar(OP_BRK, RET_OPS)}, + {"CONT", OpcodeChar(OP_CONT, RET_OPS)}, + {"SSY", OpcodeChar(OP_SSY, RET_OPS)}, + {"PBK", OpcodeChar(OP_PBK, RET_OPS)}, + {"PCNT", OpcodeChar(OP_PCNT, RET_OPS)}, + {"PRET", OpcodeChar(OP_PRET, RET_OPS)}, + {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, + {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, + + //Miscellaneous Instructions + {"NOP", OpcodeChar(OP_NOP, ALU_OP)}, + {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, + {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, + {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, + {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, +}; + +#endif diff --git a/src/trace-driven/ISA_Def/pascal_opcode.h b/src/trace-driven/ISA_Def/pascal_opcode.h new file mode 100644 index 0000000..66a0841 --- /dev/null +++ b/src/trace-driven/ISA_Def/pascal_opcode.h @@ -0,0 +1,201 @@ +//developed by Mahmoud Khairy, Purdue Univ +//abdallm@purdue.edu + +#ifndef PASCAL_OPCODE_H +#define PASCAL_OPCODE_H + +#include "trace_opcode.h" +#include +#include + +#define PASCAL_TITANX_BINART_VERSION 61 +#define PASCAL_P100_BINART_VERSION 60 + +#define PASCAL_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 + +//TO DO: moving this to a yml or def files + +///Pascal SM_61 ISA +//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html +static const std::unordered_map Pascal_OpcodeMap = { + //Floating Point 32 Instructions + {"FADD", OpcodeChar(OP_FADD, SP_OP)}, + {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, + {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, + {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, + {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, + {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, + {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, + {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, + {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, + {"FSET", OpcodeChar(OP_FSET, SP_OP)}, + {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, + {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, + {"RRO", OpcodeChar(OP_RRO, SP_OP)}, + + //SFU + {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, + + //Floating Point 16 Instructions + {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, + {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, + {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, + {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, + {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, + + //Double Point Instructions + {"DADD", OpcodeChar(OP_DADD, DP_OP)}, + {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, + {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, + {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, + {"DMNMX", OpcodeChar(OP_DMNMX, DP_OP)}, + {"DSET", OpcodeChar(OP_DSET, DP_OP)}, + + //Integer Instructions + {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, + {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, + {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, + {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, + {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, + {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, + {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, + {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, + {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, + {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, + {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, + {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, + {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, + {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, + {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, + {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, + {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, + {"ISET", OpcodeChar(OP_ISET, INTP_OP)}, + {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, + {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, + {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, + {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, + {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, + {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, + {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, + {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, + {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, + {"BFE", OpcodeChar(OP_BFE, INTP_OP)}, + {"BFI", OpcodeChar(OP_BFI, INTP_OP)}, + {"ICMP", OpcodeChar(OP_ICMP, INTP_OP)}, + {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, + {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, + {"XMAD", OpcodeChar(OP_XMAD, INTP_OP)}, + {"VMNMX", OpcodeChar(OP_VMNMX, INTP_OP)}, + + + //Conversion Instructions + {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, + {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, + {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, + {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, + {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, + {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, + + //Movement Instructions + {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, + {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, + {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, + {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, + {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, + {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, + + //Predicate Instructions + {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, + {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, + {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, + {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, + {"CSET", OpcodeChar(OP_CSET, ALU_OP)}, + {"CSETP", OpcodeChar(OP_CSETP, ALU_OP)}, + {"PSET", OpcodeChar(OP_PSET, ALU_OP)}, + + + //Load/Store Instructions + {"LD", OpcodeChar(OP_LD, LOAD_OP)}, + //For now, we ignore constant loads, consider it as ALU_OP, TO DO + {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, + {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, + {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, + {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, + {"ST", OpcodeChar(OP_ST, STORE_OP)}, + {"STG", OpcodeChar(OP_STG, STORE_OP)}, + {"STL", OpcodeChar(OP_STL, STORE_OP)}, + {"STS", OpcodeChar(OP_STS, STORE_OP)}, + {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, + {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, + {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, + {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, + {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, + {"RED", OpcodeChar(OP_RED, STORE_OP)}, + {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, + {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, + {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, + {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, + {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, + + //Texture Instructions + //For now, we ignore texture loads, consider it as ALU_OP + {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, + {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, + {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, + {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, + {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, + {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, + {"TEXS", OpcodeChar(OP_TEXS, ALU_OP)}, + {"TLD4S", OpcodeChar(OP_TLD4S, ALU_OP)}, + {"TLDS", OpcodeChar(OP_TLDS, ALU_OP)}, + + //Control Instructions + {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, + {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, + {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, + {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, + {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, + {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, + {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, + {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, + {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, + {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, + {"SSY", OpcodeChar(OP_SSY, BRANCH_OP)}, + {"SYNC", OpcodeChar(OP_SYNC, BRANCH_OP)}, + {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, + {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, + {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, + {"RET", OpcodeChar(OP_RET, RET_OPS)}, + {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, + {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, + {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, + {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, + {"CAL", OpcodeChar(OP_CAL, CALL_OPS)}, + {"JCAL", OpcodeChar(OP_JCAL, CALL_OPS)}, + {"PRET", OpcodeChar(OP_PRET, CALL_OPS)}, + {"BRK", OpcodeChar(OP_BRK, CALL_OPS)}, + {"PBK", OpcodeChar(OP_PBK, CALL_OPS)}, + {"CONT", OpcodeChar(OP_CONT, CALL_OPS)}, + {"PCNT", OpcodeChar(OP_PCNT, CALL_OPS)}, + {"PEXIT", OpcodeChar(OP_PEXIT, CALL_OPS)}, + + //Miscellaneous Instructions + {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, + {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, + {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, + {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, + {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, + {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, + {"LEPC", OpcodeChar(OP_LEPC ,ALU_OP)}, + {"NOP", OpcodeChar(OP_NOP ,ALU_OP)}, + {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, + {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, + {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, + {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, + {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, + {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, + {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, + +}; + +#endif diff --git a/src/trace-driven/ISA_Def/trace_opcode.h b/src/trace-driven/ISA_Def/trace_opcode.h new file mode 100644 index 0000000..ed147fc --- /dev/null +++ b/src/trace-driven/ISA_Def/trace_opcode.h @@ -0,0 +1,71 @@ +//developed by Mahmoud Khairy, Purdue Univ +//abdallm@purdue.edu + +#ifndef TRACE_OPCODE_H +#define TRACE_OPCODE_H + +#include "../../abstract_hardware_model.h" +#include +#include + + +enum TraceInstrOpcode { + //volta (common insts for others cards as well) + OP_FADD = 1, OP_FADD32I, OP_FCHK, OP_FFMA32I, OP_FFMA, OP_FMNMX, OP_FMUL, OP_FMUL32I, OP_FSEL, OP_FSET, OP_FSETP, + OP_FSWZADD, OP_MUFU, OP_HADD2, OP_HADD2_32I, OP_HFMA2, OP_HFMA2_32I, OP_HMUL2, OP_HMUL2_32I, OP_HSET2, OP_HSETP2, + OP_HMMA, OP_DADD, OP_DFMA, OP_DMUL, OP_DSETP, + OP_BMSK, OP_BREV, OP_FLO, OP_IABS, OP_IADD, OP_IADD3, OP_IADD32I, OP_IDP, OP_IDP4A, OP_IMAD, OP_IMMA, OP_IMNMX, + OP_IMUL, OP_IMUL32I, OP_ISCADD, OP_ISCADD32I, OP_ISETP, OP_LEA, OP_LOP, OP_LOP3, OP_LOP32I, OP_POPC, OP_SHF, OP_SHR, + OP_VABSDIFF, OP_VABSDIFF4, + OP_F2F, OP_F2I, OP_I2F, OP_I2I, OP_I2IP, OP_FRND, OP_MOV, OP_MOV32I, OP_PRMT, OP_SEL, OP_SGXT, OP_SHFL, OP_PLOP3, + OP_PSETP, OP_P2R, OP_R2P, OP_LD, OP_LDC, OP_LDG, OP_LDL, OP_LDS, OP_ST, OP_STG, OP_STL, OP_STS, OP_MATCH, OP_QSPC, + OP_ATOM, OP_ATOMS, OP_ATOMG, OP_RED, OP_CCTL, OP_CCTLL, OP_ERRBAR, OP_MEMBAR, OP_CCTLT, + OP_TEX, OP_TLD, OP_TLD4, + OP_TMML, OP_TXD, OP_TXQ, OP_BMOV, OP_BPT, OP_BRA, OP_BREAK, OP_BRX, OP_BSSY, OP_BSYNC, OP_CALL, OP_EXIT, OP_JMP, OP_JMX, + OP_KILL, OP_NANOSLEEP, OP_RET, OP_RPCMOV, OP_RTT, OP_WARPSYNC, OP_YIELD, OP_B2R, OP_BAR, OP_CS2R, OP_CSMTEST, OP_DEPBAR, + OP_GETLMEMBASE, OP_LEPC, OP_NOP, OP_PMTRIG, OP_R2B, OP_S2R, OP_SETCTAID, OP_SETLMEMBASE, OP_VOTE, OP_VOTE_VTG, + //unique insts for pascal + OP_RRO, OP_DMNMX, OP_DSET, OP_BFE, OP_BFI, OP_ICMP, OP_IMADSP, OP_SHL, OP_XMAD, OP_CSET, OP_CSETP, + OP_TEXS, OP_TLD4S, OP_TLDS, OP_CAL, OP_JCAL, OP_PRET, OP_BRK, OP_PBK, OP_CONT, OP_PCNT, OP_PEXIT, OP_SSY, OP_SYNC, OP_PSET + , OP_VMNMX, OP_ISET, + //unique insts for kepler + OP_FCMP, OP_FSWZ, OP_ISAD, OP_LDSLK, OP_STSCUL, OP_SUCLAMP, OP_SUBFM, OP_SUEAU, OP_SULDGA, OP_SUSTGA, OP_ISUB, + SASS_NUM_OPCODES /* The total number of opcodes. */ +}; +typedef enum TraceInstrOpcode sass_op_type; + +/* +enum uarch_op_t { + NO_OP=-1, + ALU_OP=1, + SFU_OP, + TENSOR_CORE_OP, + DP_OP, + SP_OP, + INTP_OP, + ALU_SFU_OP, + LOAD_OP, + TENSOR_CORE_LOAD_OP, + TENSOR_CORE_STORE_OP, + STORE_OP, + BRANCH_OP, + BARRIER_OP, + MEMORY_BARRIER_OP, + CALL_OPS, + RET_OPS +}; +typedef enum uarch_op_t op_type; + */ + +struct OpcodeChar +{ + OpcodeChar(unsigned m_opcode, unsigned m_opcode_category) { + opcode = m_opcode; + opcode_category = m_opcode_category; + } + unsigned opcode; + unsigned opcode_category; +}; + + +#endif diff --git a/src/trace-driven/ISA_Def/turing_opcode.h b/src/trace-driven/ISA_Def/turing_opcode.h new file mode 100644 index 0000000..4df44d9 --- /dev/null +++ b/src/trace-driven/ISA_Def/turing_opcode.h @@ -0,0 +1,24 @@ +//developed by Mahmoud Khairy, Purdue Univ +//abdallm@purdue.edu + +#ifndef TURING_OPCODE_H +#define TURING_OPCODE_H + +#include "trace_opcode.h" +#include +#include + +//TO DO: moving this to a yml or def files + + +#define TURING_BINART_VERSION 72 + +///Tuing SM_72 ISA +//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html +static const std::unordered_map Turing_OpcodeMap = { + +//TO fill + +}; + +#endif diff --git a/src/trace-driven/ISA_Def/volta_opcode.h b/src/trace-driven/ISA_Def/volta_opcode.h new file mode 100644 index 0000000..03d50b7 --- /dev/null +++ b/src/trace-driven/ISA_Def/volta_opcode.h @@ -0,0 +1,175 @@ +//developed by Mahmoud Khairy, Purdue Univ +//abdallm@purdue.edu + +#ifndef VOLTA_OPCODE_H +#define VOLTA_OPCODE_H + +#include "trace_opcode.h" +#include +#include + +#define VOLTA_BINART_VERSION 70 +#define VOLTA_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 + +//TO DO: moving this to a yml or def files + +///Volta SM_70 ISA +//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html +static const std::unordered_map Volta_OpcodeMap = { + //Floating Point 32 Instructions + {"FADD", OpcodeChar(OP_FADD, SP_OP)}, + {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, + {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, + {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, + {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, + {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, + {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, + {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, + {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, + {"FSET", OpcodeChar(OP_FSET, SP_OP)}, + {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, + {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, + //SFU + {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, + + //Floating Point 16 Instructions + {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, + {"HADD2_32I", OpcodeChar(OP_HADD2_32I, SP_OP)}, + {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, + {"HFMA2_32I", OpcodeChar(OP_HFMA2_32I, SP_OP)}, + {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, + {"HMUL2_32I", OpcodeChar(OP_HMUL2_32I, SP_OP)}, + {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, + {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, + + //Tensor Core Instructions + {"HMMA", OpcodeChar(OP_HMMA, TENSOR_CORE_OP)}, + + //Double Point Instructions + {"DADD", OpcodeChar(OP_DADD, DP_OP)}, + {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, + {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, + {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, + + //Integer Instructions + {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, + {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, + {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, + {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, + {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, + {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, + {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, + {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, + {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, + {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, + {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, + {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, + {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, + {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, + {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, + {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, + {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, + {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, + {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, + {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, + {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, + {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, + {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, + {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, + {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, + {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, + + //Conversion Instructions + {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, + {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, + {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, + {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, + {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, + {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, + + //Movement Instructions + {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, + {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, + {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, + {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, + {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, + {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, + + //Predicate Instructions + {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, + {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, + {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, + {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, + + //Load/Store Instructions + {"LD", OpcodeChar(OP_LD, LOAD_OP)}, + //For now, we ignore constant loads, consider it as ALU_OP, TO DO + {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, + {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, + {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, + {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, + {"ST", OpcodeChar(OP_ST, STORE_OP)}, + {"STG", OpcodeChar(OP_STG, STORE_OP)}, + {"STL", OpcodeChar(OP_STL, STORE_OP)}, + {"STS", OpcodeChar(OP_STS, STORE_OP)}, + {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, + {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, + {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, + {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, + {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, + {"RED", OpcodeChar(OP_RED, STORE_OP)}, + {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, + {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, + {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, + {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, + {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, + + //Texture Instructions + //For now, we ignore texture loads, consider it as ALU_OP + {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, + {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, + {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, + {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, + {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, + {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, + + //Control Instructions + {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, + {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, + {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, + {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, + {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, + {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, + {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, + {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, + {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, + {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, + {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, + {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, + {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, + {"RET", OpcodeChar(OP_RET, RET_OPS)}, + {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, + {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, + {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, + {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, + + //Miscellaneous Instructions + {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, + {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, + {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, + {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, + {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, + {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, + {"LEPC", OpcodeChar(OP_LEPC ,ALU_OP)}, + {"NOP", OpcodeChar(OP_NOP ,ALU_OP)}, + {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, + {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, + {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, + {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, + {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, + {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, + {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, + +}; + +#endif diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 5e07ace..90dc769 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -16,7 +16,7 @@ #include "../gpgpu-sim/gpu-sim.h" #include "../../libcuda/gpgpu_context.h" #include "trace_driven.h" -#include "trace_opcode.h" +#include "ISA_Def/trace_opcode.h" #include "../gpgpusim_entrypoint.h" /* TO DO: diff --git a/src/trace-driven/kepler_opcode.h b/src/trace-driven/kepler_opcode.h deleted file mode 100644 index 4aa8e0f..0000000 --- a/src/trace-driven/kepler_opcode.h +++ /dev/null @@ -1,150 +0,0 @@ -//developed by Mahmoud Khairy, Purdue Univ -//abdallm@purdue.edu - -#ifndef KEPLER_OPCODE_H -#define KEPLER_OPCODE_H - -#include "../abstract_hardware_model.h" -#include "trace_opcode.h" -#include -#include - -#define KEPLER_BINART_VERSION 35 -#define KEPLER_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 - -//TO DO: moving this to a yml or def files - -///Kepler ISA -//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map Kepler_OpcodeMap = { - //Floating Point 32 Instructions - {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, - {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, - {"FADD", OpcodeChar(OP_FADD, SP_OP)}, - {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, - {"FCMP", OpcodeChar(OP_FCMP, SP_OP)}, - {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, - {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, - {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, - {"FSWZ", OpcodeChar(OP_FSWZ, SP_OP)}, - {"FSET", OpcodeChar(OP_FSET, SP_OP)}, - {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, - {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, - {"RRO", OpcodeChar(OP_RRO, SP_OP)}, - //SFU - {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, - - - //Double Point Instructions - {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, - {"DADD", OpcodeChar(OP_DADD, DP_OP)}, - {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, - {"DMNMX", OpcodeChar(OP_DMNMX, DP_OP)}, - {"DSET", OpcodeChar(OP_DSET, DP_OP)}, - {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, - - //Integer Instructions - {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, - {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, - {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, - {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, - {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, - {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, - {"ISUB", OpcodeChar(OP_ISUB, INTP_OP)}, - {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, - {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, - {"ISAD", OpcodeChar(OP_ISAD, INTP_OP)}, - {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, - {"BFE", OpcodeChar(OP_BFE, INTP_OP)}, - {"BFI", OpcodeChar(OP_BFI, INTP_OP)}, - {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, - {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, - {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, - {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, - {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, - {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, - {"ISET", OpcodeChar(OP_ISET, INTP_OP)}, - {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, - {"ICMP", OpcodeChar(OP_ICMP, INTP_OP)}, - {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, - - //Conversion Instructions - {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, - {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, - {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, - {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, - - //Movement Instructions - {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, - {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, - {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, - {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, - {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, - - //Predicate Instructions - {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, - {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, - {"CSET", OpcodeChar(OP_CSET, ALU_OP)}, - {"CSETP", OpcodeChar(OP_CSETP, ALU_OP)}, - {"PSET", OpcodeChar(OP_PSET, ALU_OP)}, - {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, - - //Texture Instructions - //For now, we ignore texture loads, consider it as ALU_OP - {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, - {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, - {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, - {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, - - //Load/Store Instructions - //For now, we ignore constant loads, consider it as ALU_OP, TO DO - {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, - //in Kepler, LD is load global so set it to LDG - {"LD", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, - {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, - {"LDSLK", OpcodeChar(OP_LDSLK, LOAD_OP)}, - {"ST", OpcodeChar(OP_STG, STORE_OP)}, - {"STL", OpcodeChar(OP_STL, STORE_OP)}, - {"STS", OpcodeChar(OP_STS, STORE_OP)}, - {"STSCUL", OpcodeChar(OP_STSCUL, STORE_OP)}, - {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, - {"RED", OpcodeChar(OP_RED, STORE_OP)}, - {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, - {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, - {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, - - //surface memory instructions - {"SUCLAMP", OpcodeChar(OP_SUCLAMP, LOAD_OP)}, - {"SUBFM", OpcodeChar(OP_SUBFM, LOAD_OP)}, - {"SUEAU", OpcodeChar(OP_SUEAU, LOAD_OP)}, - {"SULDGA", OpcodeChar(OP_SULDGA, LOAD_OP)}, - {"SUSTGA", OpcodeChar(OP_SUSTGA, STORE_OP)}, - - //Control Instructions - {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, - {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, - {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, - {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, - {"CAL", OpcodeChar(OP_CAL, CALL_OPS)}, - {"JCAL", OpcodeChar(OP_JCAL, CALL_OPS)}, - {"RET", OpcodeChar(OP_RET, RET_OPS)}, - {"BRK", OpcodeChar(OP_BRK, RET_OPS)}, - {"CONT", OpcodeChar(OP_CONT, RET_OPS)}, - {"SSY", OpcodeChar(OP_SSY, RET_OPS)}, - {"PBK", OpcodeChar(OP_PBK, RET_OPS)}, - {"PCNT", OpcodeChar(OP_PCNT, RET_OPS)}, - {"PRET", OpcodeChar(OP_PRET, RET_OPS)}, - {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, - {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, - - //Miscellaneous Instructions - {"NOP", OpcodeChar(OP_NOP, ALU_OP)}, - {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, - {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, - {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, - {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, -}; - -#endif diff --git a/src/trace-driven/pascal_opcode.h b/src/trace-driven/pascal_opcode.h deleted file mode 100644 index 2cacb28..0000000 --- a/src/trace-driven/pascal_opcode.h +++ /dev/null @@ -1,202 +0,0 @@ -//developed by Mahmoud Khairy, Purdue Univ -//abdallm@purdue.edu - -#ifndef PASCAL_OPCODE_H -#define PASCAL_OPCODE_H - -#include "../abstract_hardware_model.h" -#include "trace_opcode.h" -#include -#include - -#define PASCAL_TITANX_BINART_VERSION 61 -#define PASCAL_P100_BINART_VERSION 60 - -#define PASCAL_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 - -//TO DO: moving this to a yml or def files - -///Pascal SM_61 ISA -//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map Pascal_OpcodeMap = { - //Floating Point 32 Instructions - {"FADD", OpcodeChar(OP_FADD, SP_OP)}, - {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, - {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, - {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, - {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, - {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, - {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, - {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, - {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, - {"FSET", OpcodeChar(OP_FSET, SP_OP)}, - {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, - {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, - {"RRO", OpcodeChar(OP_RRO, SP_OP)}, - - //SFU - {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, - - //Floating Point 16 Instructions - {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, - {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, - {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, - {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, - {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, - - //Double Point Instructions - {"DADD", OpcodeChar(OP_DADD, DP_OP)}, - {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, - {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, - {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, - {"DMNMX", OpcodeChar(OP_DMNMX, DP_OP)}, - {"DSET", OpcodeChar(OP_DSET, DP_OP)}, - - //Integer Instructions - {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, - {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, - {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, - {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, - {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, - {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, - {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, - {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, - {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, - {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, - {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, - {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, - {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, - {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, - {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, - {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, - {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, - {"ISET", OpcodeChar(OP_ISET, INTP_OP)}, - {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, - {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, - {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, - {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, - {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, - {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, - {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, - {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, - {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, - {"BFE", OpcodeChar(OP_BFE, INTP_OP)}, - {"BFI", OpcodeChar(OP_BFI, INTP_OP)}, - {"ICMP", OpcodeChar(OP_ICMP, INTP_OP)}, - {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, - {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, - {"XMAD", OpcodeChar(OP_XMAD, INTP_OP)}, - {"VMNMX", OpcodeChar(OP_VMNMX, INTP_OP)}, - - - //Conversion Instructions - {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, - {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, - {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, - {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, - {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, - {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, - - //Movement Instructions - {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, - {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, - {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, - {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, - {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, - {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, - - //Predicate Instructions - {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, - {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, - {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, - {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, - {"CSET", OpcodeChar(OP_CSET, ALU_OP)}, - {"CSETP", OpcodeChar(OP_CSETP, ALU_OP)}, - {"PSET", OpcodeChar(OP_PSET, ALU_OP)}, - - - //Load/Store Instructions - {"LD", OpcodeChar(OP_LD, LOAD_OP)}, - //For now, we ignore constant loads, consider it as ALU_OP, TO DO - {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, - {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, - {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, - {"ST", OpcodeChar(OP_ST, STORE_OP)}, - {"STG", OpcodeChar(OP_STG, STORE_OP)}, - {"STL", OpcodeChar(OP_STL, STORE_OP)}, - {"STS", OpcodeChar(OP_STS, STORE_OP)}, - {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, - {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, - {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, - {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, - {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, - {"RED", OpcodeChar(OP_RED, STORE_OP)}, - {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, - {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, - {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, - {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, - {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, - - //Texture Instructions - //For now, we ignore texture loads, consider it as ALU_OP - {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, - {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, - {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, - {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, - {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, - {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, - {"TEXS", OpcodeChar(OP_TEXS, ALU_OP)}, - {"TLD4S", OpcodeChar(OP_TLD4S, ALU_OP)}, - {"TLDS", OpcodeChar(OP_TLDS, ALU_OP)}, - - //Control Instructions - {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, - {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, - {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, - {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, - {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, - {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, - {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, - {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, - {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, - {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, - {"SSY", OpcodeChar(OP_SSY, BRANCH_OP)}, - {"SYNC", OpcodeChar(OP_SYNC, BRANCH_OP)}, - {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, - {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, - {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, - {"RET", OpcodeChar(OP_RET, RET_OPS)}, - {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, - {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, - {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, - {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, - {"CAL", OpcodeChar(OP_CAL, CALL_OPS)}, - {"JCAL", OpcodeChar(OP_JCAL, CALL_OPS)}, - {"PRET", OpcodeChar(OP_PRET, CALL_OPS)}, - {"BRK", OpcodeChar(OP_BRK, CALL_OPS)}, - {"PBK", OpcodeChar(OP_PBK, CALL_OPS)}, - {"CONT", OpcodeChar(OP_CONT, CALL_OPS)}, - {"PCNT", OpcodeChar(OP_PCNT, CALL_OPS)}, - {"PEXIT", OpcodeChar(OP_PEXIT, CALL_OPS)}, - - //Miscellaneous Instructions - {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, - {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, - {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, - {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, - {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, - {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, - {"LEPC", OpcodeChar(OP_LEPC ,ALU_OP)}, - {"NOP", OpcodeChar(OP_NOP ,ALU_OP)}, - {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, - {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, - {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, - {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, - {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, - {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, - {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, - -}; - -#endif diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 22c527e..76eb7ca 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -19,11 +19,11 @@ #include "../gpgpu-sim/gpu-sim.h" #include "../../libcuda/gpgpu_context.h" #include "trace_driven.h" -#include "trace_opcode.h" -#include "volta_opcode.h" -#include "turing_opcode.h" -#include "pascal_opcode.h" -#include "kepler_opcode.h" +#include "ISA_Def/trace_opcode.h" +#include "ISA_Def/volta_opcode.h" +#include "ISA_Def/turing_opcode.h" +#include "ISA_Def/pascal_opcode.h" +#include "ISA_Def/kepler_opcode.h" #include "../gpgpusim_entrypoint.h" diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index 2888f86..e9fecd9 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -9,7 +9,7 @@ #include "../abstract_hardware_model.h" #include "../gpgpu-sim/shader.h" -#include "trace_opcode.h" +#include "ISA_Def/trace_opcode.h" class trace_function_info: public function_info { public: diff --git a/src/trace-driven/trace_opcode.h b/src/trace-driven/trace_opcode.h deleted file mode 100644 index 3492fd3..0000000 --- a/src/trace-driven/trace_opcode.h +++ /dev/null @@ -1,71 +0,0 @@ -//developed by Mahmoud Khairy, Purdue Univ -//abdallm@purdue.edu - -#ifndef TRACE_OPCODE_H -#define TRACE_OPCODE_H - -#include "../abstract_hardware_model.h" -#include -#include - - -enum TraceInstrOpcode { - //volta (common insts for others cards as well) - OP_FADD = 1, OP_FADD32I, OP_FCHK, OP_FFMA32I, OP_FFMA, OP_FMNMX, OP_FMUL, OP_FMUL32I, OP_FSEL, OP_FSET, OP_FSETP, - OP_FSWZADD, OP_MUFU, OP_HADD2, OP_HADD2_32I, OP_HFMA2, OP_HFMA2_32I, OP_HMUL2, OP_HMUL2_32I, OP_HSET2, OP_HSETP2, - OP_HMMA, OP_DADD, OP_DFMA, OP_DMUL, OP_DSETP, - OP_BMSK, OP_BREV, OP_FLO, OP_IABS, OP_IADD, OP_IADD3, OP_IADD32I, OP_IDP, OP_IDP4A, OP_IMAD, OP_IMMA, OP_IMNMX, - OP_IMUL, OP_IMUL32I, OP_ISCADD, OP_ISCADD32I, OP_ISETP, OP_LEA, OP_LOP, OP_LOP3, OP_LOP32I, OP_POPC, OP_SHF, OP_SHR, - OP_VABSDIFF, OP_VABSDIFF4, - OP_F2F, OP_F2I, OP_I2F, OP_I2I, OP_I2IP, OP_FRND, OP_MOV, OP_MOV32I, OP_PRMT, OP_SEL, OP_SGXT, OP_SHFL, OP_PLOP3, - OP_PSETP, OP_P2R, OP_R2P, OP_LD, OP_LDC, OP_LDG, OP_LDL, OP_LDS, OP_ST, OP_STG, OP_STL, OP_STS, OP_MATCH, OP_QSPC, - OP_ATOM, OP_ATOMS, OP_ATOMG, OP_RED, OP_CCTL, OP_CCTLL, OP_ERRBAR, OP_MEMBAR, OP_CCTLT, - OP_TEX, OP_TLD, OP_TLD4, - OP_TMML, OP_TXD, OP_TXQ, OP_BMOV, OP_BPT, OP_BRA, OP_BREAK, OP_BRX, OP_BSSY, OP_BSYNC, OP_CALL, OP_EXIT, OP_JMP, OP_JMX, - OP_KILL, OP_NANOSLEEP, OP_RET, OP_RPCMOV, OP_RTT, OP_WARPSYNC, OP_YIELD, OP_B2R, OP_BAR, OP_CS2R, OP_CSMTEST, OP_DEPBAR, - OP_GETLMEMBASE, OP_LEPC, OP_NOP, OP_PMTRIG, OP_R2B, OP_S2R, OP_SETCTAID, OP_SETLMEMBASE, OP_VOTE, OP_VOTE_VTG, - //unique insts for pascal - OP_RRO, OP_DMNMX, OP_DSET, OP_BFE, OP_BFI, OP_ICMP, OP_IMADSP, OP_SHL, OP_XMAD, OP_CSET, OP_CSETP, - OP_TEXS, OP_TLD4S, OP_TLDS, OP_CAL, OP_JCAL, OP_PRET, OP_BRK, OP_PBK, OP_CONT, OP_PCNT, OP_PEXIT, OP_SSY, OP_SYNC, OP_PSET - , OP_VMNMX, OP_ISET, - //unique insts for kepler - OP_FCMP, OP_FSWZ, OP_ISAD, OP_LDSLK, OP_STSCUL, OP_SUCLAMP, OP_SUBFM, OP_SUEAU, OP_SULDGA, OP_SUSTGA, OP_ISUB, - SASS_NUM_OPCODES /* The total number of opcodes. */ -}; -typedef enum TraceInstrOpcode sass_op_type; - -/* -enum uarch_op_t { - NO_OP=-1, - ALU_OP=1, - SFU_OP, - TENSOR_CORE_OP, - DP_OP, - SP_OP, - INTP_OP, - ALU_SFU_OP, - LOAD_OP, - TENSOR_CORE_LOAD_OP, - TENSOR_CORE_STORE_OP, - STORE_OP, - BRANCH_OP, - BARRIER_OP, - MEMORY_BARRIER_OP, - CALL_OPS, - RET_OPS -}; -typedef enum uarch_op_t op_type; - */ - -struct OpcodeChar -{ - OpcodeChar(unsigned m_opcode, unsigned m_opcode_category) { - opcode = m_opcode; - opcode_category = m_opcode_category; - } - unsigned opcode; - unsigned opcode_category; -}; - - -#endif diff --git a/src/trace-driven/traces-generator/NVbit_tool/Makefile b/src/trace-driven/traces-generator/NVbit_tool/Makefile deleted file mode 100644 index fc0209a..0000000 --- a/src/trace-driven/traces-generator/NVbit_tool/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -NVCC=nvcc -ccbin=`which gcc` -D_FORCE_INLINES -NVBIT_PATH=../../core -INCLUDES=-I$(NVBIT_PATH) -LIBS=-L$(NVBIT_PATH) -lnvbit -NVCC_PATH=-L $(subst bin/nvcc,lib64,$(shell which nvcc | tr -s /)) -SOURCES=$(wildcard *.cu) -OBJECTS=$(SOURCES:.cu=.o) -ARCH=35 - -mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) -current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) - -all: $(OBJECTS) $(NVBIT_PATH)/libnvbit.a - $(NVCC) -arch=sm_$(ARCH) -O3 *.o $(LIBS) $(NVCC_PATH) -lcuda -lcudart_static -shared -o ${current_dir}.so - -%.o: %.cu - $(NVCC) -dc -c -std=c++11 $(INCLUDES) -Xptxas -cloning=no -maxrregcount=16 -Xcompiler -Wall -arch=sm_$(ARCH) -O3 -Xcompiler -fPIC $< -o $@ - -$(NVBIT_PATH)/libnvbit.a: - make -C $(NVBIT_PATH) - -clean: - rm -f *.so *.o diff --git a/src/trace-driven/traces-generator/NVbit_tool/traceall.cu b/src/trace-driven/traces-generator/NVbit_tool/traceall.cu deleted file mode 100644 index 1426528..0000000 --- a/src/trace-driven/traces-generator/NVbit_tool/traceall.cu +++ /dev/null @@ -1,646 +0,0 @@ -/* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of NVIDIA CORPORATION nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Author: Oreste Villa, ovilla@nvidia.com - 2018 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* every tool needs to include this once */ -#include "nvbit_tool.h" - -/* nvbit interface file */ -#include "nvbit.h" - -/* for channel */ -#include "utils/channel.hpp" - -/* for _cuda_safe and GET_VAR* macros */ -#include "macros.h" - -/* Channel used to communicate from GPU to CPU receiving thread */ -#define CHANNEL_SIZE (1l << 20) -static __managed__ ChannelDev channel_dev; -static ChannelHost channel_host; - -/* receiving thread and its control variables */ -pthread_t recv_thread; -volatile bool recv_thread_started = false; -volatile bool recv_thread_receiving = false; - -/* skip flag used to avoid re-entry on the nvbit_callback when issuing - * flush_channel kernel call */ -bool skip_flag = false; - -/* global control variables for this tool */ -uint32_t instr_begin_interval = 0; -uint32_t instr_end_interval = UINT32_MAX; -int verbose = 0; - -/* opcode to id map and reverse map */ -std::map opcode_to_id_map; -std::map id_to_opcode_map; - -/* kernel instruction counter, updated by the GPU */ -static __managed__ uint64_t total_dynamic_instr_counter = 0; -static __managed__ uint64_t reported_dynamic_instr_counter = 0; -static __managed__ uint64_t dynamic_instr_limit = 0; -uint64_t dynamic_instr_limit_input = 0; //0 means no limit - -#define MAX_SRC 4 -/* information collected in the instrumentation function */ -typedef struct { - int cta_id_x; - int cta_id_y; - int cta_id_z; - int warpid_tb; - int warpid_sm; - int sm_id; - int opcode_id; - uint64_t addrs[32]; - uint32_t vpc; - bool is_mem; - int32_t GPRDst; - int32_t GPRSrcs[MAX_SRC]; - int32_t numSrcs; - int32_t width; - uint32_t active_mask; - -} mem_access_t; - -/* Instrumentation function that we want to inject, please note the use of - * 1. extern "C" __device__ __noinline__ - * To prevent "dead"-code elimination by the compiler. - * 2. NVBIT_EXPORT_FUNC(dev_func) - * To notify nvbit the name of the function we want to inject. - * This name must match exactly the function name. - */ -extern "C" __device__ __noinline__ void instrument_mem(int pred, int opcode_id, int32_t vpc, - uint32_t reg_high, - uint32_t reg_low, - int32_t imm, - int32_t srcReg1, int32_t srcReg2, int32_t desReg, int32_t width) { - if (!pred) { - return; - } - - uint32_t active_mask = __ballot(1); - const int laneid = get_laneid(); - const int first_laneid = __ffs(active_mask) - 1; - - if (dynamic_instr_limit && total_dynamic_instr_counter >= dynamic_instr_limit) - if (first_laneid == laneid) { - atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); - return; - } - - mem_access_t ma; - - /* collect memory address information */ - int64_t base_addr = (((uint64_t)reg_high) << 32) | ((uint64_t)reg_low); - uint64_t addr = base_addr + imm; - for (int i = 0; i < 32; i++) { - ma.addrs[i] = __shfl(addr, i); - } - - int4 cta = get_ctaid(); - int uniqe_threadId = threadIdx.z * blockDim.y * blockDim.x + threadIdx.y * blockDim.x + threadIdx.x; - ma.warpid_tb = uniqe_threadId/32; - - ma.cta_id_x = cta.x; - ma.cta_id_y = cta.y; - ma.cta_id_z = cta.z; - ma.warpid_sm = get_warpid(); - ma.opcode_id = opcode_id; - ma.is_mem = true; - ma.vpc = vpc; - ma.width = width; - ma.GPRDst = desReg; - ma.GPRSrcs[0] = srcReg1; - ma.GPRSrcs[1] = srcReg2; - ma.GPRSrcs[2] = -1; - ma.GPRSrcs[3] = -1; - ma.numSrcs = 2; - ma.active_mask = active_mask; - ma.sm_id = get_smid(); - - /* first active lane pushes information on the channel */ - if (first_laneid == laneid) { - channel_dev.push(&ma, sizeof(mem_access_t)); - atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); - atomicAdd((unsigned long long*)&reported_dynamic_instr_counter, 1); - } -} -NVBIT_EXPORT_FUNC(instrument_mem); - - -extern "C" __device__ __noinline__ void instrument_inst(int pred, int opcode_id, - uint32_t vpc, int desReg, int srcReg1, int srcReg2, int srcReg3, int srcReg4, int srcNum) { - if (!pred) { - return; - } - - int active_mask = __ballot(1); - const int laneid = get_laneid(); - const int first_laneid = __ffs(active_mask) - 1; - - if (dynamic_instr_limit && total_dynamic_instr_counter >= dynamic_instr_limit) - if (first_laneid == laneid) { - atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); - return; - } - - - mem_access_t ma; - - int4 cta = get_ctaid(); - int uniqe_threadId = threadIdx.z * blockDim.y * blockDim.x + threadIdx.y * blockDim.x + threadIdx.x; - ma.warpid_tb = uniqe_threadId/32; - - ma.cta_id_x = cta.x; - ma.cta_id_y = cta.y; - ma.cta_id_z = cta.z; - ma.warpid_sm = get_warpid(); - ma.opcode_id = opcode_id; - ma.is_mem = false; - ma.vpc = vpc; - - ma.GPRDst = desReg; - ma.numSrcs = srcNum; //this is the total src number including the register and others - ma.GPRSrcs[0] = srcReg1; - ma.GPRSrcs[1] = srcReg2; - ma.GPRSrcs[2] = srcReg3; - ma.GPRSrcs[3] = srcReg4; - - ma.active_mask = active_mask; - ma.sm_id = get_smid(); - - /* first active lane pushes information on the channel */ - if (first_laneid == laneid) { - channel_dev.push(&ma, sizeof(mem_access_t)); - atomicAdd((unsigned long long*)&total_dynamic_instr_counter, 1); - atomicAdd((unsigned long long*)&reported_dynamic_instr_counter, 1); - } -} - -NVBIT_EXPORT_FUNC(instrument_inst); - -void nvbit_at_init() { - setenv("CUDA_MANAGED_FORCE_DEVICE_ALLOC", "1", 1); - GET_VAR_INT( - instr_begin_interval, "INSTR_BEGIN", 0, - "Beginning of the instruction interval where to apply instrumentation"); - GET_VAR_INT( - instr_end_interval, "INSTR_END", UINT32_MAX, - "End of the instruction interval where to apply instrumentation"); - GET_VAR_LONG( - dynamic_instr_limit_input, "DYNAMIC_INSTR_LIMIT", 0, - "Limit of the number instructions to be printed, 0 means no limit"); - GET_VAR_INT(verbose, "TOOL_VERBOSE", 0, "Enable verbosity inside the tool"); - std::string pad(100, '-'); - printf("%s\n", pad.c_str()); -} - -/* instrument each memory instruction adding a call to the above instrumentation - * function */ -void nvbit_at_function_first_load(CUcontext ctx, CUfunction f) { - - dynamic_instr_limit = dynamic_instr_limit_input; - - const std::vector &instrs = nvbit_get_instrs(ctx, f); - if (verbose) { - printf("Inspecting function %s at address 0x%lx\n", - nvbit_get_func_name(ctx, f), nvbit_get_func_addr(f)); - } - - uint32_t cnt = 0; - /* iterate on all the static instructions in the function */ - for (auto instr : instrs) { - if (cnt < instr_begin_interval || cnt >= instr_end_interval ) { - cnt++; - continue; - } - //if (verbose) { - instr->printDecoded(); - //} - - if (opcode_to_id_map.find(instr->getOpcode()) == - opcode_to_id_map.end()) { - int opcode_id = opcode_to_id_map.size(); - opcode_to_id_map[instr->getOpcode()] = opcode_id; - id_to_opcode_map[opcode_id] = instr->getOpcode(); - } - - int opcode_id = opcode_to_id_map[instr->getOpcode()]; - - //TO DO: handle generic and TEX memory space - if(instr->isLoad() && !instr->isStore() && instr->getMemOpType() != Instr::CONSTANT) { //Mem load inst //ignore constant for now - assert(instr->getNumOperands() == 2); - - /* get the operand */ - const Instr::operand_t *dst = instr->getOperand(0); - const Instr::operand_t *src = instr->getOperand(1); - - assert(dst->type == Instr::REG); - assert(src->type == Instr::MREF); - - /* insert call to the instrumentation function with its - * arguments */ - nvbit_insert_call(instr, "instrument_mem", IPOINT_BEFORE); - nvbit_add_call_arg_pred_val(instr); - nvbit_add_call_arg_const_val32(instr, opcode_id); - nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); - if (instr->isExtended()) { - nvbit_add_call_arg_reg_val(instr, (int)src->value[0] + 1); - } else { - nvbit_add_call_arg_reg_val(instr, (int)Instr::RZ); - } - nvbit_add_call_arg_reg_val(instr, (int)src->value[0]); - nvbit_add_call_arg_const_val32(instr, (int)src->value[1]); - nvbit_add_call_arg_const_val32(instr, (int)src->value[0]); - nvbit_add_call_arg_const_val32(instr, -1); - nvbit_add_call_arg_const_val32(instr, (int)dst->value[0]); - nvbit_add_call_arg_const_val32(instr, (int)instr->getSize()); - } - else if(instr->isStore() && !instr->isLoad() && instr->getMemOpType() != Instr::CONSTANT) { //Mem store inst //ignore constant for now - assert(instr->getNumOperands() == 2); - - /* get the operand */ - const Instr::operand_t *dst = instr->getOperand(0); - const Instr::operand_t *src = instr->getOperand(1); - - assert(dst->type == Instr::MREF); - assert(src->type == Instr::REG); - - /* insert call to the instrumentation function with its - * arguments */ - nvbit_insert_call(instr, "instrument_mem", IPOINT_BEFORE); - nvbit_add_call_arg_pred_val(instr); - nvbit_add_call_arg_const_val32(instr, opcode_id); - nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); - if (instr->isExtended()) { - nvbit_add_call_arg_reg_val(instr, (int)dst->value[0] + 1); - } else { - nvbit_add_call_arg_reg_val(instr, (int)Instr::RZ); - } - nvbit_add_call_arg_reg_val(instr, (int)dst->value[0]); - nvbit_add_call_arg_const_val32(instr, (int)dst->value[1]); - nvbit_add_call_arg_const_val32(instr, (int)dst->value[0]); - nvbit_add_call_arg_const_val32(instr, (int)src->value[0]); - nvbit_add_call_arg_const_val32(instr, -1); - nvbit_add_call_arg_const_val32(instr, (int)instr->getSize()); - } - else if(instr->isLoad() && instr->isStore() && instr->getMemOpType() != Instr::CONSTANT) { //if it is load and store i.e. atomic inst - assert(instr->getNumOperands() == 2); - - /* get the operand */ - const Instr::operand_t *dst = instr->getOperand(0); - const Instr::operand_t *src = instr->getOperand(1); - - assert(dst->type == Instr::MREF); - assert(src->type == Instr::REG); - - /* insert call to the instrumentation function with its - * arguments */ - nvbit_insert_call(instr, "instrument_mem", IPOINT_BEFORE); - nvbit_add_call_arg_pred_val(instr); - nvbit_add_call_arg_const_val32(instr, opcode_id); - nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); - if (instr->isExtended()) { - nvbit_add_call_arg_reg_val(instr, (int)dst->value[0] + 1); - } else { - nvbit_add_call_arg_reg_val(instr, (int)Instr::RZ); - } - nvbit_add_call_arg_reg_val(instr, (int)dst->value[0]); - nvbit_add_call_arg_const_val32(instr, (int)dst->value[1]); - nvbit_add_call_arg_const_val32(instr, (int)dst->value[0]); - nvbit_add_call_arg_const_val32(instr, (int)src->value[0]); - nvbit_add_call_arg_const_val32(instr, -1); - nvbit_add_call_arg_const_val32(instr, (int)instr->getSize()); - } - else //Other ALU, FP, DP insts - { - - nvbit_insert_call(instr, "instrument_inst", IPOINT_BEFORE); - nvbit_add_call_arg_pred_val(instr); - nvbit_add_call_arg_const_val32(instr, opcode_id); - nvbit_add_call_arg_const_val32(instr, (int)instr->getOffset()); - int srcNum = 0; - for (int i = 0; i < MAX_SRC+1; i++) { - /* get the operand "i" */ - if(i < instr->getNumOperands()) { - const Instr::operand_t *op = instr->getOperand(i); - if (op->type == Instr::REG) - nvbit_add_call_arg_const_val32(instr, (int)op->value[0]); - else - nvbit_add_call_arg_const_val32(instr, -1); - - srcNum++; - } - else - nvbit_add_call_arg_const_val32(instr, -1); - } - nvbit_add_call_arg_const_val32(instr, srcNum); - } - cnt++; - } -} - -__global__ void flush_channel() { - /* push memory access with negative cta id to communicate the kernel is - * completed */ - mem_access_t ma; - ma.cta_id_x = -1; - channel_dev.push(&ma, sizeof(mem_access_t)); - - /* flush channel */ - channel_dev.flush(); -} - -static FILE *resultsFile = NULL; -static FILE *kernelsFile= NULL; -static FILE *statsFile= NULL; -static int kernelid = 1; - -unsigned old_total_insts = 0; -unsigned old_total_reported_insts = 0; - - -void nvbit_at_cuda_event(CUcontext ctx, int is_exit, nvbit_api_cuda_t cbid, - const char *name, void *params, CUresult *pStatus) { - if (skip_flag) return; - - if (cbid == API_CUDA_cuLaunchKernel_ptsz || - cbid == API_CUDA_cuLaunchKernel) { - cuLaunchKernel_params *p = (cuLaunchKernel_params *)params; - - if (!is_exit) { - - - if (mkdir("traces", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) { - if( errno == EEXIST ) { - // alredy exists - } else { - // something else - std::cout << "cannot create folder error:" << strerror(errno) << std::endl; - return; - } - } - - int nregs; - _cuda_safe( - cuFuncGetAttribute(&nregs, CU_FUNC_ATTRIBUTE_NUM_REGS, p->f)); - - int shmem_static_nbytes; - _cuda_safe(cuFuncGetAttribute(&shmem_static_nbytes, - CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES, - p->f)); - - - - std::string func_name(nvbit_get_func_name(ctx, p->f)); - std::string::size_type end_pos = func_name.find('('); - if (end_pos != std::string::npos) - { - // std::string::size_type pos = func_name.find('<'); - //if (pos != std::string::npos) - // end_pos = pos; - - //std::string::size_type start_pos = func_name.find(' '); - //if (start_pos == std::string::npos) - // start_pos = 0; - //else - // start_pos++; - - func_name = func_name.substr(0, end_pos); - } - - char buffer[1024]; - sprintf (buffer, "./traces/%d-%s.trace", kernelid, func_name.c_str()); - - resultsFile = fopen(buffer, "w"); - - printf("Writing results to %s\n", buffer); - - fprintf(resultsFile, "-kernel name = %s", nvbit_get_func_name(ctx, p->f)); - fprintf(resultsFile, "\n"); - fprintf(resultsFile, "-kernel id = %d", kernelid); - fprintf(resultsFile, "\n"); - fprintf(resultsFile, "-grid dim = (%d,%d,%d)", p->gridDimX, p->gridDimY, p->gridDimZ); - fprintf(resultsFile, "\n"); - fprintf(resultsFile, "-block dim = (%d,%d,%d)", p->blockDimX, p->blockDimY, p->blockDimZ); - fprintf(resultsFile, "\n"); - fprintf(resultsFile, "-shmem = %d", shmem_static_nbytes + p->sharedMemBytes); - fprintf(resultsFile, "\n"); - fprintf(resultsFile, "-nregs = %d", nregs); - fprintf(resultsFile, "\n"); - fprintf(resultsFile, "-cuda stream id = %d", (uint64_t)p->hStream); - fprintf(resultsFile, "\n\n"); - - fprintf(resultsFile, "#traces format = threadblock_x threadblock_y threadblock_z warpid_tb sm_id warpid_sm PC mask dest_num reg_dests opcode src_num reg_srcs mem_width mem_addresses"); - fprintf(resultsFile, "\n"); - - if (kernelid == 1) { - kernelsFile = fopen("./traces/kernelslist", "w"); - statsFile = fopen("./traces/stats.csv", "w"); - fprintf(statsFile, "kernel name,total_insts,total_reported_insts\n"); - } - else { - kernelsFile = fopen("./traces/kernelslist", "a"); - statsFile = fopen("./traces/stats.csv", "a"); - } - - sprintf (buffer, "%d-%s.trace", kernelid, func_name.c_str()); - fprintf(kernelsFile, buffer); - fprintf(kernelsFile, "\n"); - fclose(kernelsFile); - - fprintf(statsFile, buffer); - fprintf(statsFile, ","); - - kernelid++; - recv_thread_receiving = true; - - } else { - /* make sure current kernel is completed */ - cudaDeviceSynchronize(); - assert(cudaGetLastError() == cudaSuccess); - - /* make sure we prevent re-entry on the nvbit_callback when issuing - * the flush_channel kernel */ - skip_flag = true; - - /* issue flush of channel so we are sure all the memory accesses - * have been pushed */ - flush_channel<<<1, 1>>>(); - cudaDeviceSynchronize(); - assert(cudaGetLastError() == cudaSuccess); - - /* unset the skip flag */ - skip_flag = false; - - /* wait here until the receiving thread has not finished with the - * current kernel */ - while (recv_thread_receiving) { - pthread_yield(); - } - - unsigned total_insts_per_kernel = total_dynamic_instr_counter - old_total_insts; - old_total_insts = total_dynamic_instr_counter; - - unsigned reported_insts_per_kernel = reported_dynamic_instr_counter - old_total_reported_insts; - old_total_reported_insts = reported_dynamic_instr_counter; - - fprintf(statsFile, ""); - fprintf(statsFile, "%d,%d",total_insts_per_kernel,reported_insts_per_kernel); - fprintf(statsFile, "\n"); - - - fclose(resultsFile); - fclose(statsFile); - } - } -} - -bool is_number(const std::string& s) -{ - std::string::const_iterator it = s.begin(); - while (it != s.end() && std::isdigit(*it)) ++it; - return !s.empty() && it == s.end(); -} - -void *recv_thread_fun(void *) { - char *recv_buffer = (char *)malloc(CHANNEL_SIZE); - - while (recv_thread_started) { - uint32_t num_recv_bytes = 0; - if (recv_thread_receiving && - (num_recv_bytes = channel_host.recv(recv_buffer, CHANNEL_SIZE)) > - 0) { - uint32_t num_processed_bytes = 0; - while (num_processed_bytes < num_recv_bytes) { - mem_access_t *ma = - (mem_access_t *)&recv_buffer[num_processed_bytes]; - - /* when we get this cta_id_x it means the kernel has completed - */ - if (ma->cta_id_x == -1) { - recv_thread_receiving = false; - break; - } - - fprintf(resultsFile, "%d ", ma->cta_id_x); - fprintf(resultsFile, "%d ", ma->cta_id_y); - fprintf(resultsFile, "%d ", ma->cta_id_z); - fprintf(resultsFile, "%d ", ma->warpid_tb); - fprintf(resultsFile, "%d ", ma->sm_id); - fprintf(resultsFile, "%d ", ma->warpid_sm); - fprintf(resultsFile, "0x%016lx ", ma->vpc); // Print the virtual PC. - fprintf(resultsFile, "%-8.8" PRIx32 " ", ma->active_mask); - if(ma->GPRDst >= 0) { - fprintf(resultsFile, "1 "); - fprintf(resultsFile, "R%d ", ma->GPRDst); - } - else - fprintf(resultsFile, "0 "); - - // Print the opcode. - fprintf(resultsFile, "%s ", id_to_opcode_map[ma->opcode_id].c_str()); - unsigned src_count=0; - for (int s = 0; s < MAX_SRC; s++) // GPR srcs count. - if(ma->GPRSrcs[s] >= 0) src_count++; - fprintf(resultsFile, "%d ", src_count); - - for (int s = 0; s < MAX_SRC; s++) // GPR srcs. - if(ma->GPRSrcs[s] >= 0) fprintf(resultsFile, "R%d ", ma->GPRSrcs[s]); - - //print addresses - std::bitset<32> mask(ma->active_mask); - if(ma->is_mem) { - //fprintf(resultsFile, "%d ", ma->width); - std::istringstream iss(id_to_opcode_map[ma->opcode_id]); - std::vector tokens; - std::string token; - while (std::getline(iss, token, '.')) { - if (!token.empty()) - tokens.push_back(token); - } - if (tokens.size()>=3){ - if (is_number(tokens[2])){ - fprintf(resultsFile, "%d ", (std::stoi(tokens[2],nullptr)/8)); - } - else{ - fprintf(resultsFile, "%d ", 4); - } - } - else{ - fprintf(resultsFile, "%d ", 4); - } - - for (int s = 0; s < 32; s++) - if(mask.test(s)) - fprintf(resultsFile, "0x%016lx ", ma->addrs[s]); - } - else - { - fprintf(resultsFile, "0 "); - } - - fprintf(resultsFile, "\n"); - - num_processed_bytes += sizeof(mem_access_t); - } - } - } - free(recv_buffer); - return NULL; -} - -void nvbit_at_ctx_init(CUcontext ctx) { - recv_thread_started = true; - channel_host.init(0, CHANNEL_SIZE, &channel_dev, NULL); - pthread_create(&recv_thread, NULL, recv_thread_fun, NULL); -} - -void nvbit_at_ctx_term(CUcontext ctx) { - if (recv_thread_started) { - recv_thread_started = false; - pthread_join(recv_thread, NULL); - } -} diff --git a/src/trace-driven/traces-generator/README b/src/trace-driven/traces-generator/README deleted file mode 100644 index d79d075..0000000 --- a/src/trace-driven/traces-generator/README +++ /dev/null @@ -1 +0,0 @@ -TO DO diff --git a/src/trace-driven/traces-generator/traces-post-processing/Makefile b/src/trace-driven/traces-generator/traces-post-processing/Makefile deleted file mode 100755 index 63c3f38..0000000 --- a/src/trace-driven/traces-generator/traces-post-processing/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -TARGET := post-traces-processing - -$(TARGET): post-traces-processing.cpp - g++ -o $@ $^ - -run: $(TARGET) - ./$(TARGET) - -clean: - rm -f $(TARGET) *.o - diff --git a/src/trace-driven/traces-generator/traces-post-processing/post-traces-processing.cpp b/src/trace-driven/traces-generator/traces-post-processing/post-traces-processing.cpp deleted file mode 100644 index 0dbb4e1..0000000 --- a/src/trace-driven/traces-generator/traces-post-processing/post-traces-processing.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -using namespace std; - -struct threadblock_info -{ - bool initialized; - unsigned tb_id_x, tb_id_y, tb_id_z; - vector< vector< string > > warp_insts_array; - threadblock_info() { - initialized = false; - tb_id_x = tb_id_y = tb_id_z = 0; - } -}; - -void group_per_block(const char* filepath); -void group_per_core(const char* filepath); - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int main(int argc, char** argv) -{ - - string kernellist_filepath; - bool is_per_core; - if(argc == 1) - { - cout << "File path is missing\n"; - return 0; - } else if(argc == 2) - { - kernellist_filepath = argv[1]; - is_per_core = true; - - } else if(argc == 3) { - kernellist_filepath = argv[1]; - is_per_core = bool(argv[2]); - } - else { - cout << "Too Many Arguemnts!\n"; - return 0; - } - - ifstream ifs; - ofstream ofs; - - ifs.open(kernellist_filepath.c_str()); - ofs.open((string(kernellist_filepath) + ".g").c_str()); - - if (!ifs.is_open()) { - cout << "Unable to open file: " < insts; - unsigned grid_dim_x, grid_dim_y, grid_dim_z, tb_dim_x, tb_dim_y, tb_dim_z; - unsigned tb_id_x, tb_id_y, tb_id_z, tb_id, warpid_tb; - string line; - stringstream ss; - string string1, string2; - bool found_grid_dim = false, found_block_dim = false; - - while(!ifs.eof()) { - getline(ifs, line); - - if (line.length() == 0 || line[0] == '#') { - ofs<>string1>>string2; - if(string1 == "grid" && string2 == "dim") { - sscanf(line.c_str(), "-grid dim = (%d,%d,%d)", &grid_dim_x, &grid_dim_y, &grid_dim_z); - found_grid_dim = true; - } - else if (string1 == "block" && string2 == "dim") { - sscanf(line.c_str(), "-block dim = (%d,%d,%d)", &tb_dim_x, &tb_dim_y, &tb_dim_z); - found_block_dim = true; - } - - if(found_grid_dim && found_block_dim) { - insts.resize(grid_dim_x*grid_dim_y*grid_dim_z); - for(unsigned i = 0; i>tb_id_x>>tb_id_y>>tb_id_z>>warpid_tb; - tb_id = tb_id_z * grid_dim_y * grid_dim_x + tb_id_y * grid_dim_x + tb_id_x; - if(!insts[tb_id].initialized) { - insts[tb_id].tb_id_x = tb_id_x; - insts[tb_id].tb_id_y = tb_id_y; - insts[tb_id].tb_id_z = tb_id_z; - insts[tb_id].initialized = true; - } - insts[tb_id].warp_insts_array[warpid_tb].push_back(line); - } - - } - - - for(unsigned i=0; i 0) { - ofs< -#include - -//TO DO: moving this to a yml or def files - - -#define TURING_BINART_VERSION 72 - -///Tuing SM_72 ISA -//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map Turing_OpcodeMap = { - -//TO fill - -}; - -#endif diff --git a/src/trace-driven/volta_opcode.h b/src/trace-driven/volta_opcode.h deleted file mode 100644 index 3d03201..0000000 --- a/src/trace-driven/volta_opcode.h +++ /dev/null @@ -1,176 +0,0 @@ -//developed by Mahmoud Khairy, Purdue Univ -//abdallm@purdue.edu - -#ifndef VOLTA_OPCODE_H -#define VOLTA_OPCODE_H - -#include "../abstract_hardware_model.h" -#include "trace_opcode.h" -#include -#include - -#define VOLTA_BINART_VERSION 70 -#define VOLTA_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 - -//TO DO: moving this to a yml or def files - -///Volta SM_70 ISA -//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map Volta_OpcodeMap = { - //Floating Point 32 Instructions - {"FADD", OpcodeChar(OP_FADD, SP_OP)}, - {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, - {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, - {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, - {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, - {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, - {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, - {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, - {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, - {"FSET", OpcodeChar(OP_FSET, SP_OP)}, - {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, - {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, - //SFU - {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, - - //Floating Point 16 Instructions - {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, - {"HADD2_32I", OpcodeChar(OP_HADD2_32I, SP_OP)}, - {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, - {"HFMA2_32I", OpcodeChar(OP_HFMA2_32I, SP_OP)}, - {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, - {"HMUL2_32I", OpcodeChar(OP_HMUL2_32I, SP_OP)}, - {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, - {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, - - //Tensor Core Instructions - {"HMMA", OpcodeChar(OP_HMMA, TENSOR_CORE_OP)}, - - //Double Point Instructions - {"DADD", OpcodeChar(OP_DADD, DP_OP)}, - {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, - {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, - {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, - - //Integer Instructions - {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, - {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, - {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, - {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, - {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, - {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, - {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, - {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, - {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, - {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, - {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, - {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, - {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, - {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, - {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, - {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, - {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, - {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, - {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, - {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, - {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, - {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, - {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, - {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, - {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, - {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, - - //Conversion Instructions - {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, - {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, - {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, - {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, - {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, - {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, - - //Movement Instructions - {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, - {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, - {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, - {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, - {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, - {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, - - //Predicate Instructions - {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, - {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, - {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, - {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, - - //Load/Store Instructions - {"LD", OpcodeChar(OP_LD, LOAD_OP)}, - //For now, we ignore constant loads, consider it as ALU_OP, TO DO - {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, - {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, - {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, - {"ST", OpcodeChar(OP_ST, STORE_OP)}, - {"STG", OpcodeChar(OP_STG, STORE_OP)}, - {"STL", OpcodeChar(OP_STL, STORE_OP)}, - {"STS", OpcodeChar(OP_STS, STORE_OP)}, - {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, - {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, - {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, - {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, - {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, - {"RED", OpcodeChar(OP_RED, STORE_OP)}, - {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, - {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, - {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, - {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, - {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, - - //Texture Instructions - //For now, we ignore texture loads, consider it as ALU_OP - {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, - {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, - {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, - {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, - {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, - {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, - - //Control Instructions - {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, - {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, - {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, - {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, - {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, - {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, - {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, - {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, - {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, - {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, - {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, - {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, - {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, - {"RET", OpcodeChar(OP_RET, RET_OPS)}, - {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, - {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, - {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, - {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, - - //Miscellaneous Instructions - {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, - {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, - {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, - {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, - {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, - {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, - {"LEPC", OpcodeChar(OP_LEPC ,ALU_OP)}, - {"NOP", OpcodeChar(OP_NOP ,ALU_OP)}, - {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, - {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, - {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, - {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, - {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, - {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, - {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, - -}; - -#endif -- cgit v1.3 From 47e1a8a3a45203c34a93672a1b1bd742dc193183 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Sat, 23 May 2020 22:45:28 -0400 Subject: code refomratting --- format-code.sh | 3 + libcuda/gpgpu_context.h | 2 +- src/abstract_hardware_model.cc | 48 +- src/abstract_hardware_model.h | 15 +- src/cuda-sim/cuda_device_runtime.h | 2 +- src/cuda-sim/ptx-stats.cc | 32 +- src/cuda-sim/ptx_ir.h | 15 +- src/cuda-sim/ptx_loader.cc | 3 +- src/cuda-sim/ptx_parser.cc | 5 +- src/gpgpu-sim/addrdec.cc | 145 +-- src/gpgpu-sim/addrdec.h | 4 +- src/gpgpu-sim/dram.cc | 48 +- src/gpgpu-sim/dram.h | 2 +- src/gpgpu-sim/gpu-cache.cc | 35 +- src/gpgpu-sim/gpu-sim.cc | 196 ++-- src/gpgpu-sim/gpu-sim.h | 19 +- src/gpgpu-sim/icnt_wrapper.cc | 22 +- src/gpgpu-sim/l2cache.cc | 6 +- src/gpgpu-sim/local_interconnect.cc | 225 +++-- src/gpgpu-sim/local_interconnect.h | 25 +- src/gpgpu-sim/mem_fetch.cc | 8 +- src/gpgpu-sim/mem_fetch.h | 6 +- src/gpgpu-sim/mem_latency_stat.cc | 13 +- src/gpgpu-sim/shader.cc | 418 ++++---- src/gpgpu-sim/shader.h | 29 +- src/gpgpusim_entrypoint.cc | 62 +- src/trace-driven/ISA_Def/kepler_opcode.h | 273 +++-- src/trace-driven/ISA_Def/pascal_opcode.h | 370 ++++--- src/trace-driven/ISA_Def/trace_opcode.h | 215 +++- src/trace-driven/ISA_Def/turing_opcode.h | 19 +- src/trace-driven/ISA_Def/volta_opcode.h | 324 +++--- src/trace-driven/gpgpusim_trace_driven_main.cc | 210 ++-- src/trace-driven/trace_driven.cc | 1262 ++++++++++++------------ src/trace-driven/trace_driven.h | 239 ++--- 34 files changed, 2268 insertions(+), 2032 deletions(-) (limited to 'src') diff --git a/format-code.sh b/format-code.sh index 39c24e4..fb1cc90 100755 --- a/format-code.sh +++ b/format-code.sh @@ -10,3 +10,6 @@ clang-format -i ${THIS_DIR}/src/cuda-sim/*.h clang-format -i ${THIS_DIR}/src/cuda-sim/*.cc clang-format -i ${THIS_DIR}/src/gpuwattch/*.h clang-format -i ${THIS_DIR}/src/gpuwattch/*.cc +clang-format -i ${THIS_DIR}/src/trace-driven/*.h +clang-format -i ${THIS_DIR}/src/trace-driven/*.cc +clang-format -i ${THIS_DIR}/src/trace-driven/ISA_Def/*.h diff --git a/libcuda/gpgpu_context.h b/libcuda/gpgpu_context.h index 7c58890..f02e365 100644 --- a/libcuda/gpgpu_context.h +++ b/libcuda/gpgpu_context.h @@ -77,7 +77,7 @@ class gpgpu_context { const ptx_instruction *pc_to_instruction(unsigned pc); const warp_inst_t *ptx_fetch_inst(address_type pc); unsigned translate_pc_to_ptxlineno(unsigned pc); - class gpgpu_sim *gpgpu_trace_sim_init_perf(int argc, const char *argv[]); + class gpgpu_sim *gpgpu_trace_sim_init_perf(int argc, const char *argv[]); }; gpgpu_context *GPGPU_Context(); diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index 29df769..1247235 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -536,30 +536,30 @@ void warp_inst_t::memory_coalescing_arch(bool is_write, transaction_info &info = subwarp_transactions[block_address]; // can only write to one segment - //it seems like in trace driven, a thread can write to more than one segment - //assert(block_address == line_size_based_tag_func(addr+data_size_coales-1,segment_size)); + // it seems like in trace driven, a thread can write to more than one + // segment assert(block_address == + // line_size_based_tag_func(addr+data_size_coales-1,segment_size)); info.chunks.set(chunk); info.active.set(thread); unsigned idx = (addr & 127); - for( unsigned i=0; i < data_size_coales; i++ ) - if((idx+i) < MAX_MEMORY_ACCESS_SIZE) - info.bytes.set(idx+i); - - //it seems like in trace driven, a thread can write to more than one segment - //handle this special case - if(block_address != line_size_based_tag_func(addr+data_size_coales-1,segment_size)) { - addr = addr+data_size_coales-1; - unsigned block_address = line_size_based_tag_func(addr,segment_size); - unsigned chunk = (addr&127)/32; - transaction_info &info = subwarp_transactions[block_address]; - info.chunks.set(chunk); - info.active.set(thread); - unsigned idx = (addr&127); - for( unsigned i=0; i < data_size_coales; i++ ) - if((idx+i) < MAX_MEMORY_ACCESS_SIZE) - info.bytes.set(idx+i); - } + for (unsigned i = 0; i < data_size_coales; i++) + if ((idx + i) < MAX_MEMORY_ACCESS_SIZE) info.bytes.set(idx + i); + + // it seems like in trace driven, a thread can write to more than one + // segment handle this special case + if (block_address != line_size_based_tag_func( + addr + data_size_coales - 1, segment_size)) { + addr = addr + data_size_coales - 1; + unsigned block_address = line_size_based_tag_func(addr, segment_size); + unsigned chunk = (addr & 127) / 32; + transaction_info &info = subwarp_transactions[block_address]; + info.chunks.set(chunk); + info.active.set(thread); + unsigned idx = (addr & 127); + for (unsigned i = 0; i < data_size_coales; i++) + if ((idx + i) < MAX_MEMORY_ACCESS_SIZE) info.bytes.set(idx + i); + } } } @@ -763,7 +763,9 @@ kernel_info_t::kernel_info_t(dim3 gridDim, dim3 blockDim, // Jin: launch latency management m_launch_latency = entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency; - m_kernel_TB_latency = entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency + num_blocks() * entry->gpgpu_ctx->device_runtime->g_TB_launch_latency; + m_kernel_TB_latency = + entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency + + num_blocks() * entry->gpgpu_ctx->device_runtime->g_TB_launch_latency; cache_config_set = false; } @@ -792,7 +794,9 @@ kernel_info_t::kernel_info_t( // Jin: launch latency management m_launch_latency = entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency; - m_kernel_TB_latency = entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency + num_blocks() * entry->gpgpu_ctx->device_runtime->g_TB_launch_latency; + m_kernel_TB_latency = + entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency + + num_blocks() * entry->gpgpu_ctx->device_runtime->g_TB_launch_latency; cache_config_set = false; m_NameToCudaArray = nameToCudaArray; diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index a640ba3..ef457a7 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -65,11 +65,7 @@ enum FuncCache { FuncCachePreferL1 = 2 }; -enum AdaptiveCache -{ - FIXED = 0, - ADAPTIVE_VOLTA = 1 -}; +enum AdaptiveCache { FIXED = 0, ADAPTIVE_VOLTA = 1 }; #ifdef __cplusplus @@ -101,8 +97,8 @@ enum uarch_op_t { BARRIER_OP, MEMORY_BARRIER_OP, CALL_OPS, - RET_OPS, - EXIT_OPS + RET_OPS, + EXIT_OPS }; typedef enum uarch_op_t op_type; @@ -328,11 +324,12 @@ class kernel_info_t { unsigned long long launch_cycle; unsigned long long start_cycle; unsigned long long end_cycle; - unsigned m_launch_latency; + unsigned m_launch_latency; mutable bool cache_config_set; - unsigned m_kernel_TB_latency; //this used for any CPU-GPU kernel latency and counted in the gpu_cycle + unsigned m_kernel_TB_latency; // this used for any CPU-GPU kernel latency and + // counted in the gpu_cycle }; class core_config { diff --git a/src/cuda-sim/cuda_device_runtime.h b/src/cuda-sim/cuda_device_runtime.h index 4ede31a..b06dd24 100644 --- a/src/cuda-sim/cuda_device_runtime.h +++ b/src/cuda-sim/cuda_device_runtime.h @@ -43,7 +43,7 @@ class cuda_device_runtime { std::map g_cuda_device_launch_param_map; std::list g_cuda_device_launch_op; unsigned g_kernel_launch_latency; - unsigned g_TB_launch_latency; + unsigned g_TB_launch_latency; unsigned long long g_max_total_param_size; bool g_cdp_enabled; diff --git a/src/cuda-sim/ptx-stats.cc b/src/cuda-sim/ptx-stats.cc index 8661a29..3e96984 100644 --- a/src/cuda-sim/ptx-stats.cc +++ b/src/cuda-sim/ptx-stats.cc @@ -168,10 +168,10 @@ void ptx_file_line_stats_add_exec_count(const ptx_instruction *pInsn) { void ptx_stats::ptx_file_line_stats_add_latency(unsigned pc, unsigned latency) { const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); - if(pInsn != NULL) - ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), - pInsn->source_line())] - .latency += latency; + if (pInsn != NULL) + ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), + pInsn->source_line())] + .latency += latency; } // attribute dram traffic to this ptx instruction (specified by the pc) @@ -180,10 +180,10 @@ void ptx_stats::ptx_file_line_stats_add_dram_traffic(unsigned pc, unsigned dram_traffic) { const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); - if(pInsn != NULL) - ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), - pInsn->source_line())] - .dram_traffic += dram_traffic; + if (pInsn != NULL) + ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), + pInsn->source_line())] + .dram_traffic += dram_traffic; } // attribute the number of shared memory access cycles to a ptx instruction @@ -193,12 +193,12 @@ void ptx_stats::ptx_file_line_stats_add_smem_bank_conflict( unsigned pc, unsigned n_way_bkconflict) { const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); - if(pInsn != NULL) { - ptx_file_line_stats &line_stats = ptx_file_line_stats_tracker[ptx_file_line( - pInsn->source_file(), pInsn->source_line())]; + if (pInsn != NULL) { + ptx_file_line_stats &line_stats = ptx_file_line_stats_tracker[ptx_file_line( + pInsn->source_file(), pInsn->source_line())]; line_stats.smem_n_way_bank_conflict_total += n_way_bkconflict; line_stats.smem_warp_count += 1; - } + } } // attribute a non-coalesced mem access to a ptx instruction @@ -208,12 +208,12 @@ void ptx_stats::ptx_file_line_stats_add_uncoalesced_gmem(unsigned pc, unsigned n_access) { const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); - if(pInsn != NULL) { - ptx_file_line_stats &line_stats = ptx_file_line_stats_tracker[ptx_file_line( - pInsn->source_file(), pInsn->source_line())]; + if (pInsn != NULL) { + ptx_file_line_stats &line_stats = ptx_file_line_stats_tracker[ptx_file_line( + pInsn->source_file(), pInsn->source_line())]; line_stats.gmem_n_access_total += n_access; line_stats.gmem_warp_count += 1; - } + } } // a class that tracks the inflight memory instructions of a shader core diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index 67cf157..c649702 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -1336,13 +1336,12 @@ class function_info { memory_space *param_mem, gpgpu_t *gpu, dim3 gridDim, dim3 blockDim); - virtual 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; } - virtual 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(); @@ -1378,9 +1377,10 @@ class function_info { // 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; + 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; @@ -1405,7 +1405,8 @@ protected: std::map labels; unsigned num_reconvergence_pairs; - //Registers/shmem/etc. used (from ptxas -v), loaded from ___.ptxinfo along with ___.ptx + // Registers/shmem/etc. used (from ptxas -v), loaded from ___.ptxinfo along + // with ___.ptx // with ___.ptx symbol_table *m_symtab; diff --git a/src/cuda-sim/ptx_loader.cc b/src/cuda-sim/ptx_loader.cc index 0b217a6..4e91763 100644 --- a/src/cuda-sim/ptx_loader.cc +++ b/src/cuda-sim/ptx_loader.cc @@ -38,7 +38,8 @@ /// extern prototypes -extern int ptx_error( yyscan_t yyscanner, ptx_recognizer* recognizer, 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 a401ed6..2265587 100644 --- a/src/cuda-sim/ptx_parser.cc +++ b/src/cuda-sim/ptx_parser.cc @@ -36,7 +36,8 @@ 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, ptx_recognizer* recognizer, 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); @@ -225,7 +226,7 @@ void ptx_recognizer::parse_error_impl(const char *file, unsigned line, 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, this, NULL); + ptx_error(scanner, this, NULL); abort(); exit(1); } diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc index 3018d3a..91ba47f 100644 --- a/src/gpgpu-sim/addrdec.cc +++ b/src/gpgpu-sim/addrdec.cc @@ -27,8 +27,8 @@ // POSSIBILITY OF SUCH DAMAGE. #include "addrdec.h" -#include #include +#include #include "../option_parser.h" #include "gpu-sim.h" @@ -65,7 +65,9 @@ void linear_to_raw_address_translation::addrdec_setoption(option_parser_t opp) { "0 = old addressing mask, 1 = new addressing mask, 2 " "= new add. mask + flipped bank sel and chip sel bits", "0"); - option_parser_register(opp, "-gpgpu_memory_partition_indexing", OPT_UINT32, &memory_partition_indexing, + option_parser_register( + opp, "-gpgpu_memory_partition_indexing", OPT_UINT32, + &memory_partition_indexing, "0 = no indexing, 1 = bitwise xoring, 2 = IPoly, 3 = custom indexing", "0"); } @@ -89,7 +91,7 @@ new_addr_type linear_to_raw_address_translation::partition_address( void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_t *tlx) const { - unsigned long long int addr_for_chip, rest_of_addr, rest_of_addr_high_bits; + unsigned long long int addr_for_chip, rest_of_addr, rest_of_addr_high_bits; if (!gap) { tlx->chip = addrdec_packbits(addrdec_mask[CHIP], addr, addrdec_mkhigh[CHIP], addrdec_mklow[CHIP]); @@ -101,7 +103,8 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_mklow[COL]); tlx->burst = addrdec_packbits(addrdec_mask[BURST], addr, addrdec_mkhigh[BURST], addrdec_mklow[BURST]); - rest_of_addr_high_bits = (addr>>(ADDR_CHIP_S+(log2channel+log2sub_partition))); + rest_of_addr_high_bits = + (addr >> (ADDR_CHIP_S + (log2channel + log2sub_partition))); } else { // Split the given address at ADDR_CHIP_S into (MSBs,LSBs) @@ -110,7 +113,7 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, // the LSBs addr_for_chip = (addr >> ADDR_CHIP_S) % m_n_channel; rest_of_addr = ((addr >> ADDR_CHIP_S) / m_n_channel) << ADDR_CHIP_S; - rest_of_addr_high_bits = ((addr>>ADDR_CHIP_S) / m_n_channel); + rest_of_addr_high_bits = ((addr >> ADDR_CHIP_S) / m_n_channel); rest_of_addr |= addr & ((1 << ADDR_CHIP_S) - 1); tlx->chip = addr_for_chip; @@ -130,7 +133,7 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, break; case BITWISE_PERMUTATION: { assert(!gap); - tlx->chip = (tlx->chip) ^ (rest_of_addr_high_bits & (m_n_channel-1)); + tlx->chip = (tlx->chip) ^ (rest_of_addr_high_bits & (m_n_channel - 1)); assert(tlx->chip < m_n_channel); break; } @@ -139,29 +142,31 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, * Set Indexing function from "Pseudo-randomly interleaved memory." * Rau, B. R et al. * ISCA 1991 - * http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=348DEA37A3E440473B3C075EAABC63B6?doi=10.1.1.12.7149&rep=rep1&type=pdf + * http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=348DEA37A3E440473B3C075EAABC63B6?doi=10.1.1.12.7149&rep=rep1&type=pdf * - * equations are corresponding to IPOLY(37) and are adopted from: + * 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. - * - * equations for 32 banks are corresponding to IPOLY(37) - * equations for 64 banks are corresponding to IPOLY(67) - * To see all the IPOLY equations for all the degrees, see - * http://wireless-systems.ece.gatech.edu/6604/handouts/Peterson's%20Table.pdf - * - * We generate these equations using GF(2) arithmetic: - * http://www.ee.unb.ca/cgi-bin/tervo/calc.pl?num=&den=&f=d&e=1&m=1 - * - * We go through all the strides 128 (10000000), 256 (100000000),... and do modular arithmetic in GF(2) - * Then, we create the H-matrix and group each bit together, for more info read the ISCA 1991 paper - * - * IPOLY hashing guarantees conflict-free for all 2^n strides which widely exit in GPGPU applications - * and also show good performance for other strides. + * + * equations for 32 banks are corresponding to IPOLY(37) + * equations for 64 banks are corresponding to IPOLY(67) + * To see all the IPOLY equations for all the degrees, see + * http://wireless-systems.ece.gatech.edu/6604/handouts/Peterson's%20Table.pdf + * + * We generate these equations using GF(2) arithmetic: + * http://www.ee.unb.ca/cgi-bin/tervo/calc.pl?num=&den=&f=d&e=1&m=1 + * + * We go through all the strides 128 (10000000), 256 (100000000),... and + * do modular arithmetic in GF(2) Then, we create the H-matrix and group + * each bit together, for more info read the ISCA 1991 paper + * + * IPOLY hashing guarantees conflict-free for all 2^n strides which widely + * exit in GPGPU applications and also show good performance for other + * strides. */ - assert(!gap); - if(m_n_channel == 32 && m_n_sub_partition_in_channel == 1) { - std::bitset<64> a( rest_of_addr_high_bits); + assert(!gap); + if (m_n_channel == 32 && m_n_sub_partition_in_channel == 1) { + std::bitset<64> a(rest_of_addr_high_bits); std::bitset<5> chip(tlx->chip); chip[0] = a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[6] ^ a[5] ^ a[3] ^ a[0] ^ chip[0]; @@ -174,41 +179,55 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, chip[4] = a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[5] ^ a[4] ^ a[2] ^ chip[4]; tlx->chip = chip.to_ulong(); - break; - } else if (m_n_channel == 16 && m_n_sub_partition_in_channel==2) { - std::bitset<64> a( rest_of_addr_high_bits); - std::bitset<4> chip(tlx->chip); - std::bitset<32> bk(tlx->bk); - chip[0] = a[13]^a[12]^a[11]^a[10]^a[9]^a[6]^a[5]^a[3]^a[0]^chip[0]; - chip[1] = a[14]^a[13]^a[12]^a[11]^a[10]^a[7]^a[6]^a[4]^a[1]^chip[1]; - chip[2] = a[14]^a[10]^a[9]^a[8]^a[7]^a[6]^a[3]^a[2]^a[0]^chip[2]; - chip[3] = a[11]^a[10]^a[9]^a[8]^a[7]^a[4]^a[3]^a[1]^chip[3]; - tlx->chip = chip.to_ulong(); - unsigned par_id = a[12]^a[11]^a[10]^a[9]^a[8]^a[5]^a[4]^a[2]^bk[0]; - tlx->sub_partition = tlx->chip * m_n_sub_partition_in_channel + par_id; - assert(tlx->chip < m_n_channel); - assert(tlx->sub_partition < m_n_channel * m_n_sub_partition_in_channel); - return; - break; - } else if (m_n_channel == 32 && m_n_sub_partition_in_channel==2) { - std::bitset<64> a( rest_of_addr_high_bits); - std::bitset<5> chip(tlx->chip); - std::bitset<32> bk(tlx->bk); - chip[0] = a[18]^a[17]^a[16]^a[15]^a[12]^a[10]^a[6]^a[5]^a[0]^chip[0]; - chip[1] = a[15]^a[13]^a[12]^a[11]^a[10]^a[7]^a[5]^a[1]^a[0]^chip[1]; - chip[2] = a[16]^a[14]^a[13]^a[12]^a[11]^a[8]^a[6]^a[2]^a[1]^chip[2]; - chip[3] = a[17]^a[15]^a[14]^a[13]^a[12]^a[9]^a[7]^a[3]^a[2]^chip[3]; - chip[4] = a[18]^a[16]^a[15]^a[14]^a[13]^a[10]^a[8]^a[4]^a[3]^chip[4]; - tlx->chip = chip.to_ulong(); - unsigned par_id = a[17]^a[16]^a[15]^a[14]^a[11]^a[9]^a[5]^a[4]^bk[0]; - tlx->sub_partition = tlx->chip * m_n_sub_partition_in_channel + par_id; - assert(tlx->chip < m_n_channel); - assert(tlx->sub_partition < m_n_channel * m_n_sub_partition_in_channel); - return; - break; + break; + } else if (m_n_channel == 16 && m_n_sub_partition_in_channel == 2) { + std::bitset<64> a(rest_of_addr_high_bits); + std::bitset<4> chip(tlx->chip); + std::bitset<32> bk(tlx->bk); + chip[0] = a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[6] ^ a[5] ^ a[3] ^ + a[0] ^ chip[0]; + chip[1] = a[14] ^ a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[7] ^ a[6] ^ a[4] ^ + a[1] ^ chip[1]; + chip[2] = a[14] ^ a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[6] ^ a[3] ^ a[2] ^ + a[0] ^ chip[2]; + chip[3] = + a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[4] ^ a[3] ^ a[1] ^ chip[3]; + tlx->chip = chip.to_ulong(); + unsigned par_id = + a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[5] ^ a[4] ^ a[2] ^ bk[0]; + tlx->sub_partition = tlx->chip * m_n_sub_partition_in_channel + par_id; + assert(tlx->chip < m_n_channel); + assert(tlx->sub_partition < m_n_channel * m_n_sub_partition_in_channel); + return; + break; + } else if (m_n_channel == 32 && m_n_sub_partition_in_channel == 2) { + std::bitset<64> a(rest_of_addr_high_bits); + std::bitset<5> chip(tlx->chip); + std::bitset<32> bk(tlx->bk); + chip[0] = a[18] ^ a[17] ^ a[16] ^ a[15] ^ a[12] ^ a[10] ^ a[6] ^ a[5] ^ + a[0] ^ chip[0]; + chip[1] = a[15] ^ a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[7] ^ a[5] ^ a[1] ^ + a[0] ^ chip[1]; + chip[2] = a[16] ^ a[14] ^ a[13] ^ a[12] ^ a[11] ^ a[8] ^ a[6] ^ a[2] ^ + a[1] ^ chip[2]; + chip[3] = a[17] ^ a[15] ^ a[14] ^ a[13] ^ a[12] ^ a[9] ^ a[7] ^ a[3] ^ + a[2] ^ chip[3]; + chip[4] = a[18] ^ a[16] ^ a[15] ^ a[14] ^ a[13] ^ a[10] ^ a[8] ^ a[4] ^ + a[3] ^ chip[4]; + tlx->chip = chip.to_ulong(); + unsigned par_id = + a[17] ^ a[16] ^ a[15] ^ a[14] ^ a[11] ^ a[9] ^ a[5] ^ a[4] ^ bk[0]; + tlx->sub_partition = tlx->chip * m_n_sub_partition_in_channel + par_id; + assert(tlx->chip < m_n_channel); + assert(tlx->sub_partition < m_n_channel * m_n_sub_partition_in_channel); + return; + break; } else { /* Else incorrect number of channels for the hashing function */ - assert("\nGPGPU-Sim memory_partition_indexing error: The number of channels should be " - "32 or 64 for the hashing IPOLY index function.\n" && 0); + assert( + "\nGPGPU-Sim memory_partition_indexing error: The number of " + "channels should be " + "32 or 64 for the hashing IPOLY index function.\n" && + 0); } assert(tlx->chip < m_n_channel); break; @@ -218,7 +237,7 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, // random selected bits from the page and bank bits // similar to // Liu, Yuxi, et al. "Get Out of the Valley: Power-Efficient Address - assert(!gap); + assert(!gap); std::bitset<64> a(tlx->row); std::bitset<5> chip(tlx->chip); std::bitset<4> b(tlx->bk); @@ -234,7 +253,7 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, case RANDOM: { // This is an unrealistic hashing using software hashtable // we generate a random set for each memory address and save the value in - new_addr_type chip_address = (addr>>(ADDR_CHIP_S-log2sub_partition)); + new_addr_type chip_address = (addr >> (ADDR_CHIP_S - log2sub_partition)); tr1_hash_map::const_iterator got = address_random_interleaving.find(chip_address); if (got == address_random_interleaving.end()) { @@ -354,8 +373,8 @@ void linear_to_raw_address_translation::init( unsigned i; unsigned long long int mask; unsigned int nchipbits = ::LOGB2_32(n_channel); - log2channel = nchipbits; - log2sub_partition = ::LOGB2_32(n_sub_partition_in_channel); + log2channel = nchipbits; + log2sub_partition = ::LOGB2_32(n_sub_partition_in_channel); m_n_channel = n_channel; m_n_sub_partition_in_channel = n_sub_partition_in_channel; diff --git a/src/gpgpu-sim/addrdec.h b/src/gpgpu-sim/addrdec.h index 6eddb15..dd0e5a0 100644 --- a/src/gpgpu-sim/addrdec.h +++ b/src/gpgpu-sim/addrdec.h @@ -87,8 +87,8 @@ class linear_to_raw_address_translation { unsigned int gap; unsigned m_n_channel; int m_n_sub_partition_in_channel; - unsigned log2channel; - unsigned log2sub_partition; + unsigned log2channel; + unsigned log2sub_partition; }; #endif diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc index 6f3155f..041cfce 100644 --- a/src/gpgpu-sim/dram.cc +++ b/src/gpgpu-sim/dram.cc @@ -207,31 +207,31 @@ dram_req_t::dram_req_t(class mem_fetch *mf, unsigned banks, } case BITWISE_XORING_BK_INDEX: { // xoring bank bits with lower bits of the page - int lbank = LOGB2(banks); + int lbank = LOGB2(banks); bk = tlx.bk ^ (tlx.row & ((1 << lbank) - 1)); - break; - } - case IPOLY_BK_INDEX: - { - /*IPOLY for bank indexing function from "Pseudo-randomly interleaved memory." - * Rau, B. R et al. - * ISCA 1991 - * http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=348DEA37A3E440473B3C075EAABC63B6?doi=10.1.1.12.7149&rep=rep1&type=pdf - */ - if (banks == 16) { - std::bitset<64> a(tlx.row); - std::bitset<4> b(tlx.bk); - b[0] = a[11]^a[10]^a[9]^a[8]^a[6]^a[4]^a[3]^a[0]^b[0]; - b[1] = a[12]^a[8]^a[7]^a[6]^a[5]^a[3]^a[1]^a[0]^b[1]; - b[2] = a[9]^a[8]^a[7]^a[6]^a[4]^a[2]^a[1]^b[2]; - b[3] = a[10]^a[9]^a[8]^a[7]^a[5]^a[3]^a[2]^b[3]; - bk = b.to_ulong(); - assert(bk < banks); - } - else{ /* Else incorrect number of channels for the hashing function */ - assert("\nGPGPU-Sim memory_banking indexing error: The number of banks should be " - "16 for the hashing IPOLY index function.\n" && 0); - } + break; + } + case IPOLY_BK_INDEX: { + /*IPOLY for bank indexing function from "Pseudo-randomly interleaved + * memory." Rau, B. R et al. ISCA 1991 + * http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=348DEA37A3E440473B3C075EAABC63B6?doi=10.1.1.12.7149&rep=rep1&type=pdf + */ + if (banks == 16) { + std::bitset<64> a(tlx.row); + std::bitset<4> b(tlx.bk); + b[0] = a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[6] ^ a[4] ^ a[3] ^ a[0] ^ b[0]; + b[1] = a[12] ^ a[8] ^ a[7] ^ a[6] ^ a[5] ^ a[3] ^ a[1] ^ a[0] ^ b[1]; + b[2] = a[9] ^ a[8] ^ a[7] ^ a[6] ^ a[4] ^ a[2] ^ a[1] ^ b[2]; + b[3] = a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[5] ^ a[3] ^ a[2] ^ b[3]; + bk = b.to_ulong(); + assert(bk < banks); + } else { /* Else incorrect number of channels for the hashing function */ + assert( + "\nGPGPU-Sim memory_banking indexing error: The number of banks " + "should be " + "16 for the hashing IPOLY index function.\n" && + 0); + } break; } case CUSTOM_BK_INDEX: diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h index fbdf1e1..6c212e9 100644 --- a/src/gpgpu-sim/dram.h +++ b/src/gpgpu-sim/dram.h @@ -97,7 +97,7 @@ struct bank_t { enum bank_index_function { LINEAR_BK_INDEX = 0, BITWISE_XORING_BK_INDEX, - IPOLY_BK_INDEX, + IPOLY_BK_INDEX, CUSTOM_BK_INDEX }; diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index cafa8d9..adce3a2 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -1315,9 +1315,10 @@ enum cache_request_status data_cache::wr_miss_wa_naive( mem_fetch *wb = m_memfetch_creator->alloc( evicted.m_block_addr, m_wrbk_type, evicted.m_modified_size, true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle); - //the evicted block may have wrong chip id when advanced L2 hashing is used, so set the right chip address from the original mf - wb->set_chip(mf->get_tlx_addr().chip); - wb->set_parition(mf->get_tlx_addr().sub_partition); + // the evicted block may have wrong chip id when advanced L2 hashing is + // used, so set the right chip address from the original mf + wb->set_chip(mf->get_tlx_addr().chip); + wb->set_parition(mf->get_tlx_addr().sub_partition); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } @@ -1361,9 +1362,10 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write( mem_fetch *wb = m_memfetch_creator->alloc( evicted.m_block_addr, m_wrbk_type, evicted.m_modified_size, true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle); - //the evicted block may have wrong chip id when advanced L2 hashing is used, so set the right chip address from the original mf - wb->set_chip(mf->get_tlx_addr().chip); - wb->set_parition(mf->get_tlx_addr().sub_partition); + // the evicted block may have wrong chip id when advanced L2 hashing is + // used, so set the right chip address from the original mf + wb->set_chip(mf->get_tlx_addr().chip); + wb->set_parition(mf->get_tlx_addr().sub_partition); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } @@ -1430,9 +1432,10 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write( mem_fetch *wb = m_memfetch_creator->alloc( evicted.m_block_addr, m_wrbk_type, evicted.m_modified_size, true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle); - //the evicted block may have wrong chip id when advanced L2 hashing is used, so set the right chip address from the original mf - wb->set_chip(mf->get_tlx_addr().chip); - wb->set_parition(mf->get_tlx_addr().sub_partition); + // the evicted block may have wrong chip id when advanced L2 hashing is + // used, so set the right chip address from the original mf + wb->set_chip(mf->get_tlx_addr().chip); + wb->set_parition(mf->get_tlx_addr().sub_partition); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } @@ -1482,9 +1485,10 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( mem_fetch *wb = m_memfetch_creator->alloc( evicted.m_block_addr, m_wrbk_type, evicted.m_modified_size, true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle); - //the evicted block may have wrong chip id when advanced L2 hashing is used, so set the right chip address from the original mf - wb->set_chip(mf->get_tlx_addr().chip); - wb->set_parition(mf->get_tlx_addr().sub_partition); + // the evicted block may have wrong chip id when advanced L2 hashing is + // used, so set the right chip address from the original mf + wb->set_chip(mf->get_tlx_addr().chip); + wb->set_parition(mf->get_tlx_addr().sub_partition); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } @@ -1557,9 +1561,10 @@ enum cache_request_status data_cache::rd_miss_base( mem_fetch *wb = m_memfetch_creator->alloc( evicted.m_block_addr, m_wrbk_type, evicted.m_modified_size, true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle); - //the evicted block may have wrong chip id when advanced L2 hashing is used, so set the right chip address from the original mf - wb->set_chip(mf->get_tlx_addr().chip); - wb->set_parition(mf->get_tlx_addr().sub_partition); + // the evicted block may have wrong chip id when advanced L2 hashing is + // used, so set the right chip address from the original mf + wb->set_chip(mf->get_tlx_addr().chip); + wb->set_parition(mf->get_tlx_addr().sub_partition); send_write_request(wb, WRITE_BACK_REQUEST_SENT, time, events); } return MISS; diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 34bc7d9..5d75e50 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -60,12 +60,12 @@ #include "../debug.h" #include "../gpgpusim_entrypoint.h" #include "../statwrapper.h" +#include "../trace-driven/trace_driven.h" #include "../trace.h" #include "mem_latency_stat.h" #include "power_stat.h" #include "stats.h" #include "visualizer.h" -#include "../trace-driven/trace_driven.h" #ifdef GPGPUSIM_POWER_MODEL #include "power_interface.h" @@ -130,9 +130,11 @@ void power_config::reg_options(class OptionParser *opp) { } void memory_config::reg_options(class OptionParser *opp) { - option_parser_register(opp, "-gpgpu_perf_sim_memcpy", OPT_BOOL, &m_perf_sim_memcpy, - "Fill the L2 cache on memcpy", "1"); - option_parser_register(opp, "-gpgpu_simple_dram_model", OPT_BOOL, &simple_dram_model, + option_parser_register(opp, "-gpgpu_perf_sim_memcpy", OPT_BOOL, + &m_perf_sim_memcpy, "Fill the L2 cache on memcpy", + "1"); + option_parser_register(opp, "-gpgpu_simple_dram_model", OPT_BOOL, + &simple_dram_model, "simple_dram_model with fixed latency and BW", "0"); option_parser_register(opp, "-gpgpu_dram_scheduler", OPT_INT32, &scheduler_type, "0 = fifo, 1 = FR-FCFS (defaul)", @@ -187,11 +189,12 @@ void memory_config::reg_options(class OptionParser *opp) { "DRAM timing parameters = " "{nbk:tCCD:tRRD:tRCD:tRAS:tRP:tRC:CL:WL:tCDLR:tWR:nbkgrp:tCCDL:tRTPL}", "4:2:8:12:21:13:34:9:4:5:13:1:0:0"); - option_parser_register(opp, "-gpgpu_l2_rop_latency", OPT_UINT32, &rop_latency, + option_parser_register(opp, "-gpgpu_l2_rop_latency", OPT_UINT32, &rop_latency, "ROP queue latency (default 85)", "85"); option_parser_register(opp, "-dram_latency", OPT_UINT32, &dram_latency, "DRAM latency (default 30)", "30"); - option_parser_register(opp, "-dram_dual_bus_interface", OPT_UINT32, &dual_bus_interface, + option_parser_register(opp, "-dram_dual_bus_interface", OPT_UINT32, + &dual_bus_interface, "dual_bus_interface (default = 0) ", "0"); option_parser_register(opp, "-dram_bnk_indexing_policy", OPT_UINT32, &dram_bnk_indexing_policy, @@ -203,11 +206,13 @@ void memory_config::reg_options(class OptionParser *opp) { "dram_bnkgrp_indexing_policy (0 = take higher bits, 1 " "= take lower bits) (Default = 0)", "0"); - option_parser_register(opp, "-dram_seperate_write_queue_enable", OPT_BOOL, &seperate_write_queue_enabled, + option_parser_register(opp, "-dram_seperate_write_queue_enable", OPT_BOOL, + &seperate_write_queue_enabled, "Seperate_Write_Queue_Enable", "0"); - option_parser_register(opp, "-dram_write_queue_size", OPT_CSTR, &write_queue_size_opt, - "Write_Queue_Size", "32:28:16"); - option_parser_register(opp, "-dram_elimnate_rw_turnaround", OPT_BOOL, &elimnate_rw_turnaround, + option_parser_register(opp, "-dram_write_queue_size", OPT_CSTR, + &write_queue_size_opt, "Write_Queue_Size", "32:28:16"); + option_parser_register( + opp, "-dram_elimnate_rw_turnaround", OPT_BOOL, &elimnate_rw_turnaround, "elimnate_rw_turnaround i.e set tWTR and tRTW = 0", "0"); option_parser_register(opp, "-icnt_flit_size", OPT_UINT32, &icnt_flit_size, "icnt_flit_size", "32"); @@ -245,11 +250,12 @@ void shader_core_config::reg_options(class OptionParser *opp) { " {::,:::,::, | none}", "none"); - option_parser_register(opp, "-gpgpu_l1_banks", OPT_UINT32, &m_L1D_config.l1_banks, - "The number of L1 cache banks", "1"); - option_parser_register(opp, "-gpgpu_l1_latency", OPT_UINT32, &m_L1D_config.l1_latency, - "L1 Hit Latency", "1"); - option_parser_register(opp, "-gpgpu_smem_latency", OPT_UINT32, &smem_latency, + option_parser_register(opp, "-gpgpu_l1_banks", OPT_UINT32, + &m_L1D_config.l1_banks, "The number of L1 cache banks", + "1"); + option_parser_register(opp, "-gpgpu_l1_latency", OPT_UINT32, + &m_L1D_config.l1_latency, "L1 Hit Latency", "1"); + option_parser_register(opp, "-gpgpu_smem_latency", OPT_UINT32, &smem_latency, "smem Latency", "3"); option_parser_register(opp, "-gpgpu_cache:dl1PrefL1", OPT_CSTR, &m_L1D_config.m_config_stringPrefL1, @@ -263,7 +269,7 @@ void shader_core_config::reg_options(class OptionParser *opp) { " {::,:::,::, | none}", "none"); - option_parser_register(opp, "-gpgpu_gmem_skip_L1D", OPT_BOOL, &gmem_skip_L1D, + option_parser_register(opp, "-gpgpu_gmem_skip_L1D", OPT_BOOL, &gmem_skip_L1D, "global memory access skip L1D cache (implements " "-Xptxas -dlcm=cg, default=no skip)", "0"); @@ -315,8 +321,8 @@ 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, "-gpgpu_adaptive_cache_config", OPT_UINT32, &adaptive_cache_config, - "adaptive_cache_config", "0"); + option_parser_register(opp, "-gpgpu_adaptive_cache_config", OPT_UINT32, + &adaptive_cache_config, "adaptive_cache_config", "0"); option_parser_register( opp, "-gpgpu_shmem_sizeDefault", OPT_UINT32, &gpgpu_shmem_sizeDefault, "Size of shared memory per shader core (default 16kB)", "16384"); @@ -339,7 +345,8 @@ void shader_core_config::reg_options(class OptionParser *opp) { "Number of portions a warp is divided into for shared " "memory bank conflict check ", "2"); - option_parser_register(opp, "-gpgpu_mem_unit_ports", OPT_INT32, &mem_unit_ports, + option_parser_register( + opp, "-gpgpu_mem_unit_ports", OPT_INT32, &mem_unit_ports, "The number of memory transactions allowed per core cycle", "1"); option_parser_register(opp, "-gpgpu_shmem_warp_parts", OPT_INT32, &mem_warp_parts, @@ -365,10 +372,11 @@ void shader_core_config::reg_options(class OptionParser *opp) { option_parser_register( opp, "-gpgpu_reg_bank_use_warp_id", OPT_BOOL, &gpgpu_reg_bank_use_warp_id, "Use warp ID in mapping registers to banks (default = off)", "0"); - option_parser_register(opp, "-gpgpu_sub_core_model", OPT_BOOL, &sub_core_model, + option_parser_register(opp, "-gpgpu_sub_core_model", OPT_BOOL, + &sub_core_model, "Sub Core Volta/Pascal model (default = off)", "0"); - option_parser_register(opp, "-gpgpu_enable_specialized_operand_collector", OPT_BOOL, - &enable_specialized_operand_collector, + option_parser_register(opp, "-gpgpu_enable_specialized_operand_collector", + OPT_BOOL, &enable_specialized_operand_collector, "enable_specialized_operand_collector", "1"); option_parser_register(opp, "-gpgpu_operand_collector_num_units_sp", OPT_INT32, &gpgpu_operand_collector_num_units_sp, @@ -492,9 +500,9 @@ void shader_core_config::reg_options(class OptionParser *opp) { "1"); option_parser_register(opp, "-gpgpu_num_tensor_core_units", OPT_INT32, &gpgpu_num_tensor_core_units, - "Number of tensor_core units (default=1)", - "0"); - option_parser_register(opp, "-gpgpu_num_mem_units", OPT_INT32, &gpgpu_num_mem_units, + "Number of tensor_core units (default=1)", "0"); + option_parser_register( + opp, "-gpgpu_num_mem_units", OPT_INT32, &gpgpu_num_mem_units, "Number if ldst units (default=1) WARNING: not hooked up to anything", "1"); option_parser_register( @@ -511,31 +519,43 @@ void shader_core_config::reg_options(class OptionParser *opp) { option_parser_register( opp, "-gpgpu_concurrent_kernel_sm", OPT_BOOL, &gpgpu_concurrent_kernel_sm, "Support concurrent kernels on a SM (default = disabled)", "0"); - option_parser_register(opp, "-gpgpu_perfect_inst_const_cache", OPT_BOOL, &perfect_inst_const_cache, - "perfect inst and const cache mode, so all inst and const hits in the cache(default = disabled)", - "0"); - option_parser_register(opp, "-gpgpu_inst_fetch_throughput", OPT_INT32, &inst_fetch_throughput, - "the number of fetched intruction per warp each cycle", - "1"); - option_parser_register(opp, "-gpgpu_reg_file_port_throughput", OPT_INT32, ®_file_port_throughput, - "the number ports of the register file", - "1"); - //used for trace-driven mode - option_parser_register(opp, "-trace_opcode_latency_initiation_int", OPT_CSTR, &trace_opcode_latency_initiation_int, - "Opcode latencies and initiation for integers in trace driven mode ", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_sp", OPT_CSTR, &trace_opcode_latency_initiation_sp, - "Opcode latencies and initiation for sp in trace driven mode ", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_dp", OPT_CSTR, &trace_opcode_latency_initiation_dp, - "Opcode latencies and initiation for dp in trace driven mode ", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_sfu", OPT_CSTR, &trace_opcode_latency_initiation_sfu, - "Opcode latencies and initiation for sfu in trace driven mode ", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_tensor", OPT_CSTR, &trace_opcode_latency_initiation_tensor, - "Opcode latencies and initiation for tensor in trace driven mode ", - "4,1"); + option_parser_register(opp, "-gpgpu_perfect_inst_const_cache", OPT_BOOL, + &perfect_inst_const_cache, + "perfect inst and const cache mode, so all inst and " + "const hits in the cache(default = disabled)", + "0"); + option_parser_register( + opp, "-gpgpu_inst_fetch_throughput", OPT_INT32, &inst_fetch_throughput, + "the number of fetched intruction per warp each cycle", "1"); + option_parser_register(opp, "-gpgpu_reg_file_port_throughput", OPT_INT32, + ®_file_port_throughput, + "the number ports of the register file", "1"); + // used for trace-driven mode + option_parser_register(opp, "-trace_opcode_latency_initiation_int", OPT_CSTR, + &trace_opcode_latency_initiation_int, + "Opcode latencies and initiation for integers in " + "trace driven mode ", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_sp", OPT_CSTR, + &trace_opcode_latency_initiation_sp, + "Opcode latencies and initiation for sp in trace " + "driven mode ", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_dp", OPT_CSTR, + &trace_opcode_latency_initiation_dp, + "Opcode latencies and initiation for dp in trace " + "driven mode ", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_sfu", OPT_CSTR, + &trace_opcode_latency_initiation_sfu, + "Opcode latencies and initiation for sfu in trace " + "driven mode ", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_tensor", + OPT_CSTR, &trace_opcode_latency_initiation_tensor, + "Opcode latencies and initiation for tensor in trace " + "driven mode ", + "4,1"); } void gpgpu_sim_config::reg_options(option_parser_t opp) { @@ -642,21 +662,21 @@ void gpgpu_sim_config::reg_options(option_parser_t opp) { &(gpgpu_ctx->device_runtime->g_cdp_enabled), "Turn on CDP", "0"); - option_parser_register(opp, "-gpgpu_TB_launch_latency", OPT_INT32, - &(gpgpu_ctx->device_runtime->g_TB_launch_latency), "thread block launch latency in cycles. Default: 0", - "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_skip_first_kernel", OPT_BOOL, - &trace_skip_first_kernel, "skip first intiliztion kernel in trace mode", - "0"); - option_parser_register(opp, "-trace", OPT_CSTR, - &g_traces_filename, "traces kernel file" - "traces kernel file directory", - "./traces/kernelslist.g"); + option_parser_register(opp, "-gpgpu_TB_launch_latency", OPT_INT32, + &(gpgpu_ctx->device_runtime->g_TB_launch_latency), + "thread block launch latency in cycles. Default: 0", + "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_skip_first_kernel", OPT_BOOL, + &trace_skip_first_kernel, + "skip first intiliztion kernel in trace mode", "0"); + option_parser_register(opp, "-trace", OPT_CSTR, &g_traces_filename, + "traces kernel file" + "traces kernel file directory", + "./traces/kernelslist.g"); } ///////////////////////////////////////////////////////////////////////////// @@ -733,18 +753,17 @@ bool gpgpu_sim::get_more_cta_left() const { return false; } -void gpgpu_sim::decrement_kernel_latency() -{ - for(unsigned n=0; n < m_running_kernels.size(); n++ ) { - if( m_running_kernels[n] && m_running_kernels[n]->m_kernel_TB_latency ) - m_running_kernels[n]->m_kernel_TB_latency--; - } +void gpgpu_sim::decrement_kernel_latency() { + for (unsigned n = 0; n < m_running_kernels.size(); n++) { + if (m_running_kernels[n] && m_running_kernels[n]->m_kernel_TB_latency) + m_running_kernels[n]->m_kernel_TB_latency--; + } } kernel_info_t *gpgpu_sim::select_kernel() { if (m_running_kernels[m_last_issued_kernel] && - !m_running_kernels[m_last_issued_kernel]->no_more_ctas_to_run() && - !m_running_kernels[m_last_issued_kernel]->m_kernel_TB_latency) { + !m_running_kernels[m_last_issued_kernel]->no_more_ctas_to_run() && + !m_running_kernels[m_last_issued_kernel]->m_kernel_TB_latency) { unsigned launch_uid = m_running_kernels[m_last_issued_kernel]->get_uid(); if (std::find(m_executed_kernel_uids.begin(), m_executed_kernel_uids.end(), launch_uid) == m_executed_kernel_uids.end()) { @@ -760,8 +779,8 @@ kernel_info_t *gpgpu_sim::select_kernel() { for (unsigned n = 0; n < m_running_kernels.size(); n++) { unsigned idx = (n + m_last_issued_kernel + 1) % m_config.max_concurrent_kernel; - if( kernel_more_cta_left(m_running_kernels[idx]) && - !m_running_kernels[idx]->m_kernel_TB_latency){ + if (kernel_more_cta_left(m_running_kernels[idx]) && + !m_running_kernels[idx]->m_kernel_TB_latency) { m_last_issued_kernel = idx; m_running_kernels[idx]->start_cycle = gpu_sim_cycle + gpu_tot_sim_cycle; // record this kernel for stat print if it is the first time this kernel @@ -1630,15 +1649,15 @@ void shader_core_ctx::issue_block2core(kernel_info_t &kernel) { for (unsigned i = start_thread; i < end_thread; i++) { m_threadState[i].m_cta_id = free_cta_hw_id; unsigned warp_id = i / m_config->warp_size; - if(m_gpu->get_config().is_trace_driven_mode()) { - trace_shader_core_ctx* trace_core = static_cast (this); - nthreads_in_block += trace_core->trace_sim_inc_thread(kernel); - } - else - nthreads_in_block += ptx_sim_init_thread( - kernel, &m_thread[i], m_sid, i, cta_size - (i - start_thread), - m_config->n_thread_per_shader, this, free_cta_hw_id, warp_id, - m_cluster->get_gpu()); + if (m_gpu->get_config().is_trace_driven_mode()) { + trace_shader_core_ctx *trace_core = + static_cast(this); + nthreads_in_block += trace_core->trace_sim_inc_thread(kernel); + } else + nthreads_in_block += ptx_sim_init_thread( + kernel, &m_thread[i], m_sid, i, cta_size - (i - start_thread), + m_config->n_thread_per_shader, this, free_cta_hw_id, warp_id, + m_cluster->get_gpu()); m_threadState[i].m_active = true; // load thread local memory and register file if (m_gpu->resume_option == 1 && kernel.get_uid() == m_gpu->resume_kernel && @@ -1673,7 +1692,7 @@ void shader_core_ctx::issue_block2core(kernel_info_t &kernel) { m_barriers.allocate_barrier(free_cta_hw_id, warps); // initialize the SIMT stacks and fetch hardware - init_warps( free_cta_hw_id, start_thread, end_thread, ctaid, cta_size, kernel); + init_warps(free_cta_hw_id, start_thread, end_thread, ctaid, cta_size, kernel); m_n_active_cta++; shader_CTA_count_log(m_sid, 1); @@ -1865,7 +1884,7 @@ void gpgpu_sim::cycle() { #endif issue_block2core(); - decrement_kernel_latency(); + decrement_kernel_latency(); // Depending on configuration, invalidate the caches once all of threads are // completed. @@ -1978,8 +1997,9 @@ void shader_core_ctx::dump_warp_state(FILE *fout) const { void gpgpu_sim::perf_memcpy_to_gpu(size_t dst_start_addr, size_t count) { if (m_memory_config->m_perf_sim_memcpy) { - //if(!m_config.trace_driven_mode) //in trace-driven mode, CUDA runtime can start nre data structure at any position - // assert (dst_start_addr % 32 == 0); + // if(!m_config.trace_driven_mode) //in trace-driven mode, CUDA runtime + // can start nre data structure at any position assert (dst_start_addr % 32 + //== 0); for (unsigned counter = 0; counter < count; counter += 32) { const unsigned wr_addr = dst_start_addr + counter; diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 0c4474c..53f6ead 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -370,11 +370,10 @@ class gpgpu_sim_config : public power_config, return runtime_pending_launch_count_limit; } - bool is_trace_driven_mode() const { return trace_driven_mode; } - bool is_skip_first_kernel() const { return trace_skip_first_kernel; } - char* get_traces_filename() const { return g_traces_filename; } - bool flush_l1() const { return gpgpu_flush_l1_cache; } - + bool is_trace_driven_mode() const { return trace_driven_mode; } + bool is_skip_first_kernel() const { return trace_skip_first_kernel; } + char *get_traces_filename() const { return g_traces_filename; } + bool flush_l1() const { return gpgpu_flush_l1_cache; } private: void init_clock_domains(void); @@ -428,10 +427,10 @@ class gpgpu_sim_config : public power_config, unsigned int gpgpu_compute_capability_minor; unsigned long long liveness_message_freq; - //trace driven mode options - bool trace_driven_mode; - bool trace_skip_first_kernel; - char *g_traces_filename; + // trace driven mode options + bool trace_driven_mode; + bool trace_skip_first_kernel; + char *g_traces_filename; friend class gpgpu_sim; }; @@ -536,7 +535,7 @@ class gpgpu_sim : public gpgpu_t { bool kernel_more_cta_left(kernel_info_t *kernel) const; bool hit_max_cta_count() const; kernel_info_t *select_kernel(); - void decrement_kernel_latency(); + void decrement_kernel_latency(); const gpgpu_sim_config &get_config() const { return m_config; } void gpu_print_stat(); diff --git a/src/gpgpu-sim/icnt_wrapper.cc b/src/gpgpu-sim/icnt_wrapper.cc index 4ae7aa8..82785dc 100644 --- a/src/gpgpu-sim/icnt_wrapper.cc +++ b/src/gpgpu-sim/icnt_wrapper.cc @@ -144,14 +144,20 @@ void icnt_reg_options(class OptionParser* opp) { "Interconnection network config file", "mesh"); // parameters for local xbar - option_parser_register(opp, "-icnt_in_buffer_limit", OPT_UINT32, &g_inct_config.in_buffer_limit, "in_buffer_limit", "64"); - option_parser_register(opp, "-icnt_out_buffer_limit", OPT_UINT32, &g_inct_config.out_buffer_limit, "out_buffer_limit", "64"); - option_parser_register(opp, "-icnt_subnets", OPT_UINT32, &g_inct_config.subnets, "subnets", "2"); - option_parser_register(opp, "-icnt_arbiter_algo", OPT_UINT32, &g_inct_config.arbiter_algo, "arbiter_algo", "1"); - option_parser_register(opp, "-icnt_verbose", OPT_UINT32, &g_inct_config.verbose, "inct_verbose", "0"); - option_parser_register(opp, "-icnt_grant_cycles", OPT_UINT32, &g_inct_config.grant_cycles, "grant_cycles", "1"); - - + option_parser_register(opp, "-icnt_in_buffer_limit", OPT_UINT32, + &g_inct_config.in_buffer_limit, "in_buffer_limit", + "64"); + option_parser_register(opp, "-icnt_out_buffer_limit", OPT_UINT32, + &g_inct_config.out_buffer_limit, "out_buffer_limit", + "64"); + option_parser_register(opp, "-icnt_subnets", OPT_UINT32, + &g_inct_config.subnets, "subnets", "2"); + option_parser_register(opp, "-icnt_arbiter_algo", OPT_UINT32, + &g_inct_config.arbiter_algo, "arbiter_algo", "1"); + option_parser_register(opp, "-icnt_verbose", OPT_UINT32, + &g_inct_config.verbose, "inct_verbose", "0"); + option_parser_register(opp, "-icnt_grant_cycles", OPT_UINT32, + &g_inct_config.grant_cycles, "grant_cycles", "1"); } void icnt_wrapper_init() { diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index 6651b21..b7b5745 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -793,9 +793,9 @@ void memory_sub_partition::push(mem_fetch *m_req, unsigned long long cycle) { mem_fetch *memory_sub_partition::pop() { mem_fetch *mf = m_L2_icnt_queue->pop(); m_request_tracker.erase(mf); - if ( mf && mf->isatomic() && !m_gpu->get_config().is_trace_driven_mode() ){ - mf->do_atomic(); - } + if (mf && mf->isatomic() && !m_gpu->get_config().is_trace_driven_mode()) { + mf->do_atomic(); + } if (mf && (mf->get_access_type() == L2_WRBK_ACC || mf->get_access_type() == L1_WRBK_ACC)) { delete mf; diff --git a/src/gpgpu-sim/local_interconnect.cc b/src/gpgpu-sim/local_interconnect.cc index f74960e..0e20462 100644 --- a/src/gpgpu-sim/local_interconnect.cc +++ b/src/gpgpu-sim/local_interconnect.cc @@ -37,22 +37,23 @@ #include "local_interconnect.h" #include "mem_fetch.h" -xbar_router::xbar_router(unsigned router_id, enum Interconnect_type m_type, unsigned n_shader, unsigned n_mem, const struct inct_config& m_localinct_config) -{ +xbar_router::xbar_router(unsigned router_id, enum Interconnect_type m_type, + unsigned n_shader, unsigned n_mem, + const struct inct_config& m_localinct_config) { m_id = router_id; router_type = m_type; _n_mem = n_mem; _n_shader = n_shader; total_nodes = n_shader + n_mem; - verbose=m_localinct_config.verbose; - grant_cycles = m_localinct_config.grant_cycles; - grant_cycles_count = m_localinct_config.grant_cycles; + verbose = m_localinct_config.verbose; + grant_cycles = m_localinct_config.grant_cycles; + grant_cycles_count = m_localinct_config.grant_cycles; in_buffers.resize(total_nodes); out_buffers.resize(total_nodes); next_node.resize(total_nodes, 0); - in_buffer_limit = m_localinct_config.in_buffer_limit; - out_buffer_limit = m_localinct_config.out_buffer_limit; - arbit_type = m_localinct_config.arbiter_algo; + in_buffer_limit = m_localinct_config.in_buffer_limit; + out_buffer_limit = m_localinct_config.out_buffer_limit; + arbit_type = m_localinct_config.arbiter_algo; next_node_id = 0; if (m_type == REQ_NET) { active_in_buffers = n_shader; @@ -69,9 +70,9 @@ xbar_router::xbar_router(unsigned router_id, enum Interconnect_type m_type, unsi out_buffer_util = 0; in_buffer_util = 0; packets_num = 0; - conflicts_util=0; - cycles_util=0; - reqs_util=0; + conflicts_util = 0; + cycles_util = 0; + reqs_util = 0; } xbar_router::~xbar_router() {} @@ -120,18 +121,16 @@ void xbar_router::Advance() { } void xbar_router::RR_Advance() { - - bool active = false; + bool active = false; vector issued(total_nodes, false); - unsigned conflict_sub =0 ; - unsigned reqs =0 ; - + unsigned conflict_sub = 0; + unsigned reqs = 0; for (unsigned i = 0; i < total_nodes; ++i) { unsigned node_id = (i + next_node_id) % total_nodes; if (!in_buffers[node_id].empty()) { - active=true; + active = true; Packet _packet = in_buffers[node_id].front(); // ensure that the outbuffer has space and not issued before in this cycle if (Has_Buffer_Out(_packet.output_deviceID, 1)) { @@ -139,31 +138,30 @@ void xbar_router::RR_Advance() { out_buffers[_packet.output_deviceID].push(_packet); in_buffers[node_id].pop(); issued[_packet.output_deviceID] = true; - reqs++; + reqs++; } else - conflict_sub++; + conflict_sub++; } else { out_buffer_full++; - if(issued[_packet.output_deviceID]) - conflict_sub++; + if (issued[_packet.output_deviceID]) conflict_sub++; } } } next_node_id = (++next_node_id % total_nodes); - conflicts += conflict_sub; - if(active){ - conflicts_util += conflict_sub; - cycles_util++; - reqs_util+=reqs; - } + conflicts += conflict_sub; + if (active) { + conflicts_util += conflict_sub; + cycles_util++; + reqs_util += reqs; + } - if(verbose) { - printf("%d : cycle %d : conflicts = %d\n", m_id, cycles, conflict_sub); - printf("%d : cycle %d : passing reqs = %d\n", m_id, cycles, reqs); - } + if (verbose) { + printf("%d : cycle %d : conflicts = %d\n", m_id, cycles, conflict_sub); + printf("%d : cycle %d : passing reqs = %d\n", m_id, cycles, reqs); + } // collect some stats about buffer util for (unsigned i = 0; i < total_nodes; ++i) { @@ -171,8 +169,7 @@ void xbar_router::RR_Advance() { out_buffer_util += out_buffers[i].size(); } - cycles++; - + cycles++; } // iSLIP algorithm @@ -180,36 +177,34 @@ void xbar_router::RR_Advance() { // IEEE/ACM transactions on networking 2 (1999): 188-201. // https://www.cs.rutgers.edu/~sn624/552-F18/papers/islip.pdf void xbar_router::iSLIP_Advance() { - vector node_tmp; - bool active = false; + bool active = false; - unsigned conflict_sub =0 ; - unsigned reqs =0 ; + unsigned conflict_sub = 0; + unsigned reqs = 0; - //calcaulte how many conflicts are there for stats + // calcaulte how many conflicts are there for stats for (unsigned i = 0; i < total_nodes; ++i) { - if (!in_buffers[i].empty()) { Packet _packet_tmp = in_buffers[i].front(); if (!node_tmp.empty()) { if (std::find(node_tmp.begin(), node_tmp.end(), _packet_tmp.output_deviceID) != node_tmp.end()) { - conflict_sub++; + conflict_sub++; } else node_tmp.push_back(_packet_tmp.output_deviceID); } else { node_tmp.push_back(_packet_tmp.output_deviceID); } - active=true; + active = true; } } - conflicts += conflict_sub; - if(active){ - conflicts_util += conflict_sub; - cycles_util++; - } + conflicts += conflict_sub; + if (active) { + conflicts_util += conflict_sub; + cycles_util++; + } // do iSLIP for (unsigned i = 0; i < total_nodes; ++i) { if (Has_Buffer_Out(i, 1)) { @@ -221,23 +216,25 @@ void xbar_router::iSLIP_Advance() { if (_packet.output_deviceID == i) { out_buffers[_packet.output_deviceID].push(_packet); in_buffers[node_id].pop(); - if(verbose) - printf("%d : cycle %d : send req from %d to %d\n", m_id, cycles, node_id, i-_n_shader); - if(grant_cycles_count == 1) - next_node[i] = (++node_id % total_nodes); - if(verbose){ - for(unsigned k=j+1; k(i), m_n_shader, m_n_mem, m_inct_config); + net[i] = new xbar_router(i, static_cast(i), m_n_shader, + m_n_mem, m_inct_config); } } @@ -381,29 +376,51 @@ bool LocalInterconnect::HasBuffer(unsigned deviceID, unsigned int size) const { } void LocalInterconnect::DisplayStats() const { - printf("Req_Network_injected_packets_num = %lld\n", net[REQ_NET]->packets_num); - printf("Req_Network_cycles = %lld\n", net[REQ_NET]->cycles); - printf("Req_Network_injected_packets_per_cycle = %12.4f \n", (float)(net[REQ_NET]->packets_num) / (net[REQ_NET]->cycles)); - printf("Req_Network_conflicts_per_cycle = %12.4f\n", (float)(net[REQ_NET]->conflicts) / (net[REQ_NET]->cycles)); - printf("Req_Network_conflicts_per_cycle_util = %12.4f\n", (float)(net[REQ_NET]->conflicts_util) / (net[REQ_NET]->cycles_util)); - printf("Req_Bank_Level_Parallism = %12.4f\n", (float)(net[REQ_NET]->reqs_util) / (net[REQ_NET]->cycles_util)); - printf("Req_Network_in_buffer_full_per_cycle = %12.4f\n", (float)(net[REQ_NET]->in_buffer_full) / (net[REQ_NET]->cycles)); - printf("Req_Network_in_buffer_avg_util = %12.4f\n", ((float)(net[REQ_NET]->in_buffer_util) / (net[REQ_NET]->cycles) / net[REQ_NET]->active_in_buffers)); - printf("Req_Network_out_buffer_full_per_cycle = %12.4f\n", (float)(net[REQ_NET]->out_buffer_full) / (net[REQ_NET]->cycles)); - printf("Req_Network_out_buffer_avg_util = %12.4f\n", ((float)(net[REQ_NET]->out_buffer_util) / (net[REQ_NET]->cycles) / net[REQ_NET]->active_out_buffers)); - - printf("\n"); - printf("Reply_Network_injected_packets_num = %lld\n", net[REPLY_NET]->packets_num); - printf("Reply_Network_cycles = %lld\n", net[REPLY_NET]->cycles); - printf("Reply_Network_injected_packets_per_cycle = %12.4f\n", (float)(net[REPLY_NET]->packets_num) / (net[REPLY_NET]->cycles)); - printf("Reply_Network_conflicts_per_cycle = %12.4f\n", (float)(net[REPLY_NET]->conflicts) / (net[REPLY_NET]->cycles)); - printf("Reply_Network_conflicts_per_cycle_util = %12.4f\n", (float)(net[REPLY_NET]->conflicts_util) / (net[REPLY_NET]->cycles_util)); - printf("Reply_Bank_Level_Parallism = %12.4f\n", (float)(net[REPLY_NET]->reqs_util) / (net[REPLY_NET]->cycles_util)); - printf("Reply_Network_in_buffer_full_per_cycle = %12.4f\n", (float)(net[REPLY_NET]->in_buffer_full) / (net[REPLY_NET]->cycles)); - printf("Reply_Network_in_buffer_avg_util = %12.4f\n", ((float)(net[REPLY_NET]->in_buffer_util) / (net[REPLY_NET]->cycles) / net[REPLY_NET]->active_in_buffers)); - printf("Reply_Network_out_buffer_full_per_cycle = %12.4f\n", (float)(net[REPLY_NET]->out_buffer_full) / (net[REPLY_NET]->cycles)); - printf("Reply_Network_out_buffer_avg_util = %12.4f\n", ((float)(net[REPLY_NET]->out_buffer_util) / (net[REPLY_NET]->cycles) / net[REPLY_NET]->active_out_buffers)); - + printf("Req_Network_injected_packets_num = %lld\n", + net[REQ_NET]->packets_num); + printf("Req_Network_cycles = %lld\n", net[REQ_NET]->cycles); + printf("Req_Network_injected_packets_per_cycle = %12.4f \n", + (float)(net[REQ_NET]->packets_num) / (net[REQ_NET]->cycles)); + printf("Req_Network_conflicts_per_cycle = %12.4f\n", + (float)(net[REQ_NET]->conflicts) / (net[REQ_NET]->cycles)); + printf("Req_Network_conflicts_per_cycle_util = %12.4f\n", + (float)(net[REQ_NET]->conflicts_util) / (net[REQ_NET]->cycles_util)); + printf("Req_Bank_Level_Parallism = %12.4f\n", + (float)(net[REQ_NET]->reqs_util) / (net[REQ_NET]->cycles_util)); + printf("Req_Network_in_buffer_full_per_cycle = %12.4f\n", + (float)(net[REQ_NET]->in_buffer_full) / (net[REQ_NET]->cycles)); + printf("Req_Network_in_buffer_avg_util = %12.4f\n", + ((float)(net[REQ_NET]->in_buffer_util) / (net[REQ_NET]->cycles) / + net[REQ_NET]->active_in_buffers)); + printf("Req_Network_out_buffer_full_per_cycle = %12.4f\n", + (float)(net[REQ_NET]->out_buffer_full) / (net[REQ_NET]->cycles)); + printf("Req_Network_out_buffer_avg_util = %12.4f\n", + ((float)(net[REQ_NET]->out_buffer_util) / (net[REQ_NET]->cycles) / + net[REQ_NET]->active_out_buffers)); + + printf("\n"); + printf("Reply_Network_injected_packets_num = %lld\n", + net[REPLY_NET]->packets_num); + printf("Reply_Network_cycles = %lld\n", net[REPLY_NET]->cycles); + printf("Reply_Network_injected_packets_per_cycle = %12.4f\n", + (float)(net[REPLY_NET]->packets_num) / (net[REPLY_NET]->cycles)); + printf("Reply_Network_conflicts_per_cycle = %12.4f\n", + (float)(net[REPLY_NET]->conflicts) / (net[REPLY_NET]->cycles)); + printf( + "Reply_Network_conflicts_per_cycle_util = %12.4f\n", + (float)(net[REPLY_NET]->conflicts_util) / (net[REPLY_NET]->cycles_util)); + printf("Reply_Bank_Level_Parallism = %12.4f\n", + (float)(net[REPLY_NET]->reqs_util) / (net[REPLY_NET]->cycles_util)); + printf("Reply_Network_in_buffer_full_per_cycle = %12.4f\n", + (float)(net[REPLY_NET]->in_buffer_full) / (net[REPLY_NET]->cycles)); + printf("Reply_Network_in_buffer_avg_util = %12.4f\n", + ((float)(net[REPLY_NET]->in_buffer_util) / (net[REPLY_NET]->cycles) / + net[REPLY_NET]->active_in_buffers)); + printf("Reply_Network_out_buffer_full_per_cycle = %12.4f\n", + (float)(net[REPLY_NET]->out_buffer_full) / (net[REPLY_NET]->cycles)); + printf("Reply_Network_out_buffer_avg_util = %12.4f\n", + ((float)(net[REPLY_NET]->out_buffer_util) / (net[REPLY_NET]->cycles) / + net[REPLY_NET]->active_out_buffers)); } void LocalInterconnect::DisplayOverallStats() const {} diff --git a/src/gpgpu-sim/local_interconnect.h b/src/gpgpu-sim/local_interconnect.h index ff55bad..dd10a06 100644 --- a/src/gpgpu-sim/local_interconnect.h +++ b/src/gpgpu-sim/local_interconnect.h @@ -45,15 +45,18 @@ struct inct_config { unsigned out_buffer_limit; unsigned subnets; Arbiteration_type arbiter_algo; - unsigned verbose; - unsigned grant_cycles; + unsigned verbose; + unsigned grant_cycles; }; class xbar_router { public: - xbar_router(unsigned router_id, enum Interconnect_type m_type, unsigned n_shader, unsigned n_mem, const struct inct_config& m_localinct_config); - ~xbar_router(); - void Push(unsigned input_deviceID, unsigned output_deviceID, void* data, unsigned int size); + xbar_router(unsigned router_id, enum Interconnect_type m_type, + unsigned n_shader, unsigned n_mem, + const struct inct_config& m_localinct_config); + ~xbar_router(); + void Push(unsigned input_deviceID, unsigned output_deviceID, void* data, + unsigned int size); void* Pop(unsigned ouput_deviceID); void Advance(); @@ -65,9 +68,9 @@ class xbar_router { // some stats unsigned long long cycles; unsigned long long conflicts; - unsigned long long conflicts_util; - unsigned long long cycles_util; - unsigned long long reqs_util; + unsigned long long conflicts_util; + unsigned long long cycles_util; + unsigned long long reqs_util; unsigned long long out_buffer_full; unsigned long long out_buffer_util; unsigned long long in_buffer_full; @@ -96,10 +99,10 @@ class xbar_router { enum Interconnect_type router_type; unsigned active_in_buffers, active_out_buffers; Arbiteration_type arbit_type; - unsigned verbose; + unsigned verbose; - unsigned grant_cycles; - unsigned grant_cycles_count; + unsigned grant_cycles; + unsigned grant_cycles_count; friend class LocalInterconnect; }; diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc index 952c9e9..456d891 100644 --- a/src/gpgpu-sim/mem_fetch.cc +++ b/src/gpgpu-sim/mem_fetch.cc @@ -65,10 +65,10 @@ mem_fetch::mem_fetch(const mem_access_t &access, const warp_inst_t *inst, icnt_flit_size = config->icnt_flit_size; original_mf = m_original_mf; original_wr_mf = m_original_wr_mf; - if(m_original_mf){ - m_raw_addr.chip=m_original_mf->get_tlx_addr().chip; - m_raw_addr.sub_partition=m_original_mf->get_tlx_addr().sub_partition; - } + if (m_original_mf) { + m_raw_addr.chip = m_original_mf->get_tlx_addr().chip; + m_raw_addr.sub_partition = m_original_mf->get_tlx_addr().sub_partition; + } } mem_fetch::~mem_fetch() { m_status = MEM_FETCH_DELETED; } diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h index 1e5e04e..e039846 100644 --- a/src/gpgpu-sim/mem_fetch.h +++ b/src/gpgpu-sim/mem_fetch.h @@ -76,8 +76,10 @@ class mem_fetch { void print(FILE *fp, bool print_inst = true) const; const addrdec_t &get_tlx_addr() const { return m_raw_addr; } - void set_chip(unsigned chip_id) { m_raw_addr.chip = chip_id; } - void set_parition(unsigned sub_partition_id) { m_raw_addr.sub_partition = sub_partition_id; } + void set_chip(unsigned chip_id) { m_raw_addr.chip = chip_id; } + void set_parition(unsigned sub_partition_id) { + m_raw_addr.sub_partition = sub_partition_id; + } unsigned get_data_size() const { return m_data_size; } void set_data_size(unsigned size) { m_data_size = size; } unsigned get_ctrl_size() const { return m_ctrl_size; } diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc index 7055769..63d7ee8 100644 --- a/src/gpgpu-sim/mem_latency_stat.cc +++ b/src/gpgpu-sim/mem_latency_stat.cc @@ -39,10 +39,10 @@ #include "stat-tool.h" #include "visualizer.h" +#include #include #include #include -#include #include "../../libcuda/gpgpu_context.h" @@ -228,16 +228,19 @@ void memory_stats_t::memlatstat_dram_access(mem_fetch *mf) { bankwrites[mf->get_sid()][dram_id][bank]++; shader_mem_acc_log(mf->get_sid(), dram_id, bank, 'w'); } - totalbankwrites[dram_id][bank] += ceil(mf->get_data_size() / m_memory_config->dram_atom_size); + totalbankwrites[dram_id][bank] += + ceil(mf->get_data_size() / m_memory_config->dram_atom_size); } else { bankreads[mf->get_sid()][dram_id][bank]++; shader_mem_acc_log(mf->get_sid(), dram_id, bank, 'r'); - totalbankreads[dram_id][bank] += ceil(mf->get_data_size() / m_memory_config->dram_atom_size); + totalbankreads[dram_id][bank] += + ceil(mf->get_data_size() / m_memory_config->dram_atom_size); } - mem_access_type_stats[mf->get_access_type()][dram_id][bank] += ceil(mf->get_data_size() / m_memory_config->dram_atom_size); + mem_access_type_stats[mf->get_access_type()][dram_id][bank] += + ceil(mf->get_data_size() / m_memory_config->dram_atom_size); } - if (mf->get_pc() != (unsigned)-1) + if (mf->get_pc() != (unsigned)-1) m_gpu->gpgpu_ctx->stats->ptx_file_line_stats_add_dram_traffic( mf->get_pc(), mf->get_data_size()); } diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 268d4d4..ebb6878 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -36,6 +36,7 @@ #include "../cuda-sim/ptx-stats.h" #include "../cuda-sim/ptx_sim.h" #include "../statwrapper.h" +#include "../trace-driven/trace_driven.h" #include "addrdec.h" #include "dram.h" #include "gpu-misc.h" @@ -47,7 +48,6 @@ #include "stat-tool.h" #include "traffic_breakdown.h" #include "visualizer.h" -#include "../trace-driven/trace_driven.h" #define PRIORITIZE_MSHR_OVER_WB 1 #define MAX(a, b) (((a) > (b)) ? (a) : (b)) @@ -368,12 +368,12 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, m_fu.push_back(new dp_unit(&m_pipeline_reg[EX_WB], m_config, this)); m_dispatch_port.push_back(ID_OC_DP); m_issue_port.push_back(OC_EX_DP); - } + } for (int k = 0; k < m_config->gpgpu_num_int_units; k++) { m_fu.push_back(new int_unit(&m_pipeline_reg[EX_WB], m_config, this)); m_dispatch_port.push_back(ID_OC_INT); m_issue_port.push_back(OC_EX_INT); - } + } for (int k = 0; k < m_config->gpgpu_num_sfu_units; k++) { m_fu.push_back(new sfu(&m_pipeline_reg[EX_WB], m_config, this)); @@ -442,11 +442,12 @@ void shader_core_ctx::reinit(unsigned start_thread, unsigned end_thread, } } -void shader_core_ctx::init_warps( unsigned cta_id, unsigned start_thread, unsigned end_thread, unsigned ctaid, int cta_size, kernel_info_t &kernel ) -{ - // - address_type start_pc = next_pc(start_thread); - unsigned kernel_id = kernel.get_uid(); +void shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread, + unsigned end_thread, unsigned ctaid, + int cta_size, kernel_info_t &kernel) { + // + address_type start_pc = next_pc(start_thread); + unsigned kernel_id = kernel.get_uid(); if (m_config->model == POST_DOMINATOR) { unsigned start_warp = start_thread / m_config->warp_size; unsigned warp_per_cta = cta_size / m_config->warp_size; @@ -475,10 +476,10 @@ void shader_core_ctx::init_warps( unsigned cta_id, unsigned start_thread, unsign m_simt_stack[i]->resume(fname); m_simt_stack[i]->get_pdom_stack_top_info(&pc, &rpc); for (unsigned t = 0; t < m_config->warp_size; t++) { - if(m_thread != NULL) { - m_thread[i * m_config->warp_size + t]->set_npc(pc); - m_thread[i * m_config->warp_size + t]->update_pc(); - } + if (m_thread != NULL) { + m_thread[i * m_config->warp_size + t]->set_npc(pc); + m_thread[i * m_config->warp_size + t]->update_pc(); + } } start_pc = pc; } @@ -487,12 +488,13 @@ void shader_core_ctx::init_warps( unsigned cta_id, unsigned start_thread, unsign ++m_dynamic_warp_id; m_not_completed += n_active; ++m_active_warps; - } + } - if(m_gpu->get_config().is_trace_driven_mode()){ - trace_shader_core_ctx* trace_core = static_cast (this); - trace_core->init_traces( start_warp, end_warp, kernel ); - } + if (m_gpu->get_config().is_trace_driven_mode()) { + trace_shader_core_ctx *trace_core = + static_cast(this); + trace_core->init_traces(start_warp, end_warp, kernel); + } } } @@ -782,45 +784,47 @@ void shader_core_stats::visualizer_print(gzFile visualizer_file) { check ptx_ir.h to verify this does not overlap \ other memory spaces */ void shader_core_ctx::decode() { - if( m_inst_fetch_buffer.m_valid ) { - // decode 1 or 2 instructions and place them into ibuffer - address_type pc = m_inst_fetch_buffer.m_pc; - const warp_inst_t* pI1; - if(m_gpu->get_config().is_trace_driven_mode()){ - trace_shader_core_ctx* trace_core = static_cast (this); - pI1 = trace_core->m_trace_warp[m_inst_fetch_buffer.m_warp_id].get_next_inst(); - } - else - pI1 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc); - m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(0,pI1); + if (m_inst_fetch_buffer.m_valid) { + // decode 1 or 2 instructions and place them into ibuffer + address_type pc = m_inst_fetch_buffer.m_pc; + const warp_inst_t *pI1; + if (m_gpu->get_config().is_trace_driven_mode()) { + trace_shader_core_ctx *trace_core = + static_cast(this); + pI1 = trace_core->m_trace_warp[m_inst_fetch_buffer.m_warp_id] + .get_next_inst(); + } else + pI1 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc); + m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(0, pI1); + m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline(); + if (pI1) { + m_stats->m_num_decoded_insn[m_sid]++; + if (pI1->oprnd_type == INT_OP) { + m_stats->m_num_INTdecoded_insn[m_sid]++; + } else if (pI1->oprnd_type == FP_OP) { + m_stats->m_num_FPdecoded_insn[m_sid]++; + } + const warp_inst_t *pI2; + if (m_gpu->get_config().is_trace_driven_mode()) { + trace_shader_core_ctx *trace_core = + static_cast(this); + pI2 = trace_core->m_trace_warp[m_inst_fetch_buffer.m_warp_id] + .get_next_inst(); + } else + pI2 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc + pI1->isize); + if (pI2) { + m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(1, pI2); m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline(); - if( pI1 ) { - m_stats->m_num_decoded_insn[m_sid]++; - if(pI1->oprnd_type==INT_OP){ - m_stats->m_num_INTdecoded_insn[m_sid]++; - }else if(pI1->oprnd_type==FP_OP) { - m_stats->m_num_FPdecoded_insn[m_sid]++; - } - const warp_inst_t* pI2; - if(m_gpu->get_config().is_trace_driven_mode()){ - trace_shader_core_ctx* trace_core = static_cast (this); - pI2 = trace_core->m_trace_warp[m_inst_fetch_buffer.m_warp_id].get_next_inst(); - } - else - pI2 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc+pI1->isize); - if( pI2 ) { - m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(1,pI2); - m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline(); - m_stats->m_num_decoded_insn[m_sid]++; - if(pI2->oprnd_type==INT_OP){ - m_stats->m_num_INTdecoded_insn[m_sid]++; - }else if(pI2->oprnd_type==FP_OP) { - m_stats->m_num_FPdecoded_insn[m_sid]++; - } - } + m_stats->m_num_decoded_insn[m_sid]++; + if (pI2->oprnd_type == INT_OP) { + m_stats->m_num_INTdecoded_insn[m_sid]++; + } else if (pI2->oprnd_type == FP_OP) { + m_stats->m_num_FPdecoded_insn[m_sid]++; } - m_inst_fetch_buffer.m_valid = false; + } } + m_inst_fetch_buffer.m_valid = false; + } } void shader_core_ctx::fetch() { @@ -830,15 +834,16 @@ void shader_core_ctx::fetch() { m_warp[mf->get_wid()].clear_imiss_pending(); m_inst_fetch_buffer = ifetch_buffer_t( m_warp[mf->get_wid()].get_pc(), mf->get_access_size(), mf->get_wid()); - if(m_gpu->get_config().is_trace_driven_mode()){ - trace_shader_core_ctx* trace_core = static_cast (this); - assert( trace_core->m_trace_warp[mf->get_wid()].get_pc() == (address_type)(mf->get_addr()-PROGRAM_MEM_START)); - } - else - assert(m_warp[mf->get_wid()].get_pc() == - (mf->get_addr() - - PROGRAM_MEM_START)); // Verify that we got the instruction we - // were expecting. + if (m_gpu->get_config().is_trace_driven_mode()) { + trace_shader_core_ctx *trace_core = + static_cast(this); + assert(trace_core->m_trace_warp[mf->get_wid()].get_pc() == + (address_type)(mf->get_addr() - PROGRAM_MEM_START)); + } else + assert(m_warp[mf->get_wid()].get_pc() == + (mf->get_addr() - + PROGRAM_MEM_START)); // Verify that we got the instruction we + // were expecting. m_inst_fetch_buffer.m_valid = true; m_warp[mf->get_wid()].set_last_fetch(m_gpu->gpu_sim_cycle); delete mf; @@ -861,14 +866,15 @@ void shader_core_ctx::fetch() { if (m_threadState[tid].m_active == true) { m_threadState[tid].m_active = false; unsigned cta_id = m_warp[warp_id].get_cta_id(); - if(m_gpu->get_config().is_trace_driven_mode()) { - register_cta_thread_exit(cta_id, m_kernel); - } - else - register_cta_thread_exit(cta_id, &(m_thread[tid]->get_kernel())); + if (m_gpu->get_config().is_trace_driven_mode()) { + register_cta_thread_exit(cta_id, m_kernel); + } else + register_cta_thread_exit(cta_id, + &(m_thread[tid]->get_kernel())); m_not_completed -= 1; m_active_threads.reset(tid); - if(!m_gpu->get_config().is_trace_driven_mode()) assert( m_thread[tid]!= NULL ); + if (!m_gpu->get_config().is_trace_driven_mode()) + assert(m_thread[tid] != NULL); did_exit = true; } } @@ -878,38 +884,39 @@ void shader_core_ctx::fetch() { } // this code fetches instructions from the i-cache or generates memory - if( !m_warp[warp_id].functional_done() && !m_warp[warp_id].imiss_pending() && m_warp[warp_id].ibuffer_empty() ) { - address_type pc; - if(m_gpu->get_config().is_trace_driven_mode()){ - trace_shader_core_ctx* trace_core = static_cast (this); - pc = trace_core->m_trace_warp[warp_id].get_pc(); - } - else - pc = m_warp[warp_id].get_pc(); - address_type ppc = pc + PROGRAM_MEM_START; - unsigned nbytes= m_gpu->get_config().is_trace_driven_mode()? 32 : 16; - unsigned offset_in_block = pc & (m_config->m_L1I_config.get_line_sz()-1); + if (!m_warp[warp_id].functional_done() && + !m_warp[warp_id].imiss_pending() && + m_warp[warp_id].ibuffer_empty()) { + address_type pc; + if (m_gpu->get_config().is_trace_driven_mode()) { + trace_shader_core_ctx *trace_core = + static_cast(this); + pc = trace_core->m_trace_warp[warp_id].get_pc(); + } else + pc = m_warp[warp_id].get_pc(); + address_type ppc = pc + PROGRAM_MEM_START; + unsigned nbytes = + m_gpu->get_config().is_trace_driven_mode() ? 32 : 16; + unsigned offset_in_block = + pc & (m_config->m_L1I_config.get_line_sz() - 1); if ((offset_in_block + nbytes) > m_config->m_L1I_config.get_line_sz()) nbytes = (m_config->m_L1I_config.get_line_sz() - offset_in_block); // TODO: replace with use of allocator // mem_fetch *mf = m_mem_fetch_allocator->alloc() mem_access_t acc(INST_ACC_R, ppc, nbytes, false, m_gpu->gpgpu_ctx); - mem_fetch *mf = new mem_fetch(acc, - NULL/*we don't have an instruction yet*/, - READ_PACKET_SIZE, - warp_id, - m_sid, - m_tpc, - m_memory_config, - m_gpu->gpu_tot_sim_cycle+m_gpu->gpu_sim_cycle - ); - std::list events; - enum cache_request_status status; - if(m_config->perfect_inst_const_cache) - status = HIT; - else - status = m_L1I->access( (new_addr_type)ppc, mf, m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle,events); + mem_fetch *mf = new mem_fetch( + acc, NULL /*we don't have an instruction yet*/, READ_PACKET_SIZE, + warp_id, m_sid, m_tpc, m_memory_config, + m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle); + std::list events; + enum cache_request_status status; + if (m_config->perfect_inst_const_cache) + status = HIT; + else + status = m_L1I->access( + (new_addr_type)ppc, mf, + m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle, events); if (status == MISS) { m_last_warp_fetched = warp_id; @@ -948,33 +955,33 @@ void shader_core_ctx::issue_warp(register_set &pipe_reg_set, unsigned warp_id, unsigned sch_id) { warp_inst_t **pipe_reg = pipe_reg_set.get_free(m_config->sub_core_model, sch_id); - assert(pipe_reg); + assert(pipe_reg); - m_warp[warp_id].ibuffer_free(); - assert(next_inst->valid()); - **pipe_reg = *next_inst; // static instruction information + m_warp[warp_id].ibuffer_free(); + assert(next_inst->valid()); + **pipe_reg = *next_inst; // static instruction information (*pipe_reg)->issue(active_mask, warp_id, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, m_warp[warp_id].get_dynamic_warp_id(), sch_id); // dynamic instruction information - m_stats->shader_cycle_distro[2+(*pipe_reg)->active_count()]++; - func_exec_inst( **pipe_reg ); + m_stats->shader_cycle_distro[2 + (*pipe_reg)->active_count()]++; + func_exec_inst(**pipe_reg); - if( next_inst->op == BARRIER_OP ){ - m_warp[warp_id].store_info_of_last_inst_at_barrier(*pipe_reg); + if (next_inst->op == BARRIER_OP) { + m_warp[warp_id].store_info_of_last_inst_at_barrier(*pipe_reg); m_barriers.warp_reaches_barrier(m_warp[warp_id].get_cta_id(), warp_id, const_cast(next_inst)); - }else if( next_inst->op == MEMORY_BARRIER_OP ){ - m_warp[warp_id].set_membar(); - } - - if(!m_gpu->get_config().is_trace_driven_mode()) //No SIMT-stack in trace-driven mode - updateSIMTStack(warp_id,*pipe_reg); + } else if (next_inst->op == MEMORY_BARRIER_OP) { + m_warp[warp_id].set_membar(); + } - m_scoreboard->reserveRegisters(*pipe_reg); - m_warp[warp_id].set_next_pc(next_inst->pc + next_inst->isize); + if (!m_gpu->get_config() + .is_trace_driven_mode()) // No SIMT-stack in trace-driven mode + updateSIMTStack(warp_id, *pipe_reg); + m_scoreboard->reserveRegisters(*pipe_reg); + m_warp[warp_id].set_next_pc(next_inst->pc + next_inst->isize); } void shader_core_ctx::issue() { @@ -1110,15 +1117,18 @@ void scheduler_unit::cycle() { // dual issue to diff execution // units (as in Maxwell and // Pascal) - - if(warp(warp_id).ibuffer_empty()) - SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) fails as ibuffer_empty\n", - (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id() ); - - if(warp(warp_id).waiting()) - SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) fails as waiting for barrier\n", - (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id() ); - + + if (warp(warp_id).ibuffer_empty()) + SCHED_DPRINTF( + "Warp (warp_id %u, dynamic_warp_id %u) fails as ibuffer_empty\n", + (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id()); + + if (warp(warp_id).waiting()) + SCHED_DPRINTF( + "Warp (warp_id %u, dynamic_warp_id %u) fails as waiting for " + "barrier\n", + (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id()); + while (!warp(warp_id).waiting() && !warp(warp_id).ibuffer_empty() && (checked < max_issue) && (checked <= issued) && (issued < max_issue)) { @@ -1133,10 +1143,11 @@ void scheduler_unit::cycle() { bool valid = warp(warp_id).ibuffer_next_valid(); bool warp_inst_issued = false; unsigned pc, rpc; - if(m_shader->m_gpu->get_config().is_trace_driven_mode()) - pc = pI->pc; //assume no control hazard in trace mode. TO DO: to be fixed - else - m_simt_stack[warp_id]->get_pdom_stack_top_info(&pc,&rpc); + if (m_shader->m_gpu->get_config().is_trace_driven_mode()) + pc = pI->pc; // assume no control hazard in trace mode. TO DO: to be + // fixed + else + m_simt_stack[warp_id]->get_pdom_stack_top_info(&pc, &rpc); SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) has valid instruction (%s)\n", (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id(), @@ -1160,9 +1171,12 @@ void scheduler_unit::cycle() { (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id()); ready_inst = true; - //For Trace-driven, the active mask already set in from traces, so just read it from the inst - const active_mask_t &active_mask = m_shader->m_gpu->get_config().is_trace_driven_mode()? - pI->get_active_mask() : m_simt_stack[warp_id]->get_active_mask(); + // For Trace-driven, the active mask already set in from traces, so + // just read it from the inst + const active_mask_t &active_mask = + m_shader->m_gpu->get_config().is_trace_driven_mode() + ? pI->get_active_mask() + : m_simt_stack[warp_id]->get_active_mask(); assert(warp(warp_id).inst_in_pipeline()); @@ -1182,14 +1196,24 @@ void scheduler_unit::cycle() { previous_issued_inst_exec_type = exec_unit_type_t::MEM; } } else { - - bool sp_pipe_avail = (m_shader->m_config->gpgpu_num_sp_units > 0) && m_sp_out->has_free(m_shader->m_config->sub_core_model, m_id); - bool sfu_pipe_avail = (m_shader->m_config->gpgpu_num_sfu_units > 0) && m_sfu_out->has_free(m_shader->m_config->sub_core_model, m_id); - bool tensor_core_pipe_avail = (m_shader->m_config->gpgpu_num_tensor_core_units > 0) && m_tensor_core_out->has_free(m_shader->m_config->sub_core_model, m_id); - bool dp_pipe_avail = (m_shader->m_config->gpgpu_num_dp_units > 0) && m_dp_out->has_free(m_shader->m_config->sub_core_model, m_id); - bool int_pipe_avail = (m_shader->m_config->gpgpu_num_int_units > 0) && m_int_out->has_free(m_shader->m_config->sub_core_model, m_id); - - //This code need to be refactored + bool sp_pipe_avail = + (m_shader->m_config->gpgpu_num_sp_units > 0) && + m_sp_out->has_free(m_shader->m_config->sub_core_model, m_id); + bool sfu_pipe_avail = + (m_shader->m_config->gpgpu_num_sfu_units > 0) && + m_sfu_out->has_free(m_shader->m_config->sub_core_model, m_id); + bool tensor_core_pipe_avail = + (m_shader->m_config->gpgpu_num_tensor_core_units > 0) && + m_tensor_core_out->has_free( + m_shader->m_config->sub_core_model, m_id); + bool dp_pipe_avail = + (m_shader->m_config->gpgpu_num_dp_units > 0) && + m_dp_out->has_free(m_shader->m_config->sub_core_model, m_id); + bool int_pipe_avail = + (m_shader->m_config->gpgpu_num_int_units > 0) && + m_int_out->has_free(m_shader->m_config->sub_core_model, m_id); + + // This code need to be refactored if (pI->op != TENSOR_CORE_OP && pI->op != SFU_OP && pI->op != DP_OP) { bool execute_on_SP = false; @@ -1278,10 +1302,12 @@ void scheduler_unit::cycle() { warp_inst_issued = true; previous_issued_inst_exec_type = exec_unit_type_t::SFU; } - } - else if ( (pI->op == TENSOR_CORE_OP) && !(diff_exec_units && previous_issued_inst_exec_type == exec_unit_type_t::TENSOR) ) { - if( tensor_core_pipe_avail ) { - m_shader->issue_warp(*m_tensor_core_out,pI,active_mask,warp_id,m_id); + } else if ((pI->op == TENSOR_CORE_OP) && + !(diff_exec_units && previous_issued_inst_exec_type == + exec_unit_type_t::TENSOR)) { + if (tensor_core_pipe_avail) { + m_shader->issue_warp(*m_tensor_core_out, pI, active_mask, + warp_id, m_id); issued++; issued_inst = true; warp_inst_issued = true; @@ -1698,13 +1724,11 @@ void shader_core_ctx::writeback() { } } -bool ldst_unit::shared_cycle( warp_inst_t &inst, mem_stage_stall_type &rc_fail, mem_stage_access_type &fail_type) -{ - if( inst.space.get_type() != shared_space ) - return true; +bool ldst_unit::shared_cycle(warp_inst_t &inst, mem_stage_stall_type &rc_fail, + mem_stage_access_type &fail_type) { + if (inst.space.get_type() != shared_space) return true; - if( inst.active_count() == 0 ) - return true; + if (inst.active_count() == 0) return true; if (inst.has_dispatch_delay()) { m_stats->gpgpu_n_shmem_bank_access[m_sid]++; @@ -1908,18 +1932,17 @@ bool ldst_unit::constant_cycle(warp_inst_t &inst, mem_stage_stall_type &rc_fail, return true; if (inst.active_count() == 0) return true; - mem_stage_stall_type fail; - if(m_config->perfect_inst_const_cache) { - fail = NO_RC_FAIL; - while(inst.accessq_count() > 0) inst.accessq_pop_back(); - if ( inst.is_load() ) { - for ( unsigned r=0; r < MAX_OUTPUT_VALUES; r++) - if (inst.out[r] > 0) - m_pending_writes[inst.warp_id()][inst.out[r]]--; - } - } else { - fail = process_memory_access_queue(m_L1C,inst); - } + mem_stage_stall_type fail; + if (m_config->perfect_inst_const_cache) { + fail = NO_RC_FAIL; + while (inst.accessq_count() > 0) inst.accessq_pop_back(); + if (inst.is_load()) { + for (unsigned r = 0; r < MAX_OUTPUT_VALUES; r++) + if (inst.out[r] > 0) m_pending_writes[inst.warp_id()][inst.out[r]]--; + } + } else { + fail = process_memory_access_queue(m_L1C, inst); + } if (fail != NO_RC_FAIL) { rc_fail = fail; // keep other fails if this didn't fail. @@ -1952,10 +1975,8 @@ bool ldst_unit::memory_cycle(warp_inst_t &inst, (inst.space.get_type() != local_space) && (inst.space.get_type() != param_space_local))) return true; - if( inst.active_count() == 0 ) - return true; - if( inst.accessq_empty() ) - return true; + if (inst.active_count() == 0) return true; + if (inst.accessq_empty()) return true; mem_stage_stall_type stall_cond = NO_RC_FAIL; const mem_access_t &access = inst.accessq_back(); @@ -2359,9 +2380,10 @@ void ldst_unit::writeback() { if (!m_pipeline_reg[0]->empty()) { m_next_wb = *m_pipeline_reg[0]; if (m_next_wb.isatomic()) { - if(!m_core->get_gpu()->get_config().is_trace_driven_mode()) - m_next_wb.do_atomic(); - m_core->decrement_atomic_count(m_next_wb.warp_id(), m_next_wb.active_count()); + if (!m_core->get_gpu()->get_config().is_trace_driven_mode()) + m_next_wb.do_atomic(); + m_core->decrement_atomic_count(m_next_wb.warp_id(), + m_next_wb.active_count()); } m_core->dec_inst_in_pipeline(m_pipeline_reg[0]->warp_id()); m_pipeline_reg[0]->clear(); @@ -2387,11 +2409,11 @@ void ldst_unit::writeback() { case 3: // global/local if (m_next_global) { m_next_wb = m_next_global->get_inst(); - if( m_next_global->isatomic() ) { + if (m_next_global->isatomic()) { m_core->decrement_atomic_count( m_next_global->get_wid(), m_next_global->get_access_warp_mask().count()); - } + } delete m_next_global; m_next_global = NULL; serviced_client = next_client; @@ -2446,11 +2468,10 @@ inst->space.get_type() != shared_space) { unsigned warp_id = inst->warp_id(); pipelined_simd_unit::issue(reg_set); } */ -void ldst_unit::cycle() -{ - writeback(); - for(int i=0; i< m_config->reg_file_port_throughput; ++i) - m_operand_collector->step(); +void ldst_unit::cycle() { + writeback(); + for (int i = 0; i < m_config->reg_file_port_throughput; ++i) + m_operand_collector->step(); for (unsigned stage = 0; (stage + 1) < m_pipeline_depth; stage++) if (m_pipeline_reg[stage]->empty() && !m_pipeline_reg[stage + 1]->empty()) move_warp(m_pipeline_reg[stage], m_pipeline_reg[stage + 1]); @@ -3169,11 +3190,11 @@ unsigned int shader_core_config::max_cta(const kernel_info_t &k) const { switch (adaptive_cache_config) { case FIXED: break; - case ADAPTIVE_VOLTA: { + case ADAPTIVE_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 + // 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(); @@ -3258,10 +3279,10 @@ void shader_core_ctx::cycle() { execute(); read_operands(); issue(); - for(int i=0; i< m_config->inst_fetch_throughput; ++i) { + for (int i = 0; i < m_config->inst_fetch_throughput; ++i) { decode(); fetch(); - } + } } // Flushes all content of the cache to memory @@ -3310,31 +3331,34 @@ std::list opndcoll_rfu_t::arbiter_t::allocate_reads() { ///// wavefront allocator from booksim... ---> // Loop through diagonals of request matrix - // printf("####\n"); + // printf("####\n"); for (int p = 0; p < _square; ++p) { - output = ( _pri + p ) % _outputs; + output = (_pri + p) % _outputs; // Step through the current diagonal for (input = 0; input < _inputs; ++input) { assert(input < _inputs); assert(output < _outputs); - if ( ( output < _outputs ) && - ( _inmatch[input] == -1 ) && - //( _outmatch[output] == -1 ) && //allow OC to read multiple reg banks at the same cycle + if ((output < _outputs) && (_inmatch[input] == -1) && + //( _outmatch[output] == -1 ) && //allow OC to read multiple reg + //banks at the same cycle (_request[input][output] /*.label != -1*/)) { // Grant! _inmatch[input] = output; _outmatch[output] = input; - // printf("Register File: granting bank %d to OC %d, schedid %d, warpid %d, Regid %d\n", input, output, (m_queue[input].front()).get_sid(), (m_queue[input].front()).get_wid(), (m_queue[input].front()).get_reg()); + // printf("Register File: granting bank %d to OC %d, schedid %d, warpid + // %d, Regid %d\n", input, output, (m_queue[input].front()).get_sid(), + // (m_queue[input].front()).get_wid(), + // (m_queue[input].front()).get_reg()); } - output = ( output + 1 ) % _outputs; + output = (output + 1) % _outputs; } } // Round-robin the priority diagonal - _pri = ( _pri + 1 ) % _outputs; + _pri = (_pri + 1) % _outputs; /// <--- end code from booksim @@ -3560,15 +3584,15 @@ bool shader_core_ctx::warp_waiting_at_mem_barrier(unsigned warp_id) { if (!m_warp[warp_id].get_membar()) return false; if (!m_scoreboard->pendingWrites(warp_id)) { m_warp[warp_id].clear_membar(); - if (m_gpu->get_config().flush_l1()) { - //Mahmoud fixed this on Nov 2019 - //Invalidate L1 cache - //Based on Nvidia Doc, at MEM barrier, we have to - //(1) wait for all pending writes till they are acked - //(2) invalidate L1 cache to ensure coherence and avoid reading stall data - cache_invalidate(); - //TO DO: you need to stall the SM for 5k cycles. - } + if (m_gpu->get_config().flush_l1()) { + // Mahmoud fixed this on Nov 2019 + // Invalidate L1 cache + // Based on Nvidia Doc, at MEM barrier, we have to + //(1) wait for all pending writes till they are acked + //(2) invalidate L1 cache to ensure coherence and avoid reading stall data + cache_invalidate(); + // TO DO: you need to stall the SM for 5k cycles. + } return false; } return true; @@ -4013,10 +4037,12 @@ simt_core_cluster::simt_core_cluster(class gpgpu_sim *gpu, unsigned cluster_id, m_core = new shader_core_ctx *[config->n_simt_cores_per_cluster]; for (unsigned i = 0; i < config->n_simt_cores_per_cluster; i++) { unsigned sid = m_config->cid_to_sid(i, m_cluster_id); - if(gpu->get_config().is_trace_driven_mode()) - m_core[i] = new trace_shader_core_ctx(gpu,this,sid,m_cluster_id,config,mem_config,stats); - else - m_core[i] = new shader_core_ctx(gpu,this,sid,m_cluster_id,config,mem_config,stats); + if (gpu->get_config().is_trace_driven_mode()) + m_core[i] = new trace_shader_core_ctx(gpu, this, sid, m_cluster_id, + config, mem_config, stats); + else + m_core[i] = new shader_core_ctx(gpu, this, sid, m_cluster_id, config, + mem_config, stats); m_core_sim_order.push_back(i); } } @@ -4357,5 +4383,3 @@ void shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, } } } - - diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 7d8b77a..bd08794 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1531,16 +1531,15 @@ class shader_core_config : public core_config { // Jin: concurrent kernel on sm bool gpgpu_concurrent_kernel_sm; - bool perfect_inst_const_cache; - unsigned inst_fetch_throughput; - unsigned reg_file_port_throughput; - - char* trace_opcode_latency_initiation_int; - char* trace_opcode_latency_initiation_sp; - char* trace_opcode_latency_initiation_dp; - char* trace_opcode_latency_initiation_sfu; - char* trace_opcode_latency_initiation_tensor; - + bool perfect_inst_const_cache; + unsigned inst_fetch_throughput; + unsigned reg_file_port_throughput; + + char *trace_opcode_latency_initiation_int; + char *trace_opcode_latency_initiation_sp; + char *trace_opcode_latency_initiation_dp; + char *trace_opcode_latency_initiation_sfu; + char *trace_opcode_latency_initiation_tensor; }; struct shader_core_stats_pod { @@ -2062,8 +2061,10 @@ class shader_core_ctx : public core_t { } int test_res_bus(int latency); - void init_warps(unsigned cta_id, unsigned start_thread, unsigned end_thread,unsigned ctaid, int cta_size, kernel_info_t &kernel); - virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid); + void init_warps(unsigned cta_id, unsigned start_thread, unsigned end_thread, + unsigned ctaid, int cta_size, kernel_info_t &kernel); + virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, + unsigned tid); address_type next_pc(int tid) const; void fetch(); void register_cta_thread_exit(unsigned cta_num, kernel_info_t *kernel); @@ -2077,7 +2078,7 @@ class shader_core_ctx : public core_t { void issue_warp(register_set &warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id, unsigned sch_id); - virtual void func_exec_inst( warp_inst_t &inst ); + virtual void func_exec_inst(warp_inst_t &inst); // Returns numbers of addresses in translated_addrs unsigned translate_local_memaddr(address_type localaddr, unsigned tid, @@ -2176,7 +2177,7 @@ class shader_core_ctx : public core_t { std::bitset m_occupied_hwtid; std::map m_occupied_cta_to_hwtid; - friend class trace_shader_core_ctx; + friend class trace_shader_core_ctx; }; class simt_core_cluster { diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc index d6d0b23..6ec3867 100644 --- a/src/gpgpusim_entrypoint.cc +++ b/src/gpgpusim_entrypoint.cc @@ -232,35 +232,39 @@ 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; +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) { diff --git a/src/trace-driven/ISA_Def/kepler_opcode.h b/src/trace-driven/ISA_Def/kepler_opcode.h index 675ea6c..c2f8548 100644 --- a/src/trace-driven/ISA_Def/kepler_opcode.h +++ b/src/trace-driven/ISA_Def/kepler_opcode.h @@ -1,149 +1,148 @@ -//developed by Mahmoud Khairy, Purdue Univ -//abdallm@purdue.edu +// developed by Mahmoud Khairy, Purdue Univ +// abdallm@purdue.edu #ifndef KEPLER_OPCODE_H #define KEPLER_OPCODE_H -#include "trace_opcode.h" -#include #include +#include +#include "trace_opcode.h" #define KEPLER_BINART_VERSION 35 #define KEPLER_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 -//TO DO: moving this to a yml or def files - -///Kepler ISA -//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map Kepler_OpcodeMap = { - //Floating Point 32 Instructions - {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, - {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, - {"FADD", OpcodeChar(OP_FADD, SP_OP)}, - {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, - {"FCMP", OpcodeChar(OP_FCMP, SP_OP)}, - {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, - {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, - {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, - {"FSWZ", OpcodeChar(OP_FSWZ, SP_OP)}, - {"FSET", OpcodeChar(OP_FSET, SP_OP)}, - {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, - {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, - {"RRO", OpcodeChar(OP_RRO, SP_OP)}, - //SFU - {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, - - - //Double Point Instructions - {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, - {"DADD", OpcodeChar(OP_DADD, DP_OP)}, - {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, - {"DMNMX", OpcodeChar(OP_DMNMX, DP_OP)}, - {"DSET", OpcodeChar(OP_DSET, DP_OP)}, - {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, - - //Integer Instructions - {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, - {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, - {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, - {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, - {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, - {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, - {"ISUB", OpcodeChar(OP_ISUB, INTP_OP)}, - {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, - {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, - {"ISAD", OpcodeChar(OP_ISAD, INTP_OP)}, - {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, - {"BFE", OpcodeChar(OP_BFE, INTP_OP)}, - {"BFI", OpcodeChar(OP_BFI, INTP_OP)}, - {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, - {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, - {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, - {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, - {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, - {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, - {"ISET", OpcodeChar(OP_ISET, INTP_OP)}, - {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, - {"ICMP", OpcodeChar(OP_ICMP, INTP_OP)}, - {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, - - //Conversion Instructions - {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, - {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, - {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, - {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, - - //Movement Instructions - {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, - {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, - {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, - {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, - {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, - - //Predicate Instructions - {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, - {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, - {"CSET", OpcodeChar(OP_CSET, ALU_OP)}, - {"CSETP", OpcodeChar(OP_CSETP, ALU_OP)}, - {"PSET", OpcodeChar(OP_PSET, ALU_OP)}, - {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, - - //Texture Instructions - //For now, we ignore texture loads, consider it as ALU_OP - {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, - {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, - {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, - {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, - - //Load/Store Instructions - //For now, we ignore constant loads, consider it as ALU_OP, TO DO - {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, - //in Kepler, LD is load global so set it to LDG - {"LD", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, - {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, - {"LDSLK", OpcodeChar(OP_LDSLK, LOAD_OP)}, - {"ST", OpcodeChar(OP_STG, STORE_OP)}, - {"STL", OpcodeChar(OP_STL, STORE_OP)}, - {"STS", OpcodeChar(OP_STS, STORE_OP)}, - {"STSCUL", OpcodeChar(OP_STSCUL, STORE_OP)}, - {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, - {"RED", OpcodeChar(OP_RED, STORE_OP)}, - {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, - {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, - {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, - - //surface memory instructions - {"SUCLAMP", OpcodeChar(OP_SUCLAMP, LOAD_OP)}, - {"SUBFM", OpcodeChar(OP_SUBFM, LOAD_OP)}, - {"SUEAU", OpcodeChar(OP_SUEAU, LOAD_OP)}, - {"SULDGA", OpcodeChar(OP_SULDGA, LOAD_OP)}, - {"SUSTGA", OpcodeChar(OP_SUSTGA, STORE_OP)}, - - //Control Instructions - {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, - {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, - {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, - {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, - {"CAL", OpcodeChar(OP_CAL, CALL_OPS)}, - {"JCAL", OpcodeChar(OP_JCAL, CALL_OPS)}, - {"RET", OpcodeChar(OP_RET, RET_OPS)}, - {"BRK", OpcodeChar(OP_BRK, RET_OPS)}, - {"CONT", OpcodeChar(OP_CONT, RET_OPS)}, - {"SSY", OpcodeChar(OP_SSY, RET_OPS)}, - {"PBK", OpcodeChar(OP_PBK, RET_OPS)}, - {"PCNT", OpcodeChar(OP_PCNT, RET_OPS)}, - {"PRET", OpcodeChar(OP_PRET, RET_OPS)}, - {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, - {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, - - //Miscellaneous Instructions - {"NOP", OpcodeChar(OP_NOP, ALU_OP)}, - {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, - {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, - {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, - {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, +// TO DO: moving this to a yml or def files + +/// Kepler ISA +// see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html +static const std::unordered_map Kepler_OpcodeMap = { + // Floating Point 32 Instructions + {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, + {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, + {"FADD", OpcodeChar(OP_FADD, SP_OP)}, + {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, + {"FCMP", OpcodeChar(OP_FCMP, SP_OP)}, + {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, + {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, + {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, + {"FSWZ", OpcodeChar(OP_FSWZ, SP_OP)}, + {"FSET", OpcodeChar(OP_FSET, SP_OP)}, + {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, + {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, + {"RRO", OpcodeChar(OP_RRO, SP_OP)}, + // SFU + {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, + + // Double Point Instructions + {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, + {"DADD", OpcodeChar(OP_DADD, DP_OP)}, + {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, + {"DMNMX", OpcodeChar(OP_DMNMX, DP_OP)}, + {"DSET", OpcodeChar(OP_DSET, DP_OP)}, + {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, + + // Integer Instructions + {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, + {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, + {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, + {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, + {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, + {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, + {"ISUB", OpcodeChar(OP_ISUB, INTP_OP)}, + {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, + {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, + {"ISAD", OpcodeChar(OP_ISAD, INTP_OP)}, + {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, + {"BFE", OpcodeChar(OP_BFE, INTP_OP)}, + {"BFI", OpcodeChar(OP_BFI, INTP_OP)}, + {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, + {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, + {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, + {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, + {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, + {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, + {"ISET", OpcodeChar(OP_ISET, INTP_OP)}, + {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, + {"ICMP", OpcodeChar(OP_ICMP, INTP_OP)}, + {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, + + // Conversion Instructions + {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, + {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, + {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, + {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, + + // Movement Instructions + {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, + {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, + {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, + {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, + {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, + + // Predicate Instructions + {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, + {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, + {"CSET", OpcodeChar(OP_CSET, ALU_OP)}, + {"CSETP", OpcodeChar(OP_CSETP, ALU_OP)}, + {"PSET", OpcodeChar(OP_PSET, ALU_OP)}, + {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, + + // Texture Instructions + // For now, we ignore texture loads, consider it as ALU_OP + {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, + {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, + {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, + {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, + + // Load/Store Instructions + // For now, we ignore constant loads, consider it as ALU_OP, TO DO + {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, + // in Kepler, LD is load global so set it to LDG + {"LD", OpcodeChar(OP_LDG, LOAD_OP)}, + {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, + {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, + {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, + {"LDSLK", OpcodeChar(OP_LDSLK, LOAD_OP)}, + {"ST", OpcodeChar(OP_STG, STORE_OP)}, + {"STL", OpcodeChar(OP_STL, STORE_OP)}, + {"STS", OpcodeChar(OP_STS, STORE_OP)}, + {"STSCUL", OpcodeChar(OP_STSCUL, STORE_OP)}, + {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, + {"RED", OpcodeChar(OP_RED, STORE_OP)}, + {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, + {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, + {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, + + // surface memory instructions + {"SUCLAMP", OpcodeChar(OP_SUCLAMP, LOAD_OP)}, + {"SUBFM", OpcodeChar(OP_SUBFM, LOAD_OP)}, + {"SUEAU", OpcodeChar(OP_SUEAU, LOAD_OP)}, + {"SULDGA", OpcodeChar(OP_SULDGA, LOAD_OP)}, + {"SUSTGA", OpcodeChar(OP_SUSTGA, STORE_OP)}, + + // Control Instructions + {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, + {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, + {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, + {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, + {"CAL", OpcodeChar(OP_CAL, CALL_OPS)}, + {"JCAL", OpcodeChar(OP_JCAL, CALL_OPS)}, + {"RET", OpcodeChar(OP_RET, RET_OPS)}, + {"BRK", OpcodeChar(OP_BRK, RET_OPS)}, + {"CONT", OpcodeChar(OP_CONT, RET_OPS)}, + {"SSY", OpcodeChar(OP_SSY, RET_OPS)}, + {"PBK", OpcodeChar(OP_PBK, RET_OPS)}, + {"PCNT", OpcodeChar(OP_PCNT, RET_OPS)}, + {"PRET", OpcodeChar(OP_PRET, RET_OPS)}, + {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, + {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, + + // Miscellaneous Instructions + {"NOP", OpcodeChar(OP_NOP, ALU_OP)}, + {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, + {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, + {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, + {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, }; #endif diff --git a/src/trace-driven/ISA_Def/pascal_opcode.h b/src/trace-driven/ISA_Def/pascal_opcode.h index 66a0841..34fe400 100644 --- a/src/trace-driven/ISA_Def/pascal_opcode.h +++ b/src/trace-driven/ISA_Def/pascal_opcode.h @@ -1,200 +1,198 @@ -//developed by Mahmoud Khairy, Purdue Univ -//abdallm@purdue.edu +// developed by Mahmoud Khairy, Purdue Univ +// abdallm@purdue.edu #ifndef PASCAL_OPCODE_H #define PASCAL_OPCODE_H -#include "trace_opcode.h" -#include #include +#include +#include "trace_opcode.h" #define PASCAL_TITANX_BINART_VERSION 61 #define PASCAL_P100_BINART_VERSION 60 #define PASCAL_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 -//TO DO: moving this to a yml or def files - -///Pascal SM_61 ISA -//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map Pascal_OpcodeMap = { - //Floating Point 32 Instructions - {"FADD", OpcodeChar(OP_FADD, SP_OP)}, - {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, - {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, - {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, - {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, - {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, - {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, - {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, - {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, - {"FSET", OpcodeChar(OP_FSET, SP_OP)}, - {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, - {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, - {"RRO", OpcodeChar(OP_RRO, SP_OP)}, - - //SFU - {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, - - //Floating Point 16 Instructions - {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, - {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, - {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, - {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, - {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, - - //Double Point Instructions - {"DADD", OpcodeChar(OP_DADD, DP_OP)}, - {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, - {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, - {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, - {"DMNMX", OpcodeChar(OP_DMNMX, DP_OP)}, - {"DSET", OpcodeChar(OP_DSET, DP_OP)}, - - //Integer Instructions - {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, - {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, - {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, - {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, - {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, - {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, - {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, - {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, - {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, - {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, - {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, - {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, - {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, - {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, - {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, - {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, - {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, - {"ISET", OpcodeChar(OP_ISET, INTP_OP)}, - {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, - {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, - {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, - {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, - {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, - {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, - {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, - {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, - {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, - {"BFE", OpcodeChar(OP_BFE, INTP_OP)}, - {"BFI", OpcodeChar(OP_BFI, INTP_OP)}, - {"ICMP", OpcodeChar(OP_ICMP, INTP_OP)}, - {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, - {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, - {"XMAD", OpcodeChar(OP_XMAD, INTP_OP)}, - {"VMNMX", OpcodeChar(OP_VMNMX, INTP_OP)}, - - - //Conversion Instructions - {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, - {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, - {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, - {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, - {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, - {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, - - //Movement Instructions - {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, - {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, - {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, - {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, - {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, - {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, - - //Predicate Instructions - {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, - {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, - {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, - {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, - {"CSET", OpcodeChar(OP_CSET, ALU_OP)}, - {"CSETP", OpcodeChar(OP_CSETP, ALU_OP)}, - {"PSET", OpcodeChar(OP_PSET, ALU_OP)}, - - - //Load/Store Instructions - {"LD", OpcodeChar(OP_LD, LOAD_OP)}, - //For now, we ignore constant loads, consider it as ALU_OP, TO DO - {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, - {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, - {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, - {"ST", OpcodeChar(OP_ST, STORE_OP)}, - {"STG", OpcodeChar(OP_STG, STORE_OP)}, - {"STL", OpcodeChar(OP_STL, STORE_OP)}, - {"STS", OpcodeChar(OP_STS, STORE_OP)}, - {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, - {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, - {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, - {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, - {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, - {"RED", OpcodeChar(OP_RED, STORE_OP)}, - {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, - {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, - {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, - {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, - {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, - - //Texture Instructions - //For now, we ignore texture loads, consider it as ALU_OP - {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, - {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, - {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, - {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, - {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, - {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, - {"TEXS", OpcodeChar(OP_TEXS, ALU_OP)}, - {"TLD4S", OpcodeChar(OP_TLD4S, ALU_OP)}, - {"TLDS", OpcodeChar(OP_TLDS, ALU_OP)}, - - //Control Instructions - {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, - {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, - {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, - {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, - {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, - {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, - {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, - {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, - {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, - {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, - {"SSY", OpcodeChar(OP_SSY, BRANCH_OP)}, - {"SYNC", OpcodeChar(OP_SYNC, BRANCH_OP)}, - {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, - {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, - {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, - {"RET", OpcodeChar(OP_RET, RET_OPS)}, - {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, - {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, - {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, - {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, - {"CAL", OpcodeChar(OP_CAL, CALL_OPS)}, - {"JCAL", OpcodeChar(OP_JCAL, CALL_OPS)}, - {"PRET", OpcodeChar(OP_PRET, CALL_OPS)}, - {"BRK", OpcodeChar(OP_BRK, CALL_OPS)}, - {"PBK", OpcodeChar(OP_PBK, CALL_OPS)}, - {"CONT", OpcodeChar(OP_CONT, CALL_OPS)}, - {"PCNT", OpcodeChar(OP_PCNT, CALL_OPS)}, - {"PEXIT", OpcodeChar(OP_PEXIT, CALL_OPS)}, - - //Miscellaneous Instructions - {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, - {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, - {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, - {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, - {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, - {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, - {"LEPC", OpcodeChar(OP_LEPC ,ALU_OP)}, - {"NOP", OpcodeChar(OP_NOP ,ALU_OP)}, - {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, - {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, - {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, - {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, - {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, - {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, - {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, +// TO DO: moving this to a yml or def files + +/// Pascal SM_61 ISA +// see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html +static const std::unordered_map Pascal_OpcodeMap = { + // Floating Point 32 Instructions + {"FADD", OpcodeChar(OP_FADD, SP_OP)}, + {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, + {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, + {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, + {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, + {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, + {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, + {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, + {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, + {"FSET", OpcodeChar(OP_FSET, SP_OP)}, + {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, + {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, + {"RRO", OpcodeChar(OP_RRO, SP_OP)}, + + // SFU + {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, + + // Floating Point 16 Instructions + {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, + {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, + {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, + {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, + {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, + + // Double Point Instructions + {"DADD", OpcodeChar(OP_DADD, DP_OP)}, + {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, + {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, + {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, + {"DMNMX", OpcodeChar(OP_DMNMX, DP_OP)}, + {"DSET", OpcodeChar(OP_DSET, DP_OP)}, + + // Integer Instructions + {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, + {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, + {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, + {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, + {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, + {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, + {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, + {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, + {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, + {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, + {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, + {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, + {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, + {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, + {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, + {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, + {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, + {"ISET", OpcodeChar(OP_ISET, INTP_OP)}, + {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, + {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, + {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, + {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, + {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, + {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, + {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, + {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, + {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, + {"BFE", OpcodeChar(OP_BFE, INTP_OP)}, + {"BFI", OpcodeChar(OP_BFI, INTP_OP)}, + {"ICMP", OpcodeChar(OP_ICMP, INTP_OP)}, + {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, + {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, + {"XMAD", OpcodeChar(OP_XMAD, INTP_OP)}, + {"VMNMX", OpcodeChar(OP_VMNMX, INTP_OP)}, + + // Conversion Instructions + {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, + {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, + {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, + {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, + {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, + {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, + + // Movement Instructions + {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, + {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, + {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, + {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, + {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, + {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, + + // Predicate Instructions + {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, + {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, + {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, + {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, + {"CSET", OpcodeChar(OP_CSET, ALU_OP)}, + {"CSETP", OpcodeChar(OP_CSETP, ALU_OP)}, + {"PSET", OpcodeChar(OP_PSET, ALU_OP)}, + + // Load/Store Instructions + {"LD", OpcodeChar(OP_LD, LOAD_OP)}, + // For now, we ignore constant loads, consider it as ALU_OP, TO DO + {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, + {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, + {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, + {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, + {"ST", OpcodeChar(OP_ST, STORE_OP)}, + {"STG", OpcodeChar(OP_STG, STORE_OP)}, + {"STL", OpcodeChar(OP_STL, STORE_OP)}, + {"STS", OpcodeChar(OP_STS, STORE_OP)}, + {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, + {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, + {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, + {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, + {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, + {"RED", OpcodeChar(OP_RED, STORE_OP)}, + {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, + {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, + {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, + {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, + {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, + + // Texture Instructions + // For now, we ignore texture loads, consider it as ALU_OP + {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, + {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, + {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, + {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, + {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, + {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, + {"TEXS", OpcodeChar(OP_TEXS, ALU_OP)}, + {"TLD4S", OpcodeChar(OP_TLD4S, ALU_OP)}, + {"TLDS", OpcodeChar(OP_TLDS, ALU_OP)}, + + // Control Instructions + {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, + {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, + {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, + {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, + {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, + {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, + {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, + {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, + {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, + {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, + {"SSY", OpcodeChar(OP_SSY, BRANCH_OP)}, + {"SYNC", OpcodeChar(OP_SYNC, BRANCH_OP)}, + {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, + {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, + {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, + {"RET", OpcodeChar(OP_RET, RET_OPS)}, + {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, + {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, + {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, + {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, + {"CAL", OpcodeChar(OP_CAL, CALL_OPS)}, + {"JCAL", OpcodeChar(OP_JCAL, CALL_OPS)}, + {"PRET", OpcodeChar(OP_PRET, CALL_OPS)}, + {"BRK", OpcodeChar(OP_BRK, CALL_OPS)}, + {"PBK", OpcodeChar(OP_PBK, CALL_OPS)}, + {"CONT", OpcodeChar(OP_CONT, CALL_OPS)}, + {"PCNT", OpcodeChar(OP_PCNT, CALL_OPS)}, + {"PEXIT", OpcodeChar(OP_PEXIT, CALL_OPS)}, + + // Miscellaneous Instructions + {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, + {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, + {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, + {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, + {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, + {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, + {"LEPC", OpcodeChar(OP_LEPC, ALU_OP)}, + {"NOP", OpcodeChar(OP_NOP, ALU_OP)}, + {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, + {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, + {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, + {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, + {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, + {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, + {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, }; diff --git a/src/trace-driven/ISA_Def/trace_opcode.h b/src/trace-driven/ISA_Def/trace_opcode.h index ed147fc..0badabc 100644 --- a/src/trace-driven/ISA_Def/trace_opcode.h +++ b/src/trace-driven/ISA_Def/trace_opcode.h @@ -1,36 +1,183 @@ -//developed by Mahmoud Khairy, Purdue Univ -//abdallm@purdue.edu +// developed by Mahmoud Khairy, Purdue Univ +// abdallm@purdue.edu #ifndef TRACE_OPCODE_H #define TRACE_OPCODE_H -#include "../../abstract_hardware_model.h" -#include #include - +#include +#include "../../abstract_hardware_model.h" enum TraceInstrOpcode { - //volta (common insts for others cards as well) - OP_FADD = 1, OP_FADD32I, OP_FCHK, OP_FFMA32I, OP_FFMA, OP_FMNMX, OP_FMUL, OP_FMUL32I, OP_FSEL, OP_FSET, OP_FSETP, - OP_FSWZADD, OP_MUFU, OP_HADD2, OP_HADD2_32I, OP_HFMA2, OP_HFMA2_32I, OP_HMUL2, OP_HMUL2_32I, OP_HSET2, OP_HSETP2, - OP_HMMA, OP_DADD, OP_DFMA, OP_DMUL, OP_DSETP, - OP_BMSK, OP_BREV, OP_FLO, OP_IABS, OP_IADD, OP_IADD3, OP_IADD32I, OP_IDP, OP_IDP4A, OP_IMAD, OP_IMMA, OP_IMNMX, - OP_IMUL, OP_IMUL32I, OP_ISCADD, OP_ISCADD32I, OP_ISETP, OP_LEA, OP_LOP, OP_LOP3, OP_LOP32I, OP_POPC, OP_SHF, OP_SHR, - OP_VABSDIFF, OP_VABSDIFF4, - OP_F2F, OP_F2I, OP_I2F, OP_I2I, OP_I2IP, OP_FRND, OP_MOV, OP_MOV32I, OP_PRMT, OP_SEL, OP_SGXT, OP_SHFL, OP_PLOP3, - OP_PSETP, OP_P2R, OP_R2P, OP_LD, OP_LDC, OP_LDG, OP_LDL, OP_LDS, OP_ST, OP_STG, OP_STL, OP_STS, OP_MATCH, OP_QSPC, - OP_ATOM, OP_ATOMS, OP_ATOMG, OP_RED, OP_CCTL, OP_CCTLL, OP_ERRBAR, OP_MEMBAR, OP_CCTLT, - OP_TEX, OP_TLD, OP_TLD4, - OP_TMML, OP_TXD, OP_TXQ, OP_BMOV, OP_BPT, OP_BRA, OP_BREAK, OP_BRX, OP_BSSY, OP_BSYNC, OP_CALL, OP_EXIT, OP_JMP, OP_JMX, - OP_KILL, OP_NANOSLEEP, OP_RET, OP_RPCMOV, OP_RTT, OP_WARPSYNC, OP_YIELD, OP_B2R, OP_BAR, OP_CS2R, OP_CSMTEST, OP_DEPBAR, - OP_GETLMEMBASE, OP_LEPC, OP_NOP, OP_PMTRIG, OP_R2B, OP_S2R, OP_SETCTAID, OP_SETLMEMBASE, OP_VOTE, OP_VOTE_VTG, - //unique insts for pascal - OP_RRO, OP_DMNMX, OP_DSET, OP_BFE, OP_BFI, OP_ICMP, OP_IMADSP, OP_SHL, OP_XMAD, OP_CSET, OP_CSETP, - OP_TEXS, OP_TLD4S, OP_TLDS, OP_CAL, OP_JCAL, OP_PRET, OP_BRK, OP_PBK, OP_CONT, OP_PCNT, OP_PEXIT, OP_SSY, OP_SYNC, OP_PSET - , OP_VMNMX, OP_ISET, - //unique insts for kepler - OP_FCMP, OP_FSWZ, OP_ISAD, OP_LDSLK, OP_STSCUL, OP_SUCLAMP, OP_SUBFM, OP_SUEAU, OP_SULDGA, OP_SUSTGA, OP_ISUB, - SASS_NUM_OPCODES /* The total number of opcodes. */ + // volta (common insts for others cards as well) + OP_FADD = 1, + OP_FADD32I, + OP_FCHK, + OP_FFMA32I, + OP_FFMA, + OP_FMNMX, + OP_FMUL, + OP_FMUL32I, + OP_FSEL, + OP_FSET, + OP_FSETP, + OP_FSWZADD, + OP_MUFU, + OP_HADD2, + OP_HADD2_32I, + OP_HFMA2, + OP_HFMA2_32I, + OP_HMUL2, + OP_HMUL2_32I, + OP_HSET2, + OP_HSETP2, + OP_HMMA, + OP_DADD, + OP_DFMA, + OP_DMUL, + OP_DSETP, + OP_BMSK, + OP_BREV, + OP_FLO, + OP_IABS, + OP_IADD, + OP_IADD3, + OP_IADD32I, + OP_IDP, + OP_IDP4A, + OP_IMAD, + OP_IMMA, + OP_IMNMX, + OP_IMUL, + OP_IMUL32I, + OP_ISCADD, + OP_ISCADD32I, + OP_ISETP, + OP_LEA, + OP_LOP, + OP_LOP3, + OP_LOP32I, + OP_POPC, + OP_SHF, + OP_SHR, + OP_VABSDIFF, + OP_VABSDIFF4, + OP_F2F, + OP_F2I, + OP_I2F, + OP_I2I, + OP_I2IP, + OP_FRND, + OP_MOV, + OP_MOV32I, + OP_PRMT, + OP_SEL, + OP_SGXT, + OP_SHFL, + OP_PLOP3, + OP_PSETP, + OP_P2R, + OP_R2P, + OP_LD, + OP_LDC, + OP_LDG, + OP_LDL, + OP_LDS, + OP_ST, + OP_STG, + OP_STL, + OP_STS, + OP_MATCH, + OP_QSPC, + OP_ATOM, + OP_ATOMS, + OP_ATOMG, + OP_RED, + OP_CCTL, + OP_CCTLL, + OP_ERRBAR, + OP_MEMBAR, + OP_CCTLT, + OP_TEX, + OP_TLD, + OP_TLD4, + OP_TMML, + OP_TXD, + OP_TXQ, + OP_BMOV, + OP_BPT, + OP_BRA, + OP_BREAK, + OP_BRX, + OP_BSSY, + OP_BSYNC, + OP_CALL, + OP_EXIT, + OP_JMP, + OP_JMX, + OP_KILL, + OP_NANOSLEEP, + OP_RET, + OP_RPCMOV, + OP_RTT, + OP_WARPSYNC, + OP_YIELD, + OP_B2R, + OP_BAR, + OP_CS2R, + OP_CSMTEST, + OP_DEPBAR, + OP_GETLMEMBASE, + OP_LEPC, + OP_NOP, + OP_PMTRIG, + OP_R2B, + OP_S2R, + OP_SETCTAID, + OP_SETLMEMBASE, + OP_VOTE, + OP_VOTE_VTG, + // unique insts for pascal + OP_RRO, + OP_DMNMX, + OP_DSET, + OP_BFE, + OP_BFI, + OP_ICMP, + OP_IMADSP, + OP_SHL, + OP_XMAD, + OP_CSET, + OP_CSETP, + OP_TEXS, + OP_TLD4S, + OP_TLDS, + OP_CAL, + OP_JCAL, + OP_PRET, + OP_BRK, + OP_PBK, + OP_CONT, + OP_PCNT, + OP_PEXIT, + OP_SSY, + OP_SYNC, + OP_PSET, + OP_VMNMX, + OP_ISET, + // unique insts for kepler + OP_FCMP, + OP_FSWZ, + OP_ISAD, + OP_LDSLK, + OP_STSCUL, + OP_SUCLAMP, + OP_SUBFM, + OP_SUEAU, + OP_SULDGA, + OP_SUSTGA, + OP_ISUB, + SASS_NUM_OPCODES /* The total number of opcodes. */ }; typedef enum TraceInstrOpcode sass_op_type; @@ -57,15 +204,13 @@ enum uarch_op_t { typedef enum uarch_op_t op_type; */ -struct OpcodeChar -{ - OpcodeChar(unsigned m_opcode, unsigned m_opcode_category) { - opcode = m_opcode; - opcode_category = m_opcode_category; - } - unsigned opcode; - unsigned opcode_category; +struct OpcodeChar { + OpcodeChar(unsigned m_opcode, unsigned m_opcode_category) { + opcode = m_opcode; + opcode_category = m_opcode_category; + } + unsigned opcode; + unsigned opcode_category; }; - #endif diff --git a/src/trace-driven/ISA_Def/turing_opcode.h b/src/trace-driven/ISA_Def/turing_opcode.h index 4df44d9..97921ca 100644 --- a/src/trace-driven/ISA_Def/turing_opcode.h +++ b/src/trace-driven/ISA_Def/turing_opcode.h @@ -1,23 +1,22 @@ -//developed by Mahmoud Khairy, Purdue Univ -//abdallm@purdue.edu +// developed by Mahmoud Khairy, Purdue Univ +// abdallm@purdue.edu #ifndef TURING_OPCODE_H #define TURING_OPCODE_H -#include "trace_opcode.h" -#include #include +#include +#include "trace_opcode.h" -//TO DO: moving this to a yml or def files - +// TO DO: moving this to a yml or def files #define TURING_BINART_VERSION 72 -///Tuing SM_72 ISA -//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map Turing_OpcodeMap = { +/// Tuing SM_72 ISA +// see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html +static const std::unordered_map Turing_OpcodeMap = { -//TO fill + // TO fill }; diff --git a/src/trace-driven/ISA_Def/volta_opcode.h b/src/trace-driven/ISA_Def/volta_opcode.h index 03d50b7..7bd6904 100644 --- a/src/trace-driven/ISA_Def/volta_opcode.h +++ b/src/trace-driven/ISA_Def/volta_opcode.h @@ -1,174 +1,174 @@ -//developed by Mahmoud Khairy, Purdue Univ -//abdallm@purdue.edu +// developed by Mahmoud Khairy, Purdue Univ +// abdallm@purdue.edu #ifndef VOLTA_OPCODE_H #define VOLTA_OPCODE_H -#include "trace_opcode.h" -#include #include +#include +#include "trace_opcode.h" #define VOLTA_BINART_VERSION 70 #define VOLTA_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 -//TO DO: moving this to a yml or def files - -///Volta SM_70 ISA -//see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map Volta_OpcodeMap = { - //Floating Point 32 Instructions - {"FADD", OpcodeChar(OP_FADD, SP_OP)}, - {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, - {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, - {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, - {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, - {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, - {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, - {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, - {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, - {"FSET", OpcodeChar(OP_FSET, SP_OP)}, - {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, - {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, - //SFU - {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, - - //Floating Point 16 Instructions - {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, - {"HADD2_32I", OpcodeChar(OP_HADD2_32I, SP_OP)}, - {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, - {"HFMA2_32I", OpcodeChar(OP_HFMA2_32I, SP_OP)}, - {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, - {"HMUL2_32I", OpcodeChar(OP_HMUL2_32I, SP_OP)}, - {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, - {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, - - //Tensor Core Instructions - {"HMMA", OpcodeChar(OP_HMMA, TENSOR_CORE_OP)}, - - //Double Point Instructions - {"DADD", OpcodeChar(OP_DADD, DP_OP)}, - {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, - {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, - {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, - - //Integer Instructions - {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, - {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, - {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, - {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, - {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, - {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, - {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, - {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, - {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, - {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, - {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, - {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, - {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, - {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, - {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, - {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, - {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, - {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, - {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, - {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, - {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, - {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, - {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, - {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, - {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, - {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, - - //Conversion Instructions - {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, - {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, - {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, - {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, - {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, - {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, - - //Movement Instructions - {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, - {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, - {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, - {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, - {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, - {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, - - //Predicate Instructions - {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, - {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, - {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, - {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, - - //Load/Store Instructions - {"LD", OpcodeChar(OP_LD, LOAD_OP)}, - //For now, we ignore constant loads, consider it as ALU_OP, TO DO - {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, - {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, - {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, - {"ST", OpcodeChar(OP_ST, STORE_OP)}, - {"STG", OpcodeChar(OP_STG, STORE_OP)}, - {"STL", OpcodeChar(OP_STL, STORE_OP)}, - {"STS", OpcodeChar(OP_STS, STORE_OP)}, - {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, - {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, - {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, - {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, - {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, - {"RED", OpcodeChar(OP_RED, STORE_OP)}, - {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, - {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, - {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, - {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, - {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, - - //Texture Instructions - //For now, we ignore texture loads, consider it as ALU_OP - {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, - {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, - {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, - {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, - {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, - {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, - - //Control Instructions - {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, - {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, - {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, - {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, - {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, - {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, - {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, - {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, - {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, - {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, - {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, - {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, - {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, - {"RET", OpcodeChar(OP_RET, RET_OPS)}, - {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, - {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, - {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, - {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, - - //Miscellaneous Instructions - {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, - {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, - {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, - {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, - {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, - {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, - {"LEPC", OpcodeChar(OP_LEPC ,ALU_OP)}, - {"NOP", OpcodeChar(OP_NOP ,ALU_OP)}, - {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, - {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, - {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, - {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, - {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, - {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, - {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, +// TO DO: moving this to a yml or def files + +/// Volta SM_70 ISA +// see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html +static const std::unordered_map Volta_OpcodeMap = { + // Floating Point 32 Instructions + {"FADD", OpcodeChar(OP_FADD, SP_OP)}, + {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, + {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, + {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, + {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, + {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, + {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, + {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, + {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, + {"FSET", OpcodeChar(OP_FSET, SP_OP)}, + {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, + {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, + // SFU + {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, + + // Floating Point 16 Instructions + {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, + {"HADD2_32I", OpcodeChar(OP_HADD2_32I, SP_OP)}, + {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, + {"HFMA2_32I", OpcodeChar(OP_HFMA2_32I, SP_OP)}, + {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, + {"HMUL2_32I", OpcodeChar(OP_HMUL2_32I, SP_OP)}, + {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, + {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, + + // Tensor Core Instructions + {"HMMA", OpcodeChar(OP_HMMA, TENSOR_CORE_OP)}, + + // Double Point Instructions + {"DADD", OpcodeChar(OP_DADD, DP_OP)}, + {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, + {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, + {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, + + // Integer Instructions + {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, + {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, + {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, + {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, + {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, + {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, + {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, + {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, + {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, + {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, + {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, + {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, + {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, + {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, + {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, + {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, + {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, + {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, + {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, + {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, + {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, + {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, + {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, + {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, + {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, + {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, + + // Conversion Instructions + {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, + {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, + {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, + {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, + {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, + {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, + + // Movement Instructions + {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, + {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, + {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, + {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, + {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, + {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, + + // Predicate Instructions + {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, + {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, + {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, + {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, + + // Load/Store Instructions + {"LD", OpcodeChar(OP_LD, LOAD_OP)}, + // For now, we ignore constant loads, consider it as ALU_OP, TO DO + {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, + {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, + {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, + {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, + {"ST", OpcodeChar(OP_ST, STORE_OP)}, + {"STG", OpcodeChar(OP_STG, STORE_OP)}, + {"STL", OpcodeChar(OP_STL, STORE_OP)}, + {"STS", OpcodeChar(OP_STS, STORE_OP)}, + {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, + {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, + {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, + {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, + {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, + {"RED", OpcodeChar(OP_RED, STORE_OP)}, + {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, + {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, + {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, + {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, + {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, + + // Texture Instructions + // For now, we ignore texture loads, consider it as ALU_OP + {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, + {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, + {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, + {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, + {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, + {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, + + // Control Instructions + {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, + {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, + {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, + {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, + {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, + {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, + {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, + {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, + {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, + {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, + {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, + {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, + {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, + {"RET", OpcodeChar(OP_RET, RET_OPS)}, + {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, + {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, + {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, + {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, + + // Miscellaneous Instructions + {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, + {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, + {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, + {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, + {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, + {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, + {"LEPC", OpcodeChar(OP_LEPC, ALU_OP)}, + {"NOP", OpcodeChar(OP_NOP, ALU_OP)}, + {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, + {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, + {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, + {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, + {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, + {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, + {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, }; diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 90dc769..4a5f14a 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -1,123 +1,123 @@ -//developed by Mahmoud Khairy, Purdue Univ -//abdallm@purdue.edu +// developed by Mahmoud Khairy, Purdue Univ +// abdallm@purdue.edu -#include +#include #include -#include -#include +#include #include -#include +#include #include -#include +#include +#include +#include "../../libcuda/gpgpu_context.h" #include "../abstract_hardware_model.h" -#include "../option_parser.h" #include "../cuda-sim/cuda-sim.h" #include "../gpgpu-sim/gpu-sim.h" -#include "../../libcuda/gpgpu_context.h" -#include "trace_driven.h" -#include "ISA_Def/trace_opcode.h" #include "../gpgpusim_entrypoint.h" +#include "../option_parser.h" +#include "ISA_Def/trace_opcode.h" +#include "trace_driven.h" /* TO DO: * NOTE: the current version of trace-driven is functionally working fine, * but we still need to improve traces compression and simulation speed. * This includes: - * 1- Prefetch concurrent thread that prefetches traces from disk (to not be limited by disk speed) - * 2- traces compression format - * a. cfg format and remove thread/block Id from the head - * b. using zlib library to save in binary format + * 1- Prefetch concurrent thread that prefetches traces from disk (to not be + * limited by disk speed) 2- traces compression format a. cfg format and remove + * thread/block Id from the head b. using zlib library to save in binary format * - * 3- Efficient memory improvement (save string not objects - parse only 10 in the buffer) - * 4- Seeking capability - thread scheduler (save tb index and warp index info in the traces header) - * 5- Get rid off traces intermediate files - change the tracer + * 3- Efficient memory improvement (save string not objects - parse only 10 in + * the buffer) 4- Seeking capability - thread scheduler (save tb index and warp + * index info in the traces header) 5- Get rid off traces intermediate files - + * change the tracer */ -int main ( int argc, const char **argv ) -{ - - gpgpu_context* m_gpgpu_context = new 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); - trace_config config(m_gpgpu_sim); - - std::vector commandlist = tracer.parse_kernellist_file(); - bool first_kernel=true; - - for(unsigned i=0; iperf_memcpy_to_gpu(addre, Bcount); - continue; - } - else { - //skip the first unimportant initialization kernel - if(m_gpgpu_sim->get_config().is_skip_first_kernel() && first_kernel) { - first_kernel = false; - continue; - } - kernel_info = tracer.parse_kernel_info(commandlist[i], &config); - 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 ); - - if(kernel_info) { - 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); - } - } - - //we print this message to inform the gpgpu-simulation stats_collect script that we are done - printf("GPGPU-Sim: *** simulation thread exiting ***\n"); - printf("GPGPU-Sim: *** exit detected ***\n"); - - return 1; +int main(int argc, const char** argv) { + gpgpu_context* m_gpgpu_context = new 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); + trace_config config(m_gpgpu_sim); + + std::vector commandlist = tracer.parse_kernellist_file(); + bool first_kernel = true; + + for (unsigned i = 0; i < commandlist.size(); ++i) { + trace_kernel_info_t* kernel_info = NULL; + if (commandlist[i].substr(0, 6) == "Memcpy") { + size_t addre, Bcount; + tracer.parse_memcpy_info(commandlist[i], addre, Bcount); + std::cout << commandlist[i] << std::endl; + m_gpgpu_sim->perf_memcpy_to_gpu(addre, Bcount); + continue; + } else { + // skip the first unimportant initialization kernel + if (m_gpgpu_sim->get_config().is_skip_first_kernel() && first_kernel) { + first_kernel = false; + continue; + } + kernel_info = tracer.parse_kernel_info(commandlist[i], &config); + 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); + + if (kernel_info) { + 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); + } + } + + // we print this message to inform the gpgpu-simulation stats_collect script + // that we are done + printf("GPGPU-Sim: *** simulation thread exiting ***\n"); + printf("GPGPU-Sim: *** exit detected ***\n"); + + return 1; } diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 76eb7ca..44468b1 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -1,707 +1,691 @@ -//developed by Mahmoud Khairy, Purdue Univ -//abdallm@purdue.edu +// developed by Mahmoud Khairy, Purdue Univ +// abdallm@purdue.edu -#include +#include +#include #include -#include -#include +#include #include -#include +#include #include -#include -#include +#include +#include +#include "../../libcuda/gpgpu_context.h" #include "../abstract_hardware_model.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 "../../libcuda/gpgpu_context.h" -#include "trace_driven.h" +#include "../gpgpusim_entrypoint.h" +#include "../option_parser.h" +#include "ISA_Def/kepler_opcode.h" +#include "ISA_Def/pascal_opcode.h" #include "ISA_Def/trace_opcode.h" -#include "ISA_Def/volta_opcode.h" #include "ISA_Def/turing_opcode.h" -#include "ISA_Def/pascal_opcode.h" -#include "ISA_Def/kepler_opcode.h" -#include "../gpgpusim_entrypoint.h" - +#include "ISA_Def/volta_opcode.h" +#include "trace_driven.h" -bool is_number(const std::string& s) -{ - std::string::const_iterator it = s.begin(); - while (it != s.end() && std::isdigit(*it)) ++it; - return !s.empty() && it == s.end(); +bool is_number(const std::string& s) { + std::string::const_iterator it = s.begin(); + while (it != s.end() && std::isdigit(*it)) ++it; + return !s.empty() && it == s.end(); } -void split(const std::string& str, std::vector& cont, char delimi = ' ') -{ - std::stringstream ss(str); - std::string token; - while (std::getline(ss, token, delimi)) { - cont.push_back(token); - } +void split(const std::string& str, std::vector& cont, + char delimi = ' ') { + std::stringstream ss(str); + std::string token; + while (std::getline(ss, token, delimi)) { + cont.push_back(token); + } } -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; +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 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 kernellist; + while (!ifs.eof()) { + getline(ifs, line); + if (line.empty()) + continue; + else if (line.substr(0, 6) == "Memcpy") { + kernellist.push_back(line); + } else if (line.substr(0, 6) == "kernel") { + filepath = directory + "/" + line; + kernellist.push_back(filepath); + } + } - ifs.open(kernellist_filename); - - if (!ifs.is_open()) { - std::cout << "Unable to open file: " < kernellist; - while(!ifs.eof()) { - getline(ifs, line); - if(line.empty()) - continue; - else if(line.substr(0,6) == "Memcpy") { - kernellist.push_back(line); - } - else if(line.substr(0,6) == "kernel") { - filepath = directory+"/"+line; - kernellist.push_back(filepath); - } - } - - ifs.close(); - return kernellist; + ifs.close(); + return kernellist; } -void trace_parser::parse_memcpy_info(const std::string& memcpy_command, size_t& address, size_t& count) { - std::vector params; - split(memcpy_command, params, ','); - assert(params.size() == 3); - std::stringstream ss; - ss.str(params[1]); - ss>>std::hex>>address; - ss.clear(); - ss.str(params[2]); - ss>>std::dec>>count; +void trace_parser::parse_memcpy_info(const std::string& memcpy_command, + size_t& address, size_t& count) { + std::vector params; + split(memcpy_command, params, ','); + assert(params.size() == 3); + std::stringstream ss; + ss.str(params[1]); + ss >> std::hex >> address; + ss.clear(); + ss.str(params[2]); + ss >> std::dec >> count; } -trace_kernel_info_t* trace_parser::parse_kernel_info(const std::string& kerneltraces_filepath, trace_config* config) { - - ifs.open(kerneltraces_filepath.c_str()); - - if (!ifs.is_open()) { - std::cout << "Unable to open file: " <>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); - } - else if (string1 == "binary" && string2 == "version") { - sscanf(line.c_str(), "-binary version = %d", &binary_verion); - } - std::cout << line << std::endl; - 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, binary_verion, function_info, &ifs, m_gpgpu_sim, m_gpgpu_context, config); - - return kernel_info; +trace_kernel_info_t* trace_parser::parse_kernel_info( + const std::string& kerneltraces_filepath, trace_config* config) { + 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, + binary_verion = 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); + } else if (string1 == "binary" && string2 == "version") { + sscanf(line.c_str(), "-binary version = %d", &binary_verion); + } + std::cout << line << std::endl; + 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, binary_verion, function_info, + &ifs, m_gpgpu_sim, m_gpgpu_context, config); + + return kernel_info; } +void trace_parser::kernel_finalizer(trace_kernel_info_t* kernel_info) { + if (ifs.is_open()) ifs.close(); -void trace_parser::kernel_finalizer(trace_kernel_info_t* kernel_info){ - if (ifs.is_open()) - ifs.close(); - - delete kernel_info->entry(); - delete kernel_info; + delete kernel_info->entry(); + delete kernel_info; } -const trace_warp_inst_t* trace_shd_warp_t::get_next_inst(){ - if(trace_pc < warp_traces.size()) - { - return &warp_traces[trace_pc++]; - } - else - return NULL; +const trace_warp_inst_t* trace_shd_warp_t::get_next_inst() { + if (trace_pc < warp_traces.size()) { + return &warp_traces[trace_pc++]; + } else + return NULL; } void trace_shd_warp_t::clear() { - trace_pc=0; - warp_traces.clear(); + trace_pc = 0; + warp_traces.clear(); } -//functional_done -bool trace_shd_warp_t::trace_done() { - return trace_pc==(warp_traces.size()); -} - -address_type trace_shd_warp_t::get_start_pc(){ - assert(warp_traces.size() > 0); - return warp_traces[0].pc; -} +// functional_done +bool trace_shd_warp_t::trace_done() { return trace_pc == (warp_traces.size()); } -address_type trace_shd_warp_t::get_pc(){ - assert(warp_traces.size() > 0 ); - assert(trace_pc < warp_traces.size()); - return warp_traces[trace_pc].pc; +address_type trace_shd_warp_t::get_start_pc() { + assert(warp_traces.size() > 0); + return warp_traces[0].pc; } -trace_kernel_info_t::trace_kernel_info_t(dim3 gridDim, dim3 blockDim, unsigned m_binary_verion, trace_function_info* m_function_info, std::ifstream* inputstream, gpgpu_sim * gpgpu_sim, gpgpu_context* gpgpu_context, class trace_config* config):kernel_info_t(gridDim, blockDim, m_function_info) { - ifs = inputstream; - m_gpgpu_sim = gpgpu_sim; - m_gpgpu_context = gpgpu_context; - binary_verion = m_binary_verion; - m_tconfig = config; - - //resolve the binary version - if(m_binary_verion == VOLTA_BINART_VERSION) - OpcodeMap = &Volta_OpcodeMap; - else if(m_binary_verion == PASCAL_TITANX_BINART_VERSION || m_binary_verion == PASCAL_P100_BINART_VERSION) - OpcodeMap = &Pascal_OpcodeMap; - else if(m_binary_verion == KEPLER_BINART_VERSION) - OpcodeMap = &Kepler_OpcodeMap; - else if(m_binary_verion == TURING_BINART_VERSION) - OpcodeMap = &Turing_OpcodeMap; - else - assert(0 && "unsupported binary version"); +address_type trace_shd_warp_t::get_pc() { + assert(warp_traces.size() > 0); + assert(trace_pc < warp_traces.size()); + return warp_traces[trace_pc].pc; } -bool trace_kernel_info_t::get_next_threadblock_traces(std::vector*> threadblock_traces) { - - for(unsigned i=0; iclear(); - } - - unsigned block_id_x=0, block_id_y=0, block_id_z=0; - unsigned warp_id=0; - unsigned insts_num=0; - - - bool start_of_tb_stream_found = false; - - while(!ifs->eof()) { - std::string line; - std::stringstream ss; - std::string string1, string2; - - 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); - std::cout << line << std::endl; - } - 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]->reserve(insts_num); - } - else { - assert(start_of_tb_stream_found); - trace_warp_inst_t inst(m_gpgpu_sim->getShaderCoreConfig(), m_gpgpu_context, m_tconfig); - inst.parse_from_string(line, OpcodeMap); - threadblock_traces[warp_id]->push_back(inst); - } - } - } - - return true; +trace_kernel_info_t::trace_kernel_info_t(dim3 gridDim, dim3 blockDim, + unsigned m_binary_verion, + trace_function_info* m_function_info, + std::ifstream* inputstream, + gpgpu_sim* gpgpu_sim, + gpgpu_context* gpgpu_context, + class trace_config* config) + : kernel_info_t(gridDim, blockDim, m_function_info) { + ifs = inputstream; + m_gpgpu_sim = gpgpu_sim; + m_gpgpu_context = gpgpu_context; + binary_verion = m_binary_verion; + m_tconfig = config; + + // resolve the binary version + if (m_binary_verion == VOLTA_BINART_VERSION) + OpcodeMap = &Volta_OpcodeMap; + else if (m_binary_verion == PASCAL_TITANX_BINART_VERSION || + m_binary_verion == PASCAL_P100_BINART_VERSION) + OpcodeMap = &Pascal_OpcodeMap; + else if (m_binary_verion == KEPLER_BINART_VERSION) + OpcodeMap = &Kepler_OpcodeMap; + else if (m_binary_verion == TURING_BINART_VERSION) + OpcodeMap = &Turing_OpcodeMap; + else + assert(0 && "unsupported binary version"); } -bool trace_warp_inst_t::check_opcode_contain(const std::vector& opcode, std::string param) -{ - for(unsigned i=0; i*> threadblock_traces) { + for (unsigned i = 0; i < threadblock_traces.size(); ++i) { + threadblock_traces[i]->clear(); + } + + unsigned block_id_x = 0, block_id_y = 0, block_id_z = 0; + unsigned warp_id = 0; + unsigned insts_num = 0; + + bool start_of_tb_stream_found = false; + + while (!ifs->eof()) { + std::string line; + std::stringstream ss; + std::string string1, string2; + + 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); + std::cout << line << std::endl; + } 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]->reserve(insts_num); + } else { + assert(start_of_tb_stream_found); + trace_warp_inst_t inst(m_gpgpu_sim->getShaderCoreConfig(), + m_gpgpu_context, m_tconfig); + inst.parse_from_string(line, OpcodeMap); + threadblock_traces[warp_id]->push_back(inst); + } + } + } - return false; + return true; } +bool trace_warp_inst_t::check_opcode_contain( + const std::vector& opcode, std::string param) { + for (unsigned i = 0; i < opcode.size(); ++i) + if (opcode[i] == param) return true; + return false; +} -unsigned trace_warp_inst_t::get_datawidth_from_opcode(const std::vector& opcode) -{ - for(unsigned i=0; i& opcode) { + for (unsigned i = 0; i < opcode.size(); ++i) { + if (is_number(opcode[i])) { + return (std::stoi(opcode[i], NULL) / 8); + } else if (opcode[i][0] == 'U' && is_number(opcode[i].substr(1))) { + // handle the U* case + unsigned bits; + sscanf(opcode[i].c_str(), "U%u", &bits); + return bits / 8; + } + } - return 4; //default is 4 bytes + return 4; // default is 4 bytes } -bool trace_warp_inst_t::parse_from_string(std::string trace, const std::unordered_map* OpcodeMap){ - - 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[4]; - std::string opcode; - unsigned reg_dsts_num=0; - unsigned reg_srcs_num=0; - unsigned reg_srcs[4]; - unsigned mem_width=0; - unsigned long long mem_addresses[warp_size()]; - unsigned address_mode=0; - unsigned long long base_address=0; - int stride=0; - - //Start Parsing - ss>>std::dec>>threadblock_x>>threadblock_y>>threadblock_z>>warpid_tb; - - //ignore core id - //ss>>std::dec>>sm_id>>warpid_sm; - - ss>>std::hex>>m_pc; - ss>>std::hex>>mask; - - std::bitset mask_bits(mask); - - ss>>std::dec>>reg_dsts_num; - for(unsigned i=0; i>std::dec>>temp; - sscanf(temp.c_str(), "R%d", ®_dest[i]); - } - - ss>>opcode; - - ss>>reg_srcs_num; - for(unsigned i=0; i>temp; - sscanf(temp.c_str(), "R%d", ®_srcs[i]); - - } - - ss>>mem_width; - - if(mem_width > 0) //then it is a memory inst - { - ss>>std::dec>>address_mode; - if(address_mode==0){ - //read addresses one by one from the file - for (int s = 0; s < warp_size(); s++) { - if(mask_bits.test(s)) - ss>>std::hex>>mem_addresses[s]; - else - mem_addresses[s]=0; - } - } - else if(address_mode==1){ - //read addresses as base address and stride - ss>>std::hex>>base_address; - ss>>std::dec>>stride; - bool first_bit1_found=false; - bool last_bit1_found=false; - unsigned long long addra=base_address; - for (int s = 0; s < warp_size(); s++) { - if(mask_bits.test(s) && !first_bit1_found){ - first_bit1_found=true; - mem_addresses[s]=base_address; - } else if(first_bit1_found && !last_bit1_found) { - if(mask_bits.test(s)) { - addra += stride; - mem_addresses[s] = addra; - } else - last_bit1_found=true; - } - else - mem_addresses[s]=0; - } - } - } - //Finish Parsing - //After parsing, fill the inst_t and warp_inst_t params - - //fill active mask - active_mask_t active_mask = mask_bits; - set_active( active_mask ); - - //get the opcode - std::istringstream iss(opcode); - std::vector opcode_tokens; - std::string token; - while (std::getline(iss, token, '.')) { - if (!token.empty()) - opcode_tokens.push_back(token); - } - - std::string opcode1 = opcode_tokens[0]; - - //fill and initialize common params - m_decoded = true; - pc = (address_type)m_pc; //we will lose the high 32 bits from casting long to unsigned, it should be okay! - - isize = 16; //starting from MAXWELL isize=16 bytes (including the control bytes) - for(unsigned i=0; i::const_iterator it= OpcodeMap->find(opcode1); - if (it != OpcodeMap->end()) { - m_opcode = it->second.opcode; - op = (op_type)(it->second.opcode_category); - } - else { - std::cout<<"ERROR: undefined instruction : "<set_latency(op, latency, initiation_interval); - - //fill addresses - if(mem_width > 0) { - for(unsigned i=0; i0); - //Nvbit reports incorrect data width, and we have to parse the opcode to get the correct data width - data_size = get_datawidth_from_opcode(opcode_tokens); - memory_op = memory_load; - cache_op = CACHE_ALL; - if(m_opcode == OP_LDL) - space.set_type(local_space); - else - space.set_type(global_space); - //check the cache scope, if its strong GPU, then bypass L1 - if(check_opcode_contain( opcode_tokens , "STRONG") && check_opcode_contain( opcode_tokens , "GPU")) { - cache_op = CACHE_GLOBAL; - } - break; - case OP_STG: - case OP_STL: - case OP_ATOMG: - case OP_RED: - case OP_ATOM: - assert(mem_width>0); - data_size = get_datawidth_from_opcode(opcode_tokens); - memory_op = memory_store; - cache_op = CACHE_ALL; - if(m_opcode == OP_STL) - space.set_type(local_space); - else - space.set_type(global_space); - - if(m_opcode == OP_ATOMG || m_opcode == OP_ATOM || m_opcode == OP_RED){ - m_isatomic = true; - memory_op = memory_load; - op=LOAD_OP; - cache_op = CACHE_GLOBAL; - - //ATOMIC writes to the first operand, we missed that in the trace so we fixed it here. TO be fixed in tracer - outcount=reg_dsts_num+1; - out[0]=in[0]; //Increment by one because GPGPU-sim starts from R1, while SASS starts from R0 - arch_reg.dst[0]=reg_srcs[0]; - num_regs = reg_srcs_num+reg_dsts_num+1; - num_operands = num_regs; - - } - - break; - case OP_LDS: - case OP_STS: - case OP_ATOMS: - assert(mem_width>0); - data_size = mem_width; - space.set_type(shared_space); - if(m_opcode == OP_ATOMS || m_opcode == OP_LDS) { - //m_isatomic = true; - op=LOAD_OP; - memory_op = memory_load; - } - break; - case OP_ST: - case OP_LD: - //TO DO: set generic load based on the address - //right now, we consider all loads are shared. - assert(mem_width>0); - data_size = get_datawidth_from_opcode(opcode_tokens); - space.set_type(shared_space); - if(m_opcode == OP_LD) - memory_op = memory_load; - else - memory_op = memory_store; - break; - case OP_BAR: - //TO DO: fill this correctly - bar_id = 0; - bar_count = (unsigned)-1; - bar_type = SYNC; - //TO DO - //if bar_type = RED; - //set bar_type - // barrier_type bar_type; - // reduction_type red_type; - break; - case OP_HADD2: - case OP_HADD2_32I: - case OP_HFMA2: - case OP_HFMA2_32I: - case OP_HMUL2_32I: - case OP_HSET2: - case OP_HSETP2: - initiation_interval = initiation_interval/2; //FP16 has 2X throughput than FP32 - break; - default: - break; - } - - return true; +bool trace_warp_inst_t::parse_from_string( + std::string trace, + const std::unordered_map* OpcodeMap) { + 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[4]; + std::string opcode; + unsigned reg_dsts_num = 0; + unsigned reg_srcs_num = 0; + unsigned reg_srcs[4]; + unsigned mem_width = 0; + unsigned long long mem_addresses[warp_size()]; + unsigned address_mode = 0; + unsigned long long base_address = 0; + int stride = 0; + + // Start Parsing + ss >> std::dec >> threadblock_x >> threadblock_y >> threadblock_z >> + warpid_tb; + + // ignore core id + // ss>>std::dec>>sm_id>>warpid_sm; + + ss >> std::hex >> m_pc; + ss >> std::hex >> mask; + + std::bitset mask_bits(mask); + + ss >> std::dec >> reg_dsts_num; + for (unsigned i = 0; i < reg_dsts_num; ++i) { + ss >> std::dec >> temp; + sscanf(temp.c_str(), "R%d", ®_dest[i]); + } + + 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 + { + ss >> std::dec >> address_mode; + if (address_mode == 0) { + // read addresses one by one from the file + for (int s = 0; s < warp_size(); s++) { + if (mask_bits.test(s)) + ss >> std::hex >> mem_addresses[s]; + else + mem_addresses[s] = 0; + } + } else if (address_mode == 1) { + // read addresses as base address and stride + ss >> std::hex >> base_address; + ss >> std::dec >> stride; + bool first_bit1_found = false; + bool last_bit1_found = false; + unsigned long long addra = base_address; + for (int s = 0; s < warp_size(); s++) { + if (mask_bits.test(s) && !first_bit1_found) { + first_bit1_found = true; + mem_addresses[s] = base_address; + } else if (first_bit1_found && !last_bit1_found) { + if (mask_bits.test(s)) { + addra += stride; + mem_addresses[s] = addra; + } else + last_bit1_found = true; + } else + mem_addresses[s] = 0; + } + } + } + // Finish Parsing + // After parsing, fill the inst_t and warp_inst_t params + + // fill active mask + active_mask_t active_mask = mask_bits; + set_active(active_mask); + + // get the opcode + std::istringstream iss(opcode); + std::vector opcode_tokens; + std::string token; + while (std::getline(iss, token, '.')) { + if (!token.empty()) opcode_tokens.push_back(token); + } + + std::string opcode1 = opcode_tokens[0]; + + // fill and initialize common params + m_decoded = true; + pc = (address_type)m_pc; // we will lose the high 32 bits from casting long + // to unsigned, it should be okay! + + isize = + 16; // starting from MAXWELL isize=16 bytes (including the control bytes) + for (unsigned i = 0; i < MAX_OUTPUT_VALUES; i++) { + out[i] = 0; + } + for (unsigned i = 0; i < MAX_INPUT_VALUES; i++) { + in[i] = 0; + } + + is_vectorin = 0; + is_vectorout = 0; + ar1 = 0; + ar2 = 0; + memory_op = no_memory_op; + data_size = 0; + op = ALU_OP; + mem_op = NOT_TEX; + + std::unordered_map::const_iterator it = + OpcodeMap->find(opcode1); + if (it != OpcodeMap->end()) { + m_opcode = it->second.opcode; + op = (op_type)(it->second.opcode_category); + } else { + std::cout << "ERROR: undefined instruction : " << opcode + << " Opcode: " << opcode1 << std::endl; + assert(0 && "undefined instruction"); + } + + // fill regs information + num_regs = reg_srcs_num + reg_dsts_num; + num_operands = num_regs; + outcount = reg_dsts_num; + for (unsigned m = 0; m < reg_dsts_num; ++m) { + out[m] = reg_dest[m] + 1; // Increment by one because GPGPU-sim starts from + // R1, while SASS starts from R0 + arch_reg.dst[m] = reg_dest[m] + 1; + } + + incount = reg_srcs_num; + for (unsigned m = 0; m < reg_srcs_num; ++m) { + in[m] = reg_srcs[m] + 1; // Increment by one because GPGPU-sim starts from + // R1, while SASS starts from R0 + arch_reg.src[m] = reg_srcs[m] + 1; + } + // TO DO: handle: vector, store insts have no output, double inst and hmma, + // and 64 bit address remove redundant registers + + // fill latency and initl + m_tconfig->set_latency(op, latency, initiation_interval); + + // fill addresses + if (mem_width > 0) { + for (unsigned i = 0; i < warp_size(); ++i) set_addr(i, mem_addresses[i]); + } + + // handle special cases and fill memory space + switch (m_opcode) { + case OP_LDG: + case OP_LDL: + assert(mem_width > 0); + // Nvbit reports incorrect data width, and we have to parse the opcode to + // get the correct data width + data_size = get_datawidth_from_opcode(opcode_tokens); + memory_op = memory_load; + cache_op = CACHE_ALL; + if (m_opcode == OP_LDL) + space.set_type(local_space); + else + space.set_type(global_space); + // check the cache scope, if its strong GPU, then bypass L1 + if (check_opcode_contain(opcode_tokens, "STRONG") && + check_opcode_contain(opcode_tokens, "GPU")) { + cache_op = CACHE_GLOBAL; + } + break; + case OP_STG: + case OP_STL: + case OP_ATOMG: + case OP_RED: + case OP_ATOM: + assert(mem_width > 0); + data_size = get_datawidth_from_opcode(opcode_tokens); + memory_op = memory_store; + cache_op = CACHE_ALL; + if (m_opcode == OP_STL) + space.set_type(local_space); + else + space.set_type(global_space); + + if (m_opcode == OP_ATOMG || m_opcode == OP_ATOM || m_opcode == OP_RED) { + m_isatomic = true; + memory_op = memory_load; + op = LOAD_OP; + cache_op = CACHE_GLOBAL; + + // ATOMIC writes to the first operand, we missed that in the trace so we + // fixed it here. TO be fixed in tracer + outcount = reg_dsts_num + 1; + out[0] = in[0]; // Increment by one because GPGPU-sim starts from R1, + // while SASS starts from R0 + arch_reg.dst[0] = reg_srcs[0]; + num_regs = reg_srcs_num + reg_dsts_num + 1; + num_operands = num_regs; + } + + break; + case OP_LDS: + case OP_STS: + case OP_ATOMS: + assert(mem_width > 0); + data_size = mem_width; + space.set_type(shared_space); + if (m_opcode == OP_ATOMS || m_opcode == OP_LDS) { + // m_isatomic = true; + op = LOAD_OP; + memory_op = memory_load; + } + break; + case OP_ST: + case OP_LD: + // TO DO: set generic load based on the address + // right now, we consider all loads are shared. + assert(mem_width > 0); + data_size = get_datawidth_from_opcode(opcode_tokens); + space.set_type(shared_space); + if (m_opcode == OP_LD) + memory_op = memory_load; + else + memory_op = memory_store; + break; + case OP_BAR: + // TO DO: fill this correctly + bar_id = 0; + bar_count = (unsigned)-1; + bar_type = SYNC; + // TO DO + // if bar_type = RED; + // set bar_type + // barrier_type bar_type; + // reduction_type red_type; + break; + case OP_HADD2: + case OP_HADD2_32I: + case OP_HFMA2: + case OP_HFMA2_32I: + case OP_HMUL2_32I: + case OP_HSET2: + case OP_HSETP2: + initiation_interval = + initiation_interval / 2; // FP16 has 2X throughput than FP32 + break; + default: + break; + } + + return true; } -trace_config::trace_config(gpgpu_sim* m_gpgpu_sim){ - - this->m_gpgpu_sim=m_gpgpu_sim; - parse_config(); +trace_config::trace_config(gpgpu_sim* m_gpgpu_sim) { + this->m_gpgpu_sim = m_gpgpu_sim; + parse_config(); } -void trace_config::parse_config() -{ - - sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_int, "%u,%u", - &int_latency,&int_init); - sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_sp, "%u,%u", - &fp_latency,&fp_init); - sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_dp, "%u,%u", - &dp_latency,&dp_init); - sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_sfu, "%u,%u", - &sfu_latency,&sfu_init); - sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_tensor, "%u,%u", - &tensor_latency,&tensor_init); - +void trace_config::parse_config() { + sscanf( + m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_int, + "%u,%u", &int_latency, &int_init); + sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_sp, + "%u,%u", &fp_latency, &fp_init); + sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_dp, + "%u,%u", &dp_latency, &dp_init); + sscanf( + m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_sfu, + "%u,%u", &sfu_latency, &sfu_init); + sscanf(m_gpgpu_sim->getShaderCoreConfig() + ->trace_opcode_latency_initiation_tensor, + "%u,%u", &tensor_latency, &tensor_init); } -void trace_config::set_latency(unsigned category, unsigned& latency, unsigned& initiation_interval) -{ - initiation_interval = latency = 1; - - switch(category){ - case ALU_OP: - case INTP_OP: - case BRANCH_OP: - case CALL_OPS: - case RET_OPS: - latency = int_latency; - initiation_interval = int_init; - break; - case SP_OP: - latency = fp_latency; - initiation_interval = fp_init; - break; - case DP_OP: - latency = dp_latency; - initiation_interval = dp_init; - break; - case SFU_OP: - latency = sfu_latency; - initiation_interval = sfu_init; - break; - case TENSOR_CORE_OP: - latency = tensor_latency; - initiation_interval = tensor_init; - break; - default: - break; - } - +void trace_config::set_latency(unsigned category, unsigned& latency, + unsigned& initiation_interval) { + initiation_interval = latency = 1; + + switch (category) { + case ALU_OP: + case INTP_OP: + case BRANCH_OP: + case CALL_OPS: + case RET_OPS: + latency = int_latency; + initiation_interval = int_init; + break; + case SP_OP: + latency = fp_latency; + initiation_interval = fp_init; + break; + case DP_OP: + latency = dp_latency; + initiation_interval = dp_init; + break; + case SFU_OP: + latency = sfu_latency; + initiation_interval = sfu_init; + break; + case TENSOR_CORE_OP: + latency = tensor_latency; + initiation_interval = tensor_init; + break; + default: + break; + } } -unsigned trace_shader_core_ctx::trace_sim_inc_thread( kernel_info_t &kernel) -{ - - if ( kernel.no_more_ctas_to_run() ) { - return 0; //finished! - } +unsigned trace_shader_core_ctx::trace_sim_inc_thread(kernel_info_t& kernel) { + if (kernel.no_more_ctas_to_run()) { + return 0; // finished! + } - if( kernel.more_threads_in_cta() ) { - kernel.increment_thread_id(); - } + if (kernel.more_threads_in_cta()) { + kernel.increment_thread_id(); + } - if( !kernel.more_threads_in_cta() ) - kernel.increment_cta_id(); + if (!kernel.more_threads_in_cta()) kernel.increment_cta_id(); - return 1; + return 1; } -void trace_shader_core_ctx::init_traces( unsigned start_warp, unsigned end_warp, kernel_info_t &kernel ) { - - std::vector*> threadblock_traces; - for (unsigned i = start_warp; i < end_warp; ++i) { - m_trace_warp[i].clear(); - threadblock_traces.push_back(&(m_trace_warp[i].warp_traces)); - } - trace_kernel_info_t& trace_kernel = static_cast (kernel); - trace_kernel.get_next_threadblock_traces(threadblock_traces); - - //set pc - for (unsigned i = start_warp; i < end_warp; ++i) { - m_warp[i].set_next_pc(m_trace_warp[i].get_start_pc()); - } +void trace_shader_core_ctx::init_traces(unsigned start_warp, unsigned end_warp, + kernel_info_t& kernel) { + std::vector*> threadblock_traces; + for (unsigned i = start_warp; i < end_warp; ++i) { + m_trace_warp[i].clear(); + threadblock_traces.push_back(&(m_trace_warp[i].warp_traces)); + } + trace_kernel_info_t& trace_kernel = static_cast(kernel); + trace_kernel.get_next_threadblock_traces(threadblock_traces); + + // set pc + for (unsigned i = start_warp; i < end_warp; ++i) { + m_warp[i].set_next_pc(m_trace_warp[i].get_start_pc()); + } } +void trace_shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t& inst, + unsigned t, + unsigned tid) { + if (inst.isatomic()) m_warp[inst.warp_id()].inc_n_atomic(); -void trace_shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid) -{ - if(inst.isatomic()) - m_warp[inst.warp_id()].inc_n_atomic(); - - if ( inst.op == EXIT_OPS ) { - m_warp[inst.warp_id()].set_completed(t); - } - + if (inst.op == EXIT_OPS) { + m_warp[inst.warp_id()].set_completed(t); + } } -void trace_shader_core_ctx::func_exec_inst( warp_inst_t &inst ) -{ - //here, we generate memory acessess and set the status if thread (done?) - if( inst.is_load() || inst.is_store() ) - { - inst.generate_mem_accesses(); - } - for ( unsigned t=0; t < m_warp_size; t++ ) { - if( inst.active(t) ) { - unsigned warpId = inst.warp_id(); - unsigned tid=m_warp_size*warpId+t; - - //virtual function - checkExecutionStatusAndUpdate(inst,t,tid); - } - } - if(m_trace_warp[inst.warp_id()].trace_done() && m_warp[inst.warp_id()].functional_done()) { - m_warp[inst.warp_id()].ibuffer_flush(); - m_barriers.warp_exit( inst.warp_id() ); - } +void trace_shader_core_ctx::func_exec_inst(warp_inst_t& inst) { + // here, we generate memory acessess and set the status if thread (done?) + if (inst.is_load() || inst.is_store()) { + inst.generate_mem_accesses(); + } + for (unsigned t = 0; t < m_warp_size; t++) { + if (inst.active(t)) { + unsigned warpId = inst.warp_id(); + unsigned tid = m_warp_size * warpId + t; + + // virtual function + checkExecutionStatusAndUpdate(inst, t, tid); + } + } + if (m_trace_warp[inst.warp_id()].trace_done() && + m_warp[inst.warp_id()].functional_done()) { + m_warp[inst.warp_id()].ibuffer_flush(); + m_barriers.warp_exit(inst.warp_id()); + } } - diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index e9fecd9..09a2527 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -1,8 +1,8 @@ -//developed by Mahmoud Khairy, Purdue Univ +// developed by Mahmoud Khairy, Purdue Univ +#include #include #include -#include #ifndef TRACE_DRIVEN_H #define TRACE_DRIVEN_H @@ -11,143 +11,144 @@ #include "../gpgpu-sim/shader.h" #include "ISA_Def/trace_opcode.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; - } +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 void set_kernel_info (const struct gpgpu_ptx_sim_info &info) { - m_kernel_info = info; - } + virtual const struct gpgpu_ptx_sim_info* get_kernel_info() const { + return &m_kernel_info; + } - virtual ~trace_function_info() { - - } + virtual const void set_kernel_info(const struct gpgpu_ptx_sim_info& info) { + m_kernel_info = info; + } + virtual ~trace_function_info() {} }; -class trace_warp_inst_t: public warp_inst_t { -public: - - trace_warp_inst_t() { - m_gpgpu_context=NULL; - m_opcode=0; - m_tconfig=NULL; - } - - trace_warp_inst_t(const class core_config *config, gpgpu_context* gpgpu_context, class trace_config* tconfig ):warp_inst_t(config) { - m_gpgpu_context = gpgpu_context; - m_opcode=0; - m_tconfig=tconfig; - } - - bool parse_from_string(std::string trace, const std::unordered_map* OpcodeMap); - -private: - gpgpu_context* m_gpgpu_context; - class trace_config* m_tconfig; - unsigned m_opcode; - bool check_opcode_contain(const std::vector& opcode, std::string param); - unsigned get_datawidth_from_opcode(const std::vector& opcode); +class trace_warp_inst_t : public warp_inst_t { + public: + trace_warp_inst_t() { + m_gpgpu_context = NULL; + m_opcode = 0; + m_tconfig = NULL; + } + + trace_warp_inst_t(const class core_config* config, + gpgpu_context* gpgpu_context, class trace_config* tconfig) + : warp_inst_t(config) { + m_gpgpu_context = gpgpu_context; + m_opcode = 0; + m_tconfig = tconfig; + } + + bool parse_from_string( + std::string trace, + const std::unordered_map* OpcodeMap); + + private: + gpgpu_context* m_gpgpu_context; + class trace_config* m_tconfig; + unsigned m_opcode; + bool check_opcode_contain(const std::vector& opcode, + std::string param); + unsigned get_datawidth_from_opcode(const std::vector& opcode); }; -class trace_kernel_info_t: public kernel_info_t { -public: - trace_kernel_info_t(dim3 gridDim, dim3 blockDim, unsigned m_binary_verion, trace_function_info* m_function_info, std::ifstream* inputstream, gpgpu_sim * gpgpu_sim, gpgpu_context* gpgpu_context, class trace_config* config); - - bool get_next_threadblock_traces(std::vector*> threadblock_traces); - -private: - std::ifstream* ifs; - gpgpu_sim * m_gpgpu_sim; - gpgpu_context* m_gpgpu_context; - trace_config* m_tconfig; - unsigned binary_verion; - const std::unordered_map* OpcodeMap; - +class trace_kernel_info_t : public kernel_info_t { + public: + trace_kernel_info_t(dim3 gridDim, dim3 blockDim, unsigned m_binary_verion, + trace_function_info* m_function_info, + std::ifstream* inputstream, gpgpu_sim* gpgpu_sim, + gpgpu_context* gpgpu_context, class trace_config* config); + + bool get_next_threadblock_traces( + std::vector*> threadblock_traces); + + private: + std::ifstream* ifs; + gpgpu_sim* m_gpgpu_sim; + gpgpu_context* m_gpgpu_context; + trace_config* m_tconfig; + unsigned binary_verion; + const std::unordered_map* OpcodeMap; }; - class trace_config { -public: - trace_config(gpgpu_sim * m_gpgpu_sim); - - void set_latency(unsigned category, unsigned& latency, unsigned& initiation_interval); - void parse_config(); + public: + trace_config(gpgpu_sim* m_gpgpu_sim); + void set_latency(unsigned category, unsigned& latency, + unsigned& initiation_interval); + void parse_config(); -private: - - unsigned int_latency, fp_latency, dp_latency, sfu_latency, tensor_latency; - unsigned int_init, fp_init, dp_init, sfu_init, tensor_init; - gpgpu_sim* m_gpgpu_sim; - + private: + unsigned int_latency, fp_latency, dp_latency, sfu_latency, tensor_latency; + unsigned int_init, fp_init, dp_init, sfu_init, tensor_init; + 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 parse_kernellist_file(); - trace_kernel_info_t* parse_kernel_info(const std::string& kerneltraces_filepath, trace_config* config); - void parse_memcpy_info(const std::string& memcpy_command, size_t& add, size_t& count); - - 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; - + public: + trace_parser(const char* kernellist_filepath, gpgpu_sim* m_gpgpu_sim, + gpgpu_context* m_gpgpu_context); + + std::vector parse_kernellist_file(); + trace_kernel_info_t* parse_kernel_info( + const std::string& kerneltraces_filepath, trace_config* config); + void parse_memcpy_info(const std::string& memcpy_command, size_t& add, + size_t& count); + + 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: - trace_shd_warp_t() { - trace_pc=0; - } - - std::vector warp_traces; - const trace_warp_inst_t* get_next_inst(); - void clear(); - bool trace_done(); - address_type get_start_pc(); - address_type get_pc(); - -private: - unsigned trace_pc; - + public: + trace_shd_warp_t() { trace_pc = 0; } + + std::vector warp_traces; + const trace_warp_inst_t* get_next_inst(); + void clear(); + bool trace_done(); + address_type get_start_pc(); + address_type get_pc(); + + private: + unsigned trace_pc; }; -class trace_shader_core_ctx: public shader_core_ctx { -public: - trace_shader_core_ctx(class gpgpu_sim *gpu, - class simt_core_cluster *cluster, - unsigned shader_id, - unsigned tpc_id, - const shader_core_config *config, - const memory_config *mem_config, - shader_core_stats *stats):shader_core_ctx(gpu, cluster, shader_id, tpc_id, config, mem_config, stats) { - - m_trace_warp.resize(get_config()->max_warps_per_shader); - } - - virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid); - void init_traces( unsigned start_warp, unsigned end_warp, kernel_info_t &kernel ); - unsigned trace_sim_inc_thread( kernel_info_t &kernel); - virtual void func_exec_inst( warp_inst_t &inst ); - friend class shader_core_ctx; - -private: - std::vector m_trace_warp; - +class trace_shader_core_ctx : public shader_core_ctx { + public: + trace_shader_core_ctx(class gpgpu_sim* gpu, class simt_core_cluster* cluster, + unsigned shader_id, unsigned tpc_id, + const shader_core_config* config, + const memory_config* mem_config, + shader_core_stats* stats) + : shader_core_ctx(gpu, cluster, shader_id, tpc_id, config, mem_config, + stats) { + m_trace_warp.resize(get_config()->max_warps_per_shader); + } + + virtual void checkExecutionStatusAndUpdate(warp_inst_t& inst, unsigned t, + unsigned tid); + void init_traces(unsigned start_warp, unsigned end_warp, + kernel_info_t& kernel); + unsigned trace_sim_inc_thread(kernel_info_t& kernel); + virtual void func_exec_inst(warp_inst_t& inst); + friend class shader_core_ctx; + + private: + std::vector m_trace_warp; }; #endif -- cgit v1.3 From 000631e85a91caef9ef8e6aa11551265655cff39 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Sat, 23 May 2020 23:08:17 -0400 Subject: adding turing ISA --- src/trace-driven/ISA_Def/trace_opcode.h | 61 ++++++---- src/trace-driven/ISA_Def/turing_opcode.h | 201 ++++++++++++++++++++++++++++++- 2 files changed, 235 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/trace-driven/ISA_Def/trace_opcode.h b/src/trace-driven/ISA_Def/trace_opcode.h index 0badabc..e68be45 100644 --- a/src/trace-driven/ISA_Def/trace_opcode.h +++ b/src/trace-driven/ISA_Def/trace_opcode.h @@ -9,7 +9,7 @@ #include "../../abstract_hardware_model.h" enum TraceInstrOpcode { - // volta (common insts for others cards as well) + // Volta (includes common insts for others cards as well) OP_FADD = 1, OP_FADD32I, OP_FCHK, @@ -165,6 +165,43 @@ enum TraceInstrOpcode { OP_PSET, OP_VMNMX, OP_ISET, + // unique insts for turing + OP_BMMA, + OP_MOVM, + OP_LDSM, + OP_R2UR, + OP_S2UR, + OP_UBMSK, + OP_UBREV, + OP_UCLEA, + OP_UFLO, + OP_UIADD3, + OP_UIMAD, + OP_UISETP, + OP_ULDC, + OP_ULEA, + OP_ULOP, + OP_ULOP3, + OP_ULOP32I, + OP_UMOV, + OP_UP2UR, + OP_UPLOP3, + OP_UPOPC, + OP_UPRMT, + OP_UPSETP, + OP_UR2UP, + OP_USEL, + OP_USGXT, + OP_USHF, + OP_USHL, + OP_USHR, + OP_VOTEU, + OP_SUATOM, + OP_SULD, + OP_SURED, + OP_SUST, + OP_BRXU, + OP_JMXU, // unique insts for kepler OP_FCMP, OP_FSWZ, @@ -181,28 +218,6 @@ enum TraceInstrOpcode { }; typedef enum TraceInstrOpcode sass_op_type; -/* -enum uarch_op_t { - NO_OP=-1, - ALU_OP=1, - SFU_OP, - TENSOR_CORE_OP, - DP_OP, - SP_OP, - INTP_OP, - ALU_SFU_OP, - LOAD_OP, - TENSOR_CORE_LOAD_OP, - TENSOR_CORE_STORE_OP, - STORE_OP, - BRANCH_OP, - BARRIER_OP, - MEMORY_BARRIER_OP, - CALL_OPS, - RET_OPS -}; -typedef enum uarch_op_t op_type; - */ struct OpcodeChar { OpcodeChar(unsigned m_opcode, unsigned m_opcode_category) { diff --git a/src/trace-driven/ISA_Def/turing_opcode.h b/src/trace-driven/ISA_Def/turing_opcode.h index 97921ca..0374bdd 100644 --- a/src/trace-driven/ISA_Def/turing_opcode.h +++ b/src/trace-driven/ISA_Def/turing_opcode.h @@ -8,15 +8,208 @@ #include #include "trace_opcode.h" -// TO DO: moving this to a yml or def files +#define TURING_BINART_VERSION 75 +#define TURING_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 -#define TURING_BINART_VERSION 72 +// TO DO: moving this to a yml or def files -/// Tuing SM_72 ISA +/// Volta SM_70 ISA // see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html static const std::unordered_map Turing_OpcodeMap = { + // Floating Point 32 Instructions + {"FADD", OpcodeChar(OP_FADD, SP_OP)}, + {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, + {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, + {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, + {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, + {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, + {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, + {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, + {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, + {"FSET", OpcodeChar(OP_FSET, SP_OP)}, + {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, + {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, + // SFU + {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, + + // Floating Point 16 Instructions + {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, + {"HADD2_32I", OpcodeChar(OP_HADD2_32I, SP_OP)}, + {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, + {"HFMA2_32I", OpcodeChar(OP_HFMA2_32I, SP_OP)}, + {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, + {"HMUL2_32I", OpcodeChar(OP_HMUL2_32I, SP_OP)}, + {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, + {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, + + // Tensor Core Instructions + {"HMMA", OpcodeChar(OP_HMMA, TENSOR_CORE_OP)}, + + // Double Point Instructions + {"DADD", OpcodeChar(OP_DADD, DP_OP)}, + {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, + {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, + {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, + + // Integer Instructions + {"BMMA", OpcodeChar(OP_BMMA, INTP_OP)}, //////// + {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, + {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, + {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, + {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, + {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, + {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, + {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, + {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, + {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, + {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, + {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, + {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, + {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, + {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, + {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, + {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, + {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, + {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, + {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, + {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, + {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, + {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, + {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, + {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, ////////// + {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, + {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, + {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, + + // Conversion Instructions + {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, + {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, + {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, + {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, + {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, + {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, + + // Movement Instructions + {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, + {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, + {"MOVM", OpcodeChar(OP_MOVM, ALU_OP)}, // move matrix + {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, + {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, + {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, + {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, + + // Predicate Instructions + {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, + {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, + {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, + {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, + + // Load/Store Instructions + {"LD", OpcodeChar(OP_LD, LOAD_OP)}, + // For now, we ignore constant loads, consider it as ALU_OP, TO DO + {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, + {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, + {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, + {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, + {"LDSM", OpcodeChar(OP_LDSM, LOAD_OP)}, // + {"ST", OpcodeChar(OP_ST, STORE_OP)}, + {"STG", OpcodeChar(OP_STG, STORE_OP)}, + {"STL", OpcodeChar(OP_STL, STORE_OP)}, + {"STS", OpcodeChar(OP_STS, STORE_OP)}, + {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, + {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, + {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, + {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, + {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, + {"RED", OpcodeChar(OP_RED, STORE_OP)}, + {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, + {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, + {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, + {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, + {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, + + // Uniform Datapath Instruction // + {"R2UR", OpcodeChar(OP_R2UR, ALU_OP)}, + {"S2UR", OpcodeChar(OP_S2UR, ALU_OP)}, + {"UBMSK", OpcodeChar(OP_UBMSK, ALU_OP)}, + {"UBREV", OpcodeChar(OP_UBREV, ALU_OP)}, + {"UCLEA", OpcodeChar(OP_UCLEA, ALU_OP)}, + {"UFLO", OpcodeChar(OP_UFLO, ALU_OP)}, + {"UIADD3", OpcodeChar(OP_UIADD3, ALU_OP)}, + {"UIMAD", OpcodeChar(OP_UIMAD, ALU_OP)}, + {"UISETP", OpcodeChar(OP_UISETP, ALU_OP)}, + {"ULDC", OpcodeChar(OP_ULDC, ALU_OP)}, + {"ULEA", OpcodeChar(OP_ULEA, ALU_OP)}, + {"ULOP", OpcodeChar(OP_ULOP, ALU_OP)}, + {"ULOP3", OpcodeChar(OP_ULOP3, ALU_OP)}, + {"ULOP32I", OpcodeChar(OP_ULOP32I, ALU_OP)}, + {"UMOV", OpcodeChar(OP_UMOV, ALU_OP)}, + {"UP2UR", OpcodeChar(OP_UP2UR, ALU_OP)}, + {"UPLOP3", OpcodeChar(OP_UPLOP3, ALU_OP)}, + {"UPOPC", OpcodeChar(OP_UPOPC, ALU_OP)}, + {"UPRMT", OpcodeChar(OP_UPRMT, ALU_OP)}, + {"UPSETP", OpcodeChar(OP_UPSETP, ALU_OP)}, + {"UR2UP", OpcodeChar(OP_UR2UP, ALU_OP)}, + {"USEL", OpcodeChar(OP_USEL, ALU_OP)}, + {"USGXT", OpcodeChar(OP_USGXT, ALU_OP)}, + {"USHF", OpcodeChar(OP_USHF, ALU_OP)}, + {"USHL", OpcodeChar(OP_USHL, ALU_OP)}, + {"USHR", OpcodeChar(OP_USHR, ALU_OP)}, + {"VOTEU", OpcodeChar(OP_VOTEU, ALU_OP)}, + + // Texture Instructions + // For now, we ignore texture loads, consider it as ALU_OP + {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, + {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, + {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, + {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, + {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, + {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, + + // Surface Instructions // + {"SUATOM", OpcodeChar(OP_SUATOM, ALU_OP)}, + {"SULD", OpcodeChar(OP_SULD, ALU_OP)}, + {"SURED", OpcodeChar(OP_SURED, ALU_OP)}, + {"SUST", OpcodeChar(OP_SUST, ALU_OP)}, + + // Control Instructions + {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, + {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, + {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, + {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, + {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, + {"BRXU", OpcodeChar(OP_BRXU, BRANCH_OP)}, // + {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, + {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, + {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, + {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, + {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, + {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, + {"JMXU", OpcodeChar(OP_JMXU, BRANCH_OP)}, /// + {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, + {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, + {"RET", OpcodeChar(OP_RET, RET_OPS)}, + {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, + {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, + {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, + {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, - // TO fill + // Miscellaneous Instructions + {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, + {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, + {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, + {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, + {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, + {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, + {"LEPC", OpcodeChar(OP_LEPC, ALU_OP)}, + {"NOP", OpcodeChar(OP_NOP, ALU_OP)}, + {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, + {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, + {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, + {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, + {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, + {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, + {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, }; -- cgit v1.3 From 7ebe47ac5d1f0255527a27a9bb7cd3c29fa9f6e3 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Tue, 26 May 2020 15:12:38 -0400 Subject: splitting the trace-diven from the gpgpu-sim --- src/gpgpu-sim/gpu-sim.cc | 26 ++++-- src/gpgpu-sim/l2cache.cc | 1 + src/gpgpu-sim/shader.cc | 152 +++++++++++++++----------------- src/gpgpu-sim/shader.h | 31 ++++--- src/trace-driven/ISA_Def/trace_opcode.h | 1 - src/trace-driven/trace_driven.cc | 46 +++++----- src/trace-driven/trace_driven.h | 26 +++--- 7 files changed, 148 insertions(+), 135 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 5d75e50..05a19f0 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -60,7 +60,6 @@ #include "../debug.h" #include "../gpgpusim_entrypoint.h" #include "../statwrapper.h" -#include "../trace-driven/trace_driven.h" #include "../trace.h" #include "mem_latency_stat.h" #include "power_stat.h" @@ -1584,6 +1583,20 @@ void shader_core_ctx::release_shader_resource_1block(unsigned hw_ctaid, * object that tells us which kernel to ask for a CTA from */ +unsigned shader_core_ctx::sim_inc_thread(kernel_info_t &kernel) { + if (kernel.no_more_ctas_to_run()) { + return 0; // finished! + } + + if (kernel.more_threads_in_cta()) { + kernel.increment_thread_id(); + } + + if (!kernel.more_threads_in_cta()) kernel.increment_cta_id(); + + return 1; +} + void shader_core_ctx::issue_block2core(kernel_info_t &kernel) { if (!m_config->gpgpu_concurrent_kernel_sm) set_max_cta(kernel); @@ -1649,10 +1662,10 @@ void shader_core_ctx::issue_block2core(kernel_info_t &kernel) { for (unsigned i = start_thread; i < end_thread; i++) { m_threadState[i].m_cta_id = free_cta_hw_id; unsigned warp_id = i / m_config->warp_size; + // in trace-driven mode, bypass the functional model initialization, no need + // for this if (m_gpu->get_config().is_trace_driven_mode()) { - trace_shader_core_ctx *trace_core = - static_cast(this); - nthreads_in_block += trace_core->trace_sim_inc_thread(kernel); + nthreads_in_block += sim_inc_thread(kernel); } else nthreads_in_block += ptx_sim_init_thread( kernel, &m_thread[i], m_sid, i, cta_size - (i - start_thread), @@ -1992,13 +2005,14 @@ void shader_core_ctx::dump_warp_state(FILE *fout) const { fprintf(fout, "\n"); fprintf(fout, "per warp functional simulation status:\n"); for (unsigned w = 0; w < m_config->max_warps_per_shader; w++) - m_warp[w].print(fout); + m_warp[w]->print(fout); } void gpgpu_sim::perf_memcpy_to_gpu(size_t dst_start_addr, size_t count) { if (m_memory_config->m_perf_sim_memcpy) { // if(!m_config.trace_driven_mode) //in trace-driven mode, CUDA runtime - // can start nre data structure at any position assert (dst_start_addr % 32 + // can start nre data structure at any position assert (dst_start_addr % + // 32 //== 0); for (unsigned counter = 0; counter < count; counter += 32) { diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index b7b5745..7fed99b 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -793,6 +793,7 @@ void memory_sub_partition::push(mem_fetch *m_req, unsigned long long cycle) { mem_fetch *memory_sub_partition::pop() { mem_fetch *mf = m_L2_icnt_queue->pop(); m_request_tracker.erase(mf); + // in trace-driven mode, we bypass the atomic functional model if (mf && mf->isatomic() && !m_gpu->get_config().is_trace_driven_mode()) { mf->do_atomic(); } diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index ebb6878..ee8076d 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -153,7 +153,14 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, get_shader_instruction_cache_id(), m_icnt, IN_L1I_MISS_QUEUE); - m_warp.resize(m_config->max_warps_per_shader, shd_warp_t(this, warp_size)); + m_warp.resize(m_config->max_warps_per_shader); + for (unsigned k = 0; k < m_config->max_warps_per_shader; ++k) { + if (m_gpu->get_config().is_trace_driven_mode()) + m_warp[k] = new trace_shd_warp_t(this, warp_size); + else + m_warp[k] = new shd_warp_t(this, warp_size); + } + // m_warp.resize(m_config->max_warps_per_shader, shd_warp_t(this, warp_size)); m_scoreboard = new Scoreboard(m_sid, m_config->max_warps_per_shader, gpu); // scedulers @@ -437,7 +444,7 @@ void shader_core_ctx::reinit(unsigned start_thread, unsigned end_thread, } for (unsigned i = start_thread / m_config->warp_size; i < end_thread / m_config->warp_size; ++i) { - m_warp[i].reset(); + m_warp[i]->reset(); m_simt_stack[i]->reset(); } } @@ -484,17 +491,11 @@ void shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread, start_pc = pc; } - m_warp[i].init(start_pc, cta_id, i, active_threads, m_dynamic_warp_id); + m_warp[i]->init(start_pc, cta_id, i, active_threads, m_dynamic_warp_id); ++m_dynamic_warp_id; m_not_completed += n_active; ++m_active_warps; } - - if (m_gpu->get_config().is_trace_driven_mode()) { - trace_shader_core_ctx *trace_core = - static_cast(this); - trace_core->init_traces(start_warp, end_warp, kernel); - } } } @@ -789,14 +790,14 @@ void shader_core_ctx::decode() { address_type pc = m_inst_fetch_buffer.m_pc; const warp_inst_t *pI1; if (m_gpu->get_config().is_trace_driven_mode()) { - trace_shader_core_ctx *trace_core = - static_cast(this); - pI1 = trace_core->m_trace_warp[m_inst_fetch_buffer.m_warp_id] - .get_next_inst(); - } else + // read the inst from the traces + pI1 = m_warp[m_inst_fetch_buffer.m_warp_id]->get_next_trace_inst(); + } else { + // read the inst from the functional model pI1 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc); - m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(0, pI1); - m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline(); + } + m_warp[m_inst_fetch_buffer.m_warp_id]->ibuffer_fill(0, pI1); + m_warp[m_inst_fetch_buffer.m_warp_id]->inc_inst_in_pipeline(); if (pI1) { m_stats->m_num_decoded_insn[m_sid]++; if (pI1->oprnd_type == INT_OP) { @@ -806,15 +807,15 @@ void shader_core_ctx::decode() { } const warp_inst_t *pI2; if (m_gpu->get_config().is_trace_driven_mode()) { - trace_shader_core_ctx *trace_core = - static_cast(this); - pI2 = trace_core->m_trace_warp[m_inst_fetch_buffer.m_warp_id] - .get_next_inst(); - } else + // read the inst from the traces + pI2 = m_warp[m_inst_fetch_buffer.m_warp_id]->get_next_trace_inst(); + } else { + // read the inst from the functional model pI2 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc + pI1->isize); + } if (pI2) { - m_warp[m_inst_fetch_buffer.m_warp_id].ibuffer_fill(1, pI2); - m_warp[m_inst_fetch_buffer.m_warp_id].inc_inst_in_pipeline(); + m_warp[m_inst_fetch_buffer.m_warp_id]->ibuffer_fill(1, pI2); + m_warp[m_inst_fetch_buffer.m_warp_id]->inc_inst_in_pipeline(); m_stats->m_num_decoded_insn[m_sid]++; if (pI2->oprnd_type == INT_OP) { m_stats->m_num_INTdecoded_insn[m_sid]++; @@ -831,21 +832,16 @@ void shader_core_ctx::fetch() { if (!m_inst_fetch_buffer.m_valid) { if (m_L1I->access_ready()) { mem_fetch *mf = m_L1I->next_access(); - m_warp[mf->get_wid()].clear_imiss_pending(); - m_inst_fetch_buffer = ifetch_buffer_t( - m_warp[mf->get_wid()].get_pc(), mf->get_access_size(), mf->get_wid()); - if (m_gpu->get_config().is_trace_driven_mode()) { - trace_shader_core_ctx *trace_core = - static_cast(this); - assert(trace_core->m_trace_warp[mf->get_wid()].get_pc() == - (address_type)(mf->get_addr() - PROGRAM_MEM_START)); - } else - assert(m_warp[mf->get_wid()].get_pc() == - (mf->get_addr() - - PROGRAM_MEM_START)); // Verify that we got the instruction we - // were expecting. + m_warp[mf->get_wid()]->clear_imiss_pending(); + m_inst_fetch_buffer = + ifetch_buffer_t(m_warp[mf->get_wid()]->get_pc(), + mf->get_access_size(), mf->get_wid()); + assert(m_warp[mf->get_wid()]->get_pc() == + (mf->get_addr() - + PROGRAM_MEM_START)); // Verify that we got the instruction we + // were expecting. m_inst_fetch_buffer.m_valid = true; - m_warp[mf->get_wid()].set_last_fetch(m_gpu->gpu_sim_cycle); + m_warp[mf->get_wid()]->set_last_fetch(m_gpu->gpu_sim_cycle); delete mf; } else { // find an active warp with space in instruction buffer that is not @@ -857,46 +853,38 @@ void shader_core_ctx::fetch() { // this code checks if this warp has finished executing and can be // reclaimed - if (m_warp[warp_id].hardware_done() && + if (m_warp[warp_id]->hardware_done() && !m_scoreboard->pendingWrites(warp_id) && - !m_warp[warp_id].done_exit()) { + !m_warp[warp_id]->done_exit()) { bool did_exit = false; for (unsigned t = 0; t < m_config->warp_size; t++) { unsigned tid = warp_id * m_config->warp_size + t; if (m_threadState[tid].m_active == true) { m_threadState[tid].m_active = false; - unsigned cta_id = m_warp[warp_id].get_cta_id(); - if (m_gpu->get_config().is_trace_driven_mode()) { + unsigned cta_id = m_warp[warp_id]->get_cta_id(); + if (m_thread[tid] == NULL) { register_cta_thread_exit(cta_id, m_kernel); } else register_cta_thread_exit(cta_id, &(m_thread[tid]->get_kernel())); m_not_completed -= 1; m_active_threads.reset(tid); - if (!m_gpu->get_config().is_trace_driven_mode()) - assert(m_thread[tid] != NULL); did_exit = true; } } - if (did_exit) m_warp[warp_id].set_done_exit(); + if (did_exit) m_warp[warp_id]->set_done_exit(); --m_active_warps; assert(m_active_warps >= 0); } // this code fetches instructions from the i-cache or generates memory - if (!m_warp[warp_id].functional_done() && - !m_warp[warp_id].imiss_pending() && - m_warp[warp_id].ibuffer_empty()) { + if (!m_warp[warp_id]->functional_done() && + !m_warp[warp_id]->imiss_pending() && + m_warp[warp_id]->ibuffer_empty()) { address_type pc; - if (m_gpu->get_config().is_trace_driven_mode()) { - trace_shader_core_ctx *trace_core = - static_cast(this); - pc = trace_core->m_trace_warp[warp_id].get_pc(); - } else - pc = m_warp[warp_id].get_pc(); + pc = m_warp[warp_id]->get_pc(); address_type ppc = pc + PROGRAM_MEM_START; - unsigned nbytes = - m_gpu->get_config().is_trace_driven_mode() ? 32 : 16; + unsigned nbytes = 16; unsigned offset_in_block = pc & (m_config->m_L1I_config.get_line_sz() - 1); if ((offset_in_block + nbytes) > m_config->m_L1I_config.get_line_sz()) @@ -920,12 +908,12 @@ void shader_core_ctx::fetch() { if (status == MISS) { m_last_warp_fetched = warp_id; - m_warp[warp_id].set_imiss_pending(); - m_warp[warp_id].set_last_fetch(m_gpu->gpu_sim_cycle); + m_warp[warp_id]->set_imiss_pending(); + m_warp[warp_id]->set_last_fetch(m_gpu->gpu_sim_cycle); } else if (status == HIT) { m_last_warp_fetched = warp_id; m_inst_fetch_buffer = ifetch_buffer_t(pc, nbytes, warp_id); - m_warp[warp_id].set_last_fetch(m_gpu->gpu_sim_cycle); + m_warp[warp_id]->set_last_fetch(m_gpu->gpu_sim_cycle); delete mf; } else { m_last_warp_fetched = warp_id; @@ -957,23 +945,23 @@ void shader_core_ctx::issue_warp(register_set &pipe_reg_set, pipe_reg_set.get_free(m_config->sub_core_model, sch_id); assert(pipe_reg); - m_warp[warp_id].ibuffer_free(); + m_warp[warp_id]->ibuffer_free(); assert(next_inst->valid()); **pipe_reg = *next_inst; // static instruction information (*pipe_reg)->issue(active_mask, warp_id, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, - m_warp[warp_id].get_dynamic_warp_id(), + m_warp[warp_id]->get_dynamic_warp_id(), sch_id); // dynamic instruction information m_stats->shader_cycle_distro[2 + (*pipe_reg)->active_count()]++; func_exec_inst(**pipe_reg); if (next_inst->op == BARRIER_OP) { - m_warp[warp_id].store_info_of_last_inst_at_barrier(*pipe_reg); - m_barriers.warp_reaches_barrier(m_warp[warp_id].get_cta_id(), warp_id, + m_warp[warp_id]->store_info_of_last_inst_at_barrier(*pipe_reg); + m_barriers.warp_reaches_barrier(m_warp[warp_id]->get_cta_id(), warp_id, const_cast(next_inst)); } else if (next_inst->op == MEMORY_BARRIER_OP) { - m_warp[warp_id].set_membar(); + m_warp[warp_id]->set_membar(); } if (!m_gpu->get_config() @@ -981,7 +969,7 @@ void shader_core_ctx::issue_warp(register_set &pipe_reg_set, updateSIMTStack(warp_id, *pipe_reg); m_scoreboard->reserveRegisters(*pipe_reg); - m_warp[warp_id].set_next_pc(next_inst->pc + next_inst->isize); + m_warp[warp_id]->set_next_pc(next_inst->pc + next_inst->isize); } void shader_core_ctx::issue() { @@ -999,7 +987,7 @@ void shader_core_ctx::issue() { //} } -shd_warp_t &scheduler_unit::warp(int i) { return (*m_warp)[i]; } +shd_warp_t &scheduler_unit::warp(int i) { return *((*m_warp)[i]); } /** * A general function to order things in a Loose Round Robin way. The simplist @@ -1144,8 +1132,7 @@ void scheduler_unit::cycle() { bool warp_inst_issued = false; unsigned pc, rpc; if (m_shader->m_gpu->get_config().is_trace_driven_mode()) - pc = pI->pc; // assume no control hazard in trace mode. TO DO: to be - // fixed + pc = pI->pc; // assume no control hazard in trace-driven mode. else m_simt_stack[warp_id]->get_pdom_stack_top_info(&pc, &rpc); SCHED_DPRINTF( @@ -1171,7 +1158,7 @@ void scheduler_unit::cycle() { (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id()); ready_inst = true; - // For Trace-driven, the active mask already set in from traces, so + // For Trace-driven, the active mask already set in traces, so // just read it from the inst const active_mask_t &active_mask = m_shader->m_gpu->get_config().is_trace_driven_mode() @@ -1482,7 +1469,7 @@ void two_level_active_scheduler::order_warps() { swl_scheduler::swl_scheduler(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector *warp, + std::vector *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, @@ -1712,7 +1699,7 @@ void shader_core_ctx::writeback() { m_operand_collector.writeback(*pipe_reg); unsigned warp_id = pipe_reg->warp_id(); m_scoreboard->releaseRegisters(pipe_reg); - m_warp[warp_id].dec_inst_in_pipeline(); + m_warp[warp_id]->dec_inst_in_pipeline(); warp_inst_complete(*pipe_reg); m_gpu->gpu_sim_insn_last_update_sid = m_sid; m_gpu->gpu_sim_insn_last_update = m_gpu->gpu_sim_cycle; @@ -2380,6 +2367,7 @@ void ldst_unit::writeback() { if (!m_pipeline_reg[0]->empty()) { m_next_wb = *m_pipeline_reg[0]; if (m_next_wb.isatomic()) { + // it trace driven mode, we bypass the atomic functional model if (!m_core->get_gpu()->get_config().is_trace_driven_mode()) m_next_wb.do_atomic(); m_core->decrement_atomic_count(m_next_wb.warp_id(), @@ -3049,7 +3037,7 @@ void shader_core_ctx::display_pipeline(FILE *fout, int print_mem, } fprintf(fout, "\nibuffer status:\n"); for (unsigned i = 0; i < m_config->max_warps_per_shader; i++) { - if (!m_warp[i].ibuffer_empty()) m_warp[i].print_ibuffer(fout); + if (!m_warp[i]->ibuffer_empty()) m_warp[i]->print_ibuffer(fout); } fprintf(fout, "\n"); display_simt_state(fout, mask); @@ -3342,7 +3330,7 @@ std::list opndcoll_rfu_t::arbiter_t::allocate_reads() { assert(output < _outputs); if ((output < _outputs) && (_inmatch[input] == -1) && //( _outmatch[output] == -1 ) && //allow OC to read multiple reg - //banks at the same cycle + // banks at the same cycle (_request[input][output] /*.label != -1*/)) { // Grant! _inmatch[input] = output; @@ -3569,7 +3557,7 @@ bool shader_core_ctx::check_if_non_released_reduction_barrier( bool non_released_barrier_reduction = false; bool warp_stucked_at_barrier = warp_waiting_at_barrier(warp_id); bool single_inst_in_pipeline = - (m_warp[warp_id].num_issued_inst_in_pipeline() == 1); + (m_warp[warp_id]->num_issued_inst_in_pipeline() == 1); non_released_barrier_reduction = single_inst_in_pipeline and warp_stucked_at_barrier and bar_red_op; printf("non_released_barrier_reduction=%u\n", non_released_barrier_reduction); @@ -3581,9 +3569,9 @@ bool shader_core_ctx::warp_waiting_at_barrier(unsigned warp_id) const { } bool shader_core_ctx::warp_waiting_at_mem_barrier(unsigned warp_id) { - if (!m_warp[warp_id].get_membar()) return false; + if (!m_warp[warp_id]->get_membar()) return false; if (!m_scoreboard->pendingWrites(warp_id)) { - m_warp[warp_id].clear_membar(); + m_warp[warp_id]->clear_membar(); if (m_gpu->get_config().flush_l1()) { // Mahmoud fixed this on Nov 2019 // Invalidate L1 cache @@ -3609,8 +3597,8 @@ void shader_core_ctx::set_max_cta(const kernel_info_t &kernel) { } void shader_core_ctx::decrement_atomic_count(unsigned wid, unsigned n) { - assert(m_warp[wid].get_n_atomic() >= n); - m_warp[wid].dec_n_atomic(n); + assert(m_warp[wid]->get_n_atomic() >= n); + m_warp[wid]->dec_n_atomic(n); } void shader_core_ctx::broadcast_barrier_reduction(unsigned cta_id, @@ -3619,7 +3607,7 @@ void shader_core_ctx::broadcast_barrier_reduction(unsigned cta_id, for (unsigned i = 0; i < m_config->max_warps_per_shader; i++) { if (warps.test(i)) { const warp_inst_t *inst = - m_warp[i].restore_info_of_last_inst_at_barrier(); + m_warp[i]->restore_info_of_last_inst_at_barrier(); const_cast(inst)->broadcast_barrier_reduction( inst->get_active_mask()); } @@ -3646,7 +3634,7 @@ void shader_core_ctx::store_ack(class mem_fetch *mf) { assert(mf->get_type() == WRITE_ACK || (m_config->gpgpu_perfect_mem && mf->get_is_write())); unsigned warp_id = mf->get_wid(); - m_warp[warp_id].dec_store_req(); + m_warp[warp_id]->dec_store_req(); } void shader_core_ctx::print_cache_stats(FILE *fp, unsigned &dl1_accesses, @@ -4358,7 +4346,7 @@ void simt_core_cluster::get_L1T_sub_stats(struct cache_sub_stats &css) const { void shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid) { - if (inst.isatomic()) m_warp[inst.warp_id()].inc_n_atomic(); + if (inst.isatomic()) m_warp[inst.warp_id()]->inc_n_atomic(); if (inst.space.is_local() && (inst.is_load() || inst.is_store())) { new_addr_type localaddrs[MAX_ACCESSES_PER_INSN_PER_THREAD]; unsigned num_addrs; @@ -4369,8 +4357,8 @@ void shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, inst.set_addr(t, (new_addr_type *)localaddrs, num_addrs); } if (ptx_thread_done(tid)) { - m_warp[inst.warp_id()].set_completed(t); - m_warp[inst.warp_id()].ibuffer_flush(); + m_warp[inst.warp_id()]->set_completed(t); + m_warp[inst.warp_id()]->ibuffer_flush(); } // PC-Histogram Update diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index bd08794..8e29a78 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -167,7 +167,7 @@ class shd_warp_t { void set_membar() { m_membar = true; } void clear_membar() { m_membar = false; } bool get_membar() const { return m_membar; } - address_type get_pc() const { return m_next_pc; } + virtual address_type get_pc() const { return m_next_pc; } void set_next_pc(address_type pc) { m_next_pc = pc; } void store_info_of_last_inst_at_barrier(const warp_inst_t *pI) { @@ -237,6 +237,9 @@ class shd_warp_t { unsigned get_dynamic_warp_id() const { return m_dynamic_warp_id; } unsigned get_warp_id() const { return m_warp_id; } + // this fuction is used for trace_driven mode + virtual const warp_inst_t *get_next_trace_inst() { return NULL; } + private: static const unsigned IBUFFER_SIZE = 2; class shader_core_ctx *m_shader; @@ -326,7 +329,7 @@ class scheduler_unit { // this can be copied freely, so can be used in std public: scheduler_unit(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector *warp, register_set *sp_out, + std::vector *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, register_set *mem_out, int id) @@ -415,7 +418,7 @@ class scheduler_unit { // this can be copied freely, so can be used in std Scoreboard *m_scoreboard; simt_stack **m_simt_stack; // warp_inst_t** m_pipeline_reg; - std::vector *m_warp; + std::vector *m_warp; register_set *m_sp_out; register_set *m_dp_out; register_set *m_sfu_out; @@ -430,7 +433,7 @@ class lrr_scheduler : public scheduler_unit { public: lrr_scheduler(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector *warp, register_set *sp_out, + std::vector *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, register_set *mem_out, int id) @@ -447,7 +450,7 @@ class gto_scheduler : public scheduler_unit { public: gto_scheduler(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector *warp, register_set *sp_out, + std::vector *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, register_set *mem_out, int id) @@ -464,7 +467,7 @@ class oldest_scheduler : public scheduler_unit { public: oldest_scheduler(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector *warp, register_set *sp_out, + std::vector *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, register_set *mem_out, int id) @@ -481,7 +484,7 @@ class two_level_active_scheduler : public scheduler_unit { public: two_level_active_scheduler(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector *warp, + std::vector *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, @@ -530,7 +533,7 @@ class swl_scheduler : public scheduler_unit { public: swl_scheduler(shader_core_stats *stats, shader_core_ctx *shader, Scoreboard *scoreboard, simt_stack **simt, - std::vector *warp, register_set *sp_out, + std::vector *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, register_set *mem_out, int id, char *config_string); @@ -1868,9 +1871,9 @@ class shader_core_ctx : public core_t { // modifiers void mem_instruction_stats(const warp_inst_t &inst); void decrement_atomic_count(unsigned wid, unsigned n); - void inc_store_req(unsigned warp_id) { m_warp[warp_id].inc_store_req(); } + void inc_store_req(unsigned warp_id) { m_warp[warp_id]->inc_store_req(); } void dec_inst_in_pipeline(unsigned warp_id) { - m_warp[warp_id].dec_inst_in_pipeline(); + m_warp[warp_id]->dec_inst_in_pipeline(); } // also used in writeback() void store_ack(class mem_fetch *mf); bool warp_waiting_at_mem_barrier(unsigned warp_id); @@ -2061,8 +2064,9 @@ class shader_core_ctx : public core_t { } int test_res_bus(int latency); - void init_warps(unsigned cta_id, unsigned start_thread, unsigned end_thread, - unsigned ctaid, int cta_size, kernel_info_t &kernel); + virtual void init_warps(unsigned cta_id, unsigned start_thread, + unsigned end_thread, unsigned ctaid, int cta_size, + kernel_info_t &kernel); virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, unsigned tid); address_type next_pc(int tid) const; @@ -2128,7 +2132,7 @@ class shader_core_ctx : public core_t { int m_last_warp_fetched; // decode/dispatch - std::vector m_warp; // per warp information array + std::vector m_warp; // per warp information array barrier_set_t m_barriers; ifetch_buffer_t m_inst_fetch_buffer; std::vector m_pipeline_reg; @@ -2178,6 +2182,7 @@ class shader_core_ctx : public core_t { std::map m_occupied_cta_to_hwtid; friend class trace_shader_core_ctx; + unsigned sim_inc_thread(kernel_info_t &kernel); }; class simt_core_cluster { diff --git a/src/trace-driven/ISA_Def/trace_opcode.h b/src/trace-driven/ISA_Def/trace_opcode.h index e68be45..5675957 100644 --- a/src/trace-driven/ISA_Def/trace_opcode.h +++ b/src/trace-driven/ISA_Def/trace_opcode.h @@ -218,7 +218,6 @@ enum TraceInstrOpcode { }; typedef enum TraceInstrOpcode sass_op_type; - struct OpcodeChar { OpcodeChar(unsigned m_opcode, unsigned m_opcode_category) { opcode = m_opcode; diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 44468b1..8fa63b4 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -173,7 +173,7 @@ void trace_parser::kernel_finalizer(trace_kernel_info_t* kernel_info) { delete kernel_info; } -const trace_warp_inst_t* trace_shd_warp_t::get_next_inst() { +const trace_warp_inst_t* trace_shd_warp_t::get_next_trace_inst() { if (trace_pc < warp_traces.size()) { return &warp_traces[trace_pc++]; } else @@ -188,7 +188,7 @@ void trace_shd_warp_t::clear() { // functional_done bool trace_shd_warp_t::trace_done() { return trace_pc == (warp_traces.size()); } -address_type trace_shd_warp_t::get_start_pc() { +address_type trace_shd_warp_t::get_start_trace_pc() { assert(warp_traces.size() > 0); return warp_traces[0].pc; } @@ -629,43 +629,46 @@ void trace_config::set_latency(unsigned category, unsigned& latency, } } -unsigned trace_shader_core_ctx::trace_sim_inc_thread(kernel_info_t& kernel) { - if (kernel.no_more_ctas_to_run()) { - return 0; // finished! - } - - if (kernel.more_threads_in_cta()) { - kernel.increment_thread_id(); - } +void trace_shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread, + unsigned end_thread, unsigned ctaid, + int cta_size, kernel_info_t& kernel) { + // call base class + shader_core_ctx::init_warps(cta_id, start_thread, end_thread, ctaid, cta_size, + kernel); - if (!kernel.more_threads_in_cta()) kernel.increment_cta_id(); + // then init traces + unsigned start_warp = start_thread / m_config->warp_size; + unsigned end_warp = end_thread / m_config->warp_size + + ((end_thread % m_config->warp_size) ? 1 : 0); - return 1; + init_traces(start_warp, end_warp, kernel); } void trace_shader_core_ctx::init_traces(unsigned start_warp, unsigned end_warp, kernel_info_t& kernel) { std::vector*> threadblock_traces; for (unsigned i = start_warp; i < end_warp; ++i) { - m_trace_warp[i].clear(); - threadblock_traces.push_back(&(m_trace_warp[i].warp_traces)); + trace_shd_warp_t* m_trace_warp = static_cast(m_warp[i]); + m_trace_warp->clear(); + threadblock_traces.push_back(&(m_trace_warp->warp_traces)); } trace_kernel_info_t& trace_kernel = static_cast(kernel); trace_kernel.get_next_threadblock_traces(threadblock_traces); - // set pc + // set the pc from the traces and ignore the functional model for (unsigned i = start_warp; i < end_warp; ++i) { - m_warp[i].set_next_pc(m_trace_warp[i].get_start_pc()); + trace_shd_warp_t* m_trace_warp = static_cast(m_warp[i]); + m_trace_warp->set_next_pc(m_trace_warp->get_start_trace_pc()); } } void trace_shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t& inst, unsigned t, unsigned tid) { - if (inst.isatomic()) m_warp[inst.warp_id()].inc_n_atomic(); + if (inst.isatomic()) m_warp[inst.warp_id()]->inc_n_atomic(); if (inst.op == EXIT_OPS) { - m_warp[inst.warp_id()].set_completed(t); + m_warp[inst.warp_id()]->set_completed(t); } } @@ -683,9 +686,10 @@ void trace_shader_core_ctx::func_exec_inst(warp_inst_t& inst) { checkExecutionStatusAndUpdate(inst, t, tid); } } - if (m_trace_warp[inst.warp_id()].trace_done() && - m_warp[inst.warp_id()].functional_done()) { - m_warp[inst.warp_id()].ibuffer_flush(); + trace_shd_warp_t* m_trace_warp = + static_cast(m_warp[inst.warp_id()]); + if (m_trace_warp->trace_done() && m_trace_warp->functional_done()) { + m_trace_warp->ibuffer_flush(); m_barriers.warp_exit(inst.warp_id()); } } diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index 09a2527..a35cd83 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -112,16 +112,19 @@ class trace_parser { gpgpu_context* m_gpgpu_context; }; -class trace_shd_warp_t { +class trace_shd_warp_t : public shd_warp_t { public: - trace_shd_warp_t() { trace_pc = 0; } + trace_shd_warp_t(class shader_core_ctx* shader, unsigned warp_size) + : shd_warp_t(shader, warp_size) { + trace_pc = 0; + } std::vector warp_traces; - const trace_warp_inst_t* get_next_inst(); + const trace_warp_inst_t* get_next_trace_inst(); void clear(); bool trace_done(); - address_type get_start_pc(); - address_type get_pc(); + address_type get_start_trace_pc(); + virtual address_type get_pc(); private: unsigned trace_pc; @@ -135,20 +138,19 @@ class trace_shader_core_ctx : public shader_core_ctx { const memory_config* mem_config, shader_core_stats* stats) : shader_core_ctx(gpu, cluster, shader_id, tpc_id, config, mem_config, - stats) { - m_trace_warp.resize(get_config()->max_warps_per_shader); - } + stats) {} virtual void checkExecutionStatusAndUpdate(warp_inst_t& inst, unsigned t, unsigned tid); - void init_traces(unsigned start_warp, unsigned end_warp, - kernel_info_t& kernel); - unsigned trace_sim_inc_thread(kernel_info_t& kernel); + virtual void init_warps(unsigned cta_id, unsigned start_thread, + unsigned end_thread, unsigned ctaid, int cta_size, + kernel_info_t& kernel); virtual void func_exec_inst(warp_inst_t& inst); friend class shader_core_ctx; private: - std::vector m_trace_warp; + void init_traces(unsigned start_warp, unsigned end_warp, + kernel_info_t& kernel); }; #endif -- cgit v1.3 From ede0540e798bac59f65111c8d48661f042412aa8 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Wed, 27 May 2020 18:52:01 -0400 Subject: splitting trace-driven from gpgpu-sim - part 2 --- libcuda/gpgpu_context.h | 1 - src/abstract_hardware_model.cc | 1 + src/abstract_hardware_model.h | 4 +- src/gpgpu-sim/gpu-sim.cc | 82 +++-------- src/gpgpu-sim/gpu-sim.h | 23 +-- src/gpgpu-sim/l2cache.cc | 5 +- src/gpgpu-sim/shader.cc | 187 +++++++++++++------------ src/gpgpu-sim/shader.h | 98 ++++++++++--- src/gpgpusim_entrypoint.cc | 37 +---- src/trace-driven/gpgpusim_trace_driven_main.cc | 62 ++++++-- src/trace-driven/trace_driven.cc | 126 ++++++++++++++--- src/trace-driven/trace_driven.h | 59 +++++++- 12 files changed, 427 insertions(+), 258 deletions(-) (limited to 'src') diff --git a/libcuda/gpgpu_context.h b/libcuda/gpgpu_context.h index f02e365..d0cd7c4 100644 --- a/libcuda/gpgpu_context.h +++ b/libcuda/gpgpu_context.h @@ -77,7 +77,6 @@ class gpgpu_context { const ptx_instruction *pc_to_instruction(unsigned pc); const warp_inst_t *ptx_fetch_inst(address_type pc); unsigned translate_pc_to_ptxlineno(unsigned pc); - class gpgpu_sim *gpgpu_trace_sim_init_perf(int argc, const char *argv[]); }; gpgpu_context *GPGPU_Context(); diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index 1247235..5ad6f10 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -257,6 +257,7 @@ void warp_inst_t::do_atomic(bool forceDo) { void warp_inst_t::do_atomic(const active_mask_t &access_mask, bool forceDo) { assert(m_isatomic && (!m_empty || forceDo)); + if (!should_do_atomic) return; for (unsigned i = 0; i < m_config->warp_size; i++) { if (access_mask.test(i)) { dram_callback_t &cb = m_per_scalar_thread[i].callback; diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index ef457a7..c58d39c 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -997,6 +997,7 @@ class warp_inst_t : public inst_t { m_cache_hit = false; m_is_printf = false; m_is_cdp = 0; + should_do_atomic = true; } virtual ~warp_inst_t() {} @@ -1144,6 +1145,7 @@ class warp_inst_t : public inst_t { unsigned long long issue_cycle; unsigned cycles; // used for implementing initiation interval delay bool m_isatomic; + bool should_do_atomic; bool m_is_printf; unsigned m_warp_id; unsigned m_dynamic_warp_id; @@ -1232,7 +1234,7 @@ class core_t { } void execute_warp_inst_t(warp_inst_t &inst, unsigned warpId = (unsigned)-1); bool ptx_thread_done(unsigned hw_thread_id) const; - void updateSIMTStack(unsigned warpId, warp_inst_t *inst); + virtual void updateSIMTStack(unsigned warpId, warp_inst_t *inst); void initilizeSIMTStack(unsigned warp_count, unsigned warps_size); void deleteSIMTStack(); warp_inst_t getExecuteWarp(unsigned warpId); diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 05a19f0..b62524e 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -529,32 +529,6 @@ void shader_core_config::reg_options(class OptionParser *opp) { option_parser_register(opp, "-gpgpu_reg_file_port_throughput", OPT_INT32, ®_file_port_throughput, "the number ports of the register file", "1"); - // used for trace-driven mode - option_parser_register(opp, "-trace_opcode_latency_initiation_int", OPT_CSTR, - &trace_opcode_latency_initiation_int, - "Opcode latencies and initiation for integers in " - "trace driven mode ", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_sp", OPT_CSTR, - &trace_opcode_latency_initiation_sp, - "Opcode latencies and initiation for sp in trace " - "driven mode ", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_dp", OPT_CSTR, - &trace_opcode_latency_initiation_dp, - "Opcode latencies and initiation for dp in trace " - "driven mode ", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_sfu", OPT_CSTR, - &trace_opcode_latency_initiation_sfu, - "Opcode latencies and initiation for sfu in trace " - "driven mode ", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_tensor", - OPT_CSTR, &trace_opcode_latency_initiation_tensor, - "Opcode latencies and initiation for tensor in trace " - "driven mode ", - "4,1"); } void gpgpu_sim_config::reg_options(option_parser_t opp) { @@ -665,17 +639,6 @@ void gpgpu_sim_config::reg_options(option_parser_t opp) { &(gpgpu_ctx->device_runtime->g_TB_launch_latency), "thread block launch latency in cycles. Default: 0", "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_skip_first_kernel", OPT_BOOL, - &trace_skip_first_kernel, - "skip first intiliztion kernel in trace mode", "0"); - option_parser_register(opp, "-trace", OPT_CSTR, &g_traces_filename, - "traces kernel file" - "traces kernel file directory", - "./traces/kernelslist.g"); } ///////////////////////////////////////////////////////////////////////////// @@ -828,6 +791,14 @@ void gpgpu_sim::stop_all_running_kernels() { } } +void exec_gpgpu_sim::createSIMTCluster() { + m_cluster = new simt_core_cluster *[m_shader_config->n_simt_clusters]; + for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) + m_cluster[i] = + new exec_simt_core_cluster(this, i, m_shader_config, m_memory_config, + m_shader_stats, m_memory_stats); +} + gpgpu_sim::gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx) : gpgpu_t(config, ctx), m_config(config) { gpgpu_ctx = ctx; @@ -868,12 +839,6 @@ gpgpu_sim::gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx) partiton_replys_in_parallel = 0; partiton_replys_in_parallel_total = 0; - m_cluster = new simt_core_cluster *[m_shader_config->n_simt_clusters]; - for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) - m_cluster[i] = - new simt_core_cluster(this, i, m_shader_config, m_memory_config, - m_shader_stats, m_memory_stats); - m_memory_partition_unit = new memory_partition_unit *[m_memory_config->m_n_mem]; m_memory_sub_partition = @@ -1583,18 +1548,12 @@ void shader_core_ctx::release_shader_resource_1block(unsigned hw_ctaid, * object that tells us which kernel to ask for a CTA from */ -unsigned shader_core_ctx::sim_inc_thread(kernel_info_t &kernel) { - if (kernel.no_more_ctas_to_run()) { - return 0; // finished! - } - - if (kernel.more_threads_in_cta()) { - kernel.increment_thread_id(); - } - - if (!kernel.more_threads_in_cta()) kernel.increment_cta_id(); - - return 1; +unsigned exec_shader_core_ctx::sim_init_thread( + kernel_info_t &kernel, ptx_thread_info **thread_info, int sid, unsigned tid, + unsigned threads_left, unsigned num_threads, core_t *core, + unsigned hw_cta_id, unsigned hw_warp_id, gpgpu_t *gpu) { + return ptx_sim_init_thread(kernel, thread_info, sid, tid, threads_left, + num_threads, core, hw_cta_id, hw_warp_id, gpu); } void shader_core_ctx::issue_block2core(kernel_info_t &kernel) { @@ -1662,15 +1621,10 @@ void shader_core_ctx::issue_block2core(kernel_info_t &kernel) { for (unsigned i = start_thread; i < end_thread; i++) { m_threadState[i].m_cta_id = free_cta_hw_id; unsigned warp_id = i / m_config->warp_size; - // in trace-driven mode, bypass the functional model initialization, no need - // for this - if (m_gpu->get_config().is_trace_driven_mode()) { - nthreads_in_block += sim_inc_thread(kernel); - } else - nthreads_in_block += ptx_sim_init_thread( - kernel, &m_thread[i], m_sid, i, cta_size - (i - start_thread), - m_config->n_thread_per_shader, this, free_cta_hw_id, warp_id, - m_cluster->get_gpu()); + nthreads_in_block += sim_init_thread( + kernel, &m_thread[i], m_sid, i, cta_size - (i - start_thread), + m_config->n_thread_per_shader, this, free_cta_hw_id, warp_id, + m_cluster->get_gpu()); m_threadState[i].m_active = true; // load thread local memory and register file if (m_gpu->resume_option == 1 && kernel.get_uid() == m_gpu->resume_kernel && diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 53f6ead..e083d33 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -370,9 +370,6 @@ class gpgpu_sim_config : public power_config, return runtime_pending_launch_count_limit; } - bool is_trace_driven_mode() const { return trace_driven_mode; } - bool is_skip_first_kernel() const { return trace_skip_first_kernel; } - char *get_traces_filename() const { return g_traces_filename; } bool flush_l1() const { return gpgpu_flush_l1_cache; } private: @@ -427,11 +424,6 @@ class gpgpu_sim_config : public power_config, unsigned int gpgpu_compute_capability_minor; unsigned long long liveness_message_freq; - // trace driven mode options - bool trace_driven_mode; - bool trace_skip_first_kernel; - char *g_traces_filename; - friend class gpgpu_sim; }; @@ -588,8 +580,8 @@ class gpgpu_sim : public gpgpu_t { void gpgpu_debug(); + protected: ///// data ///// - class simt_core_cluster **m_cluster; class memory_partition_unit **m_memory_partition_unit; class memory_sub_partition **m_memory_sub_partition; @@ -645,6 +637,9 @@ class gpgpu_sim : public gpgpu_t { void clear_executed_kernel_info(); //< clear the kernel information after // stat printout + virtual void createSIMTCluster() = 0; + void callCreateSIMTCluster(); + public: unsigned long long gpu_sim_insn; unsigned long long gpu_tot_sim_insn; @@ -692,4 +687,14 @@ class gpgpu_sim : public gpgpu_t { } }; +class exec_gpgpu_sim : public gpgpu_sim { + public: + exec_gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx) + : gpgpu_sim(config, ctx) { + createSIMTCluster(); + } + + virtual void createSIMTCluster(); +}; + #endif diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index 7fed99b..ab6e5c2 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -793,10 +793,7 @@ void memory_sub_partition::push(mem_fetch *m_req, unsigned long long cycle) { mem_fetch *memory_sub_partition::pop() { mem_fetch *mf = m_L2_icnt_queue->pop(); m_request_tracker.erase(mf); - // in trace-driven mode, we bypass the atomic functional model - if (mf && mf->isatomic() && !m_gpu->get_config().is_trace_driven_mode()) { - mf->do_atomic(); - } + if (mf && mf->isatomic()) mf->do_atomic(); if (mf && (mf->get_access_type() == L2_WRBK_ACC || mf->get_access_type() == L1_WRBK_ACC)) { delete mf; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index ee8076d..8efb88b 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -36,7 +36,6 @@ #include "../cuda-sim/ptx-stats.h" #include "../cuda-sim/ptx_sim.h" #include "../statwrapper.h" -#include "../trace-driven/trace_driven.h" #include "addrdec.h" #include "dram.h" #include "gpu-misc.h" @@ -75,27 +74,14 @@ std::list shader_core_ctx::get_regs_written(const inst_t &fvt) const { return result; } -shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, - class simt_core_cluster *cluster, - unsigned shader_id, unsigned tpc_id, - const shader_core_config *config, - const memory_config *mem_config, - shader_core_stats *stats) - : core_t(gpu, NULL, config->warp_size, config->n_thread_per_shader), - m_barriers(this, config->max_warps_per_shader, config->max_cta_per_core, - config->max_barriers_per_cta, config->warp_size), - m_active_warps(0), - m_dynamic_warp_id(0) { - m_cluster = cluster; - m_config = config; - m_memory_config = mem_config; - m_stats = stats; - unsigned warp_size = config->warp_size; - Issue_Prio = 0; - - m_sid = shader_id; - m_tpc = tpc_id; +void exec_shader_core_ctx::create_shd_warp() { + m_warp.resize(m_config->max_warps_per_shader); + for (unsigned k = 0; k < m_config->max_warps_per_shader; ++k) { + m_warp[k] = new shd_warp_t(this, m_config->warp_size); + } +} +void shader_core_ctx::create_front_pipeline() { m_pipeline_reg.reserve(N_PIPELINE_STAGES); for (int j = 0; j < N_PIPELINE_STAGES; j++) { m_pipeline_reg.push_back( @@ -121,14 +107,14 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, m_pipeline_reg[ID_OC_INT].get_size()); } - m_threadState = - (thread_ctx_t *)calloc(sizeof(thread_ctx_t), config->n_thread_per_shader); + m_threadState = (thread_ctx_t *)calloc(sizeof(thread_ctx_t), + m_config->n_thread_per_shader); m_not_completed = 0; m_active_threads.reset(); m_n_active_cta = 0; for (unsigned i = 0; i < MAX_CTA_PER_SHADER; i++) m_cta_status[i] = 0; - for (unsigned i = 0; i < config->n_thread_per_shader; i++) { + for (unsigned i = 0; i < m_config->n_thread_per_shader; i++) { m_thread[i] = NULL; m_threadState[i].m_cta_id = -1; m_threadState[i].m_active = false; @@ -136,12 +122,12 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, // m_icnt = new shader_memory_interface(this,cluster); if (m_config->gpgpu_perfect_mem) { - m_icnt = new perfect_memory_interface(this, cluster); + m_icnt = new perfect_memory_interface(this, m_cluster); } else { - m_icnt = new shader_memory_interface(this, cluster); + m_icnt = new shader_memory_interface(this, m_cluster); } m_mem_fetch_allocator = - new shader_core_mem_fetch_allocator(shader_id, tpc_id, mem_config); + new shader_core_mem_fetch_allocator(m_sid, m_tpc, m_memory_config); // fetch m_last_warp_fetched = 0; @@ -152,16 +138,10 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, m_L1I = new read_only_cache(name, m_config->m_L1I_config, m_sid, get_shader_instruction_cache_id(), m_icnt, IN_L1I_MISS_QUEUE); +} - m_warp.resize(m_config->max_warps_per_shader); - for (unsigned k = 0; k < m_config->max_warps_per_shader; ++k) { - if (m_gpu->get_config().is_trace_driven_mode()) - m_warp[k] = new trace_shd_warp_t(this, warp_size); - else - m_warp[k] = new shd_warp_t(this, warp_size); - } - // m_warp.resize(m_config->max_warps_per_shader, shd_warp_t(this, warp_size)); - m_scoreboard = new Scoreboard(m_sid, m_config->max_warps_per_shader, gpu); +void shader_core_ctx::create_schedulers() { + m_scoreboard = new Scoreboard(m_sid, m_config->max_warps_per_shader, m_gpu); // scedulers // must currently occur after all inputs have been initialized. @@ -196,7 +176,7 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_DP], &m_pipeline_reg[ID_OC_SFU], &m_pipeline_reg[ID_OC_INT], &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i, - config->gpgpu_scheduler_string)); + m_config->gpgpu_scheduler_string)); break; case CONCRETE_SCHEDULER_GTO: schedulers.push_back(new gto_scheduler( @@ -218,7 +198,7 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_DP], &m_pipeline_reg[ID_OC_SFU], &m_pipeline_reg[ID_OC_INT], &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i, - config->gpgpu_scheduler_string)); + m_config->gpgpu_scheduler_string)); break; default: abort(); @@ -233,9 +213,10 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, for (unsigned i = 0; i < m_config->gpgpu_num_sched_per_core; ++i) { schedulers[i]->done_adding_supervised_warps(); } +} +void shader_core_ctx::create_exec_pipeline() { // op collector configuration - enum { SP_CUS, DP_CUS, SFU_CUS, TENSOR_CORE_CUS, INT_CUS, MEM_CUS, GEN_CUS }; opndcoll_rfu_t::port_vector_t in_ports; @@ -280,8 +261,9 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, DP_CUS, m_config->gpgpu_operand_collector_num_units_dp, m_config->gpgpu_operand_collector_num_out_ports_dp); m_operand_collector.add_cu_set( - TENSOR_CORE_CUS, config->gpgpu_operand_collector_num_units_tensor_core, - config->gpgpu_operand_collector_num_out_ports_tensor_core); + TENSOR_CORE_CUS, + m_config->gpgpu_operand_collector_num_units_tensor_core, + m_config->gpgpu_operand_collector_num_out_ports_tensor_core); m_operand_collector.add_cu_set( SFU_CUS, m_config->gpgpu_operand_collector_num_units_sfu, m_config->gpgpu_operand_collector_num_out_ports_sfu); @@ -323,7 +305,7 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, } for (unsigned i = 0; - i < config->gpgpu_operand_collector_num_in_ports_tensor_core; i++) { + i < m_config->gpgpu_operand_collector_num_in_ports_tensor_core; i++) { in_ports.push_back(&m_pipeline_reg[ID_OC_TENSOR_CORE]); out_ports.push_back(&m_pipeline_reg[OC_EX_TENSOR_CORE]); cu_sets.push_back((unsigned)TENSOR_CORE_CUS); @@ -388,15 +370,15 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, m_issue_port.push_back(OC_EX_SFU); } - for (int k = 0; k < config->gpgpu_num_tensor_core_units; k++) { + for (int k = 0; k < m_config->gpgpu_num_tensor_core_units; k++) { m_fu.push_back(new tensor_core(&m_pipeline_reg[EX_WB], m_config, this)); m_dispatch_port.push_back(ID_OC_TENSOR_CORE); m_issue_port.push_back(OC_EX_TENSOR_CORE); } - m_ldst_unit = - new ldst_unit(m_icnt, m_mem_fetch_allocator, this, &m_operand_collector, - m_scoreboard, config, mem_config, stats, shader_id, tpc_id); + m_ldst_unit = new ldst_unit(m_icnt, m_mem_fetch_allocator, this, + &m_operand_collector, m_scoreboard, m_config, + m_memory_config, m_stats, m_sid, m_tpc); m_fu.push_back(m_ldst_unit); m_dispatch_port.push_back(ID_OC_MEM); m_issue_port.push_back(OC_EX_MEM); @@ -406,10 +388,32 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, m_fu.size() == m_issue_port.size()); // there are as many result buses as the width of the EX_WB stage - num_result_bus = config->pipe_widths[EX_WB]; + num_result_bus = m_config->pipe_widths[EX_WB]; for (unsigned i = 0; i < num_result_bus; i++) { this->m_result_bus.push_back(new std::bitset()); } +} + +shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, + class simt_core_cluster *cluster, + unsigned shader_id, unsigned tpc_id, + const shader_core_config *config, + const memory_config *mem_config, + shader_core_stats *stats) + : core_t(gpu, NULL, config->warp_size, config->n_thread_per_shader), + m_barriers(this, config->max_warps_per_shader, config->max_cta_per_core, + config->max_barriers_per_cta, config->warp_size), + m_active_warps(0), + m_dynamic_warp_id(0) { + m_cluster = cluster; + m_config = config; + m_memory_config = mem_config; + m_stats = stats; + unsigned warp_size = config->warp_size; + Issue_Prio = 0; + + m_sid = shader_id; + m_tpc = tpc_id; m_last_inst_gpu_sim_cycle = 0; m_last_inst_gpu_tot_sim_cycle = 0; @@ -784,18 +788,30 @@ void shader_core_stats::visualizer_print(gzFile visualizer_file) { 0xF0000000 /* should be distinct from other memory spaces... \ check ptx_ir.h to verify this does not overlap \ other memory spaces */ + +const warp_inst_t *exec_shader_core_ctx::get_next_inst(unsigned warp_id, + address_type pc) { + // read the inst from the functional model + return m_gpu->gpgpu_ctx->ptx_fetch_inst(pc); +} + +void exec_shader_core_ctx::get_pdom_stack_top_info(unsigned warp_id, + const warp_inst_t *pI, + unsigned *pc, + unsigned *rpc) { + m_simt_stack[warp_id]->get_pdom_stack_top_info(pc, rpc); +} + +const active_mask_t &exec_shader_core_ctx::get_active_mask( + unsigned warp_id, const warp_inst_t *pI) { + return m_simt_stack[warp_id]->get_active_mask(); +} + void shader_core_ctx::decode() { if (m_inst_fetch_buffer.m_valid) { // decode 1 or 2 instructions and place them into ibuffer address_type pc = m_inst_fetch_buffer.m_pc; - const warp_inst_t *pI1; - if (m_gpu->get_config().is_trace_driven_mode()) { - // read the inst from the traces - pI1 = m_warp[m_inst_fetch_buffer.m_warp_id]->get_next_trace_inst(); - } else { - // read the inst from the functional model - pI1 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc); - } + const warp_inst_t *pI1 = get_next_inst(m_inst_fetch_buffer.m_warp_id, pc); m_warp[m_inst_fetch_buffer.m_warp_id]->ibuffer_fill(0, pI1); m_warp[m_inst_fetch_buffer.m_warp_id]->inc_inst_in_pipeline(); if (pI1) { @@ -805,14 +821,8 @@ void shader_core_ctx::decode() { } else if (pI1->oprnd_type == FP_OP) { m_stats->m_num_FPdecoded_insn[m_sid]++; } - const warp_inst_t *pI2; - if (m_gpu->get_config().is_trace_driven_mode()) { - // read the inst from the traces - pI2 = m_warp[m_inst_fetch_buffer.m_warp_id]->get_next_trace_inst(); - } else { - // read the inst from the functional model - pI2 = m_gpu->gpgpu_ctx->ptx_fetch_inst(pc + pI1->isize); - } + const warp_inst_t *pI2 = + get_next_inst(m_inst_fetch_buffer.m_warp_id, pc + pI1->isize); if (pI2) { m_warp[m_inst_fetch_buffer.m_warp_id]->ibuffer_fill(1, pI2); m_warp[m_inst_fetch_buffer.m_warp_id]->inc_inst_in_pipeline(); @@ -864,9 +874,10 @@ void shader_core_ctx::fetch() { unsigned cta_id = m_warp[warp_id]->get_cta_id(); if (m_thread[tid] == NULL) { register_cta_thread_exit(cta_id, m_kernel); - } else + } else { register_cta_thread_exit(cta_id, &(m_thread[tid]->get_kernel())); + } m_not_completed -= 1; m_active_threads.reset(tid); did_exit = true; @@ -929,7 +940,7 @@ void shader_core_ctx::fetch() { m_L1I->cycle(); } -void shader_core_ctx::func_exec_inst(warp_inst_t &inst) { +void exec_shader_core_ctx::func_exec_inst(warp_inst_t &inst) { execute_warp_inst_t(inst); if (inst.is_load() || inst.is_store()) { inst.generate_mem_accesses(); @@ -964,9 +975,7 @@ void shader_core_ctx::issue_warp(register_set &pipe_reg_set, m_warp[warp_id]->set_membar(); } - if (!m_gpu->get_config() - .is_trace_driven_mode()) // No SIMT-stack in trace-driven mode - updateSIMTStack(warp_id, *pipe_reg); + updateSIMTStack(warp_id, *pipe_reg); m_scoreboard->reserveRegisters(*pipe_reg); m_warp[warp_id]->set_next_pc(next_inst->pc + next_inst->isize); @@ -1131,10 +1140,7 @@ void scheduler_unit::cycle() { bool valid = warp(warp_id).ibuffer_next_valid(); bool warp_inst_issued = false; unsigned pc, rpc; - if (m_shader->m_gpu->get_config().is_trace_driven_mode()) - pc = pI->pc; // assume no control hazard in trace-driven mode. - else - m_simt_stack[warp_id]->get_pdom_stack_top_info(&pc, &rpc); + m_shader->get_pdom_stack_top_info(warp_id, pI, &pc, &rpc); SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) has valid instruction (%s)\n", (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id(), @@ -1158,12 +1164,8 @@ void scheduler_unit::cycle() { (*iter)->get_warp_id(), (*iter)->get_dynamic_warp_id()); ready_inst = true; - // For Trace-driven, the active mask already set in traces, so - // just read it from the inst const active_mask_t &active_mask = - m_shader->m_gpu->get_config().is_trace_driven_mode() - ? pI->get_active_mask() - : m_simt_stack[warp_id]->get_active_mask(); + m_shader->get_active_mask(warp_id, pI); assert(warp(warp_id).inst_in_pipeline()); @@ -2367,9 +2369,7 @@ void ldst_unit::writeback() { if (!m_pipeline_reg[0]->empty()) { m_next_wb = *m_pipeline_reg[0]; if (m_next_wb.isatomic()) { - // it trace driven mode, we bypass the atomic functional model - if (!m_core->get_gpu()->get_config().is_trace_driven_mode()) - m_next_wb.do_atomic(); + m_next_wb.do_atomic(); m_core->decrement_atomic_count(m_next_wb.warp_id(), m_next_wb.active_count()); } @@ -4010,6 +4010,16 @@ void opndcoll_rfu_t::collector_unit_t::dispatch() { for (unsigned i = 0; i < MAX_REG_OPERANDS * 2; i++) m_src_op[i].reset(); } +void exec_simt_core_cluster::create_shader_core_ctx() { + m_core = new shader_core_ctx *[m_config->n_simt_cores_per_cluster]; + for (unsigned i = 0; i < m_config->n_simt_cores_per_cluster; i++) { + unsigned sid = m_config->cid_to_sid(i, m_cluster_id); + m_core[i] = new exec_shader_core_ctx(m_gpu, this, sid, m_cluster_id, + m_config, m_mem_config, m_stats); + m_core_sim_order.push_back(i); + } +} + simt_core_cluster::simt_core_cluster(class gpgpu_sim *gpu, unsigned cluster_id, const shader_core_config *config, const memory_config *mem_config, @@ -4022,17 +4032,7 @@ simt_core_cluster::simt_core_cluster(class gpgpu_sim *gpu, unsigned cluster_id, m_gpu = gpu; m_stats = stats; m_memory_stats = mstats; - m_core = new shader_core_ctx *[config->n_simt_cores_per_cluster]; - for (unsigned i = 0; i < config->n_simt_cores_per_cluster; i++) { - unsigned sid = m_config->cid_to_sid(i, m_cluster_id); - if (gpu->get_config().is_trace_driven_mode()) - m_core[i] = new trace_shader_core_ctx(gpu, this, sid, m_cluster_id, - config, mem_config, stats); - else - m_core[i] = new shader_core_ctx(gpu, this, sid, m_cluster_id, config, - mem_config, stats); - m_core_sim_order.push_back(i); - } + m_mem_config = mem_config; } void simt_core_cluster::core_cycle() { @@ -4344,8 +4344,9 @@ void simt_core_cluster::get_L1T_sub_stats(struct cache_sub_stats &css) const { css = total_css; } -void shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, - unsigned t, unsigned tid) { +void exec_shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t &inst, + unsigned t, + unsigned tid) { if (inst.isatomic()) m_warp[inst.warp_id()]->inc_n_atomic(); if (inst.space.is_local() && (inst.is_load() || inst.is_store())) { new_addr_type localaddrs[MAX_ACCESSES_PER_INSN_PER_THREAD]; diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 8e29a78..d77207d 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -237,9 +237,6 @@ class shd_warp_t { unsigned get_dynamic_warp_id() const { return m_dynamic_warp_id; } unsigned get_warp_id() const { return m_warp_id; } - // this fuction is used for trace_driven mode - virtual const warp_inst_t *get_next_trace_inst() { return NULL; } - private: static const unsigned IBUFFER_SIZE = 2; class shader_core_ctx *m_shader; @@ -1537,12 +1534,6 @@ class shader_core_config : public core_config { bool perfect_inst_const_cache; unsigned inst_fetch_throughput; unsigned reg_file_port_throughput; - - char *trace_opcode_latency_initiation_int; - char *trace_opcode_latency_initiation_sp; - char *trace_opcode_latency_initiation_dp; - char *trace_opcode_latency_initiation_sfu; - char *trace_opcode_latency_initiation_tensor; }; struct shader_core_stats_pod { @@ -2052,7 +2043,7 @@ class shader_core_ctx : public core_t { } bool check_if_non_released_reduction_barrier(warp_inst_t &inst); - private: + protected: unsigned inactive_lanes_accesses_sfu(unsigned active_count, double latency) { return (((32 - active_count) >> 1) * latency) + (((32 - active_count) >> 3) * latency) + @@ -2064,11 +2055,6 @@ class shader_core_ctx : public core_t { } int test_res_bus(int latency); - virtual void init_warps(unsigned cta_id, unsigned start_thread, - unsigned end_thread, unsigned ctaid, int cta_size, - kernel_info_t &kernel); - virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, - unsigned tid); address_type next_pc(int tid) const; void fetch(); void register_cta_thread_exit(unsigned cta_num, kernel_info_t *kernel); @@ -2082,7 +2068,35 @@ class shader_core_ctx : public core_t { void issue_warp(register_set &warp, const warp_inst_t *pI, const active_mask_t &active_mask, unsigned warp_id, unsigned sch_id); - virtual void func_exec_inst(warp_inst_t &inst); + + void create_front_pipeline(); + void create_schedulers(); + void create_exec_pipeline(); + + // pure virtual methods implemented based on the current execution mode + // (execution-driven vs trace-driven) + virtual void init_warps(unsigned cta_id, unsigned start_thread, + unsigned end_thread, unsigned ctaid, int cta_size, + kernel_info_t &kernel); + virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, + unsigned tid) = 0; + virtual void func_exec_inst(warp_inst_t &inst) = 0; + + virtual unsigned sim_init_thread(kernel_info_t &kernel, + ptx_thread_info **thread_info, int sid, + unsigned tid, unsigned threads_left, + unsigned num_threads, core_t *core, + unsigned hw_cta_id, unsigned hw_warp_id, + gpgpu_t *gpu) = 0; + + virtual void create_shd_warp() = 0; + + virtual const warp_inst_t *get_next_inst(unsigned warp_id, + address_type pc) = 0; + virtual void get_pdom_stack_top_info(unsigned warp_id, const warp_inst_t *pI, + unsigned *pc, unsigned *rpc) = 0; + virtual const active_mask_t &get_active_mask(unsigned warp_id, + const warp_inst_t *pI) = 0; // Returns numbers of addresses in translated_addrs unsigned translate_local_memaddr(address_type localaddr, unsigned tid, @@ -2098,6 +2112,7 @@ class shader_core_ctx : public core_t { // used in display_pipeline(): void dump_warp_state(FILE *fout) const; void print_stage(unsigned int stage, FILE *fout) const; + unsigned long long m_last_inst_gpu_sim_cycle; unsigned long long m_last_inst_gpu_tot_sim_cycle; @@ -2180,9 +2195,38 @@ class shader_core_ctx : public core_t { unsigned int m_occupied_ctas; std::bitset m_occupied_hwtid; std::map m_occupied_cta_to_hwtid; +}; - friend class trace_shader_core_ctx; - unsigned sim_inc_thread(kernel_info_t &kernel); +class exec_shader_core_ctx : public shader_core_ctx { + public: + exec_shader_core_ctx(class gpgpu_sim *gpu, class simt_core_cluster *cluster, + unsigned shader_id, unsigned tpc_id, + const shader_core_config *config, + const memory_config *mem_config, + shader_core_stats *stats) + : shader_core_ctx(gpu, cluster, shader_id, tpc_id, config, mem_config, + stats) { + create_front_pipeline(); + create_shd_warp(); + create_schedulers(); + create_exec_pipeline(); + } + + virtual void checkExecutionStatusAndUpdate(warp_inst_t &inst, unsigned t, + unsigned tid); + virtual void func_exec_inst(warp_inst_t &inst); + virtual unsigned sim_init_thread(kernel_info_t &kernel, + ptx_thread_info **thread_info, int sid, + unsigned tid, unsigned threads_left, + unsigned num_threads, core_t *core, + unsigned hw_cta_id, unsigned hw_warp_id, + gpgpu_t *gpu); + virtual void create_shd_warp(); + virtual const warp_inst_t *get_next_inst(unsigned warp_id, address_type pc); + virtual void get_pdom_stack_top_info(unsigned warp_id, const warp_inst_t *pI, + unsigned *pc, unsigned *rpc); + virtual const active_mask_t &get_active_mask(unsigned warp_id, + const warp_inst_t *pI); }; class simt_core_cluster { @@ -2232,20 +2276,36 @@ class simt_core_cluster { void get_icnt_stats(long &n_simt_to_mem, long &n_mem_to_simt) const; float get_current_occupancy(unsigned long long &active, unsigned long long &total) const; + virtual void create_shader_core_ctx() = 0; - private: + protected: unsigned m_cluster_id; gpgpu_sim *m_gpu; const shader_core_config *m_config; shader_core_stats *m_stats; memory_stats_t *m_memory_stats; shader_core_ctx **m_core; + const memory_config *m_mem_config; unsigned m_cta_issue_next_core; std::list m_core_sim_order; std::list m_response_fifo; }; +class exec_simt_core_cluster : public simt_core_cluster { + public: + exec_simt_core_cluster(class gpgpu_sim *gpu, unsigned cluster_id, + const shader_core_config *config, + const memory_config *mem_config, + class shader_core_stats *stats, + class memory_stats_t *mstats) + : simt_core_cluster(gpu, cluster_id, config, mem_config, stats, mstats) { + create_shader_core_ctx(); + } + + virtual void create_shader_core_ctx(); +}; + class shader_memory_interface : public mem_fetch_interface { public: shader_memory_interface(shader_core_ctx *core, simt_core_cluster *cluster) { diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc index 6ec3867..f4287d8 100644 --- a/src/gpgpusim_entrypoint.cc +++ b/src/gpgpusim_entrypoint.cc @@ -219,7 +219,7 @@ gpgpu_sim *gpgpu_context::gpgpu_ptx_sim_init_perf() { the_gpgpusim->g_the_gpu_config->init(); the_gpgpusim->g_the_gpu = - new gpgpu_sim(*(the_gpgpusim->g_the_gpu_config), this); + new exec_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); @@ -232,41 +232,6 @@ 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) { the_gpgpusim->g_sim_done = false; diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc index 4a5f14a..f12d39a 100644 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ b/src/trace-driven/gpgpusim_trace_driven_main.cc @@ -14,6 +14,7 @@ #include "../abstract_hardware_model.h" #include "../cuda-sim/cuda-sim.h" #include "../gpgpu-sim/gpu-sim.h" +#include "../gpgpu-sim/icnt_wrapper.h" #include "../gpgpusim_entrypoint.h" #include "../option_parser.h" #include "ISA_Def/trace_opcode.h" @@ -32,11 +33,16 @@ * index info in the traces header) 5- Get rid off traces intermediate files - * change the tracer */ +gpgpu_sim* gpgpu_trace_sim_init_perf_model(int argc, const char* argv[], + gpgpu_context* m_gpgpu_context, + class trace_config* m_config); int main(int argc, const char** argv) { gpgpu_context* m_gpgpu_context = new gpgpu_context(); + trace_config tconfig; + gpgpu_sim* m_gpgpu_sim = - m_gpgpu_context->gpgpu_trace_sim_init_perf(argc, argv); + gpgpu_trace_sim_init_perf_model(argc, argv, m_gpgpu_context, &tconfig); m_gpgpu_sim->init(); // for each kernel @@ -46,12 +52,11 @@ int main(int argc, const char** argv) { // 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); - trace_config config(m_gpgpu_sim); + trace_parser tracer(tconfig.get_traces_filename(), m_gpgpu_sim, + m_gpgpu_context); + tconfig.parse_config(); std::vector commandlist = tracer.parse_kernellist_file(); - bool first_kernel = true; for (unsigned i = 0; i < commandlist.size(); ++i) { trace_kernel_info_t* kernel_info = NULL; @@ -62,12 +67,7 @@ int main(int argc, const char** argv) { m_gpgpu_sim->perf_memcpy_to_gpu(addre, Bcount); continue; } else { - // skip the first unimportant initialization kernel - if (m_gpgpu_sim->get_config().is_skip_first_kernel() && first_kernel) { - first_kernel = false; - continue; - } - kernel_info = tracer.parse_kernel_info(commandlist[i], &config); + kernel_info = tracer.parse_kernel_info(commandlist[i], &tconfig); m_gpgpu_sim->launch(kernel_info); } @@ -121,3 +121,43 @@ int main(int argc, const char** argv) { return 1; } + +gpgpu_sim* gpgpu_trace_sim_init_perf_model(int argc, const char* argv[], + gpgpu_context* m_gpgpu_context, + trace_config* m_config) { + srand(1); + print_splash(); + + option_parser_t opp = option_parser_create(); + + m_gpgpu_context->ptx_reg_options(opp); + m_gpgpu_context->func_sim->ptx_opcocde_latency_options(opp); + + icnt_reg_options(opp); + + m_gpgpu_context->the_gpgpusim->g_the_gpu_config = + new gpgpu_sim_config(m_gpgpu_context); + m_gpgpu_context->the_gpgpusim->g_the_gpu_config->reg_options( + opp); // register GPU microrachitecture options + m_config->reg_options(opp); + + 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")); + m_gpgpu_context->the_gpgpusim->g_the_gpu_config->init(); + + m_gpgpu_context->the_gpgpusim->g_the_gpu = new trace_gpgpu_sim( + *(m_gpgpu_context->the_gpgpusim->g_the_gpu_config), m_gpgpu_context); + + m_gpgpu_context->the_gpgpusim->g_stream_manager = + new stream_manager((m_gpgpu_context->the_gpgpusim->g_the_gpu), + m_gpgpu_context->func_sim->g_cuda_launch_blocking); + + m_gpgpu_context->the_gpgpusim->g_simulation_starttime = time((time_t*)NULL); + + return m_gpgpu_context->the_gpgpusim->g_the_gpu; +} diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 8fa63b4..d42ee65 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -575,25 +575,48 @@ bool trace_warp_inst_t::parse_from_string( return true; } -trace_config::trace_config(gpgpu_sim* m_gpgpu_sim) { - this->m_gpgpu_sim = m_gpgpu_sim; - parse_config(); +trace_config::trace_config() {} + +void trace_config::reg_options(option_parser_t opp) { + option_parser_register(opp, "-trace", OPT_CSTR, &g_traces_filename, + "traces kernel file" + "traces kernel file directory", + "./traces/kernelslist.g"); + + option_parser_register(opp, "-trace_opcode_latency_initiation_int", OPT_CSTR, + &trace_opcode_latency_initiation_int, + "Opcode latencies and initiation for integers in " + "trace driven mode ", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_sp", OPT_CSTR, + &trace_opcode_latency_initiation_sp, + "Opcode latencies and initiation for sp in trace " + "driven mode ", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_dp", OPT_CSTR, + &trace_opcode_latency_initiation_dp, + "Opcode latencies and initiation for dp in trace " + "driven mode ", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_sfu", OPT_CSTR, + &trace_opcode_latency_initiation_sfu, + "Opcode latencies and initiation for sfu in trace " + "driven mode ", + "4,1"); + option_parser_register(opp, "-trace_opcode_latency_initiation_tensor", + OPT_CSTR, &trace_opcode_latency_initiation_tensor, + "Opcode latencies and initiation for tensor in trace " + "driven mode ", + "4,1"); } void trace_config::parse_config() { - sscanf( - m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_int, - "%u,%u", &int_latency, &int_init); - sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_sp, - "%u,%u", &fp_latency, &fp_init); - sscanf(m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_dp, - "%u,%u", &dp_latency, &dp_init); - sscanf( - m_gpgpu_sim->getShaderCoreConfig()->trace_opcode_latency_initiation_sfu, - "%u,%u", &sfu_latency, &sfu_init); - sscanf(m_gpgpu_sim->getShaderCoreConfig() - ->trace_opcode_latency_initiation_tensor, - "%u,%u", &tensor_latency, &tensor_init); + sscanf(trace_opcode_latency_initiation_int, "%u,%u", &int_latency, &int_init); + sscanf(trace_opcode_latency_initiation_sp, "%u,%u", &fp_latency, &fp_init); + sscanf(trace_opcode_latency_initiation_dp, "%u,%u", &dp_latency, &dp_init); + sscanf(trace_opcode_latency_initiation_sfu, "%u,%u", &sfu_latency, &sfu_init); + sscanf(trace_opcode_latency_initiation_tensor, "%u,%u", &tensor_latency, + &tensor_init); } void trace_config::set_latency(unsigned category, unsigned& latency, unsigned& initiation_interval) { @@ -629,6 +652,64 @@ void trace_config::set_latency(unsigned category, unsigned& latency, } } +void trace_gpgpu_sim::createSIMTCluster() { + m_cluster = new simt_core_cluster*[m_shader_config->n_simt_clusters]; + for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) + m_cluster[i] = + new trace_simt_core_cluster(this, i, m_shader_config, m_memory_config, + m_shader_stats, m_memory_stats); +} + +void trace_simt_core_cluster::create_shader_core_ctx() { + m_core = new shader_core_ctx*[m_config->n_simt_cores_per_cluster]; + for (unsigned i = 0; i < m_config->n_simt_cores_per_cluster; i++) { + unsigned sid = m_config->cid_to_sid(i, m_cluster_id); + m_core[i] = new trace_shader_core_ctx(m_gpu, this, sid, m_cluster_id, + m_config, m_mem_config, m_stats); + m_core_sim_order.push_back(i); + } +} + +void trace_shader_core_ctx::create_shd_warp() { + m_warp.resize(m_config->max_warps_per_shader); + for (unsigned k = 0; k < m_config->max_warps_per_shader; ++k) { + m_warp[k] = new trace_shd_warp_t(this, m_config->warp_size); + } +} + +void trace_shader_core_ctx::get_pdom_stack_top_info(unsigned warp_id, + const warp_inst_t* pI, + unsigned* pc, + unsigned* rpc) { + // In trace-driven mode, we assume no control hazard + *pc = pI->pc; + *rpc = pI->pc; +} + +const active_mask_t& trace_shader_core_ctx::get_active_mask( + unsigned warp_id, const warp_inst_t* pI) { + // For Trace-driven, the active mask already set in traces, so + // just read it from the inst + return pI->get_active_mask(); +} + +unsigned trace_shader_core_ctx::sim_init_thread( + kernel_info_t& kernel, ptx_thread_info** thread_info, int sid, unsigned tid, + unsigned threads_left, unsigned num_threads, core_t* core, + unsigned hw_cta_id, unsigned hw_warp_id, gpgpu_t* gpu) { + if (kernel.no_more_ctas_to_run()) { + return 0; // finished! + } + + if (kernel.more_threads_in_cta()) { + kernel.increment_thread_id(); + } + + if (!kernel.more_threads_in_cta()) kernel.increment_cta_id(); + + return 1; +} + void trace_shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread, unsigned end_thread, unsigned ctaid, int cta_size, kernel_info_t& kernel) { @@ -644,6 +725,19 @@ void trace_shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread, init_traces(start_warp, end_warp, kernel); } +const warp_inst_t* trace_shader_core_ctx::get_next_inst(unsigned warp_id, + address_type pc) { + // read the inst from the traces + trace_shd_warp_t* m_trace_warp = + static_cast(m_warp[warp_id]); + return m_trace_warp->get_next_trace_inst(); +} + +void trace_shader_core_ctx::updateSIMTStack(unsigned warpId, + warp_inst_t* inst) { + // No SIMT-stack in trace-driven mode +} + void trace_shader_core_ctx::init_traces(unsigned start_warp, unsigned end_warp, kernel_info_t& kernel) { std::vector*> threadblock_traces; diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index a35cd83..ea315a1 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -36,6 +36,7 @@ class trace_warp_inst_t : public warp_inst_t { m_gpgpu_context = NULL; m_opcode = 0; m_tconfig = NULL; + should_do_atomic = false; } trace_warp_inst_t(const class core_config* config, @@ -44,6 +45,7 @@ class trace_warp_inst_t : public warp_inst_t { m_gpgpu_context = gpgpu_context; m_opcode = 0; m_tconfig = tconfig; + should_do_atomic = false; } bool parse_from_string( @@ -80,16 +82,24 @@ class trace_kernel_info_t : public kernel_info_t { class trace_config { public: - trace_config(gpgpu_sim* m_gpgpu_sim); + trace_config(); void set_latency(unsigned category, unsigned& latency, unsigned& initiation_interval); void parse_config(); + void reg_options(option_parser_t opp); + char* get_traces_filename() { return g_traces_filename; } private: unsigned int_latency, fp_latency, dp_latency, sfu_latency, tensor_latency; unsigned int_init, fp_init, dp_init, sfu_init, tensor_init; - gpgpu_sim* m_gpgpu_sim; + + char* g_traces_filename; + char* trace_opcode_latency_initiation_int; + char* trace_opcode_latency_initiation_sp; + char* trace_opcode_latency_initiation_dp; + char* trace_opcode_latency_initiation_sfu; + char* trace_opcode_latency_initiation_tensor; }; class trace_parser { @@ -130,6 +140,30 @@ class trace_shd_warp_t : public shd_warp_t { unsigned trace_pc; }; +class trace_gpgpu_sim : public gpgpu_sim { + public: + trace_gpgpu_sim(const gpgpu_sim_config& config, gpgpu_context* ctx) + : gpgpu_sim(config, ctx) { + createSIMTCluster(); + } + + virtual void createSIMTCluster(); +}; + +class trace_simt_core_cluster : public simt_core_cluster { + public: + trace_simt_core_cluster(class gpgpu_sim* gpu, unsigned cluster_id, + const shader_core_config* config, + const memory_config* mem_config, + class shader_core_stats* stats, + class memory_stats_t* mstats) + : simt_core_cluster(gpu, cluster_id, config, mem_config, stats, mstats) { + create_shader_core_ctx(); + } + + virtual void create_shader_core_ctx(); +}; + class trace_shader_core_ctx : public shader_core_ctx { public: trace_shader_core_ctx(class gpgpu_sim* gpu, class simt_core_cluster* cluster, @@ -138,7 +172,12 @@ class trace_shader_core_ctx : public shader_core_ctx { const memory_config* mem_config, shader_core_stats* stats) : shader_core_ctx(gpu, cluster, shader_id, tpc_id, config, mem_config, - stats) {} + stats) { + create_front_pipeline(); + create_shd_warp(); + create_schedulers(); + create_exec_pipeline(); + } virtual void checkExecutionStatusAndUpdate(warp_inst_t& inst, unsigned t, unsigned tid); @@ -146,7 +185,19 @@ class trace_shader_core_ctx : public shader_core_ctx { unsigned end_thread, unsigned ctaid, int cta_size, kernel_info_t& kernel); virtual void func_exec_inst(warp_inst_t& inst); - friend class shader_core_ctx; + virtual unsigned sim_init_thread(kernel_info_t& kernel, + ptx_thread_info** thread_info, int sid, + unsigned tid, unsigned threads_left, + unsigned num_threads, core_t* core, + unsigned hw_cta_id, unsigned hw_warp_id, + gpgpu_t* gpu); + virtual void create_shd_warp(); + virtual const warp_inst_t* get_next_inst(unsigned warp_id, address_type pc); + virtual void updateSIMTStack(unsigned warpId, warp_inst_t* inst); + virtual void get_pdom_stack_top_info(unsigned warp_id, const warp_inst_t* pI, + unsigned* pc, unsigned* rpc); + virtual const active_mask_t& get_active_mask(unsigned warp_id, + const warp_inst_t* pI); private: void init_traces(unsigned start_warp, unsigned end_warp, -- cgit v1.3 From 3f051d4e5e24943575ac4c19c358e1a0e6de621c Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Sat, 30 May 2020 22:17:04 -0400 Subject: adding new specialization units --- configs/tested-cfgs/SM75_RTX2060/trace.config | 20 +++++ configs/tested-cfgs/SM7_QV100/trace.config | 13 +++ configs/tested-cfgs/SM7_TITANV/trace.config | 13 +++ src/abstract_hardware_model.h | 15 +++- src/gpgpu-sim/gpu-sim.cc | 11 +++ src/gpgpu-sim/shader.cc | 114 +++++++++++++++++++++++--- src/gpgpu-sim/shader.h | 79 ++++++++++++++++-- src/trace-driven/ISA_Def/turing_opcode.h | 113 +++++++++++++------------ src/trace-driven/ISA_Def/volta_opcode.h | 50 +++++------ src/trace-driven/trace_driven.cc | 15 ++++ src/trace-driven/trace_driven.h | 3 + 11 files changed, 347 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/configs/tested-cfgs/SM75_RTX2060/trace.config b/configs/tested-cfgs/SM75_RTX2060/trace.config index 41987cf..17b6cc7 100644 --- a/configs/tested-cfgs/SM75_RTX2060/trace.config +++ b/configs/tested-cfgs/SM75_RTX2060/trace.config @@ -3,3 +3,23 @@ -trace_opcode_latency_initiation_dp 8,4 -trace_opcode_latency_initiation_sfu 20,8 -trace_opcode_latency_initiation_tensor 8,4 + +#execute branch insts on spec unit 1 +#in Turing, there is a dedicated branch unit +#,,,,, +-specialized_unit_1 1,4,4,4,4,BRA +#, +-trace_opcode_latency_initiation_spec_op_1 4,4 + +#TEX unit, make fixed latency for all tex insts +-specialized_unit_2 1,1,200,4,4,TEX +-trace_opcode_latency_initiation_spec_op_2 200,4 + +#tensor unit +-specialized_unit_3 1,4,8,4,4,TENSOR +-trace_opcode_latency_initiation_spec_op_3 8,4 + +#UDP unit +#for more info about UDP, see https://www.hotchips.org/hc31/HC31_2.12_NVIDIA_final.pdf +-specialized_unit_4 1,4,4,4,4,UDP +-trace_opcode_latency_initiation_spec_op_4 4,2 diff --git a/configs/tested-cfgs/SM7_QV100/trace.config b/configs/tested-cfgs/SM7_QV100/trace.config index 04ac009..88f5706 100644 --- a/configs/tested-cfgs/SM7_QV100/trace.config +++ b/configs/tested-cfgs/SM7_QV100/trace.config @@ -4,3 +4,16 @@ -trace_opcode_latency_initiation_sfu 20,8 -trace_opcode_latency_initiation_tensor 8,4 +#execute branch insts on spec unit 1 +#in Volta, there is a dedicated branch unit +#,,,,, +-specialized_unit_1 1,4,4,4,4,BRA +-trace_opcode_latency_initiation_spec_op_1 4,4 + +#TEX unit, make fixed latency for all tex insts +-specialized_unit_2 1,4,200,4,4,TEX +-trace_opcode_latency_initiation_spec_op_2 200,4 + +#tensor unit +-specialized_unit_3 1,4,8,4,4,TENSOR +-trace_opcode_latency_initiation_spec_op_3 8,4 diff --git a/configs/tested-cfgs/SM7_TITANV/trace.config b/configs/tested-cfgs/SM7_TITANV/trace.config index 04ac009..88f5706 100644 --- a/configs/tested-cfgs/SM7_TITANV/trace.config +++ b/configs/tested-cfgs/SM7_TITANV/trace.config @@ -4,3 +4,16 @@ -trace_opcode_latency_initiation_sfu 20,8 -trace_opcode_latency_initiation_tensor 8,4 +#execute branch insts on spec unit 1 +#in Volta, there is a dedicated branch unit +#,,,,, +-specialized_unit_1 1,4,4,4,4,BRA +-trace_opcode_latency_initiation_spec_op_1 4,4 + +#TEX unit, make fixed latency for all tex insts +-specialized_unit_2 1,4,200,4,4,TEX +-trace_opcode_latency_initiation_spec_op_2 200,4 + +#tensor unit +-specialized_unit_3 1,4,8,4,4,TENSOR +-trace_opcode_latency_initiation_spec_op_3 8,4 diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index c58d39c..b22b5c4 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -79,6 +79,8 @@ typedef unsigned address_type; typedef unsigned addr_t; // the following are operations the timing model can see +#define SPECIALIZED_UNIT_NUM 8 +#define SPEC_UNIT_START_ID 100 enum uarch_op_t { NO_OP = -1, @@ -98,7 +100,15 @@ enum uarch_op_t { MEMORY_BARRIER_OP, CALL_OPS, RET_OPS, - EXIT_OPS + EXIT_OPS, + SPECIALIZED_UNIT_1_OP = SPEC_UNIT_START_ID, + SPECIALIZED_UNIT_2_OP, + SPECIALIZED_UNIT_3_OP, + SPECIALIZED_UNIT_4_OP, + SPECIALIZED_UNIT_5_OP, + SPECIALIZED_UNIT_6_OP, + SPECIALIZED_UNIT_7_OP, + SPECIALIZED_UNIT_8_OP }; typedef enum uarch_op_t op_type; @@ -135,7 +145,8 @@ enum operation_pipeline_t { INTP__OP, SFU__OP, TENSOR_CORE__OP, - MEM__OP + MEM__OP, + SPECIALIZED__OP, }; typedef enum operation_pipeline_t operation_pipeline; enum mem_operation_t { NOT_TEX, TEX }; diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index b62524e..03aebf3 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -529,6 +529,17 @@ void shader_core_config::reg_options(class OptionParser *opp) { option_parser_register(opp, "-gpgpu_reg_file_port_throughput", OPT_INT32, ®_file_port_throughput, "the number ports of the register file", "1"); + + for (unsigned j = 0; j < SPECIALIZED_UNIT_NUM; ++j) { + std::stringstream ss; + ss << "-specialized_unit_" << j + 1; + option_parser_register(opp, ss.str().c_str(), OPT_CSTR, + &specialized_unit_string[j], + "specialized unit config" + " {,::,:,}", + "0,4,4,4,4,BRA"); + } } void gpgpu_sim_config::reg_options(option_parser_t opp) { diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 8efb88b..8b226b6 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -82,11 +82,30 @@ void exec_shader_core_ctx::create_shd_warp() { } void shader_core_ctx::create_front_pipeline() { - m_pipeline_reg.reserve(N_PIPELINE_STAGES); + // pipeline_stages is the sum of normal pipeline stages and specialized_unit + // stages * 2 (for ID and EX) + unsigned total_pipeline_stages = + N_PIPELINE_STAGES + m_config->m_specialized_unit.size() * 2; + m_pipeline_reg.reserve(total_pipeline_stages); for (int j = 0; j < N_PIPELINE_STAGES; j++) { m_pipeline_reg.push_back( register_set(m_config->pipe_widths[j], pipeline_stage_name_decode[j])); } + for (int j = 0; j < m_config->m_specialized_unit.size(); j++) { + m_pipeline_reg.push_back( + register_set(m_config->m_specialized_unit[j].id_oc_spec_reg_width, + m_config->m_specialized_unit[j].name)); + m_config->m_specialized_unit[j].ID_OC_SPEC_ID = m_pipeline_reg.size() - 1; + m_specilized_dispatch_reg.push_back( + &m_pipeline_reg[m_pipeline_reg.size() - 1]); + } + for (int j = 0; j < m_config->m_specialized_unit.size(); j++) { + m_pipeline_reg.push_back( + register_set(m_config->m_specialized_unit[j].oc_ex_spec_reg_width, + m_config->m_specialized_unit[j].name)); + m_config->m_specialized_unit[j].OC_EX_SPEC_ID = m_pipeline_reg.size() - 1; + } + if (m_config->sub_core_model) { // in subcore model, each scheduler should has its own issue register, so // num scheduler = reg width @@ -168,37 +187,40 @@ void shader_core_ctx::create_schedulers() { m_stats, this, m_scoreboard, m_simt_stack, &m_warp, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_DP], &m_pipeline_reg[ID_OC_SFU], &m_pipeline_reg[ID_OC_INT], - &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i)); + &m_pipeline_reg[ID_OC_TENSOR_CORE], m_specilized_dispatch_reg, + &m_pipeline_reg[ID_OC_MEM], i)); break; case CONCRETE_SCHEDULER_TWO_LEVEL_ACTIVE: schedulers.push_back(new two_level_active_scheduler( m_stats, this, m_scoreboard, m_simt_stack, &m_warp, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_DP], &m_pipeline_reg[ID_OC_SFU], &m_pipeline_reg[ID_OC_INT], - &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i, - m_config->gpgpu_scheduler_string)); + &m_pipeline_reg[ID_OC_TENSOR_CORE], m_specilized_dispatch_reg, + &m_pipeline_reg[ID_OC_MEM], i, m_config->gpgpu_scheduler_string)); break; case CONCRETE_SCHEDULER_GTO: schedulers.push_back(new gto_scheduler( m_stats, this, m_scoreboard, m_simt_stack, &m_warp, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_DP], &m_pipeline_reg[ID_OC_SFU], &m_pipeline_reg[ID_OC_INT], - &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i)); + &m_pipeline_reg[ID_OC_TENSOR_CORE], m_specilized_dispatch_reg, + &m_pipeline_reg[ID_OC_MEM], i)); break; case CONCRETE_SCHEDULER_OLDEST_FIRST: schedulers.push_back(new oldest_scheduler( m_stats, this, m_scoreboard, m_simt_stack, &m_warp, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_DP], &m_pipeline_reg[ID_OC_SFU], &m_pipeline_reg[ID_OC_INT], - &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i)); + &m_pipeline_reg[ID_OC_TENSOR_CORE], m_specilized_dispatch_reg, + &m_pipeline_reg[ID_OC_MEM], i)); break; case CONCRETE_SCHEDULER_WARP_LIMITING: schedulers.push_back(new swl_scheduler( m_stats, this, m_scoreboard, m_simt_stack, &m_warp, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_DP], &m_pipeline_reg[ID_OC_SFU], &m_pipeline_reg[ID_OC_INT], - &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i, - m_config->gpgpu_scheduler_string)); + &m_pipeline_reg[ID_OC_TENSOR_CORE], m_specilized_dispatch_reg, + &m_pipeline_reg[ID_OC_MEM], i, m_config->gpgpu_scheduler_string)); break; default: abort(); @@ -248,6 +270,14 @@ void shader_core_ctx::create_exec_pipeline() { in_ports.push_back(&m_pipeline_reg[ID_OC_INT]); out_ports.push_back(&m_pipeline_reg[OC_EX_INT]); } + if (m_config->m_specialized_unit.size() > 0) { + for (unsigned j = 0; j < m_config->m_specialized_unit.size(); ++j) { + in_ports.push_back( + &m_pipeline_reg[m_config->m_specialized_unit[j].ID_OC_SPEC_ID]); + out_ports.push_back( + &m_pipeline_reg[m_config->m_specialized_unit[j].OC_EX_SPEC_ID]); + } + } cu_sets.push_back((unsigned)GEN_CUS); m_operand_collector.add_port(in_ports, out_ports, cu_sets); in_ports.clear(), out_ports.clear(), cu_sets.clear(); @@ -340,7 +370,7 @@ void shader_core_ctx::create_exec_pipeline() { m_num_function_units = m_config->gpgpu_num_sp_units + m_config->gpgpu_num_dp_units + m_config->gpgpu_num_sfu_units + m_config->gpgpu_num_tensor_core_units + - m_config->gpgpu_num_int_units + + m_config->gpgpu_num_int_units + m_config->m_specialized_unit_num + 1; // sp_unit, sfu, dp, tensor, int, ldst_unit // m_dispatch_port = new enum pipeline_stage_name_t[ m_num_function_units ]; // m_issue_port = new enum pipeline_stage_name_t[ m_num_function_units ]; @@ -376,6 +406,17 @@ void shader_core_ctx::create_exec_pipeline() { m_issue_port.push_back(OC_EX_TENSOR_CORE); } + for (int j = 0; j < m_config->m_specialized_unit.size(); j++) { + for (unsigned k = 0; k < m_config->m_specialized_unit[j].num_units; k++) { + m_fu.push_back(new specialized_unit( + &m_pipeline_reg[EX_WB], m_config, this, SPEC_UNIT_START_ID + j, + m_config->m_specialized_unit[j].name, + m_config->m_specialized_unit[j].latency)); + m_dispatch_port.push_back(m_config->m_specialized_unit[j].ID_OC_SPEC_ID); + m_issue_port.push_back(m_config->m_specialized_unit[j].OC_EX_SPEC_ID); + } + } + m_ldst_unit = new ldst_unit(m_icnt, m_mem_fetch_allocator, this, &m_operand_collector, m_scoreboard, m_config, m_memory_config, m_stats, m_sid, m_tpc); @@ -1204,7 +1245,7 @@ void scheduler_unit::cycle() { // This code need to be refactored if (pI->op != TENSOR_CORE_OP && pI->op != SFU_OP && - pI->op != DP_OP) { + pI->op != DP_OP && !(pI->op >= SPEC_UNIT_START_ID)) { bool execute_on_SP = false; bool execute_on_INT = false; @@ -1302,7 +1343,30 @@ void scheduler_unit::cycle() { warp_inst_issued = true; previous_issued_inst_exec_type = exec_unit_type_t::TENSOR; } + } else if ((pI->op >= SPEC_UNIT_START_ID) && + !(diff_exec_units && + previous_issued_inst_exec_type == + exec_unit_type_t::SPECIALIZED)) { + unsigned spec_id = pI->op - SPEC_UNIT_START_ID; + assert(spec_id < m_shader->m_config->m_specialized_unit.size()); + register_set *spec_reg_set = m_spec_cores_out[spec_id]; + bool spec_pipe_avail = + (m_shader->m_config->m_specialized_unit[spec_id].num_units > + 0) && + spec_reg_set->has_free(m_shader->m_config->sub_core_model, + m_id); + + if (spec_pipe_avail) { + m_shader->issue_warp(*spec_reg_set, pI, active_mask, warp_id, + m_id); + issued++; + issued_inst = true; + warp_inst_issued = true; + previous_issued_inst_exec_type = + exec_unit_type_t::SPECIALIZED; + } } + } // end of else } else { SCHED_DPRINTF( @@ -1475,9 +1539,11 @@ swl_scheduler::swl_scheduler(shader_core_stats *stats, shader_core_ctx *shader, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, + std::vector &spec_cores_out, register_set *mem_out, int id, char *config_string) : scheduler_unit(stats, shader, scoreboard, simt, warp, sp_out, dp_out, - sfu_out, int_out, tensor_core_out, mem_out, id) { + sfu_out, int_out, tensor_core_out, spec_cores_out, mem_out, + id) { unsigned m_prioritization_readin; int ret = sscanf(config_string, "warp_limiting:%d:%d", &m_prioritization_readin, &m_num_warps_to_limit); @@ -1599,7 +1665,7 @@ void shader_core_ctx::execute() { unsigned multiplier = m_fu[n]->clock_multiplier(); for (unsigned c = 0; c < multiplier; c++) m_fu[n]->cycle(); m_fu[n]->active_lanes_in_pipeline(); - enum pipeline_stage_name_t issue_port = m_issue_port[n]; + unsigned issue_port = m_issue_port[n]; register_set &issue_inst = m_pipeline_reg[issue_port]; warp_inst_t **ready_reg = issue_inst.get_ready(); if (issue_inst.has_ready() && m_fu[n]->can_issue(**ready_reg)) { @@ -2108,6 +2174,13 @@ void dp_unit::active_lanes_in_pipeline() { m_core->incfuactivelanes_stat(active_count); m_core->incfumemactivelanes_stat(active_count); } +void specialized_unit::active_lanes_in_pipeline() { + unsigned active_count = pipelined_simd_unit::get_active_lanes_in_pipeline(); + assert(active_count <= m_core->get_config()->warp_size); + m_core->incspactivelanes_stat(active_count); + m_core->incfuactivelanes_stat(active_count); + m_core->incfumemactivelanes_stat(active_count); +} void int_unit::active_lanes_in_pipeline() { unsigned active_count = pipelined_simd_unit::get_active_lanes_in_pipeline(); @@ -2138,6 +2211,15 @@ sp_unit::sp_unit(register_set *result_port, const shader_core_config *config, m_name = "SP "; } +specialized_unit::specialized_unit(register_set *result_port, + const shader_core_config *config, + shader_core_ctx *core, unsigned supported_op, + char *unit_name, unsigned latency) + : pipelined_simd_unit(result_port, config, latency, core) { + m_name = unit_name; + m_supported_op = supported_op; +} + dp_unit::dp_unit(register_set *result_port, const shader_core_config *config, shader_core_ctx *core) : pipelined_simd_unit(result_port, config, config->max_dp_latency, core) { @@ -2166,6 +2248,14 @@ void dp_unit ::issue(register_set &source_reg) { pipelined_simd_unit::issue(source_reg); } +void specialized_unit ::issue(register_set &source_reg) { + warp_inst_t **ready_reg = source_reg.get_ready(); + // m_core->incexecstat((*ready_reg)); + (*ready_reg)->op_pipe = SPECIALIZED__OP; + m_core->incsp_stat(m_core->get_config()->warp_size, (*ready_reg)->latency); + pipelined_simd_unit::issue(source_reg); +} + void int_unit ::issue(register_set &source_reg) { warp_inst_t **ready_reg = source_reg.get_ready(); // m_core->incexecstat((*ready_reg)); diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index d77207d..65c8937 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -79,7 +79,8 @@ enum exec_unit_type_t { MEM = 3, DP = 4, INT = 5, - TENSOR = 6 + TENSOR = 6, + SPECIALIZED = 7 }; class thread_ctx_t { @@ -329,6 +330,7 @@ class scheduler_unit { // this can be copied freely, so can be used in std std::vector *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, + std::vector &spec_cores_out, register_set *mem_out, int id) : m_supervised_warps(), m_stats(stats), @@ -341,6 +343,7 @@ class scheduler_unit { // this can be copied freely, so can be used in std m_sfu_out(sfu_out), m_int_out(int_out), m_tensor_core_out(tensor_core_out), + m_spec_cores_out(spec_cores_out), m_mem_out(mem_out), m_id(id) {} virtual ~scheduler_unit() {} @@ -422,6 +425,7 @@ class scheduler_unit { // this can be copied freely, so can be used in std register_set *m_int_out; register_set *m_tensor_core_out; register_set *m_mem_out; + std::vector &m_spec_cores_out; int m_id; }; @@ -433,9 +437,11 @@ class lrr_scheduler : public scheduler_unit { std::vector *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, + std::vector &spec_cores_out, register_set *mem_out, int id) : scheduler_unit(stats, shader, scoreboard, simt, warp, sp_out, dp_out, - sfu_out, int_out, tensor_core_out, mem_out, id) {} + sfu_out, int_out, tensor_core_out, spec_cores_out, + mem_out, id) {} virtual ~lrr_scheduler() {} virtual void order_warps(); virtual void done_adding_supervised_warps() { @@ -450,9 +456,11 @@ class gto_scheduler : public scheduler_unit { std::vector *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, + std::vector &spec_cores_out, register_set *mem_out, int id) : scheduler_unit(stats, shader, scoreboard, simt, warp, sp_out, dp_out, - sfu_out, int_out, tensor_core_out, mem_out, id) {} + sfu_out, int_out, tensor_core_out, spec_cores_out, + mem_out, id) {} virtual ~gto_scheduler() {} virtual void order_warps(); virtual void done_adding_supervised_warps() { @@ -467,9 +475,11 @@ class oldest_scheduler : public scheduler_unit { std::vector *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, + std::vector &spec_cores_out, register_set *mem_out, int id) : scheduler_unit(stats, shader, scoreboard, simt, warp, sp_out, dp_out, - sfu_out, int_out, tensor_core_out, mem_out, id) {} + sfu_out, int_out, tensor_core_out, spec_cores_out, + mem_out, id) {} virtual ~oldest_scheduler() {} virtual void order_warps(); virtual void done_adding_supervised_warps() { @@ -485,9 +495,11 @@ class two_level_active_scheduler : public scheduler_unit { register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, + std::vector &spec_cores_out, register_set *mem_out, int id, char *config_str) : scheduler_unit(stats, shader, scoreboard, simt, warp, sp_out, dp_out, - sfu_out, int_out, tensor_core_out, mem_out, id), + sfu_out, int_out, tensor_core_out, spec_cores_out, + mem_out, id), m_pending_warps() { unsigned inner_level_readin; unsigned outer_level_readin; @@ -533,6 +545,7 @@ class swl_scheduler : public scheduler_unit { std::vector *warp, register_set *sp_out, register_set *dp_out, register_set *sfu_out, register_set *int_out, register_set *tensor_core_out, + std::vector &spec_cores_out, register_set *mem_out, int id, char *config_string); virtual ~swl_scheduler() {} virtual void order_warps(); @@ -1211,6 +1224,24 @@ class sp_unit : public pipelined_simd_unit { virtual void issue(register_set &source_reg); }; +class specialized_unit : public pipelined_simd_unit { + public: + specialized_unit(register_set *result_port, const shader_core_config *config, + shader_core_ctx *core, unsigned supported_op, + char *unit_name, unsigned latency); + virtual bool can_issue(const warp_inst_t &inst) const { + if (inst.op != m_supported_op) { + return false; + } + return pipelined_simd_unit::can_issue(inst); + } + virtual void active_lanes_in_pipeline(); + virtual void issue(register_set &source_reg); + + private: + unsigned m_supported_op; +}; + class simt_core_cluster; class shader_memory_interface; class shader_core_mem_fetch_allocator; @@ -1361,6 +1392,16 @@ const char *const pipeline_stage_name_decode[] = { "OC_EX_SFU", "OC_EX_MEM", "EX_WB", "ID_OC_TENSOR_CORE", "OC_EX_TENSOR_CORE", "N_PIPELINE_STAGES"}; +struct specialized_unit_params { + unsigned latency; + unsigned num_units; + unsigned id_oc_spec_reg_width; + unsigned oc_ex_spec_reg_width; + char name[20]; + unsigned ID_OC_SPEC_ID; + unsigned OC_EX_SPEC_ID; +}; + class shader_core_config : public core_config { public: shader_core_config(gpgpu_context *ctx) : core_config(ctx) { @@ -1419,6 +1460,24 @@ class shader_core_config : public core_config { gpgpu_cache_texl1_linesize = m_L1T_config.get_line_sz(); gpgpu_cache_constl1_linesize = m_L1C_config.get_line_sz(); m_valid = true; + + m_specialized_unit_num = 0; + // parse the specialized units + for (unsigned i = 0; i < SPECIALIZED_UNIT_NUM; ++i) { + unsigned enabled; + specialized_unit_params sparam; + sscanf(specialized_unit_string[i], "%u,%u,%u,%u,%u,%s", &enabled, + &sparam.num_units, &sparam.latency, &sparam.id_oc_spec_reg_width, + &sparam.oc_ex_spec_reg_width, &sparam.name); + + if (enabled) { + m_specialized_unit.push_back(sparam); + strncpy(m_specialized_unit.back().name, sparam.name, + sizeof(m_specialized_unit.back().name)); + m_specialized_unit_num += sparam.num_units; + } else + break; // we only accept continuous specialized_units, i.e., 1,2,3,4 + } } void reg_options(class OptionParser *opp); unsigned max_cta(const kernel_info_t &k) const; @@ -1534,6 +1593,11 @@ class shader_core_config : public core_config { bool perfect_inst_const_cache; unsigned inst_fetch_throughput; unsigned reg_file_port_throughput; + + // specialized unit config strings + char *specialized_unit_string[SPECIALIZED_UNIT_NUM]; + mutable std::vector m_specialized_unit; + unsigned m_specialized_unit_num; }; struct shader_core_stats_pod { @@ -2154,6 +2218,7 @@ class shader_core_ctx : public core_t { Scoreboard *m_scoreboard; opndcoll_rfu_t m_operand_collector; int m_active_warps; + std::vector m_specilized_dispatch_reg; // schedule std::vector schedulers; @@ -2163,8 +2228,8 @@ class shader_core_ctx : public core_t { // execute unsigned m_num_function_units; - std::vector m_dispatch_port; - std::vector m_issue_port; + std::vector m_dispatch_port; + std::vector m_issue_port; std::vector m_fu; // stallable pipelines should be last in this array ldst_unit *m_ldst_unit; diff --git a/src/trace-driven/ISA_Def/turing_opcode.h b/src/trace-driven/ISA_Def/turing_opcode.h index 0374bdd..12bbe76 100644 --- a/src/trace-driven/ISA_Def/turing_opcode.h +++ b/src/trace-driven/ISA_Def/turing_opcode.h @@ -43,7 +43,8 @@ static const std::unordered_map Turing_OpcodeMap = { {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, // Tensor Core Instructions - {"HMMA", OpcodeChar(OP_HMMA, TENSOR_CORE_OP)}, + // Execute Tensor Core Instructions on SPECIALIZED_UNIT_3 + {"HMMA", OpcodeChar(OP_HMMA, SPECIALIZED_UNIT_3_OP)}, // Double Point Instructions {"DADD", OpcodeChar(OP_DADD, DP_OP)}, @@ -128,43 +129,46 @@ static const std::unordered_map Turing_OpcodeMap = { {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, - // Uniform Datapath Instruction // - {"R2UR", OpcodeChar(OP_R2UR, ALU_OP)}, - {"S2UR", OpcodeChar(OP_S2UR, ALU_OP)}, - {"UBMSK", OpcodeChar(OP_UBMSK, ALU_OP)}, - {"UBREV", OpcodeChar(OP_UBREV, ALU_OP)}, - {"UCLEA", OpcodeChar(OP_UCLEA, ALU_OP)}, - {"UFLO", OpcodeChar(OP_UFLO, ALU_OP)}, - {"UIADD3", OpcodeChar(OP_UIADD3, ALU_OP)}, - {"UIMAD", OpcodeChar(OP_UIMAD, ALU_OP)}, - {"UISETP", OpcodeChar(OP_UISETP, ALU_OP)}, - {"ULDC", OpcodeChar(OP_ULDC, ALU_OP)}, - {"ULEA", OpcodeChar(OP_ULEA, ALU_OP)}, - {"ULOP", OpcodeChar(OP_ULOP, ALU_OP)}, - {"ULOP3", OpcodeChar(OP_ULOP3, ALU_OP)}, - {"ULOP32I", OpcodeChar(OP_ULOP32I, ALU_OP)}, - {"UMOV", OpcodeChar(OP_UMOV, ALU_OP)}, - {"UP2UR", OpcodeChar(OP_UP2UR, ALU_OP)}, - {"UPLOP3", OpcodeChar(OP_UPLOP3, ALU_OP)}, - {"UPOPC", OpcodeChar(OP_UPOPC, ALU_OP)}, - {"UPRMT", OpcodeChar(OP_UPRMT, ALU_OP)}, - {"UPSETP", OpcodeChar(OP_UPSETP, ALU_OP)}, - {"UR2UP", OpcodeChar(OP_UR2UP, ALU_OP)}, - {"USEL", OpcodeChar(OP_USEL, ALU_OP)}, - {"USGXT", OpcodeChar(OP_USGXT, ALU_OP)}, - {"USHF", OpcodeChar(OP_USHF, ALU_OP)}, - {"USHL", OpcodeChar(OP_USHL, ALU_OP)}, - {"USHR", OpcodeChar(OP_USHR, ALU_OP)}, - {"VOTEU", OpcodeChar(OP_VOTEU, ALU_OP)}, + // Uniform Datapath Instruction + // UDP unit + // for more info about UDP, see + // https://www.hotchips.org/hc31/HC31_2.12_NVIDIA_final.pdf + {"R2UR", OpcodeChar(OP_R2UR, SPECIALIZED_UNIT_4_OP)}, + {"S2UR", OpcodeChar(OP_S2UR, SPECIALIZED_UNIT_4_OP)}, + {"UBMSK", OpcodeChar(OP_UBMSK, SPECIALIZED_UNIT_4_OP)}, + {"UBREV", OpcodeChar(OP_UBREV, SPECIALIZED_UNIT_4_OP)}, + {"UCLEA", OpcodeChar(OP_UCLEA, SPECIALIZED_UNIT_4_OP)}, + {"UFLO", OpcodeChar(OP_UFLO, SPECIALIZED_UNIT_4_OP)}, + {"UIADD3", OpcodeChar(OP_UIADD3, SPECIALIZED_UNIT_4_OP)}, + {"UIMAD", OpcodeChar(OP_UIMAD, SPECIALIZED_UNIT_4_OP)}, + {"UISETP", OpcodeChar(OP_UISETP, SPECIALIZED_UNIT_4_OP)}, + {"ULDC", OpcodeChar(OP_ULDC, SPECIALIZED_UNIT_4_OP)}, + {"ULEA", OpcodeChar(OP_ULEA, SPECIALIZED_UNIT_4_OP)}, + {"ULOP", OpcodeChar(OP_ULOP, SPECIALIZED_UNIT_4_OP)}, + {"ULOP3", OpcodeChar(OP_ULOP3, SPECIALIZED_UNIT_4_OP)}, + {"ULOP32I", OpcodeChar(OP_ULOP32I, SPECIALIZED_UNIT_4_OP)}, + {"UMOV", OpcodeChar(OP_UMOV, SPECIALIZED_UNIT_4_OP)}, + {"UP2UR", OpcodeChar(OP_UP2UR, SPECIALIZED_UNIT_4_OP)}, + {"UPLOP3", OpcodeChar(OP_UPLOP3, SPECIALIZED_UNIT_4_OP)}, + {"UPOPC", OpcodeChar(OP_UPOPC, SPECIALIZED_UNIT_4_OP)}, + {"UPRMT", OpcodeChar(OP_UPRMT, SPECIALIZED_UNIT_4_OP)}, + {"UPSETP", OpcodeChar(OP_UPSETP, SPECIALIZED_UNIT_4_OP)}, + {"UR2UP", OpcodeChar(OP_UR2UP, SPECIALIZED_UNIT_4_OP)}, + {"USEL", OpcodeChar(OP_USEL, SPECIALIZED_UNIT_4_OP)}, + {"USGXT", OpcodeChar(OP_USGXT, SPECIALIZED_UNIT_4_OP)}, + {"USHF", OpcodeChar(OP_USHF, SPECIALIZED_UNIT_4_OP)}, + {"USHL", OpcodeChar(OP_USHL, SPECIALIZED_UNIT_4_OP)}, + {"USHR", OpcodeChar(OP_USHR, SPECIALIZED_UNIT_4_OP)}, + {"VOTEU", OpcodeChar(OP_VOTEU, SPECIALIZED_UNIT_4_OP)}, // Texture Instructions // For now, we ignore texture loads, consider it as ALU_OP - {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, - {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, - {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, - {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, - {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, - {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, + {"TEX", OpcodeChar(OP_TEX, SPECIALIZED_UNIT_2_OP)}, + {"TLD", OpcodeChar(OP_TLD, SPECIALIZED_UNIT_2_OP)}, + {"TLD4", OpcodeChar(OP_TLD4, SPECIALIZED_UNIT_2_OP)}, + {"TMML", OpcodeChar(OP_TMML, SPECIALIZED_UNIT_2_OP)}, + {"TXD", OpcodeChar(OP_TXD, SPECIALIZED_UNIT_2_OP)}, + {"TXQ", OpcodeChar(OP_TXQ, SPECIALIZED_UNIT_2_OP)}, // Surface Instructions // {"SUATOM", OpcodeChar(OP_SUATOM, ALU_OP)}, @@ -173,26 +177,27 @@ static const std::unordered_map Turing_OpcodeMap = { {"SUST", OpcodeChar(OP_SUST, ALU_OP)}, // Control Instructions - {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, - {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, - {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, - {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, - {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, - {"BRXU", OpcodeChar(OP_BRXU, BRANCH_OP)}, // - {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, - {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, - {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, + // execute branch insts on a dedicated branch unit (SPECIALIZED_UNIT_1) + {"BMOV", OpcodeChar(OP_BMOV, SPECIALIZED_UNIT_1_OP)}, + {"BPT", OpcodeChar(OP_BPT, SPECIALIZED_UNIT_1_OP)}, + {"BRA", OpcodeChar(OP_BRA, SPECIALIZED_UNIT_1_OP)}, + {"BREAK", OpcodeChar(OP_BREAK, SPECIALIZED_UNIT_1_OP)}, + {"BRX", OpcodeChar(OP_BRX, SPECIALIZED_UNIT_1_OP)}, + {"BRXU", OpcodeChar(OP_BRXU, SPECIALIZED_UNIT_1_OP)}, // + {"BSSY", OpcodeChar(OP_BSSY, SPECIALIZED_UNIT_1_OP)}, + {"BSYNC", OpcodeChar(OP_BSYNC, SPECIALIZED_UNIT_1_OP)}, + {"CALL", OpcodeChar(OP_CALL, SPECIALIZED_UNIT_1_OP)}, {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, - {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, - {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, - {"JMXU", OpcodeChar(OP_JMXU, BRANCH_OP)}, /// - {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, - {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, - {"RET", OpcodeChar(OP_RET, RET_OPS)}, - {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, - {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, - {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, - {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, + {"JMP", OpcodeChar(OP_JMP, SPECIALIZED_UNIT_1_OP)}, + {"JMX", OpcodeChar(OP_JMX, SPECIALIZED_UNIT_1_OP)}, + {"JMXU", OpcodeChar(OP_JMXU, SPECIALIZED_UNIT_1_OP)}, /// + {"KILL", OpcodeChar(OP_KILL, SPECIALIZED_UNIT_3_OP)}, + {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, SPECIALIZED_UNIT_1_OP)}, + {"RET", OpcodeChar(OP_RET, SPECIALIZED_UNIT_1_OP)}, + {"RPCMOV", OpcodeChar(OP_RPCMOV, SPECIALIZED_UNIT_1_OP)}, + {"RTT", OpcodeChar(OP_RTT, SPECIALIZED_UNIT_1_OP)}, + {"WARPSYNC", OpcodeChar(OP_WARPSYNC, SPECIALIZED_UNIT_1_OP)}, + {"YIELD", OpcodeChar(OP_YIELD, SPECIALIZED_UNIT_1_OP)}, // Miscellaneous Instructions {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, diff --git a/src/trace-driven/ISA_Def/volta_opcode.h b/src/trace-driven/ISA_Def/volta_opcode.h index 7bd6904..3358211 100644 --- a/src/trace-driven/ISA_Def/volta_opcode.h +++ b/src/trace-driven/ISA_Def/volta_opcode.h @@ -43,7 +43,8 @@ static const std::unordered_map Volta_OpcodeMap = { {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, // Tensor Core Instructions - {"HMMA", OpcodeChar(OP_HMMA, TENSOR_CORE_OP)}, + // Execute Tensor Core Instructions on SPECIALIZED_UNIT_3 + {"HMMA", OpcodeChar(OP_HMMA, SPECIALIZED_UNIT_3_OP)}, // Double Point Instructions {"DADD", OpcodeChar(OP_DADD, DP_OP)}, @@ -126,32 +127,33 @@ static const std::unordered_map Volta_OpcodeMap = { // Texture Instructions // For now, we ignore texture loads, consider it as ALU_OP - {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, - {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, - {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, - {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, - {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, - {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, + {"TEX", OpcodeChar(OP_TEX, SPECIALIZED_UNIT_2_OP)}, + {"TLD", OpcodeChar(OP_TLD, SPECIALIZED_UNIT_2_OP)}, + {"TLD4", OpcodeChar(OP_TLD4, SPECIALIZED_UNIT_2_OP)}, + {"TMML", OpcodeChar(OP_TMML, SPECIALIZED_UNIT_2_OP)}, + {"TXD", OpcodeChar(OP_TXD, SPECIALIZED_UNIT_2_OP)}, + {"TXQ", OpcodeChar(OP_TXQ, SPECIALIZED_UNIT_2_OP)}, // Control Instructions - {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, - {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, - {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, - {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, - {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, - {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, - {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, - {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, + // execute branch insts on a dedicated branch unit (SPECIALIZED_UNIT_1) + {"BMOV", OpcodeChar(OP_BMOV, SPECIALIZED_UNIT_1_OP)}, + {"BPT", OpcodeChar(OP_BPT, SPECIALIZED_UNIT_1_OP)}, + {"BRA", OpcodeChar(OP_BRA, SPECIALIZED_UNIT_1_OP)}, + {"BREAK", OpcodeChar(OP_BREAK, SPECIALIZED_UNIT_1_OP)}, + {"BRX", OpcodeChar(OP_BRX, SPECIALIZED_UNIT_1_OP)}, + {"BSSY", OpcodeChar(OP_BSSY, SPECIALIZED_UNIT_1_OP)}, + {"BSYNC", OpcodeChar(OP_BSYNC, SPECIALIZED_UNIT_1_OP)}, + {"CALL", OpcodeChar(OP_CALL, SPECIALIZED_UNIT_1_OP)}, {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, - {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, - {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, - {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, - {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, - {"RET", OpcodeChar(OP_RET, RET_OPS)}, - {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, - {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, - {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, - {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, + {"JMP", OpcodeChar(OP_JMP, SPECIALIZED_UNIT_1_OP)}, + {"JMX", OpcodeChar(OP_JMX, SPECIALIZED_UNIT_1_OP)}, + {"KILL", OpcodeChar(OP_KILL, SPECIALIZED_UNIT_1_OP)}, + {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, SPECIALIZED_UNIT_1_OP)}, + {"RET", OpcodeChar(OP_RET, SPECIALIZED_UNIT_1_OP)}, + {"RPCMOV", OpcodeChar(OP_RPCMOV, SPECIALIZED_UNIT_1_OP)}, + {"RTT", OpcodeChar(OP_RTT, SPECIALIZED_UNIT_1_OP)}, + {"WARPSYNC", OpcodeChar(OP_WARPSYNC, SPECIALIZED_UNIT_1_OP)}, + {"YIELD", OpcodeChar(OP_YIELD, SPECIALIZED_UNIT_1_OP)}, // Miscellaneous Instructions {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index d42ee65..0b1e24b 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -608,6 +608,16 @@ void trace_config::reg_options(option_parser_t opp) { "Opcode latencies and initiation for tensor in trace " "driven mode ", "4,1"); + + for (unsigned j = 0; j < SPECIALIZED_UNIT_NUM; ++j) { + std::stringstream ss; + ss << "-trace_opcode_latency_initiation_spec_op_" << j + 1; + option_parser_register(opp, ss.str().c_str(), OPT_CSTR, + &trace_opcode_latency_initiation_specialized_op[j], + "specialized unit config" + " ", + "4,4"); + } } void trace_config::parse_config() { @@ -617,6 +627,11 @@ void trace_config::parse_config() { sscanf(trace_opcode_latency_initiation_sfu, "%u,%u", &sfu_latency, &sfu_init); sscanf(trace_opcode_latency_initiation_tensor, "%u,%u", &tensor_latency, &tensor_init); + + for (unsigned j = 0; j < SPECIALIZED_UNIT_NUM; ++j) { + sscanf(trace_opcode_latency_initiation_specialized_op[j], "%u,%u", + &specialized_unit_latency[j], &specialized_unit_initiation[j]); + } } void trace_config::set_latency(unsigned category, unsigned& latency, unsigned& initiation_interval) { diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h index ea315a1..3af99c3 100644 --- a/src/trace-driven/trace_driven.h +++ b/src/trace-driven/trace_driven.h @@ -93,6 +93,8 @@ class trace_config { private: unsigned int_latency, fp_latency, dp_latency, sfu_latency, tensor_latency; unsigned int_init, fp_init, dp_init, sfu_init, tensor_init; + unsigned specialized_unit_latency[SPECIALIZED_UNIT_NUM]; + unsigned specialized_unit_initiation[SPECIALIZED_UNIT_NUM]; char* g_traces_filename; char* trace_opcode_latency_initiation_int; @@ -100,6 +102,7 @@ class trace_config { char* trace_opcode_latency_initiation_dp; char* trace_opcode_latency_initiation_sfu; char* trace_opcode_latency_initiation_tensor; + char* trace_opcode_latency_initiation_specialized_op[SPECIALIZED_UNIT_NUM]; }; class trace_parser { -- cgit v1.3 From 283c71e69a85e56285c078bea7c439f72a18bde0 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Sun, 31 May 2020 09:22:03 -0400 Subject: add spec unit params set --- src/trace-driven/trace_driven.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src') diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc index 0b1e24b..83b134e 100644 --- a/src/trace-driven/trace_driven.cc +++ b/src/trace-driven/trace_driven.cc @@ -665,6 +665,13 @@ void trace_config::set_latency(unsigned category, unsigned& latency, default: break; } + // for specialized units + if (category >= SPEC_UNIT_START_ID) { + unsigned spec_id = category - SPEC_UNIT_START_ID; + assert(spec_id >= 0 && spec_id < SPECIALIZED_UNIT_NUM); + latency = specialized_unit_latency[spec_id]; + initiation_interval = specialized_unit_initiation[spec_id]; + } } void trace_gpgpu_sim::createSIMTCluster() { -- cgit v1.3 From fec6ce76ca145fa493f902f491a968305fb1c254 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Sun, 31 May 2020 15:15:01 -0400 Subject: fixing TEX error maapping by removing virtual member form gpgpu-sim class --- src/gpgpu-sim/gpu-sim.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index e083d33..f9b3a0d 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -637,9 +637,6 @@ class gpgpu_sim : public gpgpu_t { void clear_executed_kernel_info(); //< clear the kernel information after // stat printout - virtual void createSIMTCluster() = 0; - void callCreateSIMTCluster(); - public: unsigned long long gpu_sim_insn; unsigned long long gpu_tot_sim_insn; -- cgit v1.3 From b53dcfc7b079a06f26b25cedcc09c4843ef1a6b9 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Sun, 31 May 2020 22:42:30 -0400 Subject: adding the virtual method back to gpgpu-sim class --- src/abstract_hardware_model.h | 2 ++ src/gpgpu-sim/gpu-sim.h | 1 + 2 files changed, 3 insertions(+) (limited to 'src') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index b22b5c4..45e7843 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -633,6 +633,8 @@ class gpgpu_t { return m_NameToTextureInfo; } + virtual ~gpgpu_t() {} + protected: const gpgpu_functional_sim_config &m_function_model_config; FILE *ptx_inst_debug_file; diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index f9b3a0d..2e6820d 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -636,6 +636,7 @@ class gpgpu_sim : public gpgpu_t { // into a string for stat printout void clear_executed_kernel_info(); //< clear the kernel information after // stat printout + virtual void createSIMTCluster() = 0; public: unsigned long long gpu_sim_insn; -- cgit v1.3 From 3e580ee62a9cc8010930f692d8a6201a31ed77e0 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 1 Jun 2020 14:56:30 -0400 Subject: moving all ipoly equstions to one file --- .../tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config | 2 +- configs/tested-cfgs/SM6_TITANX/gpgpusim.config | 2 +- configs/tested-cfgs/SM75_RTX2060/gpgpusim.config | 4 +- configs/tested-cfgs/SM7_QV100/gpgpusim.config | 2 +- configs/tested-cfgs/SM7_TITANV/gpgpusim.config | 2 +- src/gpgpu-sim/addrdec.cc | 149 ++++++--------------- src/gpgpu-sim/addrdec.h | 2 + src/gpgpu-sim/dram.cc | 24 +--- src/gpgpu-sim/gpu-cache.cc | 97 ++++++-------- src/gpgpu-sim/gpu-cache.h | 26 ++-- src/gpgpu-sim/gpu-sim.cc | 6 + 11 files changed, 116 insertions(+), 200 deletions(-) (limited to 'src') diff --git a/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config b/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config index b173dd0..c83159f 100644 --- a/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config +++ b/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config @@ -120,7 +120,7 @@ -gpgpu_flush_l1_cache 1 # 32 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives 1.5MB L2 cache --gpgpu_cache:dl2 S:32:128:16,L:B:m:L:L,A:256:64,16:0,32 +-gpgpu_cache:dl2 S:32:128:16,L:B:m:L:P,A:256:64,16:0,32 -gpgpu_cache:dl2_texture_only 0 -gpgpu_dram_partition_queues 32:32:32:32 -gpgpu_perf_sim_memcpy 1 diff --git a/configs/tested-cfgs/SM6_TITANX/gpgpusim.config b/configs/tested-cfgs/SM6_TITANX/gpgpusim.config index ce6f745..5b243a5 100644 --- a/configs/tested-cfgs/SM6_TITANX/gpgpusim.config +++ b/configs/tested-cfgs/SM6_TITANX/gpgpusim.config @@ -115,7 +115,7 @@ -gpgpu_flush_l1_cache 1 # 64 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives 3MB L2 cache --gpgpu_cache:dl2 S:1:128:1024,L:B:m:L:L,A:256:64,16:0,32 +-gpgpu_cache:dl2 S:64:128:16,L:B:m:L:P,A:256:64,16:0,32 -gpgpu_cache:dl2_texture_only 0 -gpgpu_dram_partition_queues 32:32:32:32 -gpgpu_perf_sim_memcpy 1 diff --git a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config index 8a4be23..6fe04ee 100644 --- a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config +++ b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config @@ -111,8 +111,8 @@ -gpgpu_smem_latency 20 -gpgpu_flush_l1_cache 1 -# 32 sets, each 128 bytes 32-way for each memory sub partition (96 KB per memory sub partition). This gives us 6MB L2 cache --gpgpu_cache:dl2 S:32:128:32,L:B:m:L:L,A:192:4,32:0,32 +# 64 sets, each 128 bytes 16-way for each memory sub partition (128 KB per memory sub partition). This gives us 3MB L2 cache +-gpgpu_cache:dl2 S:64:128:16,L:B:m:L:P,A:192:4,32:0,32 -gpgpu_cache:dl2_texture_only 0 -gpgpu_dram_partition_queues 64:64:64:64 -gpgpu_perf_sim_memcpy 1 diff --git a/configs/tested-cfgs/SM7_QV100/gpgpusim.config b/configs/tested-cfgs/SM7_QV100/gpgpusim.config index c31c060..c4818d1 100644 --- a/configs/tested-cfgs/SM7_QV100/gpgpusim.config +++ b/configs/tested-cfgs/SM7_QV100/gpgpusim.config @@ -126,7 +126,7 @@ -gpgpu_flush_l1_cache 1 # 32 sets, each 128 bytes 24-way for each memory sub partition (96 KB per memory sub partition). This gives us 6MB L2 cache --gpgpu_cache:dl2 S:32:128:24,L:B:m:L:L,A:192:4,32:0,32 +-gpgpu_cache:dl2 S:32:128:24,L:B:m:L:P,A:192:4,32:0,32 -gpgpu_cache:dl2_texture_only 0 -gpgpu_dram_partition_queues 64:64:64:64 -gpgpu_perf_sim_memcpy 1 diff --git a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config index ef28dd8..64edc67 100644 --- a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config +++ b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config @@ -127,7 +127,7 @@ -gpgpu_flush_l1_cache 1 # 32 sets, each 128 bytes 24-way for each memory sub partition (96 KB per memory sub partition). This gives us 4.5MB L2 cache --gpgpu_cache:dl2 S:32:128:24,L:B:m:L:L,A:192:4,32:0,32 +-gpgpu_cache:dl2 S:32:128:24,L:B:m:L:P,A:192:4,32:0,32 -gpgpu_cache:dl2_texture_only 0 -gpgpu_dram_partition_queues 64:64:64:64 -gpgpu_perf_sim_memcpy 1 diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc index 91ba47f..c01b8fa 100644 --- a/src/gpgpu-sim/addrdec.cc +++ b/src/gpgpu-sim/addrdec.cc @@ -31,9 +31,12 @@ #include #include "../option_parser.h" #include "gpu-sim.h" +#include "hashing.h" static long int powli(long int x, long int y); static unsigned int LOGB2_32(unsigned int v); +static unsigned next_powerOf2(unsigned n); + static new_addr_type addrdec_packbits(new_addr_type mask, new_addr_type val, unsigned char high, unsigned char low); static void addrdec_getmasklimit(new_addr_type mask, unsigned char *high, @@ -133,121 +136,29 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, break; case BITWISE_PERMUTATION: { assert(!gap); - tlx->chip = (tlx->chip) ^ (rest_of_addr_high_bits & (m_n_channel - 1)); + tlx->chip = + bitwise_hash_function(rest_of_addr_high_bits, tlx->chip, m_n_channel); assert(tlx->chip < m_n_channel); break; } case IPOLY: { - /* - * Set Indexing function from "Pseudo-randomly interleaved memory." - * Rau, B. R et al. - * ISCA 1991 - * http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=348DEA37A3E440473B3C075EAABC63B6?doi=10.1.1.12.7149&rep=rep1&type=pdf - * - * 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. - * - * equations for 32 banks are corresponding to IPOLY(37) - * equations for 64 banks are corresponding to IPOLY(67) - * To see all the IPOLY equations for all the degrees, see - * http://wireless-systems.ece.gatech.edu/6604/handouts/Peterson's%20Table.pdf - * - * We generate these equations using GF(2) arithmetic: - * http://www.ee.unb.ca/cgi-bin/tervo/calc.pl?num=&den=&f=d&e=1&m=1 - * - * We go through all the strides 128 (10000000), 256 (100000000),... and - * do modular arithmetic in GF(2) Then, we create the H-matrix and group - * each bit together, for more info read the ISCA 1991 paper - * - * IPOLY hashing guarantees conflict-free for all 2^n strides which widely - * exit in GPGPU applications and also show good performance for other - * strides. - */ - assert(!gap); - if (m_n_channel == 32 && m_n_sub_partition_in_channel == 1) { - std::bitset<64> a(rest_of_addr_high_bits); - std::bitset<5> chip(tlx->chip); - chip[0] = a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[6] ^ a[5] ^ a[3] ^ - a[0] ^ chip[0]; - chip[1] = a[14] ^ a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[7] ^ a[6] ^ a[4] ^ - a[1] ^ chip[1]; - chip[2] = a[14] ^ a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[6] ^ a[3] ^ a[2] ^ - a[0] ^ chip[2]; - chip[3] = - a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[4] ^ a[3] ^ a[1] ^ chip[3]; - chip[4] = - a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[5] ^ a[4] ^ a[2] ^ chip[4]; - tlx->chip = chip.to_ulong(); - break; - } else if (m_n_channel == 16 && m_n_sub_partition_in_channel == 2) { - std::bitset<64> a(rest_of_addr_high_bits); - std::bitset<4> chip(tlx->chip); - std::bitset<32> bk(tlx->bk); - chip[0] = a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[6] ^ a[5] ^ a[3] ^ - a[0] ^ chip[0]; - chip[1] = a[14] ^ a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[7] ^ a[6] ^ a[4] ^ - a[1] ^ chip[1]; - chip[2] = a[14] ^ a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[6] ^ a[3] ^ a[2] ^ - a[0] ^ chip[2]; - chip[3] = - a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[4] ^ a[3] ^ a[1] ^ chip[3]; - tlx->chip = chip.to_ulong(); - unsigned par_id = - a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[5] ^ a[4] ^ a[2] ^ bk[0]; - tlx->sub_partition = tlx->chip * m_n_sub_partition_in_channel + par_id; - assert(tlx->chip < m_n_channel); - assert(tlx->sub_partition < m_n_channel * m_n_sub_partition_in_channel); - return; - break; - } else if (m_n_channel == 32 && m_n_sub_partition_in_channel == 2) { - std::bitset<64> a(rest_of_addr_high_bits); - std::bitset<5> chip(tlx->chip); - std::bitset<32> bk(tlx->bk); - chip[0] = a[18] ^ a[17] ^ a[16] ^ a[15] ^ a[12] ^ a[10] ^ a[6] ^ a[5] ^ - a[0] ^ chip[0]; - chip[1] = a[15] ^ a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[7] ^ a[5] ^ a[1] ^ - a[0] ^ chip[1]; - chip[2] = a[16] ^ a[14] ^ a[13] ^ a[12] ^ a[11] ^ a[8] ^ a[6] ^ a[2] ^ - a[1] ^ chip[2]; - chip[3] = a[17] ^ a[15] ^ a[14] ^ a[13] ^ a[12] ^ a[9] ^ a[7] ^ a[3] ^ - a[2] ^ chip[3]; - chip[4] = a[18] ^ a[16] ^ a[15] ^ a[14] ^ a[13] ^ a[10] ^ a[8] ^ a[4] ^ - a[3] ^ chip[4]; - tlx->chip = chip.to_ulong(); - unsigned par_id = - a[17] ^ a[16] ^ a[15] ^ a[14] ^ a[11] ^ a[9] ^ a[5] ^ a[4] ^ bk[0]; - tlx->sub_partition = tlx->chip * m_n_sub_partition_in_channel + par_id; - assert(tlx->chip < m_n_channel); - assert(tlx->sub_partition < m_n_channel * m_n_sub_partition_in_channel); - return; - break; - } else { /* Else incorrect number of channels for the hashing function */ - assert( - "\nGPGPU-Sim memory_partition_indexing error: The number of " - "channels should be " - "32 or 64 for the hashing IPOLY index function.\n" && - 0); - } - assert(tlx->chip < m_n_channel); - break; - } - case PAE: { - // Page Address Entropy - // random selected bits from the page and bank bits - // similar to - // Liu, Yuxi, et al. "Get Out of the Valley: Power-Efficient Address - assert(!gap); - std::bitset<64> a(tlx->row); - std::bitset<5> chip(tlx->chip); - std::bitset<4> b(tlx->bk); - chip[0] = a[13] ^ a[10] ^ a[9] ^ a[5] ^ a[0] ^ b[3] ^ b[0] ^ chip[0]; - chip[1] = a[12] ^ a[11] ^ a[6] ^ a[1] ^ b[3] ^ b[2] ^ b[1] ^ chip[1]; - chip[2] = a[14] ^ a[9] ^ a[8] ^ a[7] ^ a[2] ^ b[1] ^ chip[2]; - chip[3] = a[11] ^ a[10] ^ a[8] ^ a[3] ^ b[2] ^ b[3] ^ chip[3]; - chip[4] = a[12] ^ a[9] ^ a[8] ^ a[5] ^ a[4] ^ b[1] ^ b[0] ^ chip[4]; - tlx->chip = chip.to_ulong(); + // assert(!gap); + unsigned sub_partition_addr_mask = m_n_sub_partition_in_channel - 1; + unsigned sub_partition = tlx->chip * m_n_sub_partition_in_channel + + (tlx->bk & sub_partition_addr_mask); + sub_partition = ipoly_hash_function( + rest_of_addr_high_bits, sub_partition, + nextPowerOf2_m_n_channel * m_n_sub_partition_in_channel); + + if (gap) // if it is not 2^n partitions, then take modular + sub_partition = + sub_partition % (m_n_channel * m_n_sub_partition_in_channel); + + tlx->chip = sub_partition / m_n_channel; + tlx->sub_partition = sub_partition; assert(tlx->chip < m_n_channel); + assert(tlx->sub_partition < m_n_channel * m_n_sub_partition_in_channel); + return; break; } case RANDOM: { @@ -377,6 +288,8 @@ void linear_to_raw_address_translation::init( log2sub_partition = ::LOGB2_32(n_sub_partition_in_channel); m_n_channel = n_channel; m_n_sub_partition_in_channel = n_sub_partition_in_channel; + nextPowerOf2_m_n_channel = ::next_powerOf2(n_channel); + m_n_sub_partition_total = n_channel * n_sub_partition_in_channel; gap = (n_channel - ::powli(2, nchipbits)); if (gap) { @@ -663,6 +576,22 @@ static unsigned int LOGB2_32(unsigned int v) { return r; } +// compute power of two greater than or equal to n +// https://www.techiedelight.com/round-next-highest-power-2/ +unsigned next_powerOf2(unsigned n) { + // decrement n (to handle the case when n itself + // is a power of 2) + n = n - 1; + + // do till only one bit is left + while (n & n - 1) n = n & (n - 1); // unset rightmost bit + + // n is now a power of two (less than n) + + // return next power of 2 + return n << 1; +} + static new_addr_type addrdec_packbits(new_addr_type mask, new_addr_type val, unsigned char high, unsigned char low) { unsigned pos = 0; diff --git a/src/gpgpu-sim/addrdec.h b/src/gpgpu-sim/addrdec.h index dd0e5a0..d8db416 100644 --- a/src/gpgpu-sim/addrdec.h +++ b/src/gpgpu-sim/addrdec.h @@ -87,8 +87,10 @@ class linear_to_raw_address_translation { unsigned int gap; unsigned m_n_channel; int m_n_sub_partition_in_channel; + int m_n_sub_partition_total; unsigned log2channel; unsigned log2sub_partition; + unsigned nextPowerOf2_m_n_channel; }; #endif diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc index 041cfce..ca47c46 100644 --- a/src/gpgpu-sim/dram.cc +++ b/src/gpgpu-sim/dram.cc @@ -31,6 +31,7 @@ #include "dram_sched.h" #include "gpu-misc.h" #include "gpu-sim.h" +#include "hashing.h" #include "l2cache.h" #include "mem_fetch.h" #include "mem_latency_stat.h" @@ -207,8 +208,8 @@ dram_req_t::dram_req_t(class mem_fetch *mf, unsigned banks, } case BITWISE_XORING_BK_INDEX: { // xoring bank bits with lower bits of the page - int lbank = LOGB2(banks); - bk = tlx.bk ^ (tlx.row & ((1 << lbank) - 1)); + bk = bitwise_hash_function(tlx.row, tlx.bk, banks); + assert(bk < banks); break; } case IPOLY_BK_INDEX: { @@ -216,22 +217,9 @@ dram_req_t::dram_req_t(class mem_fetch *mf, unsigned banks, * memory." Rau, B. R et al. ISCA 1991 * http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=348DEA37A3E440473B3C075EAABC63B6?doi=10.1.1.12.7149&rep=rep1&type=pdf */ - if (banks == 16) { - std::bitset<64> a(tlx.row); - std::bitset<4> b(tlx.bk); - b[0] = a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[6] ^ a[4] ^ a[3] ^ a[0] ^ b[0]; - b[1] = a[12] ^ a[8] ^ a[7] ^ a[6] ^ a[5] ^ a[3] ^ a[1] ^ a[0] ^ b[1]; - b[2] = a[9] ^ a[8] ^ a[7] ^ a[6] ^ a[4] ^ a[2] ^ a[1] ^ b[2]; - b[3] = a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[5] ^ a[3] ^ a[2] ^ b[3]; - bk = b.to_ulong(); - assert(bk < banks); - } else { /* Else incorrect number of channels for the hashing function */ - assert( - "\nGPGPU-Sim memory_banking indexing error: The number of banks " - "should be " - "16 for the hashing IPOLY index function.\n" && - 0); - } + // xoring bank bits with lower bits of the page + bk = ipoly_hash_function(tlx.row, tlx.bk, banks); + assert(bk < banks); break; } case CUSTOM_BK_INDEX: diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index adce3a2..75c3691 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -29,6 +29,7 @@ #include "gpu-cache.h" #include #include "gpu-sim.h" +#include "hashing.h" #include "stat-tool.h" // used to allocate memory that is large enough to adapt the changes in cache @@ -62,24 +63,31 @@ unsigned l1d_cache_config::set_bank(new_addr_type addr) const { // 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) - return (addr >> m_sector_sz_log2) & (l1_banks - 1); - else - return (addr >> m_line_sz_log2) & (l1_banks - 1); + return cache_config::hash_function(addr, l1_banks, l1_banks_byte_interleaving, + m_l1_banks_log2, + l1_banks_hashing_function); +} + +unsigned cache_config::set_index(new_addr_type addr) const { + return cache_config::hash_function(addr, m_nset, m_line_sz_log2, m_nset_log2, + m_set_index_function); } -unsigned l1d_cache_config::set_index(new_addr_type addr) const { - unsigned set_index = m_nset; // Default to linear set index function - unsigned lower_xor = 0; - unsigned upper_xor = 0; +unsigned cache_config::hash_function(new_addr_type addr, unsigned m_nset, + unsigned m_line_sz_log2, + unsigned m_nset_log2, + unsigned m_index_function) const { + unsigned set_index = 0; - switch (m_set_index_function) { - case FERMI_HASH_SET_FUNCTION: - case BITWISE_XORING_FUNCTION: + switch (m_index_function) { + case FERMI_HASH_SET_FUNCTION: { /* * Set Indexing function from "A Detailed GPU Cache Model Based on Reuse * Distance Theory" Cedric Nugteren et al. HPCA 2014 */ + unsigned lower_xor = 0; + unsigned upper_xor = 0; + if (m_nset == 32 || m_nset == 64) { // Lower xor value is bits 7-11 lower_xor = (addr >> m_line_sz_log2) & 0x1F; @@ -102,54 +110,34 @@ unsigned l1d_cache_config::set_index(new_addr_type addr) const { 0); } break; + } - case HASH_IPOLY_FUNCTION: - /* - * Set Indexing function from "Pseudo-randomly interleaved memory." - * Rau, B. R et al. - * ISCA 1991 - * - * "Sacat: streaming-aware conflict-avoiding thrashing-resistant gpgpu - * cache management scheme." Khairy et al. IEEE TPDS 2017. - */ - if (m_nset == 32 || m_nset == 64) { - std::bitset<64> a(addr); - std::bitset<6> index; - index[0] = a[25] ^ a[24] ^ a[23] ^ a[22] ^ a[21] ^ a[18] ^ a[17] ^ - a[15] ^ a[12] ^ a[7]; // 10 - index[1] = a[26] ^ a[25] ^ a[24] ^ a[23] ^ a[22] ^ a[19] ^ a[18] ^ - a[16] ^ a[13] ^ a[8]; // 10 - index[2] = a[26] ^ a[22] ^ a[21] ^ a[20] ^ a[19] ^ a[18] ^ a[15] ^ - a[14] ^ a[12] ^ a[9]; // 10 - index[3] = a[23] ^ a[22] ^ a[21] ^ a[20] ^ a[19] ^ a[16] ^ a[15] ^ - a[13] ^ a[10]; // 9 - index[4] = a[24] ^ a[23] ^ a[22] ^ a[21] ^ a[20] ^ a[17] ^ a[16] ^ - a[14] ^ a[11]; // 9 - - if (m_nset == 64) index[5] = a[12]; - - set_index = index.to_ulong(); - - } else { /* Else incorrect number of sets for the hashing function */ - assert( - "\nGPGPU-Sim cache configuration error: The number of sets should " - "be " - "32 or 64 for the hashing set index function.\n" && - 0); - } + case BITWISE_XORING_FUNCTION: { + new_addr_type higher_bits = addr >> (m_line_sz_log2 + m_nset_log2); + unsigned index = (addr >> m_line_sz_log2) & (m_nset - 1); + set_index = bitwise_hash_function(higher_bits, index, m_nset); break; - - case CUSTOM_SET_FUNCTION: + } + case HASH_IPOLY_FUNCTION: { + new_addr_type higher_bits = addr >> (m_line_sz_log2 + m_nset_log2); + unsigned index = (addr >> m_line_sz_log2) & (m_nset - 1); + set_index = ipoly_hash_function(higher_bits, index, m_nset); + break; + } + case CUSTOM_SET_FUNCTION: { /* No custom set function implemented */ break; + } - case LINEAR_SET_FUNCTION: + case LINEAR_SET_FUNCTION: { set_index = (addr >> m_line_sz_log2) & (m_nset - 1); break; + } - default: + default: { assert("\nUndefined set index function.\n" && 0); break; + } } // Linear function selected or custom set index function not implemented @@ -166,13 +154,14 @@ void l2_cache_config::init(linear_to_raw_address_translation *address_mapping) { } unsigned l2_cache_config::set_index(new_addr_type addr) const { - if (!m_address_mapping) { - return (addr >> m_line_sz_log2) & (m_nset - 1); - } else { + new_addr_type part_addr = addr; + + if (m_address_mapping) { // Calculate set index without memory partition bits to reduce set camping - new_addr_type part_addr = m_address_mapping->partition_address(addr); - return (part_addr >> m_line_sz_log2) & (m_nset - 1); + part_addr = m_address_mapping->partition_address(addr); } + + return cache_config::set_index(part_addr); } tag_array::~tag_array() { diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 2a37876..5c28b41 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -686,17 +686,11 @@ class cache_config { m_line_sz * m_nset * m_assoc, m_nset, m_assoc, m_line_sz); } - virtual unsigned set_index(new_addr_type addr) const { - if (m_set_index_function != LINEAR_SET_FUNCTION) { - printf( - "\nGPGPU-Sim cache configuration error: Hashing or " - "custom set index function selected in configuration " - "file for a cache that has not overloaded the set_index " - "function\n"); - abort(); - } - return (addr >> m_line_sz_log2) & (m_nset - 1); - } + virtual unsigned set_index(new_addr_type addr) const; + + unsigned hash_function(new_addr_type addr, unsigned m_nset, + unsigned m_line_sz_log2, unsigned m_nset_log2, + unsigned m_index_function) const; new_addr_type tag(new_addr_type addr) const { // For generality, the tag includes both index and tag. This allows for more @@ -793,10 +787,18 @@ class cache_config { class l1d_cache_config : public cache_config { public: l1d_cache_config() : cache_config() {} - virtual unsigned set_index(new_addr_type addr) const; unsigned set_bank(new_addr_type addr) const; + void init(char *config, FuncCache status) { + m_banks_byte_interleaving_log2 = LOGB2(l1_banks_byte_interleaving); + m_l1_banks_log2 = LOGB2(l1_banks); + cache_config::init(config, status); + } unsigned l1_latency; unsigned l1_banks; + unsigned m_l1_banks_log2; + unsigned l1_banks_byte_interleaving; + unsigned m_banks_byte_interleaving_log2; + unsigned l1_banks_hashing_function; }; class l2_cache_config : public cache_config { diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 03aebf3..1650688 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -252,6 +252,12 @@ void shader_core_config::reg_options(class OptionParser *opp) { option_parser_register(opp, "-gpgpu_l1_banks", OPT_UINT32, &m_L1D_config.l1_banks, "The number of L1 cache banks", "1"); + option_parser_register(opp, "-gpgpu_l1_banks_byte_interleaving", OPT_UINT32, + &m_L1D_config.l1_banks_byte_interleaving, + "l1 banks byte interleaving granularity", "32"); + option_parser_register(opp, "-gpgpu_l1_banks_hashing_function", OPT_UINT32, + &m_L1D_config.l1_banks_hashing_function, + "l1 banks hashing function", "0"); option_parser_register(opp, "-gpgpu_l1_latency", OPT_UINT32, &m_L1D_config.l1_latency, "L1 Hit Latency", "1"); option_parser_register(opp, "-gpgpu_smem_latency", OPT_UINT32, &smem_latency, -- cgit v1.3 From ee3c46354c5ce758bf71cfb7bd2e7da7718bcc8a Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 1 Jun 2020 15:09:34 -0400 Subject: renaming the executable --- Makefile | 6 +- configs/tested-cfgs/SM7_TITANV/gpgpusim.config | 2 +- src/trace-driven/gpgpusim_trace_driven_main.cc | 163 ------------------------- src/trace-driven/main.cc | 163 +++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 167 deletions(-) delete mode 100644 src/trace-driven/gpgpusim_trace_driven_main.cc create mode 100644 src/trace-driven/main.cc (limited to 'src') diff --git a/Makefile b/Makefile index ee48514..feb9dd0 100644 --- a/Makefile +++ b/Makefile @@ -75,7 +75,7 @@ else TARGETS += $(SIM_LIB_DIR)/libOpenCL.so endif TARGETS += cuobjdump_to_ptxplus/cuobjdump_to_ptxplus - TARGETS += $(SIM_LIB_DIR)/gpgpusim.out + TARGETS += $(SIM_LIB_DIR)/accelsim.out MCPAT= MCPAT_OBJ_DIR= @@ -171,7 +171,7 @@ $(SIM_LIB_DIR)/libcudart.so: makedirs $(LIBS) cudalib if [ ! -f $(SIM_LIB_DIR)/libcudart.so.10.1 ]; then ln -s libcudart.so $(SIM_LIB_DIR)/libcudart.so.10.1; fi -$(SIM_LIB_DIR)/gpgpusim.out: makedirs $(LIBS) cudalib $(SIM_LIB_DIR)/libcudart.so +$(SIM_LIB_DIR)/accelsim.out: makedirs $(LIBS) cudalib $(SIM_LIB_DIR)/libcudart.so ar rvs $(SIM_LIB_DIR)/libgpgpusim_static.a\ $(SIM_OBJ_FILES_DIR)/libcuda/*.o \ $(SIM_OBJ_FILES_DIR)/cuda-sim/*.o \ @@ -181,7 +181,7 @@ $(SIM_LIB_DIR)/gpgpusim.out: makedirs $(LIBS) cudalib $(SIM_LIB_DIR)/libcudart.s $(SIM_OBJ_FILES_DIR)/trace-driven/*.o \ $(SIM_OBJ_FILES_DIR)/*.o \ $(MCPAT) - g++ -std=c++0x -o $(SIM_LIB_DIR)/gpgpusim.out src/trace-driven/gpgpusim_trace_driven_main.cc -L$(SIM_LIB_DIR) -I$(CUDA_INSTALL_PATH)/include -lgpgpusim_static -lm -lz -lGL -pthread + g++ -std=c++0x -o $(SIM_LIB_DIR)/accelsim.out src/trace-driven/main.cc -L$(SIM_LIB_DIR) -I$(CUDA_INSTALL_PATH)/include -lgpgpusim_static -lm -lz -lGL -pthread $(SIM_LIB_DIR)/libcudart.dylib: makedirs $(LIBS) cudalib g++ -dynamiclib -Wl,-headerpad_max_install_names,-undefined,dynamic_lookup,-compatibility_version,1.1,-current_version,1.1\ diff --git a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config index 64edc67..3fa51ee 100644 --- a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config +++ b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config @@ -131,7 +131,7 @@ -gpgpu_cache:dl2_texture_only 0 -gpgpu_dram_partition_queues 64:64:64:64 -gpgpu_perf_sim_memcpy 1 --gpgpu_memory_partition_indexing 0 +-gpgpu_memory_partition_indexing 2 # 128 KB Inst. -gpgpu_cache:il1 N:64:128:16,L:R:f:N:L,S:2:48,4 diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc deleted file mode 100644 index f12d39a..0000000 --- a/src/trace-driven/gpgpusim_trace_driven_main.cc +++ /dev/null @@ -1,163 +0,0 @@ -// developed by Mahmoud Khairy, Purdue Univ -// abdallm@purdue.edu - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../../libcuda/gpgpu_context.h" -#include "../abstract_hardware_model.h" -#include "../cuda-sim/cuda-sim.h" -#include "../gpgpu-sim/gpu-sim.h" -#include "../gpgpu-sim/icnt_wrapper.h" -#include "../gpgpusim_entrypoint.h" -#include "../option_parser.h" -#include "ISA_Def/trace_opcode.h" -#include "trace_driven.h" - -/* TO DO: - * NOTE: the current version of trace-driven is functionally working fine, - * but we still need to improve traces compression and simulation speed. - * This includes: - * 1- Prefetch concurrent thread that prefetches traces from disk (to not be - * limited by disk speed) 2- traces compression format a. cfg format and remove - * thread/block Id from the head b. using zlib library to save in binary format - * - * 3- Efficient memory improvement (save string not objects - parse only 10 in - * the buffer) 4- Seeking capability - thread scheduler (save tb index and warp - * index info in the traces header) 5- Get rid off traces intermediate files - - * change the tracer - */ -gpgpu_sim* gpgpu_trace_sim_init_perf_model(int argc, const char* argv[], - gpgpu_context* m_gpgpu_context, - class trace_config* m_config); - -int main(int argc, const char** argv) { - gpgpu_context* m_gpgpu_context = new gpgpu_context(); - trace_config tconfig; - - gpgpu_sim* m_gpgpu_sim = - gpgpu_trace_sim_init_perf_model(argc, argv, m_gpgpu_context, &tconfig); - 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(tconfig.get_traces_filename(), m_gpgpu_sim, - m_gpgpu_context); - tconfig.parse_config(); - - std::vector commandlist = tracer.parse_kernellist_file(); - - for (unsigned i = 0; i < commandlist.size(); ++i) { - trace_kernel_info_t* kernel_info = NULL; - if (commandlist[i].substr(0, 6) == "Memcpy") { - size_t addre, Bcount; - tracer.parse_memcpy_info(commandlist[i], addre, Bcount); - std::cout << commandlist[i] << std::endl; - m_gpgpu_sim->perf_memcpy_to_gpu(addre, Bcount); - continue; - } else { - kernel_info = tracer.parse_kernel_info(commandlist[i], &tconfig); - 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); - - if (kernel_info) { - 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); - } - } - - // we print this message to inform the gpgpu-simulation stats_collect script - // that we are done - printf("GPGPU-Sim: *** simulation thread exiting ***\n"); - printf("GPGPU-Sim: *** exit detected ***\n"); - - return 1; -} - -gpgpu_sim* gpgpu_trace_sim_init_perf_model(int argc, const char* argv[], - gpgpu_context* m_gpgpu_context, - trace_config* m_config) { - srand(1); - print_splash(); - - option_parser_t opp = option_parser_create(); - - m_gpgpu_context->ptx_reg_options(opp); - m_gpgpu_context->func_sim->ptx_opcocde_latency_options(opp); - - icnt_reg_options(opp); - - m_gpgpu_context->the_gpgpusim->g_the_gpu_config = - new gpgpu_sim_config(m_gpgpu_context); - m_gpgpu_context->the_gpgpusim->g_the_gpu_config->reg_options( - opp); // register GPU microrachitecture options - m_config->reg_options(opp); - - 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")); - m_gpgpu_context->the_gpgpusim->g_the_gpu_config->init(); - - m_gpgpu_context->the_gpgpusim->g_the_gpu = new trace_gpgpu_sim( - *(m_gpgpu_context->the_gpgpusim->g_the_gpu_config), m_gpgpu_context); - - m_gpgpu_context->the_gpgpusim->g_stream_manager = - new stream_manager((m_gpgpu_context->the_gpgpusim->g_the_gpu), - m_gpgpu_context->func_sim->g_cuda_launch_blocking); - - m_gpgpu_context->the_gpgpusim->g_simulation_starttime = time((time_t*)NULL); - - return m_gpgpu_context->the_gpgpusim->g_the_gpu; -} diff --git a/src/trace-driven/main.cc b/src/trace-driven/main.cc new file mode 100644 index 0000000..f12d39a --- /dev/null +++ b/src/trace-driven/main.cc @@ -0,0 +1,163 @@ +// developed by Mahmoud Khairy, Purdue Univ +// abdallm@purdue.edu + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../libcuda/gpgpu_context.h" +#include "../abstract_hardware_model.h" +#include "../cuda-sim/cuda-sim.h" +#include "../gpgpu-sim/gpu-sim.h" +#include "../gpgpu-sim/icnt_wrapper.h" +#include "../gpgpusim_entrypoint.h" +#include "../option_parser.h" +#include "ISA_Def/trace_opcode.h" +#include "trace_driven.h" + +/* TO DO: + * NOTE: the current version of trace-driven is functionally working fine, + * but we still need to improve traces compression and simulation speed. + * This includes: + * 1- Prefetch concurrent thread that prefetches traces from disk (to not be + * limited by disk speed) 2- traces compression format a. cfg format and remove + * thread/block Id from the head b. using zlib library to save in binary format + * + * 3- Efficient memory improvement (save string not objects - parse only 10 in + * the buffer) 4- Seeking capability - thread scheduler (save tb index and warp + * index info in the traces header) 5- Get rid off traces intermediate files - + * change the tracer + */ +gpgpu_sim* gpgpu_trace_sim_init_perf_model(int argc, const char* argv[], + gpgpu_context* m_gpgpu_context, + class trace_config* m_config); + +int main(int argc, const char** argv) { + gpgpu_context* m_gpgpu_context = new gpgpu_context(); + trace_config tconfig; + + gpgpu_sim* m_gpgpu_sim = + gpgpu_trace_sim_init_perf_model(argc, argv, m_gpgpu_context, &tconfig); + 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(tconfig.get_traces_filename(), m_gpgpu_sim, + m_gpgpu_context); + tconfig.parse_config(); + + std::vector commandlist = tracer.parse_kernellist_file(); + + for (unsigned i = 0; i < commandlist.size(); ++i) { + trace_kernel_info_t* kernel_info = NULL; + if (commandlist[i].substr(0, 6) == "Memcpy") { + size_t addre, Bcount; + tracer.parse_memcpy_info(commandlist[i], addre, Bcount); + std::cout << commandlist[i] << std::endl; + m_gpgpu_sim->perf_memcpy_to_gpu(addre, Bcount); + continue; + } else { + kernel_info = tracer.parse_kernel_info(commandlist[i], &tconfig); + 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); + + if (kernel_info) { + 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); + } + } + + // we print this message to inform the gpgpu-simulation stats_collect script + // that we are done + printf("GPGPU-Sim: *** simulation thread exiting ***\n"); + printf("GPGPU-Sim: *** exit detected ***\n"); + + return 1; +} + +gpgpu_sim* gpgpu_trace_sim_init_perf_model(int argc, const char* argv[], + gpgpu_context* m_gpgpu_context, + trace_config* m_config) { + srand(1); + print_splash(); + + option_parser_t opp = option_parser_create(); + + m_gpgpu_context->ptx_reg_options(opp); + m_gpgpu_context->func_sim->ptx_opcocde_latency_options(opp); + + icnt_reg_options(opp); + + m_gpgpu_context->the_gpgpusim->g_the_gpu_config = + new gpgpu_sim_config(m_gpgpu_context); + m_gpgpu_context->the_gpgpusim->g_the_gpu_config->reg_options( + opp); // register GPU microrachitecture options + m_config->reg_options(opp); + + 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")); + m_gpgpu_context->the_gpgpusim->g_the_gpu_config->init(); + + m_gpgpu_context->the_gpgpusim->g_the_gpu = new trace_gpgpu_sim( + *(m_gpgpu_context->the_gpgpusim->g_the_gpu_config), m_gpgpu_context); + + m_gpgpu_context->the_gpgpusim->g_stream_manager = + new stream_manager((m_gpgpu_context->the_gpgpusim->g_the_gpu), + m_gpgpu_context->func_sim->g_cuda_launch_blocking); + + m_gpgpu_context->the_gpgpusim->g_simulation_starttime = time((time_t*)NULL); + + return m_gpgpu_context->the_gpgpusim->g_the_gpu; +} -- cgit v1.3 From 04b5438cb61b6f040f69fa99fafc971cc43c60ed Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 1 Jun 2020 15:10:07 -0400 Subject: ooh forgot to add hashing files --- src/gpgpu-sim/hashing.cc | 150 +++++++++++++++++++++++++++++++++++++++++++++++ src/gpgpu-sim/hashing.h | 24 ++++++++ 2 files changed, 174 insertions(+) create mode 100644 src/gpgpu-sim/hashing.cc create mode 100644 src/gpgpu-sim/hashing.h (limited to 'src') diff --git a/src/gpgpu-sim/hashing.cc b/src/gpgpu-sim/hashing.cc new file mode 100644 index 0000000..003755c --- /dev/null +++ b/src/gpgpu-sim/hashing.cc @@ -0,0 +1,150 @@ +// Copyright (c) 2009-2011, Wilson W.L. Fung, Tor M. Aamodt, Ali Bakhoda, +// The University of British Columbia +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. Neither the name of +// The University of British Columbia nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#include +#include +#include "../abstract_hardware_model.h" +#include "gpu-cache.h" + +unsigned ipoly_hash_function(new_addr_type higher_bits, unsigned index, + unsigned bank_set_num) { + /* + * Set Indexing function from "Pseudo-randomly interleaved memory." + * Rau, B. R et al. + * ISCA 1991 + * http://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=348DEA37A3E440473B3C075EAABC63B6?doi=10.1.1.12.7149&rep=rep1&type=pdf + * + * 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. + * + * equations for 16 banks are corresponding to IPOLY(5) + * equations for 32 banks are corresponding to IPOLY(37) + * equations for 64 banks are corresponding to IPOLY(67) + * To see all the IPOLY equations for all the degrees, see + * http://wireless-systems.ece.gatech.edu/6604/handouts/Peterson's%20Table.pdf + * + * We generate these equations using GF(2) arithmetic: + * http://www.ee.unb.ca/cgi-bin/tervo/calc.pl?num=&den=&f=d&e=1&m=1 + * + * We go through all the strides 128 (10000000), 256 (100000000),... and + * do modular arithmetic in GF(2) Then, we create the H-matrix and group + * each bit together, for more info read the ISCA 1991 paper + * + * IPOLY hashing guarantees conflict-free for all 2^n strides which widely + * exit in GPGPU applications and also show good performance for other + * strides. + */ + if (bank_set_num == 16) { + std::bitset<64> a(higher_bits); + std::bitset<4> b(index); + std::bitset<4> new_index(index); + + new_index[0] = + a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[6] ^ a[4] ^ a[3] ^ a[0] ^ b[0]; + new_index[1] = + a[12] ^ a[8] ^ a[7] ^ a[6] ^ a[5] ^ a[3] ^ a[1] ^ a[0] ^ b[1]; + new_index[2] = a[9] ^ a[8] ^ a[7] ^ a[6] ^ a[4] ^ a[2] ^ a[1] ^ b[2]; + new_index[3] = a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[5] ^ a[3] ^ a[2] ^ b[3]; + + return new_index.to_ulong(); + + } else if (bank_set_num == 32) { + std::bitset<64> a(higher_bits); + std::bitset<5> b(index); + std::bitset<5> new_index(index); + + new_index[0] = + a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[6] ^ a[5] ^ a[3] ^ a[0] ^ b[0]; + new_index[1] = a[14] ^ a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[7] ^ a[6] ^ a[4] ^ + a[1] ^ b[1]; + new_index[2] = + a[14] ^ a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[6] ^ a[3] ^ a[2] ^ a[0] ^ b[2]; + new_index[3] = + a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[7] ^ a[4] ^ a[3] ^ a[1] ^ b[3]; + new_index[4] = + a[12] ^ a[11] ^ a[10] ^ a[9] ^ a[8] ^ a[5] ^ a[4] ^ a[2] ^ b[4]; + return new_index.to_ulong(); + + } else if (bank_set_num == 64) { + std::bitset<64> a(higher_bits); + std::bitset<6> b(index); + std::bitset<6> new_index(index); + + new_index[0] = a[18] ^ a[17] ^ a[16] ^ a[15] ^ a[12] ^ a[10] ^ a[6] ^ a[5] ^ + a[0] ^ b[0]; + new_index[1] = a[15] ^ a[13] ^ a[12] ^ a[11] ^ a[10] ^ a[7] ^ a[5] ^ a[1] ^ + a[0] ^ b[1]; + new_index[2] = a[16] ^ a[14] ^ a[13] ^ a[12] ^ a[11] ^ a[8] ^ a[6] ^ a[2] ^ + a[1] ^ b[2]; + new_index[3] = a[17] ^ a[15] ^ a[14] ^ a[13] ^ a[12] ^ a[9] ^ a[7] ^ a[3] ^ + a[2] ^ b[3]; + new_index[4] = a[18] ^ a[16] ^ a[15] ^ a[14] ^ a[13] ^ a[10] ^ a[8] ^ a[4] ^ + a[3] ^ b[4]; + new_index[5] = + a[17] ^ a[16] ^ a[15] ^ a[14] ^ a[11] ^ a[9] ^ a[5] ^ a[4] ^ b[5]; + return new_index.to_ulong(); + } else { /* Else incorrect number of channels for the hashing function */ + assert( + "\nmemory_partition_indexing error: The number of " + "channels should be " + "16, 32 or 64 for the hashing IPOLY index function. other banks " + "numbers are not supported. Generate it by yourself! \n" && + 0); + + return 0; + } +} + +unsigned bitwise_hash_function(new_addr_type higher_bits, unsigned index, + unsigned bank_set_num) { + return (index) ^ (higher_bits & (bank_set_num - 1)); +} + +unsigned PAE_hash_function(new_addr_type higher_bits, unsigned index, + unsigned bank_set_num) { + // Page Address Entropy + // random selected bits from the page and bank bits + // similar to + // Liu, Yuxi, et al. "Get Out of the Valley: Power-Efficient Address + if (bank_set_num == 32) { + std::bitset<64> a(higher_bits); + std::bitset<5> b(index); + std::bitset<5> new_index(index); + new_index[0] = a[13] ^ a[10] ^ a[9] ^ a[5] ^ a[0] ^ b[3] ^ b[0] ^ b[0]; + new_index[1] = a[12] ^ a[11] ^ a[6] ^ a[1] ^ b[3] ^ b[2] ^ b[1] ^ b[1]; + new_index[2] = a[14] ^ a[9] ^ a[8] ^ a[7] ^ a[2] ^ b[1] ^ b[2]; + new_index[3] = a[11] ^ a[10] ^ a[8] ^ a[3] ^ b[2] ^ b[3] ^ b[3]; + new_index[4] = a[12] ^ a[9] ^ a[8] ^ a[5] ^ a[4] ^ b[1] ^ b[0] ^ b[4]; + + return new_index.to_ulong(); + } else { + assert(0); + return 0; + } +} diff --git a/src/gpgpu-sim/hashing.h b/src/gpgpu-sim/hashing.h new file mode 100644 index 0000000..867c949 --- /dev/null +++ b/src/gpgpu-sim/hashing.h @@ -0,0 +1,24 @@ +// author: Mahmoud Khairy, (Purdue Univ) +// email: abdallm@purdue.edu + +#include +#include +#include +#include "../option_parser.h" + +#ifndef HASHING_H +#define HASHING_H + +#include "../abstract_hardware_model.h" +#include "gpu-cache.h" + +unsigned ipoly_hash_function(new_addr_type higher_bits, unsigned index, + unsigned bank_set_num); + +unsigned bitwise_hash_function(new_addr_type higher_bits, unsigned index, + unsigned bank_set_num); + +unsigned PAE_hash_function(new_addr_type higher_bits, unsigned index, + unsigned bank_set_num); + +#endif -- cgit v1.3 From 68e873ef5cb3d0e88b8fb2a148e7870d09110748 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 1 Jun 2020 15:15:28 -0400 Subject: revmoing traces driven from gpgpusim --- configs/tested-cfgs/SM3_KEPLER_TITAN/trace.config | 4 - configs/tested-cfgs/SM6_TITANX/trace.config | 4 - configs/tested-cfgs/SM75_RTX2060/trace.config | 25 - configs/tested-cfgs/SM7_QV100/trace.config | 19 - configs/tested-cfgs/SM7_TITANV/trace.config | 19 - src/trace-driven/ISA_Def/kepler_opcode.h | 148 ---- src/trace-driven/ISA_Def/pascal_opcode.h | 199 ------ src/trace-driven/ISA_Def/trace_opcode.h | 230 ------ src/trace-driven/ISA_Def/turing_opcode.h | 221 ------ src/trace-driven/ISA_Def/volta_opcode.h | 177 ----- src/trace-driven/main.cc | 163 ----- src/trace-driven/trace_driven.cc | 811 ---------------------- src/trace-driven/trace_driven.h | 210 ------ 13 files changed, 2230 deletions(-) delete mode 100644 configs/tested-cfgs/SM3_KEPLER_TITAN/trace.config delete mode 100644 configs/tested-cfgs/SM6_TITANX/trace.config delete mode 100644 configs/tested-cfgs/SM75_RTX2060/trace.config delete mode 100644 configs/tested-cfgs/SM7_QV100/trace.config delete mode 100644 configs/tested-cfgs/SM7_TITANV/trace.config delete mode 100644 src/trace-driven/ISA_Def/kepler_opcode.h delete mode 100644 src/trace-driven/ISA_Def/pascal_opcode.h delete mode 100644 src/trace-driven/ISA_Def/trace_opcode.h delete mode 100644 src/trace-driven/ISA_Def/turing_opcode.h delete mode 100644 src/trace-driven/ISA_Def/volta_opcode.h delete mode 100644 src/trace-driven/main.cc delete mode 100644 src/trace-driven/trace_driven.cc delete mode 100644 src/trace-driven/trace_driven.h (limited to 'src') diff --git a/configs/tested-cfgs/SM3_KEPLER_TITAN/trace.config b/configs/tested-cfgs/SM3_KEPLER_TITAN/trace.config deleted file mode 100644 index 4c80036..0000000 --- a/configs/tested-cfgs/SM3_KEPLER_TITAN/trace.config +++ /dev/null @@ -1,4 +0,0 @@ --trace_opcode_latency_initiation_int 4,1 --trace_opcode_latency_initiation_sp 4,1 --trace_opcode_latency_initiation_dp 20,2 --trace_opcode_latency_initiation_sfu 200,2 diff --git a/configs/tested-cfgs/SM6_TITANX/trace.config b/configs/tested-cfgs/SM6_TITANX/trace.config deleted file mode 100644 index 88bcdc0..0000000 --- a/configs/tested-cfgs/SM6_TITANX/trace.config +++ /dev/null @@ -1,4 +0,0 @@ --trace_opcode_latency_initiation_int 4,1 --trace_opcode_latency_initiation_sp 4,1 --trace_opcode_latency_initiation_dp 20,8 --trace_opcode_latency_initiation_sfu 20,4 diff --git a/configs/tested-cfgs/SM75_RTX2060/trace.config b/configs/tested-cfgs/SM75_RTX2060/trace.config deleted file mode 100644 index 17b6cc7..0000000 --- a/configs/tested-cfgs/SM75_RTX2060/trace.config +++ /dev/null @@ -1,25 +0,0 @@ --trace_opcode_latency_initiation_int 4,2 --trace_opcode_latency_initiation_sp 4,2 --trace_opcode_latency_initiation_dp 8,4 --trace_opcode_latency_initiation_sfu 20,8 --trace_opcode_latency_initiation_tensor 8,4 - -#execute branch insts on spec unit 1 -#in Turing, there is a dedicated branch unit -#,,,,, --specialized_unit_1 1,4,4,4,4,BRA -#, --trace_opcode_latency_initiation_spec_op_1 4,4 - -#TEX unit, make fixed latency for all tex insts --specialized_unit_2 1,1,200,4,4,TEX --trace_opcode_latency_initiation_spec_op_2 200,4 - -#tensor unit --specialized_unit_3 1,4,8,4,4,TENSOR --trace_opcode_latency_initiation_spec_op_3 8,4 - -#UDP unit -#for more info about UDP, see https://www.hotchips.org/hc31/HC31_2.12_NVIDIA_final.pdf --specialized_unit_4 1,4,4,4,4,UDP --trace_opcode_latency_initiation_spec_op_4 4,2 diff --git a/configs/tested-cfgs/SM7_QV100/trace.config b/configs/tested-cfgs/SM7_QV100/trace.config deleted file mode 100644 index 88f5706..0000000 --- a/configs/tested-cfgs/SM7_QV100/trace.config +++ /dev/null @@ -1,19 +0,0 @@ --trace_opcode_latency_initiation_int 4,2 --trace_opcode_latency_initiation_sp 4,2 --trace_opcode_latency_initiation_dp 8,4 --trace_opcode_latency_initiation_sfu 20,8 --trace_opcode_latency_initiation_tensor 8,4 - -#execute branch insts on spec unit 1 -#in Volta, there is a dedicated branch unit -#,,,,, --specialized_unit_1 1,4,4,4,4,BRA --trace_opcode_latency_initiation_spec_op_1 4,4 - -#TEX unit, make fixed latency for all tex insts --specialized_unit_2 1,4,200,4,4,TEX --trace_opcode_latency_initiation_spec_op_2 200,4 - -#tensor unit --specialized_unit_3 1,4,8,4,4,TENSOR --trace_opcode_latency_initiation_spec_op_3 8,4 diff --git a/configs/tested-cfgs/SM7_TITANV/trace.config b/configs/tested-cfgs/SM7_TITANV/trace.config deleted file mode 100644 index 88f5706..0000000 --- a/configs/tested-cfgs/SM7_TITANV/trace.config +++ /dev/null @@ -1,19 +0,0 @@ --trace_opcode_latency_initiation_int 4,2 --trace_opcode_latency_initiation_sp 4,2 --trace_opcode_latency_initiation_dp 8,4 --trace_opcode_latency_initiation_sfu 20,8 --trace_opcode_latency_initiation_tensor 8,4 - -#execute branch insts on spec unit 1 -#in Volta, there is a dedicated branch unit -#,,,,, --specialized_unit_1 1,4,4,4,4,BRA --trace_opcode_latency_initiation_spec_op_1 4,4 - -#TEX unit, make fixed latency for all tex insts --specialized_unit_2 1,4,200,4,4,TEX --trace_opcode_latency_initiation_spec_op_2 200,4 - -#tensor unit --specialized_unit_3 1,4,8,4,4,TENSOR --trace_opcode_latency_initiation_spec_op_3 8,4 diff --git a/src/trace-driven/ISA_Def/kepler_opcode.h b/src/trace-driven/ISA_Def/kepler_opcode.h deleted file mode 100644 index c2f8548..0000000 --- a/src/trace-driven/ISA_Def/kepler_opcode.h +++ /dev/null @@ -1,148 +0,0 @@ -// developed by Mahmoud Khairy, Purdue Univ -// abdallm@purdue.edu - -#ifndef KEPLER_OPCODE_H -#define KEPLER_OPCODE_H - -#include -#include -#include "trace_opcode.h" - -#define KEPLER_BINART_VERSION 35 -#define KEPLER_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 - -// TO DO: moving this to a yml or def files - -/// Kepler ISA -// see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map Kepler_OpcodeMap = { - // Floating Point 32 Instructions - {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, - {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, - {"FADD", OpcodeChar(OP_FADD, SP_OP)}, - {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, - {"FCMP", OpcodeChar(OP_FCMP, SP_OP)}, - {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, - {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, - {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, - {"FSWZ", OpcodeChar(OP_FSWZ, SP_OP)}, - {"FSET", OpcodeChar(OP_FSET, SP_OP)}, - {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, - {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, - {"RRO", OpcodeChar(OP_RRO, SP_OP)}, - // SFU - {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, - - // Double Point Instructions - {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, - {"DADD", OpcodeChar(OP_DADD, DP_OP)}, - {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, - {"DMNMX", OpcodeChar(OP_DMNMX, DP_OP)}, - {"DSET", OpcodeChar(OP_DSET, DP_OP)}, - {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, - - // Integer Instructions - {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, - {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, - {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, - {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, - {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, - {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, - {"ISUB", OpcodeChar(OP_ISUB, INTP_OP)}, - {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, - {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, - {"ISAD", OpcodeChar(OP_ISAD, INTP_OP)}, - {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, - {"BFE", OpcodeChar(OP_BFE, INTP_OP)}, - {"BFI", OpcodeChar(OP_BFI, INTP_OP)}, - {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, - {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, - {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, - {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, - {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, - {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, - {"ISET", OpcodeChar(OP_ISET, INTP_OP)}, - {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, - {"ICMP", OpcodeChar(OP_ICMP, INTP_OP)}, - {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, - - // Conversion Instructions - {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, - {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, - {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, - {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, - - // Movement Instructions - {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, - {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, - {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, - {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, - {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, - - // Predicate Instructions - {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, - {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, - {"CSET", OpcodeChar(OP_CSET, ALU_OP)}, - {"CSETP", OpcodeChar(OP_CSETP, ALU_OP)}, - {"PSET", OpcodeChar(OP_PSET, ALU_OP)}, - {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, - - // Texture Instructions - // For now, we ignore texture loads, consider it as ALU_OP - {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, - {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, - {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, - {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, - - // Load/Store Instructions - // For now, we ignore constant loads, consider it as ALU_OP, TO DO - {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, - // in Kepler, LD is load global so set it to LDG - {"LD", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, - {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, - {"LDSLK", OpcodeChar(OP_LDSLK, LOAD_OP)}, - {"ST", OpcodeChar(OP_STG, STORE_OP)}, - {"STL", OpcodeChar(OP_STL, STORE_OP)}, - {"STS", OpcodeChar(OP_STS, STORE_OP)}, - {"STSCUL", OpcodeChar(OP_STSCUL, STORE_OP)}, - {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, - {"RED", OpcodeChar(OP_RED, STORE_OP)}, - {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, - {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, - {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, - - // surface memory instructions - {"SUCLAMP", OpcodeChar(OP_SUCLAMP, LOAD_OP)}, - {"SUBFM", OpcodeChar(OP_SUBFM, LOAD_OP)}, - {"SUEAU", OpcodeChar(OP_SUEAU, LOAD_OP)}, - {"SULDGA", OpcodeChar(OP_SULDGA, LOAD_OP)}, - {"SUSTGA", OpcodeChar(OP_SUSTGA, STORE_OP)}, - - // Control Instructions - {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, - {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, - {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, - {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, - {"CAL", OpcodeChar(OP_CAL, CALL_OPS)}, - {"JCAL", OpcodeChar(OP_JCAL, CALL_OPS)}, - {"RET", OpcodeChar(OP_RET, RET_OPS)}, - {"BRK", OpcodeChar(OP_BRK, RET_OPS)}, - {"CONT", OpcodeChar(OP_CONT, RET_OPS)}, - {"SSY", OpcodeChar(OP_SSY, RET_OPS)}, - {"PBK", OpcodeChar(OP_PBK, RET_OPS)}, - {"PCNT", OpcodeChar(OP_PCNT, RET_OPS)}, - {"PRET", OpcodeChar(OP_PRET, RET_OPS)}, - {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, - {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, - - // Miscellaneous Instructions - {"NOP", OpcodeChar(OP_NOP, ALU_OP)}, - {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, - {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, - {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, - {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, -}; - -#endif diff --git a/src/trace-driven/ISA_Def/pascal_opcode.h b/src/trace-driven/ISA_Def/pascal_opcode.h deleted file mode 100644 index 34fe400..0000000 --- a/src/trace-driven/ISA_Def/pascal_opcode.h +++ /dev/null @@ -1,199 +0,0 @@ -// developed by Mahmoud Khairy, Purdue Univ -// abdallm@purdue.edu - -#ifndef PASCAL_OPCODE_H -#define PASCAL_OPCODE_H - -#include -#include -#include "trace_opcode.h" - -#define PASCAL_TITANX_BINART_VERSION 61 -#define PASCAL_P100_BINART_VERSION 60 - -#define PASCAL_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 - -// TO DO: moving this to a yml or def files - -/// Pascal SM_61 ISA -// see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map Pascal_OpcodeMap = { - // Floating Point 32 Instructions - {"FADD", OpcodeChar(OP_FADD, SP_OP)}, - {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, - {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, - {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, - {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, - {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, - {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, - {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, - {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, - {"FSET", OpcodeChar(OP_FSET, SP_OP)}, - {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, - {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, - {"RRO", OpcodeChar(OP_RRO, SP_OP)}, - - // SFU - {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, - - // Floating Point 16 Instructions - {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, - {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, - {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, - {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, - {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, - - // Double Point Instructions - {"DADD", OpcodeChar(OP_DADD, DP_OP)}, - {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, - {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, - {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, - {"DMNMX", OpcodeChar(OP_DMNMX, DP_OP)}, - {"DSET", OpcodeChar(OP_DSET, DP_OP)}, - - // Integer Instructions - {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, - {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, - {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, - {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, - {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, - {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, - {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, - {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, - {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, - {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, - {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, - {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, - {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, - {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, - {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, - {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, - {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, - {"ISET", OpcodeChar(OP_ISET, INTP_OP)}, - {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, - {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, - {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, - {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, - {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, - {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, - {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, - {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, - {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, - {"BFE", OpcodeChar(OP_BFE, INTP_OP)}, - {"BFI", OpcodeChar(OP_BFI, INTP_OP)}, - {"ICMP", OpcodeChar(OP_ICMP, INTP_OP)}, - {"IMADSP", OpcodeChar(OP_IMADSP, INTP_OP)}, - {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, - {"XMAD", OpcodeChar(OP_XMAD, INTP_OP)}, - {"VMNMX", OpcodeChar(OP_VMNMX, INTP_OP)}, - - // Conversion Instructions - {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, - {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, - {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, - {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, - {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, - {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, - - // Movement Instructions - {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, - {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, - {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, - {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, - {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, - {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, - - // Predicate Instructions - {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, - {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, - {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, - {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, - {"CSET", OpcodeChar(OP_CSET, ALU_OP)}, - {"CSETP", OpcodeChar(OP_CSETP, ALU_OP)}, - {"PSET", OpcodeChar(OP_PSET, ALU_OP)}, - - // Load/Store Instructions - {"LD", OpcodeChar(OP_LD, LOAD_OP)}, - // For now, we ignore constant loads, consider it as ALU_OP, TO DO - {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, - {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, - {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, - {"ST", OpcodeChar(OP_ST, STORE_OP)}, - {"STG", OpcodeChar(OP_STG, STORE_OP)}, - {"STL", OpcodeChar(OP_STL, STORE_OP)}, - {"STS", OpcodeChar(OP_STS, STORE_OP)}, - {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, - {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, - {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, - {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, - {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, - {"RED", OpcodeChar(OP_RED, STORE_OP)}, - {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, - {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, - {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, - {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, - {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, - - // Texture Instructions - // For now, we ignore texture loads, consider it as ALU_OP - {"TEX", OpcodeChar(OP_TEX, ALU_OP)}, - {"TLD", OpcodeChar(OP_TLD, ALU_OP)}, - {"TLD4", OpcodeChar(OP_TLD4, ALU_OP)}, - {"TMML", OpcodeChar(OP_TMML, ALU_OP)}, - {"TXD", OpcodeChar(OP_TXD, ALU_OP)}, - {"TXQ", OpcodeChar(OP_TXQ, ALU_OP)}, - {"TEXS", OpcodeChar(OP_TEXS, ALU_OP)}, - {"TLD4S", OpcodeChar(OP_TLD4S, ALU_OP)}, - {"TLDS", OpcodeChar(OP_TLDS, ALU_OP)}, - - // Control Instructions - {"BMOV", OpcodeChar(OP_BMOV, BRANCH_OP)}, - {"BPT", OpcodeChar(OP_BPT, BRANCH_OP)}, - {"BRA", OpcodeChar(OP_BRA, BRANCH_OP)}, - {"BREAK", OpcodeChar(OP_BREAK, BRANCH_OP)}, - {"BRX", OpcodeChar(OP_BRX, BRANCH_OP)}, - {"BSSY", OpcodeChar(OP_BSSY, BRANCH_OP)}, - {"BSYNC", OpcodeChar(OP_BSYNC, BRANCH_OP)}, - {"CALL", OpcodeChar(OP_CALL, CALL_OPS)}, - {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, - {"JMP", OpcodeChar(OP_JMP, BRANCH_OP)}, - {"SSY", OpcodeChar(OP_SSY, BRANCH_OP)}, - {"SYNC", OpcodeChar(OP_SYNC, BRANCH_OP)}, - {"JMX", OpcodeChar(OP_JMX, BRANCH_OP)}, - {"KILL", OpcodeChar(OP_KILL, BRANCH_OP)}, - {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, BRANCH_OP)}, - {"RET", OpcodeChar(OP_RET, RET_OPS)}, - {"RPCMOV", OpcodeChar(OP_RPCMOV, BRANCH_OP)}, - {"RTT", OpcodeChar(OP_RTT, RET_OPS)}, - {"WARPSYNC", OpcodeChar(OP_WARPSYNC, BRANCH_OP)}, - {"YIELD", OpcodeChar(OP_YIELD, BRANCH_OP)}, - {"CAL", OpcodeChar(OP_CAL, CALL_OPS)}, - {"JCAL", OpcodeChar(OP_JCAL, CALL_OPS)}, - {"PRET", OpcodeChar(OP_PRET, CALL_OPS)}, - {"BRK", OpcodeChar(OP_BRK, CALL_OPS)}, - {"PBK", OpcodeChar(OP_PBK, CALL_OPS)}, - {"CONT", OpcodeChar(OP_CONT, CALL_OPS)}, - {"PCNT", OpcodeChar(OP_PCNT, CALL_OPS)}, - {"PEXIT", OpcodeChar(OP_PEXIT, CALL_OPS)}, - - // Miscellaneous Instructions - {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, - {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, - {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, - {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, - {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, - {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, - {"LEPC", OpcodeChar(OP_LEPC, ALU_OP)}, - {"NOP", OpcodeChar(OP_NOP, ALU_OP)}, - {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, - {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, - {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, - {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, - {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, - {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, - {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, - -}; - -#endif diff --git a/src/trace-driven/ISA_Def/trace_opcode.h b/src/trace-driven/ISA_Def/trace_opcode.h deleted file mode 100644 index 5675957..0000000 --- a/src/trace-driven/ISA_Def/trace_opcode.h +++ /dev/null @@ -1,230 +0,0 @@ -// developed by Mahmoud Khairy, Purdue Univ -// abdallm@purdue.edu - -#ifndef TRACE_OPCODE_H -#define TRACE_OPCODE_H - -#include -#include -#include "../../abstract_hardware_model.h" - -enum TraceInstrOpcode { - // Volta (includes common insts for others cards as well) - OP_FADD = 1, - OP_FADD32I, - OP_FCHK, - OP_FFMA32I, - OP_FFMA, - OP_FMNMX, - OP_FMUL, - OP_FMUL32I, - OP_FSEL, - OP_FSET, - OP_FSETP, - OP_FSWZADD, - OP_MUFU, - OP_HADD2, - OP_HADD2_32I, - OP_HFMA2, - OP_HFMA2_32I, - OP_HMUL2, - OP_HMUL2_32I, - OP_HSET2, - OP_HSETP2, - OP_HMMA, - OP_DADD, - OP_DFMA, - OP_DMUL, - OP_DSETP, - OP_BMSK, - OP_BREV, - OP_FLO, - OP_IABS, - OP_IADD, - OP_IADD3, - OP_IADD32I, - OP_IDP, - OP_IDP4A, - OP_IMAD, - OP_IMMA, - OP_IMNMX, - OP_IMUL, - OP_IMUL32I, - OP_ISCADD, - OP_ISCADD32I, - OP_ISETP, - OP_LEA, - OP_LOP, - OP_LOP3, - OP_LOP32I, - OP_POPC, - OP_SHF, - OP_SHR, - OP_VABSDIFF, - OP_VABSDIFF4, - OP_F2F, - OP_F2I, - OP_I2F, - OP_I2I, - OP_I2IP, - OP_FRND, - OP_MOV, - OP_MOV32I, - OP_PRMT, - OP_SEL, - OP_SGXT, - OP_SHFL, - OP_PLOP3, - OP_PSETP, - OP_P2R, - OP_R2P, - OP_LD, - OP_LDC, - OP_LDG, - OP_LDL, - OP_LDS, - OP_ST, - OP_STG, - OP_STL, - OP_STS, - OP_MATCH, - OP_QSPC, - OP_ATOM, - OP_ATOMS, - OP_ATOMG, - OP_RED, - OP_CCTL, - OP_CCTLL, - OP_ERRBAR, - OP_MEMBAR, - OP_CCTLT, - OP_TEX, - OP_TLD, - OP_TLD4, - OP_TMML, - OP_TXD, - OP_TXQ, - OP_BMOV, - OP_BPT, - OP_BRA, - OP_BREAK, - OP_BRX, - OP_BSSY, - OP_BSYNC, - OP_CALL, - OP_EXIT, - OP_JMP, - OP_JMX, - OP_KILL, - OP_NANOSLEEP, - OP_RET, - OP_RPCMOV, - OP_RTT, - OP_WARPSYNC, - OP_YIELD, - OP_B2R, - OP_BAR, - OP_CS2R, - OP_CSMTEST, - OP_DEPBAR, - OP_GETLMEMBASE, - OP_LEPC, - OP_NOP, - OP_PMTRIG, - OP_R2B, - OP_S2R, - OP_SETCTAID, - OP_SETLMEMBASE, - OP_VOTE, - OP_VOTE_VTG, - // unique insts for pascal - OP_RRO, - OP_DMNMX, - OP_DSET, - OP_BFE, - OP_BFI, - OP_ICMP, - OP_IMADSP, - OP_SHL, - OP_XMAD, - OP_CSET, - OP_CSETP, - OP_TEXS, - OP_TLD4S, - OP_TLDS, - OP_CAL, - OP_JCAL, - OP_PRET, - OP_BRK, - OP_PBK, - OP_CONT, - OP_PCNT, - OP_PEXIT, - OP_SSY, - OP_SYNC, - OP_PSET, - OP_VMNMX, - OP_ISET, - // unique insts for turing - OP_BMMA, - OP_MOVM, - OP_LDSM, - OP_R2UR, - OP_S2UR, - OP_UBMSK, - OP_UBREV, - OP_UCLEA, - OP_UFLO, - OP_UIADD3, - OP_UIMAD, - OP_UISETP, - OP_ULDC, - OP_ULEA, - OP_ULOP, - OP_ULOP3, - OP_ULOP32I, - OP_UMOV, - OP_UP2UR, - OP_UPLOP3, - OP_UPOPC, - OP_UPRMT, - OP_UPSETP, - OP_UR2UP, - OP_USEL, - OP_USGXT, - OP_USHF, - OP_USHL, - OP_USHR, - OP_VOTEU, - OP_SUATOM, - OP_SULD, - OP_SURED, - OP_SUST, - OP_BRXU, - OP_JMXU, - // unique insts for kepler - OP_FCMP, - OP_FSWZ, - OP_ISAD, - OP_LDSLK, - OP_STSCUL, - OP_SUCLAMP, - OP_SUBFM, - OP_SUEAU, - OP_SULDGA, - OP_SUSTGA, - OP_ISUB, - SASS_NUM_OPCODES /* The total number of opcodes. */ -}; -typedef enum TraceInstrOpcode sass_op_type; - -struct OpcodeChar { - OpcodeChar(unsigned m_opcode, unsigned m_opcode_category) { - opcode = m_opcode; - opcode_category = m_opcode_category; - } - unsigned opcode; - unsigned opcode_category; -}; - -#endif diff --git a/src/trace-driven/ISA_Def/turing_opcode.h b/src/trace-driven/ISA_Def/turing_opcode.h deleted file mode 100644 index 12bbe76..0000000 --- a/src/trace-driven/ISA_Def/turing_opcode.h +++ /dev/null @@ -1,221 +0,0 @@ -// developed by Mahmoud Khairy, Purdue Univ -// abdallm@purdue.edu - -#ifndef TURING_OPCODE_H -#define TURING_OPCODE_H - -#include -#include -#include "trace_opcode.h" - -#define TURING_BINART_VERSION 75 -#define TURING_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 - -// TO DO: moving this to a yml or def files - -/// Volta SM_70 ISA -// see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map Turing_OpcodeMap = { - // Floating Point 32 Instructions - {"FADD", OpcodeChar(OP_FADD, SP_OP)}, - {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, - {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, - {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, - {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, - {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, - {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, - {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, - {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, - {"FSET", OpcodeChar(OP_FSET, SP_OP)}, - {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, - {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, - // SFU - {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, - - // Floating Point 16 Instructions - {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, - {"HADD2_32I", OpcodeChar(OP_HADD2_32I, SP_OP)}, - {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, - {"HFMA2_32I", OpcodeChar(OP_HFMA2_32I, SP_OP)}, - {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, - {"HMUL2_32I", OpcodeChar(OP_HMUL2_32I, SP_OP)}, - {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, - {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, - - // Tensor Core Instructions - // Execute Tensor Core Instructions on SPECIALIZED_UNIT_3 - {"HMMA", OpcodeChar(OP_HMMA, SPECIALIZED_UNIT_3_OP)}, - - // Double Point Instructions - {"DADD", OpcodeChar(OP_DADD, DP_OP)}, - {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, - {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, - {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, - - // Integer Instructions - {"BMMA", OpcodeChar(OP_BMMA, INTP_OP)}, //////// - {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, - {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, - {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, - {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, - {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, - {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, - {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, - {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, - {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, - {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, - {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, - {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, - {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, - {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, - {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, - {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, - {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, - {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, - {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, - {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, - {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, - {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, - {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, - {"SHL", OpcodeChar(OP_SHL, INTP_OP)}, ////////// - {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, - {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, - {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, - - // Conversion Instructions - {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, - {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, - {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, - {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, - {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, - {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, - - // Movement Instructions - {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, - {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, - {"MOVM", OpcodeChar(OP_MOVM, ALU_OP)}, // move matrix - {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, - {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, - {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, - {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, - - // Predicate Instructions - {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, - {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, - {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, - {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, - - // Load/Store Instructions - {"LD", OpcodeChar(OP_LD, LOAD_OP)}, - // For now, we ignore constant loads, consider it as ALU_OP, TO DO - {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, - {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, - {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, - {"LDSM", OpcodeChar(OP_LDSM, LOAD_OP)}, // - {"ST", OpcodeChar(OP_ST, STORE_OP)}, - {"STG", OpcodeChar(OP_STG, STORE_OP)}, - {"STL", OpcodeChar(OP_STL, STORE_OP)}, - {"STS", OpcodeChar(OP_STS, STORE_OP)}, - {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, - {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, - {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, - {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, - {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, - {"RED", OpcodeChar(OP_RED, STORE_OP)}, - {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, - {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, - {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, - {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, - {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, - - // Uniform Datapath Instruction - // UDP unit - // for more info about UDP, see - // https://www.hotchips.org/hc31/HC31_2.12_NVIDIA_final.pdf - {"R2UR", OpcodeChar(OP_R2UR, SPECIALIZED_UNIT_4_OP)}, - {"S2UR", OpcodeChar(OP_S2UR, SPECIALIZED_UNIT_4_OP)}, - {"UBMSK", OpcodeChar(OP_UBMSK, SPECIALIZED_UNIT_4_OP)}, - {"UBREV", OpcodeChar(OP_UBREV, SPECIALIZED_UNIT_4_OP)}, - {"UCLEA", OpcodeChar(OP_UCLEA, SPECIALIZED_UNIT_4_OP)}, - {"UFLO", OpcodeChar(OP_UFLO, SPECIALIZED_UNIT_4_OP)}, - {"UIADD3", OpcodeChar(OP_UIADD3, SPECIALIZED_UNIT_4_OP)}, - {"UIMAD", OpcodeChar(OP_UIMAD, SPECIALIZED_UNIT_4_OP)}, - {"UISETP", OpcodeChar(OP_UISETP, SPECIALIZED_UNIT_4_OP)}, - {"ULDC", OpcodeChar(OP_ULDC, SPECIALIZED_UNIT_4_OP)}, - {"ULEA", OpcodeChar(OP_ULEA, SPECIALIZED_UNIT_4_OP)}, - {"ULOP", OpcodeChar(OP_ULOP, SPECIALIZED_UNIT_4_OP)}, - {"ULOP3", OpcodeChar(OP_ULOP3, SPECIALIZED_UNIT_4_OP)}, - {"ULOP32I", OpcodeChar(OP_ULOP32I, SPECIALIZED_UNIT_4_OP)}, - {"UMOV", OpcodeChar(OP_UMOV, SPECIALIZED_UNIT_4_OP)}, - {"UP2UR", OpcodeChar(OP_UP2UR, SPECIALIZED_UNIT_4_OP)}, - {"UPLOP3", OpcodeChar(OP_UPLOP3, SPECIALIZED_UNIT_4_OP)}, - {"UPOPC", OpcodeChar(OP_UPOPC, SPECIALIZED_UNIT_4_OP)}, - {"UPRMT", OpcodeChar(OP_UPRMT, SPECIALIZED_UNIT_4_OP)}, - {"UPSETP", OpcodeChar(OP_UPSETP, SPECIALIZED_UNIT_4_OP)}, - {"UR2UP", OpcodeChar(OP_UR2UP, SPECIALIZED_UNIT_4_OP)}, - {"USEL", OpcodeChar(OP_USEL, SPECIALIZED_UNIT_4_OP)}, - {"USGXT", OpcodeChar(OP_USGXT, SPECIALIZED_UNIT_4_OP)}, - {"USHF", OpcodeChar(OP_USHF, SPECIALIZED_UNIT_4_OP)}, - {"USHL", OpcodeChar(OP_USHL, SPECIALIZED_UNIT_4_OP)}, - {"USHR", OpcodeChar(OP_USHR, SPECIALIZED_UNIT_4_OP)}, - {"VOTEU", OpcodeChar(OP_VOTEU, SPECIALIZED_UNIT_4_OP)}, - - // Texture Instructions - // For now, we ignore texture loads, consider it as ALU_OP - {"TEX", OpcodeChar(OP_TEX, SPECIALIZED_UNIT_2_OP)}, - {"TLD", OpcodeChar(OP_TLD, SPECIALIZED_UNIT_2_OP)}, - {"TLD4", OpcodeChar(OP_TLD4, SPECIALIZED_UNIT_2_OP)}, - {"TMML", OpcodeChar(OP_TMML, SPECIALIZED_UNIT_2_OP)}, - {"TXD", OpcodeChar(OP_TXD, SPECIALIZED_UNIT_2_OP)}, - {"TXQ", OpcodeChar(OP_TXQ, SPECIALIZED_UNIT_2_OP)}, - - // Surface Instructions // - {"SUATOM", OpcodeChar(OP_SUATOM, ALU_OP)}, - {"SULD", OpcodeChar(OP_SULD, ALU_OP)}, - {"SURED", OpcodeChar(OP_SURED, ALU_OP)}, - {"SUST", OpcodeChar(OP_SUST, ALU_OP)}, - - // Control Instructions - // execute branch insts on a dedicated branch unit (SPECIALIZED_UNIT_1) - {"BMOV", OpcodeChar(OP_BMOV, SPECIALIZED_UNIT_1_OP)}, - {"BPT", OpcodeChar(OP_BPT, SPECIALIZED_UNIT_1_OP)}, - {"BRA", OpcodeChar(OP_BRA, SPECIALIZED_UNIT_1_OP)}, - {"BREAK", OpcodeChar(OP_BREAK, SPECIALIZED_UNIT_1_OP)}, - {"BRX", OpcodeChar(OP_BRX, SPECIALIZED_UNIT_1_OP)}, - {"BRXU", OpcodeChar(OP_BRXU, SPECIALIZED_UNIT_1_OP)}, // - {"BSSY", OpcodeChar(OP_BSSY, SPECIALIZED_UNIT_1_OP)}, - {"BSYNC", OpcodeChar(OP_BSYNC, SPECIALIZED_UNIT_1_OP)}, - {"CALL", OpcodeChar(OP_CALL, SPECIALIZED_UNIT_1_OP)}, - {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, - {"JMP", OpcodeChar(OP_JMP, SPECIALIZED_UNIT_1_OP)}, - {"JMX", OpcodeChar(OP_JMX, SPECIALIZED_UNIT_1_OP)}, - {"JMXU", OpcodeChar(OP_JMXU, SPECIALIZED_UNIT_1_OP)}, /// - {"KILL", OpcodeChar(OP_KILL, SPECIALIZED_UNIT_3_OP)}, - {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, SPECIALIZED_UNIT_1_OP)}, - {"RET", OpcodeChar(OP_RET, SPECIALIZED_UNIT_1_OP)}, - {"RPCMOV", OpcodeChar(OP_RPCMOV, SPECIALIZED_UNIT_1_OP)}, - {"RTT", OpcodeChar(OP_RTT, SPECIALIZED_UNIT_1_OP)}, - {"WARPSYNC", OpcodeChar(OP_WARPSYNC, SPECIALIZED_UNIT_1_OP)}, - {"YIELD", OpcodeChar(OP_YIELD, SPECIALIZED_UNIT_1_OP)}, - - // Miscellaneous Instructions - {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, - {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, - {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, - {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, - {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, - {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, - {"LEPC", OpcodeChar(OP_LEPC, ALU_OP)}, - {"NOP", OpcodeChar(OP_NOP, ALU_OP)}, - {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, - {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, - {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, - {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, - {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, - {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, - {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, - -}; - -#endif diff --git a/src/trace-driven/ISA_Def/volta_opcode.h b/src/trace-driven/ISA_Def/volta_opcode.h deleted file mode 100644 index 3358211..0000000 --- a/src/trace-driven/ISA_Def/volta_opcode.h +++ /dev/null @@ -1,177 +0,0 @@ -// developed by Mahmoud Khairy, Purdue Univ -// abdallm@purdue.edu - -#ifndef VOLTA_OPCODE_H -#define VOLTA_OPCODE_H - -#include -#include -#include "trace_opcode.h" - -#define VOLTA_BINART_VERSION 70 -#define VOLTA_SHARED_MEMORY_VIRTIAL_ADDRESS_START 0x00007f2c60000000 - -// TO DO: moving this to a yml or def files - -/// Volta SM_70 ISA -// see: https://docs.nvidia.com/cuda/cuda-binary-utilities/index.html -static const std::unordered_map Volta_OpcodeMap = { - // Floating Point 32 Instructions - {"FADD", OpcodeChar(OP_FADD, SP_OP)}, - {"FADD32I", OpcodeChar(OP_FADD32I, SP_OP)}, - {"FCHK", OpcodeChar(OP_FCHK, SP_OP)}, - {"FFMA32I", OpcodeChar(OP_FFMA32I, SP_OP)}, - {"FFMA", OpcodeChar(OP_FFMA, SP_OP)}, - {"FMNMX", OpcodeChar(OP_FMNMX, SP_OP)}, - {"FMUL", OpcodeChar(OP_FMUL, SP_OP)}, - {"FMUL32I", OpcodeChar(OP_FMUL32I, SP_OP)}, - {"FSEL", OpcodeChar(OP_FSEL, SP_OP)}, - {"FSET", OpcodeChar(OP_FSET, SP_OP)}, - {"FSETP", OpcodeChar(OP_FSETP, SP_OP)}, - {"FSWZADD", OpcodeChar(OP_FSWZADD, SP_OP)}, - // SFU - {"MUFU", OpcodeChar(OP_MUFU, SFU_OP)}, - - // Floating Point 16 Instructions - {"HADD2", OpcodeChar(OP_HADD2, SP_OP)}, - {"HADD2_32I", OpcodeChar(OP_HADD2_32I, SP_OP)}, - {"HFMA2", OpcodeChar(OP_HFMA2, SP_OP)}, - {"HFMA2_32I", OpcodeChar(OP_HFMA2_32I, SP_OP)}, - {"HMUL2", OpcodeChar(OP_HMUL2, SP_OP)}, - {"HMUL2_32I", OpcodeChar(OP_HMUL2_32I, SP_OP)}, - {"HSET2", OpcodeChar(OP_HSET2, SP_OP)}, - {"HSETP2", OpcodeChar(OP_HSETP2, SP_OP)}, - - // Tensor Core Instructions - // Execute Tensor Core Instructions on SPECIALIZED_UNIT_3 - {"HMMA", OpcodeChar(OP_HMMA, SPECIALIZED_UNIT_3_OP)}, - - // Double Point Instructions - {"DADD", OpcodeChar(OP_DADD, DP_OP)}, - {"DFMA", OpcodeChar(OP_DFMA, DP_OP)}, - {"DMUL", OpcodeChar(OP_DMUL, DP_OP)}, - {"DSETP", OpcodeChar(OP_DSETP, DP_OP)}, - - // Integer Instructions - {"BMSK", OpcodeChar(OP_BMSK, INTP_OP)}, - {"BREV", OpcodeChar(OP_BREV, INTP_OP)}, - {"FLO", OpcodeChar(OP_FLO, INTP_OP)}, - {"IABS", OpcodeChar(OP_IABS, INTP_OP)}, - {"IADD", OpcodeChar(OP_IADD, INTP_OP)}, - {"IADD3", OpcodeChar(OP_IADD3, INTP_OP)}, - {"IADD32I", OpcodeChar(OP_IADD32I, INTP_OP)}, - {"IDP", OpcodeChar(OP_IDP, INTP_OP)}, - {"IDP4A", OpcodeChar(OP_IDP4A, INTP_OP)}, - {"IMAD", OpcodeChar(OP_IMAD, INTP_OP)}, - {"IMMA", OpcodeChar(OP_IMMA, INTP_OP)}, - {"IMNMX", OpcodeChar(OP_IMNMX, INTP_OP)}, - {"IMUL", OpcodeChar(OP_IMUL, INTP_OP)}, - {"IMUL32I", OpcodeChar(OP_IMUL32I, INTP_OP)}, - {"ISCADD", OpcodeChar(OP_ISCADD, INTP_OP)}, - {"ISCADD32I", OpcodeChar(OP_ISCADD32I, INTP_OP)}, - {"ISETP", OpcodeChar(OP_ISETP, INTP_OP)}, - {"LEA", OpcodeChar(OP_LEA, INTP_OP)}, - {"LOP", OpcodeChar(OP_LOP, INTP_OP)}, - {"LOP3", OpcodeChar(OP_LOP3, INTP_OP)}, - {"LOP32I", OpcodeChar(OP_LOP32I, INTP_OP)}, - {"POPC", OpcodeChar(OP_POPC, INTP_OP)}, - {"SHF", OpcodeChar(OP_SHF, INTP_OP)}, - {"SHR", OpcodeChar(OP_SHR, INTP_OP)}, - {"VABSDIFF", OpcodeChar(OP_VABSDIFF, INTP_OP)}, - {"VABSDIFF4", OpcodeChar(OP_VABSDIFF4, INTP_OP)}, - - // Conversion Instructions - {"F2F", OpcodeChar(OP_F2F, ALU_OP)}, - {"F2I", OpcodeChar(OP_F2I, ALU_OP)}, - {"I2F", OpcodeChar(OP_I2F, ALU_OP)}, - {"I2I", OpcodeChar(OP_I2I, ALU_OP)}, - {"I2IP", OpcodeChar(OP_I2IP, ALU_OP)}, - {"FRND", OpcodeChar(OP_FRND, ALU_OP)}, - - // Movement Instructions - {"MOV", OpcodeChar(OP_MOV, ALU_OP)}, - {"MOV32I", OpcodeChar(OP_MOV32I, ALU_OP)}, - {"PRMT", OpcodeChar(OP_PRMT, ALU_OP)}, - {"SEL", OpcodeChar(OP_SEL, ALU_OP)}, - {"SGXT", OpcodeChar(OP_SGXT, ALU_OP)}, - {"SHFL", OpcodeChar(OP_SHFL, ALU_OP)}, - - // Predicate Instructions - {"PLOP3", OpcodeChar(OP_PLOP3, ALU_OP)}, - {"PSETP", OpcodeChar(OP_PSETP, ALU_OP)}, - {"P2R", OpcodeChar(OP_P2R, ALU_OP)}, - {"R2P", OpcodeChar(OP_R2P, ALU_OP)}, - - // Load/Store Instructions - {"LD", OpcodeChar(OP_LD, LOAD_OP)}, - // For now, we ignore constant loads, consider it as ALU_OP, TO DO - {"LDC", OpcodeChar(OP_LDC, ALU_OP)}, - {"LDG", OpcodeChar(OP_LDG, LOAD_OP)}, - {"LDL", OpcodeChar(OP_LDL, LOAD_OP)}, - {"LDS", OpcodeChar(OP_LDS, LOAD_OP)}, - {"ST", OpcodeChar(OP_ST, STORE_OP)}, - {"STG", OpcodeChar(OP_STG, STORE_OP)}, - {"STL", OpcodeChar(OP_STL, STORE_OP)}, - {"STS", OpcodeChar(OP_STS, STORE_OP)}, - {"MATCH", OpcodeChar(OP_MATCH, ALU_OP)}, - {"QSPC", OpcodeChar(OP_QSPC, ALU_OP)}, - {"ATOM", OpcodeChar(OP_ATOM, STORE_OP)}, - {"ATOMS", OpcodeChar(OP_ATOMS, STORE_OP)}, - {"ATOMG", OpcodeChar(OP_ATOMG, STORE_OP)}, - {"RED", OpcodeChar(OP_RED, STORE_OP)}, - {"CCTL", OpcodeChar(OP_CCTL, ALU_OP)}, - {"CCTLL", OpcodeChar(OP_CCTLL, ALU_OP)}, - {"ERRBAR", OpcodeChar(OP_ERRBAR, ALU_OP)}, - {"MEMBAR", OpcodeChar(OP_MEMBAR, MEMORY_BARRIER_OP)}, - {"CCTLT", OpcodeChar(OP_CCTLT, ALU_OP)}, - - // Texture Instructions - // For now, we ignore texture loads, consider it as ALU_OP - {"TEX", OpcodeChar(OP_TEX, SPECIALIZED_UNIT_2_OP)}, - {"TLD", OpcodeChar(OP_TLD, SPECIALIZED_UNIT_2_OP)}, - {"TLD4", OpcodeChar(OP_TLD4, SPECIALIZED_UNIT_2_OP)}, - {"TMML", OpcodeChar(OP_TMML, SPECIALIZED_UNIT_2_OP)}, - {"TXD", OpcodeChar(OP_TXD, SPECIALIZED_UNIT_2_OP)}, - {"TXQ", OpcodeChar(OP_TXQ, SPECIALIZED_UNIT_2_OP)}, - - // Control Instructions - // execute branch insts on a dedicated branch unit (SPECIALIZED_UNIT_1) - {"BMOV", OpcodeChar(OP_BMOV, SPECIALIZED_UNIT_1_OP)}, - {"BPT", OpcodeChar(OP_BPT, SPECIALIZED_UNIT_1_OP)}, - {"BRA", OpcodeChar(OP_BRA, SPECIALIZED_UNIT_1_OP)}, - {"BREAK", OpcodeChar(OP_BREAK, SPECIALIZED_UNIT_1_OP)}, - {"BRX", OpcodeChar(OP_BRX, SPECIALIZED_UNIT_1_OP)}, - {"BSSY", OpcodeChar(OP_BSSY, SPECIALIZED_UNIT_1_OP)}, - {"BSYNC", OpcodeChar(OP_BSYNC, SPECIALIZED_UNIT_1_OP)}, - {"CALL", OpcodeChar(OP_CALL, SPECIALIZED_UNIT_1_OP)}, - {"EXIT", OpcodeChar(OP_EXIT, EXIT_OPS)}, - {"JMP", OpcodeChar(OP_JMP, SPECIALIZED_UNIT_1_OP)}, - {"JMX", OpcodeChar(OP_JMX, SPECIALIZED_UNIT_1_OP)}, - {"KILL", OpcodeChar(OP_KILL, SPECIALIZED_UNIT_1_OP)}, - {"NANOSLEEP", OpcodeChar(OP_NANOSLEEP, SPECIALIZED_UNIT_1_OP)}, - {"RET", OpcodeChar(OP_RET, SPECIALIZED_UNIT_1_OP)}, - {"RPCMOV", OpcodeChar(OP_RPCMOV, SPECIALIZED_UNIT_1_OP)}, - {"RTT", OpcodeChar(OP_RTT, SPECIALIZED_UNIT_1_OP)}, - {"WARPSYNC", OpcodeChar(OP_WARPSYNC, SPECIALIZED_UNIT_1_OP)}, - {"YIELD", OpcodeChar(OP_YIELD, SPECIALIZED_UNIT_1_OP)}, - - // Miscellaneous Instructions - {"B2R", OpcodeChar(OP_B2R, ALU_OP)}, - {"BAR", OpcodeChar(OP_BAR, BARRIER_OP)}, - {"CS2R", OpcodeChar(OP_CS2R, ALU_OP)}, - {"CSMTEST", OpcodeChar(OP_CSMTEST, ALU_OP)}, - {"DEPBAR", OpcodeChar(OP_DEPBAR, ALU_OP)}, - {"GETLMEMBASE", OpcodeChar(OP_GETLMEMBASE, ALU_OP)}, - {"LEPC", OpcodeChar(OP_LEPC, ALU_OP)}, - {"NOP", OpcodeChar(OP_NOP, ALU_OP)}, - {"PMTRIG", OpcodeChar(OP_PMTRIG, ALU_OP)}, - {"R2B", OpcodeChar(OP_R2B, ALU_OP)}, - {"S2R", OpcodeChar(OP_S2R, ALU_OP)}, - {"SETCTAID", OpcodeChar(OP_SETCTAID, ALU_OP)}, - {"SETLMEMBASE", OpcodeChar(OP_SETLMEMBASE, ALU_OP)}, - {"VOTE", OpcodeChar(OP_VOTE, ALU_OP)}, - {"VOTE_VTG", OpcodeChar(OP_VOTE_VTG, ALU_OP)}, - -}; - -#endif diff --git a/src/trace-driven/main.cc b/src/trace-driven/main.cc deleted file mode 100644 index f12d39a..0000000 --- a/src/trace-driven/main.cc +++ /dev/null @@ -1,163 +0,0 @@ -// developed by Mahmoud Khairy, Purdue Univ -// abdallm@purdue.edu - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../../libcuda/gpgpu_context.h" -#include "../abstract_hardware_model.h" -#include "../cuda-sim/cuda-sim.h" -#include "../gpgpu-sim/gpu-sim.h" -#include "../gpgpu-sim/icnt_wrapper.h" -#include "../gpgpusim_entrypoint.h" -#include "../option_parser.h" -#include "ISA_Def/trace_opcode.h" -#include "trace_driven.h" - -/* TO DO: - * NOTE: the current version of trace-driven is functionally working fine, - * but we still need to improve traces compression and simulation speed. - * This includes: - * 1- Prefetch concurrent thread that prefetches traces from disk (to not be - * limited by disk speed) 2- traces compression format a. cfg format and remove - * thread/block Id from the head b. using zlib library to save in binary format - * - * 3- Efficient memory improvement (save string not objects - parse only 10 in - * the buffer) 4- Seeking capability - thread scheduler (save tb index and warp - * index info in the traces header) 5- Get rid off traces intermediate files - - * change the tracer - */ -gpgpu_sim* gpgpu_trace_sim_init_perf_model(int argc, const char* argv[], - gpgpu_context* m_gpgpu_context, - class trace_config* m_config); - -int main(int argc, const char** argv) { - gpgpu_context* m_gpgpu_context = new gpgpu_context(); - trace_config tconfig; - - gpgpu_sim* m_gpgpu_sim = - gpgpu_trace_sim_init_perf_model(argc, argv, m_gpgpu_context, &tconfig); - 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(tconfig.get_traces_filename(), m_gpgpu_sim, - m_gpgpu_context); - tconfig.parse_config(); - - std::vector commandlist = tracer.parse_kernellist_file(); - - for (unsigned i = 0; i < commandlist.size(); ++i) { - trace_kernel_info_t* kernel_info = NULL; - if (commandlist[i].substr(0, 6) == "Memcpy") { - size_t addre, Bcount; - tracer.parse_memcpy_info(commandlist[i], addre, Bcount); - std::cout << commandlist[i] << std::endl; - m_gpgpu_sim->perf_memcpy_to_gpu(addre, Bcount); - continue; - } else { - kernel_info = tracer.parse_kernel_info(commandlist[i], &tconfig); - 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); - - if (kernel_info) { - 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); - } - } - - // we print this message to inform the gpgpu-simulation stats_collect script - // that we are done - printf("GPGPU-Sim: *** simulation thread exiting ***\n"); - printf("GPGPU-Sim: *** exit detected ***\n"); - - return 1; -} - -gpgpu_sim* gpgpu_trace_sim_init_perf_model(int argc, const char* argv[], - gpgpu_context* m_gpgpu_context, - trace_config* m_config) { - srand(1); - print_splash(); - - option_parser_t opp = option_parser_create(); - - m_gpgpu_context->ptx_reg_options(opp); - m_gpgpu_context->func_sim->ptx_opcocde_latency_options(opp); - - icnt_reg_options(opp); - - m_gpgpu_context->the_gpgpusim->g_the_gpu_config = - new gpgpu_sim_config(m_gpgpu_context); - m_gpgpu_context->the_gpgpusim->g_the_gpu_config->reg_options( - opp); // register GPU microrachitecture options - m_config->reg_options(opp); - - 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")); - m_gpgpu_context->the_gpgpusim->g_the_gpu_config->init(); - - m_gpgpu_context->the_gpgpusim->g_the_gpu = new trace_gpgpu_sim( - *(m_gpgpu_context->the_gpgpusim->g_the_gpu_config), m_gpgpu_context); - - m_gpgpu_context->the_gpgpusim->g_stream_manager = - new stream_manager((m_gpgpu_context->the_gpgpusim->g_the_gpu), - m_gpgpu_context->func_sim->g_cuda_launch_blocking); - - m_gpgpu_context->the_gpgpusim->g_simulation_starttime = time((time_t*)NULL); - - return m_gpgpu_context->the_gpgpusim->g_the_gpu; -} diff --git a/src/trace-driven/trace_driven.cc b/src/trace-driven/trace_driven.cc deleted file mode 100644 index 83b134e..0000000 --- a/src/trace-driven/trace_driven.cc +++ /dev/null @@ -1,811 +0,0 @@ -// developed by Mahmoud Khairy, Purdue Univ -// abdallm@purdue.edu - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../../libcuda/gpgpu_context.h" -#include "../abstract_hardware_model.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 "../gpgpusim_entrypoint.h" -#include "../option_parser.h" -#include "ISA_Def/kepler_opcode.h" -#include "ISA_Def/pascal_opcode.h" -#include "ISA_Def/trace_opcode.h" -#include "ISA_Def/turing_opcode.h" -#include "ISA_Def/volta_opcode.h" -#include "trace_driven.h" - -bool is_number(const std::string& s) { - std::string::const_iterator it = s.begin(); - while (it != s.end() && std::isdigit(*it)) ++it; - return !s.empty() && it == s.end(); -} - -void split(const std::string& str, std::vector& cont, - char delimi = ' ') { - std::stringstream ss(str); - std::string token; - while (std::getline(ss, token, delimi)) { - cont.push_back(token); - } -} - -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 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 kernellist; - while (!ifs.eof()) { - getline(ifs, line); - if (line.empty()) - continue; - else if (line.substr(0, 6) == "Memcpy") { - kernellist.push_back(line); - } else if (line.substr(0, 6) == "kernel") { - filepath = directory + "/" + line; - kernellist.push_back(filepath); - } - } - - ifs.close(); - return kernellist; -} - -void trace_parser::parse_memcpy_info(const std::string& memcpy_command, - size_t& address, size_t& count) { - std::vector params; - split(memcpy_command, params, ','); - assert(params.size() == 3); - std::stringstream ss; - ss.str(params[1]); - ss >> std::hex >> address; - ss.clear(); - ss.str(params[2]); - ss >> std::dec >> count; -} - -trace_kernel_info_t* trace_parser::parse_kernel_info( - const std::string& kerneltraces_filepath, trace_config* config) { - 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, - binary_verion = 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); - } else if (string1 == "binary" && string2 == "version") { - sscanf(line.c_str(), "-binary version = %d", &binary_verion); - } - std::cout << line << std::endl; - 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, binary_verion, function_info, - &ifs, m_gpgpu_sim, m_gpgpu_context, config); - - 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; -} - -const trace_warp_inst_t* trace_shd_warp_t::get_next_trace_inst() { - if (trace_pc < warp_traces.size()) { - return &warp_traces[trace_pc++]; - } else - return NULL; -} - -void trace_shd_warp_t::clear() { - trace_pc = 0; - warp_traces.clear(); -} - -// functional_done -bool trace_shd_warp_t::trace_done() { return trace_pc == (warp_traces.size()); } - -address_type trace_shd_warp_t::get_start_trace_pc() { - assert(warp_traces.size() > 0); - return warp_traces[0].pc; -} - -address_type trace_shd_warp_t::get_pc() { - assert(warp_traces.size() > 0); - assert(trace_pc < warp_traces.size()); - return warp_traces[trace_pc].pc; -} - -trace_kernel_info_t::trace_kernel_info_t(dim3 gridDim, dim3 blockDim, - unsigned m_binary_verion, - trace_function_info* m_function_info, - std::ifstream* inputstream, - gpgpu_sim* gpgpu_sim, - gpgpu_context* gpgpu_context, - class trace_config* config) - : kernel_info_t(gridDim, blockDim, m_function_info) { - ifs = inputstream; - m_gpgpu_sim = gpgpu_sim; - m_gpgpu_context = gpgpu_context; - binary_verion = m_binary_verion; - m_tconfig = config; - - // resolve the binary version - if (m_binary_verion == VOLTA_BINART_VERSION) - OpcodeMap = &Volta_OpcodeMap; - else if (m_binary_verion == PASCAL_TITANX_BINART_VERSION || - m_binary_verion == PASCAL_P100_BINART_VERSION) - OpcodeMap = &Pascal_OpcodeMap; - else if (m_binary_verion == KEPLER_BINART_VERSION) - OpcodeMap = &Kepler_OpcodeMap; - else if (m_binary_verion == TURING_BINART_VERSION) - OpcodeMap = &Turing_OpcodeMap; - else - assert(0 && "unsupported binary version"); -} - -bool trace_kernel_info_t::get_next_threadblock_traces( - std::vector*> threadblock_traces) { - for (unsigned i = 0; i < threadblock_traces.size(); ++i) { - threadblock_traces[i]->clear(); - } - - unsigned block_id_x = 0, block_id_y = 0, block_id_z = 0; - unsigned warp_id = 0; - unsigned insts_num = 0; - - bool start_of_tb_stream_found = false; - - while (!ifs->eof()) { - std::string line; - std::stringstream ss; - std::string string1, string2; - - 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); - std::cout << line << std::endl; - } 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]->reserve(insts_num); - } else { - assert(start_of_tb_stream_found); - trace_warp_inst_t inst(m_gpgpu_sim->getShaderCoreConfig(), - m_gpgpu_context, m_tconfig); - inst.parse_from_string(line, OpcodeMap); - threadblock_traces[warp_id]->push_back(inst); - } - } - } - - return true; -} - -bool trace_warp_inst_t::check_opcode_contain( - const std::vector& opcode, std::string param) { - for (unsigned i = 0; i < opcode.size(); ++i) - if (opcode[i] == param) return true; - - return false; -} - -unsigned trace_warp_inst_t::get_datawidth_from_opcode( - const std::vector& opcode) { - for (unsigned i = 0; i < opcode.size(); ++i) { - if (is_number(opcode[i])) { - return (std::stoi(opcode[i], NULL) / 8); - } else if (opcode[i][0] == 'U' && is_number(opcode[i].substr(1))) { - // handle the U* case - unsigned bits; - sscanf(opcode[i].c_str(), "U%u", &bits); - return bits / 8; - } - } - - return 4; // default is 4 bytes -} - -bool trace_warp_inst_t::parse_from_string( - std::string trace, - const std::unordered_map* OpcodeMap) { - 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[4]; - std::string opcode; - unsigned reg_dsts_num = 0; - unsigned reg_srcs_num = 0; - unsigned reg_srcs[4]; - unsigned mem_width = 0; - unsigned long long mem_addresses[warp_size()]; - unsigned address_mode = 0; - unsigned long long base_address = 0; - int stride = 0; - - // Start Parsing - ss >> std::dec >> threadblock_x >> threadblock_y >> threadblock_z >> - warpid_tb; - - // ignore core id - // ss>>std::dec>>sm_id>>warpid_sm; - - ss >> std::hex >> m_pc; - ss >> std::hex >> mask; - - std::bitset mask_bits(mask); - - ss >> std::dec >> reg_dsts_num; - for (unsigned i = 0; i < reg_dsts_num; ++i) { - ss >> std::dec >> temp; - sscanf(temp.c_str(), "R%d", ®_dest[i]); - } - - 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 - { - ss >> std::dec >> address_mode; - if (address_mode == 0) { - // read addresses one by one from the file - for (int s = 0; s < warp_size(); s++) { - if (mask_bits.test(s)) - ss >> std::hex >> mem_addresses[s]; - else - mem_addresses[s] = 0; - } - } else if (address_mode == 1) { - // read addresses as base address and stride - ss >> std::hex >> base_address; - ss >> std::dec >> stride; - bool first_bit1_found = false; - bool last_bit1_found = false; - unsigned long long addra = base_address; - for (int s = 0; s < warp_size(); s++) { - if (mask_bits.test(s) && !first_bit1_found) { - first_bit1_found = true; - mem_addresses[s] = base_address; - } else if (first_bit1_found && !last_bit1_found) { - if (mask_bits.test(s)) { - addra += stride; - mem_addresses[s] = addra; - } else - last_bit1_found = true; - } else - mem_addresses[s] = 0; - } - } - } - // Finish Parsing - // After parsing, fill the inst_t and warp_inst_t params - - // fill active mask - active_mask_t active_mask = mask_bits; - set_active(active_mask); - - // get the opcode - std::istringstream iss(opcode); - std::vector opcode_tokens; - std::string token; - while (std::getline(iss, token, '.')) { - if (!token.empty()) opcode_tokens.push_back(token); - } - - std::string opcode1 = opcode_tokens[0]; - - // fill and initialize common params - m_decoded = true; - pc = (address_type)m_pc; // we will lose the high 32 bits from casting long - // to unsigned, it should be okay! - - isize = - 16; // starting from MAXWELL isize=16 bytes (including the control bytes) - for (unsigned i = 0; i < MAX_OUTPUT_VALUES; i++) { - out[i] = 0; - } - for (unsigned i = 0; i < MAX_INPUT_VALUES; i++) { - in[i] = 0; - } - - is_vectorin = 0; - is_vectorout = 0; - ar1 = 0; - ar2 = 0; - memory_op = no_memory_op; - data_size = 0; - op = ALU_OP; - mem_op = NOT_TEX; - - std::unordered_map::const_iterator it = - OpcodeMap->find(opcode1); - if (it != OpcodeMap->end()) { - m_opcode = it->second.opcode; - op = (op_type)(it->second.opcode_category); - } else { - std::cout << "ERROR: undefined instruction : " << opcode - << " Opcode: " << opcode1 << std::endl; - assert(0 && "undefined instruction"); - } - - // fill regs information - num_regs = reg_srcs_num + reg_dsts_num; - num_operands = num_regs; - outcount = reg_dsts_num; - for (unsigned m = 0; m < reg_dsts_num; ++m) { - out[m] = reg_dest[m] + 1; // Increment by one because GPGPU-sim starts from - // R1, while SASS starts from R0 - arch_reg.dst[m] = reg_dest[m] + 1; - } - - incount = reg_srcs_num; - for (unsigned m = 0; m < reg_srcs_num; ++m) { - in[m] = reg_srcs[m] + 1; // Increment by one because GPGPU-sim starts from - // R1, while SASS starts from R0 - arch_reg.src[m] = reg_srcs[m] + 1; - } - // TO DO: handle: vector, store insts have no output, double inst and hmma, - // and 64 bit address remove redundant registers - - // fill latency and initl - m_tconfig->set_latency(op, latency, initiation_interval); - - // fill addresses - if (mem_width > 0) { - for (unsigned i = 0; i < warp_size(); ++i) set_addr(i, mem_addresses[i]); - } - - // handle special cases and fill memory space - switch (m_opcode) { - case OP_LDG: - case OP_LDL: - assert(mem_width > 0); - // Nvbit reports incorrect data width, and we have to parse the opcode to - // get the correct data width - data_size = get_datawidth_from_opcode(opcode_tokens); - memory_op = memory_load; - cache_op = CACHE_ALL; - if (m_opcode == OP_LDL) - space.set_type(local_space); - else - space.set_type(global_space); - // check the cache scope, if its strong GPU, then bypass L1 - if (check_opcode_contain(opcode_tokens, "STRONG") && - check_opcode_contain(opcode_tokens, "GPU")) { - cache_op = CACHE_GLOBAL; - } - break; - case OP_STG: - case OP_STL: - case OP_ATOMG: - case OP_RED: - case OP_ATOM: - assert(mem_width > 0); - data_size = get_datawidth_from_opcode(opcode_tokens); - memory_op = memory_store; - cache_op = CACHE_ALL; - if (m_opcode == OP_STL) - space.set_type(local_space); - else - space.set_type(global_space); - - if (m_opcode == OP_ATOMG || m_opcode == OP_ATOM || m_opcode == OP_RED) { - m_isatomic = true; - memory_op = memory_load; - op = LOAD_OP; - cache_op = CACHE_GLOBAL; - - // ATOMIC writes to the first operand, we missed that in the trace so we - // fixed it here. TO be fixed in tracer - outcount = reg_dsts_num + 1; - out[0] = in[0]; // Increment by one because GPGPU-sim starts from R1, - // while SASS starts from R0 - arch_reg.dst[0] = reg_srcs[0]; - num_regs = reg_srcs_num + reg_dsts_num + 1; - num_operands = num_regs; - } - - break; - case OP_LDS: - case OP_STS: - case OP_ATOMS: - assert(mem_width > 0); - data_size = mem_width; - space.set_type(shared_space); - if (m_opcode == OP_ATOMS || m_opcode == OP_LDS) { - // m_isatomic = true; - op = LOAD_OP; - memory_op = memory_load; - } - break; - case OP_ST: - case OP_LD: - // TO DO: set generic load based on the address - // right now, we consider all loads are shared. - assert(mem_width > 0); - data_size = get_datawidth_from_opcode(opcode_tokens); - space.set_type(shared_space); - if (m_opcode == OP_LD) - memory_op = memory_load; - else - memory_op = memory_store; - break; - case OP_BAR: - // TO DO: fill this correctly - bar_id = 0; - bar_count = (unsigned)-1; - bar_type = SYNC; - // TO DO - // if bar_type = RED; - // set bar_type - // barrier_type bar_type; - // reduction_type red_type; - break; - case OP_HADD2: - case OP_HADD2_32I: - case OP_HFMA2: - case OP_HFMA2_32I: - case OP_HMUL2_32I: - case OP_HSET2: - case OP_HSETP2: - initiation_interval = - initiation_interval / 2; // FP16 has 2X throughput than FP32 - break; - default: - break; - } - - return true; -} - -trace_config::trace_config() {} - -void trace_config::reg_options(option_parser_t opp) { - option_parser_register(opp, "-trace", OPT_CSTR, &g_traces_filename, - "traces kernel file" - "traces kernel file directory", - "./traces/kernelslist.g"); - - option_parser_register(opp, "-trace_opcode_latency_initiation_int", OPT_CSTR, - &trace_opcode_latency_initiation_int, - "Opcode latencies and initiation for integers in " - "trace driven mode ", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_sp", OPT_CSTR, - &trace_opcode_latency_initiation_sp, - "Opcode latencies and initiation for sp in trace " - "driven mode ", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_dp", OPT_CSTR, - &trace_opcode_latency_initiation_dp, - "Opcode latencies and initiation for dp in trace " - "driven mode ", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_sfu", OPT_CSTR, - &trace_opcode_latency_initiation_sfu, - "Opcode latencies and initiation for sfu in trace " - "driven mode ", - "4,1"); - option_parser_register(opp, "-trace_opcode_latency_initiation_tensor", - OPT_CSTR, &trace_opcode_latency_initiation_tensor, - "Opcode latencies and initiation for tensor in trace " - "driven mode ", - "4,1"); - - for (unsigned j = 0; j < SPECIALIZED_UNIT_NUM; ++j) { - std::stringstream ss; - ss << "-trace_opcode_latency_initiation_spec_op_" << j + 1; - option_parser_register(opp, ss.str().c_str(), OPT_CSTR, - &trace_opcode_latency_initiation_specialized_op[j], - "specialized unit config" - " ", - "4,4"); - } -} - -void trace_config::parse_config() { - sscanf(trace_opcode_latency_initiation_int, "%u,%u", &int_latency, &int_init); - sscanf(trace_opcode_latency_initiation_sp, "%u,%u", &fp_latency, &fp_init); - sscanf(trace_opcode_latency_initiation_dp, "%u,%u", &dp_latency, &dp_init); - sscanf(trace_opcode_latency_initiation_sfu, "%u,%u", &sfu_latency, &sfu_init); - sscanf(trace_opcode_latency_initiation_tensor, "%u,%u", &tensor_latency, - &tensor_init); - - for (unsigned j = 0; j < SPECIALIZED_UNIT_NUM; ++j) { - sscanf(trace_opcode_latency_initiation_specialized_op[j], "%u,%u", - &specialized_unit_latency[j], &specialized_unit_initiation[j]); - } -} -void trace_config::set_latency(unsigned category, unsigned& latency, - unsigned& initiation_interval) { - initiation_interval = latency = 1; - - switch (category) { - case ALU_OP: - case INTP_OP: - case BRANCH_OP: - case CALL_OPS: - case RET_OPS: - latency = int_latency; - initiation_interval = int_init; - break; - case SP_OP: - latency = fp_latency; - initiation_interval = fp_init; - break; - case DP_OP: - latency = dp_latency; - initiation_interval = dp_init; - break; - case SFU_OP: - latency = sfu_latency; - initiation_interval = sfu_init; - break; - case TENSOR_CORE_OP: - latency = tensor_latency; - initiation_interval = tensor_init; - break; - default: - break; - } - // for specialized units - if (category >= SPEC_UNIT_START_ID) { - unsigned spec_id = category - SPEC_UNIT_START_ID; - assert(spec_id >= 0 && spec_id < SPECIALIZED_UNIT_NUM); - latency = specialized_unit_latency[spec_id]; - initiation_interval = specialized_unit_initiation[spec_id]; - } -} - -void trace_gpgpu_sim::createSIMTCluster() { - m_cluster = new simt_core_cluster*[m_shader_config->n_simt_clusters]; - for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) - m_cluster[i] = - new trace_simt_core_cluster(this, i, m_shader_config, m_memory_config, - m_shader_stats, m_memory_stats); -} - -void trace_simt_core_cluster::create_shader_core_ctx() { - m_core = new shader_core_ctx*[m_config->n_simt_cores_per_cluster]; - for (unsigned i = 0; i < m_config->n_simt_cores_per_cluster; i++) { - unsigned sid = m_config->cid_to_sid(i, m_cluster_id); - m_core[i] = new trace_shader_core_ctx(m_gpu, this, sid, m_cluster_id, - m_config, m_mem_config, m_stats); - m_core_sim_order.push_back(i); - } -} - -void trace_shader_core_ctx::create_shd_warp() { - m_warp.resize(m_config->max_warps_per_shader); - for (unsigned k = 0; k < m_config->max_warps_per_shader; ++k) { - m_warp[k] = new trace_shd_warp_t(this, m_config->warp_size); - } -} - -void trace_shader_core_ctx::get_pdom_stack_top_info(unsigned warp_id, - const warp_inst_t* pI, - unsigned* pc, - unsigned* rpc) { - // In trace-driven mode, we assume no control hazard - *pc = pI->pc; - *rpc = pI->pc; -} - -const active_mask_t& trace_shader_core_ctx::get_active_mask( - unsigned warp_id, const warp_inst_t* pI) { - // For Trace-driven, the active mask already set in traces, so - // just read it from the inst - return pI->get_active_mask(); -} - -unsigned trace_shader_core_ctx::sim_init_thread( - kernel_info_t& kernel, ptx_thread_info** thread_info, int sid, unsigned tid, - unsigned threads_left, unsigned num_threads, core_t* core, - unsigned hw_cta_id, unsigned hw_warp_id, gpgpu_t* gpu) { - if (kernel.no_more_ctas_to_run()) { - return 0; // finished! - } - - if (kernel.more_threads_in_cta()) { - kernel.increment_thread_id(); - } - - if (!kernel.more_threads_in_cta()) kernel.increment_cta_id(); - - return 1; -} - -void trace_shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread, - unsigned end_thread, unsigned ctaid, - int cta_size, kernel_info_t& kernel) { - // call base class - shader_core_ctx::init_warps(cta_id, start_thread, end_thread, ctaid, cta_size, - kernel); - - // then init traces - unsigned start_warp = start_thread / m_config->warp_size; - unsigned end_warp = end_thread / m_config->warp_size + - ((end_thread % m_config->warp_size) ? 1 : 0); - - init_traces(start_warp, end_warp, kernel); -} - -const warp_inst_t* trace_shader_core_ctx::get_next_inst(unsigned warp_id, - address_type pc) { - // read the inst from the traces - trace_shd_warp_t* m_trace_warp = - static_cast(m_warp[warp_id]); - return m_trace_warp->get_next_trace_inst(); -} - -void trace_shader_core_ctx::updateSIMTStack(unsigned warpId, - warp_inst_t* inst) { - // No SIMT-stack in trace-driven mode -} - -void trace_shader_core_ctx::init_traces(unsigned start_warp, unsigned end_warp, - kernel_info_t& kernel) { - std::vector*> threadblock_traces; - for (unsigned i = start_warp; i < end_warp; ++i) { - trace_shd_warp_t* m_trace_warp = static_cast(m_warp[i]); - m_trace_warp->clear(); - threadblock_traces.push_back(&(m_trace_warp->warp_traces)); - } - trace_kernel_info_t& trace_kernel = static_cast(kernel); - trace_kernel.get_next_threadblock_traces(threadblock_traces); - - // set the pc from the traces and ignore the functional model - for (unsigned i = start_warp; i < end_warp; ++i) { - trace_shd_warp_t* m_trace_warp = static_cast(m_warp[i]); - m_trace_warp->set_next_pc(m_trace_warp->get_start_trace_pc()); - } -} - -void trace_shader_core_ctx::checkExecutionStatusAndUpdate(warp_inst_t& inst, - unsigned t, - unsigned tid) { - if (inst.isatomic()) m_warp[inst.warp_id()]->inc_n_atomic(); - - if (inst.op == EXIT_OPS) { - m_warp[inst.warp_id()]->set_completed(t); - } -} - -void trace_shader_core_ctx::func_exec_inst(warp_inst_t& inst) { - // here, we generate memory acessess and set the status if thread (done?) - if (inst.is_load() || inst.is_store()) { - inst.generate_mem_accesses(); - } - for (unsigned t = 0; t < m_warp_size; t++) { - if (inst.active(t)) { - unsigned warpId = inst.warp_id(); - unsigned tid = m_warp_size * warpId + t; - - // virtual function - checkExecutionStatusAndUpdate(inst, t, tid); - } - } - trace_shd_warp_t* m_trace_warp = - static_cast(m_warp[inst.warp_id()]); - if (m_trace_warp->trace_done() && m_trace_warp->functional_done()) { - m_trace_warp->ibuffer_flush(); - m_barriers.warp_exit(inst.warp_id()); - } -} diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h deleted file mode 100644 index 3af99c3..0000000 --- a/src/trace-driven/trace_driven.h +++ /dev/null @@ -1,210 +0,0 @@ -// developed by Mahmoud Khairy, Purdue Univ - -#include -#include -#include - -#ifndef TRACE_DRIVEN_H -#define TRACE_DRIVEN_H - -#include "../abstract_hardware_model.h" -#include "../gpgpu-sim/shader.h" -#include "ISA_Def/trace_opcode.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; - } - - virtual ~trace_function_info() {} -}; - -class trace_warp_inst_t : public warp_inst_t { - public: - trace_warp_inst_t() { - m_gpgpu_context = NULL; - m_opcode = 0; - m_tconfig = NULL; - should_do_atomic = false; - } - - trace_warp_inst_t(const class core_config* config, - gpgpu_context* gpgpu_context, class trace_config* tconfig) - : warp_inst_t(config) { - m_gpgpu_context = gpgpu_context; - m_opcode = 0; - m_tconfig = tconfig; - should_do_atomic = false; - } - - bool parse_from_string( - std::string trace, - const std::unordered_map* OpcodeMap); - - private: - gpgpu_context* m_gpgpu_context; - class trace_config* m_tconfig; - unsigned m_opcode; - bool check_opcode_contain(const std::vector& opcode, - std::string param); - unsigned get_datawidth_from_opcode(const std::vector& opcode); -}; - -class trace_kernel_info_t : public kernel_info_t { - public: - trace_kernel_info_t(dim3 gridDim, dim3 blockDim, unsigned m_binary_verion, - trace_function_info* m_function_info, - std::ifstream* inputstream, gpgpu_sim* gpgpu_sim, - gpgpu_context* gpgpu_context, class trace_config* config); - - bool get_next_threadblock_traces( - std::vector*> threadblock_traces); - - private: - std::ifstream* ifs; - gpgpu_sim* m_gpgpu_sim; - gpgpu_context* m_gpgpu_context; - trace_config* m_tconfig; - unsigned binary_verion; - const std::unordered_map* OpcodeMap; -}; - -class trace_config { - public: - trace_config(); - - void set_latency(unsigned category, unsigned& latency, - unsigned& initiation_interval); - void parse_config(); - void reg_options(option_parser_t opp); - char* get_traces_filename() { return g_traces_filename; } - - private: - unsigned int_latency, fp_latency, dp_latency, sfu_latency, tensor_latency; - unsigned int_init, fp_init, dp_init, sfu_init, tensor_init; - unsigned specialized_unit_latency[SPECIALIZED_UNIT_NUM]; - unsigned specialized_unit_initiation[SPECIALIZED_UNIT_NUM]; - - char* g_traces_filename; - char* trace_opcode_latency_initiation_int; - char* trace_opcode_latency_initiation_sp; - char* trace_opcode_latency_initiation_dp; - char* trace_opcode_latency_initiation_sfu; - char* trace_opcode_latency_initiation_tensor; - char* trace_opcode_latency_initiation_specialized_op[SPECIALIZED_UNIT_NUM]; -}; - -class trace_parser { - public: - trace_parser(const char* kernellist_filepath, gpgpu_sim* m_gpgpu_sim, - gpgpu_context* m_gpgpu_context); - - std::vector parse_kernellist_file(); - trace_kernel_info_t* parse_kernel_info( - const std::string& kerneltraces_filepath, trace_config* config); - void parse_memcpy_info(const std::string& memcpy_command, size_t& add, - size_t& count); - - 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) { - trace_pc = 0; - } - - std::vector warp_traces; - const trace_warp_inst_t* get_next_trace_inst(); - void clear(); - bool trace_done(); - address_type get_start_trace_pc(); - virtual address_type get_pc(); - - private: - unsigned trace_pc; -}; - -class trace_gpgpu_sim : public gpgpu_sim { - public: - trace_gpgpu_sim(const gpgpu_sim_config& config, gpgpu_context* ctx) - : gpgpu_sim(config, ctx) { - createSIMTCluster(); - } - - virtual void createSIMTCluster(); -}; - -class trace_simt_core_cluster : public simt_core_cluster { - public: - trace_simt_core_cluster(class gpgpu_sim* gpu, unsigned cluster_id, - const shader_core_config* config, - const memory_config* mem_config, - class shader_core_stats* stats, - class memory_stats_t* mstats) - : simt_core_cluster(gpu, cluster_id, config, mem_config, stats, mstats) { - create_shader_core_ctx(); - } - - virtual void create_shader_core_ctx(); -}; - -class trace_shader_core_ctx : public shader_core_ctx { - public: - trace_shader_core_ctx(class gpgpu_sim* gpu, class simt_core_cluster* cluster, - unsigned shader_id, unsigned tpc_id, - const shader_core_config* config, - const memory_config* mem_config, - shader_core_stats* stats) - : shader_core_ctx(gpu, cluster, shader_id, tpc_id, config, mem_config, - stats) { - create_front_pipeline(); - create_shd_warp(); - create_schedulers(); - create_exec_pipeline(); - } - - virtual void checkExecutionStatusAndUpdate(warp_inst_t& inst, unsigned t, - unsigned tid); - virtual void init_warps(unsigned cta_id, unsigned start_thread, - unsigned end_thread, unsigned ctaid, int cta_size, - kernel_info_t& kernel); - virtual void func_exec_inst(warp_inst_t& inst); - virtual unsigned sim_init_thread(kernel_info_t& kernel, - ptx_thread_info** thread_info, int sid, - unsigned tid, unsigned threads_left, - unsigned num_threads, core_t* core, - unsigned hw_cta_id, unsigned hw_warp_id, - gpgpu_t* gpu); - virtual void create_shd_warp(); - virtual const warp_inst_t* get_next_inst(unsigned warp_id, address_type pc); - virtual void updateSIMTStack(unsigned warpId, warp_inst_t* inst); - virtual void get_pdom_stack_top_info(unsigned warp_id, const warp_inst_t* pI, - unsigned* pc, unsigned* rpc); - virtual const active_mask_t& get_active_mask(unsigned warp_id, - const warp_inst_t* pI); - - private: - void init_traces(unsigned start_warp, unsigned end_warp, - kernel_info_t& kernel); -}; - -#endif -- cgit v1.3 From 7af8ce609ce0b9a9c92c92c140e83ade116d9370 Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 1 Jun 2020 20:10:03 -0400 Subject: fixing the dram assert due to hashing error --- src/gpgpu-sim/addrdec.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc index c01b8fa..19714ec 100644 --- a/src/gpgpu-sim/addrdec.cc +++ b/src/gpgpu-sim/addrdec.cc @@ -154,7 +154,7 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, sub_partition = sub_partition % (m_n_channel * m_n_sub_partition_in_channel); - tlx->chip = sub_partition / m_n_channel; + tlx->chip = sub_partition / m_n_sub_partition_in_channel; tlx->sub_partition = sub_partition; assert(tlx->chip < m_n_channel); assert(tlx->sub_partition < m_n_channel * m_n_sub_partition_in_channel); -- cgit v1.3 From 1af6e1b6ace58c8b874660e2c371f9c2adfdb7ce Mon Sep 17 00:00:00 2001 From: Mahmoud Date: Mon, 1 Jun 2020 20:26:27 -0400 Subject: adding my name --- src/gpgpu-sim/hashing.cc | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/gpgpu-sim/hashing.cc b/src/gpgpu-sim/hashing.cc index 003755c..f566aa4 100644 --- a/src/gpgpu-sim/hashing.cc +++ b/src/gpgpu-sim/hashing.cc @@ -1,30 +1,5 @@ -// Copyright (c) 2009-2011, Wilson W.L. Fung, Tor M. Aamodt, Ali Bakhoda, -// The University of British Columbia -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. Neither the name of -// The University of British Columbia nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. +// author: Mahmoud Khairy, (Purdue Univ) +// email: abdallm@purdue.edu #include #include -- cgit v1.3 From 4d64f31587569d4e8800aa81ececb9e809817d78 Mon Sep 17 00:00:00 2001 From: tgrogers Date: Sat, 27 Jun 2020 08:56:16 -0400 Subject: Getting rid of a warning --- src/gpgpu-sim/shader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 65c8937..07cd2d0 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1468,7 +1468,7 @@ class shader_core_config : public core_config { specialized_unit_params sparam; sscanf(specialized_unit_string[i], "%u,%u,%u,%u,%u,%s", &enabled, &sparam.num_units, &sparam.latency, &sparam.id_oc_spec_reg_width, - &sparam.oc_ex_spec_reg_width, &sparam.name); + &sparam.oc_ex_spec_reg_width, sparam.name); if (enabled) { m_specialized_unit.push_back(sparam); -- cgit v1.3