summaryrefslogtreecommitdiff
path: root/libcuda
diff options
context:
space:
mode:
authorTim Rogers <[email protected]>2018-10-05 13:42:03 -0400
committerGitHub <[email protected]>2018-10-05 13:42:03 -0400
commit77a18471d485b2a5bad8cf140185d41fd9d35055 (patch)
tree70c9ab71a18695fe1b6c23b9665a664c9328ce86 /libcuda
parent2f2345eef7e40e2fcd0cf5558adfa0fd4ff728d1 (diff)
parent6ac985565bf5cb6d621487cc4d13163f63d5b646 (diff)
Merge pull request #76 from tgrogers/dev
Changes to allow correct occupancy with newer cards, while still running PTXPlus
Diffstat (limited to 'libcuda')
-rw-r--r--libcuda/cuda_runtime_api.cc188
1 files changed, 112 insertions, 76 deletions
diff --git a/libcuda/cuda_runtime_api.cc b/libcuda/cuda_runtime_api.cc
index 5ef6115..edd4fb9 100644
--- a/libcuda/cuda_runtime_api.cc
+++ b/libcuda/cuda_runtime_api.cc
@@ -182,6 +182,8 @@ cudaError_t g_last_cudaError = cudaSuccess;
extern stream_manager *g_stream_manager;
+
+
void register_ptx_function( const char *name, function_info *impl )
{
// no longer need this
@@ -1341,6 +1343,29 @@ std::string get_app_binary(){
return self_exe_path;
}
+static int get_app_cuda_version() {
+ int app_cuda_version = 0;
+ char fname[1024];
+ snprintf(fname,1024,"_app_cuda_version_XXXXXX");
+ int fd=mkstemp(fname);
+ close(fd);
+ std::string app_cuda_version_command = "ldd " + get_app_binary() + " | grep libcudart.so | sed 's/.*libcudart.so.\\(.*\\) =>.*/\\1/' > " + fname;
+ system(app_cuda_version_command.c_str());
+ FILE * cmd = fopen(fname, "r");
+ char buf[256];
+ while (fgets(buf, sizeof(buf), cmd) != 0) {
+ std::cout << buf;
+ app_cuda_version = atoi(buf);
+ }
+ fclose(cmd);
+ if ( app_cuda_version == 0 ) {
+ printf( "Error - Cannot detect the app's CUDA version.\n" );
+ exit(1);
+ }
+ return app_cuda_version;
+}
+
+
//! Call cuobjdump to extract everything (-elf -sass -ptx)
/*!
* This Function extract the whole PTX (for all the files) using cuobjdump
@@ -1350,39 +1375,39 @@ std::string get_app_binary(){
* enabled
* */
void extract_code_using_cuobjdump(){
- CUctx_st *context = GPGPUSim_Context();
- char command[1000];
+ CUctx_st *context = GPGPUSim_Context();
+ std::string command;
- std::string app_binary = get_app_binary();
+ std::string app_binary = get_app_binary();
char fname[1024];
snprintf(fname,1024,"_cuobjdump_complete_output_XXXXXX");
int fd=mkstemp(fname);
close(fd);
// Running cuobjdump using dynamic link to current process
- snprintf(command,1000,"md5sum %s ", app_binary.c_str());
- printf("Running md5sum using \"%s\"\n", command);
- system(command);
+ command = "md5sum " + app_binary;
+ printf("Running md5sum using \"%s\"\n", command.c_str());
+ system(command.c_str());
// Running cuobjdump using dynamic link to current process
// Needs the option '-all' to extract PTX from CDP-enabled binary
extern bool g_cdp_enabled;
if(!g_cdp_enabled)
- snprintf(command,1000,"$CUDA_INSTALL_PATH/bin/cuobjdump -ptx -elf -sass %s > %s", app_binary.c_str(), fname);
+ command = "$CUDA_INSTALL_PATH/bin/cuobjdump -ptx -elf -sass " + app_binary + " > " + fname;
else
- snprintf(command,1000,"$CUDA_INSTALL_PATH/bin/cuobjdump -ptx -elf -sass -all %s > %s", app_binary.c_str(), fname);
+ command = "$CUDA_INSTALL_PATH/bin/cuobjdump -ptx -elf -sass -all " + app_binary + " > " + fname;
bool parse_output = true;
- int result = system(command);
+ int result = system(command.c_str());
if(result) {
if (context->get_device()->get_gpgpu()->get_config().experimental_lib_support() && (result == 65280)) {
// Some CUDA application may exclusively use kernels provided by CUDA
// libraries (e.g. CUBLAS). Skipping cuobjdump extraction from the
// executable for this case.
// 65280 is the return code from cuobjdump denoting the specific error (tested on CUDA 4.0/4.1/4.2)
- printf("WARNING: Failed to execute: %s\n", command);
+ printf("WARNING: Failed to execute: %s\n", command.c_str());
printf(" Executable binary does not contain any GPU kernel.\n");
parse_output = false;
} else {
- printf("ERROR: Failed to execute: %s\n", command);
+ printf("ERROR: Failed to execute: %s\n", command.c_str());
exit(1);
}
}
@@ -1435,7 +1460,7 @@ void extract_code_using_cuobjdump(){
std::cout << "Running cuobjdump on " << line << std::endl;
std::cout << "Using command: " << cmd.str() << std::endl;
result = system(cmd.str().c_str());
- if(result) {printf("ERROR: Failed to execute: %s\n", command); exit(1);}
+ if(result) {printf("ERROR: Failed to execute: %s\n", command.c_str()); exit(1);}
std::cout << "Done" << std::endl;
std::cout << "Trying to parse " << libcodfn.str() << std::endl;
@@ -1696,61 +1721,63 @@ void cuobjdumpRegisterFatBinary(unsigned int handle, const char* 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(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;
- }
+ 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);
+ 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;
+ }
+ printf("Using PTX version = %u\n", max_capability);
+ if (max_capability > 20) printf("WARNING: No guarantee that PTX will be parsed for SM version %u\n", max_capability);
- cuobjdumpPTXSection* 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) {
- 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);
- 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;
+ cuobjdumpPTXSection* 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) {
+ 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 );
+ delete[] ptxplus_str;
+ } else {
+ symtab=gpgpu_ptx_sim_load_ptx_from_string(ptxcode, 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 );
+ }
+ 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
+ //TODO: Remove temporarily files as per configurations
}
+
void** CUDARTAPI __cudaRegisterFatBinary( void *fatCubin )
{
#if (CUDART_VERSION < 2010)
@@ -1764,21 +1791,30 @@ void** CUDARTAPI __cudaRegisterFatBinary( void *fatCubin )
if (sizeof(void*) == 4)
printf("GPGPU-Sim PTX: FatBin file name extraction has not been tested on 32-bit system.\n");
- #if (CUDART_VERSION <= 6000)
- // FatBin handle from the .fatbin.c file (one of the intermediate files generated by NVCC)
- typedef struct {int m; int v; const unsigned long long* d; char* f;} __fatDeviceText __attribute__ ((aligned (8)));
- __fatDeviceText * fatDeviceText = (__fatDeviceText *) fatCubin;
+ // This code will get the CUDA version the app was compiled with.
+ // We need this to determine how to handle the parsing of the binary.
+ // Making this a runtime variable based on the app, enables GPGPU-Sim compiled
+ // with a newer version of CUDA to run apps compiled with older versions of
+ // CUDA. This is especially useful for PTXPLUS execution.
+ int app_cuda_version = get_app_cuda_version();
+ assert( app_cuda_version == CUDART_VERSION / 1000 && "The app must be compiled with same major version as the simulator." );
+ const char* filename;
+#if CUDART_VERSION < 6000
+ // FatBin handle from the .fatbin.c file (one of the intermediate files generated by NVCC)
+ typedef struct {int m; int v; const unsigned long long* d; char* f;} __fatDeviceText __attribute__ ((aligned (8)));
+ __fatDeviceText * fatDeviceText = (__fatDeviceText *) fatCubin;
+
+ // Extract the source code file name that generate the given FatBin.
+ // - Obtains the pointer to the actual fatbin structure from the FatBin handle (fatCubin).
+ // - An integer inside the fatbin structure contains the relative offset to the source code file name.
+ // - This offset differs among different CUDA and GCC versions.
+ char * pfatbin = (char*) fatDeviceText->d;
+ int offset = *((int*)(pfatbin+48));
+ filename = (pfatbin+16+offset);
+#else
+ filename = "default";
+#endif
- // Extract the source code file name that generate the given FatBin.
- // - Obtains the pointer to the actual fatbin structure from the FatBin handle (fatCubin).
- // - An integer inside the fatbin structure contains the relative offset to the source code file name.
- // - This offset differs among different CUDA and GCC versions.
- char * pfatbin = (char*) fatDeviceText->d;
- int offset = *((int*)(pfatbin+48));
- char * filename = (pfatbin+16+offset);
- #else
- const char * filename = "default";
- #endif
// The extracted file name is associated with a fat_cubin_handle passed
// into cudaLaunch(). Inside cudaLaunch(), the associated file name is
// used to find the PTX/SASS section from cuobjdump, which contains the
@@ -1846,7 +1882,7 @@ void** CUDARTAPI __cudaRegisterFatBinary( void *fatCubin )
} else {
symtab=gpgpu_ptx_sim_load_ptx_from_string(ptx,source_num);
context->add_binary(symtab,fat_cubin_handle);
- gpgpu_ptxinfo_load_from_string( ptx, source_num, max_capability );
+ gpgpu_ptxinfo_load_from_string( ptx, source_num );
}
source_num++;
load_static_globals(symtab,STATIC_ALLOC_LIMIT,0xFFFFFFFF,context->get_device()->get_gpgpu());