diff options
| -rw-r--r-- | src/abstract_hardware_model.h | 6 | ||||
| -rw-r--r-- | src/cuda-sim/cuda-sim.cc | 11 | ||||
| -rw-r--r-- | src/cuda-sim/instructions.cc | 213 | ||||
| -rw-r--r-- | src/cuda-sim/opcodes.def | 2 | ||||
| -rw-r--r-- | src/cuda-sim/ptx.l | 2 | ||||
| -rw-r--r-- | src/cuda-sim/ptx_ir.h | 25 | ||||
| -rw-r--r-- | src/gpgpu-sim/scoreboard.cc | 4 | ||||
| -rw-r--r-- | src/gpgpusim_entrypoint.cc | 1 |
8 files changed, 136 insertions, 128 deletions
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index cdd9cf3..9dc58d4 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -750,7 +750,7 @@ public: }; // the maximum number of destination, source, or address uarch operands in a instruction -#define MAX_REG_OPERANDS 8 +#define MAX_REG_OPERANDS 32 struct dram_callback_t { dram_callback_t() { function=NULL; instruction=NULL; thread=NULL; } @@ -825,8 +825,8 @@ public: address_type reconvergence_pc; // -1 => not a branch, -2 => use function return address - unsigned out[4]; - unsigned in[4]; + unsigned out[8]; + unsigned in[8]; unsigned char is_vectorin; unsigned char is_vectorout; int pred; // predicate register number diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index 54d8796..006738a 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -792,9 +792,9 @@ void ptx_instruction::set_opcode_and_latency() initiation_interval = dp_init[2]; op = SFU_OP; break; - case BSMAD_OP: - latency = int_precision/int_lane_width; - initiation_interval = int_init_precision/int_init_lane_width; + case MMA_OP: + latency = 64; + initiation_interval = 64; break; case SHFL_OP: latency = 32; @@ -1301,6 +1301,7 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id) *((warp_inst_t*)pJ) = inst; // copy active mask information pI = pJ; } + if((pI->get_opcode()!=MMA_OP)||((pI->get_opcode()==MMA_OP)&&(lane_id==0))){ switch ( pI->get_opcode() ) { #define OP_DEF(OP,FUNC,STR,DST,CLASSIFICATION) case OP: FUNC(pI,this); op_classification = CLASSIFICATION; break; #define OP_W_DEF(OP,FUNC,STR,DST,CLASSIFICATION) case OP: FUNC(pI,get_core(),inst); op_classification = CLASSIFICATION; break; @@ -1308,7 +1309,7 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id) #undef OP_DEF #undef OP_W_DEF default: printf( "Execution error: Invalid opcode (0x%x)\n", pI->get_opcode() ); break; - } + }} delete pJ; pI = pI_saved; @@ -1930,7 +1931,7 @@ void functionalCoreSim::executeWarp(unsigned i, bool &allAtBarrier, bool & someO { if(!m_warpAtBarrier[i] && m_liveThreadCount[i]!=0){ warp_inst_t inst =getExecuteWarp(i); - execute_warp_inst_t(inst,i); + execute_warp_inst_t(inst,i); if(inst.isatomic()) inst.do_atomic(true); if(inst.op==BARRIER_OP || inst.op==MEMORY_BARRIER_OP ) m_warpAtBarrier[i]=true; updateSIMTStack( i, &inst ); diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 493e307..7903343 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -771,6 +771,17 @@ void add_impl( const ptx_instruction *pI, ptx_thread_info *thread ) unsigned i_type = pI->get_type(); src1_data = thread->get_operand_value(src1, dst, i_type, thread, 1); src2_data = thread->get_operand_value(src2, dst, i_type, thread, 1); + //unsigned warpId_aa,warp_size_aa; + //warpId_aa = pI->warp_id(); + //warp_size_aa=32; + //dim3 t=thread->get_tid(); + //unsigned tid_aa=warp_size_aa*warpId_aa; + + ptx_thread_info *thread2; + thread2=thread; + src1_data = thread2->get_operand_value(src1, dst, i_type, thread2, 1); + src2_data = thread2->get_operand_value(src2, dst, i_type, thread2, 1); + unsigned rounding_mode = pI->rounding_mode(); int orig_rm = fegetround(); @@ -1483,135 +1494,102 @@ unsigned trunc(unsigned num, unsigned precision) { return num; } -void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) +void mma_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) { - // operands: - // 0 = output - // 1 = input precision - // 2 = output precision - // 3 = buffer0 - // 4 = buffer1 - // 5 = buffer2 - // 6 = buffer3 - // 7 = synapse value - // 8 = output value + int i,j,k,thrd; + int row,offset; + printf("mmaWorld\n"); + ptx_reg_t matrix_a[16][16]; + ptx_reg_t matrix_b[16][16]; + ptx_reg_t matrix_c[16][16]; + ptx_reg_t matrix_d[16][16]; + ptx_reg_t src_data; + ptx_thread_info *thread; - const operand_info &dst = pI->dst(); - const operand_info &src1 = pI->src1(); - const operand_info &src2 = pI->src2(); unsigned type = pI->get_type(); int tid = inst.warp_id_func() * core->get_warp_size(); - ptx_thread_info *thread = core->get_thread_info()[tid]; - const int ip = (thread->get_operand_value(src1, dst, type, thread, 1)).u32; - const int op = (thread->get_operand_value(src2, dst, type, thread, 1)).u32; - const int THREADS = inst.active_count(); - const int INBUFFERS = 4; - const int OUTBUFFERS = (((32/ip)*INBUFFERS) / (32/op)) + ((((32/ip)*INBUFFERS) % (32/op)) != 0); - if (OUTBUFFERS > THREADS) { - printf("GPGPU-Sim PTX: BSMAD ERROR - Number of output registers required (%d) is greater than the number available (%d)\n", OUTBUFFERS, THREADS); - abort(); - } - ptx_warp_info *warp_info = thread->m_warp_info; - warp_info->inc_done_threads(); - - // threads within the warp are executed sequentially by the simulator, store output in first four registers - if (warp_info->get_done_threads() <= OUTBUFFERS) { - unsigned buffer[THREADS][INBUFFERS]; - unsigned synapse[THREADS]; - unsigned output; - - // loop through all threads in the warp and get all data - for (unsigned i = 0, j = 0; i < core->get_warp_size(); i++) { - if (inst.active(i)) { - const operand_info &src3 = pI->operand_lookup(3); - const operand_info &src4 = pI->operand_lookup(4); - const operand_info &src5 = pI->operand_lookup(5); - const operand_info &src6 = pI->operand_lookup(6); - const operand_info &src7 = pI->operand_lookup(7); - const operand_info &src8 = pI->operand_lookup(8); + const operand_info &dst = pI->operand_lookup(0); + +//NOT WOR thread = core->get_thread_info()[tid]; +//NOT WOR const operand_info &src_a= pI->operand_lookup(1); +//NOT WOR src_data= (thread->get_operand_value(src_a, dst, type, thread, 1)); +//NOT WOR thread->set_operand_value(dst, src_data, type, thread, pI); + for (thrd=0; thrd < core->get_warp_size(); thrd++){ + row=thrd/2; + offset=8*(thrd%2); + thread = core->get_thread_info()[tid+thrd]; + printf("thread=%d:",thrd); + for(i=8;i<=31;i++){ + const operand_info &src_a= pI->operand_lookup(i); + src_data= (thread->get_operand_value(src_a, dst, type, thread, 1)); + printf("%f ",src_data.f32); + if(i<=15) + matrix_a[row][offset+(i)%8]=src_data; + else if((i>15)&&(i<=23)) + matrix_b[row][offset+(i)%8]=src_data; + else if(i>23) + matrix_c[row][offset+(i)%8]=src_data; + - thread = core->get_thread_info()[tid+i]; - // get buffer data and synapse data from each thread - buffer[j][0] = (thread->get_operand_value(src3, dst, type, thread, 1)).u32; - buffer[j][1] = (thread->get_operand_value(src4, dst, type, thread, 1)).u32; - buffer[j][2] = (thread->get_operand_value(src5, dst, type, thread, 1)).u32; - buffer[j][3] = (thread->get_operand_value(src6, dst, type, thread, 1)).u32; - synapse[j] = (thread->get_operand_value(src7, dst, type, thread, 1)).u32; - j++; - // get output data from the first 4 threads - if (j == warp_info->get_done_threads()) { - output = (thread->get_operand_value(src8, dst, type, thread, 1)).u32; - } - } } + printf("\n"); + } - // unpack registers, compute enough outputs to fill an output register - unsigned *unpacked_output = (unsigned*)calloc(32/op,sizeof(unsigned)); - unsigned buffer_data_start = (32/op)*(warp_info->get_done_threads()-1); - for (unsigned i = buffer_data_start; i < (32/op + buffer_data_start) && i < (32/ip)*INBUFFERS; i++) { - unsigned buf = i/(32/ip); - unsigned pos = i%(32/ip); - // sum values from the buffers - int sum = 0; - unsigned mask = (unsigned)(pow(2,ip)-1) << (pos*ip); - for (int j = 0; j < THREADS; j++) { - //sum += ((mask & buffer[j][buf]) >> (pos*ip)) * synapse[j]; - sum += trunc(((mask & buffer[j][buf]) >> (pos*ip)) * synapse[j], op); - } - // get the previous output - mask = (unsigned)(pow(2,op)-1) << (op*(i-buffer_data_start)); - int past_output = (mask & output) >> (op*(i-buffer_data_start)); - unpacked_output[i-buffer_data_start] = trunc(trunc(sum,op) + past_output,op); - // truncate sum, truncate (truncated sum + past_output) + printf("MATRIX_A\n"); + for (i=0;i<16;i++){ + for(j=0;j<16;j++){ + printf("%f ",matrix_a[i][j].f32); } - - // truncate output - /*for (unsigned i = 0; i < 32/op; i++) { - int mask = 1, latest_one = -1; - unsigned data = unpacked_output[i]; - for (unsigned j = 0; j < sizeof(unsigned)*8; j++) { - int bit = data & mask; - if (bit == 1) latest_one = j; - data >>= 1; - } - if (latest_one >= op) { - // round_up is 1 if the most significant truncated digit is a 1, otherwise it is 0 - int round_up = (unpacked_output[i] & (1 << (latest_one-op))) >> (latest_one-op); - unsigned shifted_output = unpacked_output[i] >> (latest_one-op+1); - // if shifted_output is a number like 1111, don't round up - if (shifted_output == (pow(2,op)-1)) round_up = 0; - unpacked_output[i] = shifted_output + round_up; - } - }*/ - - // pack the outputs into one register - unsigned mask = pow(2,op)-1; - unsigned output_data = 0; - for (int i = 0; i < 32/op; i++) { - output_data |= (unpacked_output[i] & mask) << (op*i); + printf("\n"); + } + printf("MATRIX_B\n"); + for (i=0;i<16;i++){ + for(j=0;j<16;j++){ + printf("%f ",matrix_b[i][j].f32); } - - // store the result in the correct thread's output register - for (unsigned i = 0, j = 0; i < core->get_warp_size(); i++) { - if (inst.active(i)) j++; - if (j == warp_info->get_done_threads()) { - thread = core->get_thread_info()[tid+i]; - ptx_reg_t data; - data.u32 = output_data; - thread->set_operand_value(dst, data, type, thread, pI); - break; + printf("\n"); + } + printf("MATRIX_C\n"); + for (i=0;i<16;i++){ + for(j=0;j<16;j++){ + printf("%f ",matrix_c[i][j].f32); + } + printf("\n"); + } + for (i=0;i<16;i++){ + for(j=0;j<16;j++){ + matrix_d[i][j].f32=0; + } + } + + for (i=0;i<16;i++){ + for(j=0;j<16;j++){ + for(k=0;k<16;k++){ + matrix_d[i][j].f32=matrix_d[i][j].f32+matrix_a[i][k].f32*matrix_b[j][k].f32; } + matrix_d[i][j].f32+=matrix_c[i][j].f32; } } - - // once the warp has finished, set the number of completed threads back to 0 for the next warp - if (warp_info->get_done_threads() == THREADS) { - warp_info->reset_done_threads(); + printf("MATRIX_D\n"); + for (i=0;i<16;i++){ + for(j=0;j<16;j++){ + printf("%f ",matrix_d[i][j].f32); + } + printf("\n"); + } + for (thrd=0; thrd < core->get_warp_size(); thrd++){ + thread = core->get_thread_info()[tid+thrd]; + row=thrd/2; + offset=8*(thrd%2); + for(i=0;i<8;i++){ + const operand_info &dst = pI->operand_lookup(i); + const symbol *r2; + r2=dst.get_symbol(); + printf("thrd=%d,i=%d,register%s, data=%f\n",thrd,i,(r2->name()).c_str(),matrix_d[row][offset+i].f32); + thread->set_operand_value(dst, matrix_d[row][offset+i], type, thread, pI); + } } - - // set the latency assuming 4 bits of each input get processed every cycle - // mutable latency variable??? - //pI->latency = (ip+3)/4; + } void call_impl( const ptx_instruction *pI, ptx_thread_info *thread ) @@ -4098,7 +4076,8 @@ void st_impl( const ptx_instruction *pI, ptx_thread_info *thread ) if (!vector_spec) { data = thread->get_operand_value(src1, dst, type, thread, 1); mem->write(addr,size/8,&data.s64,thread,pI); - } else { + printf("addr=%d data=%d\n",addr,data.s64); + } else { if (vector_spec == V2_TYPE) { ptx_reg_t* ptx_regs = new ptx_reg_t[2]; thread->get_vector_operand_values(src1, ptx_regs, 2); diff --git a/src/cuda-sim/opcodes.def b/src/cuda-sim/opcodes.def index 41f2f22..a3cc83f 100644 --- a/src/cuda-sim/opcodes.def +++ b/src/cuda-sim/opcodes.def @@ -52,7 +52,7 @@ OP_DEF(BRA_OP,bra_impl,"bra",0,3) OP_DEF(BRX_OP,brx_impl,"brx",0,3) OP_DEF(BREV_OP,brev_impl,"brev",1,1) OP_DEF(BRKPT_OP,brkpt_impl,"brkpt",1,9) -OP_W_DEF(BSMAD_OP,bsmad_impl,"bsmad",1,1) +OP_W_DEF(MMA_OP,mma_impl,"mma",1,1) OP_DEF(CALL_OP,call_impl,"call",1,3) OP_DEF(CALLP_OP,callp_impl,"callp",1,3) OP_DEF(CLZ_OP,clz_impl,"clz",1,1) diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l index 7620134..e07e339 100644 --- a/src/cuda-sim/ptx.l +++ b/src/cuda-sim/ptx.l @@ -68,7 +68,7 @@ bra TC; ptx_lval.int_value = BRA_OP; return OPCODE; brx TC; ptx_lval.int_value = BRX_OP; return OPCODE; brev TC; ptx_lval.int_value = BREV_OP; return OPCODE; brkpt TC; ptx_lval.int_value = BRKPT_OP; return OPCODE; -bsmad TC; ptx_lval.int_value = BSMAD_OP; return OPCODE; +mma TC; ptx_lval.int_value = MMA_OP; return OPCODE; call TC; BEGIN(NOT_OPCODE); ptx_lval.int_value = CALL_OP; return OPCODE; // blocking opcode token in case the callee has the same name as an opcode callp TC; BEGIN(NOT_OPCODE); ptx_lval.int_value = CALLP_OP; return OPCODE; clz TC; ptx_lval.int_value = CLZ_OP; return OPCODE; diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index 4c10373..0601b97 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -948,6 +948,31 @@ public: assert( m_operands.size() > 3 ); return m_operands[3]; } + const operand_info &src4() const + { + assert( m_operands.size() > 4 ); + return m_operands[4]; + } + const operand_info &src5() const + { + assert( m_operands.size() > 5 ); + return m_operands[5]; + } + const operand_info &src6() const + { + assert( m_operands.size() > 6 ); + return m_operands[6]; + } + const operand_info &src7() const + { + assert( m_operands.size() > 7 ); + return m_operands[7]; + } + const operand_info &src8() const + { + assert( m_operands.size() > 8 ); + return m_operands[8]; + } const operand_info &operand_lookup( unsigned n ) const { diff --git a/src/gpgpu-sim/scoreboard.cc b/src/gpgpu-sim/scoreboard.cc index f412054..b538fdf 100644 --- a/src/gpgpu-sim/scoreboard.cc +++ b/src/gpgpu-sim/scoreboard.cc @@ -146,6 +146,10 @@ bool Scoreboard::checkCollision( unsigned wid, const class inst_t *inst ) const if(inst->in[1] > 0) inst_regs.insert(inst->in[1]); if(inst->in[2] > 0) inst_regs.insert(inst->in[2]); if(inst->in[3] > 0) inst_regs.insert(inst->in[3]); + if(inst->in[3] > 0) inst_regs.insert(inst->in[4]); + if(inst->in[3] > 0) inst_regs.insert(inst->in[5]); + if(inst->in[3] > 0) inst_regs.insert(inst->in[6]); + if(inst->in[3] > 0) inst_regs.insert(inst->in[7]); if(inst->pred > 0) inst_regs.insert(inst->pred); if(inst->ar1 > 0) inst_regs.insert(inst->ar1); if(inst->ar2 > 0) inst_regs.insert(inst->ar2); diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc index 04845e7..a6d7eb4 100644 --- a/src/gpgpusim_entrypoint.cc +++ b/src/gpgpusim_entrypoint.cc @@ -134,7 +134,6 @@ void *gpgpu_sim_thread_concurrent(void*) gpgpu_cuda_ptx_sim_main_func(*kernel); g_the_gpu->finish_functional_sim(kernel); } - //performance simulation if( g_the_gpu->active() ) { g_the_gpu->cycle(); |
