summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilson Fung <[email protected]>2012-11-09 15:33:00 -0800
committerAndrew Boktor <[email protected]>2014-08-14 13:49:21 -0700
commit64ecf6992b5e0400877c2d1b479dddcadac6db69 (patch)
tree29497a626d6b45d31028ae8d7caac0a6fded8f37
parentc6becca8e1c9c188b515d4c66df66114ef448361 (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.h1
-rw-r--r--src/cuda-sim/cuda-sim.cc50
-rw-r--r--src/cuda-sim/ptx.y7
-rw-r--r--src/cuda-sim/ptx_ir.h11
-rw-r--r--src/cuda-sim/ptx_parser.cc15
-rw-r--r--src/cuda-sim/ptx_parser.h1
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();