diff --git a/cmake_modules/env.cmake b/cmake_modules/env.cmake index 9e7b13d8ab..2798b87374 100644 --- a/cmake_modules/env.cmake +++ b/cmake_modules/env.cmake @@ -36,6 +36,7 @@ add_definitions ( -DLITTLEENDIAN_CPU=1 ) add_definitions ( -DHSA_LARGE_MODEL= ) add_definitions ( -DHSA_DEPRECATED= ) add_definitions ( -D__HIP_PLATFORM_HCC__ ) +add_definitions ( -DHIP_PROF_HIP_API_STRING=1 ) ## Linux Compiler options set ( CMAKE_CXX_FLAGS "-std=c++11") @@ -65,11 +66,6 @@ if ( DEFINED ENV{CMAKE_DEBUG_TRACE} ) add_definitions ( -DDEBUG_TRACE=1 ) endif() -## HIP APIString() routine enableing -if ( DEFINED HIP_PROF_HIP_API_STRING ) - add_definitions ( -DHIP_PROF_HIP_API_STRING=1 ) -endif() - ## Enable HIP_VDI mode if ( DEFINED HIP_VDI ) add_definitions ( -DHIP_VDI=${HIP_VDI} ) diff --git a/inc/roctracer_hip.h b/inc/roctracer_hip.h index 28e4868d59..d6ce158d14 100644 --- a/inc/roctracer_hip.h +++ b/inc/roctracer_hip.h @@ -23,6 +23,7 @@ THE SOFTWARE. #ifndef INC_ROCTRACER_HIP_H_ #define INC_ROCTRACER_HIP_H_ +#include "inc/hip_ostream_ops.h" #include #include diff --git a/script/gen_ostream_ops.py b/script/gen_ostream_ops.py index 38f7e757cd..aa7d566e89 100755 --- a/script/gen_ostream_ops.py +++ b/script/gen_ostream_ops.py @@ -27,11 +27,19 @@ LICENSE = \ 'THE SOFTWARE.\n' + \ '*/\n' -HEADER = \ +header = \ 'template \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 {\n' + \ + 'inline static std::ostream& put(std::ostream& out, void* v) { out << std::hex << v; return out; }\n' + \ +'};\n' + \ +'template<>\n' + \ +'struct output_streamer {\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 {\n' + \ ' inline static std::ostream& put(std::ostream& out, bool v) { out << std::hex << ""; return out; }\n' + \ @@ -75,53 +83,91 @@ HEADER = \ '};\n' + \ '\n' -structs_done = {} -def process_struct(f,c,cppHeader,nname,apiname): +header_hip = \ +'template \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 << ""; return out; }\n' + \ +'std::ostream& operator<<(std::ostream& out, uint8_t v) { using std::operator<<; out << std::hex << ""; return out; }\n' + \ +'std::ostream& operator<<(std::ostream& out, uint16_t v) { using std::operator<<; out << std::hex << ""; return out; }\n' + \ +'std::ostream& operator<<(std::ostream& out, uint32_t v) { using std::operator<<; out << std::hex << ""; return out; }\n' + \ +'std::ostream& operator<<(std::ostream& out, uint64_t v) { using std::operator<<; out << std::hex << ""; return out; }\n' + \ +'std::ostream& operator<<(std::ostream& out, bool* v) { using std::operator<<; out << std::hex << ""; return out; }\n' + \ +'std::ostream& operator<<(std::ostream& out, uint8_t* v) { using std::operator<<; out << std::hex << ""; return out; }\n' + \ +'std::ostream& operator<<(std::ostream& out, uint16_t* v) { using std::operator<<; out << std::hex << ""; return out; }\n' + \ +'std::ostream& operator<<(std::ostream& out, uint32_t* v) { using std::operator<<; out << std::hex << ""; return out; }\n' + \ +'std::ostream& operator<<(std::ostream& out, uint64_t* v) { using std::operator<<; out << std::hex << ""; 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 \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']) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6d8c020b2a..0fc4b9bd2d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,7 +23,8 @@ set ( KFD_LIB_SRC ) execute_process ( COMMAND sh -xc "${CMAKE_CXX_COMPILER} -E ${HSA_KMT_INC_PATH}/hsakmttypes.h > ${PROJECT_BINARY_DIR}/hsakmttypes_pp.h" ) execute_process ( COMMAND sh -xc "${ROOT_DIR}/script/gen_ostream_ops.py -in ${PROJECT_BINARY_DIR}/hsakmttypes_pp.h -out ${ROOT_DIR}/inc/kfd_ostream_ops.h" ) -execute_process ( COMMAND sh -xc "${ROOT_DIR}/script/gen_ostream_ops.py -in ${HIP_PATH}/include/hip/hip_runtime_api.h -out ${ROOT_DIR}/inc/hip_ostream_ops.h" ) +execute_process ( COMMAND sh -xc "/usr/bin/gcc -D__HIP_PLATFORM_HCC__ -I${HIP_PATH}/include -I${CMAKE_PREFIX_PATH}/hsa/include -E ${HIP_PATH}/include/hip/hip_runtime_api.h > ${PROJECT_BINARY_DIR}/hip_runtime_api_pp.h" ) +execute_process ( COMMAND sh -xc "${ROOT_DIR}/script/gen_ostream_ops.py -in ${PROJECT_BINARY_DIR}/hip_runtime_api_pp.h -out ${ROOT_DIR}/inc/hip_ostream_ops.h" ) add_library ( ${KFD_LIB} SHARED ${KFD_LIB_SRC} ) target_include_directories ( ${KFD_LIB} PRIVATE ${LIB_DIR} ${ROOT_DIR} ${ROOT_DIR}/inc ${HSA_RUNTIME_INC_PATH} ${HSA_RUNTIME_HSA_INC_PATH} ${HSA_KMT_INC_PATH} ) target_link_libraries( ${KFD_LIB} PRIVATE c stdc++ ) diff --git a/test/golden_traces/tests_trace_cmp_levels.txt b/test/golden_traces/tests_trace_cmp_levels.txt index 653a274e18..b442541bc0 100644 --- a/test/golden_traces/tests_trace_cmp_levels.txt +++ b/test/golden_traces/tests_trace_cmp_levels.txt @@ -1,10 +1,10 @@ MatrixTranspose_ctest_trace 3 MatrixTranspose_test_trace 1 MatrixTranspose_mgpu_trace 1 -MatrixTranspose_kfd_trace 1 -MatrixTranspose_sys_trace 1 -MatrixTranspose_sys_hsa_trace 2 +MatrixTranspose_kfd_trace 0 +MatrixTranspose_sys_trace 0 +MatrixTranspose_sys_hsa_trace 0 MatrixTranspose_hip_period_trace 0 -MatrixTranspose_hip_flush_trace 1 +MatrixTranspose_hip_flush_trace 0 ctrl_hsa_trace 1 ctrl_hsa_input_trace 2 diff --git a/test/tool/tracer_tool.cpp b/test/tool/tracer_tool.cpp index 766a11d57e..7f22776660 100644 --- a/test/tool/tracer_tool.cpp +++ b/test/tool/tracer_tool.cpp @@ -406,7 +406,7 @@ void hip_api_flush_cb(hip_api_trace_entry_t* entry) { if (domain == ACTIVITY_DOMAIN_HIP_API) { #if HIP_PROF_HIP_API_STRING - const char* str = hipApiString(cid, data); + const char* str = hipApiString((hip_api_id_t)cid, data); fprintf(hip_api_file_handle, "%s\n", str); #else // !HIP_PROF_HIP_API_STRING switch (cid) { @@ -918,3 +918,4 @@ extern "C" DESTRUCTOR_API void destructor() { tool_unload(); ONLOAD_TRACE_END(); } +