diff --git a/projects/roctracer/inc/roctracer_hsa.h b/projects/roctracer/inc/roctracer_hsa.h index 4ec56662d1..bd5b9ef15b 100644 --- a/projects/roctracer/inc/roctracer_hsa.h +++ b/projects/roctracer/inc/roctracer_hsa.h @@ -44,10 +44,6 @@ namespace roctracer { namespace hsa_support { enum { HSA_OP_ID_async_copy = 0 }; -extern CoreApiTable CoreApiTable_saved; -extern AmdExtTable AmdExtTable_saved; -extern ImageExtTable ImageExtTable_saved; - struct ops_properties_t { void* table; void* reserved1[3]; diff --git a/projects/roctracer/script/hsaap.py b/projects/roctracer/script/hsaap.py index 8794513a99..7139be879f 100755 --- a/projects/roctracer/script/hsaap.py +++ b/projects/roctracer/script/hsaap.py @@ -25,7 +25,8 @@ from __future__ import print_function import os, sys, re -OUT='hsa_prof_str.h' +H_OUT='hsa_prof_str.h' +CPP_OUT='hsa_prof_str.inline.h' API_TABLES_H = 'hsa_api_trace.h' API_HEADERS_H = ( ('CoreApiTable', 'hsa.h'), @@ -35,27 +36,25 @@ API_HEADERS_H = ( ) LICENSE = \ -'/*\n' + \ -'Copyright (c) 2018 Advanced Micro Devices, Inc. All rights reserved.\n' + \ +'/* Copyright (c) 2018-2022 Advanced Micro Devices, Inc.\n' + \ '\n' + \ -'Permission is hereby granted, free of charge, to any person obtaining a copy\n' + \ -'of this software and associated documentation files (the "Software"), to deal\n' + \ -'in the Software without restriction, including without limitation the rights\n' + \ -'to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n' + \ -'copies of the Software, and to permit persons to whom the Software is\n' + \ -'furnished to do so, subject to the following conditions:\n' + \ +' Permission is hereby granted, free of charge, to any person obtaining a copy\n' + \ +' of this software and associated documentation files (the "Software"), to deal\n' + \ +' in the Software without restriction, including without limitation the rights\n' + \ +' to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n' + \ +' copies of the Software, and to permit persons to whom the Software is\n' + \ +' furnished to do so, subject to the following conditions:\n' + \ '\n' + \ -'The above copyright notice and this permission notice shall be included in\n' + \ -'all copies or substantial portions of the Software.\n' + \ +' The above copyright notice and this permission notice shall be included in\n' + \ +' all copies or substantial portions of the Software.\n' + \ '\n' + \ -'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n' + \ -'IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n' + \ -'FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n' + \ -'AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n' + \ -'LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n' + \ -'OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n' + \ -'THE SOFTWARE.\n' + \ -'*/\n' +' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n' + \ +' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n' + \ +' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n' + \ +' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n' + \ +' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n' + \ +' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n' + \ +' THE SOFTWARE. */\n' ############################################################# # Error handler @@ -260,10 +259,11 @@ class API_DescrParser: def fatal(self, msg): fatal('API_DescrParser', msg) - def __init__(self, out_file, hsa_dir, api_table_h, api_headers, license): - out_macro = re.sub(r'[\/\.]', r'_', out_file.upper()) + '_' + def __init__(self, out_h_file, hsa_dir, api_table_h, api_headers, license): + out_macro = re.sub(r'[\/\.]', r'_', out_h_file.upper()) + '_' - self.content = '' + self.h_content = '' + self.cpp_content = '' self.api_names = [] self.api_calls = {} self.api_rettypes = set() @@ -305,194 +305,208 @@ class API_DescrParser: self.api_data = api_data self.ns_calls = ns_calls - self.content += "// automatically generated\n\n" + license + '\n' + self.h_content += "/* Generated by " + os.path.basename(__file__) + " */\n" + license + "\n\n" - self.content += "/////////////////////////////////////////////////////////////////////////////\n" - self.content += "//\n" - self.content += "// HSA API tracing primitives\n" - self.content += "//\n" + self.h_content += "/* HSA API tracing primitives\n" for (name, header) in api_headers: - self.content += "// '" + name + "', header '" + header + "', " + str(len(self.api_calls[name])) + ' funcs\n' + self.h_content += " '" + name + "', header '" + header + "', " + str(len(self.api_calls[name])) + ' funcs\n' for call in self.ns_calls: - self.content += '// ' + call + ' was not parsed\n' - self.content += "//\n" - self.content += "/////////////////////////////////////////////////////////////////////////////\n" - self.content += '\n' - self.content += '#ifndef ' + out_macro + '\n' - self.content += '#define ' + out_macro + '\n' - self.add_section('API ID enumeration', ' ', self.gen_id_enum) - self.add_section('API arg structure', ' ', self.gen_arg_struct) + self.h_content += ' ' + call + ' was not parsed\n' + self.h_content += " */\n" + self.h_content += '\n' + self.h_content += '#ifndef ' + out_macro + '\n' + self.h_content += '#define ' + out_macro + '\n' - self.content += '\n' - self.content += '#if PROF_API_IMPL\n' - self.content += '#include \"util/callback_table.h\"\n'; - self.content += '#include \n' - self.content += 'namespace roctracer {\n' - self.content += 'namespace hsa_support {\n' - self.content += 'std::atomic hsa_counter_{1};\n' - self.content += 'static thread_local uint64_t hsa_correlation_id_tls = 0;\n' - self.add_section('API callback functions', '', self.gen_callbacks) - self.add_section('API intercepting code', '', self.gen_intercept) - self.add_section('API get_name function', ' ', self.gen_get_name) - self.add_section('API get_code function', ' ', self.gen_get_code) - self.content += '\n};};\n' - self.content += '#endif // PROF_API_IMPL\n' + self.h_content += self.add_section('API ID enumeration', ' ', self.gen_id_enum) + self.h_content += self.add_section('API arg structure', ' ', self.gen_arg_struct) + self.h_content += self.add_section('API output stream', ' ', self.gen_out_stream) + self.h_content += '#endif /* ' + out_macro + ' */\n' - self.add_section('API output stream', ' ', self.gen_out_stream) - self.content += '\n' + self.cpp_content += "/* Generated by " + os.path.basename(__file__) + " */\n" + license + "\n\n" - self.content += '#endif // ' + out_macro + self.cpp_content += '#include \n' + self.cpp_content += '#include \"util/callback_table.h\"\n\n' + self.cpp_content += '#include \n' + self.cpp_content += 'namespace roctracer {\n' + self.cpp_content += 'namespace hsa_support {\n\n' + + self.cpp_content += 'static CoreApiTable CoreApiTable_saved;\n' + self.cpp_content += 'static AmdExtTable AmdExtTable_saved;\n' + self.cpp_content += 'static ImageExtTable ImageExtTable_saved;\n\n' + + self.cpp_content += 'std::atomic hsa_counter_{1};\n' + self.cpp_content += 'static thread_local uint64_t hsa_correlation_id_tls = 0;\n' + + self.cpp_content += self.add_section('API callback functions', '', self.gen_callbacks) + self.cpp_content += self.add_section('API intercepting code', '', self.gen_intercept) + self.cpp_content += self.add_section('API get_name function', ' ', self.gen_get_name) + self.cpp_content += self.add_section('API get_code function', ' ', self.gen_get_code) + self.cpp_content += '\n};};\n' # add code section def add_section(self, title, gap, fun): + content = '' n = 0 - self.content += '\n// section: ' + title + '\n\n' - fun(-1, '-', '-', {}) + content += '\n/* section: ' + title + ' */\n\n' + content += fun(-1, '-', '-', {}) for index in range(len(self.api_names)): last = (index == len(self.api_names) - 1) name = self.api_names[index] if n != 0: - if gap == '': fun(n, name, '-', {}) - self.content += '\n' - self.content += gap + '// block: ' + name + ' API\n' + if gap == '': content += fun(n, name, '-', {}) + content += '\n' + content += gap + '/* block: ' + name + ' API */\n' for call in self.api_calls[name]: - fun(n, name, call, self.api_data[call]) + content += fun(n, name, call, self.api_data[call]) n += 1 - fun(n, '-', '-', {}) + content += fun(n, '-', '-', {}) + return content # generate API ID enumeration def gen_id_enum(self, n, name, call, data): + content = '' if n == -1: - self.content += 'enum hsa_api_id_t {\n' - return + content += 'enum hsa_api_id_t {\n' + return content if call != '-': - self.content += ' ' + self.api_id[call] + ' = ' + str(n) + ',\n' + content += ' ' + self.api_id[call] + ' = ' + str(n) + ',\n' else: - self.content += '\n' - self.content += ' HSA_API_ID_DISPATCH = ' + str(n) + ',\n' - self.content += ' HSA_API_ID_NUMBER = ' + str(n + 1) + ',\n' - self.content += '};\n' + content += '\n' + content += ' HSA_API_ID_DISPATCH = ' + str(n) + ',\n' + content += ' HSA_API_ID_NUMBER = ' + str(n + 1) + ',\n' + content += '};\n' + return content # generate API args structure def gen_arg_struct(self, n, name, call, struct): + content = '' if n == -1: - self.content += 'struct hsa_api_data_t {\n' - self.content += ' uint64_t correlation_id;\n' - self.content += ' uint32_t phase;\n' - self.content += ' union {\n' + content += 'struct hsa_api_data_t {\n' + content += ' uint64_t correlation_id;\n' + content += ' uint32_t phase;\n' + content += ' union {\n' for ret_type in self.api_rettypes: - self.content += ' ' + ret_type + ' ' + ret_type + '_retval;\n' - self.content += ' };\n' - self.content += ' union {\n' - return + content += ' ' + ret_type + ' ' + ret_type + '_retval;\n' + content += ' };\n' + content += ' union {\n' + return content if call != '-': - self.content += ' struct {\n' + content += ' struct {\n' for (var, item) in struct['astr'].items(): - self.content += ' ' + item + ';\n' + content += ' ' + item + ';\n' if call == "hsa_amd_memory_async_copy_rect" and item == "const hsa_dim3_t* range": - self.content += ' hsa_dim3_t range__val;\n' - self.content += ' } ' + call + ';\n' + content += ' hsa_dim3_t range__val;\n' + content += ' } ' + call + ';\n' else: - self.content += ' } args;\n' - self.content += '};\n' + content += ' } args;\n' + content += '};\n' + return content # generate API callbacks def gen_callbacks(self, n, name, call, struct): + content = '' if n == -1: - self.content += 'typedef util::CallbackTable cb_table_t;\n' - self.content += 'extern cb_table_t cb_table;\n' - self.content += '\n' + content += 'static util::CallbackTable cb_table;\n' + content += '\n' if call != '-': call_id = self.api_id[call]; ret_type = struct['ret'] - self.content += 'static ' + ret_type + ' ' + call + '_callback(' + struct['args'] + ') {\n' - self.content += ' hsa_api_data_t api_data{};\n' + content += 'static ' + ret_type + ' ' + call + '_callback(' + struct['args'] + ') {\n' + content += ' hsa_api_data_t api_data{};\n' for var in struct['alst']: item = struct['astr'][var]; if re.search(r'char\* ', item): - self.content += ' api_data.args.' + call + '.' + var + ' = ' + '(' + var + ' != NULL) ? strdup(' + var + ')' + ' : NULL;\n' + content += ' api_data.args.' + call + '.' + var + ' = ' + '(' + var + ' != NULL) ? strdup(' + var + ')' + ' : NULL;\n' else: - self.content += ' api_data.args.' + call + '.' + var + ' = ' + var + ';\n' + content += ' api_data.args.' + call + '.' + var + ' = ' + var + ';\n' if call == 'hsa_amd_memory_async_copy_rect' and var == 'range': - self.content += ' api_data.args.' + call + '.' + var + '__val = ' + '*(' + var + ');\n' - self.content += ' auto [ api_callback_fun, api_callback_arg ] = cb_table.Get(' + call_id + ');\n' - self.content += ' api_data.phase = 0;\n' - self.content += ' api_data.correlation_id = hsa_support::hsa_counter_.fetch_add(1, std::memory_order_relaxed);\n' - self.content += ' hsa_correlation_id_tls = api_data.correlation_id;\n' - self.content += ' if (api_callback_fun) api_callback_fun(ACTIVITY_DOMAIN_HSA_API, ' + call_id + ', &api_data, api_callback_arg);\n' + content += ' api_data.args.' + call + '.' + var + '__val = ' + '*(' + var + ');\n' + content += ' auto [ api_callback_fun, api_callback_arg ] = cb_table.Get(' + call_id + ');\n' + content += ' api_data.phase = 0;\n' + content += ' api_data.correlation_id = hsa_support::hsa_counter_.fetch_add(1, std::memory_order_relaxed);\n' + content += ' hsa_correlation_id_tls = api_data.correlation_id;\n' + content += ' if (api_callback_fun) api_callback_fun(ACTIVITY_DOMAIN_HSA_API, ' + call_id + ', &api_data, api_callback_arg);\n' if ret_type != 'void': - self.content += ' ' + ret_type + ' ret =' - self.content += ' ' + name + '_saved.' + call + '_fn(' + ', '.join(struct['alst']) + ');\n' + content += ' ' + ret_type + ' ret =' + content += ' ' + name + '_saved.' + call + '_fn(' + ', '.join(struct['alst']) + ');\n' if ret_type != 'void': - self.content += ' api_data.' + ret_type + '_retval = ret;\n' - self.content += ' api_data.phase = 1;\n' - self.content += ' if (api_callback_fun) api_callback_fun(ACTIVITY_DOMAIN_HSA_API, ' + call_id + ', &api_data, api_callback_arg);\n' + content += ' api_data.' + ret_type + '_retval = ret;\n' + content += ' api_data.phase = 1;\n' + content += ' if (api_callback_fun) api_callback_fun(ACTIVITY_DOMAIN_HSA_API, ' + call_id + ', &api_data, api_callback_arg);\n' if ret_type != 'void': - self.content += ' return ret;\n' - self.content += '}\n' + content += ' return ret;\n' + content += '}\n' + return content # generate API intercepting code def gen_intercept(self, n, name, call, struct): + content = '' if n > 0 and call == '-': - self.content += '};\n' + content += '};\n' if n == 0 or (call == '-' and name != '-'): - self.content += 'static void intercept_' + name + '(' + name + '* table) {\n' - self.content += ' ' + name + '_saved = *table;\n' + content += 'static void intercept_' + name + '(' + name + '* table) {\n' + content += ' ' + name + '_saved = *table;\n' if call != '-': if call != 'hsa_shut_down': - self.content += ' table->' + call + '_fn = ' + call + '_callback;\n' + content += ' table->' + call + '_fn = ' + call + '_callback;\n' else: - self.content += ' { void* p = (void*)' + call + '_callback; (void)p; }\n' + content += ' { void* p = (void*)' + call + '_callback; (void)p; }\n' + return content # generate API name function def gen_get_name(self, n, name, call, struct): + content = '' if n == -1: - self.content += 'static const char* GetApiName(const uint32_t& id) {\n' - self.content += ' switch (id) {\n' - return + content += 'static const char* GetApiName(const uint32_t& id) {\n' + content += ' switch (id) {\n' + return content if call != '-': - self.content += ' case ' + self.api_id[call] + ': return "' + call + '";\n' + content += ' case ' + self.api_id[call] + ': return "' + call + '";\n' else: - self.content += ' }\n' - self.content += ' return "unknown";\n' - self.content += '}\n' + content += ' }\n' + content += ' return "unknown";\n' + content += '}\n' + return content # generate API code function def gen_get_code(self, n, name, call, struct): + content = '' if n == -1: - self.content += 'static uint32_t GetApiCode(const char* str) {\n' - return + content += 'static uint32_t GetApiCode(const char* str) {\n' + return content if call != '-': - self.content += ' if (strcmp("' + call + '", str) == 0) return ' + self.api_id[call] + ';\n' + content += ' if (strcmp("' + call + '", str) == 0) return ' + self.api_id[call] + ';\n' else: - self.content += ' return HSA_API_ID_NUMBER;\n' - self.content += '}\n' + content += ' return HSA_API_ID_NUMBER;\n' + content += '}\n' + return content # generate stream operator def gen_out_stream(self, n, name, call, struct): + content = '' if n == -1: - self.content += '#ifdef __cplusplus\n' - self.content += 'typedef std::pair hsa_api_data_pair_t;\n' - self.content += 'inline std::ostream& operator<< (std::ostream& out, const hsa_api_data_pair_t& data_pair) {\n' - self.content += ' const uint32_t cid = data_pair.first;\n' - self.content += ' const hsa_api_data_t& api_data = data_pair.second;\n' - self.content += ' switch(cid) {\n' - return + content += '#ifdef __cplusplus\n' + content += 'typedef std::pair hsa_api_data_pair_t;\n' + content += 'inline std::ostream& operator<< (std::ostream& out, const hsa_api_data_pair_t& data_pair) {\n' + content += ' const uint32_t cid = data_pair.first;\n' + content += ' const hsa_api_data_t& api_data = data_pair.second;\n' + content += ' switch(cid) {\n' + return content if call != '-': - self.content += ' case ' + self.api_id[call] + ': {\n' - self.content += ' out << "' + call + '(";\n' + content += ' case ' + self.api_id[call] + ': {\n' + content += ' out << "' + call + '(";\n' arg_list = struct['alst'] if len(arg_list) != 0: for ind in range(len(arg_list)): arg_var = arg_list[ind] arg_val = 'api_data.args.' + call + '.' + arg_var if re.search(r'char\* ', struct['astr'][arg_var]): - self.content += ' out << "0x" << std::hex << (uint64_t)' + arg_val + content += ' out << "0x" << std::hex << (uint64_t)' + arg_val else: - self.content += ' out << ' + arg_val + content += ' out << ' + arg_val if call == "hsa_amd_memory_async_copy_rect" and arg_var == "range": - self.content += ' << ", ";\n' - self.content += ' out << ' + arg_val + '__val' + content += ' << ", ";\n' + content += ' out << ' + arg_val + '__val' ''' arg_item = struct['tlst'][ind] if re.search(r'\(\* ', arg_item): arg_pref = '' @@ -501,26 +515,27 @@ class API_DescrParser: elif re.search(r'\* ', arg_item): arg_pref = '*' else: arg_pref = '' if arg_pref != '': - self.content += ' if (' + arg_val + ') out << ' + arg_pref + '(' + arg_val + '); else out << ' + arg_val + content += ' if (' + arg_val + ') out << ' + arg_pref + '(' + arg_val + '); else out << ' + arg_val else: - self.content += ' out << ' + arg_val + content += ' out << ' + arg_val ''' - if ind < len(arg_list) - 1: self.content += ' << ", ";\n' - else: self.content += ';\n' + if ind < len(arg_list) - 1: content += ' << ", ";\n' + else: content += ';\n' if struct['ret'] != 'void': - self.content += ' out << ") = " << api_data.' + struct['ret'] + '_retval;\n' + content += ' out << ") = " << api_data.' + struct['ret'] + '_retval;\n' else: - self.content += ' out << ") = void";\n' - self.content += ' break;\n' - self.content += ' }\n' + content += ' out << ") = void";\n' + content += ' break;\n' + content += ' }\n' else: - self.content += ' default:\n' - self.content += ' out << "ERROR: unknown API";\n' - self.content += ' abort();\n' - self.content += ' }\n' - self.content += ' return out;\n' - self.content += '}\n' - self.content += '#endif\n' + content += ' default:\n' + content += ' out << "ERROR: unknown API";\n' + content += ' abort();\n' + content += ' }\n' + content += ' return out;\n' + content += '}\n' + content += '#endif\n' + return content ############################################################# # main @@ -532,11 +547,17 @@ else: PREFIX = sys.argv[1] + '/' HSA_DIR = sys.argv[2] + '/' -descr = API_DescrParser(OUT, HSA_DIR, API_TABLES_H, API_HEADERS_H, LICENSE) +descr = API_DescrParser(H_OUT, HSA_DIR, API_TABLES_H, API_HEADERS_H, LICENSE) -out_file = PREFIX + OUT +out_file = PREFIX + H_OUT print ('Generating "' + out_file + '"') f = open(out_file, 'w') -f.write(descr.content[:-1]) +f.write(descr.h_content[:-1]) +f.close() + +out_file = PREFIX + CPP_OUT +print ('Generating "' + out_file + '"') +f = open(out_file, 'w') +f.write(descr.cpp_content[:-1]) f.close() ############################################################# diff --git a/projects/roctracer/src/CMakeLists.txt b/projects/roctracer/src/CMakeLists.txt index 7eacf5d931..11568f9e45 100644 --- a/projects/roctracer/src/CMakeLists.txt +++ b/projects/roctracer/src/CMakeLists.txt @@ -54,12 +54,12 @@ get_filename_component(HSA_RUNTIME_INC_PATH ${HSA_H} DIRECTORY) ## Generate the HSA wrapper functions header add_custom_command( - OUTPUT hsa_prof_str.h + OUTPUT hsa_prof_str.h hsa_prof_str.inline.h COMMAND ${Python3_EXECUTABLE} ${PROJECT_SOURCE_DIR}/script/hsaap.py ${CMAKE_CURRENT_BINARY_DIR} "${HSA_RUNTIME_INC_PATH}" > /dev/null DEPENDS ${PROJECT_SOURCE_DIR}/script/hsaap.py "${HSA_RUNTIME_INC_PATH}/hsa.h" "${HSA_RUNTIME_INC_PATH}/hsa_ext_amd.h" "${HSA_RUNTIME_INC_PATH}/hsa_ext_image.h" "${HSA_RUNTIME_INC_PATH}/hsa_api_trace.h" - COMMENT "Generating hsa_prof_str.h...") + COMMENT "Generating hsa_prof_str.h,hsa_prof_str.inline.h...") ## Generate the HSA pretty printers add_custom_command( @@ -122,7 +122,7 @@ endforeach() ## Build the ROCtracer library file(GLOB ROCTRACER_SOURCES "roctracer/*.cpp" "util/*.cpp") -add_library(roctracer ${LIBRARY_TYPE} ${ROCTRACER_SOURCES} ${GENERATED_HEADERS}) +add_library(roctracer ${LIBRARY_TYPE} ${ROCTRACER_SOURCES} ${GENERATED_HEADERS} hsa_prof_str.inline.h) set_target_properties(roctracer PROPERTIES CXX_VISIBILITY_PRESET hidden diff --git a/projects/roctracer/src/roctracer/roctracer.cpp b/projects/roctracer/src/roctracer/roctracer.cpp index 2c3ca4958e..c7630def9b 100644 --- a/projects/roctracer/src/roctracer/roctracer.cpp +++ b/projects/roctracer/src/roctracer/roctracer.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -43,6 +44,8 @@ #include "exception.h" #include "util/logger.h" +#include "hsa_prof_str.inline.h" + #define CHECK_HSA_STATUS(msg, status) \ do { \ if ((status) != HSA_STATUS_SUCCESS) { \ @@ -124,17 +127,9 @@ void RestoreHsaApi() { table->amd_ext_->hsa_amd_memory_async_copy_rect_fn = hsa_amd_memory_async_copy_rect_fn; } -// callbacks table -cb_table_t cb_table; // async copy activity callback bool async_copy_callback_enabled = false; MemoryPool* async_copy_callback_memory_pool = nullptr; -// Table of function pointers to HSA Core Runtime -CoreApiTable CoreApiTable_saved{}; -// Table of function pointers to AMD extensions -AmdExtTable AmdExtTable_saved{}; -// Table of function pointers to HSA Image Extension -ImageExtTable ImageExtTable_saved{}; } // namespace hsa_support