User API + reorganized lib folders (#30)
* User API + reorganized lib folders - omnitrace_user_start_trace - omnitrace_user_stop_trace - omnitrace_user_start_thread_trace - omnitrace_user_stop_thread_trace - omnitrace_user_push_region - omnitrace_user_pop_region * New OpenMP examples/tests * Fix to KokkosP * OMPT support - fixed omnitrace instrumenting reporting - common invoke improvements - component::user_region * exclude kmp_threadprivate_ * Separate omnitrace into multiple files * PTL and timemory submodule updates * Active guards + USE_OMPT guards in omnitrace-dl * Tweak transpose default iterations * omnitrace-precommit build target * Omnitrace exe restructuring pt 2 - Never instrument functions with less than 4 instructions - Never instrument ompt_start_tool or nanosleep - module_function serializes heuristics - removed hash stuff from omnitrace - removed instr_procedures lambda - WAITPID_DEBUG_MESSAGE * set_state, "_hidden" fix, CI exceptions, backtrace fix - set_state function - fixed "_hidden" from appearing in print macros using __FUNCTION__ - OMNITRACE_CI_THROW - more CI checks in library - fixed backtrace init value sample issue being ignored * Tweaks to OMPT tests * cmake-formatting * Removed debug output from backtrace processing * Fix warnings and verbosity * omnitrace-dl fix for libomp * omnitrace-avail fixes - remove second omnitrace_init_library call - fix -r option not working * Additional testing - source/bin/tests - tests for omnitrace-exe - tests for omnitrace-avail * cmake-format * Reduce runtime of openmp-lu * Update openmp-lu and tests timeout * openmp-lu and CI tweaks - decrease iterations - OMP_NUM_THREADS=2 - install clang and libomp-dev in linux-ci - fix data-files in linux-ci
This commit is contained in:
committed by
GitHub
parent
2acaa7aa9f
commit
d80752bc69
+9
-181
@@ -1,186 +1,14 @@
|
||||
# ------------------------------------------------------------------------------#
|
||||
# ----------------------------------------------------------------------------- #
|
||||
#
|
||||
# omnitrace interface library
|
||||
# omnitrace: contains all instrumentation functionality
|
||||
#
|
||||
# ------------------------------------------------------------------------------#
|
||||
|
||||
add_library(omnitrace-interface-library INTERFACE)
|
||||
add_library(omnitrace::omnitrace-interface-library ALIAS omnitrace-interface-library)
|
||||
|
||||
target_include_directories(
|
||||
omnitrace-interface-library INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
target_include_directories(omnitrace-interface-library SYSTEM
|
||||
INTERFACE ${perfetto_DIR}/sdk)
|
||||
|
||||
target_compile_definitions(
|
||||
omnitrace-interface-library
|
||||
INTERFACE OMNITRACE_MAX_THREADS=${OMNITRACE_MAX_THREADS}
|
||||
$<IF:$<BOOL:${OMNITRACE_CUSTOM_DATA_SOURCE}>,CUSTOM_DATA_SOURCE,>)
|
||||
|
||||
target_link_libraries(
|
||||
omnitrace-interface-library
|
||||
INTERFACE $<BUILD_INTERFACE:omnitrace::omnitrace-headers>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-threading>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-compile-options>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-hip>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-roctracer>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-rocm-smi>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-mpi>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-ptl>
|
||||
$<BUILD_INTERFACE:timemory::timemory-headers>
|
||||
$<BUILD_INTERFACE:timemory::timemory-gotcha>
|
||||
$<BUILD_INTERFACE:timemory::timemory-cxx-static>
|
||||
$<IF:$<BOOL:${OMNITRACE_USE_SANITIZER}>,omnitrace::omnitrace-sanitizer,>)
|
||||
|
||||
# ------------------------------------------------------------------------------#
|
||||
# omnitrace-dl: contains minimal symbols and dlopen's omnitrace
|
||||
#
|
||||
# omnitrace object library
|
||||
# omnitrace-user: contains symbols for user API
|
||||
#
|
||||
# ------------------------------------------------------------------------------#
|
||||
# ----------------------------------------------------------------------------- #
|
||||
|
||||
add_library(omnitrace-object-library OBJECT)
|
||||
add_library(omnitrace::omnitrace-object-library ALIAS omnitrace-object-library)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/library/defines.hpp.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/library/defines.hpp @ONLY)
|
||||
|
||||
set(library_sources
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/api.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/config.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/cpu_freq.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/critical_trace.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/kokkosp.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/gpu.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/perfetto.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/ptl.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/sampling.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/state.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/thread_data.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/thread_sampler.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/timemory.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/components/backtrace.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/components/fork_gotcha.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/components/mpi_gotcha.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/components/omnitrace.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/components/pthread_gotcha.cpp
|
||||
${perfetto_DIR}/sdk/perfetto.cc)
|
||||
|
||||
set(library_headers
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/api.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/config.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/common.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/cpu_freq.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/critical_trace.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/debug.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/gpu.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/perfetto.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/ptl.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/sampling.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/state.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/thread_data.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/thread_sampler.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/timemory.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/fwd.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/backtrace.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/fork_gotcha.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/functors.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/mpi_gotcha.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/omnitrace.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/rocm_smi.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/roctracer.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/roctracer_callbacks.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/pthread_gotcha.hpp
|
||||
${perfetto_DIR}/sdk/perfetto.h)
|
||||
|
||||
target_sources(omnitrace-object-library PRIVATE ${library_sources} ${library_headers})
|
||||
|
||||
if(OMNITRACE_USE_ROCTRACER)
|
||||
target_sources(
|
||||
omnitrace-object-library
|
||||
PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/library/components/roctracer.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/components/roctracer_callbacks.cpp)
|
||||
endif()
|
||||
|
||||
if(OMNITRACE_USE_ROCM_SMI)
|
||||
target_sources(omnitrace-object-library
|
||||
PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/library/components/rocm_smi.cpp)
|
||||
endif()
|
||||
|
||||
target_link_libraries(omnitrace-object-library PRIVATE omnitrace-interface-library)
|
||||
|
||||
if(OMNITRACE_DYNINST_API_RT)
|
||||
get_filename_component(OMNITRACE_DYNINST_API_RT_DIR "${OMNITRACE_DYNINST_API_RT}"
|
||||
DIRECTORY)
|
||||
endif()
|
||||
|
||||
# ------------------------------------------------------------------------------#
|
||||
#
|
||||
# omnitrace shared library
|
||||
#
|
||||
# ------------------------------------------------------------------------------#
|
||||
|
||||
add_library(omnitrace-library SHARED $<TARGET_OBJECTS:omnitrace-object-library>)
|
||||
add_library(omnitrace::omnitrace-library ALIAS omnitrace-library)
|
||||
|
||||
target_link_libraries(omnitrace-library PRIVATE omnitrace-interface-library)
|
||||
|
||||
set_target_properties(
|
||||
omnitrace-library
|
||||
PROPERTIES OUTPUT_NAME omnitrace
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
INSTALL_RPATH
|
||||
"\$ORIGIN:\$ORIGIN/timemory/libunwind:\$ORIGIN/dyninst-tpls/libs")
|
||||
|
||||
install(
|
||||
TARGETS omnitrace-library
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
OPTIONAL)
|
||||
|
||||
# ------------------------------------------------------------------------------#
|
||||
#
|
||||
# omnitrace dl library
|
||||
#
|
||||
# ------------------------------------------------------------------------------#
|
||||
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
set(CMAKE_SKIP_RPATH OFF)
|
||||
set(BUILD_RPATH_USE_ORIGIN ON)
|
||||
|
||||
add_library(omnitrace-dl-library SHARED)
|
||||
add_library(omnitrace::omnitrace-dl-library ALIAS omnitrace-dl-library)
|
||||
|
||||
target_sources(omnitrace-dl-library PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/dl.cpp)
|
||||
target_link_libraries(omnitrace-dl-library PRIVATE ${dl_LIBRARY})
|
||||
|
||||
check_cxx_compiler_flag("-fno-exceptions" omnitrace_dl_library_fno_exceptions)
|
||||
check_cxx_compiler_flag("-ftls-model=local-dynamic"
|
||||
omnitrace_dl_library_ftls_module_local_dynamic)
|
||||
|
||||
if(OMNITRACE_BUILD_DEVELOPER)
|
||||
if(omnitrace_dl_library_fno_exceptions)
|
||||
target_compile_options(omnitrace-dl-library PRIVATE -fno-exceptions)
|
||||
endif()
|
||||
|
||||
if(omnitrace_dl_library_ftls_module_local_dynamic)
|
||||
target_compile_options(omnitrace-dl-library PRIVATE -ftls-model=local-dynamic)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set_target_properties(
|
||||
omnitrace-dl-library
|
||||
PROPERTIES OUTPUT_NAME omnitrace-dl
|
||||
CXX_VISIBILITY_PRESET "protected"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
BUILD_RPATH "\$ORIGIN"
|
||||
INSTALL_RPATH "\$ORIGIN")
|
||||
|
||||
install(
|
||||
TARGETS omnitrace-dl-library
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
OPTIONAL)
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(omnitrace)
|
||||
add_subdirectory(omnitrace-dl)
|
||||
add_subdirectory(omnitrace-user)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------#
|
||||
#
|
||||
# omnitrace common headers
|
||||
#
|
||||
# ------------------------------------------------------------------------------#
|
||||
|
||||
add_library(omnitrace-common-library INTERFACE)
|
||||
add_library(omnitrace::common-library ALIAS omnitrace-common-library)
|
||||
|
||||
target_sources(
|
||||
omnitrace-common-library
|
||||
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/defines.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/delimit.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/environment.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/invoke.hpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/join.hpp)
|
||||
|
||||
get_filename_component(COMMON_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" DIRECTORY)
|
||||
|
||||
target_include_directories(omnitrace-common-library INTERFACE ${COMMON_INCLUDE_DIR})
|
||||
target_compile_definitions(omnitrace-common-library
|
||||
INTERFACE $<BUILD_INTERFACE:OMNITRACE_INTERNAL_BUILD>)
|
||||
@@ -0,0 +1,36 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#define OMNITRACE_ATTRIBUTE(...) __attribute__((__VA_ARGS__))
|
||||
#define OMNITRACE_VISIBILITY(MODE) OMNITRACE_ATTRIBUTE(visibility(MODE))
|
||||
#define OMNITRACE_PUBLIC_API OMNITRACE_VISIBILITY("default")
|
||||
#define OMNITRACE_HIDDEN_API OMNITRACE_VISIBILITY("hidden")
|
||||
#define OMNITRACE_WEAK_API OMNITRACE_ATTRIBUTE(weak)
|
||||
#define OMNITRACE_INLINE OMNITRACE_ATTRIBUTE(__always_inline__)
|
||||
|
||||
#if defined(__cplusplus)
|
||||
# if !defined(OMNITRACE_FOLD_EXPRESSION)
|
||||
# define OMNITRACE_FOLD_EXPRESSION(...) ((__VA_ARGS__), ...)
|
||||
# endif
|
||||
#endif
|
||||
@@ -0,0 +1,65 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace omnitrace
|
||||
{
|
||||
inline namespace common
|
||||
{
|
||||
namespace
|
||||
{
|
||||
template <typename ContainerT = std::vector<std::string>>
|
||||
inline ContainerT
|
||||
delimit(const std::string& line, const char* delimiters = "\"',;: ");
|
||||
|
||||
template <typename ContainerT>
|
||||
inline ContainerT
|
||||
delimit(const std::string& line, const char* delimiters)
|
||||
{
|
||||
ContainerT _result{};
|
||||
size_t _beginp = 0; // position that is the beginning of the new string
|
||||
size_t _delimp = 0; // position of the delimiter in the string
|
||||
while(_beginp < line.length() && _delimp < line.length())
|
||||
{
|
||||
// find the first character (starting at _delimp) that is not a delimiter
|
||||
_beginp = line.find_first_not_of(delimiters, _delimp);
|
||||
// if no a character after or at _end that is not a delimiter is not found
|
||||
// then we are done
|
||||
if(_beginp == std::string::npos) break;
|
||||
// starting at the position of the new string, find the next delimiter
|
||||
_delimp = line.find_first_of(delimiters, _beginp);
|
||||
std::string _tmp{};
|
||||
// starting at the position of the new string, get the characters
|
||||
// between this position and the next delimiter
|
||||
_tmp = line.substr(_beginp, _delimp - _beginp);
|
||||
// don't add empty strings
|
||||
if(!_tmp.empty()) _result.emplace(_result.end(), _tmp);
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
} // namespace
|
||||
} // namespace common
|
||||
} // namespace omnitrace
|
||||
@@ -0,0 +1,77 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace omnitrace
|
||||
{
|
||||
inline namespace common
|
||||
{
|
||||
namespace
|
||||
{
|
||||
inline std::string
|
||||
get_env(const char* env_id, const char* _default)
|
||||
{
|
||||
if(strlen(env_id) == 0) return _default;
|
||||
char* env_var = ::std::getenv(env_id);
|
||||
if(env_var) return std::string{ env_var };
|
||||
return _default;
|
||||
}
|
||||
|
||||
inline int
|
||||
get_env(const char* env_id, int _default)
|
||||
{
|
||||
if(strlen(env_id) == 0) return _default;
|
||||
char* env_var = ::std::getenv(env_id);
|
||||
if(env_var) return std::stoi(env_var);
|
||||
return _default;
|
||||
}
|
||||
|
||||
inline bool
|
||||
get_env(const char* env_id, bool _default)
|
||||
{
|
||||
if(strlen(env_id) == 0) return _default;
|
||||
char* env_var = ::std::getenv(env_id);
|
||||
if(env_var)
|
||||
{
|
||||
if(std::string_view{ env_var }.find_first_not_of("0123456789") ==
|
||||
std::string_view::npos)
|
||||
return static_cast<bool>(std::stoi(env_var));
|
||||
else
|
||||
{
|
||||
for(size_t i = 0; i < strlen(env_var); ++i)
|
||||
env_var[i] = tolower(env_var[i]);
|
||||
for(const auto& itr : { "off", "false", "no", "n", "f", "0" })
|
||||
if(strcmp(env_var, itr) == 0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
} // namespace
|
||||
} // namespace common
|
||||
} // namespace omnitrace
|
||||
@@ -0,0 +1,114 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/defines.h"
|
||||
#include "common/join.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#if !defined(OMNITRACE_COMMON_LIBRARY_NAME)
|
||||
# define OMNITRACE_COMMON_LIBRARY_NAME "common"
|
||||
# error OMNITRACE_COMMON_LIBRARY_NAME must be defined
|
||||
#endif
|
||||
|
||||
namespace omnitrace
|
||||
{
|
||||
inline namespace common
|
||||
{
|
||||
namespace
|
||||
{
|
||||
template <typename FuncT, typename... Args>
|
||||
inline auto
|
||||
invoke(const char* _name, FuncT&& _func, Args... _args) OMNITRACE_HIDDEN_API;
|
||||
|
||||
inline int32_t&
|
||||
get_guard()
|
||||
{
|
||||
static thread_local int32_t _v = 0;
|
||||
return _v;
|
||||
}
|
||||
|
||||
inline int64_t
|
||||
get_thread_index()
|
||||
{
|
||||
static std::atomic<int64_t> _c{ 0 };
|
||||
static thread_local auto _v = _c++;
|
||||
return _v;
|
||||
}
|
||||
|
||||
template <typename FuncT, typename... Args>
|
||||
auto
|
||||
invoke(const char* _name, int _verbose, FuncT&& _func, Args... _args)
|
||||
{
|
||||
if(_func)
|
||||
{
|
||||
struct decrement_guard
|
||||
{
|
||||
// decrement the guard as it exits the scope
|
||||
~decrement_guard() { --get_guard(); }
|
||||
} _unlk{};
|
||||
|
||||
// if _lk is ever greater than zero on the same thread, this
|
||||
// means a function within the current function is calling
|
||||
// our instrumentation so we ignore the call
|
||||
int32_t _lk = get_guard()++;
|
||||
if(_lk == 0)
|
||||
{
|
||||
if(_verbose > 3)
|
||||
{
|
||||
fflush(stderr);
|
||||
fprintf(stderr,
|
||||
"[omnitrace][" OMNITRACE_COMMON_LIBRARY_NAME "][%li] %s(%s)\n",
|
||||
get_thread_index(), _name, join(", ", _args...).c_str());
|
||||
fflush(stderr);
|
||||
}
|
||||
return std::invoke(std::forward<FuncT>(_func), _args...);
|
||||
}
|
||||
else if(_verbose > 2)
|
||||
{
|
||||
fflush(stderr);
|
||||
fprintf(stderr,
|
||||
"[omnitrace][" OMNITRACE_COMMON_LIBRARY_NAME
|
||||
"][%li] %s(%s) was guarded :: value = %i\n",
|
||||
get_thread_index(), _name, join(", ", _args...).c_str(), _lk);
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
else if(_verbose >= 0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[omnitrace][" OMNITRACE_COMMON_LIBRARY_NAME
|
||||
"][%li] %s(%s) ignored :: null function pointer\n",
|
||||
get_thread_index(), _name, join(", ", _args...).c_str());
|
||||
}
|
||||
|
||||
using return_type = decltype(std::invoke(std::forward<FuncT>(_func), _args...));
|
||||
if constexpr(!std::is_void<return_type>::value) return return_type();
|
||||
}
|
||||
} // namespace
|
||||
} // namespace common
|
||||
} // namespace omnitrace
|
||||
@@ -0,0 +1,55 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#if !defined(OMNITRACE_FOLD_EXPRESSION)
|
||||
# define OMNITRACE_FOLD_EXPRESSION(...) ((__VA_ARGS__), ...)
|
||||
#endif
|
||||
|
||||
namespace omnitrace
|
||||
{
|
||||
inline namespace common
|
||||
{
|
||||
namespace
|
||||
{
|
||||
template <typename DelimT, typename... Args>
|
||||
auto
|
||||
join(DelimT&& _delim, Args&&... _args)
|
||||
{
|
||||
std::stringstream _ss{};
|
||||
OMNITRACE_FOLD_EXPRESSION(_ss << _delim << _args);
|
||||
if constexpr(std::is_same<DelimT, char>::value)
|
||||
{
|
||||
return _ss.str().substr(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _ss.str().substr(std::string{ _delim }.length());
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
} // namespace common
|
||||
} // namespace omnitrace
|
||||
@@ -0,0 +1,55 @@
|
||||
# ------------------------------------------------------------------------------#
|
||||
#
|
||||
# omnitrace dl library
|
||||
#
|
||||
# ------------------------------------------------------------------------------#
|
||||
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
set(CMAKE_SKIP_RPATH OFF)
|
||||
set(BUILD_RPATH_USE_ORIGIN ON)
|
||||
|
||||
add_library(omnitrace-dl-library SHARED)
|
||||
add_library(omnitrace::omnitrace-dl-library ALIAS omnitrace-dl-library)
|
||||
|
||||
target_sources(omnitrace-dl-library PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/dl.cpp)
|
||||
target_link_libraries(omnitrace-dl-library PRIVATE ${dl_LIBRARY}
|
||||
omnitrace::common-library)
|
||||
|
||||
check_cxx_compiler_flag("-fno-exceptions" omnitrace_dl_library_fno_exceptions)
|
||||
check_cxx_compiler_flag("-ftls-model=local-dynamic"
|
||||
omnitrace_dl_library_ftls_module_local_dynamic)
|
||||
|
||||
if(OMNITRACE_BUILD_DEVELOPER)
|
||||
if(omnitrace_dl_library_fno_exceptions)
|
||||
target_compile_options(omnitrace-dl-library PRIVATE -fno-exceptions)
|
||||
endif()
|
||||
|
||||
if(omnitrace_dl_library_ftls_module_local_dynamic)
|
||||
target_compile_options(omnitrace-dl-library PRIVATE -ftls-model=local-dynamic)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
omnitrace_target_compile_definitions(
|
||||
omnitrace-dl-library PRIVATE OMNITRACE_USE_OMPT=$<BOOL:${OMNITRACE_USE_OMPT}>)
|
||||
|
||||
set_target_properties(
|
||||
omnitrace-dl-library
|
||||
PROPERTIES OUTPUT_NAME omnitrace-dl
|
||||
CXX_VISIBILITY_PRESET "protected"
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
BUILD_RPATH "\$ORIGIN"
|
||||
INSTALL_RPATH "\$ORIGIN")
|
||||
|
||||
install(
|
||||
TARGETS omnitrace-dl-library
|
||||
EXPORT omnitrace-dl-library-targets
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
OPTIONAL)
|
||||
|
||||
install(
|
||||
EXPORT omnitrace-dl-library-targets
|
||||
FILE omnitrace-dl-library-targets.cmake
|
||||
NAMESPACE omnitrace::
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/omnitrace)
|
||||
@@ -22,6 +22,15 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#define OMNITRACE_COMMON_LIBRARY_NAME "dl"
|
||||
|
||||
#include "common/defines.h"
|
||||
#include "common/delimit.hpp"
|
||||
#include "common/environment.hpp"
|
||||
#include "common/invoke.hpp"
|
||||
#include "common/join.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
@@ -38,15 +47,15 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define OMNITRACE_FOLD_EXPRESSION(...) ((__VA_ARGS__), ...)
|
||||
#define OMNITRACE_VISIBLE __attribute__((visibility("default")))
|
||||
#define OMNITRACE_HIDDEN __attribute__((visibility("internal")))
|
||||
#define OMNITRACE_INLINE __attribute__((__always_inline__))
|
||||
#if !defined(OMNITRACE_USE_OMPT)
|
||||
# define OMNITRACE_USE_OMPT 0
|
||||
#endif
|
||||
|
||||
#define OMNITRACE_DLSYM(VARNAME, HANDLE, FUNCNAME) \
|
||||
if(HANDLE) \
|
||||
{ \
|
||||
*(void**) (&VARNAME) = dlsym(HANDLE, FUNCNAME); \
|
||||
if(VARNAME == nullptr && _omnitrace_dl_verbose >= 0) \
|
||||
if(VARNAME == nullptr && _omnitrace_dl_verbose >= _warn_verbose) \
|
||||
{ \
|
||||
fprintf(stderr, "[omnitrace][dl][pid=%i]> %s :: %s\n", getpid(), FUNCNAME, \
|
||||
dlerror()); \
|
||||
@@ -61,50 +70,45 @@
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void omnitrace_init_library(void) OMNITRACE_VISIBLE;
|
||||
void omnitrace_init(const char*, bool, const char*) OMNITRACE_VISIBLE;
|
||||
void omnitrace_finalize(void) OMNITRACE_VISIBLE;
|
||||
void omnitrace_set_env(const char* env_name, const char* env_val) OMNITRACE_VISIBLE;
|
||||
void omnitrace_set_mpi(bool use, bool attached) OMNITRACE_VISIBLE;
|
||||
void omnitrace_push_trace(const char* name) OMNITRACE_VISIBLE;
|
||||
void omnitrace_pop_trace(const char* name) OMNITRACE_VISIBLE;
|
||||
struct ompt_start_tool_result_t;
|
||||
|
||||
void omnitrace_init_library(void) OMNITRACE_PUBLIC_API;
|
||||
void omnitrace_init(const char*, bool, const char*) OMNITRACE_PUBLIC_API;
|
||||
void omnitrace_finalize(void) OMNITRACE_PUBLIC_API;
|
||||
void omnitrace_set_env(const char* env_name,
|
||||
const char* env_val) OMNITRACE_PUBLIC_API;
|
||||
void omnitrace_set_mpi(bool use, bool attached) OMNITRACE_PUBLIC_API;
|
||||
void omnitrace_push_trace(const char* name) OMNITRACE_PUBLIC_API;
|
||||
void omnitrace_pop_trace(const char* name) OMNITRACE_PUBLIC_API;
|
||||
|
||||
void omnitrace_user_start_trace_dl(void) OMNITRACE_HIDDEN_API;
|
||||
void omnitrace_user_stop_trace_dl(void) OMNITRACE_HIDDEN_API;
|
||||
|
||||
void omnitrace_user_start_thread_trace_dl(void) OMNITRACE_HIDDEN_API;
|
||||
void omnitrace_user_stop_thread_trace_dl(void) OMNITRACE_HIDDEN_API;
|
||||
|
||||
void omnitrace_user_push_region_dl(const char*) OMNITRACE_HIDDEN_API;
|
||||
void omnitrace_user_pop_region_dl(const char*) OMNITRACE_HIDDEN_API;
|
||||
|
||||
ompt_start_tool_result_t* ompt_start_tool(unsigned int,
|
||||
const char*) OMNITRACE_PUBLIC_API;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
inline namespace omnitrace
|
||||
namespace omnitrace
|
||||
{
|
||||
inline namespace dl
|
||||
{
|
||||
namespace
|
||||
{
|
||||
inline int
|
||||
get_omnitrace_env();
|
||||
|
||||
bool
|
||||
get_env(const char* env_id, bool _default);
|
||||
|
||||
std::string
|
||||
get_env(const char* env_id, const char* _default);
|
||||
|
||||
int
|
||||
get_env(const char* env_id, int _default);
|
||||
|
||||
template <typename DelimT, typename... Args>
|
||||
auto
|
||||
join(DelimT&& _delim, Args&&... _args)
|
||||
get_omnitrace_env()
|
||||
{
|
||||
std::stringstream _ss{};
|
||||
OMNITRACE_FOLD_EXPRESSION(_ss << _delim << _args);
|
||||
if constexpr(std::is_same<DelimT, char>::value)
|
||||
{
|
||||
return _ss.str().substr(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _ss.str().substr(std::string{ _delim }.length());
|
||||
}
|
||||
auto&& _debug = get_env("OMNITRACE_DEBUG", false);
|
||||
return get_env("OMNITRACE_VERBOSE", (_debug) ? 100 : 0);
|
||||
}
|
||||
|
||||
// environment priority:
|
||||
// - OMNITRACE_DL_DEBUG
|
||||
// - OMNITRACE_DL_VERBOSE
|
||||
@@ -114,10 +118,6 @@ int _omnitrace_dl_verbose = get_env("OMNITRACE_DL_DEBUG", false)
|
||||
? 100
|
||||
: get_env("OMNITRACE_DL_VERBOSE", get_omnitrace_env());
|
||||
|
||||
template <typename ContainerT = std::vector<std::string>>
|
||||
inline ContainerT
|
||||
delimit(const std::string& line, const char* delimiters = "\"',;: ");
|
||||
|
||||
// The docs for dlopen suggest that the combination of RTLD_LOCAL + RTLD_DEEPBIND
|
||||
// (when available) helps ensure that the symbols in the instrumentation library
|
||||
// libomnitrace.so will use it's own symbols... not symbols that are potentially
|
||||
@@ -162,39 +162,38 @@ const char* _omnitrace_dl_dlopen_descr = "RTLD_LAZY | RTLD_LOCAL";
|
||||
#endif
|
||||
|
||||
/// This class contains function pointers for omnitrace's instrumentation functions
|
||||
struct OMNITRACE_HIDDEN indirect
|
||||
struct OMNITRACE_HIDDEN_API indirect
|
||||
{
|
||||
explicit OMNITRACE_INLINE indirect(std::string libpath)
|
||||
: m_libpath{ find_path(std::move(libpath)) }
|
||||
OMNITRACE_INLINE indirect(std::string omnilib, std::string userlib)
|
||||
: m_omnilib{ find_path(std::move(omnilib)) }
|
||||
, m_userlib{ find_path(std::move(userlib)) }
|
||||
{
|
||||
if(_omnitrace_dl_verbose > 0)
|
||||
{
|
||||
fprintf(stderr, "[omnitrace][dl][pid=%i] libomnitrace.so resolved to '%s'\n",
|
||||
getpid(), m_libpath.c_str());
|
||||
getpid(), m_omnilib.c_str());
|
||||
}
|
||||
auto _omni_hsa_lib = m_libpath;
|
||||
auto _omni_hsa_lib = m_omnilib;
|
||||
const char* _hsa_lib = getenv("HSA_TOOLS_LIB");
|
||||
if(_hsa_lib) _omni_hsa_lib.append(":").append(_hsa_lib);
|
||||
setenv("HSA_TOOLS_LIB", _omni_hsa_lib.c_str(), 1);
|
||||
open();
|
||||
m_omnihandle = open(m_omnilib);
|
||||
m_userhandle = open(m_userlib);
|
||||
init();
|
||||
}
|
||||
|
||||
OMNITRACE_INLINE ~indirect() { dlclose(m_libhandle); }
|
||||
OMNITRACE_INLINE ~indirect() { dlclose(m_omnihandle); }
|
||||
|
||||
OMNITRACE_INLINE void open()
|
||||
static OMNITRACE_INLINE void* open(const std::string& _lib)
|
||||
{
|
||||
if(m_libhandle) return;
|
||||
|
||||
auto* libhandle = dlopen(m_libpath.c_str(), _omnitrace_dl_dlopen_flags);
|
||||
auto* libhandle = dlopen(_lib.c_str(), _omnitrace_dl_dlopen_flags);
|
||||
|
||||
if(libhandle)
|
||||
{
|
||||
m_libhandle = libhandle;
|
||||
if(_omnitrace_dl_verbose > 0)
|
||||
{
|
||||
fprintf(stderr, "[omnitrace][dl][pid=%i] dlopen(%s, %s) :: success\n",
|
||||
getpid(), m_libpath.c_str(), _omnitrace_dl_dlopen_descr);
|
||||
getpid(), _lib.c_str(), _omnitrace_dl_dlopen_descr);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -203,26 +202,48 @@ struct OMNITRACE_HIDDEN indirect
|
||||
{
|
||||
perror("dlopen");
|
||||
fprintf(stderr, "[omnitrace][dl][pid=%i] dlopen(%s, %s) :: %s\n",
|
||||
getpid(), m_libpath.c_str(), _omnitrace_dl_dlopen_descr,
|
||||
dlerror());
|
||||
getpid(), _lib.c_str(), _omnitrace_dl_dlopen_descr, dlerror());
|
||||
}
|
||||
}
|
||||
|
||||
dlerror(); // Clear any existing error
|
||||
|
||||
return libhandle;
|
||||
}
|
||||
|
||||
OMNITRACE_INLINE void init()
|
||||
{
|
||||
if(!m_libhandle) open();
|
||||
if(!m_omnihandle) m_omnihandle = open(m_omnilib);
|
||||
|
||||
int _warn_verbose = 0;
|
||||
// Initialize all pointers
|
||||
OMNITRACE_DLSYM(omnitrace_init_library_f, m_libhandle, "omnitrace_init_library");
|
||||
OMNITRACE_DLSYM(omnitrace_init_f, m_libhandle, "omnitrace_init");
|
||||
OMNITRACE_DLSYM(omnitrace_finalize_f, m_libhandle, "omnitrace_finalize");
|
||||
OMNITRACE_DLSYM(omnitrace_set_env_f, m_libhandle, "omnitrace_set_env");
|
||||
OMNITRACE_DLSYM(omnitrace_set_mpi_f, m_libhandle, "omnitrace_set_mpi");
|
||||
OMNITRACE_DLSYM(omnitrace_push_trace_f, m_libhandle, "omnitrace_push_trace");
|
||||
OMNITRACE_DLSYM(omnitrace_pop_trace_f, m_libhandle, "omnitrace_pop_trace");
|
||||
OMNITRACE_DLSYM(omnitrace_init_library_f, m_omnihandle, "omnitrace_init_library");
|
||||
OMNITRACE_DLSYM(omnitrace_init_f, m_omnihandle, "omnitrace_init");
|
||||
OMNITRACE_DLSYM(omnitrace_finalize_f, m_omnihandle, "omnitrace_finalize");
|
||||
OMNITRACE_DLSYM(omnitrace_set_env_f, m_omnihandle, "omnitrace_set_env");
|
||||
OMNITRACE_DLSYM(omnitrace_set_mpi_f, m_omnihandle, "omnitrace_set_mpi");
|
||||
OMNITRACE_DLSYM(omnitrace_push_trace_f, m_omnihandle, "omnitrace_push_trace");
|
||||
OMNITRACE_DLSYM(omnitrace_pop_trace_f, m_omnihandle, "omnitrace_pop_trace");
|
||||
OMNITRACE_DLSYM(omnitrace_push_region_f, m_omnihandle, "omnitrace_push_region");
|
||||
OMNITRACE_DLSYM(omnitrace_pop_region_f, m_omnihandle, "omnitrace_pop_region");
|
||||
#if OMNITRACE_USE_OMPT == 0
|
||||
_warn_verbose = 5;
|
||||
#endif
|
||||
OMNITRACE_DLSYM(ompt_start_tool_f, m_omnihandle, "ompt_start_tool");
|
||||
|
||||
if(!m_userhandle) m_userhandle = open(m_userlib);
|
||||
_warn_verbose = 0;
|
||||
OMNITRACE_DLSYM(omnitrace_user_configure_f, m_userhandle,
|
||||
"omnitrace_user_configure");
|
||||
|
||||
if(omnitrace_user_configure_f)
|
||||
{
|
||||
(*omnitrace_user_configure_f)(
|
||||
&omnitrace_user_start_trace_dl, &omnitrace_user_stop_trace_dl,
|
||||
&omnitrace_user_start_thread_trace_dl,
|
||||
&omnitrace_user_stop_thread_trace_dl, &omnitrace_user_push_region_dl,
|
||||
&omnitrace_user_pop_region_dl);
|
||||
}
|
||||
}
|
||||
|
||||
static OMNITRACE_INLINE std::string find_path(std::string&& _path)
|
||||
@@ -246,196 +267,170 @@ struct OMNITRACE_HIDDEN indirect
|
||||
}
|
||||
|
||||
public:
|
||||
void (*omnitrace_init_library_f)(void) = nullptr;
|
||||
void (*omnitrace_init_f)(const char*, bool, const char*) = nullptr;
|
||||
void (*omnitrace_finalize_f)(void) = nullptr;
|
||||
void (*omnitrace_set_env_f)(const char*, const char*) = nullptr;
|
||||
void (*omnitrace_set_mpi_f)(bool, bool) = nullptr;
|
||||
void (*omnitrace_push_trace_f)(const char*) = nullptr;
|
||||
void (*omnitrace_pop_trace_f)(const char*) = nullptr;
|
||||
void (*omnitrace_init_library_f)(void) = nullptr;
|
||||
void (*omnitrace_init_f)(const char*, bool, const char*) = nullptr;
|
||||
void (*omnitrace_finalize_f)(void) = nullptr;
|
||||
void (*omnitrace_set_env_f)(const char*, const char*) = nullptr;
|
||||
void (*omnitrace_set_mpi_f)(bool, bool) = nullptr;
|
||||
void (*omnitrace_push_trace_f)(const char*) = nullptr;
|
||||
void (*omnitrace_pop_trace_f)(const char*) = nullptr;
|
||||
void (*omnitrace_push_region_f)(const char*) = nullptr;
|
||||
void (*omnitrace_pop_region_f)(const char*) = nullptr;
|
||||
void (*omnitrace_user_configure_f)(void (*)(void), void (*)(void), void (*)(void),
|
||||
void (*)(void), void (*)(const char*),
|
||||
void (*)(const char*)) = nullptr;
|
||||
ompt_start_tool_result_t* (*ompt_start_tool_f)(unsigned int, const char*);
|
||||
|
||||
private:
|
||||
void* m_libhandle = nullptr;
|
||||
std::string m_libpath = {};
|
||||
void* m_omnihandle = nullptr;
|
||||
void* m_userhandle = nullptr;
|
||||
std::string m_omnilib = {};
|
||||
std::string m_userlib = {};
|
||||
};
|
||||
|
||||
inline indirect&
|
||||
get_indirect() OMNITRACE_HIDDEN;
|
||||
get_indirect() OMNITRACE_HIDDEN_API;
|
||||
|
||||
template <typename FuncT, typename... Args>
|
||||
inline void
|
||||
invoke(const char* _name, FuncT&& _func, Args... _args) OMNITRACE_HIDDEN;
|
||||
indirect&
|
||||
get_indirect()
|
||||
{
|
||||
static auto _v =
|
||||
indirect{ get_env("OMNITRACE_LIBRARY", "libomnitrace.so"),
|
||||
get_env("OMNITRACE_USER_LIBRARY", "libomnitrace-user.so") };
|
||||
return _v;
|
||||
}
|
||||
|
||||
auto&
|
||||
get_active()
|
||||
{
|
||||
static bool _v = false;
|
||||
return _v;
|
||||
}
|
||||
|
||||
auto&
|
||||
get_enabled()
|
||||
{
|
||||
static std::atomic<bool> _v{ get_env("OMNITRACE_INIT_ENABLED", true) };
|
||||
return _v;
|
||||
}
|
||||
|
||||
auto&
|
||||
get_thread_enabled()
|
||||
{
|
||||
static thread_local bool _v = get_enabled();
|
||||
return _v;
|
||||
}
|
||||
|
||||
auto&
|
||||
get_count()
|
||||
{
|
||||
static std::atomic<int64_t> _v{ 0 };
|
||||
return _v;
|
||||
}
|
||||
|
||||
auto&
|
||||
get_thread_count()
|
||||
{
|
||||
static thread_local int64_t _v = 0;
|
||||
return _v;
|
||||
}
|
||||
} // namespace
|
||||
} // namespace dl
|
||||
} // namespace omnitrace
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
|
||||
#define OMNITRACE_DL_INVOKE(...) \
|
||||
::omnitrace::common::invoke(__FUNCTION__, ::omnitrace::dl::_omnitrace_dl_verbose, \
|
||||
__VA_ARGS__)
|
||||
|
||||
using omnitrace::get_indirect;
|
||||
namespace dl = omnitrace::dl;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void omnitrace_init_library(void)
|
||||
{
|
||||
invoke(__FUNCTION__, get_indirect().omnitrace_init_library_f);
|
||||
OMNITRACE_DL_INVOKE(get_indirect().omnitrace_init_library_f);
|
||||
}
|
||||
|
||||
void omnitrace_init(const char* a, bool b, const char* c)
|
||||
{
|
||||
invoke(__FUNCTION__, get_indirect().omnitrace_init_f, a, b, c);
|
||||
OMNITRACE_DL_INVOKE(get_indirect().omnitrace_init_f, a, b, c);
|
||||
dl::get_active() = true;
|
||||
}
|
||||
|
||||
void omnitrace_finalize(void)
|
||||
{
|
||||
invoke(__FUNCTION__, get_indirect().omnitrace_finalize_f);
|
||||
dl::get_active() = false;
|
||||
OMNITRACE_DL_INVOKE(get_indirect().omnitrace_finalize_f);
|
||||
}
|
||||
|
||||
void omnitrace_push_trace(const char* name)
|
||||
{
|
||||
invoke(__FUNCTION__, get_indirect().omnitrace_push_trace_f, name);
|
||||
if(!dl::get_active()) return;
|
||||
if(dl::get_thread_enabled())
|
||||
{
|
||||
OMNITRACE_DL_INVOKE(get_indirect().omnitrace_push_trace_f, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
++dl::get_thread_count();
|
||||
}
|
||||
}
|
||||
|
||||
void omnitrace_pop_trace(const char* name)
|
||||
{
|
||||
invoke(__FUNCTION__, get_indirect().omnitrace_pop_trace_f, name);
|
||||
if(!dl::get_active()) return;
|
||||
if(dl::get_thread_enabled())
|
||||
{
|
||||
OMNITRACE_DL_INVOKE(get_indirect().omnitrace_pop_trace_f, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dl::get_thread_count()-- == 0) omnitrace_user_start_thread_trace_dl();
|
||||
}
|
||||
}
|
||||
|
||||
void omnitrace_set_env(const char* a, const char* b)
|
||||
{
|
||||
setenv(a, b, 0);
|
||||
invoke(__FUNCTION__, get_indirect().omnitrace_set_env_f, a, b);
|
||||
OMNITRACE_DL_INVOKE(get_indirect().omnitrace_set_env_f, a, b);
|
||||
}
|
||||
|
||||
void omnitrace_set_mpi(bool a, bool b)
|
||||
{
|
||||
invoke(__FUNCTION__, get_indirect().omnitrace_set_mpi_f, a, b);
|
||||
OMNITRACE_DL_INVOKE(get_indirect().omnitrace_set_mpi_f, a, b);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------//
|
||||
void omnitrace_user_start_trace_dl(void) { dl::get_enabled().store(true); }
|
||||
void omnitrace_user_stop_trace_dl(void) { dl::get_enabled().store(false); }
|
||||
void omnitrace_user_start_thread_trace_dl(void) { dl::get_thread_enabled() = true; }
|
||||
void omnitrace_user_stop_thread_trace_dl(void) { dl::get_thread_enabled() = false; }
|
||||
|
||||
inline namespace omnitrace
|
||||
{
|
||||
inline namespace dl
|
||||
{
|
||||
namespace
|
||||
{
|
||||
template <typename ContainerT>
|
||||
inline ContainerT
|
||||
delimit(const std::string& line, const char* delimiters)
|
||||
{
|
||||
ContainerT _result{};
|
||||
size_t _beginp = 0; // position that is the beginning of the new string
|
||||
size_t _delimp = 0; // position of the delimiter in the string
|
||||
while(_beginp < line.length() && _delimp < line.length())
|
||||
void omnitrace_user_push_region_dl(const char* name)
|
||||
{
|
||||
// find the first character (starting at _delimp) that is not a delimiter
|
||||
_beginp = line.find_first_not_of(delimiters, _delimp);
|
||||
// if no a character after or at _end that is not a delimiter is not found
|
||||
// then we are done
|
||||
if(_beginp == std::string::npos) break;
|
||||
// starting at the position of the new string, find the next delimiter
|
||||
_delimp = line.find_first_of(delimiters, _beginp);
|
||||
std::string _tmp{};
|
||||
// starting at the position of the new string, get the characters
|
||||
// between this position and the next delimiter
|
||||
_tmp = line.substr(_beginp, _delimp - _beginp);
|
||||
// don't add empty strings
|
||||
if(!_tmp.empty()) _result.emplace(_result.end(), _tmp);
|
||||
if(!dl::get_active()) return;
|
||||
OMNITRACE_DL_INVOKE(get_indirect().omnitrace_push_region_f, name);
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
|
||||
std::string
|
||||
get_env(const char* env_id, const char* _default)
|
||||
{
|
||||
if(strlen(env_id) == 0) return _default;
|
||||
char* env_var = ::std::getenv(env_id);
|
||||
if(env_var) return std::string{ env_var };
|
||||
return _default;
|
||||
}
|
||||
|
||||
int
|
||||
get_env(const char* env_id, int _default)
|
||||
{
|
||||
if(strlen(env_id) == 0) return _default;
|
||||
char* env_var = ::std::getenv(env_id);
|
||||
if(env_var) return std::stoi(env_var);
|
||||
return _default;
|
||||
}
|
||||
|
||||
bool
|
||||
get_env(const char* env_id, bool _default)
|
||||
{
|
||||
if(strlen(env_id) == 0) return _default;
|
||||
char* env_var = ::std::getenv(env_id);
|
||||
if(env_var)
|
||||
void omnitrace_user_pop_region_dl(const char* name)
|
||||
{
|
||||
if(std::string{ env_var }.find_first_not_of("0123456789") == std::string::npos)
|
||||
return static_cast<bool>(std::stoi(env_var));
|
||||
else
|
||||
{
|
||||
for(size_t i = 0; i < strlen(env_var); ++i)
|
||||
env_var[i] = tolower(env_var[i]);
|
||||
for(const auto& itr : { "off", "false", "no", "n", "f", "0" })
|
||||
if(strcmp(env_var, itr) == 0) return false;
|
||||
}
|
||||
return true;
|
||||
if(!dl::get_active()) return;
|
||||
OMNITRACE_DL_INVOKE(get_indirect().omnitrace_pop_region_f, name);
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
|
||||
int
|
||||
get_omnitrace_env()
|
||||
{
|
||||
auto&& _debug = get_env("OMNITRACE_DEBUG", false);
|
||||
return get_env("OMNITRACE_VERBOSE", (_debug) ? 100 : 0);
|
||||
}
|
||||
|
||||
indirect&
|
||||
get_indirect()
|
||||
{
|
||||
static auto _v = indirect{ get_env("OMNITRACE_LIBRARY", "libomnitrace.so") };
|
||||
return _v;
|
||||
}
|
||||
|
||||
int32_t&
|
||||
get_guard()
|
||||
{
|
||||
static thread_local int32_t _v = 0;
|
||||
return _v;
|
||||
}
|
||||
|
||||
template <typename FuncT, typename... Args>
|
||||
void
|
||||
invoke(const char* _name, FuncT&& _func, Args... _args)
|
||||
{
|
||||
if(_func)
|
||||
ompt_start_tool_result_t* ompt_start_tool(unsigned int omp_version,
|
||||
const char* runtime_version)
|
||||
{
|
||||
// if _lk is ever greater than zero on the same thread, this
|
||||
// means a function within the current function is calling
|
||||
// our instrumentation so we ignore the call
|
||||
int32_t _lk = get_guard()++;
|
||||
if(_lk == 0)
|
||||
{
|
||||
std::invoke(std::forward<FuncT>(_func), _args...);
|
||||
}
|
||||
else if(_omnitrace_dl_verbose > 2)
|
||||
{
|
||||
fflush(stderr);
|
||||
fprintf(stderr, "[omnitrace][dl] call to %s was guarded :: value = %i\n",
|
||||
_name, _lk);
|
||||
fflush(stderr);
|
||||
}
|
||||
// decrement the guard as it exits the scope
|
||||
--get_guard();
|
||||
}
|
||||
else if(_omnitrace_dl_verbose >= 0)
|
||||
{
|
||||
fprintf(stderr, "[omnitrace][dl] %s\n",
|
||||
join("", "null function pointer to ", _name, ". Ignoring ", _name, "(",
|
||||
_args..., ")")
|
||||
.c_str());
|
||||
#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
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
} // namespace dl
|
||||
} // namespace omnitrace
|
||||
@@ -0,0 +1,61 @@
|
||||
# ------------------------------------------------------------------------------#
|
||||
#
|
||||
# omnitrace user library
|
||||
#
|
||||
# ------------------------------------------------------------------------------#
|
||||
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
set(CMAKE_SKIP_RPATH OFF)
|
||||
set(BUILD_RPATH_USE_ORIGIN ON)
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
|
||||
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
|
||||
|
||||
add_library(omnitrace-user-library SHARED)
|
||||
add_library(omnitrace::omnitrace-user-library ALIAS omnitrace-user-library)
|
||||
|
||||
target_sources(
|
||||
omnitrace-user-library PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/user.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/omnitrace/user.h)
|
||||
target_include_directories(
|
||||
omnitrace-user-library PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
|
||||
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
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
BUILD_RPATH "\$ORIGIN"
|
||||
INSTALL_RPATH "\$ORIGIN")
|
||||
|
||||
install(
|
||||
TARGETS omnitrace-user-library
|
||||
EXPORT omnitrace-user-library-targets
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
OPTIONAL)
|
||||
|
||||
install(
|
||||
FILES ${CMAKE_CURRENT_SOURCE_DIR}/omnitrace/user.h
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/omnitrace
|
||||
OPTIONAL)
|
||||
|
||||
install(
|
||||
EXPORT omnitrace-user-library-targets
|
||||
FILE omnitrace-user-library-targets.cmake
|
||||
NAMESPACE omnitrace::
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/omnitrace)
|
||||
@@ -0,0 +1,50 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#ifndef OMNITRACE_USER_H_
|
||||
#define OMNITRACE_USER_H_ 1
|
||||
|
||||
#define OMNITRACE_ATTRIBUTE(...) __attribute__((__VA_ARGS__))
|
||||
#define OMNITRACE_VISIBILITY(MODE) OMNITRACE_ATTRIBUTE(visibility(MODE))
|
||||
#define OMNITRACE_PUBLIC_API OMNITRACE_VISIBILITY("default")
|
||||
#define OMNITRACE_HIDDEN_API OMNITRACE_VISIBILITY("hidden")
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
extern void omnitrace_user_start_trace(void) OMNITRACE_PUBLIC_API;
|
||||
extern void omnitrace_user_stop_trace(void) OMNITRACE_PUBLIC_API;
|
||||
extern void omnitrace_user_start_thread_trace(void) OMNITRACE_PUBLIC_API;
|
||||
extern void omnitrace_user_stop_thread_trace(void) OMNITRACE_PUBLIC_API;
|
||||
extern void omnitrace_user_push_region(const char*) OMNITRACE_PUBLIC_API;
|
||||
extern void omnitrace_user_pop_region(const char*) OMNITRACE_PUBLIC_API;
|
||||
|
||||
extern void omnitrace_user_configure(void (*)(void), void (*)(void), void (*)(void),
|
||||
void (*)(void), void (*)(const char*),
|
||||
void (*)(const char*)) OMNITRACE_PUBLIC_API;
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // OMNITRACE_USER_H_
|
||||
@@ -0,0 +1,84 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#define OMNITRACE_SOURCE 1
|
||||
|
||||
#include "omnitrace/user.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
namespace
|
||||
{
|
||||
using void_func_t = void (*)(void);
|
||||
using region_func_t = void (*)(const char*);
|
||||
|
||||
void_func_t _start_trace = nullptr;
|
||||
void_func_t _stop_trace = nullptr;
|
||||
void_func_t _start_thread_trace = nullptr;
|
||||
void_func_t _stop_thread_trace = nullptr;
|
||||
region_func_t _push_region = nullptr;
|
||||
region_func_t _pop_region = nullptr;
|
||||
} // namespace
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void omnitrace_user_start_trace(void)
|
||||
{
|
||||
if(_start_trace) (*_start_trace)();
|
||||
}
|
||||
|
||||
void omnitrace_user_stop_trace(void)
|
||||
{
|
||||
if(_stop_trace) (*_stop_trace)();
|
||||
}
|
||||
|
||||
void omnitrace_user_start_thread_trace(void)
|
||||
{
|
||||
if(_start_thread_trace) (*_start_thread_trace)();
|
||||
}
|
||||
|
||||
void omnitrace_user_stop_thread_trace(void)
|
||||
{
|
||||
if(_stop_thread_trace) (*_stop_thread_trace)();
|
||||
}
|
||||
|
||||
void omnitrace_user_push_region(const char* name)
|
||||
{
|
||||
if(_push_region) (*_push_region)(name);
|
||||
}
|
||||
|
||||
void omnitrace_user_pop_region(const char* name)
|
||||
{
|
||||
if(_pop_region) (*_pop_region)(name);
|
||||
}
|
||||
|
||||
void omnitrace_user_configure(void (*_a)(), void (*_b)(), void (*_c)(), void (*_d)(),
|
||||
void (*_e)(const char*), void (*_f)(const char*))
|
||||
{
|
||||
_start_trace = _a;
|
||||
_stop_trace = _b;
|
||||
_start_thread_trace = _c;
|
||||
_stop_thread_trace = _d;
|
||||
_push_region = _e;
|
||||
_pop_region = _f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
# ------------------------------------------------------------------------------#
|
||||
#
|
||||
# omnitrace interface library
|
||||
#
|
||||
# ------------------------------------------------------------------------------#
|
||||
|
||||
add_library(omnitrace-interface-library INTERFACE)
|
||||
add_library(omnitrace::omnitrace-interface-library ALIAS omnitrace-interface-library)
|
||||
|
||||
target_include_directories(
|
||||
omnitrace-interface-library INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
target_include_directories(omnitrace-interface-library SYSTEM
|
||||
INTERFACE ${perfetto_DIR}/sdk)
|
||||
|
||||
target_compile_definitions(
|
||||
omnitrace-interface-library
|
||||
INTERFACE OMNITRACE_MAX_THREADS=${OMNITRACE_MAX_THREADS}
|
||||
$<IF:$<BOOL:${OMNITRACE_CUSTOM_DATA_SOURCE}>,CUSTOM_DATA_SOURCE,>)
|
||||
|
||||
target_link_libraries(
|
||||
omnitrace-interface-library
|
||||
INTERFACE $<BUILD_INTERFACE:omnitrace::omnitrace-headers>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-threading>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-compile-options>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-hip>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-roctracer>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-rocm-smi>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-mpi>
|
||||
$<BUILD_INTERFACE:omnitrace::omnitrace-ptl>
|
||||
$<BUILD_INTERFACE:timemory::timemory-headers>
|
||||
$<BUILD_INTERFACE:timemory::timemory-gotcha>
|
||||
$<BUILD_INTERFACE:timemory::timemory-cxx-static>
|
||||
$<IF:$<BOOL:${OMNITRACE_USE_SANITIZER}>,omnitrace::omnitrace-sanitizer,>)
|
||||
|
||||
# ------------------------------------------------------------------------------#
|
||||
#
|
||||
# omnitrace object library
|
||||
#
|
||||
# ------------------------------------------------------------------------------#
|
||||
|
||||
add_library(omnitrace-object-library OBJECT)
|
||||
add_library(omnitrace::omnitrace-object-library ALIAS omnitrace-object-library)
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/library/defines.hpp.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include/library/defines.hpp @ONLY)
|
||||
|
||||
set(library_sources
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/api.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/config.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/cpu_freq.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/critical_trace.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/kokkosp.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/gpu.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/ompt.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/perfetto.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/ptl.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/sampling.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/state.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/thread_data.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/thread_sampler.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/timemory.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/components/backtrace.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/components/fork_gotcha.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/components/mpi_gotcha.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/components/omnitrace.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/components/pthread_gotcha.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/components/user_region.cpp
|
||||
${perfetto_DIR}/sdk/perfetto.cc)
|
||||
|
||||
set(library_headers
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/api.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/config.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/common.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/cpu_freq.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/critical_trace.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/debug.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/gpu.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/ompt.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/perfetto.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/ptl.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/sampling.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/state.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/thread_data.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/thread_sampler.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/timemory.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/fwd.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/backtrace.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/fork_gotcha.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/functors.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/mpi_gotcha.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/omnitrace.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/rocm_smi.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/roctracer.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/roctracer_callbacks.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/pthread_gotcha.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/library/components/user_region.hpp
|
||||
${perfetto_DIR}/sdk/perfetto.h)
|
||||
|
||||
target_sources(omnitrace-object-library PRIVATE ${library_sources} ${library_headers})
|
||||
|
||||
if(OMNITRACE_USE_ROCTRACER)
|
||||
target_sources(
|
||||
omnitrace-object-library
|
||||
PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/library/components/roctracer.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/library/components/roctracer_callbacks.cpp)
|
||||
endif()
|
||||
|
||||
if(OMNITRACE_USE_ROCM_SMI)
|
||||
target_sources(omnitrace-object-library
|
||||
PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/library/components/rocm_smi.cpp)
|
||||
endif()
|
||||
|
||||
target_link_libraries(omnitrace-object-library PRIVATE omnitrace-interface-library)
|
||||
|
||||
if(OMNITRACE_DYNINST_API_RT)
|
||||
get_filename_component(OMNITRACE_DYNINST_API_RT_DIR "${OMNITRACE_DYNINST_API_RT}"
|
||||
DIRECTORY)
|
||||
endif()
|
||||
|
||||
# ------------------------------------------------------------------------------#
|
||||
#
|
||||
# omnitrace shared library
|
||||
#
|
||||
# ------------------------------------------------------------------------------#
|
||||
|
||||
add_library(omnitrace-library SHARED $<TARGET_OBJECTS:omnitrace-object-library>)
|
||||
add_library(omnitrace::omnitrace-library ALIAS omnitrace-library)
|
||||
|
||||
target_link_libraries(omnitrace-library PRIVATE omnitrace-interface-library)
|
||||
|
||||
set_target_properties(
|
||||
omnitrace-library
|
||||
PROPERTIES OUTPUT_NAME omnitrace
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
INSTALL_RPATH
|
||||
"\$ORIGIN:\$ORIGIN/timemory/libunwind:\$ORIGIN/dyninst-tpls/libs")
|
||||
|
||||
install(
|
||||
TARGETS omnitrace-library
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
OPTIONAL)
|
||||
@@ -51,6 +51,12 @@ extern "C"
|
||||
/// stops an instrumentation region
|
||||
void omnitrace_pop_trace(const char* name) OMNITRACE_PUBLIC_API;
|
||||
|
||||
/// starts an instrumentation region (user-defined)
|
||||
void omnitrace_push_region(const char* name) OMNITRACE_PUBLIC_API;
|
||||
|
||||
/// stops an instrumentation region (user-defined)
|
||||
void omnitrace_pop_region(const char* name) OMNITRACE_PUBLIC_API;
|
||||
|
||||
// these are the real implementations for internal calling convention
|
||||
void omnitrace_init_library_hidden(void) OMNITRACE_HIDDEN_API;
|
||||
void omnitrace_init_hidden(const char*, bool, const char*) OMNITRACE_HIDDEN_API;
|
||||
@@ -60,4 +66,6 @@ extern "C"
|
||||
void omnitrace_set_mpi_hidden(bool use, bool attached) OMNITRACE_HIDDEN_API;
|
||||
void omnitrace_push_trace_hidden(const char* name) OMNITRACE_HIDDEN_API;
|
||||
void omnitrace_pop_trace_hidden(const char* name) OMNITRACE_HIDDEN_API;
|
||||
void omnitrace_push_region_hidden(const char* name) OMNITRACE_HIDDEN_API;
|
||||
void omnitrace_pop_region_hidden(const char* name) OMNITRACE_HIDDEN_API;
|
||||
}
|
||||
+14
@@ -68,6 +68,7 @@ using functor_t = std::function<void(Tp...)>;
|
||||
using default_functor_t = functor_t<const char*>;
|
||||
|
||||
struct omnitrace;
|
||||
struct user_region;
|
||||
struct backtrace;
|
||||
struct backtrace_wall_clock
|
||||
{};
|
||||
@@ -126,6 +127,8 @@ TIMEMORY_DEFINE_CONCRETE_TRAIT(is_available, omnitrace::component::sampling_gpu_
|
||||
|
||||
TIMEMORY_SET_COMPONENT_API(omnitrace::component::omnitrace, project::omnitrace,
|
||||
category::dynamic_instrumentation, os::supports_linux)
|
||||
TIMEMORY_SET_COMPONENT_API(omnitrace::component::user_region, project::omnitrace,
|
||||
os::supports_linux)
|
||||
TIMEMORY_SET_COMPONENT_API(omnitrace::component::roctracer, project::omnitrace,
|
||||
tpls::rocm, device::gpu, os::supports_linux,
|
||||
category::external)
|
||||
@@ -154,6 +157,8 @@ TIMEMORY_SET_COMPONENT_API(omnitrace::component::sampling_gpu_temp, project::omn
|
||||
|
||||
TIMEMORY_PROPERTY_SPECIALIZATION(omnitrace::component::omnitrace, OMNITRACE_COMPONENT,
|
||||
"omnitrace", "omnitrace_component")
|
||||
TIMEMORY_PROPERTY_SPECIALIZATION(omnitrace::component::user_region, OMNITRACE_USER_REGION,
|
||||
"user_region", "omnitrace_user_region")
|
||||
TIMEMORY_PROPERTY_SPECIALIZATION(omnitrace::component::roctracer, OMNITRACE_ROCTRACER,
|
||||
"roctracer", "omnitrace_roctracer")
|
||||
TIMEMORY_PROPERTY_SPECIALIZATION(omnitrace::component::sampling_wall_clock,
|
||||
@@ -173,6 +178,15 @@ TIMEMORY_PROPERTY_SPECIALIZATION(omnitrace::component::sampling_gpu_power,
|
||||
TIMEMORY_PROPERTY_SPECIALIZATION(omnitrace::component::sampling_gpu_temp,
|
||||
OMNITRACE_SAMPLING_GPU_TEMP, "sampling_gpu_temp", "")
|
||||
|
||||
TIMEMORY_METADATA_SPECIALIZATION(
|
||||
omnitrace::component::omnitrace, "omnitrace",
|
||||
"Invokes instrumentation functions 'omnitrace_push_trace' and 'omnitrace_pop_trace'",
|
||||
"Used by gotcha wrappers")
|
||||
TIMEMORY_METADATA_SPECIALIZATION(
|
||||
omnitrace::component::user_region, "user_region",
|
||||
"Invokes instrumentation functions 'omnitrace_user_push_region' and "
|
||||
"'omnitrace_user_pop_region'",
|
||||
"Used by OMPT")
|
||||
TIMEMORY_METADATA_SPECIALIZATION(omnitrace::component::roctracer, "roctracer",
|
||||
"High-precision ROCm API and kernel tracing", "")
|
||||
TIMEMORY_METADATA_SPECIALIZATION(omnitrace::component::sampling_wall_clock,
|
||||
-5
@@ -43,8 +43,3 @@ private:
|
||||
};
|
||||
} // namespace component
|
||||
} // namespace omnitrace
|
||||
|
||||
TIMEMORY_METADATA_SPECIALIZATION(
|
||||
omnitrace::component::omnitrace, "omnitrace",
|
||||
"Invokes instrumentation functions 'omnitrace_push_trace' and 'omnitrace_pop_trace'",
|
||||
"Used by gotcha wrappers")
|
||||
@@ -0,0 +1,56 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "library/defines.hpp"
|
||||
#include "library/timemory.hpp"
|
||||
|
||||
namespace omnitrace
|
||||
{
|
||||
namespace component
|
||||
{
|
||||
// timemory component which calls omnitrace functions
|
||||
// (used in gotcha wrappers)
|
||||
struct user_region : comp::base<user_region, void>
|
||||
{
|
||||
static std::string label() { return "user_region"; }
|
||||
void start();
|
||||
void stop();
|
||||
void set_prefix(const char*);
|
||||
|
||||
private:
|
||||
const char* m_prefix = nullptr;
|
||||
};
|
||||
} // namespace component
|
||||
} // namespace omnitrace
|
||||
|
||||
TIMEMORY_COMPONENT_ALIAS(omnitrace_user_region, omnitrace::component::user_region)
|
||||
|
||||
#if !defined(OMNITRACE_EXTERN_COMPONENTS) || \
|
||||
(defined(OMNITRACE_EXTERN_COMPONENTS) && OMNITRACE_EXTERN_COMPONENTS > 0)
|
||||
|
||||
# include <timemory/operations.hpp>
|
||||
|
||||
TIMEMORY_DECLARE_EXTERN_COMPONENT(omnitrace_user_region, false, void)
|
||||
|
||||
#endif
|
||||
+6
@@ -171,6 +171,9 @@ get_use_critical_trace();
|
||||
bool
|
||||
get_use_kokkosp();
|
||||
|
||||
bool
|
||||
get_use_ompt();
|
||||
|
||||
bool
|
||||
get_timeline_sampling();
|
||||
|
||||
@@ -245,6 +248,9 @@ get_critical_trace_per_row();
|
||||
State&
|
||||
get_state();
|
||||
|
||||
/// returns old state
|
||||
State set_state(State);
|
||||
|
||||
std::unique_ptr<main_bundle_t>&
|
||||
get_main_bundle();
|
||||
|
||||
+60
-4
@@ -30,6 +30,9 @@
|
||||
#include <timemory/utility/utility.hpp>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
namespace omnitrace
|
||||
{
|
||||
@@ -47,8 +50,32 @@ get_debug_pid();
|
||||
bool
|
||||
get_critical_trace_debug();
|
||||
} // namespace config
|
||||
|
||||
namespace debug
|
||||
{
|
||||
namespace
|
||||
{
|
||||
template <typename T, size_t... Idx>
|
||||
auto get_chars(std::index_sequence<Idx...>)
|
||||
{
|
||||
static const char _v[sizeof...(Idx) + 1] = { T::get()[Idx]..., '\0' };
|
||||
return _v;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto
|
||||
get_chars()
|
||||
{
|
||||
return get_chars<T>(typename T::sequence{});
|
||||
}
|
||||
} // namespace
|
||||
} // namespace debug
|
||||
} // namespace omnitrace
|
||||
|
||||
#define OMNITRACE_VAR_NAME_COMBINE(X, Y) X##Y
|
||||
#define OMNITRACE_LINESTR TIMEMORY_STRINGIZE(__LINE__)
|
||||
#define OMNITRACE_VARIABLE(LABEL) OMNITRACE_VAR_NAME_COMBINE(_omni_var_, LABEL)
|
||||
|
||||
#if defined(TIMEMORY_USE_MPI)
|
||||
# define OMNITRACE_PROCESS_IDENTIFIER static_cast<int>(::tim::dmp::rank())
|
||||
#elif defined(TIMEMORY_USE_MPI_HEADERS)
|
||||
@@ -59,6 +86,26 @@ get_critical_trace_debug();
|
||||
# define OMNITRACE_PROCESS_IDENTIFIER static_cast<int>(::tim::process::get_id())
|
||||
#endif
|
||||
|
||||
#define OMNITRACE_FUNCTION \
|
||||
std::string{ __FUNCTION__ } \
|
||||
.substr(0, std::string_view{ __FUNCTION__ }.find("_hidden")) \
|
||||
.c_str()
|
||||
|
||||
#define OMNITRACE_CT_FUNCTION(VAR, STR) \
|
||||
static constexpr auto OMNITRACE_VARIABLE(__LINE__) = std::string_view{ STR }; \
|
||||
VAR = OMNITRACE_CT_FUNCTION_IMPL(OMNITRACE_VARIABLE(__LINE__));
|
||||
|
||||
#define OMNITRACE_CT_FUNCTION_IMPL(STR) \
|
||||
[]() { \
|
||||
struct wrapper \
|
||||
{ \
|
||||
static constexpr const char* get() { return STR.data(); } \
|
||||
using sequence = \
|
||||
std::make_index_sequence<std::min(STR.find("_hidden"), STR.length())>; \
|
||||
}; \
|
||||
return ::omnitrace::debug::get_chars<wrapper>(); \
|
||||
}();
|
||||
|
||||
#define OMNITRACE_CONDITIONAL_PRINT(COND, ...) \
|
||||
if((COND) && ::omnitrace::config::get_debug_tid() && \
|
||||
::omnitrace::config::get_debug_pid()) \
|
||||
@@ -89,7 +136,7 @@ get_critical_trace_debug();
|
||||
fflush(stderr); \
|
||||
tim::auto_lock_t _lk{ tim::type_mutex<decltype(std::cerr)>() }; \
|
||||
fprintf(stderr, "[omnitrace][%i][%li][%s] ", OMNITRACE_PROCESS_IDENTIFIER, \
|
||||
tim::threading::get_id(), __FUNCTION__); \
|
||||
tim::threading::get_id(), OMNITRACE_FUNCTION); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
fflush(stderr); \
|
||||
}
|
||||
@@ -100,7 +147,7 @@ get_critical_trace_debug();
|
||||
{ \
|
||||
fflush(stderr); \
|
||||
tim::auto_lock_t _lk{ tim::type_mutex<decltype(std::cerr)>() }; \
|
||||
fprintf(stderr, "[omnitrace][%s] ", __FUNCTION__); \
|
||||
fprintf(stderr, "[omnitrace][%s] ", OMNITRACE_FUNCTION); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
fflush(stderr); \
|
||||
}
|
||||
@@ -110,7 +157,8 @@ get_critical_trace_debug();
|
||||
{ \
|
||||
char _msg_buffer[2048]; \
|
||||
snprintf(_msg_buffer, 2048, "[omnitrace][%i][%li][%s] ", \
|
||||
OMNITRACE_PROCESS_IDENTIFIER, tim::threading::get_id(), __FUNCTION__); \
|
||||
OMNITRACE_PROCESS_IDENTIFIER, tim::threading::get_id(), \
|
||||
OMNITRACE_FUNCTION); \
|
||||
auto len = strlen(_msg_buffer); \
|
||||
snprintf(_msg_buffer + len, 2048 - len, __VA_ARGS__); \
|
||||
throw std::runtime_error(_msg_buffer); \
|
||||
@@ -120,12 +168,20 @@ get_critical_trace_debug();
|
||||
if(COND) \
|
||||
{ \
|
||||
char _msg_buffer[2048]; \
|
||||
snprintf(_msg_buffer, 2048, "[omnitrace][%s] ", __FUNCTION__); \
|
||||
snprintf(_msg_buffer, 2048, "[omnitrace][%s] ", OMNITRACE_FUNCTION); \
|
||||
auto len = strlen(_msg_buffer); \
|
||||
snprintf(_msg_buffer + len, 2048 - len, __VA_ARGS__); \
|
||||
throw std::runtime_error(_msg_buffer); \
|
||||
}
|
||||
|
||||
#define OMNITRACE_CI_THROW(COND, ...) \
|
||||
OMNITRACE_CONDITIONAL_THROW(::omnitrace::get_is_continuous_integration() && (COND), \
|
||||
__VA_ARGS__)
|
||||
|
||||
#define OMNITRACE_CI_BASIC_THROW(COND, ...) \
|
||||
OMNITRACE_CONDITIONAL_BASIC_THROW( \
|
||||
::omnitrace::get_is_continuous_integration() && (COND), __VA_ARGS__)
|
||||
|
||||
#define OMNITRACE_STRINGIZE(...) #__VA_ARGS__
|
||||
#define OMNITRACE_ESC(...) __VA_ARGS__
|
||||
|
||||
+6
-4
@@ -36,12 +36,14 @@
|
||||
// clang-format on
|
||||
|
||||
#define TIMEMORY_USER_COMPONENT_ENUM \
|
||||
OMNITRACE_COMPONENT_idx, OMNITRACE_ROCTRACER_idx, OMNITRACE_SAMPLING_WALL_CLOCK_idx, \
|
||||
OMNITRACE_SAMPLING_CPU_CLOCK_idx, OMNITRACE_SAMPLING_PERCENT_idx, \
|
||||
OMNITRACE_SAMPLING_GPU_POWER_idx, OMNITRACE_SAMPLING_GPU_TEMP_idx, \
|
||||
OMNITRACE_SAMPLING_GPU_BUSY_idx, OMNITRACE_SAMPLING_GPU_MEMORY_USAGE_idx,
|
||||
OMNITRACE_COMPONENT_idx, OMNITRACE_USER_REGION_idx, OMNITRACE_ROCTRACER_idx, \
|
||||
OMNITRACE_SAMPLING_WALL_CLOCK_idx, OMNITRACE_SAMPLING_CPU_CLOCK_idx, \
|
||||
OMNITRACE_SAMPLING_PERCENT_idx, OMNITRACE_SAMPLING_GPU_POWER_idx, \
|
||||
OMNITRACE_SAMPLING_GPU_TEMP_idx, OMNITRACE_SAMPLING_GPU_BUSY_idx, \
|
||||
OMNITRACE_SAMPLING_GPU_MEMORY_USAGE_idx,
|
||||
|
||||
#define OMNITRACE_COMPONENT OMNITRACE_COMPONENT_idx
|
||||
#define OMNITRACE_USER_REGION OMNITRACE_USER_REGION_idx
|
||||
#define OMNITRACE_ROCTRACER OMNITRACE_ROCTRACER_idx
|
||||
#define OMNITRACE_SAMPLING_WALL_CLOCK OMNITRACE_SAMPLING_WALL_CLOCK_idx
|
||||
#define OMNITRACE_SAMPLING_CPU_CLOCK OMNITRACE_SAMPLING_CPU_CLOCK_idx
|
||||
@@ -0,0 +1,35 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace omnitrace
|
||||
{
|
||||
namespace ompt
|
||||
{
|
||||
void
|
||||
setup();
|
||||
|
||||
void
|
||||
shutdown();
|
||||
} // namespace ompt
|
||||
} // namespace omnitrace
|
||||
+2
@@ -33,6 +33,7 @@
|
||||
# define PERFETTO_CATEGORIES \
|
||||
perfetto::Category("host").SetDescription("Host-side function tracing"), \
|
||||
perfetto::Category("device").SetDescription("Device-side function tracing"), \
|
||||
perfetto::Category("user").SetDescription("User-defined regions"), \
|
||||
perfetto::Category("rocm_smi").SetDescription("Device-level metrics"), \
|
||||
perfetto::Category("sampling") \
|
||||
.SetDescription("Metrics derived from sampling"), \
|
||||
@@ -46,6 +47,7 @@
|
||||
# define PERFETTO_CATEGORIES \
|
||||
perfetto::Category("host").SetDescription("Host-side function tracing"), \
|
||||
perfetto::Category("device").SetDescription("Device-side function tracing"), \
|
||||
perfetto::Category("user").SetDescription("User-defined regions"), \
|
||||
perfetto::Category("rocm_smi").SetDescription("Device-level metrics"), \
|
||||
perfetto::Category("sampling") \
|
||||
.SetDescription("Metrics derived from sampling"), \
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "library/debug.hpp"
|
||||
#include "library/defines.hpp"
|
||||
#include "library/gpu.hpp"
|
||||
#include "library/ompt.hpp"
|
||||
#include "library/ptl.hpp"
|
||||
#include "library/sampling.hpp"
|
||||
#include "library/thread_data.hpp"
|
||||
@@ -46,10 +47,22 @@ using namespace omnitrace;
|
||||
|
||||
//======================================================================================//
|
||||
|
||||
using library_functors = omnitrace::component::functors<omnitrace::api::omnitrace>;
|
||||
namespace
|
||||
{
|
||||
struct omni_regions
|
||||
{};
|
||||
struct user_regions
|
||||
{};
|
||||
} // namespace
|
||||
|
||||
TIMEMORY_DEFINE_NAME_TRAIT("cpu_instrumentation", library_functors);
|
||||
TIMEMORY_INVOKE_PREINIT(library_functors)
|
||||
using omni_functors = omnitrace::component::functors<omni_regions>;
|
||||
using user_functors = omnitrace::component::functors<user_regions>;
|
||||
|
||||
// TIMEMORY_DEFINE_NAME_TRAIT("host", omni_functors);
|
||||
// TIMEMORY_DEFINE_NAME_TRAIT("user", user_functors);
|
||||
|
||||
TIMEMORY_INVOKE_PREINIT(omni_functors)
|
||||
TIMEMORY_INVOKE_PREINIT(user_functors)
|
||||
|
||||
//======================================================================================//
|
||||
|
||||
@@ -159,6 +172,9 @@ pop_count()
|
||||
}
|
||||
|
||||
auto _debug_push = tim::get_env("OMNITRACE_DEBUG_PUSH", false) && !get_debug_env();
|
||||
auto _debug_pop = tim::get_env("OMNITRACE_DEBUG_POP", false) && !get_debug_env();
|
||||
auto _debug_user =
|
||||
tim::get_env("OMNITRACE_DEBUG_USER_REGIONS", false) && !get_debug_env();
|
||||
} // namespace
|
||||
|
||||
//======================================================================================//
|
||||
@@ -172,11 +188,11 @@ omnitrace_push_trace_hidden(const char* name)
|
||||
if(get_state() == State::Finalized)
|
||||
{
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(
|
||||
_debug_push, "%s(%s) called during finalization\n", __FUNCTION__, name);
|
||||
_debug_push, "omnitrace_push_trace(%s) called during finalization\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(_debug_push, "%s(%s)\n", __FUNCTION__, name);
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(_debug_push, "omnitrace_push_trace(%s)\n", name);
|
||||
|
||||
// the expectation here is that if the state is not active then the call
|
||||
// to omnitrace_init_tooling_hidden will activate all the appropriate
|
||||
@@ -184,12 +200,13 @@ omnitrace_push_trace_hidden(const char* name)
|
||||
if(get_state() != State::Active && !omnitrace_init_tooling_hidden())
|
||||
{
|
||||
static auto _debug = get_debug_env() || get_debug_init();
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT_F(_debug, "%s :: not active. state = %s\n",
|
||||
name, std::to_string(get_state()).c_str());
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(
|
||||
_debug, "omnitrace_push_trace(%s) ignored :: not active. state = %s\n", name,
|
||||
std::to_string(get_state()).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
OMNITRACE_DEBUG_F("%s\n", name);
|
||||
OMNITRACE_DEBUG("omnitrace_push_trace(%s)\n", name);
|
||||
|
||||
static auto _sample_rate = std::max<size_t>(get_instrumentation_interval(), 1);
|
||||
static thread_local size_t _sample_idx = 0;
|
||||
@@ -197,7 +214,7 @@ omnitrace_push_trace_hidden(const char* name)
|
||||
auto _enabled = (_sample_idx++ % _sample_rate == 0);
|
||||
|
||||
_interval->emplace_back(_enabled);
|
||||
if(_enabled) library_functors::start(name);
|
||||
if(_enabled) omni_functors::start(name);
|
||||
if(get_use_critical_trace())
|
||||
{
|
||||
uint64_t _cid = 0;
|
||||
@@ -222,15 +239,17 @@ omnitrace_pop_trace_hidden(const char* name)
|
||||
{
|
||||
++pop_count();
|
||||
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(_debug_pop, "omnitrace_pop_trace(%s)\n", name);
|
||||
|
||||
// only execute when active
|
||||
if(get_state() == State::Active)
|
||||
{
|
||||
OMNITRACE_DEBUG_F("%s\n", name);
|
||||
OMNITRACE_DEBUG("omnitrace_pop_trace(%s)\n", name);
|
||||
|
||||
auto& _interval_data = get_interval_data();
|
||||
if(!_interval_data->empty())
|
||||
{
|
||||
if(_interval_data->back()) library_functors::stop(name);
|
||||
if(_interval_data->back()) omni_functors::stop(name);
|
||||
_interval_data->pop_back();
|
||||
}
|
||||
|
||||
@@ -255,9 +274,64 @@ omnitrace_pop_trace_hidden(const char* name)
|
||||
else
|
||||
{
|
||||
static auto _debug = get_debug_env();
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(_debug, "[%s] %s ignored :: state = %s\n",
|
||||
__FUNCTION__, name,
|
||||
std::to_string(get_state()).c_str());
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(
|
||||
_debug, "omnitrace_pop_trace(%s) ignored :: state = %s\n", name,
|
||||
std::to_string(get_state()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================================//
|
||||
///
|
||||
///
|
||||
///
|
||||
//======================================================================================//
|
||||
|
||||
extern "C" void
|
||||
omnitrace_push_region_hidden(const char* name)
|
||||
{
|
||||
// unconditionally return if finalized
|
||||
if(get_state() == State::Finalized)
|
||||
{
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(
|
||||
_debug_user, "omnitrace_push_region(%s) called during finalization\n", name);
|
||||
return;
|
||||
}
|
||||
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(_debug_push, "omnitrace_push_region(%s)\n", name);
|
||||
|
||||
// the expectation here is that if the state is not active then the call
|
||||
// to omnitrace_init_tooling_hidden will activate all the appropriate
|
||||
// tooling one time and as it exits set it to active and return true.
|
||||
if(get_state() != State::Active && !omnitrace_init_tooling_hidden())
|
||||
{
|
||||
static auto _debug = get_debug_env() || get_debug_init();
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(
|
||||
_debug, "omnitrace_push_region(%s) ignored :: not active. state = %s\n", name,
|
||||
std::to_string(get_state()).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
OMNITRACE_DEBUG("omnitrace_push_region(%s)\n", name);
|
||||
user_functors::start(name);
|
||||
}
|
||||
|
||||
//======================================================================================//
|
||||
|
||||
extern "C" void
|
||||
omnitrace_pop_region_hidden(const char* name)
|
||||
{
|
||||
// only execute when active
|
||||
if(get_state() == State::Active)
|
||||
{
|
||||
OMNITRACE_DEBUG("omnitrace_pop_region(%s)\n", name);
|
||||
user_functors::stop(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
static auto _debug = get_debug_env();
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(
|
||||
_debug, "omnitrace_pop_region(%s) ignored :: state = %s\n", name,
|
||||
std::to_string(get_state()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,7 +345,7 @@ extern "C" void
|
||||
omnitrace_set_env_hidden(const char* env_name, const char* env_val)
|
||||
{
|
||||
// just search env to avoid initializing the settings
|
||||
OMNITRACE_CONDITIONAL_PRINT(get_debug_env() || get_verbose_env() > 2,
|
||||
OMNITRACE_CONDITIONAL_PRINT(get_debug_init() || get_verbose_env() > 2,
|
||||
"[%s] Setting env: %s=%s\n", __FUNCTION__, env_name,
|
||||
env_val);
|
||||
|
||||
@@ -279,9 +353,10 @@ omnitrace_set_env_hidden(const char* env_name, const char* env_val)
|
||||
|
||||
OMNITRACE_CONDITIONAL_THROW(
|
||||
get_state() >= State::Init &&
|
||||
(config::get_is_continuous_integration() || get_debug_env()),
|
||||
"%s(\"%s\", \"%s\") called after omnitrace was initialized. state = %s",
|
||||
__FUNCTION__, env_name, env_val, std::to_string(get_state()).c_str());
|
||||
(config::get_is_continuous_integration() || get_debug_init()),
|
||||
"omnitrace_set_env(\"%s\", \"%s\") called after omnitrace was initialized. state "
|
||||
"= %s",
|
||||
env_name, env_val, std::to_string(get_state()).c_str());
|
||||
}
|
||||
|
||||
//======================================================================================//
|
||||
@@ -300,7 +375,7 @@ extern "C" void
|
||||
omnitrace_set_mpi_hidden(bool use, bool attached)
|
||||
{
|
||||
// just search env to avoid initializing the settings
|
||||
OMNITRACE_CONDITIONAL_PRINT(get_debug_env() || get_verbose_env() > 2,
|
||||
OMNITRACE_CONDITIONAL_PRINT(get_debug_init() || get_verbose_env() > 2,
|
||||
"[%s] use: %s, attached: %s\n", __FUNCTION__,
|
||||
(use) ? "y" : "n", (attached) ? "y" : "n");
|
||||
|
||||
@@ -319,9 +394,10 @@ omnitrace_set_mpi_hidden(bool use, bool attached)
|
||||
|
||||
OMNITRACE_CONDITIONAL_THROW(
|
||||
get_state() >= State::Init &&
|
||||
(config::get_is_continuous_integration() || get_debug_env()),
|
||||
"%s(use=%s, attached=%s) called after omnitrace was initialized. state = %s",
|
||||
__FUNCTION__, std::to_string(use).c_str(), std::to_string(attached).c_str(),
|
||||
(config::get_is_continuous_integration() || get_debug_init()),
|
||||
"omnitrace_set_mpi(use=%s, attached=%s) called after omnitrace was initialized. "
|
||||
"state = %s",
|
||||
std::to_string(use).c_str(), std::to_string(attached).c_str(),
|
||||
std::to_string(get_state()).c_str());
|
||||
|
||||
_start_gotcha_callback();
|
||||
@@ -335,23 +411,37 @@ omnitrace_init_library_hidden()
|
||||
auto _tid = threading::get_id();
|
||||
(void) _tid;
|
||||
|
||||
auto _mode = get_mode();
|
||||
auto _debug_init = get_debug_init();
|
||||
static bool _once = false;
|
||||
auto _mode = get_mode();
|
||||
auto _debug_init = get_debug_init();
|
||||
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT_F(_debug_init, "State is %s...\n",
|
||||
std::to_string(get_state()).c_str());
|
||||
|
||||
OMNITRACE_CI_THROW(get_state() != State::PreInit, "State is not PreInit :: %s",
|
||||
std::to_string(get_state()).c_str());
|
||||
|
||||
if(get_state() != State::PreInit || get_state() == State::Init || _once) return;
|
||||
_once = true;
|
||||
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT_F(_debug_init, "State is %s. Setting to %s...\n",
|
||||
std::to_string(get_state()).c_str(),
|
||||
std::to_string(State::Init).c_str());
|
||||
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT_F(
|
||||
_debug_init, "Calling backtrace once so that the one-time call of malloc in "
|
||||
"glibc's backtrace() occurs...\n");
|
||||
{
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT_F(
|
||||
_debug_init, "Calling backtrace once so that the one-time call of malloc in "
|
||||
"glibc's backtrace() occurs...\n");
|
||||
std::stringstream _ss{};
|
||||
tim::print_backtrace<64>(_ss);
|
||||
(void) _ss;
|
||||
}
|
||||
|
||||
get_state() = State::Init;
|
||||
set_state(State::Init);
|
||||
|
||||
OMNITRACE_CI_THROW(get_state() != State::Init,
|
||||
"set_state(State::Init) failed. state is %s",
|
||||
std::to_string(get_state()).c_str());
|
||||
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT_F(_debug_init, "Configuring settings...\n");
|
||||
|
||||
@@ -395,8 +485,9 @@ omnitrace_init_library_hidden()
|
||||
|
||||
if(get_use_kokkosp())
|
||||
{
|
||||
auto _force = 0;
|
||||
if(tim::get_env<std::string>("KOKKOS_PROFILE_LIBRARY") == "libtimemory.so")
|
||||
auto _force = 0;
|
||||
auto _current_kokkosp_lib = tim::get_env<std::string>("KOKKOS_PROFILE_LIBRARY");
|
||||
if(std::regex_search(_current_kokkosp_lib, std::regex{ "libtimemory\\." }))
|
||||
_force = 1;
|
||||
tim::set_env("KOKKOS_PROFILE_LIBRARY", "libomnitrace.so", _force);
|
||||
}
|
||||
@@ -537,8 +628,12 @@ omnitrace_init_tooling_hidden()
|
||||
return true;
|
||||
}();
|
||||
static thread_local auto _dtor = scope::destructor{ []() {
|
||||
if(get_use_sampling()) sampling::shutdown();
|
||||
thread_data<omnitrace_thread_bundle_t>::instance()->stop();
|
||||
if(get_state() != State::Finalized)
|
||||
{
|
||||
if(get_use_sampling()) sampling::shutdown();
|
||||
if(thread_data<omnitrace_thread_bundle_t>::instance())
|
||||
thread_data<omnitrace_thread_bundle_t>::instance()->stop();
|
||||
}
|
||||
} };
|
||||
(void) _thread_setup;
|
||||
(void) _dtor;
|
||||
@@ -555,7 +650,7 @@ omnitrace_init_tooling_hidden()
|
||||
(void) _v;
|
||||
};
|
||||
|
||||
// functors for starting and stopping timemory
|
||||
// functors for starting and stopping timemory omni functors
|
||||
auto _push_timemory = [](const char* name) {
|
||||
auto& _data = get_instrumentation_bundles();
|
||||
// this generates a hash for the raw string array
|
||||
@@ -566,11 +661,6 @@ omnitrace_init_tooling_hidden()
|
||||
_bundle->start();
|
||||
};
|
||||
|
||||
auto _push_perfetto = [](const char* name) {
|
||||
uint64_t _ts = comp::wall_clock::record();
|
||||
TRACE_EVENT_BEGIN("host", perfetto::StaticString(name), _ts);
|
||||
};
|
||||
|
||||
auto _pop_timemory = [](const char* name) {
|
||||
auto _hash = tim::hash::get_hash_id(tim::string_view_t{ name });
|
||||
auto& _data = get_instrumentation_bundles();
|
||||
@@ -593,14 +683,33 @@ 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 _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);
|
||||
};
|
||||
|
||||
if(get_use_perfetto() && get_use_timemory())
|
||||
{
|
||||
library_functors::configure(
|
||||
omni_functors::configure(
|
||||
[=](const char* name) {
|
||||
_thread_init();
|
||||
_push_perfetto(name);
|
||||
@@ -611,20 +720,44 @@ omnitrace_init_tooling_hidden()
|
||||
_pop_timemory(name);
|
||||
_pop_perfetto(name);
|
||||
});
|
||||
user_functors::configure(
|
||||
[=](const char* name) {
|
||||
_thread_init();
|
||||
_push_user_perfetto(name);
|
||||
_push_timemory(name);
|
||||
},
|
||||
[=](const char* name) {
|
||||
_pop_timemory(name);
|
||||
_pop_user_perfetto(name);
|
||||
});
|
||||
}
|
||||
else if(get_use_perfetto())
|
||||
{
|
||||
library_functors::configure(
|
||||
omni_functors::configure(
|
||||
[=](const char* name) {
|
||||
_thread_init();
|
||||
_push_perfetto(name);
|
||||
_setup_thread_sampling();
|
||||
},
|
||||
[=](const char* name) { _pop_perfetto(name); });
|
||||
user_functors::configure(
|
||||
[=](const char* name) {
|
||||
_thread_init();
|
||||
_push_user_perfetto(name);
|
||||
_setup_thread_sampling();
|
||||
},
|
||||
[=](const char* name) { _pop_user_perfetto(name); });
|
||||
}
|
||||
else if(get_use_timemory())
|
||||
{
|
||||
library_functors::configure(
|
||||
omni_functors::configure(
|
||||
[=](const char* name) {
|
||||
_thread_init();
|
||||
_push_timemory(name);
|
||||
_setup_thread_sampling();
|
||||
},
|
||||
[=](const char* name) { _pop_timemory(name); });
|
||||
user_functors::configure(
|
||||
[=](const char* name) {
|
||||
_thread_init();
|
||||
_push_timemory(name);
|
||||
@@ -633,6 +766,8 @@ omnitrace_init_tooling_hidden()
|
||||
[=](const char* name) { _pop_timemory(name); });
|
||||
}
|
||||
|
||||
ompt::setup();
|
||||
|
||||
if(get_use_perfetto() && !is_system_backend())
|
||||
{
|
||||
#if defined(CUSTOM_DATA_SOURCE)
|
||||
@@ -676,9 +811,16 @@ omnitrace_init_hidden(const char* _mode, bool _is_binary_rewrite, const char* _a
|
||||
(void) pop_count();
|
||||
|
||||
get_finalization_functions().emplace_back([_argv0]() {
|
||||
// if main hasn't been popped yet, pop it
|
||||
OMNITRACE_BASIC_PRINT("Running omnitrace_pop_trace(%s)...\n", _argv0);
|
||||
omnitrace_pop_trace_hidden(_argv0);
|
||||
OMNITRACE_CI_THROW(get_state() != State::Active,
|
||||
"Finalizer function for popping main invoked in non-active "
|
||||
"state :: state = %s\n",
|
||||
std::to_string(get_state()).c_str());
|
||||
if(get_state() == State::Active)
|
||||
{
|
||||
// if main hasn't been popped yet, pop it
|
||||
OMNITRACE_BASIC_VERBOSE(2, "Running omnitrace_pop_trace(%s)...\n", _argv0);
|
||||
omnitrace_pop_trace_hidden(_argv0);
|
||||
}
|
||||
});
|
||||
|
||||
std::atexit([]() {
|
||||
@@ -740,9 +882,10 @@ omnitrace_finalize_hidden(void)
|
||||
}
|
||||
}
|
||||
|
||||
get_state() = State::Finalized;
|
||||
set_state(State::Finalized);
|
||||
|
||||
library_functors::configure([](const char*) {}, [](const char*) {});
|
||||
omni_functors::configure([](const char*) {}, [](const char*) {});
|
||||
user_functors::configure([](const char*) {}, [](const char*) {});
|
||||
|
||||
pthread_gotcha::push_enable_sampling_on_child_threads(false);
|
||||
pthread_gotcha::set_sampling_on_all_future_threads(false);
|
||||
@@ -785,6 +928,8 @@ omnitrace_finalize_hidden(void)
|
||||
}
|
||||
}
|
||||
|
||||
ompt::shutdown();
|
||||
|
||||
OMNITRACE_DEBUG_F("Stopping and destroying instrumentation bundles...\n");
|
||||
for(auto& itr : instrumentation_bundles::instances())
|
||||
{
|
||||
@@ -34,6 +34,18 @@ omnitrace_pop_trace(const char* _name)
|
||||
omnitrace_pop_trace_hidden(_name);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
omnitrace_push_region(const char* _name)
|
||||
{
|
||||
omnitrace_push_region_hidden(_name);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
omnitrace_pop_region(const char* _name)
|
||||
{
|
||||
omnitrace_pop_region_hidden(_name);
|
||||
}
|
||||
|
||||
extern "C" void
|
||||
omnitrace_init_library(void)
|
||||
{
|
||||
+4
-2
@@ -231,7 +231,7 @@ backtrace::get_thread_cpu_timestamp() const
|
||||
void
|
||||
backtrace::sample(int signum)
|
||||
{
|
||||
if(get_state() != State::Active)
|
||||
if(signum != -1 && get_state() != State::Active)
|
||||
{
|
||||
OMNITRACE_CONDITIONAL_PRINT(
|
||||
get_debug_sampling(),
|
||||
@@ -341,7 +341,6 @@ backtrace::configure(bool _setup, int64_t _tid)
|
||||
|
||||
OMNITRACE_DEBUG("Configuring sampler for thread %lu...\n", _tid);
|
||||
sampler_running_instances::construct(true);
|
||||
backtrace_init_instances::construct();
|
||||
sampling::sampler_instances::construct("omnitrace", _tid, *_signal_types);
|
||||
_sampler->set_signals(*_signal_types);
|
||||
_sampler->set_flags(SA_RESTART);
|
||||
@@ -363,6 +362,7 @@ backtrace::configure(bool _setup, int64_t _tid)
|
||||
_sampler->get_rate(units::sec));
|
||||
|
||||
// (void) sampling::sampler_t::get_samplers(_tid);
|
||||
backtrace_init_instances::construct();
|
||||
get_backtrace_init(_tid)->sample();
|
||||
_sampler->configure(false);
|
||||
_sampler->start();
|
||||
@@ -617,6 +617,8 @@ backtrace::post_process(int64_t _tid)
|
||||
|
||||
auto* _bt = ditr->get<backtrace>();
|
||||
|
||||
if(_bt->m_ts < _last_wall_ts) continue;
|
||||
|
||||
double _elapsed_wc = (_bt->m_ts - _last_wall_ts).count();
|
||||
double _elapsed_cc = (_bt->m_thr_cpu_ts - _last_cpu_ts);
|
||||
|
||||
+3
-4
@@ -86,8 +86,7 @@ mpi_gotcha::audit(const gotcha_data_t& _data, audit::incoming, int*, char***)
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(get_debug_env(), "[%s] %s(int*, char***)\n",
|
||||
__FUNCTION__, _data.tool_id.c_str());
|
||||
|
||||
if(get_state() == ::omnitrace::State::DelayedInit)
|
||||
get_state() = ::omnitrace::State::PreInit;
|
||||
if(get_state() < ::omnitrace::State::Init) set_state(::omnitrace::State::PreInit);
|
||||
|
||||
omnitrace_push_trace_hidden(_data.tool_id.c_str());
|
||||
#if !defined(TIMEMORY_USE_MPI) && defined(TIMEMORY_USE_MPI_HEADERS)
|
||||
@@ -102,8 +101,8 @@ mpi_gotcha::audit(const gotcha_data_t& _data, audit::incoming, int*, char***, in
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(get_debug_env(),
|
||||
"[%s] %s(int*, char***, int, int*)\n", __FUNCTION__,
|
||||
_data.tool_id.c_str());
|
||||
if(get_state() == ::omnitrace::State::DelayedInit)
|
||||
get_state() = ::omnitrace::State::PreInit;
|
||||
|
||||
if(get_state() < ::omnitrace::State::Init) set_state(::omnitrace::State::PreInit);
|
||||
|
||||
omnitrace_push_trace_hidden(_data.tool_id.c_str());
|
||||
#if !defined(TIMEMORY_USE_MPI) && defined(TIMEMORY_USE_MPI_HEADERS)
|
||||
+2
@@ -140,6 +140,8 @@ pthread_gotcha::wrapper::operator()() const
|
||||
{
|
||||
_tid = threading::get_id();
|
||||
threading::set_thread_name(TIMEMORY_JOIN(" ", "Thread", _tid).c_str());
|
||||
// initialize thread-local statics
|
||||
(void) tim::get_unw_backtrace<12, 1, false>();
|
||||
{
|
||||
std::unique_lock<std::mutex> _lk{ bundles_mutex };
|
||||
if(comp::roctracer::is_setup())
|
||||
+5
-59
@@ -86,7 +86,7 @@ check_error(rsmi_status_t ec)
|
||||
}
|
||||
|
||||
std::atomic<State>&
|
||||
get_rocm_smi_state()
|
||||
get_state()
|
||||
{
|
||||
static std::atomic<State> _v{ State::PreInit };
|
||||
return _v;
|
||||
@@ -151,7 +151,7 @@ config()
|
||||
void
|
||||
sample()
|
||||
{
|
||||
if(get_rocm_smi_state() != State::Active) return;
|
||||
if(rocm_smi::get_state() != State::Active) return;
|
||||
|
||||
for(auto itr : data::device_list)
|
||||
{
|
||||
@@ -168,63 +168,9 @@ sample()
|
||||
void
|
||||
set_state(State _v)
|
||||
{
|
||||
get_rocm_smi_state().store(_v);
|
||||
rocm_smi::get_state().store(_v);
|
||||
}
|
||||
|
||||
/*
|
||||
void
|
||||
data::poll(std::atomic<State>* _state, nsec_t _interval, promise_t* _ready)
|
||||
{
|
||||
threading::set_thread_name("omni.rocm_smi");
|
||||
|
||||
// notify thread started
|
||||
if(_ready) _ready->set_value();
|
||||
|
||||
std::vector<std::unique_ptr<bundle_t>*> _bundle_data{};
|
||||
_bundle_data.resize(device_count, nullptr);
|
||||
for(size_t i = 0; i < device_count; ++i)
|
||||
{
|
||||
if(device_list.count(i) > 0)
|
||||
{
|
||||
_bundle_data.at(i) = &sampler_instances::instances().at(i);
|
||||
if(!*_bundle_data.at(i)) *_bundle_data.at(i) = std::make_unique<bundle_t>();
|
||||
}
|
||||
}
|
||||
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(
|
||||
get_verbose() > 0 || get_debug(),
|
||||
"Polling rocm-smi for %zu device(s) at an interval of %f seconds...\n",
|
||||
device_list.size(),
|
||||
std::chrono::duration_cast<std::chrono::duration<double>>(_interval).count());
|
||||
|
||||
get_initial().resize(device_count);
|
||||
for(auto itr : device_list)
|
||||
get_initial().at(itr).sample(itr);
|
||||
|
||||
auto _now = std::chrono::steady_clock::now();
|
||||
while(_state && _state->load() != State::Finalized && get_state() != State::Finalized)
|
||||
{
|
||||
std::this_thread::sleep_until(_now);
|
||||
if(_state->load() != State::Active) continue;
|
||||
for(auto itr : device_list)
|
||||
{
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(get_debug(),
|
||||
"Polling rocm-smi for device %u...\n", itr);
|
||||
auto& _data = *_bundle_data.at(itr);
|
||||
if(!_data) continue;
|
||||
_data->emplace_back(data{ itr });
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(get_debug(), " %s\n",
|
||||
TIMEMORY_JOIN("", _data->back()).c_str());
|
||||
}
|
||||
while(_now < std::chrono::steady_clock::now())
|
||||
_now += _interval;
|
||||
}
|
||||
OMNITRACE_CONDITIONAL_BASIC_PRINT(get_debug(), "Polling rocm-smi completed...\n");
|
||||
|
||||
if(polling_finished) polling_finished->set_value();
|
||||
}
|
||||
*/
|
||||
|
||||
std::vector<data>&
|
||||
data::get_initial()
|
||||
{
|
||||
@@ -236,7 +182,7 @@ bool
|
||||
data::setup()
|
||||
{
|
||||
perfetto_counter_track<data>::init();
|
||||
set_state(State::PreInit);
|
||||
rocm_smi::set_state(State::PreInit);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -244,7 +190,7 @@ bool
|
||||
data::shutdown()
|
||||
{
|
||||
OMNITRACE_DEBUG("Shutting down rocm-smi...\n");
|
||||
set_state(State::Finalized);
|
||||
rocm_smi::set_state(State::Finalized);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include "library/components/user_region.hpp"
|
||||
#include "library/api.hpp"
|
||||
#include "library/components/fwd.hpp"
|
||||
|
||||
namespace omnitrace
|
||||
{
|
||||
namespace component
|
||||
{
|
||||
void
|
||||
user_region::start()
|
||||
{
|
||||
if(m_prefix) omnitrace_push_region_hidden(m_prefix);
|
||||
}
|
||||
|
||||
void
|
||||
user_region::stop()
|
||||
{
|
||||
if(m_prefix) omnitrace_pop_region_hidden(m_prefix);
|
||||
}
|
||||
|
||||
void
|
||||
user_region::set_prefix(const char* _prefix)
|
||||
{
|
||||
m_prefix = _prefix;
|
||||
}
|
||||
} // namespace component
|
||||
} // namespace omnitrace
|
||||
|
||||
TIMEMORY_INITIALIZE_STORAGE(omnitrace::component::user_region)
|
||||
TIMEMORY_INSTANTIATE_EXTERN_COMPONENT(omnitrace_user_region, false, void)
|
||||
@@ -150,6 +150,12 @@ configure_settings()
|
||||
"Enable support for Kokkos Tools", false, "kokkos",
|
||||
"backend");
|
||||
|
||||
#if defined(TIMEMORY_USE_OMPT)
|
||||
OMNITRACE_CONFIG_SETTING(bool, "OMNITRACE_USE_OMPT",
|
||||
"Enable support for OpenMP-Tools", true, "openmp", "ompt",
|
||||
"backend");
|
||||
#endif
|
||||
|
||||
OMNITRACE_CONFIG_SETTING(size_t, "OMNITRACE_INSTRUMENTATION_INTERVAL",
|
||||
"Instrumentation only takes measurements once every N "
|
||||
"function calls (not statistical)",
|
||||
@@ -736,6 +742,17 @@ get_use_kokkosp()
|
||||
return static_cast<tim::tsettings<bool>&>(*_v->second).get();
|
||||
}
|
||||
|
||||
bool
|
||||
get_use_ompt()
|
||||
{
|
||||
#if defined(TIMEMORY_USE_OMPT)
|
||||
static auto _v = get_config()->find("OMNITRACE_USE_OMPT");
|
||||
return static_cast<tim::tsettings<bool>&>(*_v->second).get();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
get_critical_trace_debug()
|
||||
{
|
||||
@@ -956,6 +973,20 @@ get_state()
|
||||
return _v;
|
||||
}
|
||||
|
||||
State
|
||||
set_state(State _n)
|
||||
{
|
||||
auto _o = get_state();
|
||||
OMNITRACE_CONDITIONAL_PRINT_F(get_debug_init(), "Setting state :: %s -> %s\n",
|
||||
std::to_string(_o).c_str(), std::to_string(_n).c_str());
|
||||
// state should always be increased, not decreased
|
||||
OMNITRACE_CI_BASIC_THROW(_n < _o,
|
||||
"State is being assigned to a lesser value :: %s -> %s",
|
||||
std::to_string(_o).c_str(), std::to_string(_n).c_str());
|
||||
get_state() = _n;
|
||||
return _o;
|
||||
}
|
||||
|
||||
std::atomic<uint64_t>&
|
||||
get_cpu_cid()
|
||||
{
|
||||
@@ -22,10 +22,9 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
// used by Kokkos decls
|
||||
#if !defined(TIMEMORY_LIBRARY_SOURCE)
|
||||
# define TIMEMORY_LIBRARY_SOURCE 1
|
||||
#endif
|
||||
#include "library/defines.hpp"
|
||||
|
||||
#define TIMEMORY_KOKKOSP_POSTFIX OMNITRACE_PUBLIC_API
|
||||
|
||||
#include "library/components/omnitrace.hpp"
|
||||
#include "library/config.hpp"
|
||||
@@ -0,0 +1,114 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2020, The Regents of the University of California,
|
||||
// through Lawrence Berkeley National Laboratory (subject to receipt of any
|
||||
// required approvals from the U.S. Dept. of Energy). All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include "library/defines.hpp"
|
||||
|
||||
#include <timemory/defines.h>
|
||||
|
||||
#if defined(TIMEMORY_USE_OMPT)
|
||||
|
||||
# include "library/components/fwd.hpp"
|
||||
# include "library/components/user_region.hpp"
|
||||
# include "library/config.hpp"
|
||||
# include "library/debug.hpp"
|
||||
|
||||
# include <timemory/components/ompt.hpp>
|
||||
# include <timemory/components/ompt/extern.hpp>
|
||||
# include <timemory/timemory.hpp>
|
||||
|
||||
# include <memory>
|
||||
|
||||
using api_t = TIMEMORY_API;
|
||||
using ompt_handle_t = tim::component::ompt_handle<api_t>;
|
||||
using ompt_context_t = tim::openmp::context_handler<api_t>;
|
||||
using ompt_toolset_t = typename ompt_handle_t::toolset_type;
|
||||
using ompt_bundle_t = tim::component_tuple<ompt_handle_t>;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
ompt_start_tool_result_t* ompt_start_tool(unsigned int,
|
||||
const char*) OMNITRACE_PUBLIC_API;
|
||||
}
|
||||
|
||||
namespace omnitrace
|
||||
{
|
||||
namespace ompt
|
||||
{
|
||||
namespace
|
||||
{
|
||||
std::unique_ptr<ompt_bundle_t> f_bundle = {};
|
||||
bool _init_toolset_off = (trait::runtime_enabled<ompt_toolset_t>::set(false), true);
|
||||
} // namespace
|
||||
|
||||
void
|
||||
setup()
|
||||
{
|
||||
OMNITRACE_VERBOSE(1, "Setting up OMPT...\n");
|
||||
trait::runtime_enabled<ompt_toolset_t>::set(config::get_use_ompt());
|
||||
comp::user_ompt_bundle::global_init();
|
||||
comp::user_ompt_bundle::reset();
|
||||
// provide environment variable for enabling/disabling
|
||||
if(config::get_use_ompt())
|
||||
{
|
||||
tim::auto_lock_t lk{ tim::type_mutex<ompt_handle_t>() };
|
||||
comp::user_ompt_bundle::configure<omnitrace::component::user_region>();
|
||||
f_bundle =
|
||||
std::make_unique<ompt_bundle_t>("ompt", quirk::config<quirk::auto_start>{});
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
shutdown()
|
||||
{
|
||||
OMNITRACE_VERBOSE(1, "Shutting down OMPT...\n");
|
||||
if(f_bundle)
|
||||
{
|
||||
f_bundle->stop();
|
||||
ompt_context_t::cleanup();
|
||||
trait::runtime_enabled<ompt_toolset_t>::set(false);
|
||||
}
|
||||
f_bundle.reset();
|
||||
}
|
||||
} // namespace ompt
|
||||
} // namespace omnitrace
|
||||
|
||||
// include the ompt_start_tool definition
|
||||
# include <timemory/components/ompt/start_tool.hpp>
|
||||
|
||||
#else
|
||||
namespace omnitrace
|
||||
{
|
||||
namespace ompt
|
||||
{
|
||||
void
|
||||
setup()
|
||||
{}
|
||||
|
||||
void
|
||||
shutdown()
|
||||
{}
|
||||
} // namespace ompt
|
||||
} // namespace omnitrace
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user