Added generation of hip ostream operators

Change-Id: I5d07ea07cdd94097cb44619c29d9deba54e5d6a5

ostream ops code cleanup

Change-Id: Ia4e287de1e1953f5d323a0066c29aa6056442139
This commit is contained in:
Rachida Kebichi
2020-04-21 10:53:00 -04:00
parent d46e357aba
commit 72b0d25ea4
6 ha cambiato i file con 119 aggiunte e 56 eliminazioni
+109 -45
Vedi File
@@ -27,11 +27,19 @@ LICENSE = \
'THE SOFTWARE.\n' + \
'*/\n'
HEADER = \
header = \
'template <typename T>\n' + \
'struct output_streamer {\n' + \
' inline static std::ostream& put(std::ostream& out, const T& v) { return out; }\n' + \
'};\n' + \
'template<>\n' + \
'struct output_streamer<void*> {\n' + \
'inline static std::ostream& put(std::ostream& out, void* v) { out << std::hex << v; return out; }\n' + \
'};\n' + \
'template<>\n' + \
'struct output_streamer<const void*> {\n' + \
'inline static std::ostream& put(std::ostream& out, const void* v) { out << std::hex << v; return out; }\n' + \
'};\n' + \
'\ntemplate<>\n' + \
'struct output_streamer<bool> {\n' + \
' inline static std::ostream& put(std::ostream& out, bool v) { out << std::hex << "<bool " << "0x" << v << std::dec << ">"; return out; }\n' + \
@@ -75,53 +83,91 @@ HEADER = \
'};\n' + \
'\n'
structs_done = {}
def process_struct(f,c,cppHeader,nname,apiname):
header_hip = \
'template <typename T>\n' + \
' std::ostream& operator<<(std::ostream& out, const T& v) { using std::operator<<; out << v; return out; }\n' + \
'std::ostream& operator<<(std::ostream& out, void* v) { using std::operator<<; out << std::hex << v; return out; }\n' + \
'std::ostream& operator<<(std::ostream& out, const void* v) { using std::operator<<; out << std::hex << v; return out; }\n' + \
'std::ostream& operator<<(std::ostream& out, bool v) { using std::operator<<; out << std::hex << "<bool " << "0x" << v << std::dec << ">"; return out; }\n' + \
'std::ostream& operator<<(std::ostream& out, uint8_t v) { using std::operator<<; out << std::hex << "<uint8_t " << "0x" << v << std::dec << ">"; return out; }\n' + \
'std::ostream& operator<<(std::ostream& out, uint16_t v) { using std::operator<<; out << std::hex << "<uint16_t " << "0x" << v << std::dec << ">"; return out; }\n' + \
'std::ostream& operator<<(std::ostream& out, uint32_t v) { using std::operator<<; out << std::hex << "<uint32_t " << "0x" << v << std::dec << ">"; return out; }\n' + \
'std::ostream& operator<<(std::ostream& out, uint64_t v) { using std::operator<<; out << std::hex << "<uint64_t " << "0x" << v << std::dec << ">"; return out; }\n' + \
'std::ostream& operator<<(std::ostream& out, bool* v) { using std::operator<<; out << std::hex << "<bool " << "0x" << *v << std::dec << ">"; return out; }\n' + \
'std::ostream& operator<<(std::ostream& out, uint8_t* v) { using std::operator<<; out << std::hex << "<uint8_t " << "0x" << *v << std::dec << ">"; return out; }\n' + \
'std::ostream& operator<<(std::ostream& out, uint16_t* v) { using std::operator<<; out << std::hex << "<uint16_t " << "0x" << *v << std::dec << ">"; return out; }\n' + \
'std::ostream& operator<<(std::ostream& out, uint32_t* v) { using std::operator<<; out << std::hex << "<uint32_t " << "0x" << *v << std::dec << ">"; return out; }\n' + \
'std::ostream& operator<<(std::ostream& out, uint64_t* v) { using std::operator<<; out << std::hex << "<uint64_t " << "0x" << *v << std::dec << ">"; return out; }\n' + \
'\n'
if c not in cppHeader.classes:
structs_analyzed = {}
global_ops_hip = ''
# process_struct traverses recursively all structs to extract all fields
def process_struct(file_handle, cppHeader_struct, cppHeader, parent_hier_name, apiname):
# file_handle: handle for output file {api_name}_ostream_ops.h to be generated
# cppHeader_struct: cppHeader struct being processed
# cppHeader: cppHeader object created by CppHeaderParser.CppHeader(...)
# parent_hier_name: parent hierarchical name used for nested structs/enums
# apiname: for example hip, kfd.
if cppHeader_struct == 'max_align_t': #function pointers not working in cppheaderparser
return
if c in structs_done:
if cppHeader_struct not in cppHeader.classes:
return
if cppHeader_struct in structs_analyzed:
return
structs_done[c] = 1;
for l in range(len(cppHeader.classes[c]["properties"]["public"])):
structs_analyzed[cppHeader_struct] = 1;
for l in reversed(range(len(cppHeader.classes[cppHeader_struct]["properties"]["public"]))):
key = 'name'
name = ""
if key in cppHeader.classes[c]["properties"]["public"][l]:
name = cppHeader.classes[c]["properties"]["public"][l][key]
if key in cppHeader.classes[cppHeader_struct]["properties"]["public"][l]:
if parent_hier_name != '':
name = parent_hier_name + '.' + cppHeader.classes[cppHeader_struct]["properties"]["public"][l][key]
else:
name = cppHeader.classes[cppHeader_struct]["properties"]["public"][l][key]
if name == '':
continue
key2 = 'type'
mtype = ""
if key2 in cppHeader.classes[c]["properties"]["public"][l]:
mtype = cppHeader.classes[c]["properties"]["public"][l][key2]
if key2 in cppHeader.classes[cppHeader_struct]["properties"]["public"][l]:
mtype = cppHeader.classes[cppHeader_struct]["properties"]["public"][l][key2]
if mtype == '':
continue
key3 = 'array_size'
array_size = ""
if key3 in cppHeader.classes[c]["properties"]["public"][l]:
array_size = cppHeader.classes[c]["properties"]["public"][l][key3]
if key3 in cppHeader.classes[cppHeader_struct]["properties"]["public"][l]:
array_size = cppHeader.classes[cppHeader_struct]["properties"]["public"][l][key3]
key4 = 'property_of_class'
prop = ""
if key4 in cppHeader.classes[c]["properties"]["public"][l]:
prop = cppHeader.classes[c]["properties"]["public"][l][key4]
if key4 in cppHeader.classes[cppHeader_struct]["properties"]["public"][l]:
prop = cppHeader.classes[cppHeader_struct]["properties"]["public"][l][key4]
if mtype != "" and "union" not in mtype:
if array_size == "":
str = " roctracer::" + apiname.lower() + "_support::output_streamer<"+mtype+">::put(out,v."+name+");\n"
if "union" not in mtype:
if apiname.lower() == 'hip':
str = " roctracer::hip_support::operator<<(out, v."+name+");\n"
else:
if array_size == "":
str = " roctracer::" + apiname.lower() + "_support::output_streamer<"+mtype+">::put(out,v."+name+");\n"
else:
str = " roctracer::" + apiname.lower() + "_support::output_streamer<"+mtype+"["+array_size+"]>::put(out,v."+name+");\n"
if nname != "" and nname not in str:
#print("injecting ",nname, "in ", str)
str = str.replace("v.","v."+nname+".")
if "void" not in mtype:
f.write(str)
file_handle.write(str)
else:
nc = prop+"::"
process_struct(f,nc,cppHeader,name,apiname)
nc = prop+"::"+mtype+" "
process_struct(f,nc,cppHeader,name,apiname)
nc = c+"::"
process_struct(f,nc,cppHeader,name,apiname)
if prop != '':
next_cppHeader_struct = prop + "::"
process_struct(file_handle, next_cppHeader_struct, cppHeader, name, apiname)
next_cppHeader_struct = prop + "::" + mtype + " "
process_struct(file_handle, next_cppHeader_struct, cppHeader, name, apiname)
next_cppHeader_struct = cppHeader_struct + "::"
process_struct(file_handle, next_cppHeader_struct, cppHeader, name, apiname)
# Parses API header file and generates ostream ops files ostream_ops.h and basic_ostream_ops.h
def gen_cppheader(infilepath, outfilepath):
# infilepath: API Header file to be parsed
# outfilepath: Output file where ostream operators are written
global_ops_hip = ''
try:
cppHeader = CppHeaderParser.CppHeader(infilepath)
except CppHeaderParser.CppParseError as e:
@@ -139,42 +185,60 @@ def gen_cppheader(infilepath, outfilepath):
f2.write("// automatically generated\n")
f.write(LICENSE + '\n')
f2.write(LICENSE + '\n')
HEADER_S = \
header_s = \
'#ifndef INC_' + apiname + '_OSTREAM_OPS_H_\n' + \
'#define INC_' + apiname + '_OSTREAM_OPS_H_\n' + \
'#ifdef __cplusplus\n' + \
'#include <iostream>\n' + \
'\n' + \
'#include "roctracer.h"\n'
f.write(HEADER_S)
if apiname.lower() == 'hip':
header_s = header_s + '\n' + \
'#include "hip/hip_runtime_api.h"\n' + \
'#include "hip/hcc_detail/hip_vector_types.h"\n\n'
f.write(header_s)
f.write('\n')
f.write('namespace roctracer {\n')
f.write('namespace ' + apiname.lower() + '_support {\n')
f.write('// begin ostream ops for '+ apiname + ' \n')
f.write('#include "basic_ostream_ops.h"' + '\n')
f2.write(HEADER)
if apiname.lower() != 'hip':
f.write('#include "basic_ostream_ops.h"' + '\n')
else:
f.write("// HIP basic ostream ops\n")
f.write(header_hip)
f.write("// End of HIP basic ostream ops\n\n")
f2.write(header)
for c in cppHeader.classes:
if "union" in c:
continue
if len(cppHeader.classes[c]["properties"]["public"])!=0:
if apiname.lower() == 'hip':
f.write("std::ostream& operator<<(std::ostream& out, " + c + "& v)\n")
f.write("{\n")
global_ops_hip = global_ops_hip + "std::ostream& operator<<(std::ostream& out, const " + c + "& v)\n" + "{\n" + " roctracer::hip_support::operator<<(out, v);\n" + " return out;\n" + "}\n\n"
process_struct(f, c, cppHeader, "", apiname)
f.write(" return out;\n")
f.write("}\n")
else:
f.write("\ntemplate<>\n")
f.write("struct output_streamer<"+c+"&> {\n")
f.write("struct output_streamer<" + c + "&> {\n")
f.write(" inline static std::ostream& put(std::ostream& out, "+c+"& v)\n")
f.write("{\n")
process_struct(f,c,cppHeader,"",apiname)
process_struct(f, c, cppHeader, "", apiname)
f.write(" return out;\n")
f.write("}\n")
f.write("};\n")
FOOTER = \
footer = \
'// end ostream ops for '+ apiname + ' \n'
FOOTER += '};};\n' + \
'\n' + \
'#endif // INC_' + apiname + '_OSTREAM_OPS_H_\n' + \
' \n'
FOOTER2 = '\n\n' + \
'#endif // INC_BASIC_OSTREAM_OPS_H_\n' + \
' \n'
f.write(FOOTER)
footer += '};};\n\n'
f.write(footer)
f.write(global_ops_hip)
footer = '#endif //__cplusplus\n' + \
'#endif // INC_' + apiname + '_OSTREAM_OPS_H_\n' + \
' \n'
f.write(footer)
f.close()
f2.close()
print('File ' + outfilepath + ' generated')
@@ -190,4 +254,4 @@ requiredNamed.add_argument('-out', metavar='file', help='Output file with ostrea
args = vars(parser.parse_args())
if __name__ == '__main__':
gen_cppheader(args['in'],args['out'])
gen_cppheader(args['in'], args['out'])