581c4122aa
- complete with ctest support
[ROCm/rocprofiler-systems commit: 9ef3800986]
306 lines
13 KiB
C++
306 lines
13 KiB
C++
// 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
|
|
// 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 "timemory/macros/attributes.hpp"
|
|
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <iosfwd>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#if defined(TIMEMORY_CORE_SOURCE)
|
|
# define TIMEMORY_UTILITY_SOURCE
|
|
#elif defined(TIMEMORY_USE_CORE_EXTERN)
|
|
# define TIMEMORY_USE_UTILITY_EXTERN
|
|
#endif
|
|
//
|
|
#if defined(TIMEMORY_USE_EXTERN) && !defined(TIMEMORY_USE_UTILITY_EXTERN)
|
|
# define TIMEMORY_USE_UTILITY_EXTERN
|
|
#endif
|
|
|
|
//======================================================================================//
|
|
//
|
|
// Quick way to create a globally accessible setting
|
|
//
|
|
//======================================================================================//
|
|
|
|
#if !defined(CREATE_STATIC_VARIABLE_ACCESSOR)
|
|
# define CREATE_STATIC_VARIABLE_ACCESSOR(TYPE, FUNC_NAME, VARIABLE) \
|
|
static TYPE& FUNC_NAME() \
|
|
{ \
|
|
static TYPE _instance = Type::VARIABLE; \
|
|
return _instance; \
|
|
}
|
|
#endif
|
|
|
|
//--------------------------------------------------------------------------------------//
|
|
|
|
#if !defined(CREATE_STATIC_FUNCTION_ACCESSOR)
|
|
# define CREATE_STATIC_FUNCTION_ACCESSOR(TYPE, FUNC_NAME, VARIABLE) \
|
|
static TYPE& FUNC_NAME() \
|
|
{ \
|
|
static TYPE _instance = Type::VARIABLE(); \
|
|
return _instance; \
|
|
}
|
|
#endif
|
|
|
|
//======================================================================================//
|
|
//
|
|
// DEBUG
|
|
//
|
|
//======================================================================================//
|
|
|
|
// stringify some macro -- uses TIMEMORY_STRINGIZE2 which does the actual
|
|
// "stringify-ing" after the macro has been substituted by it's result
|
|
#if !defined(TIMEMORY_STRINGIZE)
|
|
# define TIMEMORY_STRINGIZE(X) TIMEMORY_STRINGIZE2(X)
|
|
#endif
|
|
|
|
// actual stringifying
|
|
#if !defined(TIMEMORY_STRINGIZE2)
|
|
# define TIMEMORY_STRINGIZE2(X) # X
|
|
#endif
|
|
|
|
#if !defined(TIMEMORY_TRUNCATED_FILE_STRING)
|
|
# define TIMEMORY_TRUNCATED_FILE_STRING(FILE) \
|
|
[]() { \
|
|
std::string _f{ FILE }; \
|
|
auto _pos = _f.find("/timemory/"); \
|
|
if(_pos != std::string::npos) \
|
|
{ \
|
|
return _f.substr(_pos + 1); \
|
|
} \
|
|
return _f; \
|
|
}()
|
|
#endif
|
|
|
|
#if !defined(TIMEMORY_FILE_LINE_FUNC_STRING)
|
|
# define TIMEMORY_FILE_LINE_FUNC_STRING \
|
|
std::string \
|
|
{ \
|
|
std::string{ "[" } + TIMEMORY_TRUNCATED_FILE_STRING(__FILE__) + ":" + \
|
|
std::to_string(__LINE__) + "@'" + __FUNCTION__ + "']" \
|
|
}
|
|
#endif
|
|
|
|
#if !defined(TIMEMORY_PID_TID_STRING)
|
|
# define TIMEMORY_PID_TID_STRING \
|
|
std::string \
|
|
{ \
|
|
std::string{ "[pid=" } + std::to_string(::tim::process::get_id()) + \
|
|
std::string{ "][tid=" } + std::to_string(::tim::threading::get_id()) + \
|
|
"]" \
|
|
}
|
|
#endif
|
|
|
|
template <typename Arg>
|
|
TIMEMORY_NOINLINE auto
|
|
timemory_proxy_value(Arg&& arg, int) -> decltype(arg.proxy_value())
|
|
{
|
|
return arg.proxy_value();
|
|
}
|
|
|
|
template <typename Arg>
|
|
TIMEMORY_NOINLINE auto
|
|
timemory_proxy_value(Arg&& arg, long)
|
|
{
|
|
return std::forward<Arg>(arg);
|
|
}
|
|
|
|
template <typename... Args>
|
|
TIMEMORY_NOINLINE void
|
|
timemory_print_here(const char* _pid_tid, const char* _file, int _line, const char* _func,
|
|
Args&&... args)
|
|
{
|
|
fprintf(stderr, "%s[%s:%i@'%s']> ", _pid_tid, _file, _line, _func);
|
|
fprintf(stderr, timemory_proxy_value(std::forward<Args>(args), 0)...);
|
|
fprintf(stderr, "...\n");
|
|
fflush(stderr);
|
|
}
|
|
|
|
#if !defined(PRINT_HERE)
|
|
# define PRINT_HERE(...) \
|
|
timemory_print_here(TIMEMORY_PID_TID_STRING.c_str(), \
|
|
TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), __LINE__, \
|
|
__FUNCTION__, __VA_ARGS__)
|
|
#endif
|
|
|
|
#if !defined(DEBUG_PRINT_HERE)
|
|
# if defined(DEBUG)
|
|
# define DEBUG_PRINT_HERE(...) \
|
|
if(::tim::settings::debug()) \
|
|
{ \
|
|
timemory_print_here(TIMEMORY_PID_TID_STRING.c_str(), \
|
|
TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), \
|
|
__LINE__, __FUNCTION__, __VA_ARGS__); \
|
|
}
|
|
# else
|
|
# define DEBUG_PRINT_HERE(...)
|
|
# endif
|
|
#endif
|
|
|
|
#if !defined(VERBOSE_PRINT_HERE)
|
|
# define VERBOSE_PRINT_HERE(VERBOSE_LEVEL, ...) \
|
|
if(::tim::settings::verbose() >= VERBOSE_LEVEL) \
|
|
{ \
|
|
timemory_print_here(TIMEMORY_PID_TID_STRING.c_str(), \
|
|
TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), \
|
|
__LINE__, __FUNCTION__, __VA_ARGS__); \
|
|
}
|
|
#endif
|
|
|
|
#if !defined(CONDITIONAL_PRINT_HERE)
|
|
# define CONDITIONAL_PRINT_HERE(CONDITION, ...) \
|
|
if(CONDITION) \
|
|
{ \
|
|
timemory_print_here(TIMEMORY_PID_TID_STRING.c_str(), \
|
|
TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), \
|
|
__LINE__, __FUNCTION__, __VA_ARGS__); \
|
|
}
|
|
#endif
|
|
|
|
#if !defined(TIMEMORY_CONDITIONAL_BACKTRACE)
|
|
# define TIMEMORY_CONDITIONAL_BACKTRACE(CONDITION, DEPTH) \
|
|
if(CONDITION) \
|
|
{ \
|
|
::tim::print_backtrace<DEPTH>(std::cerr, TIMEMORY_PID_TID_STRING, \
|
|
TIMEMORY_FILE_LINE_FUNC_STRING); \
|
|
}
|
|
#endif
|
|
|
|
#if !defined(TIMEMORY_CONDITIONAL_DEMANGLED_BACKTRACE)
|
|
# define TIMEMORY_CONDITIONAL_DEMANGLED_BACKTRACE(CONDITION, DEPTH) \
|
|
if(CONDITION) \
|
|
{ \
|
|
::tim::print_demangled_backtrace<DEPTH>(std::cerr, TIMEMORY_PID_TID_STRING, \
|
|
TIMEMORY_FILE_LINE_FUNC_STRING); \
|
|
}
|
|
#endif
|
|
|
|
#if !defined(PRETTY_PRINT_HERE)
|
|
# if defined(TIMEMORY_GNU_COMPILER) || defined(TIMEMORY_CLANG_COMPILER)
|
|
# define PRETTY_PRINT_HERE(...) \
|
|
timemory_print_here(TIMEMORY_PID_TID_STRING.c_str(), \
|
|
TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), \
|
|
__LINE__, __PRETTY_FUNCTION__, __VA_ARGS__)
|
|
# else
|
|
# define PRETTY_PRINT_HERE(...) \
|
|
timemory_print_here(TIMEMORY_PID_TID_STRING.c_str(), \
|
|
TIMEMORY_TRUNCATED_FILE_STRING(__FILE__).c_str(), \
|
|
__LINE__, __FUNCTION__, __VA_ARGS__)
|
|
# endif
|
|
#endif
|
|
|
|
#if !defined(TIMEMORY_CONDITIONAL_BACKTRACE)
|
|
# define TIMEMORY_CONDITIONAL_BACKTRACE(CONDITION, DEPTH) \
|
|
if(CONDITION) \
|
|
{ \
|
|
::tim::print_backtrace<DEPTH>(std::cerr, TIMEMORY_PID_TID_STRING); \
|
|
}
|
|
#endif
|
|
|
|
#if !defined(TIMEMORY_CONDITIONAL_DEMANGLED_BACKTRACE)
|
|
# define TIMEMORY_CONDITIONAL_DEMANGLED_BACKTRACE(CONDITION, DEPTH) \
|
|
if(CONDITION) \
|
|
{ \
|
|
::tim::print_demangled_backtrace<DEPTH>(std::cerr, TIMEMORY_PID_TID_STRING); \
|
|
}
|
|
#endif
|
|
|
|
#if defined(DEBUG)
|
|
|
|
template <typename... Args>
|
|
inline void
|
|
__LOG(std::string file, int line, const char* msg, Args&&... args)
|
|
{
|
|
auto _pos = file.find("/timemory/");
|
|
if(_pos == std::string::npos)
|
|
_pos = file.find_last_of('/');
|
|
if(_pos != std::string::npos)
|
|
file = file.substr(_pos);
|
|
fprintf(stderr, "[Log @ %s:%i]> ", file.c_str(), line);
|
|
fprintf(stderr, msg, std::forward<Args>(args)...);
|
|
fprintf(stderr, "\n");
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------//
|
|
|
|
inline void
|
|
__LOG(std::string file, int line, const char* msg)
|
|
{
|
|
if(file.find('/') != std::string::npos)
|
|
file = file.substr(file.find_last_of('/'));
|
|
fprintf(stderr, "[Log @ %s:%i]> %s\n", file.c_str(), line, msg);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------//
|
|
// auto insert the file and line
|
|
# define _LOG(...) __LOG(__FILE__, __LINE__, __VA_ARGS__)
|
|
|
|
//--------------------------------------------------------------------------------------//
|
|
|
|
template <typename... Args>
|
|
inline void
|
|
_DBG(const char* msg, Args&&... args)
|
|
{
|
|
fprintf(stderr, msg, std::forward<Args>(args)...);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------//
|
|
|
|
inline void
|
|
_DBG(const char* msg)
|
|
{
|
|
fprintf(stderr, "%s", msg);
|
|
}
|
|
|
|
#else
|
|
# define _LOG(...) \
|
|
{}
|
|
# define _DBG(...) \
|
|
{}
|
|
#endif
|
|
|
|
//======================================================================================//
|
|
//
|
|
// Define macros for utility
|
|
//
|
|
//======================================================================================//
|
|
//
|
|
#if defined(TIMEMORY_UTILITY_SOURCE)
|
|
# define TIMEMORY_UTILITY_LINKAGE(...) __VA_ARGS__
|
|
# define TIMEMORY_UTILITY_INLINE
|
|
#elif defined(TIMEMORY_USE_EXTERN) || defined(TIMEMORY_USE_UTILITY_EXTERN)
|
|
# define TIMEMORY_UTILITY_LINKAGE(...) __VA_ARGS__
|
|
# define TIMEMORY_UTILITY_INLINE
|
|
#else
|
|
# define TIMEMORY_UTILITY_LINKAGE(...) inline __VA_ARGS__
|
|
# define TIMEMORY_UTILITY_INLINE inline
|
|
# define TIMEMORY_UTILITY_HEADER_MODE
|
|
#endif
|