diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/abstract_hardware_model.h | 25 | ||||
| -rw-r--r-- | src/cuda-sim/cuda-sim.cc | 4 | ||||
| -rw-r--r-- | src/cuda-sim/instructions.cc | 53 |
3 files changed, 80 insertions, 2 deletions
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 766dff1..b6a4111 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -318,6 +318,21 @@ struct textureReference { #endif +// Struct that record other attributes in the textureReference declaration +// - These attributes are passed thru __cudaRegisterTexture() +struct textureReferenceAttr { + const struct textureReference *m_texref; + int m_dim; + enum cudaTextureReadMode m_readmode; + int m_ext; + textureReferenceAttr(const struct textureReference *texref, + int dim, + enum cudaTextureReadMode readmode, + int ext) + : m_texref(texref), m_dim(dim), m_readmode(readmode), m_ext(ext) + { } +}; + class gpgpu_functional_sim_config { public: @@ -364,7 +379,7 @@ public: class memory_space *get_surf_memory() { return m_surf_mem; } void gpgpu_ptx_sim_bindTextureToArray(const struct textureReference* texref, const struct cudaArray* array); - void gpgpu_ptx_sim_bindNameToTexture(const char* name, const struct textureReference* texref); + void gpgpu_ptx_sim_bindNameToTexture(const char* name, const struct textureReference* texref, int dim, int readmode, int ext); const char* gpgpu_ptx_sim_findNamefromTexture(const struct textureReference* texref); const struct textureReference* get_texref(const std::string &texname) const @@ -386,6 +401,13 @@ public: return t->second; } + const struct textureReferenceAttr* get_texattr( const struct textureReference *texref ) const + { + std::map<const struct textureReference*, const struct textureReferenceAttr*>::const_iterator t=m_TextureRefToAttribute.find(texref); + assert(t != m_TextureRefToAttribute.end()); + return t->second; + } + const gpgpu_functional_sim_config &get_config() const { return m_function_model_config; } FILE* get_ptx_inst_debug_file() { return ptx_inst_debug_file; } @@ -402,6 +424,7 @@ protected: std::map<std::string, const struct textureReference*> m_NameToTextureRef; std::map<const struct textureReference*,const struct cudaArray*> m_TextureRefToCudaArray; std::map<const struct textureReference*, const struct textureInfo*> m_TextureRefToTexureInfo; + std::map<const struct textureReference*, const struct textureReferenceAttr*> m_TextureRefToAttribute; }; struct gpgpu_ptx_sim_kernel_info diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index e6677fa..06fb7d3 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -93,10 +93,12 @@ void ptx_opcocde_latency_options (option_parser_t opp) { static address_type get_converge_point(address_type pc); -void gpgpu_t::gpgpu_ptx_sim_bindNameToTexture(const char* name, const struct textureReference* texref) +void gpgpu_t::gpgpu_ptx_sim_bindNameToTexture(const char* name, const struct textureReference* texref, int dim, int readmode, int ext) { std::string texname(name); m_NameToTextureRef[texname] = texref; + const textureReferenceAttr *texAttr = new textureReferenceAttr(texref, dim, (enum cudaTextureReadMode)readmode, ext); + m_TextureRefToAttribute[texref] = texAttr; } const char* gpgpu_t::gpgpu_ptx_sim_findNamefromTexture(const struct textureReference* texref) diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 237bfd5..65d3af8 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -3642,6 +3642,50 @@ float tex_linf_sampling(memory_space* mem, unsigned tex_array_base, return sample; } +float textureNormalizeElementSigned(int element, int bits) +{ + if (bits) { + int maxN = (1 << bits) - 1; + // removing upper bits + element &= maxN; + // normalizing the number to [-1.0,1.0] + maxN >>= 1; + float output = (float) element / maxN; + if (output < -1.0f) output = -1.0f; + return output; + } else { + return 0.0f; + } +} + +float textureNormalizeElementUnsigned(unsigned int element, int bits) +{ + if (bits) { + unsigned int maxN = (1 << bits) - 1; + // removing upper bits and normalizing the number to [0.0,1.0] + return (float)(element & maxN) / maxN; + } else { + return 0.0f; + } +} + +void textureNormalizeOutput( const struct cudaChannelFormatDesc& desc, ptx_reg_t& datax, ptx_reg_t& datay, ptx_reg_t& dataz, ptx_reg_t& dataw ) +{ + if (desc.f == cudaChannelFormatKindSigned) { + datax.f32 = textureNormalizeElementSigned( datax.s32, desc.x ); + datay.f32 = textureNormalizeElementSigned( datay.s32, desc.y ); + dataz.f32 = textureNormalizeElementSigned( dataz.s32, desc.z ); + dataw.f32 = textureNormalizeElementSigned( dataw.s32, desc.w ); + } else if (desc.f == cudaChannelFormatKindUnsigned) { + datax.f32 = textureNormalizeElementUnsigned( datax.u32, desc.x ); + datay.f32 = textureNormalizeElementUnsigned( datay.u32, desc.y ); + dataz.f32 = textureNormalizeElementUnsigned( dataz.u32, desc.z ); + dataw.f32 = textureNormalizeElementUnsigned( dataw.u32, desc.w ); + } else { + assert(0 && "Undefined texture read mode: cudaReadModeNormalizedFloat expect integer elements"); + } +} + void tex_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { unsigned dimension = pI->dimension(); @@ -3661,6 +3705,7 @@ void tex_impl( const ptx_instruction *pI, ptx_thread_info *thread ) const struct textureReference* texref = gpu->get_texref(texname); const struct cudaArray* cuArray = gpu->get_texarray(texref); const struct textureInfo* texInfo = gpu->get_texinfo(texref); + const struct textureReferenceAttr* texAttr = gpu->get_texattr(texref); //assume always 2D f32 input //access array with src2 coordinates @@ -3878,6 +3923,14 @@ void tex_impl( const ptx_instruction *pI, ptx_thread_info *thread ) assert(0); } thread->m_last_memory_space = tex_space; + + // normalize output into floating point numbers according to the texture read mode + if (texAttr->m_readmode == cudaReadModeNormalizedFloat) { + textureNormalizeOutput(cuArray->desc, data1, data2, data3, data4); + } else { + assert(texAttr->m_readmode == cudaReadModeElementType); + } + thread->set_vector_operand_values(dst,data1,data2,data3,data4); } |
