diff options
| author | Wilson Fung <[email protected]> | 2012-11-09 15:33:00 -0800 |
|---|---|---|
| committer | Andrew Boktor <[email protected]> | 2014-08-14 13:49:21 -0700 |
| commit | 64ecf6992b5e0400877c2d1b479dddcadac6db69 (patch) | |
| tree | 29497a626d6b45d31028ae8d7caac0a6fded8f37 | |
| parent | c6becca8e1c9c188b515d4c66df66114ef448361 (diff) | |
Extended PTX parser to recognize the .ptr .shared directive and allocate shared memory buffer to those pointers. This is required to support OpenCL local memorywith the newer NVIDIA driver.
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 14565]
| -rw-r--r-- | cuobjdump_to_ptxplus/ptx_parser.h | 1 | ||||
| -rw-r--r-- | src/cuda-sim/cuda-sim.cc | 50 | ||||
| -rw-r--r-- | src/cuda-sim/ptx.y | 7 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_ir.h | 11 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_parser.cc | 15 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_parser.h | 1 |
6 files changed, 62 insertions, 23 deletions
diff --git a/cuobjdump_to_ptxplus/ptx_parser.h b/cuobjdump_to_ptxplus/ptx_parser.h index dc7c7c0..f8b922b 100644 --- a/cuobjdump_to_ptxplus/ptx_parser.h +++ b/cuobjdump_to_ptxplus/ptx_parser.h @@ -105,6 +105,7 @@ void change_memory_addr_space( const char *a ) {DPRINTF(" ");} void add_literal_int( int a ) {DPRINTF(" ");} void add_literal_float( float a ) {DPRINTF(" ");} void add_literal_double( double a ) {DPRINTF(" ");} +void add_ptr_spec( enum _memory_space_t spec ) {DPRINTF(" ");} void add_extern_spec() {DPRINTF(" ");} void add_alignment_spec( int ) {DPRINTF(" ");} void add_pragma( const char *a ) {DPRINTF(" ");} diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index 85afe73..03508f3 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -835,7 +835,7 @@ void ptx_instruction::pre_decode() m_decoded=true; } -void function_info::add_param_name_type_size( unsigned index, std::string name, int type, size_t size ) +void function_info::add_param_name_type_size( unsigned index, std::string name, int type, size_t size, bool ptr, memory_space_t space ) { unsigned parsed_index; char buffer[2048]; @@ -843,10 +843,10 @@ void function_info::add_param_name_type_size( unsigned index, std::string name, int ntokens = sscanf(name.c_str(),buffer,&parsed_index); if( ntokens == 1 ) { assert( m_ptx_kernel_param_info.find(parsed_index) == m_ptx_kernel_param_info.end() ); - m_ptx_kernel_param_info[parsed_index] = param_info(name, type, size); + m_ptx_kernel_param_info[parsed_index] = param_info(name, type, size, ptr, space); } else { assert( m_ptx_kernel_param_info.find(index) == m_ptx_kernel_param_info.end() ); - m_ptx_kernel_param_info[index] = param_info(name, type, size); + m_ptx_kernel_param_info[index] = param_info(name, type, size, ptr, space); } } @@ -854,16 +854,27 @@ void function_info::add_param_data( unsigned argn, struct gpgpu_ptx_sim_arg *arg { const void *data = args->m_start; + bool scratchpad_memory_param = false; // Is this parameter in CUDA shared memory or OpenCL local memory + std::map<unsigned,param_info>::iterator i=m_ptx_kernel_param_info.find(argn); - if( i != m_ptx_kernel_param_info.end()) { - param_t tmp; - tmp.pdata = args->m_start; - tmp.size = args->m_nbytes; - tmp.offset = args->m_offset; - tmp.type = 0; - i->second.add_data(tmp); - i->second.add_offset((unsigned) args->m_offset); + if( i != m_ptx_kernel_param_info.end() ) { + if (i->second.is_ptr_shared()) { + assert(args->m_start == NULL && "OpenCL parameter pointer to local memory must have NULL as value"); + scratchpad_memory_param = true; + } else { + param_t tmp; + tmp.pdata = args->m_start; + tmp.size = args->m_nbytes; + tmp.offset = args->m_offset; + tmp.type = 0; + i->second.add_data(tmp); + i->second.add_offset((unsigned) args->m_offset); + } } else { + scratchpad_memory_param = true; + } + + if (scratchpad_memory_param) { // This should only happen for OpenCL: // // The LLVM PTX compiler in NVIDIA's driver (version 190.29) @@ -891,7 +902,12 @@ void function_info::add_param_data( unsigned argn, struct gpgpu_ptx_sim_arg *arg else { // clSetKernelArg was passed NULL pointer for data... // this is used for dynamically sized shared memory on NVIDIA platforms - if( !p->is_shared() ) { + bool is_ptr_shared = false; + if( i != m_ptx_kernel_param_info.end() ) { + is_ptr_shared = i->second.is_ptr_shared(); + } + + if( !is_ptr_shared and !p->is_shared() ) { printf("GPGPU-Sim PTX: ERROR ** clSetKernelArg passed NULL but arg not shared memory\n"); abort(); } @@ -915,6 +931,7 @@ void function_info::finalize( memory_space *param_mem ) unsigned param_address = 0; for( std::map<unsigned,param_info>::iterator i=m_ptx_kernel_param_info.begin(); i!=m_ptx_kernel_param_info.end(); i++ ) { param_info &p = i->second; + if (p.is_ptr_shared()) continue; // Pointer to local memory: Should we pass the allocated shared memory address to the param memory space? std::string name = p.get_name(); int type = p.get_type(); param_t param_value = p.get_value(); @@ -924,7 +941,7 @@ void function_info::finalize( memory_space *param_mem ) assert(xtype==(unsigned)type); size_t size; size = param_value.size; // size of param in bytes - //assert(param_value.offset == param_address); + // assert(param_value.offset == param_address); if( size != p.get_size() / 8) { printf("GPGPU-Sim PTX: WARNING actual kernel paramter size = %zu bytes vs. formal size = %zu (using smaller of two)\n", size, p.get_size()/8); @@ -943,9 +960,14 @@ void function_info::finalize( memory_space *param_mem ) void function_info::param_to_shared( memory_space *shared_mem, symbol_table *symtab ) { -/*copies parameters into simulated shared memory*/ + // TODO: call this only for PTXPlus with GT200 models + extern gpgpu_sim* g_the_gpu; + if (g_the_gpu->get_config().convert_to_ptxplus()) return; + + // copies parameters into simulated shared memory for( std::map<unsigned,param_info>::iterator i=m_ptx_kernel_param_info.begin(); i!=m_ptx_kernel_param_info.end(); i++ ) { param_info &p = i->second; + if (p.is_ptr_shared()) continue; // Pointer to local memory: Should we pass the allocated shared memory address to the param memory space? std::string name = p.get_name(); int type = p.get_type(); param_t value = p.get_value(); diff --git a/src/cuda-sim/ptx.y b/src/cuda-sim/ptx.y index f8b29c4..c4d8b06 100644 --- a/src/cuda-sim/ptx.y +++ b/src/cuda-sim/ptx.y @@ -250,10 +250,9 @@ ptr_spec: /*empty*/ | PTR_DIRECTIVE ptr_space_spec ptr_align_spec | PTR_DIRECTIVE ptr_align_spec -ptr_space_spec: GLOBAL_DIRECTIVE - | LOCAL_DIRECTIVE - | CONST_DIRECTIVE - | SHARED_DIRECTIVE +ptr_space_spec: GLOBAL_DIRECTIVE { add_ptr_spec(global_space); } + | LOCAL_DIRECTIVE { add_ptr_spec(local_space); } + | SHARED_DIRECTIVE { add_ptr_spec(shared_space); } ptr_align_spec: ALIGN_DIRECTIVE INT_OPERAND diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index ffd0c58..044bce6 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -994,14 +994,16 @@ private: class param_info { public: - param_info() { m_valid = false; m_value_set=false; m_size = 0; } - param_info( std::string name, int type, size_t size ) + param_info() { m_valid = false; m_value_set=false; m_size = 0; m_is_ptr = false; } + param_info( std::string name, int type, size_t size, bool is_ptr, memory_space_t ptr_space ) { m_valid = true; m_value_set = false; m_name = name; m_type = type; m_size = size; + m_is_ptr = is_ptr; + m_ptr_space = ptr_space; } void add_data( param_t v ) { assert( (!m_value_set) || (m_value.size == v.size) ); // if this fails concurrent kernel launches might execute incorrectly @@ -1014,6 +1016,7 @@ public: int get_type() const { assert(m_valid); return m_type; } param_t get_value() const { assert(m_value_set); return m_value; } size_t get_size() const { assert(m_valid); return m_size; } + bool is_ptr_shared() const { assert(m_valid); return (m_is_ptr and m_ptr_space == shared_space); } private: bool m_valid; std::string m_name; @@ -1022,6 +1025,8 @@ private: bool m_value_set; param_t m_value; unsigned m_offset; + bool m_is_ptr; + memory_space_t m_ptr_space; }; class function_info { @@ -1093,7 +1098,7 @@ public: { m_kernel_params[ name ] = value; } - void add_param_name_type_size( unsigned index, std::string name, int type, size_t size ); + void add_param_name_type_size( unsigned index, std::string name, int type, size_t size, bool ptr, memory_space_t space ); void add_param_data( unsigned argn, struct gpgpu_ptx_sim_arg *args ); void add_return_var( const symbol *rv ) { diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc index ddc67c1..d33007b 100644 --- a/src/cuda-sim/ptx_parser.cc +++ b/src/cuda-sim/ptx_parser.cc @@ -55,6 +55,7 @@ int g_error_detected = 0; // type specifier stuff: memory_space_t g_space_spec = undefined_space; +memory_space_t g_ptr_spec = undefined_space; int g_scalar_type_spec = -1; int g_vector_spec = -1; int g_alignment_spec = -1; @@ -127,6 +128,7 @@ void init_directive_state() { DPRINTF("init_directive_state"); g_space_spec=undefined_space; + g_ptr_spec=undefined_space; g_scalar_type_spec=-1; g_vector_spec=-1; g_opcode=-1; @@ -347,7 +349,7 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident g_last_symbol = s; if( g_func_decl ) return; - std::string msg = std::string(identifier) + " was delcared previous at " + s->decl_location() + " skipping new declaration"; + std::string msg = std::string(identifier) + " was declared previous at " + s->decl_location() + " skipping new declaration"; printf("GPGPU-Sim PTX: Warning %s\n", msg.c_str()); return; } @@ -475,7 +477,8 @@ void add_identifier( const char *identifier, int array_dim, unsigned array_ident assert( !ti.is_param_unclassified() ); if ( ti.is_param_kernel() ) { - g_func_info->add_param_name_type_size(g_entry_func_param_index,identifier, ti.scalar_type(), num_bits ); + bool is_ptr = (g_ptr_spec != undefined_space); + g_func_info->add_param_name_type_size(g_entry_func_param_index,identifier, ti.scalar_type(), num_bits, is_ptr, g_ptr_spec); g_entry_func_param_index++; } } @@ -516,6 +519,14 @@ void add_alignment_spec( int spec ) g_alignment_spec = spec; } +void add_ptr_spec( enum _memory_space_t spec ) +{ + DPRINTF("add_ptr_spec \"%s\"", g_ptx_token_decode[spec].c_str() ); + parse_assert( g_ptr_spec == undefined_space, "multiple ptr space specifiers not allowed." ); + parse_assert( spec == global_space or spec == local_space or spec == shared_space, "invalid space for ptr directive." ); + g_ptr_spec = spec; +} + void add_space_spec( enum _memory_space_t spec, int value ) { DPRINTF("add_space_spec \"%s\"", g_ptx_token_decode[spec].c_str() ); diff --git a/src/cuda-sim/ptx_parser.h b/src/cuda-sim/ptx_parser.h index edaa7af..7405dd3 100644 --- a/src/cuda-sim/ptx_parser.h +++ b/src/cuda-sim/ptx_parser.h @@ -69,6 +69,7 @@ void add_address_operand2( int offset ); void add_label( const char *idenfiier ); void add_vector_spec(int spec ); void add_space_spec( enum _memory_space_t spec, int value ); +void add_ptr_spec( enum _memory_space_t spec ); void add_extern_spec(); void add_instruction(); void set_return(); |
