diff options
Diffstat (limited to 'src/cuda-sim/cuda-sim.cc')
| -rw-r--r-- | src/cuda-sim/cuda-sim.cc | 378 |
1 files changed, 3 insertions, 375 deletions
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index 74b18bc..f5c283e 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -68,7 +68,6 @@ #include "ptx_ir.h" #include "ptx_sim.h" #include <stdio.h> -#include <dirent.h> #include "opcodes.h" #include "../intersim/statwraper.h" @@ -78,6 +77,7 @@ #include "../abstract_hardware_model.h" #include "memory.h" #include "ptx-stats.h" +#include "ptx_loader.h" extern bool g_interactive_debugger_enabled; @@ -85,30 +85,15 @@ int gpgpu_ptx_instruction_classification=0; void ** g_inst_classification_stat = NULL; void ** g_inst_op_classification_stat= NULL; int g_ptx_kernel_count = -1; // used for classification stat collection purposes -extern "C" int ptx_parse(); -extern "C" int ptx__scan_string(const char*); -extern "C" int ptx_debug; -extern "C" FILE *ptx_in; - -extern "C" const char *g_ptxinfo_filename = NULL; -extern "C" int ptxinfo_parse(); -extern "C" int ptxinfo_debug; -extern "C" FILE *ptxinfo_in; int g_debug_execution = 0; int g_debug_thread_uid = 0; addr_t g_debug_pc = 0xBEEF1518; -int g_override_embedded_ptx = false; const char *g_filename; bool g_debug_ir_generation = false; unsigned g_ptx_sim_num_insn = 0; -extern memory_space *g_global_mem; -extern memory_space *g_param_mem; -extern memory_space *g_tex_mem; -extern memory_space *g_surf_mem; - std::map<const struct textureReference*,const struct cudaArray*> TextureToArrayMap; // texture bindings std::map<const struct textureReference*, const struct textureInfo*> TextureToInfoMap; std::map<std::string, const struct textureReference*> NameToTextureMap; @@ -309,100 +294,6 @@ void gpgpu_ptx_sim_init_memory() } } -int load_static_globals( symbol_table *symtab, unsigned min_gaddr, unsigned max_gaddr) -{ - printf( "GPGPU-Sim PTX: loading globals with explicit initializers... \n" ); - fflush(stdout); - int ng_bytes=0; - symbol_table::iterator g=symtab->global_iterator_begin(); - - for ( ; g!=symtab->global_iterator_end(); g++) { - symbol *global = *g; - if ( global->has_initializer() ) { - printf( "GPGPU-Sim PTX: initializing '%s' ... ", global->name().c_str() ); - unsigned addr=global->get_address(); - const type_info *type = global->type(); - type_info_key ti=type->get_key(); - size_t size; - int t; - ti.type_decode(size,t); - int nbytes = size/8; - int offset=0; - std::list<operand_info> init_list = global->get_initializer(); - for ( std::list<operand_info>::iterator i=init_list.begin(); i!=init_list.end(); i++ ) { - operand_info op = *i; - ptx_reg_t value = op.get_literal_value(); - assert( (addr+offset+nbytes) < min_gaddr ); // min_gaddr is start of "heap" for cudaMalloc - g_global_mem->write(addr+offset,nbytes,&value,NULL,NULL); // assuming little endian here - offset+=nbytes; - ng_bytes+=nbytes; - } - printf(" wrote %u bytes\n", offset ); - } - } - printf( "GPGPU-Sim PTX: finished loading globals (%u bytes total).\n", ng_bytes ); - fflush(stdout); - return ng_bytes; -} - -int load_constants( symbol_table *symtab, addr_t min_gaddr ) -{ - printf( "GPGPU-Sim PTX: loading constants with explicit initializers... " ); - fflush(stdout); - int nc_bytes = 0; - symbol_table::iterator g=symtab->const_iterator_begin(); - - for ( ; g!=symtab->const_iterator_end(); g++) { - symbol *constant = *g; - if ( constant->is_const() && constant->has_initializer() ) { - - // get the constant element data size - int basic_type; - size_t num_bits; - constant->type()->get_key().type_decode(num_bits,basic_type); - - std::list<operand_info> init_list = constant->get_initializer(); - int nbytes_written = 0; - for ( std::list<operand_info>::iterator i=init_list.begin(); i!=init_list.end(); i++ ) { - operand_info op = *i; - ptx_reg_t value = op.get_literal_value(); - int nbytes = num_bits/8; - switch ( op.get_type() ) { - case int_t: assert(nbytes >= 1); break; - case float_op_t: assert(nbytes == 4); break; - case double_op_t: assert(nbytes >= 4); break; // account for double DEMOTING - default: - abort(); - } - unsigned addr=constant->get_address() + nbytes_written; - assert( addr+nbytes < min_gaddr ); - - g_global_mem->write(addr,nbytes,&value,NULL,NULL); // assume little endian (so u8 is the first byte in u32) - nc_bytes+=nbytes; - nbytes_written += nbytes; - } - } - } - printf( " done.\n"); - fflush(stdout); - return nc_bytes; -} - -#define GLOBAL_HEAP_START 0x10000000 - // start allocating from this address (lower values used for allocating globals in .ptx file) - -#define SHARED_MEM_SIZE_MAX (64*1024) -#define LOCAL_MEM_SIZE_MAX 1024 -#define MAX_STREAMING_MULTIPROCESSORS 64 -#define MAX_THREAD_PER_SM 1024 -#define TOTAL_LOCAL_MEM_PER_SM (MAX_THREAD_PER_SM*LOCAL_MEM_SIZE_MAX) -#define TOTAL_SHARED_MEM (MAX_STREAMING_MULTIPROCESSORS*SHARED_MEM_SIZE_MAX) -#define TOTAL_LOCAL_MEM (MAX_STREAMING_MULTIPROCESSORS*MAX_THREAD_PER_SM*LOCAL_MEM_SIZE_MAX) -#define SHARED_GENERIC_START (GLOBAL_HEAP_START-TOTAL_SHARED_MEM) -#define LOCAL_GENERIC_START (SHARED_GENERIC_START-TOTAL_LOCAL_MEM) - -#define STATIC_ALLOC_LIMIT (GLOBAL_HEAP_START - (TOTAL_LOCAL_MEM+TOTAL_SHARED_MEM)) - addr_t shared_to_generic( unsigned smid, addr_t addr ) { assert( addr < SHARED_MEM_SIZE_MAX ); @@ -1340,7 +1231,6 @@ std::map<const void*,std::string> g_const_name_lookup; // indexed by hostVar std::map<const void*,std::string> g_global_name_lookup; // indexed by hostVar std::set<std::string> g_globals; std::set<std::string> g_constants; -extern std::map<std::string,symbol_table*> g_sym_name_to_symbol_table; void gpgpu_ptx_sim_register_const_variable(void *hostVar, const char *deviceName, size_t size ) { @@ -1432,20 +1322,9 @@ int g_ptx_sim_mode=0; // used by libcuda.a if non-zer cudaLaunch() will call gpgpu_ptx_sim_main_func() // if zero it calls gpgpu_ptx_sim_main_perf() -#if defined(__APPLE__) -int ptx_file_filter(struct dirent *de ) -#else -int ptx_file_filter(const struct dirent *de ) -#endif -{ - const char *tmp = strstr(de->d_name,".ptx"); - if ( tmp != NULL && tmp[4] == 0 ) { - return 1; - } - return 0; -} +extern "C" int ptx_debug; -void read_environment_variables() +void read_sim_environment_variables() { ptx_debug = 0; g_debug_execution = 0; @@ -1503,261 +1382,10 @@ void read_environment_variables() } } -static FILE *open_ptxinfo (const char* ptx_filename) -{ - const int ptx_fnamelen = strlen(ptx_filename); - char *ptxi_fname = new char[ptx_fnamelen+5]; - strcpy (ptxi_fname, ptx_filename); - strcpy (ptxi_fname+ptx_fnamelen, "info"); - - //ptxinfo_debug=1; - g_ptxinfo_filename = ptxi_fname; - FILE *f = fopen (ptxi_fname, "rt"); - return f; -} -struct ptx_info_t { - char *str; - char *fname; - ptx_info_t *next; -}; -ptx_info_t *g_ptx_source_array = NULL; -unsigned g_used_embedded_ptx_files; -extern double g_ptx_version; -void gpgpu_ptx_sim_add_ptxstring( const char *ptx_string, const char *sourcefname ) -{ - ptx_info_t *t = new ptx_info_t; - t->next = NULL; - t->str = strdup(ptx_string); - t->fname = strdup(sourcefname); - - // put ptx source into a fifo - if (g_ptx_source_array == NULL) { - // first ptx source - g_ptx_source_array = t; - } else { - // insert subsequent ptx source at the end of queue - ptx_info_t *l_ptx_source = g_ptx_source_array; - while (l_ptx_source->next != NULL) { - l_ptx_source = l_ptx_source->next; - } - l_ptx_source->next = t; - } -} -const ptx_instruction *ptx_instruction_lookup( const char *filename, unsigned linenumber ); - -void print_ptx_file( const char *p, unsigned source_num, const char *filename ) -{ - printf("\nGPGPU-Sim PTX: file _%u.ptx contents:\n\n", source_num ); - char *s = strdup(p); - char *t = s; - unsigned n=1; - while ( *t != '\0' ) { - char *u = t; - while ( (*u != '\n') && (*u != '\0') ) u++; - unsigned last = (*u == '\0'); - *u = '\0'; - const ptx_instruction *pI = ptx_instruction_lookup(filename,n); - char pc[64]; - if( pI && pI->get_PC() ) - snprintf(pc,64,"%4u", pI->get_PC() ); - else - snprintf(pc,64," "); - printf(" _%u.ptx %4u (pc=%s): %s\n", source_num, n, pc, t ); - if ( last ) break; - t = u+1; - n++; - } - free(s); - fflush(stdout); -} - -extern int g_save_embedded_ptx; - -void gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source_num ) -{ - char buf[1024]; - snprintf(buf,1024,"_%u.ptx", source_num ); - if( g_save_embedded_ptx ) { - FILE *fp = fopen(buf,"w"); - fprintf(fp,"%s",p); - fclose(fp); - } - g_filename = strdup(buf); - init_parser(); - ptx__scan_string(p); - int errors = ptx_parse (); - if ( errors ) { - char fname[1024]; - snprintf(fname,1024,"_ptx_XXXXXX"); - int fd=mkstemp(fname); - close(fd); - printf("GPGPU-Sim PTX: parser error detected, exiting... but first extracting .ptx to \"%s\"\n", fname); - FILE *ptxfile = fopen(fname,"w"); - fprintf(ptxfile,"%s", p ); - fclose(ptxfile); - abort(); - exit(40); - } - - if ( g_debug_execution >= 100 ) - print_ptx_file(p,source_num,g_filename); - - printf("GPGPU-Sim PTX: finished parsing EMBEDDED .ptx file %s\n",g_filename); - - char fname[1024]; - snprintf(fname,1024,"_ptx_XXXXXX"); - int fd=mkstemp(fname); - close(fd); - - printf("GPGPU-Sim PTX: extracting embedded .ptx to temporary file \"%s\"\n", fname); - FILE *ptxfile = fopen(fname,"w"); - fprintf(ptxfile,"%s",p); - fclose(ptxfile); - - char fname2[1024]; - snprintf(fname2,1024,"_ptx2_XXXXXX"); - fd=mkstemp(fname2); - close(fd); - char commandline2[4096]; - snprintf(commandline2,4096,"cat %s | sed 's/.version 1.5/.version 1.4/' | sed 's/, texmode_independent//' | sed 's/\\(\\.extern \\.const\\[1\\] .b8 \\w\\+\\)\\[\\]/\\1\\[1\\]/' | sed 's/const\\[.\\]/const\\[0\\]/g' > %s", fname, fname2); - int result = system(commandline2); - if( result != 0 ) { - printf("GPGPU-Sim PTX: ERROR ** while loading PTX (a) %d\n", result); - printf(" Ensure you have write access to simulation directory\n"); - printf(" and have \'cat\' and \'sed\' in your path.\n"); - exit(1); - } - - char tempfile_ptxinfo[1024]; - snprintf(tempfile_ptxinfo,1024,"%sinfo",fname); - char commandline[1024]; - char extra_flags[1024]; - extra_flags[0]=0; -#if CUDART_VERSION >= 3000 - snprintf(extra_flags,1024,"--gpu-name=sm_20"); -#endif - snprintf(commandline,1024,"ptxas %s -v %s --output-file /dev/null 2> %s", - extra_flags, fname2, tempfile_ptxinfo); - printf("GPGPU-Sim PTX: generating ptxinfo using \"%s\"\n", commandline); - result = system(commandline); - if( result != 0 ) { - printf("GPGPU-Sim PTX: ERROR ** while loading PTX (b) %d\n", result); - printf(" Ensure ptxas is in your path.\n"); - exit(1); - } - - ptxinfo_in = fopen(tempfile_ptxinfo,"r"); - g_ptxinfo_filename = tempfile_ptxinfo; - ptxinfo_parse(); - snprintf(commandline,1024,"rm -f %s %s %s", fname, fname2, tempfile_ptxinfo); - printf("GPGPU-Sim PTX: removing ptxinfo using \"%s\"\n", commandline); - result = system(commandline); - if( result != 0 ) { - printf("GPGPU-Sim PTX: ERROR ** while loading PTX (c) %d\n", result); - exit(1); - } - g_filename = NULL; -} - -void gpgpu_ptx_assemble( std::string kname, void *kinfo ) -{ - function_info *func_info = (function_info *)kinfo; - if( func_info->is_extern() ) { - printf("GPGPU-Sim PTX: skipping assembly for extern declared function \'%s\'\n", func_info->get_name().c_str() ); - return; - } - if( g_kernel_name_to_symtab_lookup[ kname ] == NULL ) { - printf("\nGPGPU-Sim PTX: ERROR no information for kernel \'%s\'\n" - " this can happen for kernels contained in CUDA\n" - " libraries (such as CUBLAS, CUFFT, or CUDPP)\n", kname.c_str() ); - exit(1); - } - g_func_info = func_info; - func_info->ptx_assemble(); -} - -void gpgpu_ptx_sim_load_gpu_kernels() -{ - ptx_in = NULL; - if ( g_filename ) - ptx_in = fopen( g_filename, "r" ); - static unsigned source_num = 0; - gpgpu_ptx_sim_init_memory(); - if (ptx_in) { - init_parser(); - ptx_parse(); - ptxinfo_in = open_ptxinfo(g_filename); - ptxinfo_parse(); - load_static_globals(g_global_symbol_table,STATIC_ALLOC_LIMIT,0xFFFFFFFF); - load_constants(g_global_symbol_table,STATIC_ALLOC_LIMIT); - } else { - if (!g_override_embedded_ptx) { - g_used_embedded_ptx_files=1; - printf("GPGPU-Sim PTX: USING EMBEDDED .ptx files...\n"); - ptx_info_t *s; - for ( s=g_ptx_source_array; s!=NULL; s=s->next ) { - gpgpu_ptx_sim_load_ptx_from_string(s->str, ++source_num); - load_static_globals(g_global_symbol_table,STATIC_ALLOC_LIMIT,0xFFFFFFFF); - load_constants(g_global_symbol_table,STATIC_ALLOC_LIMIT); - } - } else { - g_filename = NULL; - struct dirent **namelist; - int n; - - n = scandir(".", &namelist, ptx_file_filter, alphasort); - if (n < 0) - perror("scandir"); - else { - while (n--) { - if ( g_filename != NULL ) { - printf("Loader error: support for multiple .ptx files not yet enabled\n"); - abort(); - } - g_filename = strdup(namelist[n]->d_name); - printf("Parsing %s..\n", g_filename); - ptx_in = fopen( g_filename, "r" ); - free(namelist[n]); - init_parser(); - ptx_parse (); - ptxinfo_in = open_ptxinfo(g_filename); - ptxinfo_parse(); - g_filename = NULL; - load_static_globals(g_global_symbol_table,STATIC_ALLOC_LIMIT,0xFFFFFFFF); - load_constants(g_global_symbol_table,STATIC_ALLOC_LIMIT); - } - free(namelist); - } - } - } - - if ( ptx_in == NULL && g_override_embedded_ptx ) { - printf("GPGPU-Sim PTX Simulator error: Could find/open .ptx file for reading\n"); - printf(" This means there are no .ptx files in the current directory.\n"); - printf(" Either place a .ptx file in the current directory, or ensure\n" ); - printf(" the PTX_SIM_KERNELFILE environment variable points to .ptx file.\n"); - printf(" PTX_SIM_KERNELFILE=\"%s\"\n", g_filename ); - exit(1); - } - - if ( g_error_detected ) { - printf( "GPGPU-Sim PTX: Program parsing completed: Errors detected.\n" ); - exit(1); - } else { - printf( "GPGPU-Sim PTX: Program parsing completed (max %u registers used per thread).\n", g_max_regs_per_thread ); - } - - if ( g_kernel_name_to_function_lookup ) { - for ( std::map<std::string,function_info*>::iterator f=g_kernel_name_to_function_lookup->begin(); - f != g_kernel_name_to_function_lookup->end(); f++ ) { - gpgpu_ptx_assemble(f->first,f->second); - } - } -} extern time_t simulation_starttime; |
