From 35cf76f383ec8de6de901bbbcd8fb478f69e46e4 Mon Sep 17 00:00:00 2001 From: sspenst Date: Wed, 6 Jul 2016 13:56:52 -0700 Subject: Added sstarr memory, which works the same as shared memory --- src/abstract_hardware_model.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/abstract_hardware_model.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index b29f918..750eb6a 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -41,6 +41,7 @@ enum _memory_space_t { reg_space, local_space, shared_space, + sstarr_space, param_space_unclassified, param_space_kernel, /* global to all threads in a kernel : read-only */ param_space_local, /* local to a thread : read-writable */ -- cgit v1.3 From 19595382f05235b8887955c76794a976fad04833 Mon Sep 17 00:00:00 2001 From: sspenst Date: Thu, 7 Jul 2016 11:53:56 -0700 Subject: SST instruction now updates the original array instead of storing the result in sstarr memory --- src/abstract_hardware_model.h | 1 + src/cuda-sim/instructions.cc | 49 ++++++++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 22 deletions(-) (limited to 'src/abstract_hardware_model.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 750eb6a..6ed9b8e 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -554,6 +554,7 @@ public: return false; } enum _memory_space_t get_type() const { return m_type; } + void set_type( enum _memory_space_t t ) { m_type = t; } unsigned get_bank() const { return m_bank; } void set_bank( unsigned b ) { m_bank = b; } bool is_const() const { return (m_type == const_space) || (m_type == param_space_kernel); } diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 47f7075..d4b74fa 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -3747,10 +3747,11 @@ void sst_impl( const ptx_instruction *pI, ptx_thread_info *thread ) const operand_info &src3 = pI->src3(); unsigned type = pI->get_type(); ptx_reg_t src1_data = thread->get_operand_value(src1, src1, type, thread, 1); - ptx_reg_t src2_data, src3_data; + ptx_reg_t src2_data = thread->get_operand_value(src2, src1, type, thread, 1); + ptx_reg_t src3_data = thread->get_operand_value(src3, src1, type, thread, 1); memory_space_t space = pI->get_space(); memory_space *mem = NULL; - addr_t addr = src1_data.u32; + addr_t addr = src2_data.u32 * 4; // this assumes sstarr memory starts at address 0 decode_space(space,thread,src1,mem,addr); @@ -3758,13 +3759,8 @@ void sst_impl( const ptx_instruction *pI, ptx_thread_info *thread ) int t; type_info_key::type_decode(type,size,t); - src2_data = thread->get_operand_value(src2, src1, type, thread, 1); - src3_data = thread->get_operand_value(src3, src1, type, thread, 1); mem->write(addr,size/8,&src3_data.s64,thread,pI); - thread->m_last_effective_address = addr; - thread->m_last_memory_space = space; - // Step 2: __syncthreads() to make sure all data is stored in sstarr memory // (function must be called with dst = 0 so that all threads execute bar.sync 0) ptx_instruction * cpI = const_cast(pI); @@ -3776,35 +3772,44 @@ void sst_impl( const ptx_instruction *pI, ptx_thread_info *thread ) thread->m_last_dram_callback.function = bar_callback; thread->m_last_dram_callback.instruction = pI; - // Step 3: pick only one thread to load all of the data back from sstarr memory - // rearrange the data so that zeros are at the end of the array - // store this data back in the original array (each thread can maybe do this after another sync?) - int NUM_THREADS = 8; + + int NUM_THREADS = 8; // (how do you get this dynamically?) if (src2_data.s64 == NUM_THREADS-1) { - addr -= (NUM_THREADS-1)*4; + // Step 3: pick only one thread to load all of the data back from sstarr memory unsigned offset = 0; + addr -= (NUM_THREADS-1)*4; ptx_reg_t data; - // loop through all of the threads (how do you do this dynamically?) + float sstarr_fdata[NUM_THREADS]; + signed long long sstarr_ldata[NUM_THREADS]; + // loop through all of the threads for (int tid = 0; tid < NUM_THREADS; tid++) { data.u64=0; mem->read(addr+(tid*4),size/8,&data.s64); + sstarr_fdata[tid] = data.f32; + sstarr_ldata[tid] = data.s64; + } - // store nonzero entries - if (data.s64 != 0) { - mem->write(addr+(offset*4),size/8,&data.s64,thread,pI); - thread->m_last_effective_address = addr+(offset*4); + // Step 4: squeeze the zeros out of the array and store data back into original array + mem = NULL; + addr = src1_data.u32; + space.set_type(global_space); + decode_space(space,thread,src1,mem,addr); + // store nonzero entries + for (int tid = 0; tid < NUM_THREADS; tid++) { + if (sstarr_fdata[tid] != 0) { + mem->write(addr+(offset*4),size/8,&sstarr_ldata[tid],thread,pI); offset++; } } - // fill the rest of the array with zeros + + // fill the rest of the array with zeros (dst should always have a 0 in it) while (offset < NUM_THREADS) { - mem->write(addr+(offset*4),size/8,&src2_data.s64,thread,pI); - thread->m_last_effective_address = addr+(offset*4); + mem->write(addr+(offset*4),size/8,&dst_data.s64,thread,pI); offset++; } - // Step 4: load from sstarr memory and store data back into original array - + thread->m_last_effective_address = addr+(NUM_THREADS-1)*4; + thread->m_last_memory_space = space; } //if( type == S16_TYPE || type == S32_TYPE ) sign_extend(data,size,dst); -- cgit v1.3 From 6c1fb702e17b00fd7de72ac7dd4a31584d5978b9 Mon Sep 17 00:00:00 2001 From: sspenst Date: Fri, 8 Jul 2016 14:51:44 -0700 Subject: Made gridDim and blockDim global variables so that they can be accessed from sst_impl --- libcuda/cuda_runtime_api.cc | 7 +++++-- src/abstract_hardware_model.h | 3 +++ src/cuda-sim/instructions.cc | 3 +-- src/cuda-sim/opcodes.def | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) (limited to 'src/abstract_hardware_model.h') diff --git a/libcuda/cuda_runtime_api.cc b/libcuda/cuda_runtime_api.cc index e8a0e91..3eff4af 100644 --- a/libcuda/cuda_runtime_api.cc +++ b/libcuda/cuda_runtime_api.cc @@ -180,6 +180,9 @@ cudaError_t g_last_cudaError = cudaSuccess; extern stream_manager *g_stream_manager; +dim3 gridDim = (dim3){1,1,1}; +dim3 blockDim = (dim3){1,1,1}; + void register_ptx_function( const char *name, function_info *impl ) { // no longer need this @@ -959,8 +962,8 @@ __host__ cudaError_t CUDARTAPI cudaLaunch( const char *hostFun ) g_ptx_sim_mode?"functional simulation":"performance simulation", stream?stream->get_uid():0 ); kernel_info_t *grid = gpgpu_cuda_ptx_sim_init_grid(hostFun,config.get_args(),config.grid_dim(),config.block_dim(),context); std::string kname = grid->name(); - dim3 gridDim = config.grid_dim(); - dim3 blockDim = config.block_dim(); + gridDim = config.grid_dim(); + blockDim = config.block_dim(); printf("GPGPU-Sim PTX: pushing kernel \'%s\' to stream %u, gridDim= (%u,%u,%u) blockDim = (%u,%u,%u) \n", kname.c_str(), stream?stream->get_uid():0, gridDim.x,gridDim.y,gridDim.z,blockDim.x,blockDim.y,blockDim.z ); stream_operation op(grid,g_ptx_sim_mode,stream); diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 6ed9b8e..46c3279 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -162,6 +162,9 @@ struct dim3 { }; #endif +extern dim3 gridDim; +extern dim3 blockDim; + void increment_x_then_y_then_z( dim3 &i, const dim3 &bound); class kernel_info_t { diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 8bdb94f..fd3b1fa 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -3772,7 +3772,7 @@ void sst_impl( const ptx_instruction *pI, ptx_thread_info *thread ) thread->m_last_dram_callback.function = bar_callback; thread->m_last_dram_callback.instruction = cpI; - int NUM_THREADS = 8; // (how do you get this dynamically?) + int NUM_THREADS = blockDim.x * blockDim.y * blockDim.z; if (src2_data.s64 == NUM_THREADS-1) { // pick only one thread to load all of the data back from sstarr memory unsigned offset = 0; @@ -3809,7 +3809,6 @@ void sst_impl( const ptx_instruction *pI, ptx_thread_info *thread ) // fill the rest of the array with zeros (dst should always have a 0 in it) while (offset < NUM_THREADS) { mem->write(addr+(offset*4),size/8,&dst_data.s64,thread,pI); - mem->write(addr+((NUM_THREADS+offset)*4),size/8,&dst_data.s64,thread,pI); offset++; } diff --git a/src/cuda-sim/opcodes.def b/src/cuda-sim/opcodes.def index 0c0eda9..1af04ea 100644 --- a/src/cuda-sim/opcodes.def +++ b/src/cuda-sim/opcodes.def @@ -103,7 +103,7 @@ OP_DEF(SHR_OP,shr_impl,"shr",1,1) OP_DEF(SIN_OP,sin_impl,"sin",1,4) OP_DEF(SLCT_OP,slct_impl,"slct",1,1) OP_DEF(SQRT_OP,sqrt_impl,"sqrt",1,4) -OP_DEF(SST_OP,sst_impl,"sst",1,1) +OP_DEF(SST_OP,sst_impl,"sst",1,5) OP_DEF(SSY_OP,ssy_impl,"ssy",0,3) OP_DEF(ST_OP,st_impl,"st",0,5) OP_DEF(SUB_OP,sub_impl,"sub",1,1) -- cgit v1.3 From adc311951d67b0685ebf2fab4ce6410f96f0039a Mon Sep 17 00:00:00 2001 From: sspenst Date: Mon, 11 Jul 2016 11:16:46 -0700 Subject: Reverted the previous commit to add a cleaner way of getting NUM_THREADS. Now, sst_impl doesn't functionally execute on the last indexed element of an array, but instead on the actual last thread that executes --- libcuda/cuda_runtime_api.cc | 7 ++----- src/abstract_hardware_model.h | 3 --- src/cuda-sim/instructions.cc | 13 ++++++++----- src/cuda-sim/ptx_sim.cc | 16 ++++++++++++++++ src/cuda-sim/ptx_sim.h | 4 ++++ 5 files changed, 30 insertions(+), 13 deletions(-) (limited to 'src/abstract_hardware_model.h') diff --git a/libcuda/cuda_runtime_api.cc b/libcuda/cuda_runtime_api.cc index 3eff4af..e8a0e91 100644 --- a/libcuda/cuda_runtime_api.cc +++ b/libcuda/cuda_runtime_api.cc @@ -180,9 +180,6 @@ cudaError_t g_last_cudaError = cudaSuccess; extern stream_manager *g_stream_manager; -dim3 gridDim = (dim3){1,1,1}; -dim3 blockDim = (dim3){1,1,1}; - void register_ptx_function( const char *name, function_info *impl ) { // no longer need this @@ -962,8 +959,8 @@ __host__ cudaError_t CUDARTAPI cudaLaunch( const char *hostFun ) g_ptx_sim_mode?"functional simulation":"performance simulation", stream?stream->get_uid():0 ); kernel_info_t *grid = gpgpu_cuda_ptx_sim_init_grid(hostFun,config.get_args(),config.grid_dim(),config.block_dim(),context); std::string kname = grid->name(); - gridDim = config.grid_dim(); - blockDim = config.block_dim(); + dim3 gridDim = config.grid_dim(); + dim3 blockDim = config.block_dim(); printf("GPGPU-Sim PTX: pushing kernel \'%s\' to stream %u, gridDim= (%u,%u,%u) blockDim = (%u,%u,%u) \n", kname.c_str(), stream?stream->get_uid():0, gridDim.x,gridDim.y,gridDim.z,blockDim.x,blockDim.y,blockDim.z ); stream_operation op(grid,g_ptx_sim_mode,stream); diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 46c3279..6ed9b8e 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -162,9 +162,6 @@ struct dim3 { }; #endif -extern dim3 gridDim; -extern dim3 blockDim; - void increment_x_then_y_then_z( dim3 &i, const dim3 &bound); class kernel_info_t { diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index fd3b1fa..b5a3db4 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -3754,6 +3754,7 @@ void sst_impl( const ptx_instruction *pI, ptx_thread_info *thread ) memory_space_t space = pI->get_space(); memory_space *mem = NULL; addr_t addr = src2_data.u32 * 4; // this assumes sstarr memory starts at address 0 + ptx_cta_info *cta_info = thread->m_cta_info; decode_space(space,thread,src1,mem,addr); @@ -3765,18 +3766,19 @@ void sst_impl( const ptx_instruction *pI, ptx_thread_info *thread ) mem->write(addr,size/8,&src3_data.s64,thread,pI); // sync threads - cpI->set_bar_id(dst_data.u32); + cpI->set_bar_id(16); // use 16 for sst because bar uses an int from 0-15 thread->m_last_effective_address = addr; thread->m_last_memory_space = space; thread->m_last_dram_callback.function = bar_callback; thread->m_last_dram_callback.instruction = cpI; - int NUM_THREADS = blockDim.x * blockDim.y * blockDim.z; - if (src2_data.s64 == NUM_THREADS-1) { - // pick only one thread to load all of the data back from sstarr memory + // the last thread that executes loads all of the data back from sstarr memory + int NUM_THREADS = cta_info->num_threads(); + cta_info->inc_bar_threads(); + if (NUM_THREADS == cta_info->get_bar_threads()) { unsigned offset = 0; - addr -= (NUM_THREADS-1)*4; + addr = 0; ptx_reg_t data; float sstarr_fdata[NUM_THREADS]; signed long long sstarr_ldata[NUM_THREADS]; @@ -3812,6 +3814,7 @@ void sst_impl( const ptx_instruction *pI, ptx_thread_info *thread ) offset++; } + cta_info->reset_bar_threads(); thread->m_last_effective_address = addr+(NUM_THREADS-1)*4; thread->m_last_memory_space = space; } diff --git a/src/cuda-sim/ptx_sim.cc b/src/cuda-sim/ptx_sim.cc index 511e8d6..f48115b 100644 --- a/src/cuda-sim/ptx_sim.cc +++ b/src/cuda-sim/ptx_sim.cc @@ -44,6 +44,7 @@ ptx_cta_info::ptx_cta_info( unsigned sm_idx ) m_sm_idx = sm_idx; m_uid = g_ptx_cta_info_uid++; + m_bar_threads = 0; } void ptx_cta_info::add_thread( ptx_thread_info *thd ) @@ -128,6 +129,21 @@ unsigned ptx_cta_info::get_sm_idx() const return m_sm_idx; } +unsigned ptx_cta_info::get_bar_threads() const +{ + return m_bar_threads; +} + +void ptx_cta_info::inc_bar_threads() +{ + m_bar_threads++; +} + +void ptx_cta_info::reset_bar_threads() +{ + m_bar_threads = 0; +} + unsigned g_ptx_thread_info_uid_next=1; unsigned g_ptx_thread_info_delete_count=0; diff --git a/src/cuda-sim/ptx_sim.h b/src/cuda-sim/ptx_sim.h index c66b68c..4e748e9 100644 --- a/src/cuda-sim/ptx_sim.h +++ b/src/cuda-sim/ptx_sim.h @@ -158,8 +158,12 @@ public: void register_thread_exit( ptx_thread_info *thd ); void register_deleted_thread( ptx_thread_info *thd ); unsigned get_sm_idx() const; + unsigned get_bar_threads() const; + void inc_bar_threads(); + void reset_bar_threads(); private: + unsigned m_bar_threads; unsigned long long m_uid; unsigned m_sm_idx; std::set m_threads_in_cta; -- cgit v1.3 From feda07a5e0053ef2f2bfa382f5ba9a7a0b6c6bf5 Mon Sep 17 00:00:00 2001 From: sspenst Date: Thu, 4 Aug 2016 13:09:41 -0700 Subject: A thread executing BSMAD is now able to access information from all threads in its warp --- src/abstract_hardware_model.h | 1 + src/cuda-sim/cuda-sim.cc | 14 ++++ src/cuda-sim/instructions.cc | 158 ++++++++++++++++++++++++++++++++++++++++++ src/cuda-sim/opcodes.def | 3 + src/cuda-sim/opcodes.h | 4 +- src/cuda-sim/ptx.l | 3 + 6 files changed, 182 insertions(+), 1 deletion(-) (limited to 'src/abstract_hardware_model.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 6ed9b8e..13dfce3 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -1053,6 +1053,7 @@ class core_t { warp_inst_t getExecuteWarp(unsigned warpId); void get_pdom_stack_top_info( unsigned warpId, unsigned *pc, unsigned *rpc ) const; kernel_info_t * get_kernel_info(){ return m_kernel;} + class ptx_thread_info ** get_thread_info() { return m_thread; } unsigned get_warp_size() const { return m_warp_size; } void and_reduction(unsigned ctaid, unsigned barid, bool value) { reduction_storage[ctaid][barid] &= value; } void or_reduction(unsigned ctaid, unsigned barid, bool value) { reduction_storage[ctaid][barid] |= value; } diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index e194a2a..059fbe2 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -849,8 +849,10 @@ void ptx_instruction::pre_decode() switch ( get_opcode() ) { #define OP_DEF(OP,FUNC,STR,DST,CLASSIFICATION) case OP: has_dst = (DST!=0); break; +#define OP_W_DEF(OP,FUNC,STR,DST,CLASSIFICATION) case OP: has_dst = (DST!=0); break; #include "opcodes.def" #undef OP_DEF +#undef OP_W_DEF default: printf( "Execution error: Invalid opcode (0x%x)\n", get_opcode() ); break; @@ -1242,10 +1244,22 @@ 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; } + /*const ptx_instruction **pA; + if( pI->get_opcode() == BSMAD_OP ) { + //pA = (const ptx_instruction**)malloc(get_core()->get_warp_size()*(sizeof(ptx_instruction*))); + pA = (const ptx_instruction**)malloc(8*(sizeof(ptx_instruction*))); + for (int i = 0; i < get_core()->get_warp_size() && inst.active(i); i++) { + //pA[i] = get_core()->get_thread_info()[inst.warp_id() * get_core()->get_warp_size() + i]->func_info()->get_instruction(pc+(i-lane_id)*(pI->inst_size())); + int tid = inst.warp_id() * get_core()->get_warp_size() + i; + pA[i] = get_core()->get_thread_info()[tid]->func_info()->get_instruction(pc); + } + }*/ 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; #include "opcodes.def" #undef OP_DEF +#undef OP_W_DEF default: printf( "Execution error: Invalid opcode (0x%x)\n", pI->get_opcode() ); break; } delete pJ; diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index b401bef..618add1 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -47,8 +47,10 @@ unsigned ptx_instruction::g_num_ptx_inst_uid=0; const char *g_opcode_string[NUM_OPCODES] = { #define OP_DEF(OP,FUNC,STR,DST,CLASSIFICATION) STR, +#define OP_W_DEF(OP,FUNC,STR,DST,CLASSIFICATION) STR, #include "opcodes.def" #undef OP_DEF +#undef OP_W_DEF }; void inst_not_implemented( const ptx_instruction * pI ) ; @@ -1456,6 +1458,162 @@ void breakaddr_impl( const ptx_instruction *pI, ptx_thread_info *thread ) void brev_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); } void brkpt_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); } +void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) +{ + for (int i = 0; i < core->get_warp_size() && inst.active(i); i++) { + const operand_info &dst = pI->dst(); + unsigned type = pI->get_type(); + + int tid = inst.warp_id() * core->get_warp_size() + i; + ptx_thread_info *thread = core->get_thread_info()[tid]; + ptx_reg_t data = thread->get_operand_value(dst, dst, type, thread, 1); + printf("BSMAD - DATA FROM THREAD %d: %d\n", i, data.u32); + } + printf("\n"); + /*const unsigned OPERANDS = 9; + // 0 = output + // 1 = input precision + // 2 = output precision + // 3 = buffer0 + // 4 = buffer1 + // 5 = buffer2 + // 6 = buffer3 + // 7 = synapse value + // 8 = output value + // as a temporary solution, let 0 be the base address of output, which is an array of shared memory + // that will be filled when the last thread completes the bsmad instruction + // maybe you can store the addresses of other ptx_instruction in sstarr memory and then update dst later? + // not sure if that works + + //ptx_instruction * cpI = const_cast(pI); + const operand_info &src[OPERANDS]; + ptx_reg_t src_data[OPERANDS]; + unsigned type = pI->get_type(); + + for (int i = 0; i < OPERANDS; i++) { + src[i] = pI->operand_lookup(i); + src_data[i] = thread->get_operand_value(src[i], src[0], type, thread, 1); + } + + memory_space_t space = pI->get_space(); + memory_space *mem = NULL; + addr_t addr = thread->get_tid().x * 24; // 4 bytes per register * 6 registers per thread = 24 bytes + + decode_space(space,thread,src[0],mem,addr); + + size_t size; + int t; + type_info_key::type_decode(type,size,t); + + // store src_data[1:4] in sstarr memory + for (int i = 0; i < 6; i++) { + mem->write(addr + i*4,size/8,&src_data[i+3].s64,thread,pI); + } + + // sync threads + //cpI->set_bar_id(16); // use 16 for sst because bar uses an int from 0-15 + + thread->m_last_effective_address = addr; + thread->m_last_memory_space = space; + thread->m_last_dram_callback.function = bar_callback; + thread->m_last_dram_callback.instruction = cpI; + + // the last thread that executes loads all of the data back from sstarr memory + ptx_cta_info *cta_info = thread->m_cta_info;((32/ip)*4)/(32/op) + const int NUM_THREADS = cta_info->num_threads(); + cta_info->inc_bar_threads(); + if (NUM_THREADS == cta_info->get_bar_threads()) { + // load all things from sstarr memory + addr = 0; + ptx_reg_t data; + unsigned sstarr_data[NUM_THREADS*6]; + for (int i = 0; i < NUM_THREADS*6; i++) { + data.u64 = 0; + mem->read(addr+(i*4),size/8,&data.s64); + sstarr_data[i] = data.u32; + } + + // unpack registers, add data from across threads + unsigned ip = src_data[1].u32; + unsigned op = src_data[2].u32; + unsigned unpacked_output[(32/ip)*4]; + + for (unsigned i = 0; i < (32/ip)*4; i++) { + unsigned buf = i/(32/ip); + unsigned pos = i%(32/ip); + + unsigned mask = 0; + for (int b = 0; b < ip; b++) { + mask |= (1 << b); + } + mask <<= (pos*ip); + + int sum = 0; + for (int j = 0; j < NUM_THREADS; j++) { + sum += mask & sstarr_data[j*6 + buf]; + } + unpacked_output[i] = sum; + } + + // truncate result, repack, store in shared mem + unsigned output_regs[((32/ip)*4)/(32/op) + (((32/ip)*4)%(32/op) != 0)]; + + + + unsigned offset = 0; + addr = 0; + ptx_reg_t data; + float sstarr_fdata[NUM_THREADS]; + signed long long sstarr_ldata[NUM_THREADS]; + // loop through all of the threads + for (int tid = 0; tid < NUM_THREADS; tid++) { + data.u64=0; + mem->read(addr+(tid*4),size/8,&data.s64); + sstarr_fdata[tid] = data.f32; + sstarr_ldata[tid] = data.s64; + } + + // squeeze the zeros out of the array and store data back into original array + mem = NULL; + addr = src1_data.u32; + space.set_type(global_space); + decode_space(space,thread,src1,mem,addr); + // store nonzero entries and indices + for (int tid = 0; tid < NUM_THREADS; tid++) { + if (sstarr_fdata[tid] != 0) { + float ftid = (float)tid; + mem->write(addr+(offset*4),size/8,&sstarr_ldata[tid],thread,pI); + mem->write(addr+((NUM_THREADS+offset)*4),size/8,&ftid,thread,pI); + offset++; + } + } + // store the number of nonzero elements in the array + data = thread->get_op((32/ip)*4)/(32/op)erand_value(src1, dst, type, thread, 1); + data.s64 += 4*(offset-1); + thread->set_operand_value(dst, data, type, thread, pI); + + // fill the rest of the array with zeros (dst should always have a 0 in it) + while (offset < NUM_THREADS) { + mem->write(addr+(offset*4),size/8,&dst_data.s64,thread,pI); + offset++; + } + + cta_info->reset_bar_threads(); + thread->m_last_effective_address = addr+(NUM_THREADS-1)*4; + thread->m_last_memory_space = space; + }*/ +} + +void bsmul_impl( const ptx_instruction *pI, ptx_thread_info *thread ) +{ + printf("BSMUL instruction found.\n"); +} + +void buf_impl( const ptx_instruction *pI, ptx_thread_info *thread ) +{ + printf("BUF instruction found.\n"); +} + void call_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { static unsigned call_uid_next = 1; diff --git a/src/cuda-sim/opcodes.def b/src/cuda-sim/opcodes.def index 1af04ea..d0e6f25 100644 --- a/src/cuda-sim/opcodes.def +++ b/src/cuda-sim/opcodes.def @@ -52,6 +52,9 @@ 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",0,1) +OP_DEF(BSMUL_OP,bsmul_impl,"bsmul",1,1) +OP_DEF(BUF_OP,buf_impl,"buf",0,5) 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/opcodes.h b/src/cuda-sim/opcodes.h index 871091c..aa133da 100644 --- a/src/cuda-sim/opcodes.h +++ b/src/cuda-sim/opcodes.h @@ -30,9 +30,11 @@ enum opcode_t { #define OP_DEF(OP,FUNC,STR,DST,CLASSIFICATION) OP, +#define OP_W_DEF(OP,FUNC,STR,DST,CLASSIFICATION) OP, #include "opcodes.def" - NUM_OPCODES + NUM_OPCODES #undef OP_DEF +#undef OP_W_DEF }; enum special_regs { diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l index 69349a0..e0d7b9d 100644 --- a/src/cuda-sim/ptx.l +++ b/src/cuda-sim/ptx.l @@ -68,6 +68,9 @@ 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; +bsmul TC; ptx_lval.int_value = BSMUL_OP; return OPCODE; +buf TC; ptx_lval.int_value = BUF_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; -- cgit v1.3 From d1b45cf53a39261663a3eff0d409d6c1220d923d Mon Sep 17 00:00:00 2001 From: sspenst Date: Fri, 5 Aug 2016 14:45:56 -0700 Subject: Added ptx_warp_info to know how many threads within a warp have executed --- src/abstract_hardware_model.h | 2 + src/cuda-sim/cuda-sim.cc | 10 +++++ src/cuda-sim/instructions.cc | 95 +++++++++++++++++++++++-------------------- src/cuda-sim/ptx_sim.cc | 21 ++++++++++ src/cuda-sim/ptx_sim.h | 12 ++++++ 5 files changed, 95 insertions(+), 45 deletions(-) (limited to 'src/abstract_hardware_model.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 13dfce3..cfa8c9f 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -1028,6 +1028,7 @@ class core_t { m_warp_count += 1; } assert( m_warp_count * m_warp_size > 0 ); + //m_warp = ( ptx_warp_info** )calloc( m_warp_count, sizeof( ptx_warp_info* ) ); m_thread = ( ptx_thread_info** ) calloc( m_warp_count * m_warp_size, sizeof( ptx_thread_info* ) ); @@ -1063,6 +1064,7 @@ class core_t { class gpgpu_sim *m_gpu; kernel_info_t *m_kernel; simt_stack **m_simt_stack; // pdom based reconvergence context for each warp + //class ptx_warp_info ** m_warp; class ptx_thread_info ** m_thread; unsigned m_warp_size; unsigned m_warp_count; diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index 337463b..ba0d00b 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -1417,6 +1417,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel, static std::map shared_memory_lookup; static std::map sstarr_memory_lookup; static std::map ptx_cta_lookup; + static std::map ptx_warp_lookup; static std::map > local_memory_lookup; if ( *thread_info != NULL ) { @@ -1501,6 +1502,15 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel, new_tid += tid; ptx_thread_info *thd = new ptx_thread_info(kernel); + ptx_warp_info *warp_info = NULL; + if ( ptx_warp_lookup.find(hw_warp_id) == ptx_warp_lookup.end() ) { + warp_info = new ptx_warp_info(); // num_threads should be threads in the warp + ptx_warp_lookup[hw_warp_id] = warp_info; + } else { + warp_info = ptx_warp_lookup[hw_warp_id]; + } + thd->m_warp_info = warp_info; + memory_space *local_mem = NULL; std::map::iterator l = local_mem_lookup.find(new_tid); if ( l != local_mem_lookup.end() ) { diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index f58c4f5..9dcc25c 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -1471,74 +1471,81 @@ void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) // 7 = synapse value // 8 = output value - // TODO: what should happen when the output precision is larger than the input precision? - // TODO: create a ptx_warp_info that can do the same thing that ptx_cta_info does here - ptx_cta_info *cta_info = core->get_thread_info()[inst.warp_id() * core->get_warp_size()]->m_cta_info; - const int NUM_THREADS = cta_info->num_threads(); - const int NUM_BUFFERS = 4; - cta_info->inc_bar_threads(); + 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() * 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 = core->get_thread_info()[inst.warp_id() * core->get_warp_size()]->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 (cta_info->get_bar_threads() <= NUM_BUFFERS) { - unsigned ip, op; // only get these when i = 0 - unsigned buffer[inst.active_count()][NUM_BUFFERS]; + if (warp_info->get_done_threads() <= OUTBUFFERS) { + unsigned buffer[inst.active_count()][INBUFFERS]; unsigned synapse[inst.active_count()]; - unsigned output[NUM_BUFFERS]; + 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 dst = pI->dst(); - const operand_info src1 = pI->operand_lookup(1); - const operand_info src2 = pI->operand_lookup(2); - 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); - unsigned type = pI->get_type(); - - int tid = inst.warp_id() * core->get_warp_size() + i; - ptx_thread_info *thread = core->get_thread_info()[tid]; - - // only get precision data once - if (j == 0) { - ip = (thread->get_operand_value(src1, dst, type, thread, 1)).u32; - op = (thread->get_operand_value(src2, dst, type, thread, 1)).u32; - } + 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); + + 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 < NUM_BUFFERS) { - output[j] = (thread->get_operand_value(src8, dst, type, thread, 1)).u32; + if (j == warp_info->get_done_threads()) { + output = (thread->get_operand_value(src8, dst, type, thread, 1)).u32; } - j++; } } // 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)*(cta_info->get_bar_threads()-1); - for (unsigned i = buffer_data_start; i < (32/op + buffer_data_start) && i < (32/ip)*NUM_BUFFERS; i++) { + 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); - unsigned mask = 0; + int sum = 0; + // sum values from the buffers for (int b = 0; b < ip; b++) { mask |= (1 << b); } mask <<= (pos*ip); - int sum = 0; - for (int j = 0; j < NUM_THREADS; j++) { + for (int j = 0; j < THREADS; j++) { sum += (mask & buffer[j][buf]) >> (pos*ip); } - unpacked_output[i - buffer_data_start] = sum; + // get the previous output + mask = 0; + for (int b = 0; b < op; b++) { + mask |= (1 << b); + } + mask <<= (op*(i-buffer_data_start)); + int past_output = (mask & output) >> (op*(i-buffer_data_start)); + + unpacked_output[i-buffer_data_start] = sum + past_output; } // truncate output @@ -1575,11 +1582,8 @@ void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) // 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 == cta_info->get_bar_threads()) { - const operand_info &dst = pI->dst(); - unsigned type = pI->get_type(); - int tid = inst.warp_id() * core->get_warp_size() + i; - ptx_thread_info *thread = core->get_thread_info()[tid]; + 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); @@ -1588,8 +1592,9 @@ void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) } } - if (cta_info->get_bar_threads() == NUM_THREADS) { - cta_info->reset_bar_threads(); + // 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(); } } diff --git a/src/cuda-sim/ptx_sim.cc b/src/cuda-sim/ptx_sim.cc index f48115b..820287d 100644 --- a/src/cuda-sim/ptx_sim.cc +++ b/src/cuda-sim/ptx_sim.cc @@ -144,6 +144,26 @@ void ptx_cta_info::reset_bar_threads() m_bar_threads = 0; } +ptx_warp_info::ptx_warp_info() +{ + reset_done_threads(); +} + +unsigned ptx_warp_info::get_done_threads() const +{ + return m_done_threads; +} + +void ptx_warp_info::inc_done_threads() +{ + m_done_threads++; +} + +void ptx_warp_info::reset_done_threads() +{ + m_done_threads = 0; +} + unsigned g_ptx_thread_info_uid_next=1; unsigned g_ptx_thread_info_delete_count=0; @@ -170,6 +190,7 @@ ptx_thread_info::ptx_thread_info( kernel_info_t &kernel ) m_branch_taken = 0; m_shared_mem = NULL; m_sstarr_mem = NULL; + m_warp_info = NULL; m_cta_info = NULL; m_local_mem = NULL; m_symbol_table = NULL; diff --git a/src/cuda-sim/ptx_sim.h b/src/cuda-sim/ptx_sim.h index 4e748e9..c62fa57 100644 --- a/src/cuda-sim/ptx_sim.h +++ b/src/cuda-sim/ptx_sim.h @@ -171,6 +171,17 @@ private: std::set m_dangling_pointers; }; +class ptx_warp_info { +public: + ptx_warp_info(); // add get_core or something, or threads? + unsigned get_done_threads() const; + void inc_done_threads(); + void reset_done_threads(); + +private: + unsigned m_done_threads; +}; + class symbol; struct stack_entry { @@ -430,6 +441,7 @@ public: memory_space *m_shared_mem; memory_space *m_sstarr_mem; memory_space *m_local_mem; + ptx_warp_info *m_warp_info; ptx_cta_info *m_cta_info; ptx_reg_t m_last_set_operand_value; -- cgit v1.3 From de21c009ca25fbbfd460047c3ae8a3cf59c31454 Mon Sep 17 00:00:00 2001 From: sspenst Date: Fri, 5 Aug 2016 14:50:37 -0700 Subject: Deleted useless comments --- src/abstract_hardware_model.h | 2 -- src/cuda-sim/cuda-sim.cc | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'src/abstract_hardware_model.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index cfa8c9f..13dfce3 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -1028,7 +1028,6 @@ class core_t { m_warp_count += 1; } assert( m_warp_count * m_warp_size > 0 ); - //m_warp = ( ptx_warp_info** )calloc( m_warp_count, sizeof( ptx_warp_info* ) ); m_thread = ( ptx_thread_info** ) calloc( m_warp_count * m_warp_size, sizeof( ptx_thread_info* ) ); @@ -1064,7 +1063,6 @@ class core_t { class gpgpu_sim *m_gpu; kernel_info_t *m_kernel; simt_stack **m_simt_stack; // pdom based reconvergence context for each warp - //class ptx_warp_info ** m_warp; class ptx_thread_info ** m_thread; unsigned m_warp_size; unsigned m_warp_count; diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index ba0d00b..53ee25b 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -1504,7 +1504,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel, ptx_warp_info *warp_info = NULL; if ( ptx_warp_lookup.find(hw_warp_id) == ptx_warp_lookup.end() ) { - warp_info = new ptx_warp_info(); // num_threads should be threads in the warp + warp_info = new ptx_warp_info(); ptx_warp_lookup[hw_warp_id] = warp_info; } else { warp_info = ptx_warp_lookup[hw_warp_id]; -- cgit v1.3 From 8c264f2e77fe628987416269a925bb9930a1b813 Mon Sep 17 00:00:00 2001 From: sspenst Date: Mon, 8 Aug 2016 16:10:43 -0700 Subject: Forgot to multiply by the synapse --- src/abstract_hardware_model.h | 2 +- src/cuda-sim/instructions.cc | 35 ++++++++++++----------------------- 2 files changed, 13 insertions(+), 24 deletions(-) (limited to 'src/abstract_hardware_model.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 13dfce3..c009276 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -788,7 +788,7 @@ public: int src[MAX_REG_OPERANDS]; } arch_reg; //int arch_reg[MAX_REG_OPERANDS]; // register number for bank conflict evaluation - unsigned latency; // operation latency + unsigned latency; // operation latency unsigned initiation_interval; unsigned data_size; // what is the size of the word being operated on? diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 9dcc25c..3b938bb 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -1486,13 +1486,13 @@ void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) 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 = core->get_thread_info()[inst.warp_id() * core->get_warp_size()]->m_warp_info; + 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[inst.active_count()][INBUFFERS]; - unsigned synapse[inst.active_count()]; + unsigned buffer[THREADS][INBUFFERS]; + unsigned synapse[THREADS]; unsigned output; // loop through all threads in the warp and get all data @@ -1526,25 +1526,15 @@ void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) 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); - unsigned mask = 0; - int sum = 0; // sum values from the buffers - for (int b = 0; b < ip; b++) { - mask |= (1 << b); - } - mask <<= (pos*ip); - + 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); + sum += ((mask & buffer[j][buf]) >> (pos*ip)) * synapse[j]; } // get the previous output - mask = 0; - for (int b = 0; b < op; b++) { - mask |= (1 << b); - } - mask <<= (op*(i-buffer_data_start)); + 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] = sum + past_output; } @@ -1567,13 +1557,8 @@ void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) } } - // create mask of 1s - unsigned mask = 0; - for (int b = 0; b < op; b++) { - mask |= (1 << b); - } - // 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); @@ -1596,6 +1581,10 @@ void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) if (warp_info->get_done_threads() == THREADS) { warp_info->reset_done_threads(); } + + // 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 ) -- cgit v1.3 From 0751c1489add70d7494521c7f9d65f462e4391c6 Mon Sep 17 00:00:00 2001 From: speverel Date: Sun, 24 Sep 2017 21:12:40 -0700 Subject: Changed how warp level instructions are handled to avoid an assert that is guaranteed to fail in functional simulation only mode. Hopefully this shouldn't introduce any new issues. --- src/abstract_hardware_model.h | 4 ++++ src/cuda-sim/instructions.cc | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src/abstract_hardware_model.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 607eda7..cdd9cf3 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -980,6 +980,10 @@ public: assert( !m_empty ); return m_warp_id; } + unsigned warp_id_func() const // to be used in functional simulations only + { + return m_warp_id; + } unsigned dynamic_warp_id() const { assert( !m_empty ); diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 159fd4c..493e307 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -1500,7 +1500,7 @@ void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) const operand_info &src1 = pI->src1(); const operand_info &src2 = pI->src2(); unsigned type = pI->get_type(); - int tid = inst.warp_id() * core->get_warp_size(); + 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; @@ -3698,7 +3698,7 @@ void set_impl( const ptx_instruction *pI, ptx_thread_info *thread ) void shfl_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) { unsigned i_type = pI->get_type(); - int tid = inst.warp_id() * core->get_warp_size(); + int tid = inst.warp_id_func() * core->get_warp_size(); ptx_thread_info *thread = core->get_thread_info()[tid]; ptx_warp_info *warp_info = thread->m_warp_info; int lane = warp_info->get_done_threads(); -- cgit v1.3 From 68674d4ba230df0d3bf9f4e5b035f4cf9cfc185b Mon Sep 17 00:00:00 2001 From: negargoli93 Date: Sat, 12 May 2018 16:09:04 -0700 Subject: commit for eece527project --- src/abstract_hardware_model.h | 6 +- src/cuda-sim/cuda-sim.cc | 11 ++- src/cuda-sim/instructions.cc | 213 +++++++++++++++++++----------------------- src/cuda-sim/opcodes.def | 2 +- src/cuda-sim/ptx.l | 2 +- src/cuda-sim/ptx_ir.h | 25 +++++ src/gpgpu-sim/scoreboard.cc | 4 + src/gpgpusim_entrypoint.cc | 1 - 8 files changed, 136 insertions(+), 128 deletions(-) (limited to 'src/abstract_hardware_model.h') 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(); + 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; + - // 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); - - 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(); -- cgit v1.3 From 5b1ba75a3d5d02fbc12b5218abaaae4fcf2b5c2d Mon Sep 17 00:00:00 2001 From: aamir Date: Wed, 30 May 2018 17:34:14 -0700 Subject: changes for vector operands --- src/abstract_hardware_model.h | 2 +- src/cuda-sim/cuda-sim.cc | 24 +++++++++---- src/cuda-sim/instructions.cc | 80 +++++++++++++++++++++++++++++++++---------- src/cuda-sim/ptx_ir.h | 10 +++++- 4 files changed, 88 insertions(+), 28 deletions(-) (limited to 'src/abstract_hardware_model.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 9dc58d4..e00c941 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -826,7 +826,7 @@ public: address_type reconvergence_pc; // -1 => not a branch, -2 => use function return address unsigned out[8]; - unsigned in[8]; + unsigned in[24]; 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 006738a..62077e6 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -852,8 +852,10 @@ void ptx_instruction::pre_decode() { pc = m_PC; isize = m_inst_size; - for( unsigned i=0; i<4; i++) { + for(unsigned i=0; i<8; i++) { out[i] = 0; + } + for(unsigned i=0; i<24; i++) { in[i] = 0; } is_vectorin = 0; @@ -922,6 +924,10 @@ void ptx_instruction::pre_decode() if( num_elem >= 2 ) out[1] = o.reg2_num(); if( num_elem >= 3 ) out[2] = o.reg3_num(); if( num_elem >= 4 ) out[3] = o.reg4_num(); + if( num_elem >= 5 ) out[4] = o.reg5_num(); + if( num_elem >= 6 ) out[5] = o.reg6_num(); + if( num_elem >= 7 ) out[6] = o.reg7_num(); + if( num_elem >= 8 ) out[7] = o.reg8_num(); for (int i = 0; i < num_elem; i++) arch_reg.dst[i] = o.arch_reg_num(i); } @@ -940,13 +946,17 @@ void ptx_instruction::pre_decode() //assert(m == 0); //only support 1 vector operand (for textures) right now is_vectorout = 1; unsigned num_elem = o.get_vect_nelem(); - if( num_elem >= 1 ) in[0] = o.reg1_num(); - if( num_elem >= 2 ) in[1] = o.reg2_num(); - if( num_elem >= 3 ) in[2] = o.reg3_num(); - if( num_elem >= 4 ) in[3] = o.reg4_num(); + if( num_elem >= 1 ) in[m+0] = o.reg1_num(); + if( num_elem >= 2 ) in[m+1] = o.reg2_num(); + if( num_elem >= 3 ) in[m+2] = o.reg3_num(); + if( num_elem >= 4 ) in[m+3] = o.reg4_num(); + if( num_elem >= 5 ) in[m+4] = o.reg5_num(); + if( num_elem >= 6 ) in[m+5] = o.reg6_num(); + if( num_elem >= 7 ) in[m+6] = o.reg7_num(); + if( num_elem >= 8 ) in[m+7] = o.reg8_num(); for (int i = 0; i < num_elem; i++) - arch_reg.src[i] = o.arch_reg_num(i); - m+=4; + arch_reg.src[m+i] = o.arch_reg_num(i); + m+=num_elem; } } } diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 7407269..446cdbf 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -748,7 +748,7 @@ void addp_impl( const ptx_instruction *pI, ptx_thread_info *thread ) case U64_TYPE: data.s64 = src1_data.s64 + src2_data.s64 + (src3_data.pred & 0x4); break; - case F16_TYPE: assert(0); break; + case F16_TYPE: data.f16=src1_data.f16+src2_data.f16; break;//assert(0); break; case F32_TYPE: data.f32 = src1_data.f32 + src2_data.f32; break; case F64_TYPE: case FF64_TYPE: data.f64 = src1_data.f64 + src2_data.f64; break; default: assert(0); break; @@ -826,7 +826,7 @@ void add_impl( const ptx_instruction *pI, ptx_thread_info *thread ) case U64_TYPE: data.u64 = src1_data.u64 + src2_data.u64; break; - case F16_TYPE: assert(0); break; + case F16_TYPE: data.f16=src1_data.f16+src2_data.f16; break;//assert(0); break; case F32_TYPE: data.f32 = src1_data.f32 + src2_data.f32; break; case F64_TYPE: case FF64_TYPE: data.f64 = src1_data.f64 + src2_data.f64; break; default: assert(0); break; @@ -1878,7 +1878,9 @@ ptx_reg_t f2x( ptx_reg_t x, unsigned from_width, unsigned to_width, int to_sign, } } else { switch ( to_width ) { - case 16: assert(0); break; + case 16: //assert(0); break; + y.f16 = x.f32; + break; case 32: assert(0); break; // handled by f2f case 64: y.f64 = x.f32; @@ -2140,7 +2142,7 @@ void ptx_round(ptx_reg_t& data, int rounding_mode, int type) case U32_TYPE: case U64_TYPE: printf("Trying to round an integer??\n"); assert(0); break; - case F16_TYPE: assert(0); break; + case F16_TYPE: data.f16=truncf(data.f16);break;//assert(0); break; case F32_TYPE: data.f32 = truncf(data.f32); break; @@ -2163,7 +2165,13 @@ void ptx_round(ptx_reg_t& data, int rounding_mode, int type) case U32_TYPE: case U64_TYPE: printf("Trying to round an integer??\n"); assert(0); break; - case F16_TYPE: assert(0); break; + case F16_TYPE:// assert(0); break; +#if CUDART_VERSION >= 3000 + data.f16 = nearbyintf(data.f16); +#else + data.f16 = cuda_math::__cuda_nearbyintf(data.f16); +#endif + break; case F32_TYPE: #if CUDART_VERSION >= 3000 data.f32 = nearbyintf(data.f32); @@ -2186,7 +2194,7 @@ void ptx_round(ptx_reg_t& data, int rounding_mode, int type) case U32_TYPE: case U64_TYPE: printf("Trying to round an integer??\n"); assert(0); break; - case F16_TYPE: assert(0); break; + case F16_TYPE: data.f16=floorf(data.f16);break;//assert(0); break; case F32_TYPE: data.f32 = floorf(data.f32); break; @@ -2205,7 +2213,7 @@ void ptx_round(ptx_reg_t& data, int rounding_mode, int type) case U32_TYPE: case U64_TYPE: printf("Trying to round an integer??\n"); assert(0); break; - case F16_TYPE: assert(0); break; + case F16_TYPE: data.f16 = ceilf(data.f16); break; //assert(0); break; case F32_TYPE: data.f32 = ceilf(data.f32); break; case F64_TYPE: case FF64_TYPE: data.f64 = ceil(data.f64); break; default: assert(0); break; @@ -2246,7 +2254,10 @@ void ptx_saturate(ptx_reg_t& data, int saturation_mode, int type) case U32_TYPE: case U64_TYPE: printf("Trying to clamp an integer to 1??\n"); assert(0); break; - case F16_TYPE: assert(0); break; + case F16_TYPE: //assert(0); break; + if (data.f16 > 1.0f) data.f16 = 1.0f; //negative + if (data.f16 < 0.0f) data.f16 = 0.0f; //positive + break; case F32_TYPE: if (data.f32 > 1.0f) data.f32 = 1.0f; //negative if (data.f32 < 0.0f) data.f32 = 0.0f; //positive @@ -2270,8 +2281,8 @@ void cvt_impl( const ptx_instruction *pI, ptx_thread_info *thread ) unsigned rounding_mode = pI->rounding_mode(); unsigned saturation_mode = pI->saturation_mode(); - if ( to_type == F16_TYPE || from_type == F16_TYPE ) - abort(); +// if ( to_type == F16_TYPE || from_type == F16_TYPE ) +// abort(); int to_sign, from_sign; size_t from_width, to_width; @@ -2406,7 +2417,7 @@ void div_impl( const ptx_instruction *pI, ptx_thread_info *thread ) data.u32 = src1_data.u32 / src2_data.u32; break; case B64_TYPE: data.u64 = src1_data.u64 / src2_data.u64; break; - case F16_TYPE: assert(0); break; + case F16_TYPE: data.f16 = src1_data.f16 / src2_data.f16; break;//assert(0); break; case F32_TYPE: data.f32 = src1_data.f32 / src2_data.f32; break; case F64_TYPE: case FF64_TYPE: data.f64 = src1_data.f64 / src2_data.f64; break; default: assert(0); break; @@ -2744,9 +2755,24 @@ void mad_def( const ptx_instruction *pI, ptx_thread_info *thread, bool use_carry if ( pI->is_lo() ) d.u64 = t.u64 + c.u64 + carry_bit.pred; else assert(0); break; - case F16_TYPE: - assert(0); - break; + case F16_TYPE:{ + // assert(0); + // break; + assert( use_carry == false); + int orig_rm = fegetround(); + switch ( rounding_mode ) { + case RN_OPTION: break; + case RZ_OPTION: fesetround( FE_TOWARDZERO ); break; + default: assert(0); break; + } + d.f16 = a.f16 * b.f16 + c.f16; + if ( pI->saturation_mode() ) { + if ( d.f16 < 0 ) d.f16 = 0; + else if ( d.f16 > 1.0f ) d.f16 = 1.0f; + } + fesetround( orig_rm ); + break; + } case F32_TYPE: { assert( use_carry == false); int orig_rm = fegetround(); @@ -3046,9 +3072,25 @@ void mul_impl( const ptx_instruction *pI, ptx_thread_info *thread ) if ( pI->is_lo() ) d.u64 = t.u64; else assert(0); break; - case F16_TYPE: - assert(0); - break; + case F16_TYPE:{ + //assert(0); + //break; + int orig_rm = fegetround(); + switch ( rounding_mode ) { + case RN_OPTION: break; + case RZ_OPTION: fesetround( FE_TOWARDZERO ); break; + default: assert(0); break; + } + + d.f16 = a.f16 * b.f16; + + if ( pI->saturation_mode() ) { + if ( d.f16 < 0 ) d.f16 = 0; + else if ( d.f16 > 1.0f ) d.f16 = 1.0f; + } + fesetround( orig_rm ); + break; + } case F32_TYPE: { int orig_rm = fegetround(); switch ( rounding_mode ) { @@ -3111,7 +3153,7 @@ void neg_impl( const ptx_instruction *pI, ptx_thread_info *thread ) case U32_TYPE: case U64_TYPE: assert(0); break; - case F16_TYPE: assert(0); break; + case F16_TYPE: data.f16 =0.0f - src1_data.f16; break;//assert(0); break; case F32_TYPE: data.f32 = 0.0f - src1_data.f32; break; case F64_TYPE: case FF64_TYPE: data.f64 = 0.0f - src1_data.f64; break; default: assert(0); break; @@ -4165,7 +4207,7 @@ void sub_impl( const ptx_instruction *pI, ptx_thread_info *thread ) case B64_TYPE: case U64_TYPE: data.u64 = src1_data.u64 - src2_data.u64; break; - case F16_TYPE: assert(0); break; + case F16_TYPE: data.f16 = src1_data.f16 - src2_data.f16; break;//assert(0); break; case F32_TYPE: data.f32 = src1_data.f32 - src2_data.f32; break; case F64_TYPE: case FF64_TYPE: data.f64 = src1_data.f64 - src2_data.f64; break; default: assert(0); break; diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index ff24a66..833f175 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -656,7 +656,11 @@ public: if( !m_value.m_vector_symbolic[1] ) return 1; if( !m_value.m_vector_symbolic[2] ) return 2; if( !m_value.m_vector_symbolic[3] ) return 3; - return 4; + if( !m_value.m_vector_symbolic[4] ) return 4; + if( !m_value.m_vector_symbolic[5] ) return 5; + if( !m_value.m_vector_symbolic[6] ) return 6; + if( !m_value.m_vector_symbolic[7] ) return 7; + return 8; } const symbol* vec_symbol(int idx) const @@ -718,6 +722,10 @@ public: int reg2_num() const { return m_value.m_vector_symbolic[1]->reg_num();} int reg3_num() const { return m_value.m_vector_symbolic[2]?m_value.m_vector_symbolic[2]->reg_num():0; } int reg4_num() const { return m_value.m_vector_symbolic[3]?m_value.m_vector_symbolic[3]->reg_num():0; } + int reg5_num() const { return m_value.m_vector_symbolic[4]?m_value.m_vector_symbolic[4]->reg_num():0; } + int reg6_num() const { return m_value.m_vector_symbolic[5]?m_value.m_vector_symbolic[5]->reg_num():0; } + int reg7_num() const { return m_value.m_vector_symbolic[6]?m_value.m_vector_symbolic[6]->reg_num():0; } + int reg8_num() const { return m_value.m_vector_symbolic[7]?m_value.m_vector_symbolic[7]->reg_num():0; } int arch_reg_num() const { return m_value.m_symbolic->arch_reg_num(); } int arch_reg_num(unsigned n) const { return (m_value.m_vector_symbolic[n])? m_value.m_vector_symbolic[n]->arch_reg_num() : -1; } bool is_label() const { return m_type == label_t;} -- cgit v1.3 From 262663ac90d2aa801d6af1eb9bf8a75ee9a5bb18 Mon Sep 17 00:00:00 2001 From: negargoli93 Date: Wed, 20 Jun 2018 18:20:05 -0700 Subject: Tensor core timing model --- cuda-kernels/gpgpusim.config | 7 +++-- src/abstract_hardware_model.h | 2 ++ src/cuda-sim/cuda-sim.cc | 5 ++-- src/gpgpu-sim/gpu-sim.cc | 16 ++++++++-- src/gpgpu-sim/scoreboard.cc | 40 +++++++++++++++++++------ src/gpgpu-sim/shader.cc | 70 +++++++++++++++++++++++++++++++++++++++---- src/gpgpu-sim/shader.h | 47 ++++++++++++++++++++++++++--- 7 files changed, 163 insertions(+), 24 deletions(-) (limited to 'src/abstract_hardware_model.h') diff --git a/cuda-kernels/gpgpusim.config b/cuda-kernels/gpgpusim.config index 306d7f9..69a110f 100755 --- a/cuda-kernels/gpgpusim.config +++ b/cuda-kernels/gpgpusim.config @@ -33,10 +33,10 @@ # ID_OC_SP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_SFU,OC_EX_MEM,EX_WB ## Pascal GP102 has 4 SP SIMD units and 1 SFU unit ## we need to scale the number of pipeline registers to be equal to the number of SP units --gpgpu_pipeline_widths 4,1,1,4,1,1,6 +-gpgpu_pipeline_widths 4,1,1,1,4,1,1,1,,6 -gpgpu_num_sp_units 4 -gpgpu_num_sfu_units 1 - +-gpgpu_num_tensor_core_units 1 # Instruction latencies and initiation intervals # "ADD,MAX,MUL,MAD,DIV" # SFU is 32-width in pascal, then dp units initiation is 1 cycle @@ -72,11 +72,14 @@ ## larger operand collectors and reg_banks are needed for the 4 warp schedulers and 4 SIMD units -gpgpu_operand_collector_num_units_sp 20 -gpgpu_operand_collector_num_units_sfu 4 +-gpgpu_operand_collector_num_units_tensor_core 24 -gpgpu_operand_collector_num_units_mem 8 -gpgpu_operand_collector_num_in_ports_sp 4 -gpgpu_operand_collector_num_out_ports_sp 4 -gpgpu_operand_collector_num_in_ports_sfu 1 -gpgpu_operand_collector_num_out_ports_sfu 1 +-gpgpu_operand_collector_num_in_ports_tensor_core 1 +-gpgpu_operand_collector_num_out_ports_tensor_core 1 -gpgpu_operand_collector_num_in_ports_mem 1 -gpgpu_operand_collector_num_out_ports_mem 1 # gpgpu_num_reg_banks should be increased to 32, but it gives an error! diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index e00c941..e2e116e 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -77,6 +77,7 @@ enum uarch_op_t { NO_OP=-1, ALU_OP=1, SFU_OP, + TENSOR_CORE_OP, ALU_SFU_OP, LOAD_OP, STORE_OP, @@ -133,6 +134,7 @@ enum operation_pipeline_t { UNKOWN_OP, SP__OP, SFU__OP, + TENSOR_CORE__OP, MEM__OP }; typedef enum operation_pipeline_t operation_pipeline; diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index 7552acf..6da0840 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -520,7 +520,7 @@ void ptx_instruction::set_mul_div_or_other_archop(){ sp_op=FP_EXP_OP; break; default: - if(op==ALU_OP) + if((op==ALU_OP)||(op==TENSOR_CORE_OP)) sp_op=FP__OP; break; @@ -542,7 +542,7 @@ void ptx_instruction::set_mul_div_or_other_archop(){ sp_op=INT_DIV_OP; break; default: - if(op==ALU_OP) + if((op==ALU_OP)||(op==TENSOR_CORE_OP)) sp_op=INT__OP; break; } @@ -795,6 +795,7 @@ void ptx_instruction::set_opcode_and_latency() case MMA_OP: latency = 64; initiation_interval = 64; + op=TENSOR_CORE_OP; break; case SHFL_OP: latency = 32; diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 3bd1892..cc23051 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -306,6 +306,9 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_operand_collector_num_units_sfu", OPT_INT32, &gpgpu_operand_collector_num_units_sfu, "number of collector units (default = 4)", "4"); + option_parser_register(opp, "-gpgpu_operand_collector_num_units_tensor_core", OPT_INT32, &gpgpu_operand_collector_num_units_tensor_core, + "number of collector units (default = 4)", + "4"); option_parser_register(opp, "-gpgpu_operand_collector_num_units_mem", OPT_INT32, &gpgpu_operand_collector_num_units_mem, "number of collector units (default = 2)", "2"); @@ -318,6 +321,9 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_operand_collector_num_in_ports_sfu", OPT_INT32, &gpgpu_operand_collector_num_in_ports_sfu, "number of collector unit in ports (default = 1)", "1"); + option_parser_register(opp, "-gpgpu_operand_collector_num_in_ports_tensor_core", OPT_INT32, &gpgpu_operand_collector_num_in_ports_tensor_core, + "number of collector unit in ports (default = 1)", + "1"); option_parser_register(opp, "-gpgpu_operand_collector_num_in_ports_mem", OPT_INT32, &gpgpu_operand_collector_num_in_ports_mem, "number of collector unit in ports (default = 1)", "1"); @@ -330,6 +336,9 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_operand_collector_num_out_ports_sfu", OPT_INT32, &gpgpu_operand_collector_num_out_ports_sfu, "number of collector unit in ports (default = 1)", "1"); + option_parser_register(opp, "-gpgpu_operand_collector_num_out_ports_tensor_core", OPT_INT32, &gpgpu_operand_collector_num_out_ports_tensor_core, + "number of collector unit in ports (default = 1)", + "1"); option_parser_register(opp, "-gpgpu_operand_collector_num_out_ports_mem", OPT_INT32, &gpgpu_operand_collector_num_out_ports_mem, "number of collector unit in ports (default = 1)", "1"); @@ -350,14 +359,17 @@ void shader_core_config::reg_options(class OptionParser * opp) "1"); option_parser_register(opp, "-gpgpu_pipeline_widths", OPT_CSTR, &pipeline_widths_string, "Pipeline widths " - "ID_OC_SP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_SFU,OC_EX_MEM,EX_WB", - "1,1,1,1,1,1,1" ); + "ID_OC_SP,ID_OC_SFU,ID_OC_TENSOR_CORE,ID_OC_MEM,OC_EX_SP,OC_EX_SFU,OC_EX_TENSOR_CORE,OC_EX_MEM,EX_WB", + "1,1,1,1,1,1,1,1,1" ); option_parser_register(opp, "-gpgpu_num_sp_units", OPT_INT32, &gpgpu_num_sp_units, "Number of SP units (default=1)", "1"); option_parser_register(opp, "-gpgpu_num_sfu_units", OPT_INT32, &gpgpu_num_sfu_units, "Number of SF units (default=1)", "1"); + option_parser_register(opp, "-gpgpu_num_tensor_core_units", OPT_INT32, &gpgpu_num_tensor_core_units, + "Number of tensor_core units (default=1)", + "1"); option_parser_register(opp, "-gpgpu_num_mem_units", OPT_INT32, &gpgpu_num_mem_units, "Number if ldst units (default=1) WARNING: not hooked up to anything", "1"); diff --git a/src/gpgpu-sim/scoreboard.cc b/src/gpgpu-sim/scoreboard.cc index b538fdf..4d1b43a 100644 --- a/src/gpgpu-sim/scoreboard.cc +++ b/src/gpgpu-sim/scoreboard.cc @@ -82,7 +82,7 @@ const bool Scoreboard::islongop (unsigned warp_id,unsigned regnum) { void Scoreboard::reserveRegisters(const class warp_inst_t* inst) { - for( unsigned r=0; r < 4; r++) { + for( unsigned r=0; r < 8; r++) { if(inst->out[r] > 0) { reserveRegister(inst->warp_id(), inst->out[r]); SHADER_DPRINTF( SCOREBOARD, @@ -100,7 +100,7 @@ void Scoreboard::reserveRegisters(const class warp_inst_t* inst) inst->space.get_type() == param_space_local || inst->space.get_type() == param_space_unclassified || inst->space.get_type() == tex_space)){ - for ( unsigned r=0; r<4; r++) { + for ( unsigned r=0; r<8; r++) { if(inst->out[r] > 0) { SHADER_DPRINTF( SCOREBOARD, "New longopreg marked - warp:%d, reg: %d\n", @@ -115,7 +115,7 @@ void Scoreboard::reserveRegisters(const class warp_inst_t* inst) // Release registers for an instruction void Scoreboard::releaseRegisters(const class warp_inst_t *inst) { - for( unsigned r=0; r < 4; r++) { + for( unsigned r=0; r < 8; r++) { if(inst->out[r] > 0) { SHADER_DPRINTF( SCOREBOARD, "Register Released - warp:%d, reg: %d\n", @@ -142,15 +142,37 @@ bool Scoreboard::checkCollision( unsigned wid, const class inst_t *inst ) const if(inst->out[1] > 0) inst_regs.insert(inst->out[1]); if(inst->out[2] > 0) inst_regs.insert(inst->out[2]); if(inst->out[3] > 0) inst_regs.insert(inst->out[3]); - if(inst->in[0] > 0) inst_regs.insert(inst->in[0]); + if(inst->out[4] > 0) inst_regs.insert(inst->out[4]); + if(inst->out[5] > 0) inst_regs.insert(inst->out[5]); + if(inst->out[6] > 0) inst_regs.insert(inst->out[6]); + if(inst->out[7] > 0) inst_regs.insert(inst->out[7]); + + if(inst->in[0] > 0) inst_regs.insert(inst->in[0]); 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->in[4] > 0) inst_regs.insert(inst->in[4]); + if(inst->in[5] > 0) inst_regs.insert(inst->in[5]); + if(inst->in[6] > 0) inst_regs.insert(inst->in[6]); + if(inst->in[7] > 0) inst_regs.insert(inst->in[7]); + if(inst->in[8] > 0) inst_regs.insert(inst->in[8]); + if(inst->in[9] > 0) inst_regs.insert(inst->in[9]); + if(inst->in[10] > 0) inst_regs.insert(inst->in[10]); + if(inst->in[11] > 0) inst_regs.insert(inst->in[11]); + if(inst->in[12] > 0) inst_regs.insert(inst->in[12]); + if(inst->in[13] > 0) inst_regs.insert(inst->in[13]); + if(inst->in[14] > 0) inst_regs.insert(inst->in[14]); + if(inst->in[15] > 0) inst_regs.insert(inst->in[15]); + if(inst->in[16] > 0) inst_regs.insert(inst->in[16]); + if(inst->in[17] > 0) inst_regs.insert(inst->in[17]); + if(inst->in[18] > 0) inst_regs.insert(inst->in[18]); + if(inst->in[19] > 0) inst_regs.insert(inst->in[19]); + if(inst->in[20] > 0) inst_regs.insert(inst->in[20]); + if(inst->in[21] > 0) inst_regs.insert(inst->in[21]); + if(inst->in[22] > 0) inst_regs.insert(inst->in[22]); + if(inst->in[23] > 0) inst_regs.insert(inst->in[23]); + + 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/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 92cdb5b..fcac755 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -148,6 +148,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, &m_warp, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_SFU], + &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i ) @@ -162,6 +163,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, &m_warp, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_SFU], + &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i, config->gpgpu_scheduler_string @@ -177,6 +179,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, &m_warp, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_SFU], + &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i ) @@ -191,6 +194,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, &m_warp, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_SFU], + &m_pipeline_reg[ID_OC_TENSOR_CORE], &m_pipeline_reg[ID_OC_MEM], i, config->gpgpu_scheduler_string @@ -211,9 +215,10 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, } //op collector configuration - enum { SP_CUS, SFU_CUS, MEM_CUS, GEN_CUS }; + enum { SP_CUS, SFU_CUS, TENSOR_CORE_CUS, MEM_CUS, GEN_CUS }; m_operand_collector.add_cu_set(SP_CUS, m_config->gpgpu_operand_collector_num_units_sp, m_config->gpgpu_operand_collector_num_out_ports_sp); m_operand_collector.add_cu_set(SFU_CUS, m_config->gpgpu_operand_collector_num_units_sfu, m_config->gpgpu_operand_collector_num_out_ports_sfu); + m_operand_collector.add_cu_set(TENSOR_CORE_CUS, m_config->gpgpu_operand_collector_num_units_tensor_core, m_config->gpgpu_operand_collector_num_out_ports_tensor_core); m_operand_collector.add_cu_set(MEM_CUS, m_config->gpgpu_operand_collector_num_units_mem, m_config->gpgpu_operand_collector_num_out_ports_mem); m_operand_collector.add_cu_set(GEN_CUS, m_config->gpgpu_operand_collector_num_units_gen, m_config->gpgpu_operand_collector_num_out_ports_gen); @@ -237,7 +242,17 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_operand_collector.add_port(in_ports,out_ports,cu_sets); in_ports.clear(),out_ports.clear(),cu_sets.clear(); } + + for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_tensor_core; i++) { + in_ports.push_back(&m_pipeline_reg[ID_OC_TENSOR_CORE]); + out_ports.push_back(&m_pipeline_reg[OC_EX_TENSOR_CORE]); + cu_sets.push_back((unsigned)TENSOR_CORE_CUS); + cu_sets.push_back((unsigned)GEN_CUS); + m_operand_collector.add_port(in_ports,out_ports,cu_sets); + in_ports.clear(),out_ports.clear(),cu_sets.clear(); + } + for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_mem; i++) { in_ports.push_back(&m_pipeline_reg[ID_OC_MEM]); out_ports.push_back(&m_pipeline_reg[OC_EX_MEM]); @@ -251,9 +266,11 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_gen; i++) { in_ports.push_back(&m_pipeline_reg[ID_OC_SP]); in_ports.push_back(&m_pipeline_reg[ID_OC_SFU]); + in_ports.push_back(&m_pipeline_reg[ID_OC_TENSOR_CORE]); in_ports.push_back(&m_pipeline_reg[ID_OC_MEM]); out_ports.push_back(&m_pipeline_reg[OC_EX_SP]); out_ports.push_back(&m_pipeline_reg[OC_EX_SFU]); + out_ports.push_back(&m_pipeline_reg[OC_EX_TENSOR_CORE]); out_ports.push_back(&m_pipeline_reg[OC_EX_MEM]); cu_sets.push_back((unsigned)GEN_CUS); m_operand_collector.add_port(in_ports,out_ports,cu_sets); @@ -263,7 +280,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_operand_collector.init( m_config->gpgpu_num_reg_banks, this ); // execute - m_num_function_units = m_config->gpgpu_num_sp_units + m_config->gpgpu_num_sfu_units + 1; // sp_unit, sfu, ldst_unit + m_num_function_units = m_config->gpgpu_num_sp_units + m_config->gpgpu_num_sfu_units + m_config->gpgpu_num_tensor_core_units + 1; // sp_unit, sfu, ldst_unit //m_dispatch_port = new enum pipeline_stage_name_t[ m_num_function_units ]; //m_issue_port = new enum pipeline_stage_name_t[ m_num_function_units ]; @@ -280,6 +297,12 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_dispatch_port.push_back(ID_OC_SFU); m_issue_port.push_back(OC_EX_SFU); } + + for (int k = 0; k < m_config->gpgpu_num_tensor_core_units; k++) { + m_fu.push_back(new tensor_core( &m_pipeline_reg[EX_WB], m_config, this )); + m_dispatch_port.push_back(ID_OC_TENSOR_CORE); + m_issue_port.push_back(OC_EX_TENSOR_CORE); + } m_ldst_unit = new ldst_unit( m_icnt, m_mem_fetch_allocator, this, &m_operand_collector, m_scoreboard, config, mem_config, stats, shader_id, tpc_id ); m_fu.push_back(m_ldst_unit); @@ -886,7 +909,8 @@ void scheduler_unit::cycle() } else { bool sp_pipe_avail = m_sp_out->has_free(); bool sfu_pipe_avail = m_sfu_out->has_free(); - if( sp_pipe_avail && (pI->op != SFU_OP) ) { + bool tensor_core_pipe_avail = m_tensor_core_out->has_free(); + if( sp_pipe_avail && (pI->op != SFU_OP) && (pI->op != TENSOR_CORE_OP)) { //Jin: special for CDP api if(pI->m_is_cdp && !warp(warp_id).m_cdp_dummy) { @@ -918,6 +942,14 @@ void scheduler_unit::cycle() issued_inst=true; warp_inst_issued = true; } + } + else if ( (pI->op == TENSOR_CORE_OP) ) { + if( tensor_core_pipe_avail ) { + m_shader->issue_warp(*m_tensor_core_out,pI,active_mask,warp_id); + issued++; + issued_inst=true; + warp_inst_issued = true; + } } } } else { SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) fails scoreboard\n", @@ -1083,10 +1115,11 @@ swl_scheduler::swl_scheduler ( shader_core_stats* stats, shader_core_ctx* shader std::vector* warp, register_set* sp_out, register_set* sfu_out, + register_set* tensor_core_out, register_set* mem_out, int id, char* config_string ) - : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, mem_out, id ) + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, tensor_core_out, mem_out, id ) { unsigned m_prioritization_readin; int ret = sscanf( config_string, @@ -1509,6 +1542,13 @@ sfu:: sfu( register_set* result_port, const shader_core_config *config,shader_c m_name = "SFU"; } +tensor_core:: tensor_core( register_set* result_port, const shader_core_config *config,shader_core_ctx *core ) + : pipelined_simd_unit(result_port,config,config->max_tensor_core_latency,core) +{ + m_name = "TENSOR_CORE"; +} + + void sfu::issue( register_set& source_reg ) { warp_inst_t** ready_reg = source_reg.get_ready(); @@ -1519,6 +1559,17 @@ void sfu::issue( register_set& source_reg ) pipelined_simd_unit::issue(source_reg); } +void tensor_core::issue( register_set& source_reg ) +{ + warp_inst_t** ready_reg = source_reg.get_ready(); + //m_core->incexecstat((*ready_reg)); + + (*ready_reg)->op_pipe= TENSOR_CORE__OP; + m_core->incsfu_stat(m_core->get_config()->warp_size,(*ready_reg)->latency); + pipelined_simd_unit::issue(source_reg); +} + + void ldst_unit::active_lanes_in_pipeline(){ unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline(); assert(active_count<=m_core->get_config()->warp_size); @@ -1540,6 +1591,15 @@ void sfu::active_lanes_in_pipeline(){ m_core->incfumemactivelanes_stat(active_count); } +void tensor_core::active_lanes_in_pipeline(){ + unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline(); + assert(active_count<=m_core->get_config()->warp_size); + m_core->incsfuactivelanes_stat(active_count); + m_core->incfuactivelanes_stat(active_count); + m_core->incfumemactivelanes_stat(active_count); +} + + sp_unit::sp_unit( register_set* result_port, const shader_core_config *config,shader_core_ctx *core) : pipelined_simd_unit(result_port,config,config->max_sp_latency,core) { @@ -2237,7 +2297,7 @@ void shader_core_ctx::incexecstat(warp_inst_t *&inst) switch(inst->sp_op){ case INT__OP: - incialu_stat(inst->active_count(),25); + incialu_stat(inst->active_count(),32); break; case INT_MUL_OP: incimul_stat(inst->active_count(),7.2); diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index db2af01..2c4c43d 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -318,11 +318,12 @@ public: std::vector* warp, register_set* sp_out, register_set* sfu_out, + register_set* tensor_core_out, register_set* mem_out, int id) : m_supervised_warps(), m_stats(stats), m_shader(shader), m_scoreboard(scoreboard), m_simt_stack(simt), /*m_pipeline_reg(pipe_regs),*/ m_warp(warp), - m_sp_out(sp_out),m_sfu_out(sfu_out),m_mem_out(mem_out), m_id(id){} + m_sp_out(sp_out),m_sfu_out(sfu_out),m_tensor_core_out(tensor_core_out),m_mem_out(mem_out), m_id(id){} virtual ~scheduler_unit(){} virtual void add_supervised_warp_id(int i) { m_supervised_warps.push_back(&warp(i)); @@ -395,6 +396,7 @@ protected: std::vector* m_warp; register_set* m_sp_out; register_set* m_sfu_out; + register_set* m_tensor_core_out; register_set* m_mem_out; int m_id; @@ -407,9 +409,10 @@ public: std::vector* warp, register_set* sp_out, register_set* sfu_out, + register_set* tensor_core_out, register_set* mem_out, int id ) - : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, mem_out, id ){} + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, tensor_core_out, mem_out, id ){} virtual ~lrr_scheduler () {} virtual void order_warps (); virtual void done_adding_supervised_warps() { @@ -424,9 +427,10 @@ public: std::vector* warp, register_set* sp_out, register_set* sfu_out, + register_set* tensor_core_out, register_set* mem_out, int id ) - : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, mem_out, id ){} + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, tensor_core_out, mem_out, id ){} virtual ~gto_scheduler () {} virtual void order_warps (); virtual void done_adding_supervised_warps() { @@ -443,10 +447,11 @@ public: std::vector* warp, register_set* sp_out, register_set* sfu_out, + register_set* tensor_core_out, register_set* mem_out, int id, char* config_str ) - : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, mem_out, id ), + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, tensor_core_out, mem_out, id ), m_pending_warps() { unsigned inner_level_readin; @@ -493,6 +498,7 @@ public: std::vector* warp, register_set* sp_out, register_set* sfu_out, + register_set* tensor_core_out, register_set* mem_out, int id, char* config_string ); @@ -1062,6 +1068,23 @@ public: virtual void issue( register_set& source_reg ); }; +class tensor_core : public pipelined_simd_unit +{ +public: + tensor_core( register_set* result_port, const shader_core_config *config, shader_core_ctx *core ); + virtual bool can_issue( const warp_inst_t &inst ) const + { + switch(inst.op) { + case TENSOR_CORE_OP: break; + default: return false; + } + return pipelined_simd_unit::can_issue(inst); + } + virtual void active_lanes_in_pipeline(); + virtual void issue( register_set& source_reg ); +}; + + class sp_unit : public pipelined_simd_unit { public: @@ -1201,9 +1224,11 @@ protected: enum pipeline_stage_name_t { ID_OC_SP=0, ID_OC_SFU, + ID_OC_TENSOR_CORE, ID_OC_MEM, OC_EX_SP, OC_EX_SFU, + OC_EX_TENSOR_CORE, OC_EX_MEM, EX_WB, N_PIPELINE_STAGES @@ -1212,9 +1237,11 @@ enum pipeline_stage_name_t { const char* const pipeline_stage_name_decode[] = { "ID_OC_SP", "ID_OC_SFU", + "ID_OC_TENSOR_CORE", "ID_OC_MEM", "OC_EX_SP", "OC_EX_SFU", + "OC_EX_TENSOR_CORE", "OC_EX_MEM", "EX_WB", "N_PIPELINE_STAGES" @@ -1257,6 +1284,7 @@ struct shader_core_config : public core_config max_warps_per_shader = n_thread_per_shader/warp_size; assert( !(n_thread_per_shader % warp_size) ); max_sfu_latency = 512; + max_tensor_core_latency = 512; max_sp_latency = 32; m_L1I_config.init(m_L1I_config.m_config_string,FuncCachePreferNone); m_L1T_config.init(m_L1T_config.m_config_string,FuncCachePreferNone); @@ -1304,21 +1332,25 @@ struct shader_core_config : public core_config //op collector int gpgpu_operand_collector_num_units_sp; int gpgpu_operand_collector_num_units_sfu; + int gpgpu_operand_collector_num_units_tensor_core; int gpgpu_operand_collector_num_units_mem; int gpgpu_operand_collector_num_units_gen; unsigned int gpgpu_operand_collector_num_in_ports_sp; unsigned int gpgpu_operand_collector_num_in_ports_sfu; + unsigned int gpgpu_operand_collector_num_in_ports_tensor_core; unsigned int gpgpu_operand_collector_num_in_ports_mem; unsigned int gpgpu_operand_collector_num_in_ports_gen; unsigned int gpgpu_operand_collector_num_out_ports_sp; unsigned int gpgpu_operand_collector_num_out_ports_sfu; + unsigned int gpgpu_operand_collector_num_out_ports_tensor_core; unsigned int gpgpu_operand_collector_num_out_ports_mem; unsigned int gpgpu_operand_collector_num_out_ports_gen; int gpgpu_num_sp_units; int gpgpu_num_sfu_units; + int gpgpu_num_tensor_core_units; int gpgpu_num_mem_units; //Shader core resources @@ -1331,6 +1363,7 @@ struct shader_core_config : public core_config unsigned max_sp_latency; unsigned max_sfu_latency; + unsigned max_tensor_core_latency; unsigned n_simt_cores_per_cluster; unsigned n_simt_clusters; @@ -1368,12 +1401,14 @@ struct shader_core_stats_pod { unsigned *m_num_fpdiv_acesses; unsigned *m_num_sp_acesses; unsigned *m_num_sfu_acesses; + unsigned *m_num_tensor_core_acesses; unsigned *m_num_trans_acesses; unsigned *m_num_mem_acesses; unsigned *m_num_sp_committed; unsigned *m_num_tlb_hits; unsigned *m_num_tlb_accesses; unsigned *m_num_sfu_committed; + unsigned *m_num_tensor_core_committed; unsigned *m_num_mem_committed; unsigned *m_read_regfile_acesses; unsigned *m_write_regfile_acesses; @@ -1382,6 +1417,7 @@ struct shader_core_stats_pod { unsigned *m_num_imul32_acesses; unsigned *m_active_sp_lanes; unsigned *m_active_sfu_lanes; + unsigned *m_active_tensor_core_lanes; unsigned *m_active_fu_lanes; unsigned *m_active_fu_mem_lanes; unsigned *m_n_diverge; // number of divergence occurring in this shader @@ -1453,6 +1489,7 @@ public: m_num_fpdiv_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_sp_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_sfu_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); + m_num_tensor_core_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_trans_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_mem_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_sp_committed= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); @@ -1460,9 +1497,11 @@ public: m_num_tlb_accesses=(unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_active_sp_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_active_sfu_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); + m_active_tensor_core_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_active_fu_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_active_fu_mem_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_sfu_committed= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); + m_num_tensor_core_committed= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_mem_committed= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_read_regfile_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_write_regfile_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); -- cgit v1.3 From b3ad8abea43b7d1e8887f57d6e30c5a40cf752a6 Mon Sep 17 00:00:00 2001 From: aamir Date: Sat, 21 Jul 2018 19:21:30 -0700 Subject: merging the changes of cutlass on negar tensorcore branch --- .gitignore | 6 +- cutlass-example | 1 + libcuda/cuda_runtime_api.cc | 42 +++++++++++++- src/abstract_hardware_model.h | 2 +- src/cuda-sim/cuda-sim.cc | 7 +++ src/cuda-sim/instructions.cc | 125 ++++++++++++++++++++++++++++++++---------- 6 files changed, 151 insertions(+), 32 deletions(-) create mode 160000 cutlass-example (limited to 'src/abstract_hardware_model.h') diff --git a/.gitignore b/.gitignore index 53fadb5..b214862 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +*~ +*.swp +*.swo + src/intersim2/lex.yy.c src/intersim2/y.tab.c src/intersim2/y.tab.h @@ -26,4 +30,4 @@ cuobjdump_to_ptxplus/sass_parser.cc cuobjdump_to_ptxplus/sass_parser.hh cuobjdump_to_ptxplus/sass_parser.output -build/* \ No newline at end of file +build/* diff --git a/cutlass-example b/cutlass-example new file mode 160000 index 0000000..e69115d --- /dev/null +++ b/cutlass-example @@ -0,0 +1 @@ +Subproject commit e69115d598bef1e5372c9134322972b2ea450d9f diff --git a/libcuda/cuda_runtime_api.cc b/libcuda/cuda_runtime_api.cc index cbe8a11..aa43ffa 100644 --- a/libcuda/cuda_runtime_api.cc +++ b/libcuda/cuda_runtime_api.cc @@ -952,7 +952,9 @@ __host__ cudaError_t CUDARTAPI cudaSetupArgument(const void *arg, size_t size, s gpgpusim_ptx_assert( !g_cuda_launch_stack.empty(), "empty launch stack" ); kernel_config &config = g_cuda_launch_stack.back(); config.set_arg(arg,size,offset); - + #if 0 + printf("cudaSetupArgument:size%d,offset%d,sizeof(Arg[0])=%d)\n ",size,offset,sizeof(arg)); + #endif return g_last_cudaError = cudaSuccess; } @@ -980,6 +982,44 @@ __host__ cudaError_t CUDARTAPI cudaLaunch( const char *hostFun ) return g_last_cudaError = cudaSuccess; } +__host__ cudaError_t CUDARTAPI cudaLaunchKernel ( const char* hostFun, dim3 gridDim, dim3 blockDim, const void** args, size_t sharedMem, cudaStream_t stream ) +{ + struct CUstream_st *s = (struct CUstream_st *)stream; + g_cuda_launch_stack.push_back( kernel_config(gridDim,blockDim,sharedMem,s) ); + + + printf("cudaLaunchKernel:sizeof(Arg[0])=%d)\n ",sizeof(args[0])); + //gpgpusim_ptx_assert( !g_cuda_launch_stack.empty(), "empty launch stack" ); + kernel_config &config = g_cuda_launch_stack.back(); + config.set_arg(args[0],432,0); + printf("cudaLaunchParameter\n"); + for(int i=0;i<108;i++){ + printf("cudaLaunchParameter:%d:%08x\n",i,*(*((int **)args)+i)); + } + + CUctx_st* context = GPGPUSim_Context(); + char *mode = getenv("PTX_SIM_MODE_FUNC"); + if( mode ) + sscanf(mode,"%u", &g_ptx_sim_mode); + gpgpusim_ptx_assert( !g_cuda_launch_stack.empty(), "empty launch stack" ); + kernel_config config1 = g_cuda_launch_stack.back(); + struct CUstream_st *stream1 = config1.get_stream(); + printf("\nGPGPU-Sim PTX: cudaLaunch for 0x%p (mode=%s) on stream %u\n", hostFun, + g_ptx_sim_mode?"functional simulation":"performance simulation", stream1?stream1->get_uid():0 ); + kernel_info_t *grid = gpgpu_cuda_ptx_sim_init_grid(hostFun,config1.get_args(),config1.grid_dim(),config1.block_dim(),context); + std::string kname = grid->name(); + dim3 gridDim1 = config1.grid_dim(); + dim3 blockDim1 = config1.block_dim(); + printf("GPGPU-Sim PTX: pushing kernel \'%s\' to stream %u, gridDim= (%u,%u,%u) blockDim = (%u,%u,%u) \n", + kname.c_str(), stream1?stream1->get_uid():0, gridDim1.x,gridDim1.y,gridDim1.z,blockDim1.x,blockDim1.y,blockDim1.z ); + stream_operation op(grid,g_ptx_sim_mode,stream1); + g_stream_manager->push(op); + g_cuda_launch_stack.pop_back(); + return g_last_cudaError = cudaSuccess; + + +} + /******************************************************************************* * * * * diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index e2e116e..7fe5d82 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -386,7 +386,7 @@ protected: std::deque m_stack; }; -#define GLOBAL_HEAP_START 0x703E20000 +#define GLOBAL_HEAP_START 0xC0000000 // start allocating from this address (lower values used for allocating globals in .ptx file) #define SHARED_MEM_SIZE_MAX (64*1024) #define LOCAL_MEM_SIZE_MAX (8*1024) diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index 506bc95..8284ad5 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -1273,6 +1273,13 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id) addr_t pc = next_instr(); assert( pc == inst.pc ); // make sure timing model and functional model are in sync const ptx_instruction *pI = m_func_info->get_instruction(pc); + #if 0 + if(lane_id==0){ + printf("EXECUTION_FLOW:LINE_NUM:%d\n",pI->source_line()); + printf("EXECUTION_FLOW:INST:%s\n",pI->get_source()); + } + #endif + set_npc( pc + pI->inst_size() ); diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index cebce1e..7af157f 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -48,7 +48,7 @@ using half_float::half; unsigned ptx_instruction::g_num_ptx_inst_uid=0; -bool g_debug_instruction = 0; +bool g_debug_instruction = 1; const char *g_opcode_string[NUM_OPCODES] = { @@ -239,9 +239,9 @@ ptx_reg_t ptx_thread_info::get_operand_value( const operand_info &op, operand_in } else if ( op.is_sstarr() ) { result.u64 = op.get_symbol()->get_address() + op.get_addr_offset(); } else { - const char *name = op.name().c_str(); - printf("GPGPU-Sim PTX: ERROR ** get_operand_value : unknown memory operand type for %s\n", name ); - abort(); + const char *name = op.name().c_str(); + printf("GPGPU-Sim PTX: ERROR ** get_operand_value : unknown memory operand type for %s\n", name ); + abort(); } } else if ( op.is_literal() ) { @@ -260,10 +260,18 @@ ptx_reg_t ptx_thread_info::get_operand_value( const operand_info &op, operand_in result.u64 = op.get_symbol()->get_address(); } else if ( op.is_function_address() ) { result.u64 = (size_t)op.get_symbol()->get_pc(); - } else { + }else { const char *name = op.name().c_str(); - printf("GPGPU-Sim PTX: ERROR ** get_operand_value : unknown operand type for %s\n", name ); - assert(0); + const symbol *sym2 = op.get_symbol(); + const type_info *type2 = sym2->type(); + const type_info_key &info2 = type2->get_key(); + if ( info2.is_param_kernel() ) { + result.u64 = sym2->get_address()+ op.get_addr_offset(); + } + else{ + printf("GPGPU-Sim PTX: ERROR ** get_operand_value : unknown operand type for %s\n", name ); + assert(0); + } } if(op.get_operand_lohi() == 1) @@ -1551,7 +1559,44 @@ void bfe_impl( const ptx_instruction *pI, ptx_thread_info *thread ) thread->set_operand_value(dst,d, i_type, thread, pI); } -void bfi_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); } +void bfi_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { + int i,max; + ptx_reg_t src1_data, src2_data; + ptx_reg_t src3_data, src4_data, data; + + const operand_info &dst = pI->dst(); //get operand info of sources and destination + const operand_info &src1 = pI->src1(); //use them to determine that they are of type 'register' + const operand_info &src2 = pI->src2(); + const operand_info &src3 = pI->src3(); + const operand_info &src4 = pI->src4(); + + 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); + src3_data = thread->get_operand_value(src3, dst, i_type, thread, 1); + src4_data = thread->get_operand_value(src4, dst, i_type, thread, 1); + + switch ( i_type ) { + case B32_TYPE: + max = 32; + break; + case B64_TYPE: + max = 64; + break; + default: + printf("Execution error: type mismatch with instruction\n"); + assert(0); + break; + } + data=src2_data; + unsigned pos = src3_data.u32 & 0xFF; + unsigned len = src4_data.u32 & 0xFF; + for(i=0;iset_operand_value(dst, data, i_type, thread, pI); +} void bfind_impl( const ptx_instruction *pI, ptx_thread_info *thread ) { inst_not_implemented(pI); } void bra_impl( const ptx_instruction *pI, ptx_thread_info *thread ) @@ -2180,16 +2225,19 @@ ptx_reg_t f2x( ptx_reg_t x, unsigned from_width, unsigned to_width, int to_sign, } } else { switch ( to_width ) { - case 16: //assert(0); break; + case 16: mytemp=half(x.f32); myfloat=mytemp; y.f16 =mytemp; - //y.f16 = half(x.f32); + #if 0 printf("f2x: %f\n",myfloat); + #endif break; case 32: - y.f32=float(x.f16); - + y.f32=float(x.f16); + #if 0 + printf("f2xnew:%x:my%f:%f\n",x.f16,y.f32,half_float::detail::half2float(x.u16)); + #endif break; // handled by f2f case 64: y.f64 = x.f32; @@ -2813,7 +2861,12 @@ void decode_space( memory_space_t &space, ptx_thread_info *thread, const operand space = param_space_kernel; else if( ti.is_param_local() ) { space = param_space_local; - } else { + } + //mov r1, param-label + else if (ti.is_reg() ){ + space = param_space_kernel; + } + else { printf("GPGPU-Sim PTX: ERROR ** cannot resolve .param space for '%s'\n", s->name().c_str() ); abort(); } @@ -2908,6 +2961,7 @@ void ldu_impl( const ptx_instruction *pI, ptx_thread_info *thread ) void mma_st_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) { size_t size; + unsigned smid; int t; int thrd,odd,inx,k; ptx_thread_info *thread; @@ -2936,7 +2990,12 @@ void mma_st_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) memory_space *mem = NULL; addr_t addr = addr_reg.u32; - + + smid = thread->get_hw_sid(); + if( whichspace(addr) == shared_space ) { + addr= generic_to_shared(smid,addr); + space = shared_space; + } decode_space(space,thread,src1,mem,addr); type_info_key::type_decode(type,size,t); @@ -2961,7 +3020,7 @@ void mma_st_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) int l; printf("thread=%d:",thrd); for(l=0;l<8;l++){ - temp=v[0].f32; + temp=v[l].f32; printf("%f",temp); } printf("\n"); @@ -2988,6 +3047,7 @@ void mma_ld_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) { size_t size; int t,i; + unsigned smid; const operand_info &dst = pI->dst(); const operand_info &src1 = pI->src1(); const operand_info &src2 = pI->src2(); @@ -3008,9 +3068,16 @@ void mma_ld_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) memory_space *mem = NULL; addr_t addr = src1_data.u32; - decode_space(space,thread,src1,mem,addr); - type_info_key::type_decode(type,size,t); + smid = thread->get_hw_sid(); + if( whichspace(addr) == shared_space ) { + addr= generic_to_shared(smid,addr); + space = shared_space; + } + + decode_space(space,thread,src1,mem,addr); + type_info_key::type_decode(type,size,t); + ptx_reg_t data[16]; if(g_debug_instruction) printf("mma_ld: thrd=%d,addr=%d, fpsize=%d, stride=%d\n",thrd,src1_data.u32,size,src2_data.u32); @@ -3070,13 +3137,13 @@ void mma_ld_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) } if(g_debug_instruction){ if(type==F16_TYPE){ - printf("\nthread%d= ",thrd); + printf("\nmma_ld:thread%d= ",thrd); for(i=0;i<16;i++){ printf("%x ",data[i].u64); } printf("\n"); - printf("\nthread%d= ",thrd); + printf("\nmma_ld:thread%d= ",thrd); float temp; for(i=0;i<16;i++){ temp=data[i].f16; @@ -3085,12 +3152,12 @@ void mma_ld_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) printf("\n"); } else{ - printf("\nthread%d= ",thrd); + printf("\nmma_ld:thread%d= ",thrd); for(i=0;i<8;i++){ printf("%f ",data[i].f32); } printf("\n"); - printf("\nthread%d= ",thrd); + printf("\nmma_ld:thread%d= ",thrd); for(i=0;i<8;i++){ printf("%x ",data[i].u64); } @@ -3119,15 +3186,15 @@ void mma_ld_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) else thread->set_wmma_vector_operand_values(dst,nw_data[0],nw_data[1],nw_data[2],nw_data[3],nw_data[4],nw_data[5],nw_data[6],nw_data[7]); if(g_debug_instruction){ - printf("wmma_load:data[0].s64=%x,data[1].s64=%x,new_data[0].s64=%x\n",data[0].u64,data[1].u64,nw_data[0].u64); - printf("wmma_load:data[2].s64=%x,data[3].s64=%x,new_data[1].s64=%x\n",data[2].u64,data[3].u64,nw_data[1].u64); - printf("wmma_load:data[4].s64=%x,data[5].s64=%x,new_data[2].s64=%x\n",data[4].u64,data[5].u64,nw_data[2].u64); - printf("wmma_load:data[6].s64=%x,data[7].s64=%x,new_data[3].s64=%x\n",data[6].u64,data[7].u64,nw_data[3].u64); + printf("mma_ld:data[0].s64=%x,data[1].s64=%x,new_data[0].s64=%x\n",data[0].u64,data[1].u64,nw_data[0].u64); + printf("mma_ld:data[2].s64=%x,data[3].s64=%x,new_data[1].s64=%x\n",data[2].u64,data[3].u64,nw_data[1].u64); + printf("mma_ld:data[4].s64=%x,data[5].s64=%x,new_data[2].s64=%x\n",data[4].u64,data[5].u64,nw_data[2].u64); + printf("mma_ld:data[6].s64=%x,data[7].s64=%x,new_data[3].s64=%x\n",data[6].u64,data[7].u64,nw_data[3].u64); if(wmma_type!=LOAD_C){ - printf("wmma_load:data[8].s64=%x,data[9].s64=%x,new_data[4].s64=%x\n",data[8].u64,data[9].u64,nw_data[4].s64); - printf("wmma_load:data[10].s64=%x,data[11].s64=%x,new_data[5].s64=%x\n",data[10].u64,data[11].u64,nw_data[5].u64); - printf("wmma_load:data[12].s64=%x,data[13].s64=%x,new_data[6].s64=%x\n",data[12].u64,data[13].u64,nw_data[6].u64); - printf("wmma_load:data[14].s64=%x,data[15].s64=%x,new_data[7].s64=%x\n",data[14].u64,data[15].u64,nw_data[3].u64); + printf("mma_ld:data[8].s64=%x,data[9].s64=%x,new_data[4].s64=%x\n",data[8].u64,data[9].u64,nw_data[4].s64); + printf("mma_ld:data[10].s64=%x,data[11].s64=%x,new_data[5].s64=%x\n",data[10].u64,data[11].u64,nw_data[5].u64); + printf("mma_ld:data[12].s64=%x,data[13].s64=%x,new_data[6].s64=%x\n",data[12].u64,data[13].u64,nw_data[6].u64); + printf("mma_ld:data[14].s64=%x,data[15].s64=%x,new_data[7].s64=%x\n",data[14].u64,data[15].u64,nw_data[3].u64); } } } -- cgit v1.3 From 9e7cd8867d76fb99eadfadfa09947ff057d012d3 Mon Sep 17 00:00:00 2001 From: negargoli93 Date: Thu, 16 Aug 2018 15:20:07 -0700 Subject: Timing model for VCORE --- src/abstract_hardware_model.h | 2 ++ src/cuda-sim/cuda-sim.cc | 28 ++++++++++++++++--- src/cuda-sim/ptx_ir.h | 4 +-- src/gpgpu-sim/gpu-sim.cc | 16 +++++++++-- src/gpgpu-sim/shader.cc | 62 ++++++++++++++++++++++++++++++++++++++++--- src/gpgpu-sim/shader.h | 57 ++++++++++++++++++++++++++++++++++----- 6 files changed, 152 insertions(+), 17 deletions(-) (limited to 'src/abstract_hardware_model.h') diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 7fe5d82..781509f 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -78,6 +78,7 @@ enum uarch_op_t { ALU_OP=1, SFU_OP, TENSOR_CORE_OP, + VP_CORE_OP, ALU_SFU_OP, LOAD_OP, STORE_OP, @@ -135,6 +136,7 @@ enum operation_pipeline_t { SP__OP, SFU__OP, TENSOR_CORE__OP, + VP_CORE__OP, MEM__OP }; typedef enum operation_pipeline_t operation_pipeline; diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index 2fe5667..1ad12ee 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -542,7 +542,7 @@ void ptx_instruction::set_mul_div_or_other_archop(){ sp_op=INT_DIV_OP; break; default: - if((op==ALU_OP)||(op==TENSOR_CORE_OP)) + if((op==ALU_OP)||(op==VP_CORE_OP)) sp_op=INT__OP; break; } @@ -649,9 +649,11 @@ void ptx_instruction::set_opcode_and_latency() break; case LD_OP: op = LOAD_OP; break; case MMA_LD_OP: op = LOAD_OP; break; + case VP_LD_OP: op = LOAD_OP; break; case LDU_OP: op = LOAD_OP; break; case ST_OP: op = STORE_OP; break; case MMA_ST_OP: op = STORE_OP; break; + case VP_ST_OP: op = STORE_OP; break; case BRA_OP: op = BRANCH_OP; break; case BREAKADDR_OP: op = BRANCH_OP; break; case TEX_OP: op = LOAD_OP; mem_op=TEX; break; @@ -799,6 +801,26 @@ void ptx_instruction::set_opcode_and_latency() initiation_interval = 64; op=TENSOR_CORE_OP; break; + case VP_MMA_OP: + if(get_wmma_type()==VP_MMA4) + { + latency = 5; + initiation_interval = 5; + } + if(get_wmma_type()==VP_MMA8) + { + latency = 5; + initiation_interval = 5; + } + if(get_wmma_type()==VP_MMA16) + { + latency = 5; + initiation_interval = 5; + } + op=VP_CORE_OP; + op=VP_CORE_OP; + op=VP_CORE_OP; + break; case SHFL_OP: latency = 32; initiation_interval = 15; @@ -900,10 +922,10 @@ void ptx_instruction::pre_decode() case WT_OPTION: cache_op = CACHE_WRITE_THROUGH; break; default: //if( m_opcode == LD_OP || m_opcode == LDU_OP ) - if( m_opcode == MMA_LD_OP || m_opcode == LD_OP || m_opcode == LDU_OP ) + if( m_opcode ==VP_LD_OP || m_opcode == MMA_LD_OP || m_opcode == LD_OP || m_opcode == LDU_OP ) cache_op = CACHE_ALL; //else if( m_opcode == ST_OP ) - else if( m_opcode == ST_OP || m_opcode == ST_OP ) + else if( m_opcode == VP_ST_OP ||m_opcode == MMA_ST_OP || m_opcode == ST_OP ) cache_op = CACHE_WRITE_BACK; else if( m_opcode == ATOM_OP ) cache_op = CACHE_GLOBAL; diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index cb4556e..e025013 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -1093,7 +1093,7 @@ public: int membar_level() const { return m_membar_level; } bool has_memory_read() const { - if( m_opcode == LD_OP || m_opcode == LDU_OP || m_opcode == TEX_OP|| m_opcode==MMA_LD_OP) + if( m_opcode == LD_OP || m_opcode == LDU_OP || m_opcode == TEX_OP|| m_opcode==MMA_LD_OP || m_opcode==VP_LD_OP) return true; // Check PTXPlus operand type below // Source operands are memory operands @@ -1105,7 +1105,7 @@ public: return false; } bool has_memory_write() const { - if( m_opcode == ST_OP || m_opcode==MMA_ST_OP ) return true; + if( m_opcode == ST_OP || m_opcode==MMA_ST_OP || m_opcode==VP_ST_OP ) return true; // Check PTXPlus operand type below // Destination operand is a memory operand ptx_instruction::const_iterator op=op_iter_begin(); diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index 3e064c7..7a797b5 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -309,6 +309,9 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_operand_collector_num_units_tensor_core", OPT_INT32, &gpgpu_operand_collector_num_units_tensor_core, "number of collector units (default = 4)", "4"); + option_parser_register(opp, "-gpgpu_operand_collector_num_units_vp_core", OPT_INT32, &gpgpu_operand_collector_num_units_vp_core, + "number of collector units (default = 4)", + "4"); option_parser_register(opp, "-gpgpu_operand_collector_num_units_mem", OPT_INT32, &gpgpu_operand_collector_num_units_mem, "number of collector units (default = 2)", "2"); @@ -324,6 +327,9 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_operand_collector_num_in_ports_tensor_core", OPT_INT32, &gpgpu_operand_collector_num_in_ports_tensor_core, "number of collector unit in ports (default = 1)", "1"); + option_parser_register(opp, "-gpgpu_operand_collector_num_in_ports_vp_core", OPT_INT32, &gpgpu_operand_collector_num_in_ports_vp_core, + "number of collector unit in ports (default = 1)", + "1"); option_parser_register(opp, "-gpgpu_operand_collector_num_in_ports_mem", OPT_INT32, &gpgpu_operand_collector_num_in_ports_mem, "number of collector unit in ports (default = 1)", "1"); @@ -339,6 +345,9 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_operand_collector_num_out_ports_tensor_core", OPT_INT32, &gpgpu_operand_collector_num_out_ports_tensor_core, "number of collector unit in ports (default = 1)", "1"); + option_parser_register(opp, "-gpgpu_operand_collector_num_out_ports_vp_core", OPT_INT32, &gpgpu_operand_collector_num_out_ports_vp_core, + "number of collector unit in ports (default = 1)", + "1"); option_parser_register(opp, "-gpgpu_operand_collector_num_out_ports_mem", OPT_INT32, &gpgpu_operand_collector_num_out_ports_mem, "number of collector unit in ports (default = 1)", "1"); @@ -359,8 +368,8 @@ void shader_core_config::reg_options(class OptionParser * opp) "1"); option_parser_register(opp, "-gpgpu_pipeline_widths", OPT_CSTR, &pipeline_widths_string, "Pipeline widths " - "ID_OC_SP,ID_OC_SFU,ID_OC_TENSOR_CORE,ID_OC_MEM,OC_EX_SP,OC_EX_SFU,OC_EX_TENSOR_CORE,OC_EX_MEM,EX_WB", - "1,1,1,1,1,1,1,1,1" ); + "ID_OC_SP,ID_OC_SFU,ID_OC_TENSOR_CORE,ID_OC_VP_CORE,ID_OC_MEM,OC_EX_SP,OC_EX_SFU,OC_EX_TENSOR_CORE,OC_EX_TENSOR_CORE,OC_EX_MEM,EX_WB", + "1,1,1,1,1,1,1,1,1,1,1" ); option_parser_register(opp, "-gpgpu_num_sp_units", OPT_INT32, &gpgpu_num_sp_units, "Number of SP units (default=1)", "1"); @@ -370,6 +379,9 @@ void shader_core_config::reg_options(class OptionParser * opp) option_parser_register(opp, "-gpgpu_num_tensor_core_units", OPT_INT32, &gpgpu_num_tensor_core_units, "Number of tensor_core units (default=1)", "1"); + option_parser_register(opp, "-gpgpu_num_vp_core_units", OPT_INT32, &gpgpu_num_vp_core_units, + "Number of vp_core units (default=1)", + "1"); option_parser_register(opp, "-gpgpu_num_mem_units", OPT_INT32, &gpgpu_num_mem_units, "Number if ldst units (default=1) WARNING: not hooked up to anything", "1"); diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 226e7f0..6f11ad9 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -149,6 +149,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_SFU], &m_pipeline_reg[ID_OC_TENSOR_CORE], + &m_pipeline_reg[ID_OC_VP_CORE], &m_pipeline_reg[ID_OC_MEM], i ) @@ -164,6 +165,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_SFU], &m_pipeline_reg[ID_OC_TENSOR_CORE], + &m_pipeline_reg[ID_OC_VP_CORE], &m_pipeline_reg[ID_OC_MEM], i, config->gpgpu_scheduler_string @@ -180,6 +182,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_SFU], &m_pipeline_reg[ID_OC_TENSOR_CORE], + &m_pipeline_reg[ID_OC_VP_CORE], &m_pipeline_reg[ID_OC_MEM], i ) @@ -195,6 +198,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, &m_pipeline_reg[ID_OC_SP], &m_pipeline_reg[ID_OC_SFU], &m_pipeline_reg[ID_OC_TENSOR_CORE], + &m_pipeline_reg[ID_OC_VP_CORE], &m_pipeline_reg[ID_OC_MEM], i, config->gpgpu_scheduler_string @@ -215,10 +219,11 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, } //op collector configuration - enum { SP_CUS, SFU_CUS, TENSOR_CORE_CUS, MEM_CUS, GEN_CUS }; + enum { SP_CUS, SFU_CUS, TENSOR_CORE_CUS, VP_CORE_CUS, MEM_CUS, GEN_CUS }; m_operand_collector.add_cu_set(SP_CUS, m_config->gpgpu_operand_collector_num_units_sp, m_config->gpgpu_operand_collector_num_out_ports_sp); m_operand_collector.add_cu_set(SFU_CUS, m_config->gpgpu_operand_collector_num_units_sfu, m_config->gpgpu_operand_collector_num_out_ports_sfu); m_operand_collector.add_cu_set(TENSOR_CORE_CUS, config->gpgpu_operand_collector_num_units_tensor_core, config->gpgpu_operand_collector_num_out_ports_tensor_core); + m_operand_collector.add_cu_set(VP_CORE_CUS, config->gpgpu_operand_collector_num_units_vp_core, config->gpgpu_operand_collector_num_out_ports_vp_core); m_operand_collector.add_cu_set(MEM_CUS, m_config->gpgpu_operand_collector_num_units_mem, m_config->gpgpu_operand_collector_num_out_ports_mem); m_operand_collector.add_cu_set(GEN_CUS, m_config->gpgpu_operand_collector_num_units_gen, m_config->gpgpu_operand_collector_num_out_ports_gen); @@ -252,6 +257,14 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, in_ports.clear(),out_ports.clear(),cu_sets.clear(); } + for (unsigned i = 0; i < config->gpgpu_operand_collector_num_in_ports_vp_core; i++) { + in_ports.push_back(&m_pipeline_reg[ID_OC_VP_CORE]); + out_ports.push_back(&m_pipeline_reg[OC_EX_VP_CORE]); + cu_sets.push_back((unsigned)VP_CORE_CUS); + cu_sets.push_back((unsigned)GEN_CUS); + m_operand_collector.add_port(in_ports,out_ports,cu_sets); + in_ports.clear(),out_ports.clear(),cu_sets.clear(); + } for (unsigned i = 0; i < m_config->gpgpu_operand_collector_num_in_ports_mem; i++) { in_ports.push_back(&m_pipeline_reg[ID_OC_MEM]); @@ -267,10 +280,12 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, in_ports.push_back(&m_pipeline_reg[ID_OC_SP]); in_ports.push_back(&m_pipeline_reg[ID_OC_SFU]); in_ports.push_back(&m_pipeline_reg[ID_OC_TENSOR_CORE]); + in_ports.push_back(&m_pipeline_reg[ID_OC_VP_CORE]); in_ports.push_back(&m_pipeline_reg[ID_OC_MEM]); out_ports.push_back(&m_pipeline_reg[OC_EX_SP]); out_ports.push_back(&m_pipeline_reg[OC_EX_SFU]); out_ports.push_back(&m_pipeline_reg[OC_EX_TENSOR_CORE]); + out_ports.push_back(&m_pipeline_reg[OC_EX_VP_CORE]); out_ports.push_back(&m_pipeline_reg[OC_EX_MEM]); cu_sets.push_back((unsigned)GEN_CUS); m_operand_collector.add_port(in_ports,out_ports,cu_sets); @@ -280,7 +295,7 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_operand_collector.init( m_config->gpgpu_num_reg_banks, this ); // execute - m_num_function_units = m_config->gpgpu_num_sp_units + m_config->gpgpu_num_sfu_units + config->gpgpu_num_tensor_core_units + 1; // sp_unit, sfu, ldst_unit + m_num_function_units = m_config->gpgpu_num_sp_units + m_config->gpgpu_num_sfu_units + config->gpgpu_num_tensor_core_units + config->gpgpu_num_vp_core_units + 1; // sp_unit, sfu, ldst_unit //m_dispatch_port = new enum pipeline_stage_name_t[ m_num_function_units ]; //m_issue_port = new enum pipeline_stage_name_t[ m_num_function_units ]; @@ -304,6 +319,12 @@ shader_core_ctx::shader_core_ctx( class gpgpu_sim *gpu, m_issue_port.push_back(OC_EX_TENSOR_CORE); } + for (int k = 0; k < config->gpgpu_num_vp_core_units; k++) { + m_fu.push_back(new vp_core( &m_pipeline_reg[EX_WB], m_config, this )); + m_dispatch_port.push_back(ID_OC_VP_CORE); + m_issue_port.push_back(OC_EX_VP_CORE); + } + m_ldst_unit = new ldst_unit( m_icnt, m_mem_fetch_allocator, this, &m_operand_collector, m_scoreboard, config, mem_config, stats, shader_id, tpc_id ); m_fu.push_back(m_ldst_unit); m_dispatch_port.push_back(ID_OC_MEM); @@ -910,7 +931,8 @@ void scheduler_unit::cycle() bool sp_pipe_avail = m_sp_out->has_free(); bool sfu_pipe_avail = m_sfu_out->has_free(); bool tensor_core_pipe_avail = m_tensor_core_out->has_free(); - if( sp_pipe_avail && (pI->op != SFU_OP) && (pI->op != TENSOR_CORE_OP)) { + bool vp_core_pipe_avail = m_vp_core_out->has_free(); + if( sp_pipe_avail && (pI->op != SFU_OP) && (pI->op != TENSOR_CORE_OP) && (pI->op !=VP_CORE_OP)) { //Jin: special for CDP api if(pI->m_is_cdp && !warp(warp_id).m_cdp_dummy) { @@ -950,6 +972,14 @@ void scheduler_unit::cycle() issued_inst=true; warp_inst_issued = true; } + } + else if ( (pI->op == VP_CORE_OP) ) { + if( vp_core_pipe_avail ) { + m_shader->issue_warp(*m_vp_core_out,pI,active_mask,warp_id); + issued++; + issued_inst=true; + warp_inst_issued = true; + } } } } else { SCHED_DPRINTF( "Warp (warp_id %u, dynamic_warp_id %u) fails scoreboard\n", @@ -1116,10 +1146,11 @@ swl_scheduler::swl_scheduler ( shader_core_stats* stats, shader_core_ctx* shader register_set* sp_out, register_set* sfu_out, register_set* tensor_core_out, + register_set* vp_core_out, register_set* mem_out, int id, char* config_string ) - : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, tensor_core_out, mem_out, id ) + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, tensor_core_out, vp_core_out, mem_out, id ) { unsigned m_prioritization_readin; int ret = sscanf( config_string, @@ -1548,6 +1579,12 @@ tensor_core:: tensor_core( register_set* result_port, const shader_core_config m_name = "TENSOR_CORE"; } +vp_core:: vp_core( register_set* result_port, const shader_core_config *config,shader_core_ctx *core ) + : pipelined_simd_unit(result_port,config,config->max_vp_core_latency,core) +{ + m_name = "VP_CORE"; +} + void sfu::issue( register_set& source_reg ) { @@ -1569,6 +1606,16 @@ void tensor_core::issue( register_set& source_reg ) pipelined_simd_unit::issue(source_reg); } +void vp_core::issue( register_set& source_reg ) +{ + warp_inst_t** ready_reg = source_reg.get_ready(); + //m_core->incexecstat((*ready_reg)); + + (*ready_reg)->op_pipe= VP_CORE__OP; + m_core->incsfu_stat(m_core->get_config()->warp_size,(*ready_reg)->latency); + pipelined_simd_unit::issue(source_reg); +} + void ldst_unit::active_lanes_in_pipeline(){ unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline(); @@ -1599,6 +1646,13 @@ void tensor_core::active_lanes_in_pipeline(){ m_core->incfumemactivelanes_stat(active_count); } +void vp_core::active_lanes_in_pipeline(){ + unsigned active_count=pipelined_simd_unit::get_active_lanes_in_pipeline(); + assert(active_count<=m_core->get_config()->warp_size); + m_core->incsfuactivelanes_stat(active_count); + m_core->incfuactivelanes_stat(active_count); + m_core->incfumemactivelanes_stat(active_count); +} sp_unit::sp_unit( register_set* result_port, const shader_core_config *config,shader_core_ctx *core) : pipelined_simd_unit(result_port,config,config->max_sp_latency,core) diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 90a3134..d292d56 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -319,11 +319,12 @@ public: register_set* sp_out, register_set* sfu_out, register_set* tensor_core_out, + register_set* vp_core_out, register_set* mem_out, int id) : m_supervised_warps(), m_stats(stats), m_shader(shader), m_scoreboard(scoreboard), m_simt_stack(simt), /*m_pipeline_reg(pipe_regs),*/ m_warp(warp), - m_sp_out(sp_out),m_sfu_out(sfu_out),m_tensor_core_out(tensor_core_out),m_mem_out(mem_out), m_id(id){} + m_sp_out(sp_out),m_sfu_out(sfu_out),m_tensor_core_out(tensor_core_out),m_vp_core_out(vp_core_out),m_mem_out(mem_out), m_id(id){} virtual ~scheduler_unit(){} virtual void add_supervised_warp_id(int i) { m_supervised_warps.push_back(&warp(i)); @@ -397,6 +398,7 @@ protected: register_set* m_sp_out; register_set* m_sfu_out; register_set* m_tensor_core_out; + register_set* m_vp_core_out; register_set* m_mem_out; int m_id; @@ -410,9 +412,10 @@ public: register_set* sp_out, register_set* sfu_out, register_set* tensor_core_out, + register_set* vp_core_out, register_set* mem_out, int id ) - : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, tensor_core_out, mem_out, id ){} + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, tensor_core_out, vp_core_out, mem_out, id ){} virtual ~lrr_scheduler () {} virtual void order_warps (); virtual void done_adding_supervised_warps() { @@ -428,9 +431,10 @@ public: register_set* sp_out, register_set* sfu_out, register_set* tensor_core_out, + register_set* vp_core_out, register_set* mem_out, int id ) - : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, tensor_core_out, mem_out, id ){} + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, tensor_core_out,vp_core_out, mem_out, id ){} virtual ~gto_scheduler () {} virtual void order_warps (); virtual void done_adding_supervised_warps() { @@ -448,10 +452,11 @@ public: register_set* sp_out, register_set* sfu_out, register_set* tensor_core_out, + register_set* vp_core_out, register_set* mem_out, int id, char* config_str ) - : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, tensor_core_out, mem_out, id ), + : scheduler_unit ( stats, shader, scoreboard, simt, warp, sp_out, sfu_out, tensor_core_out, vp_core_out, mem_out, id ), m_pending_warps() { unsigned inner_level_readin; @@ -499,6 +504,7 @@ public: register_set* sp_out, register_set* sfu_out, register_set* tensor_core_out, + register_set* vp_core_out, register_set* mem_out, int id, char* config_string ); @@ -1083,6 +1089,22 @@ public: virtual void active_lanes_in_pipeline(); virtual void issue( register_set& source_reg ); }; +class vp_core : public pipelined_simd_unit +{ +public: + vp_core( register_set* result_port, const shader_core_config *config, shader_core_ctx *core ); + virtual bool can_issue( const warp_inst_t &inst ) const + { + switch(inst.op) { + case VP_CORE_OP: break; + default: return false; + } + return pipelined_simd_unit::can_issue(inst); + } + virtual void active_lanes_in_pipeline(); + virtual void issue( register_set& source_reg ); +}; + class sp_unit : public pipelined_simd_unit @@ -1225,10 +1247,12 @@ enum pipeline_stage_name_t { ID_OC_SP=0, ID_OC_SFU, ID_OC_TENSOR_CORE, + ID_OC_VP_CORE, ID_OC_MEM, OC_EX_SP, OC_EX_SFU, OC_EX_TENSOR_CORE, + OC_EX_VP_CORE, OC_EX_MEM, EX_WB, N_PIPELINE_STAGES @@ -1238,10 +1262,12 @@ const char* const pipeline_stage_name_decode[] = { "ID_OC_SP", "ID_OC_SFU", "ID_OC_TENSOR_CORE", + "ID_OC_VP_CORE", "ID_OC_MEM", "OC_EX_SP", "OC_EX_SFU", "OC_EX_TENSOR_CORE", + "OC_EX_VP_CORE", "OC_EX_MEM", "EX_WB", "N_PIPELINE_STAGES" @@ -1286,13 +1312,21 @@ struct shader_core_config : public core_config max_warps_per_shader = n_thread_per_shader/warp_size; assert( !(n_thread_per_shader % warp_size) ); max_sfu_latency = 512; - max_tensor_core_latency = 64; max_sp_latency = 32; + + max_tensor_core_latency = 64; gpgpu_num_tensor_core_units=8; gpgpu_operand_collector_num_units_tensor_core=24; gpgpu_operand_collector_num_in_ports_tensor_core=8; gpgpu_operand_collector_num_out_ports_tensor_core=8; - m_L1I_config.init(m_L1I_config.m_config_string,FuncCachePreferNone); + + max_vp_core_latency = 64; + gpgpu_num_vp_core_units=8; + gpgpu_operand_collector_num_units_vp_core=24; + gpgpu_operand_collector_num_in_ports_vp_core=8; + gpgpu_operand_collector_num_out_ports_vp_core=8; + + m_L1I_config.init(m_L1I_config.m_config_string,FuncCachePreferNone); m_L1T_config.init(m_L1T_config.m_config_string,FuncCachePreferNone); m_L1C_config.init(m_L1C_config.m_config_string,FuncCachePreferNone); m_L1D_config.init(m_L1D_config.m_config_string,FuncCachePreferNone); @@ -1339,24 +1373,28 @@ struct shader_core_config : public core_config int gpgpu_operand_collector_num_units_sp; int gpgpu_operand_collector_num_units_sfu; int gpgpu_operand_collector_num_units_tensor_core; + int gpgpu_operand_collector_num_units_vp_core; int gpgpu_operand_collector_num_units_mem; int gpgpu_operand_collector_num_units_gen; unsigned int gpgpu_operand_collector_num_in_ports_sp; unsigned int gpgpu_operand_collector_num_in_ports_sfu; unsigned int gpgpu_operand_collector_num_in_ports_tensor_core; + unsigned int gpgpu_operand_collector_num_in_ports_vp_core; unsigned int gpgpu_operand_collector_num_in_ports_mem; unsigned int gpgpu_operand_collector_num_in_ports_gen; unsigned int gpgpu_operand_collector_num_out_ports_sp; unsigned int gpgpu_operand_collector_num_out_ports_sfu; unsigned int gpgpu_operand_collector_num_out_ports_tensor_core; + unsigned int gpgpu_operand_collector_num_out_ports_vp_core; unsigned int gpgpu_operand_collector_num_out_ports_mem; unsigned int gpgpu_operand_collector_num_out_ports_gen; int gpgpu_num_sp_units; int gpgpu_num_sfu_units; int gpgpu_num_tensor_core_units; + int gpgpu_num_vp_core_units; int gpgpu_num_mem_units; //Shader core resources @@ -1370,6 +1408,7 @@ struct shader_core_config : public core_config unsigned max_sp_latency; unsigned max_sfu_latency; unsigned max_tensor_core_latency; + unsigned max_vp_core_latency; unsigned n_simt_cores_per_cluster; unsigned n_simt_clusters; @@ -1408,6 +1447,7 @@ struct shader_core_stats_pod { unsigned *m_num_sp_acesses; unsigned *m_num_sfu_acesses; unsigned *m_num_tensor_core_acesses; + unsigned *m_num_vp_core_acesses; unsigned *m_num_trans_acesses; unsigned *m_num_mem_acesses; unsigned *m_num_sp_committed; @@ -1415,6 +1455,7 @@ struct shader_core_stats_pod { unsigned *m_num_tlb_accesses; unsigned *m_num_sfu_committed; unsigned *m_num_tensor_core_committed; + unsigned *m_num_vp_core_committed; unsigned *m_num_mem_committed; unsigned *m_read_regfile_acesses; unsigned *m_write_regfile_acesses; @@ -1424,6 +1465,7 @@ struct shader_core_stats_pod { unsigned *m_active_sp_lanes; unsigned *m_active_sfu_lanes; unsigned *m_active_tensor_core_lanes; + unsigned *m_active_vp_core_lanes; unsigned *m_active_fu_lanes; unsigned *m_active_fu_mem_lanes; unsigned *m_n_diverge; // number of divergence occurring in this shader @@ -1496,6 +1538,7 @@ public: m_num_sp_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_sfu_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_tensor_core_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); + m_num_vp_core_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_trans_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_mem_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_sp_committed= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); @@ -1504,10 +1547,12 @@ public: m_active_sp_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_active_sfu_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_active_tensor_core_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); + m_active_vp_core_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_active_fu_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_active_fu_mem_lanes= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_sfu_committed= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_tensor_core_committed= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); + m_num_vp_core_committed= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_num_mem_committed= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_read_regfile_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); m_write_regfile_acesses= (unsigned*) calloc(config->num_shader(),sizeof(unsigned)); -- cgit v1.3 From 7a77d951e6a900d61436df12826bb677aeaee6e6 Mon Sep 17 00:00:00 2001 From: aamir Date: Sun, 9 Sep 2018 15:10:06 -0700 Subject: minor changes for generating mem transaction in timing model. NOTE NOT COMPLETED --- cuda-kernels/gpgpusim.config | 2 +- cutlass-example/gpgpusim.config | 2 +- src/abstract_hardware_model.cc | 2 +- src/abstract_hardware_model.h | 8 +++-- src/cuda-sim/cuda-sim.cc | 65 ++++++++++++++++++++++++----------------- src/cuda-sim/instructions.cc | 64 +++++++++++++++++++++++++++++----------- src/gpgpu-sim/shader.cc | 2 +- src/gpgpu-sim/shader.h | 8 +++++ 8 files changed, 104 insertions(+), 49 deletions(-) (limited to 'src/abstract_hardware_model.h') diff --git a/cuda-kernels/gpgpusim.config b/cuda-kernels/gpgpusim.config index 2510d21..3daa539 100755 --- a/cuda-kernels/gpgpusim.config +++ b/cuda-kernels/gpgpusim.config @@ -33,7 +33,7 @@ # ID_OC_SP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_SFU,OC_EX_MEM,EX_WB ## Pascal GP102 has 4 SP SIMD units and 1 SFU unit ## we need to scale the number of pipeline registers to be equal to the number of SP units --gpgpu_pipeline_widths 4,1,1,1,4,1,1,1,6 +-gpgpu_pipeline_widths 4,1,1,1,1,4,1,1,1,1,6 -gpgpu_num_sp_units 4 -gpgpu_num_sfu_units 1 # Instruction latencies and initiation intervals diff --git a/cutlass-example/gpgpusim.config b/cutlass-example/gpgpusim.config index 2510d21..3daa539 100644 --- a/cutlass-example/gpgpusim.config +++ b/cutlass-example/gpgpusim.config @@ -33,7 +33,7 @@ # ID_OC_SP,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_SFU,OC_EX_MEM,EX_WB ## Pascal GP102 has 4 SP SIMD units and 1 SFU unit ## we need to scale the number of pipeline registers to be equal to the number of SP units --gpgpu_pipeline_widths 4,1,1,1,4,1,1,1,6 +-gpgpu_pipeline_widths 4,1,1,1,1,4,1,1,1,1,6 -gpgpu_num_sp_units 4 -gpgpu_num_sfu_units 1 # Instruction latencies and initiation intervals diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index d668de7..b24a77e 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -184,7 +184,7 @@ void warp_inst_t::generate_mem_accesses() { if( empty() || op == MEMORY_BARRIER_OP || m_mem_accesses_created ) return; - if ( !((op == LOAD_OP) || (op == STORE_OP)) ) + if (!((op == LOAD_OP) || (op==TENSOR_CORE_LOAD_OP) || (op==VP_LOAD_OP) || (op == STORE_OP)||(op==TENSOR_CORE_STORE_OP)||(op==VP_STORE_OP))) return; if( m_warp_active_mask.count() == 0 ) return; // predicated off diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 781509f..9c418fa 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -81,6 +81,10 @@ enum uarch_op_t { VP_CORE_OP, ALU_SFU_OP, LOAD_OP, + VP_LOAD_OP, + TENSOR_CORE_LOAD_OP, + TENSOR_CORE_STORE_OP, + VP_STORE_OP, STORE_OP, BRANCH_OP, BARRIER_OP, @@ -801,8 +805,8 @@ public: { fprintf(fp," [inst @ pc=0x%04x] ", pc ); } - bool is_load() const { return (op == LOAD_OP || memory_op == memory_load); } - bool is_store() const { return (op == STORE_OP || memory_op == memory_store); } + bool is_load() const { return (op == LOAD_OP ||op==TENSOR_CORE_LOAD_OP||op==VP_LOAD_OP || memory_op == memory_load); } + bool is_store() const { return (op == STORE_OP ||op==TENSOR_CORE_STORE_OP||op==VP_STORE_OP || memory_op == memory_store); } unsigned get_num_operands() const {return num_operands;} unsigned get_num_regs() const {return num_regs;} void set_num_regs(unsigned num) {num_regs=num;} diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index bcf64c4..8f684e2 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -648,12 +648,12 @@ void ptx_instruction::set_opcode_and_latency() if ( has_memory_write() ) op = STORE_OP; break; case LD_OP: op = LOAD_OP; break; - case MMA_LD_OP: op = LOAD_OP; break; - case VP_LD_OP: op = LOAD_OP; break; + case MMA_LD_OP: op = TENSOR_CORE_LOAD_OP; break; + case VP_LD_OP: op = VP_LOAD_OP; break; case LDU_OP: op = LOAD_OP; break; case ST_OP: op = STORE_OP; break; - case MMA_ST_OP: op = STORE_OP; break; - case VP_ST_OP: op = STORE_OP; break; + case MMA_ST_OP: op = TENSOR_CORE_STORE_OP; break; + case VP_ST_OP: op = VP_STORE_OP; break; case BRA_OP: op = BRANCH_OP; break; case BREAKADDR_OP: op = BRANCH_OP; break; case TEX_OP: op = LOAD_OP; mem_op=TEX; break; @@ -1334,6 +1334,7 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id) skip = !pred_lookup(pI->get_pred_mod(), pred_value.pred & 0x000F); } } + int inst_opcode=pI->get_opcode(); if( skip ) { inst.set_not_active(lane_id); @@ -1346,17 +1347,21 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id) pI = pJ; } - int inst_opcode=pI->get_opcode(); + if(((inst_opcode==MMA_OP||inst_opcode==MMA_LD_OP||inst_opcode==MMA_ST_OP||inst_opcode==VP_MMA_OP||inst_opcode==VP_LD_OP||inst_opcode==VP_ST_OP))){ + if(inst.active_count()!=MAX_WARP_SIZE) + while(1); + } if(((inst_opcode!=MMA_OP)&&(inst_opcode!=MMA_LD_OP)&&(inst_opcode!=MMA_ST_OP)&&(inst_opcode!=VP_LD_OP)&&(inst_opcode!=VP_ST_OP)&&(inst_opcode!=VP_MMA_OP))||((inst_opcode==MMA_OP||inst_opcode==MMA_LD_OP||inst_opcode==MMA_ST_OP||inst_opcode==VP_MMA_OP||inst_opcode==VP_LD_OP||inst_opcode==VP_ST_OP)&&(lane_id==0))){ - switch ( inst_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; -#include "opcodes.def" -#undef OP_DEF -#undef OP_W_DEF - default: printf( "Execution error: Invalid opcode (0x%x)\n", pI->get_opcode() ); break; - }} + switch ( inst_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; + #include "opcodes.def" + #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; @@ -1398,13 +1403,17 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id) _memory_op_t insn_memory_op = no_memory_op; unsigned insn_data_size = 0; if ( (pI->has_memory_read() || pI->has_memory_write()) ) { - insn_memaddr = last_eaddr(); - insn_space = last_space(); - unsigned to_type = pI->get_type(); - insn_data_size = datatype2size(to_type); - insn_memory_op = pI->has_memory_read() ? memory_load : memory_store; - } - + //if(!((inst_opcode==MMA_LD_OP||inst_opcode==MMA_ST_OP||inst_opcode==VP_LD_OP||inst_opcode==VP_ST_OP))) + //if(!((inst_opcode==MMA_LD_OP||inst_opcode==VP_LD_OP))) + //{ + insn_memaddr = last_eaddr(); + insn_space = last_space(); + unsigned to_type = pI->get_type(); + insn_data_size = datatype2size(to_type); + insn_memory_op = pI->has_memory_read() ? memory_load : memory_store; + //} + } + if ( pI->get_opcode() == BAR_OP && pI->barrier_op() == RED_OPTION) { inst.add_callback( lane_id, last_callback().function, last_callback().instruction, this,false /*not atomic*/); } @@ -1476,12 +1485,16 @@ void ptx_thread_info::ptx_exec_inst( warp_inst_t &inst, unsigned lane_id) // "Return values" if(!skip) { - inst.space = insn_space; - inst.set_addr(lane_id, insn_memaddr); - inst.data_size = insn_data_size; // simpleAtomicIntrinsics - assert( inst.memory_op == insn_memory_op ); - } - + //if(!((inst_opcode==MMA_LD_OP||inst_opcode==MMA_ST_OP||inst_opcode==VP_LD_OP||inst_opcode==VP_ST_OP))) + //if(!((inst_opcode==MMA_LD_OP||inst_opcode==VP_LD_OP))) + //{ + inst.space = insn_space; + inst.set_addr(lane_id, insn_memaddr); + inst.data_size = insn_data_size; // simpleAtomicIntrinsics + assert( inst.memory_op == insn_memory_op ); + //} + } + } catch ( int x ) { printf("GPGPU-Sim PTX: ERROR (%d) executing intruction (%s:%u)\n", x, pI->source_file(), pI->source_line() ); printf("GPGPU-Sim PTX: '%s'\n", pI->get_source() ); diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 39b8ba5..77e8e71 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -3196,6 +3196,7 @@ void mma_st_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) unsigned wmma_type = pI->get_wmma_type(); unsigned wmma_layout = pI->get_wmma_layout(0); int stride; + _memory_op_t insn_memory_op = pI->has_memory_read() ? memory_load : memory_store; for (thrd=0; thrd < core->get_warp_size(); thrd++) { thread = core->get_thread_info()[tid+thrd]; odd=thrd%2; @@ -3224,6 +3225,7 @@ void mma_st_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) if(g_debug_instruction) printf("mma_st: thrd=%d,addr=%x, fp(size=%d), stride=%d\n",thrd,addr_reg.u32,size,src2_data.u32); addr_t new_addr = addr+thread_group_offset(thrd,wmma_type,wmma_layout,type,stride)*size/8; + addr_t push_addr; ptx_reg_t nw_v[8]; for(k=0;k<8;k++){ @@ -3235,7 +3237,10 @@ void mma_st_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) for(k=0;k<8;k++){ if(type==F32_TYPE){ - mem->write(new_addr+4*acc_float_offset(k,wmma_layout,stride),size/8,&v[k].s64,thread,pI); + //mem->write(new_addr+4*acc_float_offset(k,wmma_layout,stride),size/8,&v[k].s64,thread,pI); + push_addr=new_addr+4*acc_float_offset(k,wmma_layout,stride); + mem->write(push_addr,size/8,&v[k].s64,thread,pI); + if(g_debug_instruction){ printf("wmma:store:thread%d=%x,%x,%x,%x,%x,%x,%x,%x\n",thrd,v[0].s64,v[1].s64,v[2].s64,v[3].s64,v[4].s64,v[5].s64,v[6].s64,v[7].s64); float temp; @@ -3250,10 +3255,16 @@ void mma_st_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) } else if(type==F16_TYPE){ - if(wmma_layout==ROW) - mem->write(new_addr+k*2,size/8,&nw_v[k].s64,thread,pI); - else if(wmma_layout==COL) - mem->write(new_addr+k*2*stride,size/8,&nw_v[k].s64,thread,pI); + if(wmma_layout==ROW){ + //mem->write(new_addr+k*2,size/8,&nw_v[k].s64,thread,pI); + push_addr=new_addr+k*2; + mem->write(push_addr,size/8,&nw_v[k].s64,thread,pI); + } + else if(wmma_layout==COL){ + //mem->write(new_addr+k*2*stride,size/8,&nw_v[k].s64,thread,pI); + push_addr=new_addr+k*2*stride; + mem->write(push_addr,size/8,&nw_v[k].s64,thread,pI); + } if(g_debug_instruction) printf("wmma:store:thread%d=%x,%x,%x,%x,%x,%x,%x,%x\n",thrd,nw_v[0].s64,nw_v[1].s64,nw_v[2].s64,nw_v[3].s64,nw_v[4].s64,nw_v[5].s64,nw_v[6].s64,nw_v[7].s64); } @@ -3427,6 +3438,7 @@ void mma_ld_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) int tid = inst.warp_id_func()*core->get_warp_size(); int thrd,stride; ptx_thread_info *thread; + _memory_op_t insn_memory_op = pI->has_memory_read() ? memory_load : memory_store; for (thrd=0; thrd < core->get_warp_size(); thrd++){ thread = core->get_thread_info()[tid+thrd]; @@ -3452,13 +3464,18 @@ void mma_ld_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) printf("mma_ld: thrd=%d,addr=%x, fpsize=%d, stride=%d\n",thrd,src1_data.u32,size,src2_data.u32); addr_t new_addr = addr+thread_group_offset(thrd,wmma_type,wmma_layout,type,stride)*size/8; - + addr_t fetch_addr; if(wmma_type==LOAD_A){ for(i=0;i<16;i++){ - if(wmma_layout==ROW) - mem->read(new_addr+2*i,size/8,&data[i].s64); + if(wmma_layout==ROW){ + //mem->read(new_addr+2*i,size/8,&data[i].s64); + fetch_addr=new_addr+2*i; + mem->read(fetch_addr,size/8,&data[i].s64); + } else if(wmma_layout==COL){ - mem->read(new_addr+2*(i%4)+2*stride*4*(i/4),size/8,&data[i].s64); + //mem->read(new_addr+2*(i%4)+2*stride*4*(i/4),size/8,&data[i].s64); + fetch_addr=new_addr+2*(i%4)+2*stride*4*(i/4); + mem->read(fetch_addr,size/8,&data[i].s64); } else{ printf("mma_ld:wrong_layout_type\n"); @@ -3468,10 +3485,15 @@ void mma_ld_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) } else if(wmma_type==LOAD_B){ for(i=0;i<16;i++){ - if(wmma_layout==COL) - mem->read(new_addr+2*i,size/8,&data[i].s64); + if(wmma_layout==COL){ + //mem->read(new_addr+2*i,size/8,&data[i].s64); + fetch_addr=new_addr+2*i; + mem->read(fetch_addr,size/8,&data[i].s64); + } else if(wmma_layout==ROW){ - mem->read(new_addr+2*(i%4)+2*stride*4*(i/4),size/8,&data[i].s64); + //mem->read(new_addr+2*(i%4)+2*stride*4*(i/4),size/8,&data[i].s64); + fetch_addr=new_addr+2*(i%4)+2*stride*4*(i/4); + mem->read(fetch_addr,size/8,&data[i].s64); } else{ printf("mma_ld:wrong_layout_type\n"); @@ -3482,17 +3504,25 @@ void mma_ld_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst ) else if(wmma_type==LOAD_C){ for(i=0;i<8;i++){ if(type==F16_TYPE){ - if(wmma_layout==ROW) - mem->read(new_addr+2*i,size/8,&data[i].s64); - else if(wmma_layout==COL) - mem->read(new_addr+2*stride*i,size/8,&data[i].s64); + if(wmma_layout==ROW){ + //mem->read(new_addr+2*i,size/8,&data[i].s64); + fetch_addr=new_addr+2*i; + mem->read(fetch_addr,size/8,&data[i].s64); + } + else if(wmma_layout==COL){ + //mem->read(new_addr+2*stride*i,size/8,&data[i].s64); + fetch_addr=new_addr+2*stride*i; + mem->read(fetch_addr,size/8,&data[i].s64); + } else{ printf("mma_ld:wrong_type\n"); abort(); } } else if(type==F32_TYPE){ - mem->read(new_addr+4*acc_float_offset(i,wmma_layout,stride),size/8,&data[i].s64); + //mem->read(new_addr+4*acc_float_offset(i,wmma_layout,stride),size/8,&data[i].s64); + fetch_addr=new_addr+4*acc_float_offset(i,wmma_layout,stride); + mem->read(fetch_addr,size/8,&data[i].s64); } else{ printf("wrong type"); diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 6f11ad9..5e80fb1 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -920,7 +920,7 @@ void scheduler_unit::cycle() ready_inst = true; const active_mask_t &active_mask = m_simt_stack[warp_id]->get_active_mask(); assert( warp(warp_id).inst_in_pipeline() ); - if ( (pI->op == LOAD_OP) || (pI->op == STORE_OP) || (pI->op == MEMORY_BARRIER_OP) ) { + if ( (pI->op == LOAD_OP)||(pI->op ==TENSOR_CORE_LOAD_OP)||(pI->op ==VP_LOAD_OP)|| (pI->op == STORE_OP)|| (pI->op==TENSOR_CORE_STORE_OP) ||(pI->op==VP_STORE_OP) || (pI->op == MEMORY_BARRIER_OP) ) { if( m_mem_out->has_free() ) { m_shader->issue_warp(*m_mem_out,pI,active_mask,warp_id); issued++; diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index d292d56..d9558b0 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1116,7 +1116,11 @@ public: switch(inst.op) { case SFU_OP: return false; case LOAD_OP: return false; + case TENSOR_CORE_LOAD_OP: return false; + case VP_LOAD_OP: return false; case STORE_OP: return false; + case TENSOR_CORE_STORE_OP: return false; + case VP_STORE_OP: return false; case MEMORY_BARRIER_OP: return false; default: break; } @@ -1158,7 +1162,11 @@ public: { switch(inst.op) { case LOAD_OP: break; + case TENSOR_CORE_LOAD_OP: break; + case VP_LOAD_OP: break; case STORE_OP: break; + case TENSOR_CORE_STORE_OP: break; + case VP_STORE_OP: break; case MEMORY_BARRIER_OP: break; default: return false; } -- cgit v1.3 From 3949357047a621a06b2e7fb4fd6099cce1469d27 Mon Sep 17 00:00:00 2001 From: aamir Date: Sun, 16 Sep 2018 20:07:33 -0700 Subject: print for mem transaction --- src/abstract_hardware_model.cc | 1 + src/abstract_hardware_model.h | 13 ++++++++++++- src/cuda-sim/instructions.cc | 15 ++++++++++++++- src/gpgpu-sim/shader.cc | 6 +++++- src/gpgpu-sim/traffic_breakdown.cc | 1 + 5 files changed, 33 insertions(+), 3 deletions(-) (limited to 'src/abstract_hardware_model.h') diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index 83e76fe..72ece0b 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -352,6 +352,7 @@ void warp_inst_t::generate_mem_accesses() ptx_file_line_stats_add_uncoalesced_gmem( pc, m_accessq.size() - starting_queue_size ); } m_mem_accesses_created=true; + print_m_accessq(); } void warp_inst_t::memory_coalescing_arch_13( bool is_write, mem_access_type access_type ) diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index 9c418fa..d628745 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -933,7 +933,18 @@ public: for(unsigned i=0; i::iterator it; + for (it = m_accessq.begin(); it != m_accessq.end(); ++it){ + printf("MEM_TXN_GEN:%s:%x, Size:%d \n",mem_access_type_str(it->get_type()), it->get_addr(),it->get_size()); + } + } + } struct transaction_info { std::bitset<4> chunks; // bitmask: 32-byte chunks accessed mem_access_byte_mask_t bytes; diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 42c63ca..52d89f2 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -3354,31 +3354,41 @@ void vp_ld_impl(const ptx_instruction *pI, core_t *core, warp_inst_t &inst) printf("vp_ld: thrx=%d,addr=%x, base_addr=%x, size=%d, stride=%d\n",thrd,new_addr,addr,size,src2_data.u32); if(wmma_type==LOAD_A||wmma_type==LOAD_C){ + printf("lda/c:"); for(i=0;i<8;i++){ if(wmma_layout==ROW){ //mem->read(new_addr+4*i,size/8,&data[i].s64); mem->read(new_addr+4*i,size/8,&data[i].s64); + printf("%x ", new_addr+4*i); mem_txn_addr[num_mem_txn++]=new_addr+4*i; } else if(wmma_layout==COL){ //mem->read(new_addr+4*stride*i,size/8,&data[i].s64); + printf("%x ", new_addr+4*stride*i); mem->read(new_addr+4*stride*i,size/8,&data[i].s64); mem_txn_addr[num_mem_txn++]=new_addr+4*stride*i; } } + } + else if(wmma_type==LOAD_B4){ + printf("ldb4:"); if(wmma_layout==ROW){ mem->read(new_addr,size/8,&data[0].s64); + printf("%x ",new_addr); mem_txn_addr[num_mem_txn++]=new_addr; } else if(wmma_layout==COL){ } } else if(wmma_type==LOAD_B8){ + printf("ldb8:"); if(wmma_layout==ROW){ mem->read(new_addr,size/8,&data[0].s64); mem->read(new_addr+4,size/8,&data[1].s64); + printf("%x ",new_addr,new_addr+4); + mem_txn_addr[num_mem_txn++]=new_addr; mem_txn_addr[num_mem_txn++]=new_addr+4; } @@ -3387,12 +3397,13 @@ void vp_ld_impl(const ptx_instruction *pI, core_t *core, warp_inst_t &inst) } } else if(wmma_type==LOAD_B16){ - printf("LOADB16_MODE"); + printf("ldb16:"); if(wmma_layout==ROW){ mem->read(new_addr,size/8,&data[0].s64); mem->read(new_addr+4,size/8,&data[1].s64); mem->read(new_addr+8,size/8,&data[2].s64); mem->read(new_addr+12,size/8,&data[3].s64); + printf("%x ",new_addr,new_addr+4,new_addr+8,new_addr+12); mem_txn_addr[num_mem_txn++]=new_addr; mem_txn_addr[num_mem_txn++]=new_addr+4; mem_txn_addr[num_mem_txn++]=new_addr+8; @@ -3405,6 +3416,8 @@ void vp_ld_impl(const ptx_instruction *pI, core_t *core, warp_inst_t &inst) printf("wrong vp_load type\n");; abort(); } + printf("\n"); + //generate timing memory request inst.space = space; inst.set_addr(thrd, (new_addr_type *)mem_txn_addr , num_mem_txn); diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index 5e80fb1..e745f03 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -741,7 +741,10 @@ void shader_core_ctx::func_exec_inst( warp_inst_t &inst ) { execute_warp_inst_t(inst); if( inst.is_load() || inst.is_store() ) - inst.generate_mem_accesses(); + { + inst.generate_mem_accesses(); + //inst.print_m_accessq(); + } } void shader_core_ctx::issue_warp( register_set& pipe_reg_set, const warp_inst_t* next_inst, const active_mask_t &active_mask, unsigned warp_id ) @@ -1512,6 +1515,7 @@ bool ldst_unit::memory_cycle( warp_inst_t &inst, mem_stage_stall_type &stall_rea // bypass L1 cache unsigned control_size = inst.is_store() ? WRITE_PACKET_SIZE : READ_PACKET_SIZE; unsigned size = access.get_size() + control_size; + //printf("Interconnect:Addr: %x, size=%d\n",access.get_addr(),size); if( m_icnt->full(size, inst.is_store() || inst.isatomic()) ) { stall_cond = ICNT_RC_FAIL; } else { diff --git a/src/gpgpu-sim/traffic_breakdown.cc b/src/gpgpu-sim/traffic_breakdown.cc index 32f0d30..587067f 100644 --- a/src/gpgpu-sim/traffic_breakdown.cc +++ b/src/gpgpu-sim/traffic_breakdown.cc @@ -46,6 +46,7 @@ std::string traffic_breakdown::classify_memfetch(class mem_fetch * mf) break; default: assert(0 && "Unknown traffic type"); } + printf("%s:Icnt:%s:Request: %x,Size%d,DataSize:%d,CntrlSize%d:\n",m_network_name.c_str(),traffic_name.c_str(),mf->get_addr(),mf->size(),mf->get_data_size(),mf->get_ctrl_size()); return traffic_name; } -- cgit v1.3