diff options
Diffstat (limited to 'src/cuda-sim')
| -rw-r--r-- | src/cuda-sim/cuda-sim.cc | 2 | ||||
| -rw-r--r-- | src/cuda-sim/cuda_device_runtime.h | 1 | ||||
| -rw-r--r-- | src/cuda-sim/instructions.cc | 138 | ||||
| -rw-r--r-- | src/cuda-sim/opcodes.def | 1 | ||||
| -rw-r--r-- | src/cuda-sim/ptx-stats.cc | 34 | ||||
| -rw-r--r-- | src/cuda-sim/ptx.l | 1 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_ir.cc | 3 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_ir.h | 14 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_loader.cc | 3 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_parser.cc | 10 |
10 files changed, 177 insertions, 30 deletions
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index 75dd3c8..71f0703 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -1741,7 +1741,7 @@ void ptx_thread_info::ptx_exec_inst(warp_inst_t &inst, unsigned lane_id) { } else { const ptx_instruction *pI_saved = pI; ptx_instruction *pJ = NULL; - if (pI->get_opcode() == VOTE_OP) { + if (pI->get_opcode() == VOTE_OP || pI->get_opcode() == ACTIVEMASK_OP) { pJ = new ptx_instruction(*pI); *((warp_inst_t *)pJ) = inst; // copy active mask information pI = pJ; diff --git a/src/cuda-sim/cuda_device_runtime.h b/src/cuda-sim/cuda_device_runtime.h index 1d661b2..b06dd24 100644 --- a/src/cuda-sim/cuda_device_runtime.h +++ b/src/cuda-sim/cuda_device_runtime.h @@ -43,6 +43,7 @@ class cuda_device_runtime { std::map<void*, device_launch_config_t> g_cuda_device_launch_param_map; std::list<device_launch_operation_t> g_cuda_device_launch_op; unsigned g_kernel_launch_latency; + unsigned g_TB_launch_latency; unsigned long long g_max_total_param_size; bool g_cdp_enabled; diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index bf9a040..8936fa8 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -166,6 +166,8 @@ void inst_not_implemented(const ptx_instruction *pI); ptx_reg_t srcOperandModifiers(ptx_reg_t opData, operand_info opInfo, operand_info dstInfo, unsigned type, ptx_thread_info *thread); + +void video_mem_instruction(const ptx_instruction *pI, ptx_thread_info *thread, int op_code); void sign_extend(ptx_reg_t &data, unsigned src_size, const operand_info &dst); @@ -1709,8 +1711,40 @@ void bfi_impl(const ptx_instruction *pI, ptx_thread_info *thread) { } thread->set_operand_value(dst, data, i_type, thread, pI); } -void bfind_impl(const ptx_instruction *pI, ptx_thread_info *thread) { - inst_not_implemented(pI); +void bfind_impl(const ptx_instruction *pI, ptx_thread_info *thread) +{ + const operand_info &dst = pI->dst(); + const operand_info &src1 = pI->src1(); + const unsigned i_type = pI->get_type(); + + const ptx_reg_t src1_data = thread->get_operand_value(src1, dst, i_type, thread, 1); + const int msb = ( i_type == U32_TYPE || i_type == S32_TYPE) ? 31 : 63; + + unsigned long a = 0; + switch (i_type) + { + case S32_TYPE: a = src1_data.s32; break; + case U32_TYPE: a = src1_data.u32; break; + case S64_TYPE: a = src1_data.s64; break; + case U64_TYPE: a = src1_data.u64; break; + default: assert(false); abort(); + } + + // negate negative signed inputs + if ( ( i_type == S32_TYPE || i_type == S64_TYPE ) && ( a & ( 1 << msb ) ) ) { + a = ~a; + } + uint32_t d_data = 0xffffffff; + for (uint32_t i = msb; i >= 0; i--) { + if (a & (1<<i)) { d_data = i; break; } + } + + // if (.shiftamt && d != 0xffffffff) { d = msb - d; } + + // store d + thread->set_operand_value(dst, d_data, U32_TYPE, thread, pI); + + } void bra_impl(const ptx_instruction *pI, ptx_thread_info *thread) { @@ -6301,11 +6335,17 @@ void vadd_impl(const ptx_instruction *pI, ptx_thread_info *thread) { void vmad_impl(const ptx_instruction *pI, ptx_thread_info *thread) { inst_not_implemented(pI); } -void vmax_impl(const ptx_instruction *pI, ptx_thread_info *thread) { - inst_not_implemented(pI); + +#define VMAX 0 +#define VMIN 1 + +void vmax_impl(const ptx_instruction *pI, ptx_thread_info *thread) +{ + video_mem_instruction(pI, thread, VMAX); } -void vmin_impl(const ptx_instruction *pI, ptx_thread_info *thread) { - inst_not_implemented(pI); +void vmin_impl(const ptx_instruction *pI, ptx_thread_info *thread) +{ + video_mem_instruction(pI, thread, VMIN); } void vset_impl(const ptx_instruction *pI, ptx_thread_info *thread) { inst_not_implemented(pI); @@ -6400,6 +6440,15 @@ void vote_impl(const ptx_instruction *pI, ptx_thread_info *thread) { } } +void activemask_impl( const ptx_instruction *pI, ptx_thread_info *thread ) +{ + active_mask_t l_activemask_bitset = pI->get_warp_active_mask(); + uint32_t l_activemask_uint = static_cast<uint32_t>(l_activemask_bitset.to_ulong()); + + const operand_info &dst = pI->dst(); + thread->set_operand_value(dst, l_activemask_uint, U32_TYPE, thread, pI); +} + void xor_impl(const ptx_instruction *pI, ptx_thread_info *thread) { ptx_reg_t src1_data, src2_data, data; @@ -6477,3 +6526,80 @@ ptx_reg_t srcOperandModifiers(ptx_reg_t opData, operand_info opInfo, return result; } + +void video_mem_instruction(const ptx_instruction *pI, ptx_thread_info *thread, int op_code) +{ + const operand_info &dst = pI->dst(); // d + const operand_info &src1 = pI->src1(); // a + const operand_info &src2 = pI->src2(); // b + const operand_info &src3 = pI->src3(); // c + + const unsigned i_type = pI->get_type(); + + std::list<int> scalar_type; + std::list<int> options; + + ptx_reg_t a, b, ta, tb, c, data; + + a = thread->get_operand_value(src1, dst, i_type, thread, 1); + b = thread->get_operand_value(src2, dst, i_type, thread, 1); + c = thread->get_operand_value(src3, dst, i_type, thread, 1); + + // TODO: implement this + // ta = partSelectSignExtend( a, atype ); + // tb = partSelectSignExtend( b, btype ); + ta = a; + tb = b; + + options = pI->get_options(); + assert(options.size() == 1); + + auto option = options.begin(); + assert(*option == ATOMIC_MAX || *option == ATOMIC_MIN); + + switch ( i_type ) { + case S32_TYPE: { + // assert all operands are S32_TYPE: + scalar_type = pI->get_scalar_type(); + for (std::list<int>::iterator scalar = scalar_type.begin(); scalar != scalar_type.end(); scalar++) + { + assert(*scalar == S32_TYPE); + } + assert(scalar_type.size() == 3); + scalar_type.clear(); + + switch (op_code) + { + case VMAX: + data.s32 = MY_MAX_I(ta.s32, tb.s32); + break; + case VMIN: + data.s32 = MY_MIN_I(ta.s32, tb.s32); + break; + default: + assert(0); + } + + switch (*option) + { + case ATOMIC_MAX: + data.s32 = MY_MAX_I(data.s32, c.s32); + break; + case ATOMIC_MIN: + data.s32 = MY_MIN_I(data.s32, c.s32); + break; + default: + assert(0); // not yet implemented + } + break; + + } + default: + assert(0); // not yet implemented + } + + thread->set_operand_value(dst, data, i_type, thread, pI); + + return; +} + diff --git a/src/cuda-sim/opcodes.def b/src/cuda-sim/opcodes.def index c4d6a83..f5bf156 100644 --- a/src/cuda-sim/opcodes.def +++ b/src/cuda-sim/opcodes.def @@ -129,6 +129,7 @@ OP_DEF(VSHL_OP,vshl_impl,"vshl",0,11) OP_DEF(VSHR_OP,vshr_impl,"vshr",0,11) OP_DEF(VSUB_OP,vsub_impl,"vsub",0,11) OP_DEF(VOTE_OP,vote_impl,"vote",0,3) +OP_DEF(ACTIVEMASK_OP,activemask_impl,"activemask",1,3) OP_DEF(XOR_OP,xor_impl,"xor",1,1) OP_DEF(NOP_OP,nop_impl,"nop",0,7) OP_DEF(BREAK_OP,break_impl,"break",0,3) diff --git a/src/cuda-sim/ptx-stats.cc b/src/cuda-sim/ptx-stats.cc index 9f7e760..3e96984 100644 --- a/src/cuda-sim/ptx-stats.cc +++ b/src/cuda-sim/ptx-stats.cc @@ -168,9 +168,10 @@ void ptx_file_line_stats_add_exec_count(const ptx_instruction *pInsn) { void ptx_stats::ptx_file_line_stats_add_latency(unsigned pc, unsigned latency) { const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); - ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), - pInsn->source_line())] - .latency += latency; + if (pInsn != NULL) + ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), + pInsn->source_line())] + .latency += latency; } // attribute dram traffic to this ptx instruction (specified by the pc) @@ -179,9 +180,10 @@ void ptx_stats::ptx_file_line_stats_add_dram_traffic(unsigned pc, unsigned dram_traffic) { const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); - ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), - pInsn->source_line())] - .dram_traffic += dram_traffic; + if (pInsn != NULL) + ptx_file_line_stats_tracker[ptx_file_line(pInsn->source_file(), + pInsn->source_line())] + .dram_traffic += dram_traffic; } // attribute the number of shared memory access cycles to a ptx instruction @@ -191,10 +193,12 @@ void ptx_stats::ptx_file_line_stats_add_smem_bank_conflict( unsigned pc, unsigned n_way_bkconflict) { const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); - ptx_file_line_stats &line_stats = ptx_file_line_stats_tracker[ptx_file_line( - pInsn->source_file(), pInsn->source_line())]; - line_stats.smem_n_way_bank_conflict_total += n_way_bkconflict; - line_stats.smem_warp_count += 1; + if (pInsn != NULL) { + ptx_file_line_stats &line_stats = ptx_file_line_stats_tracker[ptx_file_line( + pInsn->source_file(), pInsn->source_line())]; + line_stats.smem_n_way_bank_conflict_total += n_way_bkconflict; + line_stats.smem_warp_count += 1; + } } // attribute a non-coalesced mem access to a ptx instruction @@ -204,10 +208,12 @@ void ptx_stats::ptx_file_line_stats_add_uncoalesced_gmem(unsigned pc, unsigned n_access) { const ptx_instruction *pInsn = gpgpu_ctx->pc_to_instruction(pc); - ptx_file_line_stats &line_stats = ptx_file_line_stats_tracker[ptx_file_line( - pInsn->source_file(), pInsn->source_line())]; - line_stats.gmem_n_access_total += n_access; - line_stats.gmem_warp_count += 1; + if (pInsn != NULL) { + ptx_file_line_stats &line_stats = ptx_file_line_stats_tracker[ptx_file_line( + pInsn->source_file(), pInsn->source_line())]; + line_stats.gmem_n_access_total += n_access; + line_stats.gmem_warp_count += 1; + } } // a class that tracks the inflight memory instructions of a shader core diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l index 2dadda4..6754045 100644 --- a/src/cuda-sim/ptx.l +++ b/src/cuda-sim/ptx.l @@ -158,6 +158,7 @@ vshl TC; yylval->int_value = VSHL_OP; return OPCODE; vshr TC; yylval->int_value = VSHR_OP; return OPCODE; vsub TC; yylval->int_value = VSUB_OP; return OPCODE; vote TC; yylval->int_value = VOTE_OP; return OPCODE; +activemask TC; yylval->int_value = ACTIVEMASK_OP; return OPCODE; xor TC; yylval->int_value = XOR_OP; return OPCODE; nop TC; yylval->int_value = NOP_OP; return OPCODE; break TC; yylval->int_value = BREAK_OP; return OPCODE; diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc index aa1c25a..e5b5fb7 100644 --- a/src/cuda-sim/ptx_ir.cc +++ b/src/cuda-sim/ptx_ir.cc @@ -1147,7 +1147,8 @@ static std::list<operand_info> check_operands( const std::list<operand_info> &operands, gpgpu_context *ctx) { static int g_warn_literal_operands_two_type_inst; if ((opcode == CVT_OP) || (opcode == SET_OP) || (opcode == SLCT_OP) || - (opcode == TEX_OP) || (opcode == MMA_OP) || (opcode == DP4A_OP)) { + (opcode == TEX_OP) || (opcode == MMA_OP) || (opcode == DP4A_OP) || + (opcode == VMIN_OP) || (opcode == VMAX_OP) ) { // just make sure these do not have have const operands... if (!g_warn_literal_operands_two_type_inst) { std::list<operand_info>::const_iterator o; diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index 6627847..4243941 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -966,6 +966,9 @@ class ptx_instruction : public warp_inst_t { int get_pred_mod() const { return m_pred_mod; } const char *get_source() const { return m_source.c_str(); } + const std::list<int> get_scalar_type() const {return m_scalar_type;} + const std::list<int> get_options() const {return m_options;} + typedef std::vector<operand_info>::const_iterator const_iterator; const_iterator op_iter_begin() const { return m_operands.begin(); } @@ -1336,12 +1339,12 @@ class function_info { memory_space *param_mem, gpgpu_t *gpu, dim3 gridDim, dim3 blockDim); - const struct gpgpu_ptx_sim_info *get_kernel_info() const { + virtual const struct gpgpu_ptx_sim_info *get_kernel_info() const { assert(m_kernel_info.maxthreads == maxnt_id); return &m_kernel_info; } - const void set_kernel_info(const struct gpgpu_ptx_sim_info &info) { + virtual const void set_kernel_info(const struct gpgpu_ptx_sim_info &info) { m_kernel_info = info; m_kernel_info.ptx_version = 10 * get_ptx_version().ver(); m_kernel_info.sm_target = get_ptx_version().target(); @@ -1377,6 +1380,11 @@ class function_info { // backward pointer class gpgpu_context *gpgpu_ctx; + protected: + // Registers/shmem/etc. used (from ptxas -v), loaded from ___.ptxinfo along + // with ___.ptx + struct gpgpu_ptx_sim_info m_kernel_info; + private: unsigned maxnt_id; unsigned m_uid; @@ -1402,7 +1410,7 @@ class function_info { // Registers/shmem/etc. used (from ptxas -v), loaded from ___.ptxinfo along // with ___.ptx - struct gpgpu_ptx_sim_info m_kernel_info; + // with ___.ptx symbol_table *m_symtab; diff --git a/src/cuda-sim/ptx_loader.cc b/src/cuda-sim/ptx_loader.cc index 372bda4..4e91763 100644 --- a/src/cuda-sim/ptx_loader.cc +++ b/src/cuda-sim/ptx_loader.cc @@ -38,7 +38,8 @@ /// extern prototypes -extern int ptx_error(yyscan_t yyscanner, const char *s); +extern int ptx_error(yyscan_t yyscanner, ptx_recognizer *recognizer, + const char *s); extern int ptx_lex_init(yyscan_t *scanner); extern void ptx_set_in(FILE *_in_str, yyscan_t yyscanner); extern int ptx_parse(yyscan_t scanner, ptx_recognizer *recognizer); diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc index 3ae8de3..afdb41b 100644 --- a/src/cuda-sim/ptx_parser.cc +++ b/src/cuda-sim/ptx_parser.cc @@ -36,7 +36,8 @@ typedef void *yyscan_t; extern int ptx_get_lineno(yyscan_t yyscanner); extern YYSTYPE *ptx_get_lval(yyscan_t yyscanner); -extern int ptx_error(yyscan_t yyscanner, const char *s); +extern int ptx_error(yyscan_t yyscanner, ptx_recognizer *recognizer, + const char *s); extern int ptx_lex_init(yyscan_t *scanner); extern void ptx_set_in(FILE *_in_str, yyscan_t yyscanner); extern FILE *ptx_get_in(yyscan_t yyscanner); @@ -225,7 +226,7 @@ void ptx_recognizer::parse_error_impl(const char *file, unsigned line, g_error_detected = 1; printf("%s:%u: Parse error: %s (%s:%u)\n\n", gpgpu_ctx->g_filename, ptx_get_lineno(scanner), buf, file, line); - ptx_error(scanner, NULL); + ptx_error(scanner, this, NULL); abort(); exit(1); } @@ -624,8 +625,9 @@ void ptx_recognizer::add_scalar_type_spec(int type_spec) { parse_assert((g_opcode == -1) || (g_opcode == CVT_OP) || (g_opcode == SET_OP) || (g_opcode == SLCT_OP) || (g_opcode == TEX_OP) || (g_opcode == MMA_OP) || - (g_opcode == DP4A_OP), - "only cvt, set, slct, tex and dp4a can have more than one " + (g_opcode == DP4A_OP) || (g_opcode == VMIN_OP) || + (g_opcode == VMAX_OP), + "only cvt, set, slct, tex, vmin, vmax and dp4a can have more than one " "type specifier."); } g_scalar_type_spec = type_spec; |
