Cleanup and reorg of lib/common (#34)
* Cleanup and reorg of lib/common
- remove stale code in helper.cpp
- move helper.hpp to demangle.hpp
- move helper.cpp to demangle.cpp
- update CMakeLists.txt with new filenames
- fix includes in config.cpp
* Remove log.hpp and join.hpp
- replace with glog and fmt
* Update lib/common/environment
- move implementation functions into cpp file
* Common library tests
- tests for demangling
- tests for mpl (template metaprogramming)
- tests for environment
[ROCm/rocprofiler-sdk commit: ba0eb11e96]
This commit is contained in:
zatwierdzone przez
GitHub
rodzic
697c751c62
commit
144d7018e7
@@ -1,9 +1,8 @@
|
||||
#
|
||||
# Builds common utilities into a static library
|
||||
#
|
||||
set(common_sources config.cpp helper.cpp)
|
||||
set(common_headers config.hpp defines.hpp environment.hpp join.hpp log.hpp helper.hpp
|
||||
mpl.hpp)
|
||||
set(common_sources config.cpp environment.cpp demangle.cpp)
|
||||
set(common_headers config.hpp defines.hpp environment.hpp demangle.hpp mpl.hpp)
|
||||
|
||||
add_library(rocprofiler-common-library STATIC)
|
||||
add_library(rocprofiler::rocprofiler-common-library ALIAS rocprofiler-common-library)
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
//
|
||||
|
||||
#include "lib/common/config.hpp"
|
||||
#include "lib/common/demangle.hpp"
|
||||
#include "lib/common/environment.hpp"
|
||||
#include "lib/common/helper.hpp"
|
||||
#include "lib/common/join.hpp"
|
||||
#include "lib/common/log.hpp"
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
@@ -210,13 +210,13 @@ output_keys(std::string _tag)
|
||||
auto _mpi_size = get_env<int>("OMPI_COMM_WORLD_SIZE", get_env<int>("MV2_COMM_WORLD_SIZE", 0));
|
||||
auto _mpi_rank = get_env<int>("OMPI_COMM_WORLD_RANK", get_env<int>("MV2_COMM_WORLD_RANK", -1));
|
||||
|
||||
auto _dmp_size = join("", (_mpi_size) > 0 ? _mpi_size : 1);
|
||||
auto _dmp_rank = join("", (_mpi_rank) > 0 ? _mpi_rank : 0);
|
||||
auto _proc_id = join("", getpid());
|
||||
auto _parent_id = join("", getppid());
|
||||
auto _pgroup_id = join("", getpgid(getpid()));
|
||||
auto _session_id = join("", getsid(getpid()));
|
||||
auto _proc_size = join("", get_num_siblings());
|
||||
auto _dmp_size = fmt::format("{}", (_mpi_size) > 0 ? _mpi_size : 1);
|
||||
auto _dmp_rank = fmt::format("{}", (_mpi_rank) > 0 ? _mpi_rank : 0);
|
||||
auto _proc_id = fmt::format("{}", getpid());
|
||||
auto _parent_id = fmt::format("{}", getppid());
|
||||
auto _pgroup_id = fmt::format("{}", getpgid(getpid()));
|
||||
auto _session_id = fmt::format("{}", getsid(getpid()));
|
||||
auto _proc_size = fmt::format("{}", get_num_siblings());
|
||||
auto _pwd_string = get_env<std::string>("PWD", ".");
|
||||
auto _slurm_job_id = get_env<std::string>("SLURM_JOB_ID", "0");
|
||||
auto _slurm_proc_id = get_env("SLURM_PROCID", _dmp_rank);
|
||||
@@ -248,7 +248,7 @@ output_keys(std::string _tag)
|
||||
for(size_t i = 0; i < _cmdline.size(); ++i)
|
||||
{
|
||||
auto _v = _cmdline.at(i);
|
||||
_options.emplace_back(join("", "%arg", i, "%"), _v, join("", "Argument #", i));
|
||||
_options.emplace_back(fmt::format("%arg{}%", i), _v, fmt::format("Argument #{}", i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,19 +317,13 @@ format(std::string _fpath, const std::string& _tag)
|
||||
}
|
||||
auto _beg = std::regex_replace(_fpath, _re, "$1");
|
||||
auto _end = std::regex_replace(_fpath, _re, "$4");
|
||||
_fpath = join("", _beg, _val, _end);
|
||||
_fpath = fmt::format("{}{}{}", _beg, _val, _end);
|
||||
}
|
||||
}
|
||||
} catch(std::exception& _e)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s[rocprofiler][%s:%i] %s threw exception :: %s\n%s",
|
||||
log::color::dmesg(),
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
__FUNCTION__,
|
||||
_e.what(),
|
||||
log::color::end());
|
||||
LOG(WARNING) << "[rocprofiler] " << __FUNCTION__ << " threw an exception :: " << _e.what()
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
// remove %arg<N>% where N >= argc
|
||||
@@ -340,14 +334,8 @@ format(std::string _fpath, const std::string& _tag)
|
||||
_fpath = std::regex_replace(_fpath, _re, "$1$4");
|
||||
} catch(std::exception& _e)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s[rocprofiler][%s:%i] %s threw exception :: %s\n%s",
|
||||
log::color::dmesg(),
|
||||
__FILE__,
|
||||
__LINE__,
|
||||
__FUNCTION__,
|
||||
_e.what(),
|
||||
log::color::end());
|
||||
LOG(WARNING) << "[rocprofiler] " << __FUNCTION__ << " threw an exception :: " << _e.what()
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
return _fpath;
|
||||
@@ -365,11 +353,11 @@ compose_filename(const config& _cfg)
|
||||
{
|
||||
if(_cfg.mpi_rank >= 0)
|
||||
{
|
||||
_output_file = join('.', _output_file, _cfg.mpi_rank);
|
||||
_output_file = fmt::format("{}.{}", _output_file, _cfg.mpi_rank);
|
||||
}
|
||||
else
|
||||
{
|
||||
_output_file = join('.', _output_file, getpid());
|
||||
_output_file = fmt::format("{}.{}", _output_file, getpid());
|
||||
}
|
||||
}
|
||||
if(!_output_ext.empty())
|
||||
|
||||
+27
-196
@@ -18,7 +18,7 @@
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE. */
|
||||
|
||||
#include "lib/common/helper.hpp"
|
||||
#include "lib/common/demangle.hpp"
|
||||
|
||||
#include <amd_comgr/amd_comgr.h>
|
||||
|
||||
@@ -32,11 +32,6 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#define ENABLE_BACKTRACE
|
||||
#if defined(ENABLE_BACKTRACE)
|
||||
# include <backtrace.h>
|
||||
#endif
|
||||
|
||||
#define amd_comgr_(call) \
|
||||
do \
|
||||
{ \
|
||||
@@ -127,79 +122,39 @@ cxa_demangle(std::string_view _mangled_name, int* _status)
|
||||
return _demangled_name;
|
||||
}
|
||||
|
||||
namespace
|
||||
// C++ symbol demangle
|
||||
std::string
|
||||
cxx_demangle(std::string_view symbol)
|
||||
{
|
||||
#if defined(ENABLE_BACKTRACE)
|
||||
int _status = 0;
|
||||
auto demangled_str = cxa_demangle(symbol, &_status);
|
||||
if(_status == 0)
|
||||
{
|
||||
return demangled_str;
|
||||
}
|
||||
|
||||
// struct BackTraceInfo
|
||||
// {
|
||||
// struct ::backtrace_state* state = nullptr;
|
||||
// std::stringstream sstream{};
|
||||
// int depth = 0;
|
||||
// int error = 0;
|
||||
// };
|
||||
amd_comgr_data_t mangled_data;
|
||||
amd_comgr_(create_data(AMD_COMGR_DATA_KIND_BYTES, &mangled_data));
|
||||
amd_comgr_(set_data(mangled_data, symbol.size(), symbol.data()));
|
||||
|
||||
// void
|
||||
// errorCallback(void* data, const char* message, int errnum)
|
||||
// {
|
||||
// BackTraceInfo* info = static_cast<BackTraceInfo*>(data);
|
||||
// info->sstream << "ROCProfiler: error: " << message << '(' << errnum << ')';
|
||||
// info->error = 1;
|
||||
// }
|
||||
amd_comgr_data_t demangled_data;
|
||||
amd_comgr_(demangle_symbol_name(mangled_data, &demangled_data));
|
||||
|
||||
// void
|
||||
// syminfoCallback(void* data,
|
||||
// uintptr_t /* pc */,
|
||||
// const char* symname,
|
||||
// uintptr_t /* symval */,
|
||||
// uintptr_t /* symsize */)
|
||||
// {
|
||||
// BackTraceInfo* info = static_cast<BackTraceInfo*>(data);
|
||||
size_t demangled_size = 0;
|
||||
amd_comgr_(get_data(demangled_data, &demangled_size, nullptr));
|
||||
|
||||
// if(symname == nullptr) return;
|
||||
demangled_str.resize(demangled_size);
|
||||
amd_comgr_(get_data(demangled_data, &demangled_size, demangled_str.data()));
|
||||
|
||||
// int status = 0;
|
||||
// auto&& _demangled = cxa_demangle(symname, &status);
|
||||
// info->sstream << ' '
|
||||
// << (status == 0 ? std::string_view{_demangled} : std::string_view{symname});
|
||||
// }
|
||||
amd_comgr_(release_data(mangled_data));
|
||||
amd_comgr_(release_data(demangled_data));
|
||||
return demangled_str;
|
||||
}
|
||||
|
||||
// int
|
||||
// fullCallback(void* data, uintptr_t pc, const char* filename, int lineno, const char* function)
|
||||
// {
|
||||
// BackTraceInfo* info = static_cast<BackTraceInfo*>(data);
|
||||
|
||||
// info->sstream << std::endl
|
||||
// << " #" << std::dec << info->depth++ << ' ' << "0x" << std::noshowbase
|
||||
// << std::hex << std::setfill('0') << std::setw(sizeof(pc) * 2) << pc;
|
||||
// if(function == nullptr)
|
||||
// {
|
||||
// backtrace_syminfo(info->state, pc, syminfoCallback, errorCallback, data);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// int status = 0;
|
||||
// auto&& _demangled = cxa_demangle(function, &status);
|
||||
// info->sstream << ' '
|
||||
// << (status == 0 ? std::string_view{_demangled} :
|
||||
// std::string_view{function});
|
||||
|
||||
// if(filename != nullptr)
|
||||
// {
|
||||
// info->sstream << " in " << filename;
|
||||
// if(lineno != 0) info->sstream << ':' << std::dec << lineno;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return info->error;
|
||||
// }
|
||||
#endif // defined (ENABLE_BACKTRACE)
|
||||
} // namespace
|
||||
|
||||
/* The function extracts the kernel name from
|
||||
input string. By using the iterators it finds the
|
||||
window in the string which contains only the kernel name.
|
||||
For example 'Foo<int, float>::foo(a[], int (int))' -> 'foo'*/
|
||||
// The function extracts the kernel name from
|
||||
// input string. By using the iterators it finds the
|
||||
// window in the string which contains only the kernel name.
|
||||
// For example 'Foo<int, float>::foo(a[], int (int))' -> 'foo'
|
||||
std::string
|
||||
truncate_name(std::string_view name)
|
||||
{
|
||||
@@ -245,129 +200,5 @@ truncate_name(std::string_view name)
|
||||
rit++;
|
||||
return std::string{name.substr(rend - rit, rit - rbeg)};
|
||||
}
|
||||
|
||||
// C++ symbol demangle
|
||||
std::string
|
||||
cxx_demangle(std::string_view symbol)
|
||||
{
|
||||
int _status = 0;
|
||||
auto demangled_str = cxa_demangle(symbol, &_status);
|
||||
if(_status == 0)
|
||||
{
|
||||
return demangled_str;
|
||||
}
|
||||
|
||||
amd_comgr_data_t mangled_data;
|
||||
amd_comgr_(create_data(AMD_COMGR_DATA_KIND_BYTES, &mangled_data));
|
||||
amd_comgr_(set_data(mangled_data, symbol.size(), symbol.data()));
|
||||
|
||||
amd_comgr_data_t demangled_data;
|
||||
amd_comgr_(demangle_symbol_name(mangled_data, &demangled_data));
|
||||
|
||||
size_t demangled_size = 0;
|
||||
amd_comgr_(get_data(demangled_data, &demangled_size, nullptr));
|
||||
|
||||
demangled_str.resize(demangled_size);
|
||||
amd_comgr_(get_data(demangled_data, &demangled_size, demangled_str.data()));
|
||||
|
||||
amd_comgr_(release_data(mangled_data));
|
||||
amd_comgr_(release_data(demangled_data));
|
||||
return demangled_str;
|
||||
}
|
||||
|
||||
// check if string has special char
|
||||
bool
|
||||
has_special_char(std::string_view str)
|
||||
{
|
||||
return std::find_if(str.begin(), str.end(), [](unsigned char ch) {
|
||||
return !((isalnum(ch) != 0) || ch == '_' || ch == ':' || ch == ' ');
|
||||
}) != str.end();
|
||||
}
|
||||
|
||||
// check if string has correct counter format
|
||||
bool
|
||||
has_counter_format(std::string_view str)
|
||||
{
|
||||
return std::find_if(str.begin(), str.end(), [](unsigned char ch) {
|
||||
return ((isalnum(ch) != 0) || ch == '_');
|
||||
}) != str.end();
|
||||
}
|
||||
|
||||
// trims the begining of the line for spaces
|
||||
std::string
|
||||
left_trim(std::string_view s)
|
||||
{
|
||||
constexpr std::string_view WHITESPACE = " \n\r\t\f\v";
|
||||
size_t start = s.find_first_not_of(WHITESPACE);
|
||||
if(start == std::string_view::npos) return std::string{};
|
||||
return std::string{s.substr(start)};
|
||||
}
|
||||
|
||||
// trims begining and end of input line in place
|
||||
void
|
||||
trim(std::string& str)
|
||||
{
|
||||
// Remove leading spaces.
|
||||
str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](unsigned char ch) {
|
||||
return std::isspace(ch) == 0;
|
||||
}));
|
||||
// Remove trailing spaces.
|
||||
str.erase(std::find_if(
|
||||
str.rbegin(), str.rend(), [](unsigned char ch) { return std::isspace(ch) == 0; })
|
||||
.base(),
|
||||
str.end());
|
||||
}
|
||||
|
||||
// replace unsuported specail chars with space
|
||||
static void
|
||||
handle_special_chars(std::string& str)
|
||||
{
|
||||
std::set<char> specialChars = {'!', '@', '#', '$', '%', '&', '(', ')', ',',
|
||||
'*', '+', '-', '.', '/', ';', '<', '=', '>',
|
||||
'?', '@', '{', '}', '^', '`', '~', '|', ':'};
|
||||
|
||||
// Iterate over the string and replace any special characters with a space.
|
||||
for(char& i : str)
|
||||
{
|
||||
if(specialChars.find(i) != specialChars.end())
|
||||
{
|
||||
i = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// validate input coutners and correct format if needed
|
||||
void
|
||||
validate_counters_format(std::vector<std::string>& counters, std::string line)
|
||||
{
|
||||
// trim line for any white spaces
|
||||
trim(line);
|
||||
|
||||
if(!(line[0] == '#' || line.find("pmc") == std::string::npos))
|
||||
{
|
||||
handle_special_chars(line);
|
||||
|
||||
std::stringstream input_line(line);
|
||||
std::string counter;
|
||||
while(getline(input_line, counter, ' '))
|
||||
{
|
||||
if(counter.substr(0, 3) != "pmc" && has_counter_format(counter))
|
||||
{
|
||||
counters.push_back(counter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// raise exception with correct usage if user still managed to corrupt input
|
||||
for(const auto& itr : counters)
|
||||
{
|
||||
if(!has_counter_format(itr))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[rocprofiler] Bad input metric. usage --> pmc: <counter1> <counter2>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace common
|
||||
} // namespace rocprofiler
|
||||
+5
-22
@@ -37,32 +37,15 @@ namespace common
|
||||
[[nodiscard]] std::string
|
||||
cxa_demangle(std::string_view _mangled_name, int* _status) __attribute__((nonnull(2)));
|
||||
|
||||
/* The function extracts the kernel name from
|
||||
input string. By using the iterators it finds the
|
||||
window in the string which contains only the kernel name.
|
||||
For example 'Foo<int, float>::foo(a[], int (int))' -> 'foo'*/
|
||||
std::string
|
||||
truncate_name(std::string_view name);
|
||||
|
||||
// C++ symbol demangle
|
||||
std::string
|
||||
cxx_demangle(std::string_view symbol);
|
||||
|
||||
// check if string has special char
|
||||
bool
|
||||
has_special_char(std::string_view str);
|
||||
|
||||
// check if string has correct counter format
|
||||
bool
|
||||
has_counter_format(std::string_view str);
|
||||
|
||||
// trims the begining of the line for spaces
|
||||
// The function extracts the kernel name from
|
||||
// input string. By using the iterators it finds the
|
||||
// window in the string which contains only the kernel name.
|
||||
// For example 'Foo<int, float>::foo(a[], int (int))' -> 'foo'
|
||||
std::string
|
||||
left_trim(std::string_view s);
|
||||
|
||||
// validates pmc user input format
|
||||
void
|
||||
validate_counters_format(std::vector<std::string>& counters, std::string line);
|
||||
|
||||
truncate_name(std::string_view name);
|
||||
} // namespace common
|
||||
} // namespace rocprofiler
|
||||
@@ -0,0 +1,102 @@
|
||||
// Copyright (c) 2023 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// 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 "lib/common/environment.hpp"
|
||||
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace rocprofiler
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
namespace impl
|
||||
{
|
||||
std::string
|
||||
get_env(std::string_view env_id, std::string_view _default)
|
||||
{
|
||||
if(env_id.empty()) return std::string{_default};
|
||||
char* env_var = ::std::getenv(env_id.data());
|
||||
if(env_var) return std::string{env_var};
|
||||
return std::string{_default};
|
||||
}
|
||||
|
||||
std::string
|
||||
get_env(std::string_view env_id, const char* _default)
|
||||
{
|
||||
return get_env(env_id, std::string_view{_default});
|
||||
}
|
||||
|
||||
int
|
||||
get_env(std::string_view env_id, int _default)
|
||||
{
|
||||
if(env_id.empty()) return _default;
|
||||
char* env_var = ::std::getenv(env_id.data());
|
||||
if(env_var)
|
||||
{
|
||||
try
|
||||
{
|
||||
return std::stoi(env_var);
|
||||
} catch(std::exception& _e)
|
||||
{
|
||||
LOG(WARNING) << "[rocprofiler][get_env] Exception thrown converting getenv(\"" << env_id
|
||||
<< "\") = " << env_var << " to integer :: " << _e.what()
|
||||
<< ". Using default value of " << _default << "\n";
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
|
||||
bool
|
||||
get_env(std::string_view env_id, bool _default)
|
||||
{
|
||||
if(env_id.empty()) return _default;
|
||||
char* env_var = ::std::getenv(env_id.data());
|
||||
if(env_var)
|
||||
{
|
||||
if(std::string_view{env_var}.empty())
|
||||
{
|
||||
throw std::runtime_error(std::string{"No boolean value provided for "} +
|
||||
std::string{env_id});
|
||||
}
|
||||
|
||||
if(std::string_view{env_var}.find_first_not_of("0123456789") == std::string_view::npos)
|
||||
{
|
||||
return static_cast<bool>(std::stoi(env_var));
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < std::string_view{env_var}.length(); ++i)
|
||||
env_var[i] = tolower(env_var[i]);
|
||||
|
||||
for(const auto& itr : {"off", "false", "no", "n", "f", "0"})
|
||||
if(std::string_view{env_var} == itr) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
} // namespace impl
|
||||
} // namespace common
|
||||
} // namespace rocprofiler
|
||||
@@ -20,133 +20,30 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "lib/common/log.hpp"
|
||||
#include <glog/logging.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(ROCPROFILER_ENVIRON_LOG_NAME)
|
||||
# if defined(ROCPROFILER_COMMON_LIBRARY_NAME)
|
||||
# define ROCPROFILER_ENVIRON_LOG_NAME "[" ROCPROFILER_COMMON_LIBRARY_NAME "]"
|
||||
# else
|
||||
# define ROCPROFILER_ENVIRON_LOG_NAME "[environ]"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(ROCPROFILER_ENVIRON_LOG_START)
|
||||
# if defined(ROCPROFILER_COMMON_LIBRARY_LOG_START)
|
||||
# define ROCPROFILER_ENVIRON_LOG_START ROCPROFILER_COMMON_LIBRARY_LOG_START
|
||||
# elif defined(ROCPROFILER_LOG_COLORS_AVAILABLE)
|
||||
# define ROCPROFILER_ENVIRON_LOG_START \
|
||||
fprintf(stderr, "%s", ::rocprofiler::common::log::color::dmesg());
|
||||
# else
|
||||
# define ROCPROFILER_ENVIRON_LOG_START
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(ROCPROFILER_ENVIRON_LOG_END)
|
||||
# if defined(ROCPROFILER_COMMON_LIBRARY_LOG_END)
|
||||
# define ROCPROFILER_ENVIRON_LOG_END ROCPROFILER_COMMON_LIBRARY_LOG_END
|
||||
# elif defined(ROCPROFILER_LOG_COLORS_AVAILABLE)
|
||||
# define ROCPROFILER_ENVIRON_LOG_END \
|
||||
fprintf(stderr, "%s", ::rocprofiler::common::log::color::dmesg());
|
||||
# else
|
||||
# define ROCPROFILER_ENVIRON_LOG_END
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define ROCPROFILER_ENVIRON_LOG(CONDITION, ...) \
|
||||
if(CONDITION) \
|
||||
{ \
|
||||
fflush(stderr); \
|
||||
ROCPROFILER_ENVIRON_LOG_START \
|
||||
fprintf(stderr, "[rocprofiler]" ROCPROFILER_ENVIRON_LOG_NAME "[%i] ", getpid()); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
ROCPROFILER_ENVIRON_LOG_END \
|
||||
fflush(stderr); \
|
||||
}
|
||||
|
||||
namespace rocprofiler
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
namespace
|
||||
namespace impl
|
||||
{
|
||||
inline std::string
|
||||
get_env_impl(std::string_view env_id, std::string_view _default)
|
||||
{
|
||||
if(env_id.empty()) return std::string{_default};
|
||||
char* env_var = ::std::getenv(env_id.data());
|
||||
if(env_var) return std::string{env_var};
|
||||
return std::string{_default};
|
||||
}
|
||||
std::string get_env(std::string_view, std::string_view);
|
||||
|
||||
inline std::string
|
||||
get_env_impl(std::string_view env_id, const char* _default)
|
||||
{
|
||||
return get_env_impl(env_id, std::string_view{_default});
|
||||
}
|
||||
std::string
|
||||
get_env(std::string_view, const char*);
|
||||
|
||||
inline int
|
||||
get_env_impl(std::string_view env_id, int _default)
|
||||
{
|
||||
if(env_id.empty()) return _default;
|
||||
char* env_var = ::std::getenv(env_id.data());
|
||||
if(env_var)
|
||||
{
|
||||
try
|
||||
{
|
||||
return std::stoi(env_var);
|
||||
} catch(std::exception& _e)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[rocprofiler][get_env] Exception thrown converting getenv(\"%s\") = "
|
||||
"%s to integer :: %s. Using default value of %i\n",
|
||||
env_id.data(),
|
||||
env_var,
|
||||
_e.what(),
|
||||
_default);
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
int
|
||||
get_env(std::string_view, int);
|
||||
|
||||
inline bool
|
||||
get_env_impl(std::string_view env_id, bool _default)
|
||||
{
|
||||
if(env_id.empty()) return _default;
|
||||
char* env_var = ::std::getenv(env_id.data());
|
||||
if(env_var)
|
||||
{
|
||||
if(std::string_view{env_var}.empty())
|
||||
{
|
||||
throw std::runtime_error(std::string{"No boolean value provided for "} +
|
||||
std::string{env_id});
|
||||
}
|
||||
|
||||
if(std::string_view{env_var}.find_first_not_of("0123456789") == std::string_view::npos)
|
||||
{
|
||||
return static_cast<bool>(std::stoi(env_var));
|
||||
}
|
||||
|
||||
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
|
||||
bool
|
||||
get_env(std::string_view, bool);
|
||||
} // namespace impl
|
||||
|
||||
template <typename Tp>
|
||||
inline auto
|
||||
@@ -156,11 +53,11 @@ get_env(std::string_view env_id, Tp&& _default)
|
||||
{
|
||||
using Up = std::underlying_type_t<Tp>;
|
||||
// cast to underlying type -> get_env -> cast to enum type
|
||||
return static_cast<Tp>(get_env_impl(env_id, static_cast<Up>(_default)));
|
||||
return static_cast<Tp>(impl::get_env(env_id, static_cast<Up>(_default)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_env_impl(env_id, std::forward<Tp>(_default));
|
||||
return impl::get_env(env_id, std::forward<Tp>(_default));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,17 +65,14 @@ struct env_config
|
||||
{
|
||||
std::string env_name = {};
|
||||
std::string env_value = {};
|
||||
int override = 0;
|
||||
int overwrite = 0;
|
||||
|
||||
auto operator()(bool _verbose = false) const
|
||||
{
|
||||
if(env_name.empty()) return -1;
|
||||
ROCPROFILER_ENVIRON_LOG(_verbose,
|
||||
"setenv(\"%s\", \"%s\", %i)\n",
|
||||
env_name.c_str(),
|
||||
env_value.c_str(),
|
||||
override);
|
||||
return setenv(env_name.c_str(), env_value.c_str(), override);
|
||||
LOG_IF(INFO, _verbose) << "[rocprofiler][set_env] setenv(\"" << env_name << "\", \""
|
||||
<< env_value << "\", " << overwrite << ")\n";
|
||||
return setenv(env_name.c_str(), env_value.c_str(), overwrite);
|
||||
}
|
||||
};
|
||||
} // namespace common
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
// Copyright (c) 2023 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// 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 <array>
|
||||
#include <initializer_list>
|
||||
#include <ios>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(ROCPROFILER_FOLD_EXPRESSION)
|
||||
# define ROCPROFILER_FOLD_EXPRESSION(...) ((__VA_ARGS__), ...)
|
||||
#endif
|
||||
|
||||
namespace rocprofiler
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
namespace
|
||||
{
|
||||
template <typename Tp>
|
||||
struct is_string_impl : std::false_type
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_string_impl<std::string> : std::true_type
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_string_impl<std::string_view> : std::true_type
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_string_impl<const char*> : std::true_type
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct is_string_impl<char*> : std::true_type
|
||||
{};
|
||||
|
||||
template <typename Tp>
|
||||
struct is_string : is_string_impl<std::remove_cv_t<std::decay_t<Tp>>>
|
||||
{};
|
||||
|
||||
template <typename ArgT>
|
||||
auto
|
||||
as_string(ArgT&& _v, std::enable_if_t<is_string<ArgT>::value, int> = 0)
|
||||
{
|
||||
if constexpr(std::is_pointer<std::decay_t<ArgT>>::value)
|
||||
{
|
||||
return (_v == nullptr) ? std::string{"\"\""} : (std::string{"\""} + _v + std::string{"\""});
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::string{"\""} + _v + std::string{"\""};
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ArgT>
|
||||
auto
|
||||
as_string(ArgT&& _v, std::enable_if_t<!is_string<ArgT>::value, long> = 0)
|
||||
{
|
||||
return _v;
|
||||
}
|
||||
|
||||
template <typename DelimT, typename... Args>
|
||||
auto
|
||||
join(DelimT&& _delim, Args&&... _args)
|
||||
{
|
||||
using delim_type = std::remove_cv_t<std::remove_reference_t<DelimT>>;
|
||||
|
||||
std::stringstream _ss{};
|
||||
_ss << std::boolalpha;
|
||||
|
||||
if constexpr(std::is_same<delim_type, char>::value)
|
||||
{
|
||||
const char _delim_c[2] = {_delim, '\0'};
|
||||
ROCPROFILER_FOLD_EXPRESSION(_ss << _delim_c << _args);
|
||||
auto _ret = _ss.str();
|
||||
return (_ret.length() > 1) ? _ret.substr(1) : std::string{};
|
||||
}
|
||||
else
|
||||
{
|
||||
ROCPROFILER_FOLD_EXPRESSION(_ss << _delim << _args);
|
||||
auto _ret = _ss.str();
|
||||
auto&& _len = std::string{_delim}.length();
|
||||
return (_ret.length() > _len) ? _ret.substr(_len) : std::string{};
|
||||
}
|
||||
}
|
||||
|
||||
struct QuoteStrings
|
||||
{};
|
||||
|
||||
template <typename DelimT, typename... Args>
|
||||
auto
|
||||
join(QuoteStrings&&, DelimT&& _delim, Args&&... _args)
|
||||
{
|
||||
using delim_type = std::remove_cv_t<std::remove_reference_t<DelimT>>;
|
||||
|
||||
std::stringstream _ss{};
|
||||
_ss << std::boolalpha;
|
||||
|
||||
if constexpr(std::is_same<delim_type, char>::value)
|
||||
{
|
||||
const char _delim_c[2] = {_delim, '\0'};
|
||||
ROCPROFILER_FOLD_EXPRESSION(_ss << _delim_c << as_string(_args));
|
||||
auto _ret = _ss.str();
|
||||
return (_ret.length() > 1) ? _ret.substr(1) : std::string{};
|
||||
}
|
||||
else
|
||||
{
|
||||
ROCPROFILER_FOLD_EXPRESSION(_ss << _delim << as_string(_args));
|
||||
auto _ret = _ss.str();
|
||||
auto&& _len = std::string{_delim}.length();
|
||||
return (_ret.length() > _len) ? _ret.substr(_len) : std::string{};
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
auto
|
||||
join(std::array<std::string_view, 3>&& _delim, Args&&... _args)
|
||||
{
|
||||
return join("",
|
||||
std::get<0>(_delim),
|
||||
join(std::get<1>(_delim), std::forward<Args>(_args)...),
|
||||
std::get<2>(_delim));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
auto
|
||||
join(QuoteStrings&&, std::array<std::string_view, 3>&& _delim, Args&&... _args)
|
||||
{
|
||||
return join(QuoteStrings{},
|
||||
"",
|
||||
std::get<0>(_delim),
|
||||
join(std::get<1>(_delim), std::forward<Args>(_args)...),
|
||||
std::get<2>(_delim));
|
||||
}
|
||||
|
||||
template <typename DelimB, typename DelimT, typename DelimE, typename... Args>
|
||||
auto
|
||||
join(std::tuple<DelimB, DelimT, DelimE>&& _delim, Args&&... _args)
|
||||
{
|
||||
return join("",
|
||||
std::get<0>(_delim),
|
||||
join(std::get<1>(_delim), std::forward<Args>(_args)...),
|
||||
std::get<2>(_delim));
|
||||
}
|
||||
|
||||
template <typename DelimB, typename DelimT, typename DelimE, typename... Args>
|
||||
auto
|
||||
join(QuoteStrings&&, std::tuple<DelimB, DelimT, DelimE>&& _delim, Args&&... _args)
|
||||
{
|
||||
return join(QuoteStrings{},
|
||||
"",
|
||||
std::get<0>(_delim),
|
||||
join(std::get<1>(_delim), std::forward<Args>(_args)...),
|
||||
std::get<2>(_delim));
|
||||
}
|
||||
} // namespace
|
||||
} // namespace common
|
||||
} // namespace rocprofiler
|
||||
@@ -1,138 +0,0 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2023 ROCm Developer Tools
|
||||
//
|
||||
// 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
|
||||
|
||||
#ifndef ROCPROFILER_LOG_COLORS_AVAILABLE
|
||||
# define ROCPROFILER_LOG_COLORS_AVAILABLE 1
|
||||
#endif
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace rocprofiler
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
namespace log
|
||||
{
|
||||
bool&
|
||||
monochrome();
|
||||
|
||||
inline bool&
|
||||
monochrome()
|
||||
{
|
||||
static bool _v = []() {
|
||||
auto _val = false;
|
||||
const char* _env_cstr = nullptr;
|
||||
#if defined(ROCPROFILER_LOG_COLORS_ENV)
|
||||
_env_cstr = std::getenv(ROCPROFILER_LOG_COLORS_ENV);
|
||||
#elif defined(ROCPROFILER_PROJECT_NAME)
|
||||
auto _env_name = std::string{ROCPROFILER_PROJECT_NAME} + "_MONOCHROME";
|
||||
for(auto& itr : _env_name)
|
||||
itr = toupper(itr);
|
||||
_env_cstr = std::getenv(_env_name.c_str());
|
||||
#else
|
||||
_env_cstr = std::getenv("ROCPROFILER_MONOCHROME");
|
||||
#endif
|
||||
|
||||
if(!_env_cstr) _env_cstr = std::getenv("MONOCHROME");
|
||||
|
||||
if(_env_cstr)
|
||||
{
|
||||
auto _env = std::string{_env_cstr};
|
||||
|
||||
// check if numeric
|
||||
if(_env.find_first_not_of("0123456789") == std::string::npos)
|
||||
{
|
||||
return _env.length() > 1 || _env[0] != '0';
|
||||
}
|
||||
|
||||
for(auto& itr : _env)
|
||||
itr = tolower(itr);
|
||||
|
||||
// check for matches to acceptable forms of false
|
||||
for(const auto& itr : {"off", "false", "no", "n", "f"})
|
||||
{
|
||||
if(_env == itr) return false;
|
||||
}
|
||||
|
||||
// check for matches to acceptable forms of true
|
||||
for(const auto& itr : {"on", "true", "yes", "y", "t"})
|
||||
{
|
||||
if(_env == itr) return true;
|
||||
}
|
||||
}
|
||||
return _val;
|
||||
}();
|
||||
return _v;
|
||||
}
|
||||
|
||||
namespace color
|
||||
{
|
||||
static constexpr auto info_value = "\033[01;34m";
|
||||
static constexpr auto warning_value = "\033[01;33m";
|
||||
static constexpr auto fatal_value = "\033[01;31m";
|
||||
static constexpr auto source_value = "\033[01;32m";
|
||||
static constexpr auto dmesg_value = "\033[01;37m";
|
||||
static constexpr auto end_value = "\033[0m";
|
||||
|
||||
inline const char*
|
||||
info()
|
||||
{
|
||||
return (log::monochrome()) ? "" : info_value;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
warning()
|
||||
{
|
||||
return (log::monochrome()) ? "" : warning_value;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
fatal()
|
||||
{
|
||||
return (log::monochrome()) ? "" : fatal_value;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
source()
|
||||
{
|
||||
return (log::monochrome()) ? "" : source_value;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
dmesg()
|
||||
{
|
||||
return (log::monochrome()) ? "" : dmesg_value;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
end()
|
||||
{
|
||||
return (log::monochrome()) ? "" : end_value;
|
||||
}
|
||||
} // namespace color
|
||||
} // namespace log
|
||||
} // namespace common
|
||||
} // namespace rocprofiler
|
||||
@@ -2,3 +2,4 @@
|
||||
#
|
||||
#
|
||||
add_subdirectory(buffering)
|
||||
add_subdirectory(common)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#
|
||||
# Tests for the common library
|
||||
#
|
||||
project(rocprofiler-tests-common LANGUAGES C CXX)
|
||||
|
||||
include(GoogleTest)
|
||||
|
||||
set(common_sources demangling.cpp environment.cpp mpl.cpp)
|
||||
|
||||
add_executable(common-tests)
|
||||
target_sources(common-tests PRIVATE ${common_sources})
|
||||
target_link_libraries(
|
||||
common-tests
|
||||
PRIVATE rocprofiler::rocprofiler-headers rocprofiler::rocprofiler-common-library
|
||||
GTest::gtest GTest::gtest_main)
|
||||
|
||||
gtest_add_tests(
|
||||
TARGET common-tests
|
||||
SOURCES ${common_sources}
|
||||
TEST_LIST common-tests_TESTS
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
set_tests_properties(${common-tests_TESTS} PROPERTIES TIMEOUT 45 LABELS "unittests")
|
||||
@@ -0,0 +1,95 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2023 ROCm Developer Tools
|
||||
//
|
||||
// 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 "lib/common/demangle.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
TEST(common, demangling)
|
||||
{
|
||||
// the purpose of this test is to verify the cxx_demangle function.
|
||||
// We want to make sure that the function produces the right demangling
|
||||
// when it is a correctly mangled string and does not change the string
|
||||
// when demangling fails
|
||||
|
||||
using strview_pair_t = std::pair<std::string_view, std::string_view>;
|
||||
for(auto [mangled, demangled] :
|
||||
{strview_pair_t{"_ZN11rocprofiler8internal18correlation_config20get_unique_record_idEv",
|
||||
"rocprofiler::internal::correlation_config::get_unique_record_id()"},
|
||||
strview_pair_t{"_ZN11rocprofiler8internal18get_active_configsEv",
|
||||
"rocprofiler::internal::get_active_configs()"},
|
||||
strview_pair_t{"_ZN11rocprofiler8internal22get_registered_configsEv",
|
||||
"rocprofiler::internal::get_registered_configs()"},
|
||||
strview_pair_t{
|
||||
"_ZZN11rocprofiler8internal18correlation_config20get_unique_record_idEvE2_v",
|
||||
"rocprofiler::internal::correlation_config::get_unique_record_id()::_v"},
|
||||
strview_pair_t{"_ZZN11rocprofiler8internal18get_active_configsEvE2_v",
|
||||
"rocprofiler::internal::get_active_configs()::_v"},
|
||||
strview_pair_t{"_ZZN11rocprofiler8internal22get_registered_configsEvE2_v",
|
||||
"rocprofiler::internal::get_registered_configs()::_v"}})
|
||||
{
|
||||
// verify the demangling works
|
||||
EXPECT_EQ(rocprofiler::common::cxx_demangle(mangled), demangled)
|
||||
<< "failed to demangle '" << mangled << "'";
|
||||
|
||||
// verify we get same string in when improperly mangled string
|
||||
auto bad_mangled = std::string{"_Z"} + std::string{mangled};
|
||||
EXPECT_EQ(rocprofiler::common::cxx_demangle(bad_mangled), bad_mangled)
|
||||
<< "demangling succeeded for '" << bad_mangled << "'";
|
||||
}
|
||||
}
|
||||
|
||||
TEST(common, truncate)
|
||||
{
|
||||
// this test is verify that the truncate_name function correctly finds the function
|
||||
// name in a complex template instantiation
|
||||
|
||||
auto mangled = std::string_view{"_ZSt16__do_uninit_copyIPKSt4pairINSt7__cxx1112basic_"
|
||||
"stringIcSt11char_traitsIcESaIcEEES6_EPS7_ET0_T_SC_SB_"};
|
||||
|
||||
auto untruncated = std::string_view{
|
||||
"std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> "
|
||||
">, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >* "
|
||||
"std::__do_uninit_copy<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, "
|
||||
"std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, "
|
||||
"std::allocator<char> > > const*, std::pair<std::__cxx11::basic_string<char, "
|
||||
"std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, "
|
||||
"std::char_traits<char>, std::allocator<char> > "
|
||||
">*>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, "
|
||||
"std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, "
|
||||
"std::allocator<char> > > const*, std::pair<std::__cxx11::basic_string<char, "
|
||||
"std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, "
|
||||
"std::char_traits<char>, std::allocator<char> > > const*, "
|
||||
"std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> "
|
||||
">, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)"};
|
||||
|
||||
EXPECT_EQ(rocprofiler::common::cxx_demangle(mangled), untruncated);
|
||||
|
||||
EXPECT_EQ(rocprofiler::common::truncate_name(untruncated),
|
||||
std::string_view{"__do_uninit_copy"});
|
||||
|
||||
EXPECT_EQ(rocprofiler::common::truncate_name(rocprofiler::common::cxx_demangle(mangled)),
|
||||
std::string_view{"__do_uninit_copy"});
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2023 ROCm Developer Tools
|
||||
//
|
||||
// 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 "lib/common/environment.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(common, environment)
|
||||
{
|
||||
using rocprofiler::common::env_config;
|
||||
using rocprofiler::common::get_env;
|
||||
|
||||
enum TestBareEnum : unsigned short // NOLINT(performance-enum-size)
|
||||
{
|
||||
BZero = 0,
|
||||
BOne = 1,
|
||||
};
|
||||
|
||||
enum class TestClassEnum : unsigned short // NOLINT(performance-enum-size)
|
||||
{
|
||||
CZero = 0,
|
||||
COne = 1,
|
||||
};
|
||||
|
||||
//
|
||||
// int testing section
|
||||
//
|
||||
EXPECT_EQ(get_env("ROCPROFILER_ENV_TEST_INT", 0), 0);
|
||||
|
||||
setenv("ROCPROFILER_ENV_TEST_INT", "1", 1);
|
||||
EXPECT_EQ(get_env("ROCPROFILER_ENV_TEST_INT", 0), 1);
|
||||
|
||||
env_config{"ROCPROFILER_ENV_TEST_INT", "2"}();
|
||||
EXPECT_EQ(get_env("ROCPROFILER_ENV_TEST_INT", 0), 1);
|
||||
|
||||
env_config{"ROCPROFILER_ENV_TEST_INT", "2", 1}();
|
||||
EXPECT_EQ(get_env("ROCPROFILER_ENV_TEST_INT", 0), 2);
|
||||
|
||||
//
|
||||
// enum testing section
|
||||
//
|
||||
EXPECT_EQ(get_env("ROCPROFILER_ENV_TEST_BARE_ENUM", BZero), BZero);
|
||||
|
||||
env_config{"ROCPROFILER_ENV_TEST_BARE_ENUM", "1", 1}();
|
||||
EXPECT_EQ(get_env("ROCPROFILER_ENV_TEST_BARE_ENUM", BZero), BOne);
|
||||
|
||||
EXPECT_EQ(get_env("ROCPROFILER_ENV_TEST_CLASS_ENUM", TestClassEnum::CZero),
|
||||
TestClassEnum::CZero);
|
||||
|
||||
env_config{"ROCPROFILER_ENV_TEST_CLASS_ENUM", "1", 1}();
|
||||
EXPECT_EQ(get_env("ROCPROFILER_ENV_TEST_CLASS_ENUM", TestClassEnum::CZero),
|
||||
TestClassEnum::COne);
|
||||
|
||||
//
|
||||
// string testing section
|
||||
//
|
||||
EXPECT_EQ(get_env("ROCPROFILER_ENV_TEST_STR", "nostr"), std::string_view{"nostr"});
|
||||
|
||||
env_config{"ROCPROFILER_ENV_TEST_STR", "hasstr", 0}();
|
||||
EXPECT_EQ(get_env("ROCPROFILER_ENV_TEST_STR", "nostr"), std::string_view{"hasstr"});
|
||||
|
||||
//
|
||||
// bool testing section
|
||||
//
|
||||
EXPECT_FALSE(get_env("ROCPROFILER_ENV_TEST_BOOL", false));
|
||||
|
||||
env_config{"ROCPROFILER_ENV_TEST_BOOL", "YES", 1}();
|
||||
EXPECT_TRUE(get_env("ROCPROFILER_ENV_TEST_BOOL", false));
|
||||
|
||||
env_config{"ROCPROFILER_ENV_TEST_BOOL", "yes", 1}();
|
||||
EXPECT_TRUE(get_env("ROCPROFILER_ENV_TEST_BOOL", false));
|
||||
|
||||
env_config{"ROCPROFILER_ENV_TEST_BOOL", "y", 1}();
|
||||
EXPECT_TRUE(get_env("ROCPROFILER_ENV_TEST_BOOL", false));
|
||||
|
||||
env_config{"ROCPROFILER_ENV_TEST_BOOL", "true", 1}();
|
||||
EXPECT_TRUE(get_env("ROCPROFILER_ENV_TEST_BOOL", false));
|
||||
|
||||
env_config{"ROCPROFILER_ENV_TEST_BOOL", "on", 1}();
|
||||
EXPECT_TRUE(get_env("ROCPROFILER_ENV_TEST_BOOL", false));
|
||||
|
||||
env_config{"ROCPROFILER_ENV_TEST_BOOL", "no", 1}();
|
||||
EXPECT_FALSE(get_env("ROCPROFILER_ENV_TEST_BOOL", true));
|
||||
|
||||
env_config{"ROCPROFILER_ENV_TEST_BOOL", "false", 1}();
|
||||
EXPECT_FALSE(get_env("ROCPROFILER_ENV_TEST_BOOL", true));
|
||||
|
||||
env_config{"ROCPROFILER_ENV_TEST_BOOL", "0", 1}();
|
||||
EXPECT_FALSE(get_env("ROCPROFILER_ENV_TEST_BOOL", true));
|
||||
|
||||
for(auto n : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
|
||||
{
|
||||
env_config{"ROCPROFILER_ENV_TEST_BOOL", std::to_string(n), 1}();
|
||||
EXPECT_TRUE(get_env("ROCPROFILER_ENV_TEST_BOOL", false));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2023 ROCm Developer Tools
|
||||
//
|
||||
// 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 "lib/common/mpl.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
TEST(common, mpl)
|
||||
{
|
||||
namespace mpl = ::rocprofiler::common::mpl;
|
||||
struct Foo;
|
||||
using test_type_list_t = mpl::type_list<int, long, int, Foo, Foo*>;
|
||||
using test_tuple_t = std::tuple<int, long, int, Foo, Foo*>;
|
||||
|
||||
EXPECT_EQ(mpl::size_of<test_type_list_t>::value, 5);
|
||||
EXPECT_EQ(mpl::size_of<test_tuple_t>::value, 5);
|
||||
|
||||
{
|
||||
constexpr bool _foo_p_is_one_of = mpl::is_one_of<Foo*, test_type_list_t>::value;
|
||||
constexpr bool _int_is_one_of = mpl::is_one_of<int, test_type_list_t>::value;
|
||||
constexpr bool _double_is_one_of = mpl::is_one_of<double, test_type_list_t>::value;
|
||||
|
||||
EXPECT_TRUE(_foo_p_is_one_of);
|
||||
EXPECT_TRUE(_int_is_one_of);
|
||||
EXPECT_FALSE(_double_is_one_of);
|
||||
|
||||
constexpr auto _foo_p_index_of = mpl::index_of<Foo*, test_type_list_t>::value;
|
||||
constexpr auto _int_index_of = mpl::index_of<int, test_type_list_t>::value;
|
||||
|
||||
EXPECT_EQ(_foo_p_index_of, 4);
|
||||
EXPECT_EQ(_int_index_of, 0);
|
||||
}
|
||||
|
||||
{
|
||||
constexpr bool _foo_p_is_one_of = mpl::is_one_of<Foo*, test_tuple_t>::value;
|
||||
constexpr bool _int_is_one_of = mpl::is_one_of<int, test_tuple_t>::value;
|
||||
constexpr bool _double_is_one_of = mpl::is_one_of<double, test_tuple_t>::value;
|
||||
|
||||
EXPECT_TRUE(_foo_p_is_one_of);
|
||||
EXPECT_TRUE(_int_is_one_of);
|
||||
EXPECT_FALSE(_double_is_one_of);
|
||||
|
||||
constexpr auto _foo_p_index_of = mpl::index_of<Foo*, test_tuple_t>::value;
|
||||
constexpr auto _int_index_of = mpl::index_of<int, test_tuple_t>::value;
|
||||
|
||||
EXPECT_EQ(_foo_p_index_of, 4);
|
||||
EXPECT_EQ(_int_index_of, 0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user