summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES2
-rw-r--r--libcuda/cuda_runtime_api.cc137
-rw-r--r--libcuda/cuobjdump.l2
-rw-r--r--libcuda/cuobjdump.y2
4 files changed, 115 insertions, 28 deletions
diff --git a/CHANGES b/CHANGES
index fde27fe..4697bd6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,8 @@
CHANGE LOG:
Version 3.1.1+edits (development branch) versus 3.1.1
+- Added an improved and less brittle support for associating fatbins to
+ sections from the output of cuobjdump
- Bug Fixes:
- Fixed a compile error that happens with newer gcc/g++ versions (4.7.1)
- Fixed a bug with the association between cuobjdump output and cubin
diff --git a/libcuda/cuda_runtime_api.cc b/libcuda/cuda_runtime_api.cc
index 35207bd..2b04aac 100644
--- a/libcuda/cuda_runtime_api.cc
+++ b/libcuda/cuda_runtime_api.cc
@@ -1163,7 +1163,7 @@ public:
std::string getPTXfilename() {return ptxfilename;}
void setPTXfilename(std::string f) {ptxfilename = f;}
virtual void print() {
- std::cout << "ELF Section:" << std::endl;
+ std::cout << "PTX Section:" << std::endl;
std::cout << "arch: sm_" << getArch() << std::endl;
std::cout << "identifier: " << getIdentifier() << std::endl;
std::cout << "ptx filename: " << getPTXfilename() << std::endl;
@@ -1181,7 +1181,7 @@ void addCuobjdumpSection(int sectiontype){
cuobjdumpSectionList.push_front(new cuobjdumpELFSection());
else
cuobjdumpSectionList.push_front(new cuobjdumpPTXSection());
- printf("## Adding new section %s\n", sectiontype==PTXSECTION?"PTX":"ELF");
+ printf("## Adding new section %s\n", sectiontype?"ELF":"PTX");
}
void setCuobjdumparch(const char* arch){
@@ -1271,10 +1271,22 @@ char* readfile (const std::string filename){
return ret;
}
+//Function that helps debugging
+void printSectionList(std::list<cuobjdumpSection*> sl) {
+ std::list<cuobjdumpSection*>::iterator iter;
+ for ( iter = sl.begin();
+ iter != sl.end();
+ iter++
+ ){
+ (*iter)->print();
+ }
+}
//remove unecessary sm versions from the section list
std::list<cuobjdumpSection*> pruneSectionList(std::list<cuobjdumpSection*> cuobjdumpSectionList, CUctx_st *context) {
unsigned forced_max_capability = context->get_device()->get_gpgpu()->get_config().get_forced_max_capability();
+
+ //For ptxplus, force the max capability to 19 if it's higher or unspecified(0)
if (context->get_device()->get_gpgpu()->get_config().convert_to_ptxplus()){
if ( (forced_max_capability == 0) ||
(forced_max_capability >= 20)){
@@ -1284,6 +1296,9 @@ std::list<cuobjdumpSection*> pruneSectionList(std::list<cuobjdumpSection*> cuobj
}
std::list<cuobjdumpSection*> prunedList;
+
+ //Find the highest capability (that is lower than the forces maximum) for each cubin file
+ //and set it in cuobjdumpSectionMap. Do this only for ptx sections
std::map<std::string, unsigned> cuobjdumpSectionMap;
for ( std::list<cuobjdumpSection*>::iterator iter = cuobjdumpSectionList.begin();
iter != cuobjdumpSectionList.end();
@@ -1292,10 +1307,13 @@ std::list<cuobjdumpSection*> pruneSectionList(std::list<cuobjdumpSection*> cuobj
if(dynamic_cast<cuobjdumpPTXSection*>(*iter) != NULL &&
(capability <= forced_max_capability ||
forced_max_capability==0)) {
- if(cuobjdumpSectionMap[(*iter)->getIdentifier()] < capability) cuobjdumpSectionMap[(*iter)->getIdentifier()] = capability;
+ if(cuobjdumpSectionMap[(*iter)->getIdentifier()] < capability)
+ cuobjdumpSectionMap[(*iter)->getIdentifier()] = capability;
}
}
+ //Throw away the sections with the lower capabilites and push those with the highest in
+ //the pruned list
for ( std::list<cuobjdumpSection*>::iterator iter = cuobjdumpSectionList.begin();
iter != cuobjdumpSectionList.end();
iter++){
@@ -1310,10 +1328,8 @@ std::list<cuobjdumpSection*> pruneSectionList(std::list<cuobjdumpSection*> cuobj
}
-//! Find number of files with a certain sm version
/*!
- * Within the section list, find the ELF section corresponding to a given
- * sm version and identifier
+ * Within the section list, find the ELF section corresponding to a given identifier
*/
cuobjdumpELFSection* findelfsection(std::list<cuobjdumpSection*> sectionlist, const std::string identifier){
@@ -1321,7 +1337,7 @@ cuobjdumpELFSection* findelfsection(std::list<cuobjdumpSection*> sectionlist, co
for ( iter = sectionlist.begin();
iter != sectionlist.end();
iter++
- ){
+ ){
cuobjdumpELFSection* elfsection;
if((elfsection=dynamic_cast<cuobjdumpELFSection*>(*iter)) != NULL){
if(elfsection->getIdentifier() == identifier)
@@ -1332,32 +1348,97 @@ cuobjdumpELFSection* findelfsection(std::list<cuobjdumpSection*> sectionlist, co
return NULL;
}
-
-//Function that helps debugging
-void printSectionList(std::list<cuobjdumpSection*> sl) {
+/*!
+ * Within the section list, find the PTX section corresponding to a given identifier
+ */
+cuobjdumpPTXSection* findptxsection(std::list<cuobjdumpSection*> sectionlist, const std::string identifier){
std::list<cuobjdumpSection*>::iterator iter;
- for ( iter = sl.begin();
- iter != sl.end();
+ for ( iter = sectionlist.begin();
+ iter != sectionlist.end();
iter++
){
- (*iter)->print();
+ cuobjdumpPTXSection* ptxsection;
+ if((ptxsection=dynamic_cast<cuobjdumpPTXSection*>(*iter)) != NULL){
+ if(ptxsection->getIdentifier() == identifier)
+ return ptxsection;
+ }
}
+ std::cout << identifier << std::endl;
+ assert(0 && "Could not find the required PTX section");
+ return NULL;
}
+
+void cuobjdumpInit(){
+ CUctx_st *context = GPGPUSim_Context();
+
+ extract_code_using_cuobjdump(); //extract all the output of cuobjdump to _cuobjdump_*.*
+
+ cuobjdumpSectionList = pruneSectionList(cuobjdumpSectionList, context);
+}
+
+
+
+void cuobjdumpRegisterFatBinary(unsigned int handle, char* filename){
+
+ CUctx_st *context = GPGPUSim_Context();
+
+ std::string fname = filename;
+ cuobjdumpPTXSection* ptx = findptxsection(cuobjdumpSectionList, fname);
+
+ symbol_table *symtab;
+ char *ptxcode = readfile(ptx->getPTXfilename());
+ if(context->get_device()->get_gpgpu()->get_config().convert_to_ptxplus() ) {
+ cuobjdumpELFSection* elfsection = findelfsection(cuobjdumpSectionList, 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());
+
+ //TODO: Remove temporarily files as per configurations
+}
+
+
+// Currently not used
void useCuobjdump() {
CUctx_st *context = GPGPUSim_Context();
+
unsigned source_num=1;
extract_code_using_cuobjdump(); //extract all the output of cuobjdump to _cuobjdump_*.*
+
+ // There is variation in the order by which the cubins are registered. It was observed that
+ // the order is correct when the first section is a PTX section and is reversed when the
+ // first section is an ELF section
+ bool reverse=false;
+ if (dynamic_cast<cuobjdumpELFSection*>(cuobjdumpSectionList.front()) != NULL)reverse=true;
+
cuobjdumpSectionList = pruneSectionList(cuobjdumpSectionList, context);
unsigned total_ptx_files = cuobjdumpSectionList.size()/2 + 1;
for ( std::list<cuobjdumpSection*>::iterator iter2 = cuobjdumpSectionList.begin();
iter2 != cuobjdumpSectionList.end();
iter2++
- ){
+ ){
if (dynamic_cast<cuobjdumpPTXSection*>(*iter2) != NULL)
{
+ int cubin_handle;
+ if(reverse) cubin_handle = total_ptx_files-source_num;
+ else cubin_handle = source_num;
cuobjdumpPTXSection *iter = dynamic_cast<cuobjdumpPTXSection*>(*iter2);
symbol_table *symtab;
char *ptxcode = readfile(iter->getPTXfilename());
@@ -1368,16 +1449,16 @@ void useCuobjdump() {
iter->getPTXfilename(),
elfsection->getELFfilename(),
elfsection->getSASSfilename());
- symtab=gpgpu_ptx_sim_load_ptx_from_string(ptxplus_str,source_num);
- printf("Adding %s with cubin handle %u\n", iter->getPTXfilename().c_str(), total_ptx_files-source_num);
- context->add_binary(symtab, total_ptx_files-source_num);
- gpgpu_ptxinfo_load_from_string( ptxcode,total_ptx_files-source_num);
+ symtab=gpgpu_ptx_sim_load_ptx_from_string(ptxplus_str,cubin_handle);
+ printf("Adding %s with cubin handle %u\n", iter->getPTXfilename().c_str(), cubin_handle);
+ context->add_binary(symtab, cubin_handle);
+ gpgpu_ptxinfo_load_from_string( ptxcode, cubin_handle);
delete[] ptxplus_str;
} else {
- symtab=gpgpu_ptx_sim_load_ptx_from_string(ptxcode, source_num);
- printf("Adding %s with cubin handle %u\n", iter->getPTXfilename().c_str(), total_ptx_files-source_num);
- context->add_binary(symtab,total_ptx_files-source_num);
- gpgpu_ptxinfo_load_from_string( ptxcode, total_ptx_files-source_num);
+ symtab=gpgpu_ptx_sim_load_ptx_from_string(ptxcode, cubin_handle);
+ printf("Adding %s with cubin handle %u\n", iter->getPTXfilename().c_str(), cubin_handle);
+ context->add_binary(symtab, cubin_handle);
+ gpgpu_ptxinfo_load_from_string( ptxcode, cubin_handle);
}
source_num++;
@@ -1400,6 +1481,7 @@ void useCuobjdump() {
}
+
void** CUDARTAPI __cudaRegisterFatBinary( void *fatCubin )
{
#if (CUDART_VERSION < 2010)
@@ -1409,16 +1491,19 @@ void** CUDARTAPI __cudaRegisterFatBinary( void *fatCubin )
CUctx_st *context = GPGPUSim_Context();
static unsigned next_fat_bin_handle = 1;
if(context->get_device()->get_gpgpu()->get_config().use_cuobjdump()) {
+ void * s1 = *((void**)(fatCubin+8));
+ void * s2 = (s1+72);
+ char * filename = (char *)s2;
unsigned fat_cubin_handle = next_fat_bin_handle;
next_fat_bin_handle++;
- printf("GPGPU-Sim PTX: __cudaRegisterFatBinary, fat_cubin_handle = %u\n", fat_cubin_handle);
+ printf("GPGPU-Sim PTX: __cudaRegisterFatBinary, fat_cubin_handle = %u, filename=%s\n", fat_cubin_handle, filename);
/*!
* This function extracts all data from all files in first call
* then for next calls, only returns the appropriate number
*/
assert(fat_cubin_handle >= 1);
- if(fat_cubin_handle == 1)
- useCuobjdump();
+ if (fat_cubin_handle==1) cuobjdumpInit();
+ cuobjdumpRegisterFatBinary(fat_cubin_handle, filename);
return (void**)fat_cubin_handle;
} else {
@@ -1463,7 +1548,7 @@ void** CUDARTAPI __cudaRegisterFatBinary( void *fatCubin )
const char *ptx = info->ptx[selected_capability].ptx;
if(context->get_device()->get_gpgpu()->get_config().convert_to_ptxplus() ) {
printf("GPGPU-Sim PTX: ERROR ** PTXPlus is only supported through cuobjdump\n"
- "\tEither enable cuobjdump or disable PTXPlus in your configuration file\n");
+ "\tEither enable cuobjdump or disable PTXPlus in your configuration file\n");
exit(1);
} else {
symtab=gpgpu_ptx_sim_load_ptx_from_string(ptx,source_num);
diff --git a/libcuda/cuobjdump.l b/libcuda/cuobjdump.l
index fb9a60a..e782c17 100644
--- a/libcuda/cuobjdump.l
+++ b/libcuda/cuobjdump.l
@@ -107,7 +107,7 @@ newlines {newline}+
<header>"has debug info"{newline}
/* Looking for the identifier (filename) then the header is done */
-<endheader>[[:alnum:]_\.]+{newline} yylval.string_value = strdup(yytext); yy_pop_state(); return FILENAME;
+<endheader>[[:alnum:]_\.]+ yylval.string_value = strdup(yytext); yy_pop_state(); return FILENAME;
{newline} return NEWLINE;
diff --git a/libcuda/cuobjdump.y b/libcuda/cuobjdump.y
index 914a3d6..b8e9c11 100644
--- a/libcuda/cuobjdump.y
+++ b/libcuda/cuobjdump.y
@@ -95,7 +95,7 @@ headerinfo : H_SEPARATOR NEWLINE
H_PRODUCER IDENTIFIER NEWLINE
H_HOST IDENTIFIER NEWLINE
H_COMPILESIZE IDENTIFIER NEWLINE
- H_IDENTIFIER FILENAME {setCuobjdumparch($4); setCuobjdumpidentifier($19);};
+ H_IDENTIFIER FILENAME emptylines {setCuobjdumparch($4); setCuobjdumpidentifier($19);};
ptxcode : ptxcode PTXLINE {fprintf(ptxfile, "%s", $2);}
| ;