aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/abstract_hardware_model.cc4
-rw-r--r--src/abstract_hardware_model.h9
-rw-r--r--src/cuda-sim/ptx_ir.h10
-rw-r--r--src/cuda-sim/ptx_loader.cc2
-rw-r--r--src/cuda-sim/ptx_parser.cc4
-rw-r--r--src/gpgpu-sim/addrdec.cc4
-rw-r--r--src/gpgpu-sim/gpu-cache.cc7
-rw-r--r--src/gpgpu-sim/gpu-cache.h5
-rw-r--r--src/gpgpu-sim/gpu-sim.cc11
-rw-r--r--src/gpgpu-sim/gpu-sim.h7
-rw-r--r--src/gpgpu-sim/shader.cc54
-rw-r--r--src/gpgpusim_entrypoint.cc31
-rw-r--r--src/trace-driven/gpgpusim_trace_driven_main.cc356
-rw-r--r--src/trace-driven/trace_driven.h94
14 files changed, 563 insertions, 35 deletions
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index 07232ee..e8e4b51 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -729,7 +729,7 @@ kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *
//Jin: launch latency management
m_launch_latency = entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency;
- volta_cache_config_set=false;
+ cache_config_set=false;
}
/*A snapshot of the texture mappings needs to be stored in the kernel's info as
@@ -754,7 +754,7 @@ kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *
//Jin: launch latency management
m_launch_latency = entry->gpgpu_ctx->device_runtime->g_kernel_launch_latency;
- volta_cache_config_set=false;
+ cache_config_set=false;
m_NameToCudaArray = nameToCudaArray;
m_NameToTextureInfo = nameToTextureInfo;
}
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index 29e4a30..341e44c 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -67,6 +67,11 @@ enum FuncCache
FuncCachePreferL1 = 2
};
+enum AdaptiveCache
+{
+ FIXED = 0,
+ VOLTA = 1
+};
#ifdef __cplusplus
@@ -344,7 +349,7 @@ public:
unsigned long long end_cycle;
unsigned m_launch_latency;
- mutable bool volta_cache_config_set;
+ mutable bool cache_config_set;
};
class core_config {
@@ -391,7 +396,7 @@ class core_config {
unsigned gpgpu_max_insn_issue_per_warp;
bool gmem_skip_L1D; // on = global memory access always skip the L1 cache
- bool adaptive_volta_cache_config;
+ unsigned adaptive_cache_config;
};
// bounded stack that implements simt reconvergence using pdom mechanism from MICRO'07 paper
diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h
index f4c5c37..8ceb60b 100644
--- a/src/cuda-sim/ptx_ir.h
+++ b/src/cuda-sim/ptx_ir.h
@@ -1354,13 +1354,13 @@ public:
void list_param( FILE *fout ) const;
void ptx_jit_config(std::map<unsigned long long, size_t> mallocPtr_Size, memory_space *param_mem, gpgpu_t* gpu, dim3 gridDim, dim3 blockDim) ;
- const struct gpgpu_ptx_sim_info* get_kernel_info () const
+ virtual const struct gpgpu_ptx_sim_info* get_kernel_info () const
{
assert (m_kernel_info.maxthreads == maxnt_id);
return &m_kernel_info;
}
- const void set_kernel_info (const struct gpgpu_ptx_sim_info &info) {
+ virtual const void set_kernel_info (const struct gpgpu_ptx_sim_info &info) {
m_kernel_info = info;
m_kernel_info.ptx_version = 10*get_ptx_version().ver();
m_kernel_info.sm_target = get_ptx_version().target();
@@ -1401,6 +1401,10 @@ public:
// backward pointer
class gpgpu_context* gpgpu_ctx;
+protected:
+ //Registers/shmem/etc. used (from ptxas -v), loaded from ___.ptxinfo along with ___.ptx
+ struct gpgpu_ptx_sim_info m_kernel_info;
+
private:
unsigned maxnt_id;
unsigned m_uid;
@@ -1424,8 +1428,6 @@ private:
std::map<std::string,unsigned> labels;
unsigned num_reconvergence_pairs;
- //Registers/shmem/etc. used (from ptxas -v), loaded from ___.ptxinfo along with ___.ptx
- struct gpgpu_ptx_sim_info m_kernel_info;
symbol_table *m_symtab;
diff --git a/src/cuda-sim/ptx_loader.cc b/src/cuda-sim/ptx_loader.cc
index 33bcf45..f06fefd 100644
--- a/src/cuda-sim/ptx_loader.cc
+++ b/src/cuda-sim/ptx_loader.cc
@@ -37,7 +37,7 @@
/// extern prototypes
-extern int ptx_error( yyscan_t yyscanner, const char *s );
+extern int ptx_error( yyscan_t yyscanner, ptx_recognizer* recognizer, const char *s );
extern int ptx_lex_init(yyscan_t* scanner);
extern void ptx_set_in(FILE * _in_str ,yyscan_t yyscanner );
extern int ptx_parse(yyscan_t scanner, ptx_recognizer* recognizer);
diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc
index a4f4a0c..24af3ad 100644
--- a/src/cuda-sim/ptx_parser.cc
+++ b/src/cuda-sim/ptx_parser.cc
@@ -35,7 +35,7 @@ typedef void * yyscan_t;
extern int ptx_get_lineno (yyscan_t yyscanner );
extern YYSTYPE* ptx_get_lval (yyscan_t yyscanner );
-extern int ptx_error( yyscan_t yyscanner, const char *s );
+extern int ptx_error( yyscan_t yyscanner, ptx_recognizer* recognizer, const char *s );
extern int ptx_lex_init(yyscan_t* scanner);
extern void ptx_set_in(FILE * _in_str ,yyscan_t yyscanner );
extern FILE *ptx_get_in (yyscan_t yyscanner );
@@ -226,7 +226,7 @@ void ptx_recognizer::parse_error_impl( const char *file, unsigned line, const ch
g_error_detected = 1;
printf("%s:%u: Parse error: %s (%s:%u)\n\n", gpgpu_ctx->g_filename, ptx_get_lineno(scanner), buf, file, line);
- ptx_error(scanner, NULL);
+ ptx_error(scanner, this, NULL);
abort();
exit(1);
}
diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc
index e3713f3..f225933 100644
--- a/src/gpgpu-sim/addrdec.cc
+++ b/src/gpgpu-sim/addrdec.cc
@@ -124,8 +124,8 @@ void linear_to_raw_address_translation::addrdec_tlx(new_addr_type addr, addrdec_
* Rau, B. R et al.
* ISCA 1991
*
- * equations are adopted from:
- * "Sacat: streaming-aware conflict-avoiding thrashing-resistant gpgpu cache management scheme."
+ * equations are corresponding to IPOLY(37) and are adopted from:
+ * "SACAT: streaming-aware conflict-avoiding thrashing-resistant gpgpu cache management scheme."
* Khairy et al.
* IEEE TPDS 2017.
*/
diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc
index 1e99fec..65f2f6d 100644
--- a/src/gpgpu-sim/gpu-cache.cc
+++ b/src/gpgpu-sim/gpu-cache.cc
@@ -66,8 +66,13 @@ const char * cache_fail_status_str(enum cache_reservation_fail_reason status)
unsigned l1d_cache_config::set_bank(new_addr_type addr) const{
- if(m_cache_type == SECTOR)
+ //For sector cache, we select one sector per bank (sector interleaving)
+ //This is what was found in Volta (one sector per bank, sector interleaving)
+ //otherwise, line interleaving
+ if(m_cache_type == SECTOR) {
+ //assert(l1_banks == SECTOR_CHUNCK_SIZE);
return (addr >> m_sector_sz_log2) & (l1_banks-1);
+ }
else
return (addr >> m_line_sz_log2) & (l1_banks-1);
}
diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h
index 6f39221..b7d0400 100644
--- a/src/gpgpu-sim/gpu-cache.h
+++ b/src/gpgpu-sim/gpu-cache.h
@@ -656,6 +656,11 @@ public:
assert( m_valid );
return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER * m_nset * original_m_assoc;
}
+ unsigned get_max_assoc() const
+ {
+ assert( m_valid );
+ return MAX_DEFAULT_CACHE_SIZE_MULTIBLIER * original_m_assoc;
+ }
void print( FILE *fp ) const
{
fprintf( fp, "Size = %d B (%d Set x %d-way x %d byte line)\n",
diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc
index 56ea8c4..a70185e 100644
--- a/src/gpgpu-sim/gpu-sim.cc
+++ b/src/gpgpu-sim/gpu-sim.cc
@@ -305,7 +305,7 @@ void shader_core_config::reg_options(class OptionParser * opp)
option_parser_register(opp, "-gpgpu_shmem_size", OPT_UINT32, &gpgpu_shmem_size,
"Size of shared memory per shader core (default 16kB)",
"16384");
- option_parser_register(opp, "-adaptive_cache_config", OPT_BOOL, &adaptive_volta_cache_config,
+ option_parser_register(opp, "-adaptive_cache_config", OPT_UINT32, &adaptive_cache_config,
"adaptive_cache_config",
"0");
option_parser_register(opp, "-gpgpu_shmem_sizeDefault", OPT_UINT32, &gpgpu_shmem_sizeDefault,
@@ -560,6 +560,15 @@ void gpgpu_sim_config::reg_options(option_parser_t opp)
option_parser_register(opp, "-gpgpu_cdp_enabled", OPT_BOOL,
&(gpgpu_ctx->device_runtime->g_cdp_enabled), "Turn on CDP",
"0");
+
+ //Trace driven mode parameters
+ option_parser_register(opp, "-trace_driven_mode", OPT_BOOL,
+ &trace_driven_mode, "Turn on trace_driven_mode",
+ "0");
+ option_parser_register(opp, "-trace", OPT_CSTR,
+ &g_traces_filename, "traces kernel file"
+ "traces kernel file directory",
+ "./traces/kernelslist.g");
}
/////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h
index fba770d..86d6206 100644
--- a/src/gpgpu-sim/gpu-sim.h
+++ b/src/gpgpu-sim/gpu-sim.h
@@ -348,6 +348,9 @@ public:
size_t sync_depth_limit() const {return runtime_sync_depth_limit; }
size_t pending_launch_count_limit() const {return runtime_pending_launch_count_limit;}
+ unsigned is_trace_driven_mode() const { return trace_driven_mode; }
+ char* get_traces_filename() const { return g_traces_filename; }
+
private:
void init_clock_domains(void );
@@ -401,6 +404,10 @@ private:
unsigned int gpgpu_compute_capability_minor;
unsigned long long liveness_message_freq;
+ //trace driven mode options
+ bool trace_driven_mode;
+ char *g_traces_filename;
+
friend class gpgpu_sim;
};
diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc
index 6a0e3d6..86508f6 100644
--- a/src/gpgpu-sim/shader.cc
+++ b/src/gpgpu-sim/shader.cc
@@ -2994,33 +2994,47 @@ unsigned int shader_core_config::max_cta( const kernel_info_t &k ) const
abort();
}
- if(adaptive_volta_cache_config && !k.volta_cache_config_set) {
- //For Volta, we assign the remaining shared memory to L1 cache
- //For more info, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x
+ if(adaptive_cache_config && !k.cache_config_set) {
+ //For more info about adaptive cache, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x
unsigned total_shmed = kernel_info->smem * result;
assert(total_shmed >=0 && total_shmed <= gpgpu_shmem_size);
- assert(gpgpu_shmem_size == 98304); //Volta has 96 KB shared
- assert(m_L1D_config.get_nset() == 4); //Volta L1 has four sets
+ //assert(gpgpu_shmem_size == 98304); //Volta has 96 KB shared
+ //assert(m_L1D_config.get_nset() == 4); //Volta L1 has four sets
if(total_shmed < gpgpu_shmem_size){
- if(total_shmed == 0)
- m_L1D_config.set_assoc(256); //L1 is 128KB ans shd=0
- else if(total_shmed > 0 && total_shmed <= 8192)
- m_L1D_config.set_assoc(240); //L1 is 120KB ans shd=8KB
- else if(total_shmed > 8192 && total_shmed <= 16384)
- m_L1D_config.set_assoc(224); //L1 is 112KB ans shd=16KB
- else if(total_shmed > 16384 && total_shmed <= 32768)
- m_L1D_config.set_assoc(192); //L1 is 96KB ans shd=32KB
- else if(total_shmed > 32768 && total_shmed <= 65536)
- m_L1D_config.set_assoc(128); //L1 is 64KB ans shd=64KB
- else if(total_shmed > 65536 && total_shmed <= gpgpu_shmem_size)
- m_L1D_config.set_assoc(64); //L1 is 32KB and shd=96KB
- else
+ switch (adaptive_cache_config) {
+ case FIXED:
+ break;
+ case VOLTA: {
+ //For Volta, we assign the remaining shared memory to L1 cache
+ //For more info about adaptive cache, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x
+ assert(gpgpu_shmem_size == 98304); //Volta has 96 KB shared
+
+ //To Do: make it flexible and not tuned to 9KB share memory
+ unsigned max_assoc = m_L1D_config.get_max_assoc();
+ if(total_shmed == 0)
+ m_L1D_config.set_assoc(max_assoc); //L1 is 128KB and shd=0
+ else if(total_shmed > 0 && total_shmed <= 8192)
+ m_L1D_config.set_assoc(0.9375 * max_assoc); //L1 is 120KB and shd=8KB
+ else if(total_shmed > 8192 && total_shmed <= 16384)
+ m_L1D_config.set_assoc(0.875 * max_assoc); //L1 is 112KB and shd=16KB
+ else if(total_shmed > 16384 && total_shmed <= 32768)
+ m_L1D_config.set_assoc(0.75 * max_assoc); //L1 is 96KB and shd=32KB
+ else if(total_shmed > 32768 && total_shmed <= 65536)
+ m_L1D_config.set_assoc(0.5 * max_assoc); //L1 is 64KB and shd=64KB
+ else if(total_shmed > 65536 && total_shmed <= gpgpu_shmem_size)
+ m_L1D_config.set_assoc(0.25 * max_assoc); //L1 is 32KB and shd=96KB
+ else
+ assert(0);
+ break;
+ }
+ default:
assert(0);
+ }
- printf ("GPGPU-Sim: Reconfigure L1 cache in Volta Archi to %uKB\n", m_L1D_config.get_total_size_inKB());
+ printf ("GPGPU-Sim: Reconfigure L1 cache to %uKB\n", m_L1D_config.get_total_size_inKB());
}
- k.volta_cache_config_set = true;
+ k.cache_config_set = true;
}
return result;
diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc
index 846773d..69cc1b0 100644
--- a/src/gpgpusim_entrypoint.cc
+++ b/src/gpgpusim_entrypoint.cc
@@ -225,6 +225,37 @@ gpgpu_sim *gpgpu_context::gpgpu_ptx_sim_init_perf()
return the_gpgpusim->g_the_gpu;
}
+gpgpu_sim *gpgpu_context::gpgpu_trace_sim_init_perf(int argc, const char *argv[])
+{
+ srand(1);
+ print_splash();
+ func_sim->read_sim_environment_variables();
+ ptx_parser->read_parser_environment_variables();
+ option_parser_t opp = option_parser_create();
+
+ ptx_reg_options(opp);
+ func_sim->ptx_opcocde_latency_options(opp);
+
+ icnt_reg_options(opp);
+ the_gpgpusim->g_the_gpu_config = new gpgpu_sim_config(this);
+ the_gpgpusim->g_the_gpu_config->reg_options(opp); // register GPU microrachitecture options
+
+ option_parser_cmdline(opp, argc, argv); // parse configuration options
+ fprintf(stdout, "GPGPU-Sim: Configuration options:\n\n");
+ option_parser_print(opp, stdout);
+ // Set the Numeric locale to a standard locale where a decimal point is a "dot" not a "comma"
+ // so it does the parsing correctly independent of the system environment variables
+ assert(setlocale(LC_NUMERIC,"C"));
+ the_gpgpusim->g_the_gpu_config->init();
+
+ the_gpgpusim->g_the_gpu = new gpgpu_sim(*(the_gpgpusim->g_the_gpu_config), this);
+ the_gpgpusim->g_stream_manager = new stream_manager((the_gpgpusim->g_the_gpu), func_sim->g_cuda_launch_blocking);
+
+ the_gpgpusim->g_simulation_starttime = time((time_t *)NULL);
+
+ return the_gpgpusim->g_the_gpu;
+}
+
void gpgpu_context::start_sim_thread(int api)
{
if( the_gpgpusim->g_sim_done ) {
diff --git a/src/trace-driven/gpgpusim_trace_driven_main.cc b/src/trace-driven/gpgpusim_trace_driven_main.cc
new file mode 100644
index 0000000..4f973cd
--- /dev/null
+++ b/src/trace-driven/gpgpusim_trace_driven_main.cc
@@ -0,0 +1,356 @@
+//developed by Mahmoud Khairy, Purdue Univ
+
+//#include "../abstract_hardware_model.h"
+#include <time.h>
+#include <stdio.h>
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <sstream>
+#include <stdio.h>
+#include <math.h>
+
+
+//#include "../option_parser.h"
+//#include "../cuda-sim/cuda-sim.h"
+//#include "../cuda-sim/ptx_ir.h"
+//#include "../cuda-sim/ptx_parser.h"
+#include "../gpgpu-sim/gpu-sim.h"
+//#include "../gpgpu-sim/icnt_wrapper.h"
+//#include "../gpgpu-sim/icnt_wrapper.h"
+#include "../../libcuda/gpgpu_context.h"
+#include "trace_driven.h"
+
+//#include "../stream_manager.h"
+
+
+void arguments_check();
+
+int main ( int argc, const char **argv )
+{
+
+ gpgpu_context* m_gpgpu_context = GPGPU_Context();
+ gpgpu_sim * m_gpgpu_sim = m_gpgpu_context->gpgpu_trace_sim_init_perf(argc,argv);
+ m_gpgpu_sim->init();
+
+ //for each kernel
+ //load file
+ //parse and create kernel info
+ //launch
+ //while loop till the end of the end kernel execution
+ //prints stats
+
+ trace_parser tracer(m_gpgpu_sim->get_config().get_traces_filename(), m_gpgpu_sim, m_gpgpu_context);
+
+ std::vector<std::string> kernellist = tracer.parse_kernellist_file();
+
+ for(unsigned i=0; i<kernellist.size(); ++i) {
+
+ trace_kernel_info_t* kernel_info = tracer.parse_kernel_info(kernellist[i]);
+ m_gpgpu_sim->launch(kernel_info);
+
+ bool active = false;
+ bool sim_cycles = false;
+ bool break_limit = false;
+
+ do {
+ if(!m_gpgpu_sim->active())
+ break;
+
+ //performance simulation
+ if( m_gpgpu_sim->active() ) {
+ m_gpgpu_sim->cycle();
+ sim_cycles = true;
+ m_gpgpu_sim->deadlock_check();
+ }else {
+ if(m_gpgpu_sim->cycle_insn_cta_max_hit()){
+ m_gpgpu_context->the_gpgpusim->g_stream_manager->stop_all_running_kernels();
+ break_limit = true;
+ }
+ }
+
+ active=m_gpgpu_sim->active() ;
+
+ } while( active );
+
+ tracer.kernel_finalizer(kernel_info);
+
+ m_gpgpu_sim->print_stats();
+
+ if(sim_cycles) {
+ m_gpgpu_sim->update_stats();
+ m_gpgpu_context->print_simulation_time();
+ }
+
+ if(break_limit) {
+ printf("GPGPU-Sim: ** break due to reaching the maximum cycles (or instructions) **\n");
+ fflush(stdout);
+ exit(1);
+ }
+ }
+
+ return 1;
+}
+
+trace_parser::trace_parser(const char* kernellist_filepath, gpgpu_sim * m_gpgpu_sim, gpgpu_context* m_gpgpu_context)
+{
+
+ this->m_gpgpu_sim = m_gpgpu_sim;
+ this->m_gpgpu_context = m_gpgpu_context;
+ kernellist_filename = kernellist_filepath;
+}
+
+std::vector<std::string> trace_parser::parse_kernellist_file() {
+
+ ifs.open(kernellist_filename);
+
+ if (!ifs.is_open()) {
+ std::cout << "Unable to open file: " <<kernellist_filename<<std::endl;
+ exit(1);
+ }
+
+ std::string directory(kernellist_filename);
+ const size_t last_slash_idx = directory.rfind('/');
+ if (std::string::npos != last_slash_idx)
+ {
+ directory = directory.substr(0, last_slash_idx);
+ }
+
+ std::string line, filepath;
+ std::vector<std::string> kernellist;
+ while(!ifs.eof()) {
+ getline(ifs, line);
+ if(line.empty())
+ continue;
+ filepath = directory+"/"+line;
+ kernellist.push_back(filepath);
+ }
+
+ ifs.close();
+ return kernellist;
+}
+
+
+trace_kernel_info_t* trace_parser::parse_kernel_info(const std::string& kerneltraces_filepath) {
+
+ ifs.open(kerneltraces_filepath.c_str());
+
+ if (!ifs.is_open()) {
+ std::cout << "Unable to open file: " <<kerneltraces_filepath<<std::endl;
+ exit(1);
+ }
+
+ std::cout << "Processing kernel " <<kerneltraces_filepath<<std::endl;
+
+ unsigned grid_dim_x=0, grid_dim_y=0, grid_dim_z=0, tb_dim_x=0, tb_dim_y=0, tb_dim_z=0;
+ unsigned shmem=0, nregs=0, cuda_stream_id=0, kernel_id=0;
+ std::string line;
+ std::stringstream ss;
+ std::string string1, string2;
+ std::string kernel_name;
+
+ while(!ifs.eof()) {
+ getline(ifs, line);
+
+ if (line.length() == 0) {
+ continue;
+ }
+ else if(line[0] == '#'){
+ //the trace format, ignore this and assume fixed format for now
+ break; //the begin of the instruction stream
+ }
+ else if(line[0] == '-') {
+ ss.str(line);
+ ss.ignore();
+ ss>>string1>>string2;
+ if(string1 == "kernel" && string2 == "name") {
+ const size_t equal_idx = line.find('=');
+ kernel_name = line.substr(equal_idx+1);
+ }
+ else if(string1 == "kernel" && string2 == "id") {
+ sscanf(line.c_str(), "-kernel id = %d", &kernel_id);
+ }
+ else if(string1 == "grid" && string2 == "dim") {
+ sscanf(line.c_str(), "-grid dim = (%d,%d,%d)", &grid_dim_x, &grid_dim_y, &grid_dim_z);
+ }
+ else if (string1 == "block" && string2 == "dim") {
+ sscanf(line.c_str(), "-block dim = (%d,%d,%d)", &tb_dim_x, &tb_dim_y, &tb_dim_z);
+ }
+ else if (string1 == "shmem") {
+ sscanf(line.c_str(), "-shmem = %d", &shmem);
+ }
+ else if (string1 == "nregs") {
+ sscanf(line.c_str(), "-nregs = %d", &nregs);
+ }
+ else if (string1 == "cuda" && string2 == "stream") {
+ sscanf(line.c_str(), "-cuda stream id = %d", &cuda_stream_id);
+ }
+ continue;
+ }
+ }
+
+ gpgpu_ptx_sim_info info;
+ info.smem = shmem;
+ info.regs = nregs;
+ dim3 gridDim(grid_dim_x, grid_dim_y, grid_dim_z);
+ dim3 blockDim(tb_dim_x, tb_dim_y, tb_dim_z);
+ trace_function_info* function_info = new trace_function_info(info, m_gpgpu_context);
+ function_info->set_name(kernel_name.c_str());
+ trace_kernel_info_t* kernel_info = new trace_kernel_info_t(gridDim, blockDim, function_info, &ifs, m_gpgpu_sim);
+
+ return kernel_info;
+}
+
+
+void trace_parser::kernel_finalizer(trace_kernel_info_t* kernel_info){
+ if (ifs.is_open())
+ ifs.close();
+
+ delete kernel_info->entry();
+ delete kernel_info;
+}
+
+bool trace_kernel_info_t::get_next_threadblock_traces(std::vector<std::vector<trace_warp_inst_t>>& threadblock_traces) {
+
+ threadblock_traces.clear();
+ unsigned warps_per_tb = ceil(float(threads_per_cta()/32));
+ threadblock_traces.resize(warps_per_tb);
+
+ unsigned block_id_x=0, block_id_y=0, block_id_z=0;
+ unsigned warp_id=0;
+ unsigned insts_num=0;
+ std::string line;
+ std::stringstream ss;
+ std::string string1, string2;
+
+ bool start_of_tb_stream_found = false;
+
+ while(!ifs->eof()) {
+ getline(*ifs, line);
+
+ if (line.length() == 0) {
+ continue;
+ }
+ else {
+ ss.str(line);
+ ss>>string1>>string2;
+ if (string1 == "#BEGIN_TB") {
+ if(!start_of_tb_stream_found)
+ start_of_tb_stream_found=true;
+ else assert(0 && "Parsing error: thread block start before the previous one finish");
+ }
+ else if (string1 == "#END_TB") {
+ assert(start_of_tb_stream_found);
+ break; //end of TB stream
+ }
+ else if(string1 == "thread" && string2 == "block") {
+ assert(start_of_tb_stream_found);
+ sscanf(line.c_str(), "thread block = %d,%d,%d", &block_id_x, &block_id_y, &block_id_z);
+ }
+ else if (string1 == "warp") {
+ //the start of new warp stream
+ assert(start_of_tb_stream_found);
+ sscanf(line.c_str(), "warp = %d", &warp_id);
+ }
+ else if (string1 == "insts") {
+ assert(start_of_tb_stream_found);
+ sscanf(line.c_str(), "insts = %d", &insts_num);
+ threadblock_traces[warp_id].resize(insts_num);
+ }
+ else {
+ assert(start_of_tb_stream_found);
+ trace_warp_inst_t inst(m_gpgpu_sim->getShaderCoreConfig());
+ inst.parse_from_string(line);
+ threadblock_traces[warp_id].push_back(inst);
+ }
+ }
+ }
+
+ return true;
+}
+
+
+bool trace_warp_inst_t::parse_from_string(std::string trace){
+
+ std::stringstream ss;
+ ss.str(trace);
+
+
+ std::string temp;
+ unsigned threadblock_x=0, threadblock_y=0, threadblock_z=0, warpid_tb=0, sm_id=0, warpid_sm=0;
+ unsigned long long m_pc=0;
+ unsigned mask=0;
+ unsigned reg_dest=0;
+ std::string opcode;
+ unsigned reg_srcs_num=0;
+ unsigned reg_srcs[4];
+ unsigned mem_width=0;
+ unsigned long long mem_addresses[warp_size()];
+
+ ss>>std::dec>>threadblock_x>>threadblock_y>>threadblock_z>>warpid_tb>>sm_id>>warpid_sm;
+
+ ss>>std::hex>>m_pc>>mask;
+ std::bitset<MAX_WARP_SIZE> mask_bits(mask);
+
+ ss>>std::dec>>temp;
+ sscanf(temp.c_str(), "R%d", &reg_dest);
+
+ ss>>opcode;
+ ss>>reg_srcs_num;
+
+ for(unsigned i=0; i<reg_srcs_num; ++i) {
+ ss>>temp;
+ sscanf(temp.c_str(), "R%d", &reg_srcs[i]);
+ }
+
+ ss>>mem_width;
+ if(mem_width > 0) //then it is a memory inst
+ {
+ for (int s = 0; s < warp_size(); s++) {
+ if(mask_bits.test(s))
+ ss>>std::hex>>mem_addresses[s];
+ else
+ mem_addresses[s]=0;
+ }
+ }
+
+ //After parsing, fill the inst_t and warp_inst_t params
+ active_mask_t active_mask = mask_bits;
+ set_active( active_mask );
+
+ for(unsigned i=0; i<warp_size(); ++i)
+ set_addr(i, mem_addresses[i]);
+
+ std::string opcode1 = opcode.substr(0, opcode.find("."));
+
+ m_decoded = true;
+ pc = m_pc;
+ isize = 16; //TO DO, change this
+ for(unsigned i=0; i<MAX_OUTPUT_VALUES; i++) {
+ out[i] = 0;
+ }
+ for(unsigned i=0; i<MAX_INPUT_VALUES; i++) {
+ in[i] = 0;
+ }
+ incount=0;
+ outcount=0;
+ is_vectorin = 0;
+ is_vectorout = 0;
+
+ /*
+ switch(opcode1){
+ case "MOV":
+ incount=1;
+ break;
+ default:
+ std::cout<<"unknown instruction: "<<opcode;
+ break;
+ }
+ */
+
+ return true;
+}
+
+
diff --git a/src/trace-driven/trace_driven.h b/src/trace-driven/trace_driven.h
new file mode 100644
index 0000000..091707a
--- /dev/null
+++ b/src/trace-driven/trace_driven.h
@@ -0,0 +1,94 @@
+//developed by Mahmoud Khairy, Purdue Univ
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#ifndef TRACE_DRIVEN_H
+#define TRACE_DRIVEN_H
+
+#include "../abstract_hardware_model.h"
+#include "../gpgpu-sim/shader.h"
+
+class trace_function_info: public function_info {
+public:
+ trace_function_info(const struct gpgpu_ptx_sim_info &info, gpgpu_context* m_gpgpu_context):function_info(0, m_gpgpu_context ) {
+ m_kernel_info = info;
+ }
+
+ virtual const struct gpgpu_ptx_sim_info* get_kernel_info () const {
+ return &m_kernel_info;
+ }
+
+ virtual const void set_kernel_info (const struct gpgpu_ptx_sim_info &info) {
+ m_kernel_info = info;
+ }
+
+private:
+
+
+};
+
+class trace_warp_inst_t: public warp_inst_t {
+public:
+
+ trace_warp_inst_t() {
+
+ }
+ trace_warp_inst_t(const class core_config *config):warp_inst_t(config) {
+ }
+
+ bool parse_from_string(std::string trace);
+
+
+private:
+
+
+};
+
+class trace_kernel_info_t: public kernel_info_t {
+public:
+ trace_kernel_info_t(dim3 gridDim, dim3 blockDim, trace_function_info* m_function_info, std::ifstream* inputstream, gpgpu_sim * gpgpu_sim):kernel_info_t(gridDim, blockDim, m_function_info) {
+ ifs = inputstream;
+ m_gpgpu_sim = gpgpu_sim;
+ }
+
+ bool get_next_threadblock_traces(std::vector<std::vector<trace_warp_inst_t>>& threadblock_traces);
+
+private:
+ std::ifstream* ifs;
+ gpgpu_sim * m_gpgpu_sim;
+
+};
+
+
+
+class trace_parser {
+public:
+ trace_parser(const char* kernellist_filepath, gpgpu_sim * m_gpgpu_sim, gpgpu_context* m_gpgpu_context);
+
+ std::vector<std::string> parse_kernellist_file();
+ trace_kernel_info_t* parse_kernel_info(const std::string& kerneltraces_filepath);
+ void kernel_finalizer(trace_kernel_info_t* kernel_info);
+
+private:
+
+ std::string kernellist_filename;
+ std::ifstream ifs;
+ gpgpu_sim * m_gpgpu_sim;
+ gpgpu_context* m_gpgpu_context;
+
+};
+
+class trace_shd_warp_t: public shd_warp_t {
+public:
+ trace_shd_warp_t(class shader_core_ctx *shader, unsigned warp_size):shd_warp_t(shader, warp_size) {
+ }
+
+ bool get_next_threadblock_traces(std::vector<std::vector<trace_warp_inst_t>>& threadblock_traces);
+
+private:
+
+};
+
+#endif