summaryrefslogtreecommitdiff
path: root/libcuda/cuda_runtime_api.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libcuda/cuda_runtime_api.cc')
-rw-r--r--libcuda/cuda_runtime_api.cc257
1 files changed, 147 insertions, 110 deletions
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 <regex>
#include <sstream>
#include <fstream>
+#include <queue>
#ifdef OPENGL_SUPPORT
#define GL_GLEXT_PROTOTYPES
#ifdef __APPLE__
@@ -148,6 +149,10 @@
std::map<void *,void **> pinned_memory; //support for pinned memories added
std::map<void *, size_t> pinned_memory_size;
int no_of_ptx=0;
+char ptx_list_file_name[1024];
+std::map<int, std::string> fatbinmap;
+std::map<int, bool>fatbin_registered;
+std::map<std::string, symbol_table*> 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<int, std::set<std::string> > 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<std::string>();
+ }
+ version_filename[version].insert(line);
+ }
+
+ symbol_table *symtab;
+ //loops through all ptx files from smallest sm version to largest
+ std::map<int,std::set<std::string> >::iterator itr_m;
+ for (itr_m = version_filename.begin(); itr_m!=version_filename.end(); itr_m++){
+ std::set<std::string>::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<cuobjdumpSection*>::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<int, std::string> fatbinmap;
-std::map<int, bool>fatbin_registered;
-std::map<std::string, symbol_table*> 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<cuobjdumpSection*>::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 )
{