diff options
Diffstat (limited to 'src/abstract_hardware_model.cc')
| -rw-r--r-- | src/abstract_hardware_model.cc | 224 |
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 ) |
