From 26b9853cc1f6a3b17de0e319b40f28a5703ad6bf Mon Sep 17 00:00:00 2001 From: Amruth Date: Sun, 25 Mar 2018 16:01:22 -0700 Subject: code for removing duplicates in embedded ptx --- src/cuda-sim/ptx_loader.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cuda-sim/ptx_loader.h') diff --git a/src/cuda-sim/ptx_loader.h b/src/cuda-sim/ptx_loader.h index d3d0c92..a8ecda3 100644 --- a/src/cuda-sim/ptx_loader.h +++ b/src/cuda-sim/ptx_loader.h @@ -30,6 +30,7 @@ #include extern bool g_override_embedded_ptx; +extern int no_of_ptx; //counter to track number of ptx files to be extracted in an application. class symbol_table *gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source_num ); void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num, unsigned sm_version=20 ); -- cgit v1.3 From 2278609c8e279e7dfba49211256e818e3152318b Mon Sep 17 00:00:00 2001 From: Jonathan Date: Fri, 1 Jun 2018 13:04:30 -0700 Subject: WIP attempting to parse ptx files in order --- libcuda/cuda_runtime_api.cc | 257 +++++++++++++++++++++++++------------------- src/cuda-sim/ptx_loader.cc | 20 ++++ src/cuda-sim/ptx_loader.h | 1 + 3 files changed, 168 insertions(+), 110 deletions(-) (limited to 'src/cuda-sim/ptx_loader.h') diff --git a/libcuda/cuda_runtime_api.cc b/libcuda/cuda_runtime_api.cc index dc92522..ece958e 100644 --- a/libcuda/cuda_runtime_api.cc +++ b/libcuda/cuda_runtime_api.cc @@ -112,6 +112,7 @@ #include #include #include +#include #ifdef OPENGL_SUPPORT #define GL_GLEXT_PROTOTYPES #ifdef __APPLE__ @@ -148,6 +149,10 @@ std::map pinned_memory; //support for pinned memories added std::map pinned_memory_size; int no_of_ptx=0; +char ptx_list_file_name[1024]; +std::map fatbinmap; +std::mapfatbin_registered; +std::map name_symtab; extern void synchronize(); extern void exit_simulation(); @@ -1500,6 +1505,145 @@ char* get_app_binary_name(std::string abs_path){ return self_exe_path; } +//extracts all ptx files from binary and dumps into prog_name.unique_no.sm_<>.ptx files +void extract_ptx_files_using_cuobjdump(bool g_cdp_enabled){ + char command[1000]; + std::string app_binary = get_app_binary(); + + snprintf(ptx_list_file_name,1024,"_cuobjdump_list_ptx_XXXXXX"); + int fd2=mkstemp(ptx_list_file_name); + close(fd2); + //only want file names + snprintf(command,1000,"$CUDA_INSTALL_PATH/bin/cuobjdump -lptx %s | cut -d \":\" -f 2 | awk '{$1=$1}1' > %s", app_binary.c_str(), ptx_list_file_name); + if( system(command) != 0 ) { + printf("WARNING: Failed to execute cuobjdump to get list of ptx files \n"); + exit(0); + } + if(!g_cdp_enabled) { + //based on the list above, dump ptx files individually. Format of dumped ptx file is prog_name.unique_no.sm_<>.ptx + + std::ifstream infile(ptx_list_file_name); + std::string line; + while (std::getline(infile, line)) + { + //int pos = line.find(std::string(get_app_binary_name(app_binary))); + const char *ptx_file = line.c_str(); + printf("Extracting specific PTX file named %s \n",ptx_file); + snprintf(command,1000,"$CUDA_INSTALL_PATH/bin/cuobjdump -xptx %s %s", ptx_file, app_binary.c_str()); + if (system(command)!=0) { + printf("ERROR: command: %s failed \n",command); + exit(0); + } + no_of_ptx++; + } + } + + if(!no_of_ptx){ + printf("WARNING: Number of ptx in the executable file are 0. One of the reasons might be\n"); + printf("\t1. CDP is enabled\n"); + } +} + +void cuobjdumpParseBinary(unsigned int handle){ + + + if(fatbin_registered[handle]) return; + fatbin_registered[handle] = true; + CUctx_st *context = GPGPUSim_Context(); + std::string fname = fatbinmap[handle]; + + if (name_symtab.find(fname) != name_symtab.end()) { + symbol_table *symtab = name_symtab[fname]; + context->add_binary(symtab, handle); + return; + } + + std::map > version_filename; + + std::ifstream infile(ptx_list_file_name); + std::string line; + while (std::getline(infile, line)) + { + //int pos = line.find(std::string(get_app_binary_name(app_binary))); + const char *ptx_file = line.c_str(); + int pos1 = line.find("sm_"); + int pos2 = line.find_last_of("."); + if (pos1==std::string::npos&&pos2==std::string::npos){ + printf("ERROR: PTX list is not in correct format"); + exit(0); + } + std::string vstr = line.substr(pos1+3,pos2-pos1-3); + int version = atoi(vstr.c_str()); + if (version_filename.find(version)==version_filename.end()){ + version_filename[version] = std::set(); + } + version_filename[version].insert(line); + } + + symbol_table *symtab; + //loops through all ptx files from smallest sm version to largest + std::map >::iterator itr_m; + for (itr_m = version_filename.begin(); itr_m!=version_filename.end(); itr_m++){ + std::set::iterator itr_s; + for (itr_s = itr_m->second.begin(); itr_s!=itr_m->second.end(); itr_s++){ + std::string ptx_filename = *itr_s; + printf("GPGPU-Sim PTX: Parsing %s\n",ptx_filename.c_str()); + symtab = gpgpu_ptx_sim_load_ptx_from_filename( ptx_filename.c_str() ); + } + } + name_symtab[fname] = symtab; + context->add_binary(symtab, handle); + + +// unsigned max_capability = 0; +// for ( std::list::iterator iter = cuobjdumpSectionList.begin(); +// iter != cuobjdumpSectionList.end(); +// iter++){ +// unsigned capability = (*iter)->getArch(); +// if (capability > max_capability) max_capability = capability; +// } +// if (max_capability > 20) printf("WARNING: No guarantee that PTX will be parsed for SM version %u\n", max_capability); +// if (max_capability == 0) max_capability=context->get_device()->get_gpgpu()->get_config().get_forced_max_capability(); +// +// cuobjdumpPTXSection* ptx = NULL; +// const char* pre_load = getenv("CUOBJDUMP_SIM_FILE"); +// if(pre_load==NULL || strlen(pre_load)==0) +// ptx = findPTXSection(fname); +// symbol_table *symtab; +// char *ptxcode; +// const char *override_ptx_name = getenv("PTX_SIM_KERNELFILE"); +// if (override_ptx_name == NULL or getenv("PTX_SIM_USE_PTX_FILE") == NULL or strlen(getenv("PTX_SIM_USE_PTX_FILE"))==0) { +// ptxcode = readfile(ptx->getPTXfilename()); +// } else { +// printf("GPGPU-Sim PTX: overriding embedded ptx with '%s' (PTX_SIM_USE_PTX_FILE is set)\n", override_ptx_name); +// ptxcode = readfile(override_ptx_name); +// } +// if(context->get_device()->get_gpgpu()->get_config().convert_to_ptxplus() ) { +// cuobjdumpELFSection* elfsection = findELFSection(ptx->getIdentifier()); +// assert (elfsection!= NULL); +// char *ptxplus_str = gpgpu_ptx_sim_convert_ptx_and_sass_to_ptxplus( +// ptx->getPTXfilename(), +// elfsection->getELFfilename(), +// elfsection->getSASSfilename()); +// symtab=gpgpu_ptx_sim_load_ptx_from_string(ptxplus_str, handle); +// printf("Adding %s with cubin handle %u\n", ptx->getPTXfilename().c_str(), handle); +// context->add_binary(symtab, handle); +// gpgpu_ptxinfo_load_from_string( ptxcode, handle, max_capability ); +// delete[] ptxplus_str; +// } else { +// symtab=gpgpu_ptx_sim_load_ptx_from_string(ptxcode, handle); +// //if CUOBJDUMP_SIM_FILE is not set, ptx is NULL. So comment below. +// //printf("Adding %s with cubin handle %u\n", ptx->getPTXfilename().c_str(), handle); +// context->add_binary(symtab, handle); +// gpgpu_ptxinfo_load_from_string( ptxcode, handle, max_capability ); +// } + load_static_globals(symtab,STATIC_ALLOC_LIMIT,0xFFFFFFFF,context->get_device()->get_gpgpu()); + load_constants(symtab,STATIC_ALLOC_LIMIT,context->get_device()->get_gpgpu()); +// name_symtab[fname] = symtab; + + //TODO: Remove temporarily files as per configurations +} + //! Call cuobjdump to extract everything (-elf -sass -ptx) /*! * This Function extract the whole PTX (for all the files) using cuobjdump @@ -1514,7 +1658,7 @@ void extract_code_using_cuobjdump(){ //prevent the dumping by cuobjdump everytime we execute the code! const char *override_cuobjdump = getenv("CUOBJDUMP_SIM_FILE"); - char command[1000], ptx_file[1000]; + char command[1000]; std::string app_binary = get_app_binary(); //Running cuobjdump using dynamic link to current process snprintf(command,1000,"md5sum %s ", app_binary.c_str()); @@ -1527,50 +1671,8 @@ void extract_code_using_cuobjdump(){ //dump ptx for all individial ptx files into sepearte files which is later used by ptxas. int result=0; #if (CUDART_VERSION >= 6000) - char fname2[1024]; - snprintf(fname2,1024,"_cuobjdump_list_ptx_XXXXXX"); - int fd2=mkstemp(fname2); - close(fd2); - snprintf(command,1000,"$CUDA_INSTALL_PATH/bin/cuobjdump -lptx -arch=sm_%u %s > %s", forced_max_capability, app_binary.c_str(), fname2); - result = system(command); - if( result != 0 ) { - printf("WARNING: Failed to execute cuobjdump to get list of ptx files \n"); - exit(0); - } else { - /* - as we got list of ptx files, we need to extract one by one into seperate files so that ptxas can understand it. - In this way, the duplicate definitions in a single embedded file can be prevented. - No of lines in the file is equal to no of ptx fileis available. - */ - FILE *fp = fopen(fname2,"r"); - if (fp==NULL) { - printf("WARNING: cuobjdump file error! Could not open file %s \n", fname2); - exit(0); - } else { - for (char c = getc(fp); c != EOF; c = getc(fp)) - if (c == '\n') - no_of_ptx = no_of_ptx + 1; - fclose(fp); - } - if(no_of_ptx==0){ - printf("WARNING: Number of ptx in the executable file are 0. One of the reasons might be\n"); - printf("\t1. CDP is enabled\n"); - printf("\t2. cuobjdump -lptx doesnt recognize sm_%u\n",forced_max_capability); - printf("\t3. the application was not compiled with nvcc flag sm_%u\n",forced_max_capability); - } - } - if(!g_cdp_enabled) { - //based on the list above, dump ptx files individually. Format of dumped ptx file is prog_name.unique_no.sm_<>.ptx - for (int index=1; index<= no_of_ptx; index++){ - snprintf(ptx_file, 1000, "%s.%d.sm_%u.ptx", get_app_binary_name(app_binary), index, forced_max_capability); - printf("Extracting specific PTX file named %s \n",ptx_file); - snprintf(command,1000,"$CUDA_INSTALL_PATH/bin/cuobjdump -arch=sm_%u -xptx %s %s", forced_max_capability, ptx_file, app_binary.c_str()); - if (system(command)!=0) { - printf("ERROR: command: %s failed \n",command); - exit(0); - } - } - } + extract_ptx_files_using_cuobjdump(g_cdp_enabled); + cuobjdumpParseBinary(1); #endif //TODO: redundant to dump twice. how can it be prevented? //dump only for specific arch @@ -1904,77 +2006,12 @@ void cuobjdumpInit(){ } } -std::map fatbinmap; -std::mapfatbin_registered; -std::map name_symtab; //! Keep track of the association between filename and cubin handle void cuobjdumpRegisterFatBinary(unsigned int handle, const char* filename){ fatbinmap[handle] = filename; } -//! Either submit PTX for simulation or convert SASS to PTXPlus and submit it -void cuobjdumpParseBinary(unsigned int handle){ - - if(fatbin_registered[handle]) return; - fatbin_registered[handle] = true; - CUctx_st *context = GPGPUSim_Context(); - std::string fname = fatbinmap[handle]; - - if (name_symtab.find(fname) != name_symtab.end()) { - symbol_table *symtab = name_symtab[fname]; - context->add_binary(symtab, handle); - return; - } - - unsigned max_capability = 0; - for ( std::list::iterator iter = cuobjdumpSectionList.begin(); - iter != cuobjdumpSectionList.end(); - iter++){ - unsigned capability = (*iter)->getArch(); - if (capability > max_capability) max_capability = capability; - } - if (max_capability > 20) printf("WARNING: No guarantee that PTX will be parsed for SM version %u\n", max_capability); - if (max_capability == 0) max_capability=context->get_device()->get_gpgpu()->get_config().get_forced_max_capability(); - - cuobjdumpPTXSection* ptx = NULL; - const char* pre_load = getenv("CUOBJDUMP_SIM_FILE"); - if(pre_load==NULL || strlen(pre_load)==0) - ptx = findPTXSection(fname); - symbol_table *symtab; - char *ptxcode; - const char *override_ptx_name = getenv("PTX_SIM_KERNELFILE"); - if (override_ptx_name == NULL or getenv("PTX_SIM_USE_PTX_FILE") == NULL or strlen(getenv("PTX_SIM_USE_PTX_FILE"))==0) { - ptxcode = readfile(ptx->getPTXfilename()); - } else { - printf("GPGPU-Sim PTX: overriding embedded ptx with '%s' (PTX_SIM_USE_PTX_FILE is set)\n", override_ptx_name); - ptxcode = readfile(override_ptx_name); - } - if(context->get_device()->get_gpgpu()->get_config().convert_to_ptxplus() ) { - cuobjdumpELFSection* elfsection = findELFSection(ptx->getIdentifier()); - assert (elfsection!= NULL); - char *ptxplus_str = gpgpu_ptx_sim_convert_ptx_and_sass_to_ptxplus( - ptx->getPTXfilename(), - elfsection->getELFfilename(), - elfsection->getSASSfilename()); - symtab=gpgpu_ptx_sim_load_ptx_from_string(ptxplus_str, handle); - printf("Adding %s with cubin handle %u\n", ptx->getPTXfilename().c_str(), handle); - context->add_binary(symtab, handle); - gpgpu_ptxinfo_load_from_string( ptxcode, handle, max_capability ); - delete[] ptxplus_str; - } else { - symtab=gpgpu_ptx_sim_load_ptx_from_string(ptxcode, handle); - //if CUOBJDUMP_SIM_FILE is not set, ptx is NULL. So comment below. - //printf("Adding %s with cubin handle %u\n", ptx->getPTXfilename().c_str(), handle); - context->add_binary(symtab, handle); - gpgpu_ptxinfo_load_from_string( ptxcode, handle, max_capability ); - } - load_static_globals(symtab,STATIC_ALLOC_LIMIT,0xFFFFFFFF,context->get_device()->get_gpgpu()); - load_constants(symtab,STATIC_ALLOC_LIMIT,context->get_device()->get_gpgpu()); - name_symtab[fname] = symtab; - - //TODO: Remove temporarily files as per configurations -} void** CUDARTAPI __cudaRegisterFatBinary( void *fatCubin ) { diff --git a/src/cuda-sim/ptx_loader.cc b/src/cuda-sim/ptx_loader.cc index 33a4260..8deafc6 100644 --- a/src/cuda-sim/ptx_loader.cc +++ b/src/cuda-sim/ptx_loader.cc @@ -185,6 +185,26 @@ symbol_table *gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source return symtab; } +symbol_table *gpgpu_ptx_sim_load_ptx_from_filename( const char *filename ) +{ + symbol_table *symtab=init_parser(filename); + int errors = ptx_parse (); + if ( errors ) { + char fname[1024]; + snprintf(fname,1024,"_ptx_errors_XXXXXX"); + int fd=mkstemp(fname); + close(fd); + printf("GPGPU-Sim PTX: parser error detected, exiting... but first extracting .ptx to \"%s\"\n", fname); + FILE *ptxfile = fopen(fname,"w"); + fclose(ptxfile); + abort(); + exit(40); + } + + printf("GPGPU-Sim PTX: finished parsing EMBEDDED .ptx file %s\n",filename); + return symtab; +} + void fix_duplicate_errors(char fname2[1024]) { char tempfile[1024] = "_temp_ptx"; char commandline[1024]; diff --git a/src/cuda-sim/ptx_loader.h b/src/cuda-sim/ptx_loader.h index a8ecda3..c5c9dd8 100644 --- a/src/cuda-sim/ptx_loader.h +++ b/src/cuda-sim/ptx_loader.h @@ -33,6 +33,7 @@ extern bool g_override_embedded_ptx; extern int no_of_ptx; //counter to track number of ptx files to be extracted in an application. class symbol_table *gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source_num ); +class symbol_table *gpgpu_ptx_sim_load_ptx_from_filename( const char *filename ); void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num, unsigned sm_version=20 ); char* gpgpu_ptx_sim_convert_ptx_and_sass_to_ptxplus(const std::string ptx_str, const std::string sass_str, const std::string elf_str); bool keep_intermediate_files(); -- cgit v1.3 From bd9a49ef576bfbbaf2be1d163eb99b7316f7bd20 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Mon, 23 Jul 2018 14:20:14 -0700 Subject: brought back ptxinfo --- libcuda/cuda_runtime_api.cc | 19 +++++++++++++++---- src/cuda-sim/ptx_loader.cc | 23 ++++++++++++++++++++++- src/cuda-sim/ptx_loader.h | 1 + 3 files changed, 38 insertions(+), 5 deletions(-) (limited to 'src/cuda-sim/ptx_loader.h') diff --git a/libcuda/cuda_runtime_api.cc b/libcuda/cuda_runtime_api.cc index db4f58e..c87c6c3 100644 --- a/libcuda/cuda_runtime_api.cc +++ b/libcuda/cuda_runtime_api.cc @@ -152,7 +152,8 @@ std::map pinned_memory; //support for pinned memories added std::map pinned_memory_size; std::map g_mallocPtr_Size; int no_of_ptx=0; -std::map > version_filename; +//maps sm version number to set of filenames +std::map > version_filename; extern void synchronize(); extern void exit_simulation(); @@ -1718,7 +1719,8 @@ char* get_app_binary_name(std::string abs_path){ } //extracts all ptx files from binary and dumps into prog_name.unique_no.sm_<>.ptx files -void extract_ptx_files_using_cuobjdump(bool g_cdp_enabled){ +void extract_ptx_files_using_cuobjdump(){ + extern bool g_cdp_enabled; char command[1000]; std::string app_binary = get_app_binary(); @@ -1808,7 +1810,8 @@ void extract_code_using_cuobjdump(){ //dump ptx for all individial ptx files into sepearte files which is later used by ptxas. int result=0; #if (CUDART_VERSION >= 6000) - extract_ptx_files_using_cuobjdump(g_cdp_enabled); + extract_ptx_files_using_cuobjdump(); + return; #endif //TODO: redundant to dump twice. how can it be prevented? //dump only for specific arch @@ -2168,7 +2171,7 @@ void cuobjdumpParseBinary(unsigned int handle){ #if (CUDART_VERSION >= 6000) //loops through all ptx files from smallest sm version to largest - std::map >::iterator itr_m; + std::map >::iterator itr_m; for (itr_m = version_filename.begin(); itr_m!=version_filename.end(); itr_m++){ std::set::iterator itr_s; for (itr_s = itr_m->second.begin(); itr_s!=itr_m->second.end(); itr_s++){ @@ -2181,6 +2184,14 @@ void cuobjdumpParseBinary(unsigned int handle){ context->add_binary(symtab, handle); load_static_globals(symtab,STATIC_ALLOC_LIMIT,0xFFFFFFFF,context->get_device()->get_gpgpu()); load_constants(symtab,STATIC_ALLOC_LIMIT,context->get_device()->get_gpgpu()); + for (itr_m = version_filename.begin(); itr_m!=version_filename.end(); itr_m++){ + std::set::iterator itr_s; + for (itr_s = itr_m->second.begin(); itr_s!=itr_m->second.end(); itr_s++){ + std::string ptx_filename = *itr_s; + printf("GPGPU-Sim PTX: Loading PTXInfo from %s\n",ptx_filename.c_str()); + gpgpu_ptx_info_load_from_filename( ptx_filename.c_str(), itr_m->first ); + } + } return; #endif diff --git a/src/cuda-sim/ptx_loader.cc b/src/cuda-sim/ptx_loader.cc index 2064b13..f5a1c77 100644 --- a/src/cuda-sim/ptx_loader.cc +++ b/src/cuda-sim/ptx_loader.cc @@ -320,8 +320,29 @@ char* get_app_binary_name(){ return self_exe_path; } -void gpgpu_ptx_info_load_from_filename( const char *filename ) +void gpgpu_ptx_info_load_from_filename( const char *filename, unsigned sm_version) { + std::string ptxas_filename(std::string(filename) + "as"); + char buff[1024], extra_flags[256]; + extra_flags[0]=0; + extern bool g_cdp_enabled; + if(!g_cdp_enabled) + snprintf(extra_flags,1024,"--gpu-name=sm_%u",sm_version); + else + snprintf(extra_flags,1024,"--compile-only --gpu-name=sm_%u",sm_version); + snprintf(buff,1024,"$CUDA_INSTALL_PATH/bin/ptxas %s -v %s --output-file /dev/null 2> %s", + extra_flags, filename, ptxas_filename.c_str()); + int result = system(buff); + if( result != 0 ) { + printf("GPGPU-Sim PTX: ERROR ** while loading PTX (b) %d\n", result); + printf(" Ensure ptxas is in your path.\n"); + exit(1); + } + + g_ptxinfo_filename = strdup(ptxas_filename.c_str()); + ptxinfo_in = fopen(g_ptxinfo_filename,"r"); + ptxinfo_parse(); + fclose(ptxinfo_in); } void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num, unsigned sm_version ) diff --git a/src/cuda-sim/ptx_loader.h b/src/cuda-sim/ptx_loader.h index c5c9dd8..e5df6a9 100644 --- a/src/cuda-sim/ptx_loader.h +++ b/src/cuda-sim/ptx_loader.h @@ -35,6 +35,7 @@ extern int no_of_ptx; //counter to track number of ptx files to be extracted in class symbol_table *gpgpu_ptx_sim_load_ptx_from_string( const char *p, unsigned source_num ); class symbol_table *gpgpu_ptx_sim_load_ptx_from_filename( const char *filename ); void gpgpu_ptxinfo_load_from_string( const char *p_for_info, unsigned source_num, unsigned sm_version=20 ); +void gpgpu_ptx_info_load_from_filename( const char *filename, unsigned sm_version ); char* gpgpu_ptx_sim_convert_ptx_and_sass_to_ptxplus(const std::string ptx_str, const std::string sass_str, const std::string elf_str); bool keep_intermediate_files(); -- cgit v1.3