summaryrefslogtreecommitdiff
path: root/src/abstract_hardware_model.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/abstract_hardware_model.cc')
-rw-r--r--src/abstract_hardware_model.cc224
1 files changed, 215 insertions, 9 deletions
diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc
index d2a155c..023f51b 100644
--- a/src/abstract_hardware_model.cc
+++ b/src/abstract_hardware_model.cc
@@ -35,10 +35,68 @@
#include "gpgpu-sim/gpu-sim.h"
#include "option_parser.h"
#include <algorithm>
+#include <sys/stat.h>
+#include <sstream>
+#include <iostream>
unsigned mem_access_t::sm_next_access_uid = 0;
unsigned warp_inst_t::sm_next_uid = 0;
+checkpoint::checkpoint()
+{
+
+ struct stat st = {0};
+
+ if (stat("checkpoint_files", &st) == -1) {
+ mkdir("checkpoint_files", 0777);
+ }
+
+}
+void checkpoint::load_global_mem(class memory_space *temp_mem, char * f1name)
+{
+
+ FILE * fp2 = fopen(f1name, "r");
+ assert(fp2!=NULL);
+ char line [ 128 ]; /* or other suitable maximum line size */
+ unsigned int offset ;
+ while ( fgets ( line, sizeof line, fp2 ) != NULL ) /* read a line */
+ {
+ unsigned int index;
+ char * pch;
+ pch = strtok (line," ");
+ if (pch[0]=='g' || pch[0]=='s' || pch[0]=='l')
+ {
+
+ pch = strtok (NULL, " ");
+
+ std::stringstream ss;
+ ss << std::hex << pch;
+ ss >> index;
+
+ offset=0;
+ }
+ else {
+ unsigned int data;
+ std::stringstream ss;
+ ss << std::hex << pch;
+ ss >> data;
+ temp_mem->write_only(offset,index, 4,&data);
+ offset= offset+4;
+ }
+ //fputs ( line, stdout ); /* write the line */
+ }
+ fclose ( fp2 );
+}
+
+void checkpoint::store_global_mem(class memory_space * mem, char *fname, char * format)
+{
+
+ FILE * fp3 = fopen(fname, "w");
+ assert(fp3!=NULL);
+ mem->print(format,fp3);
+ fclose(fp3);
+}
+
void move_warp( warp_inst_t *&dst, warp_inst_t *&src )
{
assert( dst->empty() );
@@ -64,6 +122,31 @@ void gpgpu_functional_sim_config::reg_options(class OptionParser * opp)
&m_experimental_lib_support,
"Try to extract code from cuda libraries [Broken because of unknown cudaGetExportTable]",
"0");
+ option_parser_register(opp, "-checkpoint_option", OPT_INT32, &checkpoint_option,
+ " checkpointing flag (0 = no checkpoint)",
+ "0");
+ option_parser_register(opp, "-checkpoint_kernel", OPT_INT32, &checkpoint_kernel,
+ " checkpointing during execution of which kernel (1- 1st kernel)",
+ "1");
+ option_parser_register(opp, "-checkpoint_CTA", OPT_INT32, &checkpoint_CTA,
+ " checkpointing after # of CTA (< less than total CTA)",
+ "0");
+ option_parser_register(opp, "-resume_option", OPT_INT32, &resume_option,
+ " resume flag (0 = no resume)",
+ "0");
+ option_parser_register(opp, "-resume_kernel", OPT_INT32, &resume_kernel,
+ " Resume from which kernel (1= 1st kernel)",
+ "0");
+ option_parser_register(opp, "-resume_CTA", OPT_INT32, &resume_CTA,
+ " resume from which CTA ",
+ "0");
+ option_parser_register(opp, "-checkpoint_CTA_t", OPT_INT32, &checkpoint_CTA_t,
+ " resume from which CTA ",
+ "0");
+ option_parser_register(opp, "-checkpoint_insn_Y", OPT_INT32, &checkpoint_insn_Y,
+ " resume from which CTA ",
+ "0");
+
option_parser_register(opp, "-gpgpu_ptx_convert_to_ptxplus", OPT_BOOL,
&m_ptx_convert_to_ptxplus,
"Convert SASS (native ISA) to ptxplus and run ptxplus",
@@ -93,10 +176,25 @@ gpgpu_t::gpgpu_t( const gpgpu_functional_sim_config &config )
: m_function_model_config(config)
{
m_global_mem = new memory_space_impl<8192>("global",64*1024);
+
m_tex_mem = new memory_space_impl<8192>("tex",64*1024);
m_surf_mem = new memory_space_impl<8192>("surf",64*1024);
m_dev_malloc=GLOBAL_HEAP_START;
+ checkpoint_option = m_function_model_config.get_checkpoint_option();
+ checkpoint_kernel = m_function_model_config.get_checkpoint_kernel();
+ checkpoint_CTA = m_function_model_config.get_checkpoint_CTA();
+ resume_option = m_function_model_config.get_resume_option();
+ resume_kernel = m_function_model_config.get_resume_kernel();
+ resume_CTA = m_function_model_config.get_resume_CTA();
+ checkpoint_CTA_t = m_function_model_config.get_checkpoint_CTA_t();
+ checkpoint_insn_Y = m_function_model_config.get_checkpoint_insn_Y();
+
+ // initialize texture mappings to empty
+ m_NameToTextureInfo.clear();
+ m_NameToCudaArray.clear();
+ m_TextureRefToName.clear();
+ m_NameToAttribute.clear();
if(m_function_model_config.get_ptx_inst_debug_to_file() != 0)
ptx_inst_debug_file = fopen(m_function_model_config.get_ptx_inst_debug_file(), "w");
@@ -184,7 +282,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 == STORE_OP)||(op==TENSOR_CORE_STORE_OP)))
return;
if( m_warp_active_mask.count() == 0 )
return; // predicated off
@@ -213,6 +311,7 @@ void warp_inst_t::generate_mem_accesses()
access_type = is_write? LOCAL_ACC_W: LOCAL_ACC_R;
break;
case shared_space: break;
+ case sstarr_space: break;
default: assert(0); break;
}
@@ -220,7 +319,8 @@ void warp_inst_t::generate_mem_accesses()
new_addr_type cache_block_size = 0; // in bytes
switch( space.get_type() ) {
- case shared_space: {
+ case shared_space:
+ case sstarr_space: {
unsigned subwarp_size = m_config->warp_size / m_config->mem_warp_parts;
unsigned total_accesses=0;
for( unsigned subwarp=0; subwarp < m_config->mem_warp_parts; subwarp++ ) {
@@ -314,7 +414,7 @@ void warp_inst_t::generate_mem_accesses()
break;
case global_space: case local_space: case param_space_local:
- if( m_config->gpgpu_coalesce_arch >= 13 && m_config->gpgpu_coalesce_arch <= 62) {
+ if( m_config->gpgpu_coalesce_arch >= 13) {
if(isatomic())
memory_coalescing_arch_atomic(is_write, access_type);
else
@@ -369,7 +469,7 @@ void warp_inst_t::memory_coalescing_arch( bool is_write, mem_access_type access_
}
else if(m_config->gpgpu_coalesce_arch >= 40)
{
- //Maxwell and Pascal, L1 and L2 are sectors
+ //Maxwell, Pascal and Volta, L1 and L2 are sectors
//all requests should be 32 bytes
sector_segment_size = true;
}
@@ -404,7 +504,8 @@ void warp_inst_t::memory_coalescing_arch( bool is_write, mem_access_type access_
assert(num_accesses <= MAX_ACCESSES_PER_INSN_PER_THREAD);
- for(unsigned access=0; access<num_accesses; access++) {
+// for(unsigned access=0; access<num_accesses; access++) {
+ for(unsigned access=0; (access<MAX_ACCESSES_PER_INSN_PER_THREAD)&&(m_per_scalar_thread[thread].memreqaddr[access]!=0); access++) {
new_addr_type addr = m_per_scalar_thread[thread].memreqaddr[access];
unsigned block_address = line_size_based_tag_func(addr,segment_size);
unsigned chunk = (addr&127)/32; // which 32-byte chunk within in a 128-byte chunk does this thread access?
@@ -440,11 +541,28 @@ void warp_inst_t::memory_coalescing_arch_atomic( bool is_write, mem_access_type
// see the CUDA manual where it discusses coalescing rules before reading this
unsigned segment_size = 0;
- unsigned warp_parts = 2;
+ unsigned warp_parts = m_config->mem_warp_parts;
+ bool sector_segment_size = false;
+
+ if(m_config->gpgpu_coalesce_arch >= 20 && m_config->gpgpu_coalesce_arch < 39)
+ {
+ //Fermi and Kepler, L1 is normal and L2 is sector
+ if(m_config->gmem_skip_L1D || cache_op == CACHE_GLOBAL)
+ sector_segment_size = true;
+ else
+ sector_segment_size = false;
+ }
+ else if(m_config->gpgpu_coalesce_arch >= 40)
+ {
+ //Maxwell, Pascal and Volta, L1 and L2 are sectors
+ //all requests should be 32 bytes
+ sector_segment_size = true;
+ }
+
switch( data_size ) {
case 1: segment_size = 32; break;
- case 2: segment_size = 64; break;
- case 4: case 8: case 16: segment_size = 128; break;
+ case 2: segment_size = sector_segment_size? 32 : 64; break;
+ case 4: case 8: case 16: segment_size = sector_segment_size? 32 : 128; break;
}
unsigned subwarp_size = m_config->warp_size / warp_parts;
@@ -573,7 +691,32 @@ unsigned g_kernel_launch_latency;
unsigned kernel_info_t::m_next_uid = 1;
-kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *entry )
+kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *entry)
+{
+ m_kernel_entry=entry;
+ m_grid_dim=gridDim;
+ m_block_dim=blockDim;
+ m_next_cta.x=0;
+ m_next_cta.y=0;
+ m_next_cta.z=0;
+ m_next_tid=m_next_cta;
+ m_num_cores_running=0;
+ m_uid = m_next_uid++;
+ m_param_mem = new memory_space_impl<8192>("param",64*1024);
+
+ //Jin: parent and child kernel management for CDP
+ m_parent_kernel = NULL;
+
+ //Jin: launch latency management
+ m_launch_latency = g_kernel_launch_latency;
+
+ volta_cache_config_set=false;
+}
+
+/*A snapshot of the texture mappings needs to be stored in the kernel's info as
+kernels should use the texture bindings seen at the time of launch and textures
+ can be bound/unbound asynchronously with respect to streams. */
+kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *entry, std::map<std::string, const struct cudaArray*> nameToCudaArray, std::map<std::string, const struct textureInfo*> nameToTextureInfo)
{
m_kernel_entry=entry;
m_grid_dim=gridDim;
@@ -591,6 +734,10 @@ kernel_info_t::kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *
//Jin: launch latency management
m_launch_latency = g_kernel_launch_latency;
+
+ volta_cache_config_set=false;
+ m_NameToCudaArray = nameToCudaArray;
+ m_NameToTextureInfo = nameToTextureInfo;
}
kernel_info_t::~kernel_info_t()
@@ -728,6 +875,51 @@ void simt_stack::launch( address_type start_pc, const simt_mask_t &active_mask )
m_stack.push_back(new_stack_entry);
}
+void simt_stack::resume( char * fname )
+{
+ reset();
+
+
+
+ FILE * fp2 = fopen(fname, "r");
+ assert(fp2!=NULL);
+
+ char line [ 200 ]; /* or other suitable maximum line size */
+
+ while ( fgets ( line, sizeof line, fp2 ) != NULL ) /* read a line */
+ {
+ simt_stack_entry new_stack_entry;
+ char * pch;
+ pch = strtok (line," ");
+ for (unsigned j=0; j<m_warp_size; j++)
+ {
+ if (pch[0]=='1')
+ new_stack_entry.m_active_mask.set(j);
+ else
+ new_stack_entry.m_active_mask.reset(j);
+ pch = strtok (NULL," ");
+
+ }
+
+ new_stack_entry.m_pc=atoi(pch);
+ pch = strtok (NULL," ");
+ new_stack_entry.m_calldepth=atoi(pch);
+ pch = strtok (NULL," ");
+ new_stack_entry.m_recvg_pc=atoi(pch);
+ pch = strtok (NULL," ");
+ new_stack_entry.m_branch_div_cycle=atoi(pch);
+ pch = strtok (NULL," ");
+ if(pch[0]=='0')
+ new_stack_entry.m_type= STACK_ENTRY_TYPE_NORMAL;
+ else
+ new_stack_entry.m_type= STACK_ENTRY_TYPE_CALL;
+ m_stack.push_back(new_stack_entry);
+ }
+ fclose ( fp2 );
+
+
+}
+
const simt_mask_t &simt_stack::get_active_mask() const
{
assert(m_stack.size() > 0);
@@ -772,6 +964,20 @@ void simt_stack::print (FILE *fout) const
ptx_print_insn( stack_entry.m_pc, fout );
fprintf(fout,"\n");
}
+
+}
+
+void simt_stack::print_checkpoint (FILE *fout) const
+{
+ for ( unsigned k=0; k < m_stack.size(); k++ ) {
+ simt_stack_entry stack_entry = m_stack[k];
+
+ for (unsigned j=0; j<m_warp_size; j++)
+ fprintf(fout, "%c ", (stack_entry.m_active_mask.test(j)?'1':'0') );
+ fprintf(fout, "%d %d %d %lld %d ", stack_entry.m_pc,stack_entry.m_calldepth,stack_entry.m_recvg_pc,stack_entry.m_branch_div_cycle,stack_entry.m_type );
+ fprintf(fout, "%d %d\n",m_warp_id, m_warp_size );
+
+ }
}
void simt_stack::update( simt_mask_t &thread_done, addr_vector_t &next_pc, address_type recvg_pc, op_type next_inst_op,unsigned next_inst_size, address_type next_inst_pc )