diff --git a/.github/workflows/ubuntu-focal.yml b/.github/workflows/ubuntu-focal.yml index 032bfac2d3..035c5d6509 100644 --- a/.github/workflows/ubuntu-focal.yml +++ b/.github/workflows/ubuntu-focal.yml @@ -54,7 +54,7 @@ jobs: -DOMNITRACE_USE_MPI=${USE_MPI} -DOMNITRACE_USE_HIP=OFF -DOMNITRACE_USE_PYTHON=ON - -DOMNITRACE_USE_OMPT=OFF + -DOMNITRACE_USE_OMPT=ON -DDYNINST_BUILD_ELFUTILS=ON -DDYNINST_BUILD_LIBIBERTY=ON -DDYNINST_BUILD_SHARED_LIBS=ON diff --git a/cmake/ConfigCPack.cmake b/cmake/ConfigCPack.cmake index 71c734da66..0f49ed7ae6 100644 --- a/cmake/ConfigCPack.cmake +++ b/cmake/ConfigCPack.cmake @@ -186,7 +186,7 @@ endif() string(REPLACE ";" ", " _DEBIAN_PACKAGE_DEPENDS "${_DEBIAN_PACKAGE_DEPENDS}") set(CPACK_DEBIAN_PACKAGE_DEPENDS "${_DEBIAN_PACKAGE_DEPENDS}" - CACHE STRING "Debian package dependencies") + CACHE STRING "Debian package dependencies" FORCE) omnitrace_add_feature(CPACK_DEBIAN_PACKAGE_DEPENDS "Debian package dependencies") set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT") diff --git a/cmake/MacroUtilities.cmake b/cmake/MacroUtilities.cmake index b709a90e56..488b5fccc0 100644 --- a/cmake/MacroUtilities.cmake +++ b/cmake/MacroUtilities.cmake @@ -400,6 +400,24 @@ function(OMNITRACE_ADD_OPTION _NAME _MESSAGE _DEFAULT) endif() endfunction() +# ----------------------------------------------------------------------------------------# +# function omnitrace_report_feature_changes() :: print changes in features +# +function(OMNITRACE_REPORT_FEATURE_CHANGES) + get_property(_features GLOBAL PROPERTY ${PROJECT_NAME}_FEATURES) + if(NOT "${_features}" STREQUAL "") + list(REMOVE_DUPLICATES _features) + list(SORT _features) + endif() + foreach(_feature ${_features}) + if("${ARGN}" STREQUAL "") + omnitrace_watch_for_change(${_feature}) + elseif("${_feature}" IN_LIST ARGN) + omnitrace_watch_for_change(${_feature}) + endif() + endforeach() +endfunction() + # ----------------------------------------------------------------------------------------# # function print_enabled_features() Print enabled features plus their docstrings. # @@ -481,6 +499,7 @@ endfunction() # function print_features() Print all features plus their docstrings. # function(OMNITRACE_PRINT_FEATURES) + omnitrace_report_feature_changes() omnitrace_print_enabled_features() omnitrace_print_disabled_features() endfunction() diff --git a/cmake/Packages.cmake b/cmake/Packages.cmake index 01e4568109..9edd5d8ccd 100644 --- a/cmake/Packages.cmake +++ b/cmake/Packages.cmake @@ -34,8 +34,9 @@ set(OMNITRACE_EXTENSION_LIBRARIES omnitrace::omnitrace-mpi omnitrace::omnitrace-ptl omnitrace::omnitrace-ompt omnitrace::omnitrace-papi) -target_include_directories(omnitrace-headers INTERFACE ${PROJECT_SOURCE_DIR}/include - ${PROJECT_BINARY_DIR}/include) +target_include_directories( + omnitrace-headers INTERFACE ${PROJECT_SOURCE_DIR}/source/lib/omnitrace/include + ${PROJECT_BINARY_DIR}/source/lib/omnitrace/include) # include threading because of rooflines target_link_libraries(omnitrace-headers INTERFACE omnitrace-threading) diff --git a/external/timemory b/external/timemory index 2389cecd50..9ccf9ec9f6 160000 --- a/external/timemory +++ b/external/timemory @@ -1 +1 @@ -Subproject commit 2389cecd50d250bcdb89903468ae28da42ddacda +Subproject commit 9ccf9ec9f648a7a0bb7d0753df44f56d77c4a9a9 diff --git a/scripts/build-release.sh b/scripts/build-release.sh index 8a2bb8a44a..ad507a128c 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -10,6 +10,8 @@ : ${PYTHON_VERSIONS:="6 7 8 9"} : ${GENERATORS:="STGZ DEB RPM"} : ${MPI_IMPL:="openmpi"} +: ${CLEAN:=0} +: ${FRESH:=0} if [ -z "${DISTRO}" ]; then if [ -f /etc/os-release ]; then @@ -65,7 +67,14 @@ build-and-package-base() { local DIR=${1} shift + if [ "${FRESH}" -gt 0 ]; then + verbose-run rm -rf ${BUILD_DIR}/${DIR}/* + fi verbose-run cmake -B ${BUILD_DIR}/${DIR} -DCMAKE_INSTALL_PREFIX=${BUILD_DIR}/${DIR}/install-release ${STANDARD_ARGS} $@ . + if [ "${CLEAN}" -gt 0 ]; then + verbose-run cmake --build ${BUILD_DIR}/${DIR} --target clean + fi + verbose-run cmake --build ${BUILD_DIR}/${DIR} --target all --parallel ${NJOBS} verbose-run cmake --build ${BUILD_DIR}/${DIR} --target all --parallel ${NJOBS} pushd ${BUILD_DIR}/${DIR} verbose-run rm -f *.sh *.deb *.rpm @@ -107,14 +116,14 @@ build-and-package-python() { local DIR=${1} shift + local _PYTHON_ENVS="" for i in ${PYTHON_VERSIONS} do conda activate py3.${i} - _PYTHON_VERS="${_PYTHON_VERS}3.${i};" - _PYTHON_DIRS="${_PYTHON_DIRS}$(dirname $(dirname $(which python)));" + _PYTHON_ENVS="${_PYTHON_ENVS}$(dirname $(dirname $(which python)));" conda deactivate done - build-and-package-base ${DIR}-python $@ -DOMNITRACE_USE_PYTHON=ON -DOMNITRACE_BUILD_PYTHON=ON -DOMNITRACE_PYTHON_VERSIONS=\"${_PYTHON_VERS}\" -DOMNITRACE_PYTHON_ROOT_DIRS=\"${_PYTHON_DIRS}\" + build-and-package-base ${DIR}-python $@ -DOMNITRACE_USE_PYTHON=ON -DOMNITRACE_BUILD_PYTHON=ON -DOMNITRACE_PYTHON_ENVS=\"${_PYTHON_ENVS}\" } build-and-package() @@ -156,6 +165,17 @@ do shift VAL=0 + case "${ARG}" in + --clean) + CLEAN=1 + continue + ;; + --fresh) + FRESH=1 + continue + ;; + esac + while [[ $# -gt 0 ]] do if [ "$1" = "-python" ]; then @@ -190,6 +210,10 @@ do MPI_IMPL=${1} shift ;; + --clean) + CLEAN=1 + shift + ;; *) echo -e "Error! Unknown option : ${ARG}" usage diff --git a/source/bin/omnitrace/omnitrace.cpp b/source/bin/omnitrace/omnitrace.cpp index 737a215d80..7c6ccfd804 100644 --- a/source/bin/omnitrace/omnitrace.cpp +++ b/source/bin/omnitrace/omnitrace.cpp @@ -1367,7 +1367,7 @@ main(int argc, char** argv) } else { - verbprintf(0, "using '%s' and '%s' in lieu of '%s'...", "_init", "_fini", + verbprintf(0, "using '%s' and '%s' in lieu of '%s'...\n", "_init", "_fini", main_fname.c_str()); } } diff --git a/source/lib/omnitrace-dl/dl.cpp b/source/lib/omnitrace-dl/dl.cpp index dcd21345bc..75f3b4843f 100644 --- a/source/lib/omnitrace-dl/dl.cpp +++ b/source/lib/omnitrace-dl/dl.cpp @@ -192,8 +192,9 @@ struct OMNITRACE_HIDDEN_API indirect #if OMNITRACE_USE_OMPT == 0 _warn_verbose = 5; -#endif +#else OMNITRACE_DLSYM(ompt_start_tool_f, m_omnihandle, "ompt_start_tool"); +#endif if(!m_userhandle) m_userhandle = open(m_userlib); _warn_verbose = 0; @@ -251,7 +252,9 @@ public: int (*omnitrace_push_region_f)(const char*) = nullptr; int (*omnitrace_pop_region_f)(const char*) = nullptr; int (*omnitrace_user_configure_f)(int, void*, void*) = nullptr; +#if defined(OMNITRACE_USE_OMPT) && OMNITRACE_USE_OMPT > 0 ompt_start_tool_result_t* (*ompt_start_tool_f)(unsigned int, const char*); +#endif private: void* m_omnihandle = nullptr; @@ -519,17 +522,13 @@ extern "C" return OMNITRACE_DL_INVOKE(get_indirect().omnitrace_pop_region_f, name); } +#if OMNITRACE_USE_OMPT > 0 ompt_start_tool_result_t* ompt_start_tool(unsigned int omp_version, const char* runtime_version) { -#if OMNITRACE_USE_OMPT == 0 - (void) omp_version; - (void) runtime_version; - return nullptr; -#else if(!omnitrace::common::get_env("OMNITRACE_USE_OMPT", true)) return nullptr; return OMNITRACE_DL_INVOKE(get_indirect().ompt_start_tool_f, omp_version, runtime_version); -#endif } +#endif } diff --git a/source/lib/omnitrace-dl/dl.hpp b/source/lib/omnitrace-dl/dl.hpp index afea26fef1..294378fa2a 100644 --- a/source/lib/omnitrace-dl/dl.hpp +++ b/source/lib/omnitrace-dl/dl.hpp @@ -80,9 +80,11 @@ extern "C" int omnitrace_user_push_region_dl(const char*) OMNITRACE_HIDDEN_API; int omnitrace_user_pop_region_dl(const char*) OMNITRACE_HIDDEN_API; +# if OMNITRACE_USE_OMPT > 0 struct ompt_start_tool_result_t; ompt_start_tool_result_t* ompt_start_tool(unsigned int, const char*) OMNITRACE_PUBLIC_API; +# endif #endif } diff --git a/source/lib/omnitrace-user/CMakeLists.txt b/source/lib/omnitrace-user/CMakeLists.txt index e3ed7f5ddd..1fc59d558c 100644 --- a/source/lib/omnitrace-user/CMakeLists.txt +++ b/source/lib/omnitrace-user/CMakeLists.txt @@ -22,20 +22,6 @@ target_include_directories( target_link_libraries(omnitrace-user-library PRIVATE $) -check_cxx_compiler_flag("-fno-exceptions" omnitrace_user_library_fno_exceptions) -check_cxx_compiler_flag("-ftls-model=local-dynamic" - omnitrace_user_library_ftls_module_local_dynamic) - -if(OMNITRACE_BUILD_DEVELOPER) - if(omnitrace_user_library_fno_exceptions) - target_compile_options(omnitrace-user-library PRIVATE -fno-exceptions) - endif() - - if(omnitrace_user_library_ftls_module_local_dynamic) - target_compile_options(omnitrace-user-library PRIVATE -ftls-model=local-dynamic) - endif() -endif() - set_target_properties( omnitrace-user-library PROPERTIES OUTPUT_NAME omnitrace-user diff --git a/source/lib/omnitrace/CMakeLists.txt b/source/lib/omnitrace/CMakeLists.txt index e98a0bafae..cc37a89924 100644 --- a/source/lib/omnitrace/CMakeLists.txt +++ b/source/lib/omnitrace/CMakeLists.txt @@ -25,12 +25,12 @@ target_link_libraries( $ $ $ + $ + $ + $ $ $ $ - $ - $ - $ $,$,> $,$,> $,omnitrace::omnitrace-sanitizer,>) diff --git a/source/lib/omnitrace/include/library/api.hpp b/source/lib/omnitrace/include/library/api.hpp index 71473de9eb..dc29a050b5 100644 --- a/source/lib/omnitrace/include/library/api.hpp +++ b/source/lib/omnitrace/include/library/api.hpp @@ -70,6 +70,7 @@ extern "C" // these are the real implementations for internal calling convention void omnitrace_init_library_hidden(void) OMNITRACE_HIDDEN_API; + bool omnitrace_init_tooling_hidden(void) OMNITRACE_HIDDEN_API; void omnitrace_init_hidden(const char*, bool, const char*) OMNITRACE_HIDDEN_API; void omnitrace_finalize_hidden(void) OMNITRACE_HIDDEN_API; void omnitrace_set_env_hidden(const char* env_name, diff --git a/source/lib/omnitrace/include/library/components/fwd.hpp b/source/lib/omnitrace/include/library/components/fwd.hpp index bc3c341496..cb0d682d28 100644 --- a/source/lib/omnitrace/include/library/components/fwd.hpp +++ b/source/lib/omnitrace/include/library/components/fwd.hpp @@ -52,6 +52,11 @@ TIMEMORY_DECLARE_TYPE_TRAIT(name, typename Tp) { \ static constexpr auto value = NAME; \ }; \ + template <> \ + struct name> \ + { \ + static constexpr auto value = NAME; \ + }; \ } \ } diff --git a/source/lib/omnitrace/include/library/ptl.hpp b/source/lib/omnitrace/include/library/ptl.hpp index d43af73fff..7595064666 100644 --- a/source/lib/omnitrace/include/library/ptl.hpp +++ b/source/lib/omnitrace/include/library/ptl.hpp @@ -32,22 +32,55 @@ namespace omnitrace { namespace tasking { +void +setup(); + +void +join(); + +void +shutdown(); + +//--------------------------------------------------------------------------------------// +// +// roctracer +// +//--------------------------------------------------------------------------------------// + +namespace roctracer +{ std::mutex& -get_roctracer_mutex(); +get_mutex(); PTL::ThreadPool& -get_roctracer_thread_pool(); +get_thread_pool(); PTL::TaskGroup& -get_roctracer_task_group(); +get_task_group(); +bool +get_thread_pool_is_active(); +} // namespace roctracer + +//--------------------------------------------------------------------------------------// +// +// critical trace +// +//--------------------------------------------------------------------------------------// + +namespace critical_trace +{ std::mutex& -get_critical_trace_mutex(); +get_mutex(); PTL::ThreadPool& -get_critical_trace_thread_pool(); +get_thread_pool(); PTL::TaskGroup& -get_critical_trace_task_group(); +get_task_group(); + +bool +get_thread_pool_is_active(); +} // namespace critical_trace } // namespace tasking } // namespace omnitrace diff --git a/source/lib/omnitrace/include/library/thread_data.hpp b/source/lib/omnitrace/include/library/thread_data.hpp index c4e6483660..dc40f5bac2 100644 --- a/source/lib/omnitrace/include/library/thread_data.hpp +++ b/source/lib/omnitrace/include/library/thread_data.hpp @@ -134,8 +134,8 @@ template typename thread_data::instance_array_t& thread_data::instances(construct_on_init, Args&&... _args) { - static auto _v = [&]() { - auto _internal = instance_array_t{}; + static auto& _v = [&]() -> instance_array_t& { + auto& _internal = instances(); for(size_t i = 0; i < MaxThreads; ++i) _internal.at(i) = unique_ptr_t{ new Tp(std::forward(_args)...) }; return _internal; diff --git a/source/lib/omnitrace/src/library.cpp b/source/lib/omnitrace/src/library.cpp index c73dc0633d..0aada61041 100644 --- a/source/lib/omnitrace/src/library.cpp +++ b/source/lib/omnitrace/src/library.cpp @@ -45,6 +45,7 @@ #include using namespace omnitrace; +using tim::type_list; //======================================================================================// @@ -59,17 +60,14 @@ struct user_regions using omni_functors = omnitrace::component::functors; using user_functors = omnitrace::component::functors; -// TIMEMORY_DEFINE_NAME_TRAIT("host", omni_functors); -// TIMEMORY_DEFINE_NAME_TRAIT("user", user_functors); +TIMEMORY_DEFINE_NAME_TRAIT("host", omni_functors); +TIMEMORY_DEFINE_NAME_TRAIT("user", user_functors); TIMEMORY_INVOKE_PREINIT(omni_functors) TIMEMORY_INVOKE_PREINIT(user_functors) //======================================================================================// -extern "C" bool -omnitrace_init_tooling_hidden() OMNITRACE_HIDDEN_API; - namespace { using interval_data_instances = thread_data>; @@ -100,15 +98,14 @@ get_timemory_hash_aliases(int64_t _tid = threading::get_id()) auto ensure_finalization(bool _static_init = false) { - auto _main_tid = threading::get_id(); - (void) _main_tid; + (void) threading::get_id(); if(!_static_init) { OMNITRACE_DEBUG_F("\n"); } else { - OMNITRACE_CONDITIONAL_PRINT_F(get_debug_env(), "\n"); + OMNITRACE_BASIC_DEBUG_F("\n"); // This environment variable forces the ROCR-Runtime to use polling to wait // for signals rather than interrupts. We set this variable to avoid issues with // rocm/roctracer hanging when interrupted by the sampler @@ -522,6 +519,10 @@ omnitrace_init_library_hidden() tim::set_env("KOKKOS_PROFILE_LIBRARY", "libomnitrace.so", _force); } + // recycle all subsequent thread ids + threading::recycle_ids() = + tim::get_env("OMNITRACE_RECYCLE_TIDS", !get_use_sampling()); + #if defined(OMNITRACE_USE_ROCTRACER) && OMNITRACE_USE_ROCTRACER > 0 tim::set_env("HSA_TOOLS_LIB", "libomnitrace.so", 0); #endif @@ -721,27 +722,17 @@ omnitrace_init_tooling_hidden() }; // functors for starting and stopping perfetto omni functors - auto _push_perfetto = [](const char* name) { - uint64_t _ts = comp::wall_clock::record(); - TRACE_EVENT_BEGIN("host", perfetto::StaticString(name), _ts); + auto _push_perfetto = [](auto _category, const char* name) { + using CategoryT = std::decay_t; + uint64_t _ts = comp::wall_clock::record(); + TRACE_EVENT_BEGIN(trait::name::value, perfetto::StaticString(name), + _ts); }; - auto _pop_perfetto = [](const char*) { - uint64_t _ts = comp::wall_clock::record(); - TRACE_EVENT_END("host", _ts); - }; - - // functors for starting and stopping perfetto user functors - auto _push_user_perfetto = [](const char* name) { - uint64_t _ts = comp::wall_clock::record(); - TRACE_EVENT_BEGIN("user", nullptr, _ts, [name](perfetto::EventContext& _ctx) { - _ctx.event()->set_name(name); - }); - }; - - auto _pop_user_perfetto = [](const char*) { - uint64_t _ts = comp::wall_clock::record(); - TRACE_EVENT_END("user", _ts); + auto _pop_perfetto = [](auto _category, const char*) { + using CategoryT = std::decay_t; + uint64_t _ts = comp::wall_clock::record(); + TRACE_EVENT_END(trait::name::value, _ts); }; if(get_use_perfetto() && get_use_timemory()) @@ -749,23 +740,23 @@ omnitrace_init_tooling_hidden() omni_functors::configure( [=](const char* name) { _thread_init(); - _push_perfetto(name); + _push_perfetto(type_list{}, name); _push_timemory(name); _setup_thread_sampling(); }, [=](const char* name) { _pop_timemory(name); - _pop_perfetto(name); + _pop_perfetto(type_list{}, name); }); user_functors::configure( [=](const char* name) { _thread_init(); - _push_user_perfetto(name); + _push_perfetto(type_list{}, name); _push_timemory(name); }, [=](const char* name) { _pop_timemory(name); - _pop_user_perfetto(name); + _pop_perfetto(type_list{}, name); }); } else if(get_use_perfetto()) @@ -773,17 +764,17 @@ omnitrace_init_tooling_hidden() omni_functors::configure( [=](const char* name) { _thread_init(); - _push_perfetto(name); + _push_perfetto(type_list{}, name); _setup_thread_sampling(); }, - [=](const char* name) { _pop_perfetto(name); }); + [=](const char* name) { _pop_perfetto(type_list{}, name); }); user_functors::configure( [=](const char* name) { _thread_init(); - _push_user_perfetto(name); + _push_perfetto(type_list{}, name); _setup_thread_sampling(); }, - [=](const char* name) { _pop_user_perfetto(name); }); + [=](const char* name) { _pop_perfetto(type_list{}, name); }); } else if(get_use_timemory()) { @@ -935,6 +926,9 @@ omnitrace_init_hidden(const char* _mode, bool _is_binary_rewrite, const char* _a extern "C" void omnitrace_finalize_hidden(void) { + // disable thread id recycling during finalization + threading::recycle_ids() = false; + // return if not active if(get_state() != State::Active) { @@ -1062,8 +1056,7 @@ omnitrace_finalize_hidden(void) } // join extra thread(s) used by roctracer - OMNITRACE_DEBUG_F("waiting for all roctracer tasks to complete...\n"); - tasking::get_roctracer_task_group().join(); + tasking::join(); // print out thread-data if they are not still running // if they are still running (e.g. thread-pool still alive), the @@ -1111,7 +1104,7 @@ omnitrace_finalize_hidden(void) { OMNITRACE_DEBUG_F("Generating the critical trace...\n"); // increase the thread-pool size - tasking::get_critical_trace_thread_pool().initialize_threadpool( + tasking::critical_trace::get_thread_pool().initialize_threadpool( get_critical_trace_num_threads()); for(size_t i = 0; i < max_supported_threads; ++i) @@ -1138,15 +1131,14 @@ omnitrace_finalize_hidden(void) if(get_use_critical_trace()) { // make sure outstanding hash tasks completed before compute - OMNITRACE_PRINT_F("waiting for all critical trace tasks to complete...\n"); - tasking::get_critical_trace_task_group().join(); + tasking::join(); // launch compute task OMNITRACE_PRINT_F("launching critical trace compute task...\n"); critical_trace::compute(); } - tasking::get_critical_trace_task_group().join(); + tasking::join(); bool _perfetto_output_error = false; if(get_use_perfetto() && !is_system_backend()) @@ -1200,25 +1192,8 @@ omnitrace_finalize_hidden(void) if(get_verbose() >= 0) fprintf(stderr, "\n"); } - // these should be destroyed before timemory is finalized, especially the - // roctracer thread-pool - OMNITRACE_DEBUG_F("Destroying the roctracer thread pool...\n"); - { - std::unique_lock _lk{ tasking::get_roctracer_mutex() }; - tasking::get_roctracer_task_group().join(); - tasking::get_roctracer_task_group().clear(); - tasking::get_roctracer_task_group().set_pool(nullptr); - tasking::get_roctracer_thread_pool().destroy_threadpool(); - } - - OMNITRACE_DEBUG_F("Destroying the critical trace thread pool...\n"); - { - std::unique_lock _lk{ tasking::get_critical_trace_mutex() }; - tasking::get_critical_trace_task_group().join(); - tasking::get_critical_trace_task_group().clear(); - tasking::get_critical_trace_task_group().set_pool(nullptr); - tasking::get_critical_trace_thread_pool().destroy_threadpool(); - } + // shutdown tasking before timemory is finalized, especially the roctracer thread-pool + tasking::shutdown(); coverage::post_process(); diff --git a/source/lib/omnitrace/src/library/components/roctracer_callbacks.cpp b/source/lib/omnitrace/src/library/components/roctracer_callbacks.cpp index 63468585b8..7dd3ece44a 100644 --- a/source/lib/omnitrace/src/library/components/roctracer_callbacks.cpp +++ b/source/lib/omnitrace/src/library/components/roctracer_callbacks.cpp @@ -253,11 +253,11 @@ hsa_api_callback(uint32_t domain, uint32_t cid, const void* callback_data, void* if(get_use_timemory()) { - std::unique_lock _lk{ tasking::get_roctracer_mutex() }; + std::unique_lock _lk{ tasking::roctracer::get_mutex() }; auto _beg_ns = begin_timestamp; auto _end_ns = end_timestamp; - if(tasking::get_roctracer_task_group().pool()) - tasking::get_roctracer_task_group().exec( + if(tasking::roctracer::get_task_group().pool()) + tasking::roctracer::get_task_group().exec( [_name, _beg_ns, _end_ns]() { roctracer_hsa_bundle_t _bundle{ _name, _scope }; _bundle.start() @@ -324,9 +324,9 @@ hsa_activity_callback(uint32_t op, activity_record_t* record, void* arg) } }; - std::unique_lock _lk{ tasking::get_roctracer_mutex() }; - if(tasking::get_roctracer_task_group().pool()) - tasking::get_roctracer_task_group().exec(_func); + std::unique_lock _lk{ tasking::roctracer::get_mutex() }; + if(tasking::roctracer::get_task_group().pool()) + tasking::roctracer::get_task_group().exec(_func); // timemory is disabled in this callback because collecting data in this thread // causes strange segmentation faults @@ -713,9 +713,6 @@ roctracer_shutdown_routines() using namespace omnitrace; -extern "C" bool -omnitrace_init_tooling_hidden() OMNITRACE_HIDDEN_API; - // HSA-runtime tool on-load method extern "C" { diff --git a/source/lib/omnitrace/src/library/config.cpp b/source/lib/omnitrace/src/library/config.cpp index c7a6ad0744..ae30167a18 100644 --- a/source/lib/omnitrace/src/library/config.cpp +++ b/source/lib/omnitrace/src/library/config.cpp @@ -469,8 +469,8 @@ configure_settings(bool _init) auto _info = ::tim::signal_settings::get_info(static_cast(_v)); OMNITRACE_CONDITIONAL_BASIC_PRINT( - get_verbose_env() > 0 || get_debug_env(), - "signal %s (%i) ignored (OMNITRACE_IGNORE_DYNINST_TRAMPOLINE=ON)", + get_verbose_env() >= 2 || get_debug_env(), + "signal %s (%i) ignored (OMNITRACE_IGNORE_DYNINST_TRAMPOLINE=ON)\n", std::get<0>(_info).c_str(), _v); if(get_verbose_env() > 1 || get_debug_env()) ::tim::print_demangled_backtrace<64>(); diff --git a/source/lib/omnitrace/src/library/critical_trace.cpp b/source/lib/omnitrace/src/library/critical_trace.cpp index 91281a8ac6..a117e08469 100644 --- a/source/lib/omnitrace/src/library/critical_trace.cpp +++ b/source/lib/omnitrace/src/library/critical_trace.cpp @@ -509,9 +509,9 @@ get(int64_t _tid) void add_hash_id(const hash_ids& _labels) { - std::unique_lock _lk{ tasking::get_critical_trace_mutex() }; - if(!tasking::get_critical_trace_task_group().pool()) return; - tasking::get_critical_trace_task_group().exec([_labels]() { + std::unique_lock _lk{ tasking::critical_trace::get_mutex() }; + if(!tasking::critical_trace::get_task_group().pool()) return; + tasking::critical_trace::get_task_group().exec([_labels]() { static std::mutex _mtx{}; _mtx.lock(); for(auto itr : _labels) @@ -539,20 +539,20 @@ void update(int64_t _tid) { if(!get_use_critical_trace() && !get_use_rocm_smi()) return; - std::unique_lock _lk{ tasking::get_critical_trace_mutex() }; - if(!tasking::get_critical_trace_task_group().pool()) return; + std::unique_lock _lk{ tasking::critical_trace::get_mutex() }; + if(!tasking::critical_trace::get_task_group().pool()) return; call_chain _data{}; std::swap(_data, *critical_trace::get(_tid)); - tasking::get_critical_trace_task_group().exec(update_critical_path, _data, _tid); + tasking::critical_trace::get_task_group().exec(update_critical_path, _data, _tid); } void compute(int64_t _tid) { update(_tid); - std::unique_lock _lk{ tasking::get_critical_trace_mutex() }; - if(!tasking::get_critical_trace_task_group().pool()) return; - tasking::get_critical_trace_task_group().exec(compute_critical_trace); + std::unique_lock _lk{ tasking::critical_trace::get_mutex() }; + if(!tasking::critical_trace::get_task_group().pool()) return; + tasking::critical_trace::get_task_group().exec(compute_critical_trace); } //--------------------------------------------------------------------------------------// @@ -825,12 +825,12 @@ get_entries(int64_t _ts, const std::function& _eval) } *_targ = _v; }; - std::unique_lock _lk{ tasking::get_critical_trace_mutex() }; - size_t _n = 0; + std::unique_lock _lk{ tasking::critical_trace::get_mutex() }; + size_t _n = 0; std::vector> _v{}; - if(!tasking::get_critical_trace_task_group().pool()) return _v; - tasking::get_critical_trace_task_group().exec(_func, &_v, &_n); - tasking::get_critical_trace_task_group().join(); + if(!tasking::critical_trace::get_task_group().pool()) return _v; + tasking::critical_trace::get_task_group().exec(_func, &_v, &_n); + tasking::critical_trace::get_task_group().join(); OMNITRACE_DEBUG("critical_trace::%s :: found %zu out of %zu entries at %li...\n", __FUNCTION__, _v.size(), _n, _ts); return _v; diff --git a/source/lib/omnitrace/src/library/kokkosp.cpp b/source/lib/omnitrace/src/library/kokkosp.cpp index 2bb76ce9e1..3959b55099 100644 --- a/source/lib/omnitrace/src/library/kokkosp.cpp +++ b/source/lib/omnitrace/src/library/kokkosp.cpp @@ -24,7 +24,8 @@ #define TIMEMORY_KOKKOSP_POSTFIX OMNITRACE_PUBLIC_API -#include "library/components/omnitrace.hpp" +#include "library/api.hpp" +#include "library/components/user_region.hpp" #include "library/config.hpp" #include "library/debug.hpp" @@ -68,13 +69,36 @@ setup_kernel_logger() } // namespace +namespace +{ +bool _standalone_initialized = false; +std::vector _initialize_arguments = {}; +} // namespace + //--------------------------------------------------------------------------------------// extern "C" { void kokkosp_print_help(char*) {} - void kokkosp_parse_args(int, char**) {} + void kokkosp_parse_args(int argc, char** argv) + { + if(!omnitrace::config::settings_are_configured() && + omnitrace::get_state() < omnitrace::State::Active) + { + _standalone_initialized = true; + + OMNITRACE_BASIC_VERBOSE_F(0, "Parsing arguments...\n"); + std::string _command_line = {}; + for(int i = 0; i < argc; ++i) + { + _initialize_arguments.emplace_back(argv[i]); + _command_line.append(" ").append(argv[i]); + } + if(_command_line.length() > 1) _command_line = _command_line.substr(1); + tim::set_env("OMNITRACE_COMMAND_LINE", _command_line, 0); + } + } void kokkosp_declare_metadata(const char* key, const char* value) { @@ -86,6 +110,20 @@ extern "C" { tim::consume_parameters(devInfoCount, deviceInfo); + if(_standalone_initialized || (!omnitrace::config::settings_are_configured() && + omnitrace::get_state() < omnitrace::State::Active)) + { + OMNITRACE_BASIC_VERBOSE_F(0, "Initializing omnitrace...\n"); + auto _mode = tim::get_env("OMNITRACE_MODE", "trace"); + auto _arg0 = (_initialize_arguments.empty()) ? std::string{ "unknown" } + : _initialize_arguments.at(0); + + _standalone_initialized = true; + omnitrace_set_mpi_hidden(false, false); + omnitrace_init_hidden(_mode.c_str(), false, _arg0.c_str()); + omnitrace_push_trace("kokkos_main"); + } + OMNITRACE_VERBOSE_F(0, "Initializing connector (sequence is %d, version: %llu)...", loadSeq, (unsigned long long) interfaceVer); @@ -100,11 +138,18 @@ extern "C" void kokkosp_finalize_library() { - OMNITRACE_VERBOSE_F(0, "Finalizing connector... \n"); - - kokkosp::cleanup(); - - if(omnitrace::get_verbose() >= 0) fprintf(stderr, "Done\n"); + if(_standalone_initialized) + { + omnitrace_pop_trace("kokkos_main"); + OMNITRACE_VERBOSE_F(0, "Finalizing connector (standalone)...\n"); + omnitrace_finalize_hidden(); + } + else + { + OMNITRACE_VERBOSE_F(0, "Finalizing connector... "); + kokkosp::cleanup(); + if(omnitrace::get_verbose() >= 0) fprintf(stderr, "Done\n"); + } } //----------------------------------------------------------------------------------// @@ -117,15 +162,15 @@ extern "C" : TIMEMORY_JOIN(" ", TIMEMORY_JOIN("", "[kokkos][dev", devid, ']'), name); *kernid = kokkosp::get_unique_id(); kokkosp::logger_t{}.mark(1, __FUNCTION__, name, *kernid); - kokkosp::create_profiler(pname, *kernid); - kokkosp::start_profiler(*kernid); + kokkosp::create_profiler(pname, *kernid); + kokkosp::start_profiler(*kernid); } void kokkosp_end_parallel_for(uint64_t kernid) { kokkosp::logger_t{}.mark(-1, __FUNCTION__, kernid); - kokkosp::stop_profiler(kernid); - kokkosp::destroy_profiler(kernid); + kokkosp::stop_profiler(kernid); + kokkosp::destroy_profiler(kernid); } //----------------------------------------------------------------------------------// @@ -138,15 +183,15 @@ extern "C" : TIMEMORY_JOIN(" ", TIMEMORY_JOIN("", "[kokkos][dev", devid, ']'), name); *kernid = kokkosp::get_unique_id(); kokkosp::logger_t{}.mark(1, __FUNCTION__, name, *kernid); - kokkosp::create_profiler(pname, *kernid); - kokkosp::start_profiler(*kernid); + kokkosp::create_profiler(pname, *kernid); + kokkosp::start_profiler(*kernid); } void kokkosp_end_parallel_reduce(uint64_t kernid) { kokkosp::logger_t{}.mark(-1, __FUNCTION__, kernid); - kokkosp::stop_profiler(kernid); - kokkosp::destroy_profiler(kernid); + kokkosp::stop_profiler(kernid); + kokkosp::destroy_profiler(kernid); } //----------------------------------------------------------------------------------// @@ -159,15 +204,15 @@ extern "C" : TIMEMORY_JOIN(" ", TIMEMORY_JOIN("", "[kokkos][dev", devid, ']'), name); *kernid = kokkosp::get_unique_id(); kokkosp::logger_t{}.mark(1, __FUNCTION__, name, *kernid); - kokkosp::create_profiler(pname, *kernid); - kokkosp::start_profiler(*kernid); + kokkosp::create_profiler(pname, *kernid); + kokkosp::start_profiler(*kernid); } void kokkosp_end_parallel_scan(uint64_t kernid) { kokkosp::logger_t{}.mark(-1, __FUNCTION__, kernid); - kokkosp::stop_profiler(kernid); - kokkosp::destroy_profiler(kernid); + kokkosp::stop_profiler(kernid); + kokkosp::destroy_profiler(kernid); } //----------------------------------------------------------------------------------// @@ -180,15 +225,15 @@ extern "C" : TIMEMORY_JOIN(" ", TIMEMORY_JOIN("", "[kokkos][dev", devid, ']'), name); *kernid = kokkosp::get_unique_id(); kokkosp::logger_t{}.mark(1, __FUNCTION__, name, *kernid); - kokkosp::create_profiler(pname, *kernid); - kokkosp::start_profiler(*kernid); + kokkosp::create_profiler(pname, *kernid); + kokkosp::start_profiler(*kernid); } void kokkosp_end_fence(uint64_t kernid) { kokkosp::logger_t{}.mark(-1, __FUNCTION__, kernid); - kokkosp::stop_profiler(kernid); - kokkosp::destroy_profiler(kernid); + kokkosp::stop_profiler(kernid); + kokkosp::destroy_profiler(kernid); } //----------------------------------------------------------------------------------// @@ -196,17 +241,18 @@ extern "C" void kokkosp_push_profile_region(const char* name) { kokkosp::logger_t{}.mark(1, __FUNCTION__, name); - kokkosp::get_profiler_stack().push_back( - kokkosp::profiler_t(name)); - kokkosp::get_profiler_stack().back().start(); + kokkosp::get_profiler_stack().push_back( + kokkosp::profiler_t(name)); + kokkosp::get_profiler_stack().back().start(); } void kokkosp_pop_profile_region() { kokkosp::logger_t{}.mark(-1, __FUNCTION__); - if(kokkosp::get_profiler_stack().empty()) return; - kokkosp::get_profiler_stack().back().stop(); - kokkosp::get_profiler_stack().pop_back(); + if(kokkosp::get_profiler_stack().empty()) + return; + kokkosp::get_profiler_stack().back().stop(); + kokkosp::get_profiler_stack().pop_back(); } //----------------------------------------------------------------------------------// @@ -215,12 +261,12 @@ extern "C" { *secid = kokkosp::get_unique_id(); auto pname = TIMEMORY_JOIN(" ", "[kokkos]", name); - kokkosp::create_profiler(pname, *secid); + kokkosp::create_profiler(pname, *secid); } void kokkosp_destroy_profile_section(uint32_t secid) { - kokkosp::destroy_profiler(secid); + kokkosp::destroy_profiler(secid); } //----------------------------------------------------------------------------------// @@ -228,13 +274,13 @@ extern "C" void kokkosp_start_profile_section(uint32_t secid) { kokkosp::logger_t{}.mark(1, __FUNCTION__, secid); - kokkosp::start_profiler(secid); + kokkosp::start_profiler(secid); } void kokkosp_stop_profile_section(uint32_t secid) { kokkosp::logger_t{}.mark(-1, __FUNCTION__, secid); - kokkosp::start_profiler(secid); + kokkosp::start_profiler(secid); } //----------------------------------------------------------------------------------// @@ -273,7 +319,7 @@ extern "C" TIMEMORY_JOIN('=', dst_handle.name, dst_name), TIMEMORY_JOIN('=', src_handle.name, src_name)); - auto& _data = kokkosp::get_profiler_stack(); + auto& _data = kokkosp::get_profiler_stack(); _data.emplace_back(name); _data.back().audit(dst_handle, dst_name, dst_ptr, src_handle, src_name, src_ptr, size); @@ -284,7 +330,7 @@ extern "C" void kokkosp_end_deep_copy() { kokkosp::logger_t{}.mark(-1, __FUNCTION__); - auto& _data = kokkosp::get_profiler_stack(); + auto& _data = kokkosp::get_profiler_stack(); if(_data.empty()) return; _data.back().store(std::minus{}, 0); _data.back().stop(); @@ -295,7 +341,7 @@ extern "C" void kokkosp_profile_event(const char* name) { - kokkosp::profiler_t{}.mark(name); + kokkosp::profiler_t{}.mark(name); } //----------------------------------------------------------------------------------// diff --git a/source/lib/omnitrace/src/library/ompt.cpp b/source/lib/omnitrace/src/library/ompt.cpp index f1e760925a..a1b7630afa 100644 --- a/source/lib/omnitrace/src/library/ompt.cpp +++ b/source/lib/omnitrace/src/library/ompt.cpp @@ -24,7 +24,7 @@ #include -#if defined(TIMEMORY_USE_OMPT) +#if defined(OMNITRACE_USE_OMPT) && OMNITRACE_USE_OMPT > 0 # include "library/components/fwd.hpp" # include "library/components/user_region.hpp" diff --git a/source/lib/omnitrace/src/library/ptl.cpp b/source/lib/omnitrace/src/library/ptl.cpp index a2cf9d98a6..26dedca112 100644 --- a/source/lib/omnitrace/src/library/ptl.cpp +++ b/source/lib/omnitrace/src/library/ptl.cpp @@ -53,45 +53,119 @@ auto _thread_pool_cfg = []() { }(); } +namespace roctracer +{ +namespace +{ +auto& +get_thread_pool_state() +{ + static auto _v = State::PreInit; + return _v; +} +} // namespace +} // namespace roctracer + +namespace critical_trace +{ +namespace +{ +auto& +get_thread_pool_state() +{ + static auto _v = State::PreInit; + return _v; +} +} // namespace +} // namespace critical_trace + +void +setup() +{} + +void +join() +{ + if(roctracer::get_thread_pool_state() == State::Active) + { + OMNITRACE_DEBUG_F("waiting for all roctracer tasks to complete...\n"); + tasking::roctracer::get_task_group().join(); + } + + if(critical_trace::get_thread_pool_state() == State::Active) + { + OMNITRACE_DEBUG_F("waiting for all critical tasks to complete...\n"); + tasking::critical_trace::get_task_group().join(); + } +} + +void +shutdown() +{ + if(roctracer::get_thread_pool_state() == State::Active) + { + OMNITRACE_DEBUG_F("Destroying the roctracer thread pool...\n"); + std::unique_lock _lk{ roctracer::get_mutex() }; + roctracer::get_task_group().join(); + roctracer::get_task_group().clear(); + roctracer::get_task_group().set_pool(nullptr); + roctracer::get_thread_pool().destroy_threadpool(); + roctracer::get_thread_pool_state() = State::Finalized; + } + + if(critical_trace::get_thread_pool_state() == State::Active) + { + OMNITRACE_DEBUG_F("Destroying the critical trace thread pool...\n"); + std::unique_lock _lk{ critical_trace::get_mutex() }; + critical_trace::get_task_group().join(); + critical_trace::get_task_group().clear(); + critical_trace::get_task_group().set_pool(nullptr); + critical_trace::get_thread_pool().destroy_threadpool(); + critical_trace::get_thread_pool_state() = State::Finalized; + } +} + std::mutex& -get_roctracer_mutex() +roctracer::get_mutex() { static std::mutex _v{}; return _v; } PTL::ThreadPool& -get_roctracer_thread_pool() +roctracer::get_thread_pool() { - static auto _v = PTL::ThreadPool{ _thread_pool_cfg }; + static auto _v = (roctracer::get_thread_pool_state() = State::Active, + PTL::ThreadPool{ _thread_pool_cfg }); return _v; } PTL::TaskGroup& -get_roctracer_task_group() +roctracer::get_task_group() { - static PTL::TaskGroup _v{ &get_roctracer_thread_pool() }; + static PTL::TaskGroup _v{ &roctracer::get_thread_pool() }; return _v; } std::mutex& -get_critical_trace_mutex() +critical_trace::get_mutex() { static std::mutex _v{}; return _v; } PTL::ThreadPool& -get_critical_trace_thread_pool() +critical_trace::get_thread_pool() { - static auto _v = PTL::ThreadPool{ _thread_pool_cfg }; + static auto _v = (critical_trace::get_thread_pool_state() = State::Active, + PTL::ThreadPool{ _thread_pool_cfg }); return _v; } PTL::TaskGroup& -get_critical_trace_task_group() +critical_trace::get_task_group() { - static PTL::TaskGroup _v{ &get_critical_trace_thread_pool() }; + static PTL::TaskGroup _v{ &critical_trace::get_thread_pool() }; return _v; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 855bac3827..06f5c4b3d9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -448,7 +448,8 @@ omnitrace_add_test( [==[lib(gomp|m-)]==] RUN_ARGS -i 10 -s 20 -p ENVIRONMENT - "${_base_environment};OMNITRACE_CRITICAL_TRACE=OFF;OMNITRACE_USE_KOKKOSP=OFF") + "${_base_environment};OMNITRACE_CRITICAL_TRACE=OFF;OMNITRACE_USE_KOKKOSP=ON;KOKKOS_PROFILE_LIBRARY=libomnitrace.so" + ) omnitrace_add_test( SKIP_BASELINE