summaryrefslogtreecommitdiff
path: root/src/cuda-sim
diff options
context:
space:
mode:
authorTor Aamodt <[email protected]>2010-08-08 12:17:43 -0800
committerTor Aamodt <[email protected]>2010-08-08 12:17:43 -0800
commitef53bd94e416c74a3ea3b4d6240eb8f043e86e60 (patch)
tree5b0a8bb30f9472188390360f123d5d91a606027f /src/cuda-sim
parent43eb0e822424b39b52091f45725376cc903b08ee (diff)
refactoring: moving 'loading' operations into ptx_loader.*
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 7166]
Diffstat (limited to 'src/cuda-sim')
-rw-r--r--src/cuda-sim/Makefile3
-rw-r--r--src/cuda-sim/cuda-sim.cc378
-rw-r--r--src/cuda-sim/cuda-sim.h12
-rw-r--r--src/cuda-sim/instructions.cc7
-rw-r--r--src/cuda-sim/ptx_ir.cc172
-rw-r--r--src/cuda-sim/ptx_ir.h23
-rw-r--r--src/cuda-sim/ptx_loader.cc303
-rw-r--r--src/cuda-sim/ptx_loader.h80
8 files changed, 579 insertions, 399 deletions
diff --git a/src/cuda-sim/Makefile b/src/cuda-sim/Makefile
index 9d43f58..6140048 100644
--- a/src/cuda-sim/Makefile
+++ b/src/cuda-sim/Makefile
@@ -91,7 +91,7 @@ ifeq ($(GNUC_CPP0X),1)
endif
endif
-OBJS := cuda_device_printf.o instructions.o cuda-sim.o ptx_ir.o ptx_sim.o memory.o ptx-stats.o ptx.tab.o lex.ptx_.o ptxinfo.tab.o lex.ptxinfo_.o
+OBJS := ptx_loader.o cuda_device_printf.o instructions.o cuda-sim.o ptx_ir.o ptx_sim.o memory.o ptx-stats.o ptx.tab.o lex.ptx_.o ptxinfo.tab.o lex.ptxinfo_.o
CUDART_VERSION:=$(shell nvcc --version | awk '/release/ {print $$5;}' | sed 's/,//' | sed 's/\./ /' | awk '{printf("%02u%02u", 10*int($$1), 10*$$2);}')
@@ -166,6 +166,7 @@ depend:
instructions.o: instructions.h ptx.tab.c
cuda_device_printf.o: ptx.tab.c
ptx_ir.o: ptx.tab.c ptx_parser_decode.def
+ptx_loader.o: ptx.tab.c
# DO NOT DELETE
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;
diff --git a/src/cuda-sim/cuda-sim.h b/src/cuda-sim/cuda-sim.h
index 25b0cb2..2e67e15 100644
--- a/src/cuda-sim/cuda-sim.h
+++ b/src/cuda-sim/cuda-sim.h
@@ -3,12 +3,23 @@
#include "../abstract_hardware_model.h"
#include <stdlib.h>
+#include <map>
+#include <string>
class memory_space;
+class function_info;
+class symbol_table;
extern const char *g_gpgpusim_version_string;
extern int g_ptx_sim_mode;
extern memory_space *g_global_mem;
+extern int g_debug_execution;
+extern int g_debug_thread_uid;
+extern unsigned g_max_regs_per_thread;
+extern bool g_debug_ir_generation;
+extern const char *g_filename;
+extern std::map<std::string,function_info*> *g_kernel_name_to_function_lookup;
+extern std::map<std::string,symbol_table*> g_kernel_name_to_symtab_lookup;
extern void gpgpu_ptx_sim_add_ptxstring( const char *ptx, const char *source_fname );
extern void gpgpu_ptx_sim_main_func( const char *kernel_key, dim3 gridDim, dim3 blockDim, struct gpgpu_ptx_sim_arg *);
@@ -30,5 +41,6 @@ extern void gpgpu_ptx_sim_bindNameToTexture(const char* name, const struct tex
extern int gpgpu_ptx_sim_sizeofTexture(const char* name);
extern const char* gpgpu_ptx_sim_findNamefromTexture(const struct textureReference* texref);
extern const struct textureReference* gpgpu_ptx_sim_accessTextureofName(const char* name);
+extern void read_sim_environment_variables();
#endif
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index d663d0a..b3a0342 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -74,6 +74,8 @@
#include "cuda-math.h"
#include "../abstract_hardware_model.h"
+#include "ptx_loader.h"
+
#include <stdarg.h>
unsigned g_num_ptx_inst_uid=0;
@@ -90,11 +92,6 @@ extern std::map<struct textureReference*,struct cudaArray*> TextureToArrayMap; /
extern std::map<struct textureReference*,struct textureInfo*> TextureToInfoMap; // texture bindings
extern std::map<std::string, struct textureReference*> NameToTextureMap;
-memory_space *g_global_mem;
-memory_space *g_tex_mem;
-memory_space *g_surf_mem;
-memory_space *g_param_mem;
-
void inst_not_implemented( const ptx_instruction * pI ) ;
unsigned unfound_register_warned = 0;
diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc
index d049a6a..51ad05f 100644
--- a/src/cuda-sim/ptx_ir.cc
+++ b/src/cuda-sim/ptx_ir.cc
@@ -72,16 +72,17 @@
#include <stdarg.h>
#include "cuda-sim.h"
+#include "../option_parser.h"
-extern unsigned g_max_regs_per_thread;
extern "C" int ptx_error( const char *s );
+extern int ptx_lineno;
// the program intermediate representation...
symbol_table *g_global_symbol_table = NULL;
-static symbol_table *g_current_symbol_table = NULL;
-std::list<ptx_instruction*> g_instructions;
-symbol *g_last_symbol = NULL;
std::map<std::string,symbol_table*> g_sym_name_to_symbol_table;
+static symbol_table *g_current_symbol_table = NULL;
+static std::list<ptx_instruction*> g_instructions;
+static symbol *g_last_symbol = NULL;
int g_error_detected = 0;
@@ -104,13 +105,6 @@ std::list<operand_info> g_operands;
std::list<int> g_options;
std::list<int> g_scalar_type;
-extern bool g_debug_ir_generation;
-extern const char *g_filename;
-extern int ptx_lineno;
-extern int g_debug_execution;
-extern int g_debug_thread_uid;
-
-
#define DPRINTF(...) \
if( g_debug_ir_generation ) { \
printf(" %s:%u => ",g_filename,ptx_lineno); \
@@ -212,8 +206,6 @@ void add_directive()
#define mymax(a,b) ((a)>(b)?(a):(b))
-void gpgpu_ptx_assemble( std::string kname, void *kinfo );
-
void end_function()
{
DPRINTF("end_function");
@@ -229,9 +221,6 @@ void end_function()
DPRINTF("function %s, PC = %d\n", g_func_info->get_name().c_str(), g_func_info->get_start_PC());
}
-extern int ptx_lineno;
-extern const char *g_filename;
-
#define parse_error(msg, ...) parse_error_impl(__FILE__,__LINE__, msg, ##__VA_ARGS__)
#define parse_assert(cond,msg, ...) parse_assert_impl((cond),__FILE__,__LINE__, msg, ##__VA_ARGS__)
@@ -1680,3 +1669,154 @@ void function_info::print_insn( unsigned pc, FILE * fp ) const
}
}
+static int g_save_embedded_ptx = 0;
+
+extern "C" int ptx_parse();
+extern "C" int ptx__scan_string(const char*);
+extern "C" FILE *ptx_in;
+
+extern "C" const char *g_ptxinfo_filename;
+extern "C" int ptxinfo_parse();
+extern "C" int ptxinfo_debug;
+extern "C" FILE *ptxinfo_in;
+
+static void print_ptx_file( const char *p, unsigned source_num, const char *filename );
+
+void ptx_reg_options(option_parser_t opp)
+{
+ option_parser_register(opp, "-save_embedded_ptx", OPT_BOOL, &g_save_embedded_ptx,
+ "saves ptx files embedded in binary as <n>.ptx",
+ "0");
+}
+
+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;
+}
+
+
+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);
+}
+
+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();
+}
diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h
index 839cceb..4600be5 100644
--- a/src/cuda-sim/ptx_ir.h
+++ b/src/cuda-sim/ptx_ir.h
@@ -1257,12 +1257,31 @@ struct textureInfo {
extern function_info *g_func_info;
extern int g_error_detected;
-extern bool g_debug_ir_generation;
-extern std::list<ptx_instruction*> g_instructions;
extern symbol_table *g_entrypoint_symbol_table;
extern function_info *g_entrypoint_func_info;
extern symbol_table *g_global_symbol_table;
+extern std::map<std::string,symbol_table*> g_sym_name_to_symbol_table;
void init_parser();
+#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))
+
+void gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source_num );
+void gpgpu_ptx_assemble( std::string kname, void *kinfo );
+#include "../option_parser.h"
+void ptx_reg_options(option_parser_t opp);
+
extern "C" {
#endif
diff --git a/src/cuda-sim/ptx_loader.cc b/src/cuda-sim/ptx_loader.cc
new file mode 100644
index 0000000..8c13f6d
--- /dev/null
+++ b/src/cuda-sim/ptx_loader.cc
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2009 by Tor M. Aamodt, Wilson W. L. Fung, Ali Bakhoda,
+ * George L. Yuan, Dan O'Connor, Joey Ting, Henry Wong and the
+ * University of British Columbia
+ * Vancouver, BC V6T 1Z4
+ * All Rights Reserved.
+ *
+ * THIS IS A LEGAL DOCUMENT BY DOWNLOADING GPGPU-SIM, YOU ARE AGREEING TO THESE
+ * TERMS AND CONDITIONS.
+ *
+ * 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 OWNERS 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.
+ *
+ * NOTE: The files libcuda/cuda_runtime_api.c and src/cuda-sim/cuda-math.h
+ * are derived from the CUDA Toolset available from http://www.nvidia.com/cuda
+ * (property of NVIDIA). The files benchmarks/BlackScholes/ and
+ * benchmarks/template/ are derived from the CUDA SDK available from
+ * http://www.nvidia.com/cuda (also property of NVIDIA). The files from
+ * src/intersim/ are derived from Booksim (a simulator provided with the
+ * textbook "Principles and Practices of Interconnection Networks" available
+ * from http://cva.stanford.edu/books/ppin/). As such, those files are bound by
+ * the corresponding legal terms and conditions set forth separately (original
+ * copyright notices are left in files from these sources and where we have
+ * modified a file our copyright notice appears before the original copyright
+ * notice).
+ *
+ * Using this version of GPGPU-Sim requires a complete installation of CUDA
+ * which is distributed seperately by NVIDIA under separate terms and
+ * conditions. To use this version of GPGPU-Sim with OpenCL requires a
+ * recent version of NVIDIA's drivers which support OpenCL.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. 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.
+ *
+ * 4. This version of GPGPU-SIM is distributed freely for non-commercial use only.
+ *
+ * 5. No nonprofit user may place any restrictions on the use of this software,
+ * including as modified by the user, by any other authorized user.
+ *
+ * 6. GPGPU-SIM was developed primarily by Tor M. Aamodt, Wilson W. L. Fung,
+ * Ali Bakhoda, George L. Yuan, at the University of British Columbia,
+ * Vancouver, BC V6T 1Z4
+ */
+
+#include "ptx_loader.h"
+#include "ptx_ir.h"
+#include "cuda-sim.h"
+#include <dirent.h>
+
+/// globals
+
+memory_space *g_global_mem;
+memory_space *g_tex_mem;
+memory_space *g_surf_mem;
+memory_space *g_param_mem;
+bool g_override_embedded_ptx = false;
+
+struct ptx_info_t {
+ char *str;
+ char *fname;
+ ptx_info_t *next;
+};
+
+/// extern prototypes
+
+extern "C" int ptx_parse();
+extern "C" int ptx__scan_string(const char*);
+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;
+
+/// static functions
+
+static 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;
+}
+
+static 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;
+}
+
+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;
+}
+
+static int ptx_file_filter(
+#if !defined(__APPLE__)
+ const
+#endif
+ struct dirent *de )
+{
+ const char *tmp = strstr(de->d_name,".ptx");
+ if ( tmp != NULL && tmp[4] == 0 ) {
+ return 1;
+ }
+ return 0;
+}
+
+// global functions
+
+static ptx_info_t *g_ptx_source_array = NULL;
+
+void gpgpu_ptx_sim_load_gpu_kernels()
+{
+ static unsigned source_num = 0;
+ ptx_in = NULL;
+ if ( g_filename )
+ ptx_in = fopen( g_filename, "r" );
+ 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) {
+ 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);
+ }
+ }
+}
+
+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;
+ }
+}
diff --git a/src/cuda-sim/ptx_loader.h b/src/cuda-sim/ptx_loader.h
new file mode 100644
index 0000000..33c6dc9
--- /dev/null
+++ b/src/cuda-sim/ptx_loader.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2009 by Tor M. Aamodt, Wilson W. L. Fung, Ali Bakhoda,
+ * George L. Yuan, Dan O'Connor, Joey Ting, Henry Wong and the
+ * University of British Columbia
+ * Vancouver, BC V6T 1Z4
+ * All Rights Reserved.
+ *
+ * THIS IS A LEGAL DOCUMENT BY DOWNLOADING GPGPU-SIM, YOU ARE AGREEING TO THESE
+ * TERMS AND CONDITIONS.
+ *
+ * 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 OWNERS 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.
+ *
+ * NOTE: The files libcuda/cuda_runtime_api.c and src/cuda-sim/cuda-math.h
+ * are derived from the CUDA Toolset available from http://www.nvidia.com/cuda
+ * (property of NVIDIA). The files benchmarks/BlackScholes/ and
+ * benchmarks/template/ are derived from the CUDA SDK available from
+ * http://www.nvidia.com/cuda (also property of NVIDIA). The files from
+ * src/intersim/ are derived from Booksim (a simulator provided with the
+ * textbook "Principles and Practices of Interconnection Networks" available
+ * from http://cva.stanford.edu/books/ppin/). As such, those files are bound by
+ * the corresponding legal terms and conditions set forth separately (original
+ * copyright notices are left in files from these sources and where we have
+ * modified a file our copyright notice appears before the original copyright
+ * notice).
+ *
+ * Using this version of GPGPU-Sim requires a complete installation of CUDA
+ * which is distributed seperately by NVIDIA under separate terms and
+ * conditions. To use this version of GPGPU-Sim with OpenCL requires a
+ * recent version of NVIDIA's drivers which support OpenCL.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. 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.
+ *
+ * 4. This version of GPGPU-SIM is distributed freely for non-commercial use only.
+ *
+ * 5. No nonprofit user may place any restrictions on the use of this software,
+ * including as modified by the user, by any other authorized user.
+ *
+ * 6. GPGPU-SIM was developed primarily by Tor M. Aamodt, Wilson W. L. Fung,
+ * Ali Bakhoda, George L. Yuan, at the University of British Columbia,
+ * Vancouver, BC V6T 1Z4
+ */
+
+
+#ifndef PTX_LOADER_H_INCLUDED
+#define PTX_LOADER_H_INCLUDED
+
+class memory_space;
+
+extern memory_space *g_global_mem;
+extern memory_space *g_tex_mem;
+extern memory_space *g_surf_mem;
+extern memory_space *g_param_mem;
+extern bool g_override_embedded_ptx;
+
+void gpgpu_ptx_sim_load_gpu_kernels();
+void gpgpu_ptx_sim_add_ptxstring( const char *ptx_string, const char *sourcefname );
+
+#endif