summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim')
-rw-r--r--src/gpgpu-sim/gpu-sim.cc16
-rw-r--r--src/gpgpu-sim/scoreboard.cc40
-rw-r--r--src/gpgpu-sim/shader.cc70
-rw-r--r--src/gpgpu-sim/shader.h47
4 files changed, 153 insertions, 20 deletions
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<shd_warp_t>* 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<shd_warp_t>* 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<shd_warp_t>* 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<shd_warp_t>* 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<shd_warp_t>* 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<shd_warp_t>* 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<shd_warp_t>* 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));