* googletest submodule

* cmake folder

* misc root files

- clang-format
- cmake-format
- pyproject.toml
- requirements.txt
- VERSION

* workflows

* RPM files

* external folder

* samples folder

* tests root folder

* source/bin folder

* source/include folder

* source/lib/common folder

* source/lib/plugins folder

* source/lib/tests folder

- for library unit tests

* source/lib/rocprofiler folder

- rocprofiler library implementation

* Remaining cmake files

* lib/common/containers

- ring_buffer
- atomic_ring_buffer
- stable_vector
- static_vector

* Update .gitignore

* Update hsa.hpp

- include cstdint

* cmake formatting (cmake-format) (#2)

Co-authored-by: jrmadsen <jrmadsen@users.noreply.github.com>

* Remove linting.yml

- uses self-hosted runners

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Этот коммит содержится в:
Jonathan R. Madsen
2023-08-08 18:39:01 -05:00
коммит произвёл GitHub
родитель 7d1c7757a8
Коммит 527aa71f5a
75 изменённых файлов: 20094 добавлений и 0 удалений
+114
Просмотреть файл
@@ -0,0 +1,114 @@
# clang-format v11
---
Language: Cpp
BasedOnStyle: Google
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true
AlignConsecutiveAssignments: true
AlignConsecutiveBitFields: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: TopLevel
AlwaysBreakAfterReturnType: TopLevel
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: Always
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: false
BeforeElse: true
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: true
BreakInheritanceList: BeforeComma
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakStringLiterals: true
ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 0
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeBlocks: Preserve
IndentCaseLabels: true
IndentCaseBlocks: false
IndentFunctionDeclarationAfterType: false
IndentGotoLabels: true
IndentPPDirectives: AfterHash
IndentExternBlock: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
ReflowComments: true
SortIncludes: false
SortUsingDeclarations: true
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: Never
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Auto
TabWidth: 4
UseTab: Never
...
+305
Просмотреть файл
@@ -0,0 +1,305 @@
parse:
additional_commands:
rocprofiler_checkout_git_submodule:
flags:
- RECURSIVE
kwargs:
RELATIVE_PATH: '*'
WORKING_DIRECTORY: '*'
TEST_FILE: '*'
REPO_URL: '*'
REPO_BRANCH: '*'
ADDITIONAL_COMMANDS: '*'
rocprofiler_save_variables:
kwargs:
VARIABLES: '*'
CONDITION: '*'
rocprofiler_restore_variables:
kwargs:
VARIABLES: '*'
CONDITION: '*'
rocprofiler_target_compile_options:
flags:
- BUILD_INTERFACE
- FORCE
kwargs:
PUBLIC: '*'
PRIVATE: '*'
INTERFACE: '*'
LANGUAGES: '*'
LINK_LANGUAGES: '*'
rocprofiler_add_test:
flags:
- SKIP_BASELINE
- SKIP_SAMPLING
- SKIP_REWRITE
- SKIP_RUNTIME
kwargs:
NAME: '*'
TARGET: '*'
MPI: '*'
GPU: '*'
NUM_PROCS: '*'
REWRITE_TIMEOUT: '*'
RUNTIME_TIMEOUT: '*'
SAMPLING_TIMEOUT: '*'
SAMPLING_ARGS: '*'
REWRITE_ARGS: '*'
RUNTIME_ARGS: '*'
RUN_ARGS: '*'
ENVIRONMENT: '*'
LABELS: '*'
PROPERTIES: '*'
SAMPLING_PASS_REGEX: '*'
SAMPLING_FAIL_REGEX: '*'
RUNTIME_PASS_REGEX: '*'
RUNTIME_FAIL_REGEX: '*'
REWRITE_PASS_REGEX: '*'
REWRITE_FAIL_REGEX: '*'
BASELINE_PASS_REGEX: '*'
BASELINE_FAIL_REGEX: '*'
REWRITE_RUN_PASS_REGEX: '*'
REWRITE_RUN_FAIL_REGEX: '*'
rocprofiler_add_causal_test:
flags:
- SKIP_BASELINE
kwargs:
NAME: '*'
TARGET: '*'
CAUSAL_TIMEOUT: '*'
CAUSAL_VALIDATE_TIMEOUT: '*'
CAUSAL_MODE: '*'
CAUSAL_ARGS: '*'
CAUSAL_VALIDATE_ARGS: '*'
RUNTIME_ARGS: '*'
RUN_ARGS: '*'
ENVIRONMENT: '*'
LABELS: '*'
PROPERTIES: '*'
CAUSAL_PASS_REGEX: '*'
CAUSAL_FAIL_REGEX: '*'
BASELINE_PASS_REGEX: '*'
BASELINE_FAIL_REGEX: '*'
CAUSAL_VALIDATE_PASS_REGEX: '*'
CAUSAL_VALIDATE_FAIL_REGEX: '*'
rocprofiler_target_compile_definitions:
kwargs:
PUBLIC: '*'
PRIVATE: '*'
INTERFACE: '*'
rocprofiler_add_bin_test:
flags:
- WILL_FAIL
kwargs:
NAME: '*'
ARGS: '*'
LABELS: '*'
TARGET: '*'
DEPENDS: '*'
COMMAND: '*'
TIMEOUT: '*'
PROPERTIES: '*'
ENVIRONMENT: '*'
WORKING_DIRECTORY: '*'
PASS_REGEX: '*'
FAIL_REGEX: '*'
SKIP_REGEX: '*'
rocprofiler_add_python_test:
flags:
- STANDALONE
kwargs:
NAME: '*'
FILE: '*'
TIMEOUT: '*'
PROFILE_ARGS: '*'
RUN_ARGS: '*'
ENVIRONMENT: '*'
LABELS: '*'
DEPENDS: '*'
COMMAND: '*'
PROPERTIES: '*'
PYTHON_EXECUTABLE: '*'
PYTHON_VERSION: '*'
PASS_REGEX: '*'
FAIL_REGEX: '*'
SKIP_REGEX: '*'
rocprofiler_add_python_validation_test:
kwargs:
NAME: '*'
ARGS: '*'
PERFETTO_FILE: '*'
PERFETTO_METRIC: '*'
TIMEMORY_FILE: '*'
TIMEMORY_METRIC: '*'
rocm_version_message:
flags:
- STATUS
- WARNING
- SEND_ERROR
- FATAL_ERROR
- AUTHOR_WARNING
rocprofiler_find_python:
flags:
- REQUIRED
- QUIET
kwargs:
VERSION: '*'
ROOT_DIR: '*'
COMPONENTS: '*'
rocprofiler_python_console_script:
kwargs:
VERSION: '*'
ROOT_DIR: '*'
rocprofiler_pybind11_add_module:
flags:
- MODULE
- SHARED
- EXCLUDE_FROM_ALL
- NO_EXTRAS
- SYSTEM
- THIN_LTO
- LTO
kwargs:
PYTHON_VERSION: '*'
CXX_STANDARD: '*'
VISIBILITY: '*'
rocprofiler_directory:
flags:
- MKDIR
- FAIL
kwargs:
PREFIX: '*'
OUTPUT_VARIABLE: '*'
WORKING_DIRECTORY: '*'
PATHS: '*'
rocprofiler_check_python_dirs_and_versions:
flags:
- UNSET
- FAIL
kwargs:
RESULT_VARIABLE: '*'
OUTPUT_VARIABLE: '*'
rocprofiler_find_static_library:
flags:
- NO_CACHE
- REQUIRED
- NO_DEFAULT_PATH
- NO_PACKAGE_ROOT_PATH
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
- NO_SYSTEM_ENVIRONMENT_PATH
- CMAKE_FIND_ROOT_PATH_BOTH
- ONLY_CMAKE_FIND_ROOT_PATH
- NO_CMAKE_FIND_ROOT_PATH
kwargs:
NAMES: '*'
NAMES_PER_DIR: '*'
HINTS: '*'
PATHS: '*'
PATH_SUFFIXES: '*'
DOC: '*'
rocprofiler_find_shared_library:
flags:
- NO_CACHE
- REQUIRED
- NO_DEFAULT_PATH
- NO_PACKAGE_ROOT_PATH
- NO_CMAKE_PATH
- NO_CMAKE_ENVIRONMENT_PATH
- NO_SYSTEM_ENVIRONMENT_PATH
- CMAKE_FIND_ROOT_PATH_BOTH
- ONLY_CMAKE_FIND_ROOT_PATH
- NO_CMAKE_FIND_ROOT_PATH
kwargs:
NAMES: '*'
NAMES_PER_DIR: '*'
HINTS: '*'
PATHS: '*'
PATH_SUFFIXES: '*'
DOC: '*'
rocprofiler_causal_example_executable:
kwargs:
TAG: '*'
SOURCES: '*'
DEFINITIONS: '*'
LINK_LIBRARIES: '*'
INCLUDE_DIRECTORIES: '*'
rocprofiler_add_validation_test:
kwargs:
NAME: '*'
ARGS: '*'
LABELS: '*'
TIMEOUT: '*'
DEPENDS: '*'
PROPERTIES: '*'
PASS_REGEX: '*'
FAIL_REGEX: '*'
SKIP_REGEX: '*'
ENVIRONMENT: '*'
PERFETTO_FILE: '*'
PERFETTO_METRIC: '*'
TIMEMORY_FILE: '*'
TIMEMORY_METRIC: '*'
override_spec: {}
vartags: []
proptags: []
format:
disable: false
line_width: 90
tab_size: 4
use_tabchars: false
fractional_tab_policy: use-space
max_subgroups_hwrap: 2
max_pargs_hwrap: 8
max_rows_cmdline: 2
separate_ctrl_name_with_space: false
separate_fn_name_with_space: false
dangle_parens: false
dangle_align: child
min_prefix_chars: 4
max_prefix_chars: 10
max_lines_hwrap: 2
line_ending: unix
command_case: lower
keyword_case: upper
always_wrap: []
enable_sort: true
autosort: false
require_valid_layout: false
layout_passes: {}
markup:
bullet_char: '*'
enum_char: .
first_comment_is_literal: true
literal_comment_pattern: ^#
fence_pattern: ^\s*([`~]{3}[`~]*)(.*)$
ruler_pattern: ^\s*[^\w\s]{3}.*[^\w\s]{3}$
explicit_trailing_pattern: '#<'
hashruler_min_length: 10
canonicalize_hashrulers: true
enable_markup: true
lint:
disabled_codes: []
function_pattern: '[0-9a-z_]+'
macro_pattern: '[0-9A-Z_]+'
global_var_pattern: '[A-Z][0-9A-Z_]+'
internal_var_pattern: _[A-Z][0-9A-Z_]+
local_var_pattern: '[a-z][a-z0-9_]+'
private_var_pattern: _[0-9a-z_]+
public_var_pattern: '[A-Z][0-9A-Z_]+'
argument_var_pattern: '[a-z][a-z0-9_]+'
keyword_pattern: '[A-Z][0-9A-Z_]+'
max_conditionals_custom_parser: 2
min_statement_spacing: 1
max_statement_spacing: 2
max_returns: 6
max_branches: 12
max_arguments: 5
max_localvars: 15
max_statements: 50
encode:
emit_byteorder_mark: false
input_encoding: utf-8
output_encoding: utf-8
misc:
per_command: {}
+146
Просмотреть файл
@@ -0,0 +1,146 @@
name: Formatting
on:
workflow_dispatch:
pull_request:
branches: [ main ]
paths-ignore:
- '.github/workflows/pull_*.yml'
- '.github/workflows/linting.yml'
- '.github/workflows/markdown_lint.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
cmake:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Extract branch name
shell: bash
run: |
echo "branch=${GITHUB_HEAD_REF:-${GITHUB_HEAD_REF#refs/heads/}}" >> $GITHUB_OUTPUT
id: extract_branch
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y python3-pip
python3 -m pip install -U cmake-format
- name: Run cmake-format
run: |
set +e
cmake-format -i $(find . -type f | egrep 'CMakeLists.txt|\.cmake$')
if [ $(git diff | wc -l) -ne 0 ]; then
echo -e "\nError! CMake code not formatted. Run cmake-format...\n"
echo -e "\nFiles:\n"
git diff --name-only
echo -e "\nFull diff:\n"
git diff
exit 1
fi
- name: Create pull request
if: failure()
uses: peter-evans/create-pull-request@v5
with:
commit-message: "cmake formatting (cmake-format)"
branch: ${{ steps.extract_branch.outputs.branch }}-cmake-format
delete-branch: true
title: "Format cmake code (via cmake-format) on ${{ steps.extract_branch.outputs.branch }}"
base: ${{ steps.extract_branch.outputs.branch }}
source:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: |
DISTRIB_CODENAME=$(cat /etc/lsb-release | grep DISTRIB_CODENAME | awk -F '=' '{print $NF}')
sudo apt-get update
sudo apt-get install -y software-properties-common wget curl clang-format-11
- name: Extract branch name
shell: bash
run: |
echo "branch=${GITHUB_HEAD_REF:-${GITHUB_HEAD_REF#refs/heads/}}" >> $GITHUB_OUTPUT
id: extract_branch
- name: Run clang-format
run: |
set +e
FILES=$(find samples source tests -type f | egrep '\.(h|hpp|hh|c|cc|cpp)(|\.in)$')
FORMAT_OUT=$(clang-format-11 -i ${FILES})
if [ $(git diff | wc -l) -ne 0 ]; then
echo -e "\nError! Code not formatted. Run clang-format (version 11)...\n"
echo -e "\nFiles:\n"
git diff --name-only
echo -e "\nFull diff:\n"
git diff
exit 1
fi
- name: Create pull request
if: failure()
uses: peter-evans/create-pull-request@v5
with:
commit-message: "source formatting (clang-format v11)"
branch: ${{ steps.extract_branch.outputs.branch }}-clang-format
delete-branch: true
title: "Format source code (via clang-format v11) on ${{ steps.extract_branch.outputs.branch }}"
base: ${{ steps.extract_branch.outputs.branch }}
python:
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: ['3.10']
steps:
- uses: actions/checkout@v3
- name: Extract branch name
shell: bash
run: |
echo "branch=${GITHUB_HEAD_REF:-${GITHUB_HEAD_REF#refs/heads/}}" >> $GITHUB_OUTPUT
id: extract_branch
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install black
- name: black format
run: |
black .
if [ $(git diff | wc -l) -ne 0 ]; then
echo -e "\nError! Python code not formatted. Run black...\n"
echo -e "\nFiles:\n"
git diff --name-only
echo -e "\nFull diff:\n"
git diff
exit 1
fi
- name: Create pull request
if: failure()
uses: peter-evans/create-pull-request@v5
with:
commit-message: "python formatting (black)"
branch: ${{ steps.extract_branch.outputs.branch }}-python-format
delete-branch: true
title: "Format python code (via black) on ${{ steps.extract_branch.outputs.branch }}"
base: ${{ steps.extract_branch.outputs.branch }}
+3
Просмотреть файл
@@ -30,3 +30,6 @@
*.exe
*.out
*.app
# Build directories
/build*
+3
Просмотреть файл
@@ -0,0 +1,3 @@
[submodule "external/googletest"]
path = external/googletest
url = https://github.com/google/googletest.git
+89
Просмотреть файл
@@ -0,0 +1,89 @@
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND CMAKE_CURRENT_SOURCE_DIR STREQUAL
CMAKE_SOURCE_DIR)
set(MSG "")
message(STATUS "Warning! Building from the source directory is not recommended")
message(STATUS "If unintended, please remove 'CMakeCache.txt' and 'CMakeFiles'")
message(STATUS "and build from a separate directory")
message(AUTHOR_WARNING "In-source build")
endif()
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" FULL_VERSION_STRING LIMIT_COUNT 1)
string(REGEX REPLACE "(\n|\r)" "" FULL_VERSION_STRING "${FULL_VERSION_STRING}")
string(REGEX REPLACE "([0-9]+)\.([0-9]+)\.([0-9]+)(.*)" "\\1.\\2.\\3" ROCPROFILER_VERSION
"${FULL_VERSION_STRING}")
project(
rocprofiler
LANGUAGES C CXX
VERSION ${ROCPROFILER_VERSION}
DESCRIPTION "ROCm GPU performance analysis"
HOMEPAGE_URL "https://github.com/ROCm-Developer-Tools/rocprofiler-v2-internal")
find_package(Git)
if(Git_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags
OUTPUT_VARIABLE ROCPROFILER_GIT_DESCRIBE
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE _GIT_DESCRIBE_RESULT
ERROR_QUIET)
if(NOT _GIT_DESCRIBE_RESULT EQUAL 0)
execute_process(
COMMAND ${GIT_EXECUTABLE} describe
OUTPUT_VARIABLE ROCPROFILER_GIT_DESCRIBE
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE _GIT_DESCRIBE_RESULT
ERROR_QUIET)
endif()
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
OUTPUT_VARIABLE ROCPROFILER_GIT_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
else()
set(ROCPROFILER_GIT_DESCRIBE "v${ROCPROFILER_VERSION}")
set(ROCPROFILER_GIT_REVISION "")
endif()
message(
STATUS
"[${PROJECT_NAME}] version ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} (${FULL_VERSION_STRING})"
)
message(STATUS "[${PROJECT_NAME}] git revision: ${ROCPROFILER_GIT_REVISION}")
message(STATUS "[${PROJECT_NAME}] git describe: ${ROCPROFILER_GIT_DESCRIBE}")
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${PROJECT_SOURCE_DIR}/cmake/Modules
${CMAKE_MODULE_PATH})
include(GNUInstallDirs) # install directories
include(rocprofiler_utilities) # various functions/macros
include(rocprofiler_interfaces) # interface libraries
include(rocprofiler_compilers) # compiler identification
include(rocprofiler_options) # project options
include(rocprofiler_build_settings) # build flags
include(rocprofiler_formatting) # formatting
include(rocprofiler_linting) # clang-tidy
include(rocprofiler_config_interfaces) # configure interface libraries
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
add_subdirectory(external)
add_subdirectory(source)
if(ROCPROFILER_BUILD_TESTS)
add_subdirectory(tests)
endif()
if(ROCPROFILER_BUILD_SAMPLES)
add_subdirectory(samples)
endif()
#
include(rocprofiler_config_install)
include(rocprofiler_config_packaging)
+5
Просмотреть файл
@@ -0,0 +1,5 @@
# left-hand term originates from ENABLE_LDCONFIG = ON/OFF at package build
if [ "@ENABLE_LDCONFIG@" == "ON" ]; then
echo @CPACK_PACKAGING_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@ > /@CMAKE_INSTALL_SYSCONFDIR@/ld.so.conf.d/librocprofiler64.conf
ldconfig
fi
+4
Просмотреть файл
@@ -0,0 +1,4 @@
# left-hand term originates from ENABLE_LDCONFIG = ON/OFF at package build
if [ "@ENABLE_LDCONFIG@" == "ON" ]; then
rm -f /@CMAKE_INSTALL_SYSCONFDIR@/ld.so.conf.d/librocprofiler64.conf && ldconfig
fi
+1
Просмотреть файл
@@ -0,0 +1 @@
2.0.0
+302
Просмотреть файл
@@ -0,0 +1,302 @@
#[=======================================================================[.rst:
Findrocm_version
---------------
Search the <ROCM_PATH>/.info/version* files to determine the version of ROCm
Use this module by invoking find_package with the form::
find_package(rocm_version
[version] [EXACT]
[REQUIRED])
This module finds the version info for ROCm. The cached variables are::
rocm_version_FOUND - Whether the ROCm versioning was found
rocm_version_FULL_VERSION - The exact string from `<ROCM_PATH>/.info/version` or similar
rocm_version_MAJOR_VERSION - Major version, e.g. 4 in 4.5.2.100-40502
rocm_version_MINOR_VERSION - Minor version, e.g. 5 in 4.5.2.100-40502
rocm_version_PATCH_VERSION - Patch version, e.g. 2 in 4.5.2.100-40502
rocm_version_TWEAK_VERSION - Tweak version, e.g. 100 in 4.5.2.100-40502
rocm_version_REVISION_VERSION - Revision version, e.g. 40502 in 4.5.2.100-40502.
rocm_version_EPOCH_VERSION - See deb-version for a description of epochs. Epochs are used when versioning system change
rocm_version_CANONICAL_VERSION - `[<EPOCH>:]<MAJOR>.<MINOR>.<MINOR>[.<TWEAK>][-<REVISION>]`
rocm_version_NUMERIC_VERSION - e.g. `10000*<MAJOR> + 100*<MINOR> + <PATCH>`, e.g. 40502 for ROCm 4.5.2
rocm_version_TRIPLE_VERSION - e.g. `<MAJOR>.<MINOR>.<PATCH>`, e.g. 4.5.2 for ROCm 4.5.2
These variables are relevant for the find procedure::
rocm_version_DEBUG - Print info about processing
rocm_version_VERSION_FILE - `<FILE>` to read from in `<ROCM_PATH>/.info/<FILE>`, e.g. `version`, `version-dev`, `version-hip-libraries`, etc.
It may also be a full path
rocm_version_DIR - Root location for <ROCM_PATH>
#]=======================================================================]
set(rocm_version_VARIABLES
EPOCH
MAJOR
MINOR
PATCH
TWEAK
REVISION
TRIPLE
NUMERIC
CANONICAL
FULL)
function(ROCM_VERSION_MESSAGE _TYPE)
if(rocm_version_DEBUG)
message(${_TYPE} "[rocm_version] ${ARGN}")
endif()
endfunction()
# read a .info/version* file and propagate the variables to the calling scope
function(ROCM_VERSION_COMPUTE FULL_VERSION_STRING _VAR_PREFIX)
# remove any line endings
string(REGEX REPLACE "(\n|\r)" "" FULL_VERSION_STRING "${FULL_VERSION_STRING}")
# store the full version so it can be set later
set(FULL_VERSION "${FULL_VERSION_STRING}")
# get number and remove from full version string
string(REGEX REPLACE "([0-9]+)\:(.*)" "\\1" EPOCH_VERSION "${FULL_VERSION_STRING}")
string(REGEX REPLACE "([0-9]+)\:(.*)" "\\2" FULL_VERSION_STRING
"${FULL_VERSION_STRING}")
if(EPOCH_VERSION STREQUAL FULL_VERSION)
set(EPOCH_VERSION)
endif()
# get number and remove from full version string
string(REGEX REPLACE "([0-9]+)(.*)" "\\1" MAJOR_VERSION "${FULL_VERSION_STRING}")
string(REGEX REPLACE "([0-9]+)(.*)" "\\2" FULL_VERSION_STRING
"${FULL_VERSION_STRING}")
# get number and remove from full version string
string(REGEX REPLACE "\.([0-9]+)(.*)" "\\1" MINOR_VERSION "${FULL_VERSION_STRING}")
string(REGEX REPLACE "\.([0-9]+)(.*)" "\\2" FULL_VERSION_STRING
"${FULL_VERSION_STRING}")
# get number and remove from full version string
string(REGEX REPLACE "\.([0-9]+)(.*)" "\\1" PATCH_VERSION "${FULL_VERSION_STRING}")
string(REGEX REPLACE "\.([0-9]+)(.*)" "\\2" FULL_VERSION_STRING
"${FULL_VERSION_STRING}")
if(NOT PATCH_VERSION LESS 100)
set(PATCH_VERSION 0)
endif()
# get number and remove from full version string
string(REGEX REPLACE "\.([0-9]+)(.*)" "\\1" TWEAK_VERSION "${FULL_VERSION_STRING}")
string(REGEX REPLACE "\.([0-9]+)(.*)" "\\2" FULL_VERSION_STRING
"${FULL_VERSION_STRING}")
# get number
string(REGEX REPLACE "-([0-9A-Za-z+~]+)" "\\1" REVISION_VERSION
"${FULL_VERSION_STRING}")
set(CANONICAL_VERSION)
set(_MAJOR_SEP ":")
set(_MINOR_SEP ".")
set(_PATCH_SEP ".")
set(_TWEAK_SEP ".")
set(_REVISION_SEP "-")
foreach(_V EPOCH MAJOR MINOR PATCH TWEAK REVISION)
if(${_V}_VERSION)
set(CANONICAL_VERSION "${CANONICAL_VERSION}${_${_V}_SEP}${${_V}_VERSION}")
else()
set(CANONICAL_VERSION "${CANONICAL_VERSION}${_${_V}_SEP}0")
endif()
endforeach()
set(_MAJOR_SEP "")
foreach(_V MAJOR MINOR PATCH)
if(${_V}_VERSION)
set(TRIPLE_VERSION "${TRIPLE_VERSION}${_${_V}_SEP}${${_V}_VERSION}")
else()
set(TRIPLE_VERSION "${TRIPLE_VERSION}${_${_V}_SEP}0")
endif()
endforeach()
math(
EXPR
NUMERIC_VERSION
"(10000 * (${MAJOR_VERSION}+0)) + (100 * (${MINOR_VERSION}+0)) + (${PATCH_VERSION}+0)"
)
# propagate to parent scopes
foreach(_V ${rocm_version_VARIABLES})
set(${_VAR_PREFIX}_${_V}_VERSION
${${_V}_VERSION}
PARENT_SCOPE)
endforeach()
endfunction()
# this macro watches for changes in the variables and unsets the remaining cache varaible
# when they change
function(ROCM_VERSION_WATCH_FOR_CHANGE _var)
set(_rocm_version_watch_var_name rocm_version_WATCH_VALUE_${_var})
if(DEFINED ${_rocm_version_watch_var_name})
if("${${_var}}" STREQUAL "${${_rocm_version_watch_var_name}}")
if(NOT "${${_var}}" STREQUAL "")
rocm_version_message(STATUS "${_var} :: ${${_var}}")
endif()
list(REMOVE_ITEM _REMAIN_VARIABLES ${_var})
set(_REMAIN_VARIABLES
"${_REMAIN_VARIABLES}"
PARENT_SCOPE)
return()
else()
rocm_version_message(
STATUS
"${_var} changed :: ${${_rocm_version_watch_var_name}} --> ${${_var}}")
foreach(_V ${_REMAIN_VARIABLES})
rocm_version_message(
STATUS "${_var} changed :: Unsetting cache variable ${_V}...")
unset(${_V} CACHE)
endforeach()
endif()
else()
if(NOT "${${_var}}" STREQUAL "")
rocm_version_message(STATUS "${_var} :: ${${_var}}")
endif()
endif()
# store the value for the next run
set(${_rocm_version_watch_var_name}
"${${_var}}"
CACHE INTERNAL "Last value of ${_var}" FORCE)
endfunction()
# scope this to a function to avoid leaking local variables
function(ROCM_VERSION_PARSE_VERSION_FILES)
# the list of variables set by module. when one of these changes, we need to unset the
# cache variables after it
set(_ALL_VARIABLES)
foreach(_V ${rocm_version_VARIABLES})
list(APPEND _ALL_VARIABLES rocm_version_${_V}_VERSION)
endforeach()
set(_REMAIN_VARIABLES ${_ALL_VARIABLES})
# read a .info/version* file and propagate the variables to the calling scope
function(ROCM_VERSION_READ_FILE _FILE _VAR_PREFIX)
file(READ "${_FILE}" FULL_VERSION_STRING LIMIT_COUNT 1)
rocm_version_compute("${FULL_VERSION_STRING}" "${_VAR_PREFIX}")
# propagate to parent scopes
foreach(_V ${rocm_version_VARIABLES})
set(${_VAR_PREFIX}_${_V}_VERSION
${${_VAR_PREFIX}_${_V}_VERSION}
PARENT_SCOPE)
endforeach()
endfunction()
# search for HIP to set ROCM_PATH if(NOT hip_FOUND) find_package(hip) endif()
function(COMPUTE_ROCM_VERSION_DIR)
if(EXISTS "${rocm_version_VERSION_FILE}" AND IS_ABSOLUTE
"${rocm_version_VERSION_FILE}")
get_filename_component(_VERSION_DIR "${rocm_version_VERSION_FILE}" PATH)
get_filename_component(_VERSION_DIR "${_VERSION_DIR}/.." REALPATH)
set(rocm_version_DIR
"${_VERSION_DIR}"
CACHE PATH "Root path to ROCm's .info/${rocm_version_VERSION_FILE}"
${ARGN})
rocm_version_watch_for_change(rocm_version_DIR)
endif()
endfunction()
if(rocm_version_VERSION_FILE)
get_filename_component(_VERSION_FILE "${rocm_version_VERSION_FILE}" NAME)
set(_VERSION_FILES ${_VERSION_FILE})
compute_rocm_version_dir(FORCE)
else()
set(_VERSION_FILES version version-dev version-hip-libraries version-hiprt
version-hiprt-devel version-hip-sdk version-libs version-utils)
rocm_version_message(STATUS "rocm_version version files: ${_VERSION_FILES}")
endif()
# convert env to cache if not defined
foreach(_PATH rocm_version_DIR rocm_version_ROOT rocm_version_ROOT_DIR
ROCPROFILER_DEFAULT_ROCM_PATH ROCM_PATH)
if(NOT DEFINED ${_PATH} AND DEFINED ENV{${_PATH}})
set(_VAL "$ENV{${_PATH}}")
get_filename_component(_VAL "${_VAL}" REALPATH)
set(${_PATH}
"${_VAL}"
CACHE PATH "Search path for ROCm version for rocm_version")
endif()
endforeach()
if(rocm_version_DIR)
set(_PATHS ${rocm_version_DIR})
else()
set(_PATHS)
foreach(
_DIR
${rocm_version_DIR} ${rocm_version_ROOT} ${rocm_version_ROOT_DIR}
$ENV{CMAKE_PREFIX_PATH} ${CMAKE_PREFIX_PATH} ${ROCPROFILER_DEFAULT_ROCM_PATH}
${ROCM_PATH} /opt/rocm)
if(EXISTS ${_DIR})
get_filename_component(_ABS_DIR "${_DIR}" REALPATH)
list(APPEND _PATHS ${_ABS_DIR})
endif()
endforeach()
rocm_version_message(STATUS "rocm_version search paths: ${_PATHS}")
endif()
string(REPLACE ":" ";" _PATHS "${_PATHS}")
foreach(_PATH ${_PATHS})
foreach(_FILE ${_VERSION_FILES})
set(_F ${_PATH}/.info/${_FILE})
if(EXISTS ${_F})
set(rocm_version_VERSION_FILE
"${_F}"
CACHE FILEPATH "File with versioning info")
rocm_version_watch_for_change(rocm_version_VERSION_FILE)
compute_rocm_version_dir()
else()
rocm_version_message(AUTHOR_WARNING "File does not exist: ${_F}")
endif()
endforeach()
endforeach()
if(EXISTS "${rocm_version_VERSION_FILE}")
set(_F "${rocm_version_VERSION_FILE}")
rocm_version_message(STATUS "Reading ${_F}...")
get_filename_component(_B "${_F}" NAME)
string(REPLACE "." "_" _B "${_B}")
string(REPLACE "-" "_" _B "${_B}")
rocm_version_read_file(${_F} ${_B})
foreach(_V ${rocm_version_VARIABLES})
set(_CACHE_VAR rocm_version_${_V}_VERSION)
set(_LOCAL_VAR ${_B}_${_V}_VERSION)
set(rocm_version_${_V}_VERSION
"${${_LOCAL_VAR}}"
CACHE STRING "ROCm ${_V} version")
rocm_version_watch_for_change(${_CACHE_VAR})
endforeach()
endif()
endfunction()
# execute
rocm_version_parse_version_files()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
rocm_version
VERSION_VAR rocm_version_FULL_VERSION
REQUIRED_VARS rocm_version_FULL_VERSION rocm_version_TRIPLE_VERSION rocm_version_DIR
rocm_version_VERSION_FILE)
# don't add major/minor/patch/etc. version variables to required vars because they might
# be zero, which will cause CMake to evaluate it as not set
+97
Просмотреть файл
@@ -0,0 +1,97 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying file
# Copyright.txt or https://cmake.org/licensing for details.
include(FindPackageHandleStandardArgs)
# ----------------------------------------------------------------------------------------#
if(NOT ROCM_PATH AND NOT "$ENV{ROCM_PATH}" STREQUAL "")
set(ROCM_PATH "$ENV{ROCM_PATH}")
endif()
foreach(_DIR ${rocm_version_DIR} ${ROCM_PATH} /opt/rocm /opt/rocm/rocprofiler)
if(EXISTS ${_DIR})
get_filename_component(_ABS_DIR "${_DIR}" REALPATH)
list(APPEND _ROCM_ROCPROFILER_PATHS ${_ABS_DIR})
endif()
endforeach()
# ----------------------------------------------------------------------------------------#
find_path(
rocprofiler_ROOT_DIR
NAMES include/rocprofiler/rocprofiler.h include/rocprofiler.h
HINTS ${_ROCM_ROCPROFILER_PATHS}
PATHS ${_ROCM_ROCPROFILER_PATHS}
PATH_SUFFIXES rocprofiler)
mark_as_advanced(rocprofiler_ROOT_DIR)
# ----------------------------------------------------------------------------------------#
find_path(
rocprofiler_INCLUDE_DIR
NAMES rocprofiler.h
HINTS ${rocprofiler_ROOT_DIR} ${_ROCM_ROCPROFILER_PATHS}
PATHS ${rocprofiler_ROOT_DIR} ${_ROCM_ROCPROFILER_PATHS}
PATH_SUFFIXES include include/rocprofiler rocprofiler/include)
mark_as_advanced(rocprofiler_INCLUDE_DIR)
find_path(
rocprofiler_hsa_INCLUDE_DIR
NAMES hsa.h
HINTS ${rocprofiler_ROOT_DIR} ${_ROCM_ROCPROFILER_PATHS}
PATHS ${rocprofiler_ROOT_DIR} ${_ROCM_ROCPROFILER_PATHS}
PATH_SUFFIXES include include/hsa)
mark_as_advanced(rocprofiler_hsa_INCLUDE_DIR)
# ----------------------------------------------------------------------------------------#
find_library(
rocprofiler_LIBRARY
NAMES rocprofiler64 rocprofiler
HINTS ${rocprofiler_ROOT_DIR}/rocprofiler ${rocprofiler_ROOT_DIR}
${_ROCM_ROCPROFILER_PATHS}
PATHS ${rocprofiler_ROOT_DIR}/rocprofiler ${rocprofiler_ROOT_DIR}
${_ROCM_ROCPROFILER_PATHS}
PATH_SUFFIXES lib lib64
NO_DEFAULT_PATH)
find_library(
rocprofiler_hsa-runtime_LIBRARY
NAMES hsa-runtime64 hsa-runtime
HINTS ${rocprofiler_ROOT_DIR} ${_ROCM_ROCPROFILER_PATHS}
PATHS ${rocprofiler_ROOT_DIR} ${_ROCM_ROCPROFILER_PATHS}
PATH_SUFFIXES lib lib64)
if(rocprofiler_LIBRARY)
get_filename_component(rocprofiler_LIBRARY_DIR "${rocprofiler_LIBRARY}" PATH CACHE)
endif()
mark_as_advanced(rocprofiler_LIBRARY rocprofiler_hsa-runtime_LIBRARY)
unset(_ROCM_ROCPROFILER_PATHS)
# ----------------------------------------------------------------------------------------#
find_package_handle_standard_args(
rocprofiler DEFAULT_MSG rocprofiler_ROOT_DIR rocprofiler_INCLUDE_DIR
rocprofiler_hsa_INCLUDE_DIR rocprofiler_LIBRARY rocprofiler_hsa-runtime_LIBRARY)
# ----------------------------------------------------------------------------------------#
if(rocprofiler_FOUND)
add_library(rocprofiler::rocprofiler INTERFACE IMPORTED)
add_library(rocprofiler::roctx INTERFACE IMPORTED)
set(rocprofiler_INCLUDE_DIRS ${rocprofiler_INCLUDE_DIR}
${rocprofiler_hsa_INCLUDE_DIR})
set(rocprofiler_LIBRARIES ${rocprofiler_LIBRARY} ${rocprofiler_hsa-runtime_LIBRARY})
set(rocprofiler_LIBRARY_DIRS ${rocprofiler_LIBRARY_DIR})
target_include_directories(
rocprofiler::rocprofiler INTERFACE ${rocprofiler_INCLUDE_DIR}
${rocprofiler_hsa_INCLUDE_DIR})
target_link_libraries(rocprofiler::rocprofiler INTERFACE ${rocprofiler_LIBRARIES})
endif()
+16
Просмотреть файл
@@ -0,0 +1,16 @@
#%Module1.0
module-whatis "@PROJECT_NAME@ (version @PROJECT_VERSION@)"
proc ModulesHelp { } {
puts stderr "Loads @PROJECT_NAME@ v@PROJECT_VERSION@"
}
set ROOT [file normalize [file dirname [file normalize ${ModulesCurrentModulefile}]]/../../..]
setenv @PROJECT_NAME@_ROOT "${ROOT}"
prepend-path CMAKE_PREFIX_PATH "${ROOT}"
prepend-path PATH "${ROOT}/bin"
prepend-path LD_LIBRARY_PATH "${ROOT}/@CMAKE_INSTALL_LIBDIR@"
prepend-path PYTHONPATH "${ROOT}/@CMAKE_INSTALL_PYTHONDIR@"
setenv @PROJECT_NAME@_DIR "${ROOT}/@CMAKE_INSTALL_DATAROOTDIR@/cmake/@PROJECT_NAME@"
+56
Просмотреть файл
@@ -0,0 +1,56 @@
# - Config file for @PROJECT_NAME@ and its component libraries
# It defines the following variables:
#
# @PROJECT_NAME@_INCLUDE_DIRS
# @PROJECT_NAME@_LIBRARIES
# @PROJECT_NAME@_INTERNAL_DEFINES - used by the test suite
# compute paths
get_filename_component(@PROJECT_NAME@_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
# version
include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-version.cmake)
@PACKAGE_INIT@
set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_LIB_INSTALL_DIR@")
get_filename_component(@PROJECT_NAME@_ROOT_DIR ${@PROJECT_NAME@_INCLUDE_DIR} PATH)
set(@PROJECT_NAME@_LIBRARIES)
add_library(@PROJECT_NAME@::@PROJECT_NAME@ INTERFACE IMPORTED)
include("${@PROJECT_NAME@_CMAKE_DIR}/@PROJECT_NAME@-library-targets.cmake")
# Library dependencies
foreach(TARG @PROJECT_BUILD_TARGETS@)
set(TARG @PROJECT_NAME@-${TARG})
if(NOT @PROJECT_NAME@_FIND_COMPONENTS)
list(APPEND @PROJECT_NAME@_LIBRARIES @PROJECT_NAME@::${TARG})
target_link_libraries(@PROJECT_NAME@::@PROJECT_NAME@
INTERFACE @PROJECT_NAME@::${TARG})
endif()
endforeach()
if(@PROJECT_NAME@_FIND_COMPONENTS)
foreach(COMP ${@PROJECT_NAME@_FIND_COMPONENTS})
set(TARG @PROJECT_NAME@::@PROJECT_NAME@-${COMP})
if(TARGET ${TARG})
set(@PROJECT_NAME@_${COMP}_FOUND 1)
list(APPEND @PROJECT_NAME@_LIBRARIES ${TARG})
target_link_libraries(@PROJECT_NAME@::@PROJECT_NAME@
INTERFACE ${TARG})
else()
set(@PROJECT_NAME@_${COMP}_FOUND 0)
endif()
endforeach()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
@PROJECT_NAME@
FOUND_VAR @PROJECT_NAME@_FOUND
REQUIRED_VARS @PROJECT_NAME@_ROOT_DIR @PROJECT_NAME@_INCLUDE_DIR @PROJECT_NAME@_LIBRARIES
VERSION_VAR @PROJECT_NAME@_VERSION
HANDLE_COMPONENTS)
+23
Просмотреть файл
@@ -0,0 +1,23 @@
#!/usr/bin/env bash
BASEDIR=$(dirname ${BASH_SOURCE[0]})
command -v realpath &> /dev/null && BASEDIR=$(realpath ${BASEDIR}/../..) || BASEDIR=$(cd ${BASEDIR}/../.. && pwd)
if [ ! -d "${BASEDIR}" ]; then
echo "${BASEDIR} does not exist"
return 1
fi
@PROJECT_NAME@_ROOT=${BASEDIR}
PATH=${BASEDIR}/bin:${PATH}
LD_LIBRARY_PATH=${BASEDIR}/@CMAKE_INSTALL_LIBDIR@:${LD_LIBRARY_PATH}
PYTHONPATH=${BASEDIR}/@CMAKE_INSTALL_PYTHONDIR@:${PYTHONPATH}
CMAKE_PREFIX_PATH=${BASEDIR}:${CMAKE_PREFIX_PATH}
@PROJECT_NAME@_DIR=${BASEDIR}/@CMAKE_INSTALL_DATAROOTDIR@/cmake/@PROJECT_NAME@
export @PROJECT_NAME@_ROOT
export PATH
export LD_LIBRARY_PATH
export PYTHONPATH
export CMAKE_PREFIX_PATH
export @PROJECT_NAME@_DIR
+182
Просмотреть файл
@@ -0,0 +1,182 @@
# ########################################################################################
#
# Handles the build settings
#
# ########################################################################################
include_guard(DIRECTORY)
include(GNUInstallDirs)
include(FindPackageHandleStandardArgs)
include(rocprofiler_compilers)
include(rocprofiler_utilities)
target_compile_definitions(rocprofiler-build-flags INTERFACE $<$<CONFIG:DEBUG>:DEBUG>)
if(ROCPROFILER_BUILD_CI)
rocprofiler_target_compile_definitions(rocprofiler-build-flags
INTERFACE ROCPROFILER_CI)
endif()
# ----------------------------------------------------------------------------------------#
# dynamic linking and runtime libraries
#
if(CMAKE_DL_LIBS AND NOT "${CMAKE_DL_LIBS}" STREQUAL "dl")
# if cmake provides dl library, use that
set(dl_LIBRARY
${CMAKE_DL_LIBS}
CACHE FILEPATH "dynamic linking system library")
endif()
foreach(_TYPE dl rt)
if(NOT ${_TYPE}_LIBRARY)
find_library(${_TYPE}_LIBRARY NAMES ${_TYPE})
find_package_handle_standard_args(${_TYPE}-library REQUIRED_VARS ${_TYPE}_LIBRARY)
if(${_TYPE}-library_FOUND)
string(TOUPPER "${_TYPE}" _TYPE_UC)
rocprofiler_target_compile_definitions(rocprofiler-${_TYPE}
INTERFACE ROCPROFILER_${_TYPE_UC}=1)
target_link_libraries(rocprofiler-${_TYPE} INTERFACE ${${_TYPE}_LIBRARY})
if("${_TYPE}" STREQUAL "dl")
# This instructs the linker to add all symbols, not only used ones, to the
# dynamic symbol table. This option is needed for some uses of dlopen or
# to allow obtaining backtraces from within a program.
rocprofiler_target_compile_options(
rocprofiler-${_TYPE}
LANGUAGES C CXX
LINK_LANGUAGES C CXX
INTERFACE "-rdynamic")
endif()
else()
rocprofiler_target_compile_definitions(rocprofiler-${_TYPE}
INTERFACE ROCPROFILER_${_TYPE_UC}=0)
endif()
endif()
endforeach()
target_link_libraries(rocprofiler-build-flags INTERFACE rocprofiler::rocprofiler-dl)
# ----------------------------------------------------------------------------------------#
# set the compiler flags
#
rocprofiler_target_compile_options(rocprofiler-build-flags
INTERFACE "-W" "-Wall" "-Wno-unknown-pragmas")
# ----------------------------------------------------------------------------------------#
# extra flags for debug information in debug or optimized binaries
#
rocprofiler_target_compile_options(
rocprofiler-debug-flags INTERFACE "-g3" "-fno-omit-frame-pointer"
"-fno-optimize-sibling-calls")
target_compile_options(
rocprofiler-debug-flags
INTERFACE $<$<COMPILE_LANGUAGE:C>:$<$<C_COMPILER_ID:GNU>:-rdynamic>>
$<$<COMPILE_LANGUAGE:CXX>:$<$<CXX_COMPILER_ID:GNU>:-rdynamic>>)
if(NOT APPLE)
target_link_options(rocprofiler-debug-flags INTERFACE
$<$<CXX_COMPILER_ID:GNU>:-rdynamic>)
endif()
if(dl_LIBRARY)
target_link_libraries(rocprofiler-debug-flags INTERFACE ${dl_LIBRARY})
endif()
if(rt_LIBRARY)
target_link_libraries(rocprofiler-debug-flags INTERFACE ${rt_LIBRARY})
endif()
if(ROCPROFILER_BUILD_DEBUG)
target_link_libraries(rocprofiler-build-flags
INTERFACE rocprofiler::rocprofiler-debug-flags)
endif()
# ----------------------------------------------------------------------------------------#
# debug-safe optimizations
#
rocprofiler_target_compile_options(
rocprofiler-build-flags
LANGUAGES CXX
INTERFACE "-faligned-new")
# ----------------------------------------------------------------------------------------#
# fstack-protector
#
rocprofiler_target_compile_options(
rocprofiler-stack-protector
LANGUAGES C CXX
INTERFACE "-fstack-protector-strong" "-Wstack-protector")
if(ROCPROFILER_BUILD_STACK_PROTECTOR)
target_link_libraries(rocprofiler-build-flags
INTERFACE rocprofiler::rocprofiler-stack-protector)
endif()
# ----------------------------------------------------------------------------------------#
# developer build flags
#
rocprofiler_target_compile_options(
rocprofiler-developer-flags
LANGUAGES C CXX
INTERFACE "-Werror" "-Wdouble-promotion" "-Wshadow" "-Wextra"
"-Wstack-usage=524288" # 512 KB
)
if(ROCPROFILER_BUILD_DEVELOPER)
target_link_libraries(rocprofiler-build-flags
INTERFACE rocprofiler::rocprofiler-developer-flags)
endif()
# ----------------------------------------------------------------------------------------#
# release build flags
#
rocprofiler_target_compile_options(
rocprofiler-release-flags
LANGUAGES C CXX
INTERFACE "-g1" "-feliminate-unused-debug-symbols" "-gno-column-info"
"-gno-variable-location-views" "-gline-tables-only")
if(ROCPROFILER_BUILD_RELEASE)
target_link_libraries(rocprofiler-build-flags
INTERFACE rocprofiler::rocprofiler-release-flags)
endif()
# ----------------------------------------------------------------------------------------#
# static lib flags
#
target_compile_options(
rocprofiler-static-libgcc
INTERFACE $<$<COMPILE_LANGUAGE:C>:$<$<C_COMPILER_ID:GNU>:-static-libgcc>>
$<$<COMPILE_LANGUAGE:CXX>:$<$<CXX_COMPILER_ID:GNU>:-static-libgcc>>)
target_link_options(
rocprofiler-static-libgcc INTERFACE
$<$<COMPILE_LANGUAGE:C>:$<$<C_COMPILER_ID:GNU,Clang>:-static-libgcc>>
$<$<COMPILE_LANGUAGE:CXX>:$<$<CXX_COMPILER_ID:GNU,Clang>:-static-libgcc>>)
target_compile_options(
rocprofiler-static-libstdcxx
INTERFACE $<$<COMPILE_LANGUAGE:CXX>:$<$<CXX_COMPILER_ID:GNU>:-static-libstdc++>>)
target_link_options(
rocprofiler-static-libstdcxx INTERFACE
$<$<COMPILE_LANGUAGE:CXX>:$<$<CXX_COMPILER_ID:GNU,Clang>:-static-libstdc++>>)
if(ROCPROFILER_BUILD_STATIC_LIBGCC)
target_link_libraries(rocprofiler-build-flags
INTERFACE rocprofiler::rocprofiler-static-libgcc)
endif()
if(ROCPROFILER_BUILD_STATIC_LIBSTDCXX)
target_link_libraries(rocprofiler-build-flags
INTERFACE rocprofiler::rocprofiler-static-libstdcxx)
endif()
# ----------------------------------------------------------------------------------------#
# user customization
#
get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
if(NOT APPLE OR "$ENV{CONDA_PYTHON_EXE}" STREQUAL "")
rocprofiler_target_user_flags(rocprofiler-build-flags "CXX")
endif()
+350
Просмотреть файл
@@ -0,0 +1,350 @@
# include guard
# ########################################################################################
#
# Compilers
#
# ########################################################################################
#
# sets (cached):
#
# CMAKE_C_COMPILER_IS_<TYPE> CMAKE_CXX_COMPILER_IS_<TYPE>
#
# where TYPE is: - GNU - CLANG - INTEL - INTEL_ICC - INTEL_ICPC - PGI - XLC - HP_ACC -
# MIPS - MSVC
#
include(CheckCCompilerFlag)
include(CheckCSourceCompiles)
include(CheckCSourceRuns)
include(CheckCXXCompilerFlag)
include(CheckCXXSourceCompiles)
include(CheckCXXSourceRuns)
include(CMakeParseArguments)
include(rocprofiler_utilities)
# ----------------------------------------------------------------------------------------#
# macro converting string to list
# ----------------------------------------------------------------------------------------#
macro(ROCPROFILER_TO_LIST _VAR _STR)
string(REPLACE " " " " ${_VAR} "${_STR}")
string(REPLACE " " ";" ${_VAR} "${_STR}")
endmacro()
# ----------------------------------------------------------------------------------------#
# macro converting string to list
# ----------------------------------------------------------------------------------------#
macro(ROCPROFILER_TO_STRING _VAR _STR)
string(REPLACE ";" " " ${_VAR} "${_STR}")
endmacro()
# ----------------------------------------------------------------------------------------#
# Macro to add to string
# ----------------------------------------------------------------------------------------#
macro(add _VAR _FLAG)
if(NOT "${_FLAG}" STREQUAL "")
if("${${_VAR}}" STREQUAL "")
set(${_VAR} "${_FLAG}")
else()
set(${_VAR} "${${_VAR}} ${_FLAG}")
endif()
endif()
endmacro()
# ----------------------------------------------------------------------------------------#
# call before running check_{c,cxx}_compiler_flag
# ----------------------------------------------------------------------------------------#
macro(ROCPROFILER_BEGIN_FLAG_CHECK)
if(ROCPROFILER_QUIET_CONFIG)
if(NOT DEFINED CMAKE_REQUIRED_QUIET)
set(CMAKE_REQUIRED_QUIET OFF)
endif()
rocprofiler_save_variables(FLAG_CHECK VARIABLES CMAKE_REQUIRED_QUIET)
set(CMAKE_REQUIRED_QUIET ON)
endif()
endmacro()
# ----------------------------------------------------------------------------------------#
# call after running check_{c,cxx}_compiler_flag
# ----------------------------------------------------------------------------------------#
macro(ROCPROFILER_END_FLAG_CHECK)
if(ROCPROFILER_QUIET_CONFIG)
rocprofiler_restore_variables(FLAG_CHECK VARIABLES CMAKE_REQUIRED_QUIET)
endif()
endmacro()
# ----------------------------------------------------------------------------------------#
# check flag
# ----------------------------------------------------------------------------------------#
function(ROCPROFILER_TARGET_COMPILE_OPTIONS _TARG_TARGET)
cmake_parse_arguments(_TARG "BUILD_INTERFACE;FORCE" ""
"PUBLIC;INTERFACE;PRIVATE;LANGUAGES;LINK_LANGUAGES" ${ARGN})
if(NOT _TARG_MODE)
set(_TARG_MODE INTERFACE)
endif()
get_property(_ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
set(_SUPPORTED_LANGUAGES "C" "CXX")
if(NOT _TARG_LANGUAGES)
foreach(_LANG ${_ENABLED_LANGUAGES})
if(_LANG IN_LIST _SUPPORTED_LANGUAGES)
list(APPEND _TARG_LANGUAGES ${_LANG})
endif()
endforeach()
endif()
string(TOLOWER "_${_TARG_TARGET}" _TARG_TARGET_LC)
function(rocprofiler_target_compile_option_impl _TARGET_IMPL _TARGET_MODE_IMPL
_TARGET_LANG_IMPL _TARGET_FLAG_IMPL)
if(_TARG_BUILD_INTERFACE)
target_compile_options(
${_TARGET_IMPL}
${_TARGET_MODE_IMPL}
$<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:${_TARGET_LANG_IMPL}>:${_TARGET_FLAG_IMPL}>>
)
else()
target_compile_options(
${_TARGET_IMPL} ${_TARGET_MODE_IMPL}
$<$<COMPILE_LANGUAGE:${_TARGET_LANG_IMPL}>:${_TARGET_FLAG_IMPL}>)
endif()
if("${_TARGET_LANG_IMPL}" IN_LIST _TARG_LINK_LANGUAGES)
if(_TARG_BUILD_INTERFACE)
target_link_options(
${_TARGET_IMPL}
${_TARGET_MODE_IMPL}
$<BUILD_INTERFACE:$<$<LINK_LANGUAGE:${_TARGET_LANG_IMPL}>:${_TARGET_FLAG_IMPL}>>
)
else()
target_link_options(
${_TARGET_IMPL} ${_TARGET_MODE_IMPL}
$<$<LINK_LANGUAGE:${_TARGET_LANG_IMPL}>:${_TARGET_FLAG_IMPL}>)
endif()
endif()
endfunction()
function(rocprofiler_target_compile_option_patch_name _P_LANG _P_IN _P_OUT)
string(TOLOWER "${_P_LANG}" _P_LANG)
string(REGEX REPLACE "^(/|-)" "${_P_LANG}${_TARG_TARGET_LC}_" _NAME "${_P_IN}")
string(REPLACE "-" "_" _NAME "${_NAME}")
string(REPLACE " " "_" _NAME "${_NAME}")
string(REPLACE "=" "_" _NAME "${_NAME}")
set(${_P_OUT}
"${_NAME}"
PARENT_SCOPE)
endfunction()
if(NOT DEFINED rocprofiler_c_error AND NOT DEFINED rocprofiler_cxx_error)
rocprofiler_begin_flag_check()
check_c_compiler_flag("-Werror" c_rocprofiler_werror)
check_cxx_compiler_flag("-Werror" cxx_rocprofiler_werror)
rocprofiler_end_flag_check()
endif()
foreach(_TARG_MODE PUBLIC INTERFACE PRIVATE)
foreach(_FLAG ${_TARG_${_TARG_MODE}})
foreach(_LANG ${_TARG_LANGUAGES})
unset(FLAG_NAME)
rocprofiler_target_compile_option_patch_name(${_LANG} "${_FLAG}"
FLAG_NAME)
if(_TARG_FORCE)
set(${FLAG_NAME}
1
CACHE INTERNAL "${_LANG} flag: ${_FLAG}")
else()
rocprofiler_begin_flag_check()
if("${_LANG}" STREQUAL "C")
if(c_rocprofiler_werror)
check_c_compiler_flag("${_FLAG} -Werror" ${FLAG_NAME})
else()
check_c_compiler_flag("${_FLAG}" ${FLAG_NAME})
endif()
elseif("${_LANG}" STREQUAL "CXX")
if(cxx_rocprofiler_werror)
check_cxx_compiler_flag("${_FLAG} -Werror" ${FLAG_NAME})
else()
check_cxx_compiler_flag("${_FLAG}" ${FLAG_NAME})
endif()
else()
message(
FATAL_ERROR
"rocprofiler_target_compile_option :: unknown language: ${_LANG}"
)
endif()
rocprofiler_end_flag_check()
endif()
if(${FLAG_NAME})
rocprofiler_target_compile_option_impl(${_TARG_TARGET} ${_TARG_MODE}
${_LANG} "${_FLAG}")
endif()
endforeach()
endforeach()
endforeach()
endfunction()
# ----------------------------------------------------------------------------------------#
# add to any language
# ----------------------------------------------------------------------------------------#
function(ROCPROFILER_TARGET_USER_FLAGS _TARGET _LANGUAGE)
set(_FLAGS ${${_LANGUAGE}FLAGS} $ENV{${_LANGUAGE}FLAGS} ${${_LANGUAGE}_FLAGS}
$ENV{${_LANGUAGE}_FLAGS})
string(REPLACE " " ";" _FLAGS "${_FLAGS}")
set(${PROJECT_NAME}_${_LANGUAGE}_FLAGS
${${PROJECT_NAME}_${_LANGUAGE}_FLAGS} ${_FLAGS}
PARENT_SCOPE)
set(${PROJECT_NAME}_${_LANGUAGE}_COMPILE_OPTIONS
${${PROJECT_NAME}_${_LANGUAGE}_COMPILE_OPTIONS} ${_FLAGS}
PARENT_SCOPE)
target_compile_options(${_TARGET}
INTERFACE $<$<COMPILE_LANGUAGE:${_LANGUAGE}>:${_FLAGS}>)
endfunction()
# ----------------------------------------------------------------------------------------#
# add compiler definition
# ----------------------------------------------------------------------------------------#
function(ROCPROFILER_TARGET_COMPILE_DEFINITIONS _TARG _VIS)
foreach(_DEF ${ARGN})
if(NOT "${_DEF}" MATCHES "[A-Za-z_]+=.*" AND "${_DEF}" MATCHES "^ROCPROFILER_")
set(_DEF "${_DEF}=1")
endif()
target_compile_definitions(${_TARG} ${_VIS} $<$<COMPILE_LANGUAGE:CXX>:${_DEF}>)
endforeach()
endfunction()
# ----------------------------------------------------------------------------------------#
# determine compiler types for each language
# ----------------------------------------------------------------------------------------#
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
foreach(LANG C CXX HIP CUDA)
if(NOT DEFINED CMAKE_${LANG}_COMPILER)
set(CMAKE_${LANG}_COMPILER "")
endif()
if(NOT DEFINED CMAKE_${LANG}_COMPILER_ID)
set(CMAKE_${LANG}_COMPILER_ID "")
endif()
function(SET_COMPILER_VAR VAR _BOOL)
set(CMAKE_${LANG}_COMPILER_IS_${VAR}
${_BOOL}
CACHE INTERNAL "CMake ${LANG} compiler identification (${VAR})" FORCE)
mark_as_advanced(CMAKE_${LANG}_COMPILER_IS_${VAR})
endfunction()
if(("${LANG}" STREQUAL "C" AND CMAKE_COMPILER_IS_GNUCC)
OR ("${LANG}" STREQUAL "CXX" AND CMAKE_COMPILER_IS_GNUCXX))
# GNU compiler
set_compiler_var(GNU 1)
elseif(CMAKE_${LANG}_COMPILER MATCHES "icc.*")
# Intel icc compiler
set_compiler_var(INTEL 1)
set_compiler_var(INTEL_ICC 1)
elseif(CMAKE_${LANG}_COMPILER MATCHES "icpc.*")
# Intel icpc compiler
set_compiler_var(INTEL 1)
set_compiler_var(INTEL_ICPC 1)
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "AppleClang")
# Clang/LLVM compiler
set_compiler_var(CLANG 1)
set_compiler_var(APPLE_CLANG 1)
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "Clang")
# Clang/LLVM compiler
set_compiler_var(CLANG 1)
# HIP Clang compiler
if(CMAKE_${LANG}_COMPILER MATCHES "hipcc")
set_compiler_var(HIPCC 1)
endif()
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "PGI")
# PGI compiler
set_compiler_var(PGI 1)
elseif(CMAKE_${LANG}_COMPILER MATCHES "xlC" AND UNIX)
# IBM xlC compiler
set_compiler_var(XLC 1)
elseif(CMAKE_${LANG}_COMPILER MATCHES "aCC" AND UNIX)
# HP aC++ compiler
set_compiler_var(HP_ACC 1)
elseif(
CMAKE_${LANG}_COMPILER MATCHES "CC"
AND CMAKE_SYSTEM_NAME MATCHES "IRIX"
AND UNIX)
# IRIX MIPSpro CC Compiler
set_compiler_var(MIPS 1)
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "Intel")
set_compiler_var(INTEL 1)
set(CTYPE ICC)
if("${LANG}" STREQUAL "CXX")
set(CTYPE ICPC)
endif()
set_compiler_var(INTEL_${CTYPE} 1)
elseif(CMAKE_${LANG}_COMPILER MATCHES "MSVC")
# Windows Visual Studio compiler
set_compiler_var(MSVC 1)
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "NVIDIA")
# NVCC
set_compiler_var(NVIDIA 1)
endif()
# set other to no
foreach(
TYPE
GNU
INTEL
INTEL_ICC
INTEL_ICPC
APPLE_CLANG
CLANG
PGI
XLC
HP_ACC
MIPS
MSVC
NVIDIA
HIPCC)
if(NOT DEFINED CMAKE_${LANG}_COMPILER_IS_${TYPE})
set_compiler_var(${TYPE} 0)
endif()
endforeach()
endforeach()
+68
Просмотреть файл
@@ -0,0 +1,68 @@
# include guard
include_guard(GLOBAL)
include(CMakePackageConfigHelpers)
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME config)
install(
EXPORT rocprofiler-library-targets
FILE rocprofiler-library-targets.cmake
NAMESPACE rocprofiler::
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/rocprofiler)
# ------------------------------------------------------------------------------#
# install tree
#
set(PROJECT_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR})
set(PROJECT_BUILD_TARGETS user)
configure_package_config_file(
${PROJECT_SOURCE_DIR}/cmake/Templates/${PROJECT_NAME}-config.cmake.in
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/rocprofiler
INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
PATH_VARS PROJECT_INSTALL_DIR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR)
write_basic_package_version_file(
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-version.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMinorVersion)
install(
FILES
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-version.cmake
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}
OPTIONAL)
export(PACKAGE ${PROJECT_NAME})
# ------------------------------------------------------------------------------#
# build tree
#
set(_BUILDTREE_EXPORT_DIR
"${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/cmake/rocprofiler")
if(NOT EXISTS "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
endif()
if(NOT EXISTS "${_BUILDTREE_EXPORT_DIR}")
file(MAKE_DIRECTORY "${_BUILDTREE_EXPORT_DIR}")
endif()
if(NOT EXISTS "${_BUILDTREE_EXPORT_DIR}/rocprofiler-library-targets.cmake")
file(TOUCH "${_BUILDTREE_EXPORT_DIR}/rocprofiler-library-targets.cmake")
endif()
export(
EXPORT rocprofiler-library-targets
NAMESPACE rocprofiler::
FILE "${_BUILDTREE_EXPORT_DIR}/rocprofiler-library-targets.cmake")
set(rocprofiler_DIR
"${_BUILDTREE_EXPORT_DIR}"
CACHE PATH "rocprofiler" FORCE)
+141
Просмотреть файл
@@ -0,0 +1,141 @@
# include guard
include_guard(DIRECTORY)
# ########################################################################################
#
# External Packages are found here
#
# ########################################################################################
target_include_directories(
rocprofiler-headers
INTERFACE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/source/include>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/source>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
# include threading because of rooflines
target_link_libraries(rocprofiler-headers INTERFACE rocprofiler::rocprofiler-threading)
# ensure the env overrides the appending /opt/rocm later
string(REPLACE ":" ";" CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH};${CMAKE_PREFIX_PATH}")
set(ROCPROFILER_DEFAULT_ROCM_PATH
/opt/rocm
CACHE PATH "Default search path for ROCM")
if(EXISTS ${ROCPROFILER_DEFAULT_ROCM_PATH})
get_filename_component(_ROCPROFILER_DEFAULT_ROCM_PATH
"${ROCPROFILER_DEFAULT_ROCM_PATH}" REALPATH)
if(NOT "${_ROCPROFILER_DEFAULT_ROCM_PATH}" STREQUAL
"${ROCPROFILER_DEFAULT_ROCM_PATH}")
set(ROCPROFILER_DEFAULT_ROCM_PATH
"${_ROCPROFILER_DEFAULT_ROCM_PATH}"
CACHE PATH "Default search path for ROCM" FORCE)
endif()
endif()
# ----------------------------------------------------------------------------------------#
#
# Threading
#
# ----------------------------------------------------------------------------------------#
set(CMAKE_THREAD_PREFER_PTHREAD ON)
set(THREADS_PREFER_PTHREAD_FLAG OFF)
find_library(pthread_LIBRARY NAMES pthread pthreads)
find_package_handle_standard_args(pthread-library REQUIRED_VARS pthread_LIBRARY)
find_library(pthread_LIBRARY NAMES pthread pthreads)
find_package_handle_standard_args(pthread-library REQUIRED_VARS pthread_LIBRARY)
if(pthread_LIBRARY)
target_link_libraries(rocprofiler-threading INTERFACE ${pthread_LIBRARY})
else()
find_package(Threads ${rocprofiler_FIND_QUIETLY} ${rocprofiler_FIND_REQUIREMENT})
if(Threads_FOUND)
target_link_libraries(rocprofiler-threading INTERFACE Threads::Threads)
endif()
endif()
# ----------------------------------------------------------------------------------------#
#
# dynamic linking (dl) and runtime (rt) libraries
#
# ----------------------------------------------------------------------------------------#
foreach(_LIB dl rt)
find_library(${_LIB}_LIBRARY NAMES ${_LIB})
find_package_handle_standard_args(${_LIB}-library REQUIRED_VARS ${_LIB}_LIBRARY)
if(${_LIB}_LIBRARY)
target_link_libraries(rocprofiler-threading INTERFACE ${${_LIB}_LIBRARY})
endif()
endforeach()
# ----------------------------------------------------------------------------------------#
#
# stdc++fs (filesystem) library
#
# ----------------------------------------------------------------------------------------#
find_library(stdcxxfs_LIBRARY NAMES stdc++fs)
find_package_handle_standard_args(stdcxxfs-library REQUIRED_VARS stdcxxfs_LIBRARY)
if(stdcxxfs_LIBRARY)
target_link_libraries(rocprofiler-stdcxxfs INTERFACE ${stdcxxfs_LIBRARY})
else()
target_link_libraries(rocprofiler-stdcxxfs INTERFACE stdc++fs)
endif()
# ----------------------------------------------------------------------------------------#
#
# HIP
#
# ----------------------------------------------------------------------------------------#
find_package(rocm_version REQUIRED)
list(APPEND CMAKE_PREFIX_PATH "${rocm_version_DIR}" "${rocm_version_DIR}/llvm")
list(APPEND CMAKE_MODULE_PATH "${rocm_version_DIR}/hip/cmake"
"${rocm_version_DIR}/lib/cmake")
find_package(hip REQUIRED CONFIG)
target_link_libraries(rocprofiler-hip INTERFACE hip::host)
# ----------------------------------------------------------------------------------------#
#
# HSA runtime
#
# ----------------------------------------------------------------------------------------#
find_package(
hsa-runtime64
REQUIRED
CONFIG
HINTS
${rocm_version_DIR}
${ROCM_PATH}
PATHS
${rocm_version_DIR}
${ROCM_PATH})
target_link_libraries(rocprofiler-hsa-runtime INTERFACE hsa-runtime64::hsa-runtime64)
# ----------------------------------------------------------------------------------------#
#
# amd comgr
#
# ----------------------------------------------------------------------------------------#
find_package(
amd_comgr
REQUIRED
CONFIG
HINTS
${rocm_version_DIR}
${ROCM_PATH}
PATHS
${rocm_version_DIR}
${ROCM_PATH}
PATH_SUFFIXES
lib/cmake/amd_comgr)
target_link_libraries(rocprofiler-amd-comgr INTERFACE amd_comgr)
+128
Просмотреть файл
@@ -0,0 +1,128 @@
# configure packaging
function(rocprofiler_parse_release)
if(EXISTS /etc/lsb-release AND NOT IS_DIRECTORY /etc/lsb-release)
file(READ /etc/lsb-release _LSB_RELEASE)
if(_LSB_RELEASE)
string(REGEX
REPLACE "DISTRIB_ID=(.*)\nDISTRIB_RELEASE=(.*)\nDISTRIB_CODENAME=.*"
"\\1-\\2" _SYSTEM_NAME "${_LSB_RELEASE}")
endif()
elseif(EXISTS /etc/os-release AND NOT IS_DIRECTORY /etc/os-release)
file(READ /etc/os-release _OS_RELEASE)
if(_OS_RELEASE)
string(REPLACE "\"" "" _OS_RELEASE "${_OS_RELEASE}")
string(REPLACE "-" " " _OS_RELEASE "${_OS_RELEASE}")
string(REGEX REPLACE "NAME=.*\nVERSION=([0-9\.]+).*\nID=([a-z]+).*" "\\2-\\1"
_SYSTEM_NAME "${_OS_RELEASE}")
endif()
endif()
string(TOLOWER "${_SYSTEM_NAME}" _SYSTEM_NAME)
if(NOT _SYSTEM_NAME)
set(_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}")
endif()
set(_SYSTEM_NAME
"${_SYSTEM_NAME}"
PARENT_SCOPE)
endfunction()
# parse either /etc/lsb-release or /etc/os-release
rocprofiler_parse_release()
if(NOT _SYSTEM_NAME)
set(_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}")
endif()
# Add packaging directives
set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
set(CPACK_PACKAGE_VENDOR "Advanced Micro Devices, Inc.")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_DESCRIPTION}")
set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
set(CPACK_PACKAGE_CONTACT "jonathan.madsen@amd.com")
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
set(ROCPROFILER_CPACK_SYSTEM_NAME
"${_SYSTEM_NAME}"
CACHE STRING "System name, e.g. Linux or Ubuntu-18.04")
set(ROCPROFILER_CPACK_PACKAGE_SUFFIX "")
set(CPACK_PACKAGE_FILE_NAME
"${CPACK_PACKAGE_NAME}-${ROCPROFILER_VERSION}-${ROCPROFILER_CPACK_SYSTEM_NAME}${ROCPROFILER_CPACK_PACKAGE_SUFFIX}"
)
if(DEFINED ENV{CPACK_PACKAGE_FILE_NAME})
set(CPACK_PACKAGE_FILE_NAME $ENV{CPACK_PACKAGE_FILE_NAME})
endif()
set(ROCPROFILER_PACKAGE_FILE_NAME
${CPACK_PACKAGE_NAME}-${ROCPROFILER_VERSION}-${ROCPROFILER_CPACK_SYSTEM_NAME}${ROCPROFILER_CPACK_PACKAGE_SUFFIX}
)
rocprofiler_add_feature(ROCPROFILER_PACKAGE_FILE_NAME "CPack filename")
# -------------------------------------------------------------------------------------- #
#
# Debian package specific variables
#
# -------------------------------------------------------------------------------------- #
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "${PROJECT_HOMEPAGE_URL}")
set(CPACK_DEBIAN_PACKAGE_RELEASE
"${ROCPROFILER_CPACK_SYSTEM_NAME}${ROCPROFILER_CPACK_PACKAGE_SUFFIX}")
string(REGEX REPLACE "([a-zA-Z])-([0-9])" "\\1\\2" CPACK_DEBIAN_PACKAGE_RELEASE
"${CPACK_DEBIAN_PACKAGE_RELEASE}")
string(REPLACE "-" "~" CPACK_DEBIAN_PACKAGE_RELEASE "${CPACK_DEBIAN_PACKAGE_RELEASE}")
if(DEFINED ENV{CPACK_DEBIAN_PACKAGE_RELEASE})
set(CPACK_DEBIAN_PACKAGE_RELEASE $ENV{CPACK_DEBIAN_PACKAGE_RELEASE})
endif()
set(_DEBIAN_PACKAGE_DEPENDS "")
if(rocm_version_FOUND)
set(_ROCPROFILER_SUFFIX " (>= 1.0.0.${rocm_version_NUMERIC_VERSION})")
set(_ROCTRACER_SUFFIX " (>= 1.0.0.${rocm_version_NUMERIC_VERSION})")
set(_ROCM_SMI_SUFFIX
" (>= ${rocm_version_MAJOR_VERSION}.0.0.${rocm_version_NUMERIC_VERSION})")
endif()
string(REPLACE ";" ", " _DEBIAN_PACKAGE_DEPENDS "${_DEBIAN_PACKAGE_DEPENDS}")
set(CPACK_DEBIAN_PACKAGE_DEPENDS
"${_DEBIAN_PACKAGE_DEPENDS}"
CACHE STRING "Debian package dependencies" FORCE)
rocprofiler_add_feature(CPACK_DEBIAN_PACKAGE_DEPENDS "Debian package dependencies")
set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT")
# -------------------------------------------------------------------------------------- #
#
# RPM package specific variables
#
# -------------------------------------------------------------------------------------- #
if(DEFINED CPACK_PACKAGING_INSTALL_PREFIX)
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "${CPACK_PACKAGING_INSTALL_PREFIX}")
endif()
set(CPACK_RPM_PACKAGE_RELEASE
"${ROCPROFILER_CPACK_SYSTEM_NAME}${ROCPROFILER_CPACK_PACKAGE_SUFFIX}")
string(REGEX REPLACE "([a-zA-Z])-([0-9])" "\\1\\2" CPACK_RPM_PACKAGE_RELEASE
"${CPACK_RPM_PACKAGE_RELEASE}")
string(REPLACE "-" "~" CPACK_RPM_PACKAGE_RELEASE "${CPACK_RPM_PACKAGE_RELEASE}")
if(DEFINED ENV{CPACK_RPM_PACKAGE_RELEASE})
set(CPACK_RPM_PACKAGE_RELEASE $ENV{CPACK_RPM_PACKAGE_RELEASE})
endif()
# Get rpm distro
if(CPACK_RPM_PACKAGE_RELEASE)
set(CPACK_RPM_PACKAGE_RELEASE_DIST ON)
endif()
set(CPACK_RPM_FILE_NAME "RPM-DEFAULT")
# -------------------------------------------------------------------------------------- #
#
# Prepare final version for the CPACK use
#
# -------------------------------------------------------------------------------------- #
set(CPACK_PACKAGE_VERSION
"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}"
)
include(CPack)
+102
Просмотреть файл
@@ -0,0 +1,102 @@
# ------------------------------------------------------------------------------#
#
# creates following targets to format code:
# - format
# - format-source
# - format-cmake
# - format-python
# - format-rocprofiler-source
# - format-rocprofiler-cmake
# - format-rocprofiler-python
#
# ------------------------------------------------------------------------------#
include_guard(DIRECTORY)
find_program(ROCPROFILER_CLANG_FORMAT_EXE NAMES clang-format-11 clang-format-mp-11)
find_program(ROCPROFILER_CMAKE_FORMAT_EXE NAMES cmake-format)
find_program(ROCPROFILER_BLACK_FORMAT_EXE NAMES black)
add_custom_target(format-rocprofiler)
if(NOT TARGET format)
add_custom_target(format)
endif()
foreach(_TYPE source python cmake)
if(NOT TARGET format-${_TYPE})
add_custom_target(format-${_TYPE})
endif()
endforeach()
if(ROCPROFILER_CLANG_FORMAT_EXE
OR ROCPROFILER_BLACK_FORMAT_EXE
OR ROCPROFILER_CMAKE_FORMAT_EXE)
set(rocp_source_files)
set(rocp_header_files)
set(rocp_python_files)
set(rocp_cmake_files ${PROJECT_SOURCE_DIR}/CMakeLists.txt
${PROJECT_SOURCE_DIR}/external/CMakeLists.txt)
foreach(_DIR cmake samples source tests)
foreach(_TYPE header_files source_files cmake_files python_files)
set(${_TYPE})
endforeach()
file(GLOB_RECURSE header_files ${PROJECT_SOURCE_DIR}/${_DIR}/*.h
${PROJECT_SOURCE_DIR}/${_DIR}/*.hpp)
file(GLOB_RECURSE source_files ${PROJECT_SOURCE_DIR}/${_DIR}/*.c
${PROJECT_SOURCE_DIR}/${_DIR}/*.cpp)
file(GLOB_RECURSE cmake_files ${PROJECT_SOURCE_DIR}/${_DIR}/*CMakeLists.txt
${PROJECT_SOURCE_DIR}/${_DIR}/*.cmake)
file(GLOB_RECURSE python_files ${PROJECT_SOURCE_DIR}/${_DIR}/*.py)
foreach(_TYPE header_files source_files cmake_files python_files)
list(APPEND rocp_${_TYPE} ${${_TYPE}})
endforeach()
endforeach()
foreach(_TYPE header_files source_files cmake_files python_files)
if(rocp_${_TYPE})
list(REMOVE_DUPLICATES rocp_${_TYPE})
list(SORT rocp_${_TYPE})
endif()
endforeach()
if(ROCPROFILER_CLANG_FORMAT_EXE)
add_custom_target(
format-rocprofiler-source
${ROCPROFILER_CLANG_FORMAT_EXE} -i ${rocp_header_files} ${rocp_source_files}
COMMENT
"[rocprofiler] Running source formatter ${ROCPROFILER_CLANG_FORMAT_EXE}..."
)
endif()
if(ROCPROFILER_BLACK_FORMAT_EXE)
add_custom_target(
format-rocprofiler-python
${ROCPROFILER_BLACK_FORMAT_EXE} -q ${rocp_python_files}
COMMENT
"[rocprofiler] Running Python formatter ${ROCPROFILER_BLACK_FORMAT_EXE}..."
)
endif()
if(ROCPROFILER_CMAKE_FORMAT_EXE)
add_custom_target(
format-rocprofiler-cmake
${ROCPROFILER_CMAKE_FORMAT_EXE} -i ${rocp_cmake_files}
COMMENT
"[rocprofiler] Running CMake formatter ${ROCPROFILER_CMAKE_FORMAT_EXE}..."
)
endif()
foreach(_TYPE source python cmake)
if(TARGET format-rocprofiler-${_TYPE})
add_dependencies(format-rocprofiler format-rocprofiler-${_TYPE})
add_dependencies(format-${_TYPE} format-rocprofiler-${_TYPE})
endif()
endforeach()
foreach(_TYPE source python)
if(TARGET format-rocprofiler-${_TYPE})
add_dependencies(format format-rocprofiler-${_TYPE})
endif()
endforeach()
endif()
+44
Просмотреть файл
@@ -0,0 +1,44 @@
#
#
# Forward declaration of all INTERFACE targets
#
#
include(rocprofiler_utilities)
#
# interfaces for build flags
#
rocprofiler_add_interface_library(
rocprofiler-headers
"Provides minimal set of include flags to compile with rocprofiler")
rocprofiler_add_interface_library(rocprofiler-build-flags
"Provides generalized build flags for rocprofiler")
rocprofiler_add_interface_library(rocprofiler-threading "Enables multithreading support")
rocprofiler_add_interface_library(rocprofiler-perfetto "Enables Perfetto support")
rocprofiler_add_interface_library(rocprofiler-compile-definitions "Compile definitions")
rocprofiler_add_interface_library(rocprofiler-static-libgcc
"Link to static version of libgcc")
rocprofiler_add_interface_library(rocprofiler-static-libstdcxx
"Link to static version of libstdc++")
rocprofiler_add_interface_library(rocprofiler-developer-flags
"Compiler flags for developers (more warnings, etc.)")
rocprofiler_add_interface_library(rocprofiler-debug-flags
"Compiler flags for more debug info")
rocprofiler_add_interface_library(rocprofiler-release-flags
"Compiler flags for more debug info")
rocprofiler_add_interface_library(rocprofiler-stack-protector
"Adds stack-protector compiler flags")
rocprofiler_add_interface_library(rocprofiler-memcheck INTERFACE)
#
# interfaces for libraries
#
rocprofiler_add_interface_library(rocprofiler-dl
"Build flags for dynamic linking library")
rocprofiler_add_interface_library(rocprofiler-rt "Build flags for runtime library")
rocprofiler_add_interface_library(rocprofiler-hip "HIP library")
rocprofiler_add_interface_library(rocprofiler-hsa-runtime "HSA runtime library")
rocprofiler_add_interface_library(rocprofiler-amd-comgr "AMD comgr library")
rocprofiler_add_interface_library(rocprofiler-googletest "Google Test library" INTERNAL)
rocprofiler_add_interface_library(rocprofiler-stdcxxfs "C++ filesystem library" INTERNAL)
+36
Просмотреть файл
@@ -0,0 +1,36 @@
include_guard(GLOBAL)
# ----------------------------------------------------------------------------------------#
#
# Clang Tidy
#
# ----------------------------------------------------------------------------------------#
find_program(ROCPROFILER_CLANG_TIDY_COMMAND NAMES clang-tidy)
macro(ROCPROFILER_ACTIVATE_CLANG_TIDY)
if(ROCPROFILER_ENABLE_CLANG_TIDY)
if(NOT ROCPROFILER_CLANG_TIDY_COMMAND)
message(
FATAL_ERROR
"ROCPROFILER_ENABLE_CLANG_TIDY is ON but clang-tidy is not found!")
endif()
set(CMAKE_CXX_CLANG_TIDY ${ROCPROFILER_CLANG_TIDY_COMMAND}
-header-filter=${PROJECT_SOURCE_DIR}/.*)
# Create a preprocessor definition that depends on .clang-tidy content so the
# compile command will change when .clang-tidy changes. This ensures that a
# subsequent build re-runs clang-tidy on all sources even if they do not otherwise
# need to be recompiled. Nothing actually uses this definition. We add it to
# targets on which we run clang-tidy just to get the build dependency on the
# .clang-tidy file.
file(SHA1 ${PROJECT_SOURCE_DIR}/.clang-tidy clang_tidy_sha1)
set(CLANG_TIDY_DEFINITIONS "CLANG_TIDY_SHA1=${clang_tidy_sha1}")
unset(clang_tidy_sha1)
endif()
endmacro()
macro(ROCPROFILER_DEACTIVATE_CLANG_TIDY)
set(CMAKE_CXX_CLANG_TIDY)
endmacro()
+67
Просмотреть файл
@@ -0,0 +1,67 @@
#
#
#
set(ROCPROFILER_MEMCHECK_TYPES "ThreadSanitizer" "AddressSanitizer" "LeakSanitizer"
"MemorySanitizer" "UndefinedBehaviorSanitizer")
if(ROCPROFILER_MEMCHECK AND NOT ROCPROFILER_MEMCHECK IN_LIST ROCPROFILER_MEMCHECK_TYPES)
message(
FATAL_ERROR
"Unsupported memcheck type '${ROCPROFILER_MEMCHECK}'. Options: ${ROCPROFILER_MEMCHECK_TYPES}"
)
endif()
set_property(CACHE ROCPROFILER_MEMCHECK PROPERTY STRINGS "${ROCPROFILER_MEMCHECK_TYPES}")
function(rocprofiler_add_memcheck_flags _TYPE)
target_compile_options(
rocprofiler-memcheck
INTERFACE $<BUILD_INTERFACE:-g3 -Og -fno-omit-frame-pointer
-fno-optimize-sibling-calls -fno-inline-functions -fsanitize=${_TYPE}>)
target_link_options(rocprofiler-memcheck INTERFACE
$<BUILD_INTERFACE:-fsanitize=${_TYPE} -Wl,--no-undefined>)
endfunction()
function(rocprofiler_set_memcheck_env _TYPE _LIB_BASE)
set(_LIBS ${_LIB_BASE})
foreach(_N 6 5 4 3 2 1 0)
list(
APPEND _LIBS
${CMAKE_SHARED_LIBRARY_PREFIX}${_LIB_BASE}${CMAKE_SHARED_LIBRARY_SUFFIX}.${_N}
)
endforeach()
foreach(_LIB ${_LIBS})
if(NOT ${_TYPE}_LIBRARY)
find_library(${_TYPE}_LIBRARY NAMES ${_LIB} ${ARGN})
endif()
endforeach()
target_link_libraries(rocprofiler-memcheck INTERFACE ${_LIB_BASE})
if(${_TYPE}_LIBRARY)
set(ROCPROFILER_MEMCHECK_PRELOAD_ENV
" LD_PRELOAD=${${_TYPE}_LIBRARY} "
CACHE INTERNAL " LD_PRELOAD env variable for tests " FORCE)
endif()
endfunction()
# always unset so that it doesn't preload if memcheck disabled
unset(ROCPROFILER_MEMCHECK_PRELOAD_ENV CACHE)
if(ROCPROFILER_MEMCHECK STREQUAL " AddressSanitizer ")
rocprofiler_add_memcheck_flags(" address ")
rocprofiler_set_memcheck_env(" ${ROCPROFILER_MEMCHECK}" "asan ")
elseif(ROCPROFILER_MEMCHECK STREQUAL " LeakSanitizer ")
rocprofiler_add_memcheck_flags(" leak ")
rocprofiler_set_memcheck_env(" ${ROCPROFILER_MEMCHECK}" "lsan ")
elseif(ROCPROFILER_MEMCHECK STREQUAL " MemorySanitizer ")
rocprofiler_add_memcheck_flags(" memory ")
elseif(ROCPROFILER_MEMCHECK STREQUAL " ThreadSanitizer ")
rocprofiler_add_memcheck_flags(" thread ")
rocprofiler_set_memcheck_env(" ${ROCPROFILER_MEMCHECK}" "tsan ")
elseif(ROCPROFILER_MEMCHECK STREQUAL " UndefinedBehaviorSanitizer ")
rocprofiler_add_memcheck_flags(" undefined ")
rocprofiler_set_memcheck_env(" ${ROCPROFILER_MEMCHECK}" "ubsan ")
endif()
+104
Просмотреть файл
@@ -0,0 +1,104 @@
#
# rocprofiler_options.cmake
#
# Configure miscellaneous settings
#
# standard cmake options
rocprofiler_add_option(BUILD_SHARED_LIBS "Build shared libraries" ON)
rocprofiler_add_option(BUILD_STATIC_LIBS "Build static libraries" OFF)
rocprofiler_add_option(CMAKE_POSITION_INDEPENDENT_CODE "Build position independent code"
ON)
# export compile commands in the project
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
rocprofiler_add_option(ROCPROFILER_BUILD_TESTS "Enable building the tests" OFF)
rocprofiler_add_option(ROCPROFILER_BUILD_SAMPLES "Enable building the code samples" OFF)
# CLI and FILE plugins are always built
foreach(_PLUGIN "ATT" "CTF" "PERFETTO")
rocprofiler_add_option(ROCPROFILER_BUILD_PLUGIN_${_PLUGIN}
"Enable building the ${_PLUGIN} plugin" ON)
endforeach()
rocprofiler_add_option(ROCPROFILER_DEBUG_TRACE "Enable debug tracing" OFF ADVANCED)
rocprofiler_add_option(ROCPROFILER_LD_AQLPROFILE
"Enable direct loading of AQL-profile HSA extension" OFF ADVANCED)
rocprofiler_add_option(ROCPROFILER_BUILD_CI "Enable continuous integration additions" OFF
ADVANCED)
rocprofiler_add_option(ROCPROFILER_ENABLE_CLANG_TIDY "Enable clang-tidy checks" OFF
ADVANCED)
rocprofiler_add_option(ROCPROFILER_BUILD_WERROR "Any compiler warnings are errors" OFF
ADVANCED)
rocprofiler_add_option(
ROCPROFILER_BUILD_DEVELOPER "Extra build flags for development like -Werror"
${ROCPROFILER_BUILD_CI} ADVANCED)
rocprofiler_add_option(ROCPROFILER_BUILD_RELEASE "Build with minimal debug info" OFF
ADVANCED)
rocprofiler_add_option(ROCPROFILER_BUILD_DEBUG "Build with extra debug info" OFF ADVANCED)
rocprofiler_add_option(ROCPROFILER_BUILD_STATIC_LIBGCC
"Build with -static-libgcc if possible" OFF ADVANCED)
rocprofiler_add_option(ROCPROFILER_BUILD_STATIC_LIBSTDCXX
"Build with -static-libstdc++ if possible" OFF ADVANCED)
rocprofiler_add_option(ROCPROFILER_BUILD_STACK_PROTECTOR "Build with -fstack-protector"
OFF ADVANCED)
# In the future, we will do this even with clang-tidy enabled
if(ROCPROFILER_BUILD_CI AND NOT ROCPROFILER_ENABLE_CLANG_TIDY)
message(STATUS "Forcing ROCPROFILER_BUILD_WERROR=ON because ROCPROFILER_BUILD_CI=ON")
set(ROCPROFILER_BUILD_WERROR
ON
CACHE BOOL
"Any compiler warnings are errors (forced due ROCPROFILER_BUILD_CI=ON)"
FORCE)
endif()
set(ROCPROFILER_BUILD_TYPES "Release" "RelWithDebInfo" "Debug" "MinSizeRel" "Coverage")
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE
"Release"
CACHE STRING "Build type" FORCE)
endif()
if(NOT CMAKE_BUILD_TYPE IN_LIST ROCPROFILER_BUILD_TYPES)
message(
FATAL_ERROR
"Unsupported build type '${CMAKE_BUILD_TYPE}'. Options: ${ROCPROFILER_BUILD_TYPES}"
)
endif()
if(ROCPROFILER_BUILD_CI)
foreach(_BUILD_TYPE ${ROCPROFILER_BUILD_TYPES})
string(TOUPPER "${_BUILD_TYPE}" _BUILD_TYPE)
# remove NDEBUG preprocessor def so that asserts are triggered
string(REGEX REPLACE ".DNDEBUG" "" CMAKE_C_FLAGS_${_BUILD_TYPE}
"${CMAKE_C_FLAGS_${_BUILD_TYPE}}")
string(REGEX REPLACE ".DNDEBUG" "" CMAKE_CXX_FLAGS_${_BUILD_TYPE}
"${CMAKE_CXX_FLAGS_${_BUILD_TYPE}}")
endforeach()
endif()
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${ROCPROFILER_BUILD_TYPES}")
endif()
rocprofiler_add_cache_option(ROCPROFILER_MEMCHECK "" STRING "Memory checker type"
ADVANCED)
# ASAN is defined by testing team on Jenkins
if(ASAN)
set(ROCPROFILER_MEMCHECK
"AddressSanitizer"
CACHE STRING "Memory checker type (forced by ASAN defined)" FORCE)
endif()
include(rocprofiler_memcheck)
+928
Просмотреть файл
@@ -0,0 +1,928 @@
# include guard
include_guard(GLOBAL)
# MacroUtilities - useful macros and functions for generic tasks
#
cmake_policy(PUSH)
cmake_policy(SET CMP0054 NEW)
cmake_policy(SET CMP0057 NEW)
include(CMakeDependentOption)
include(CMakeParseArguments)
# -----------------------------------------------------------------------
# message which handles ROCPROFILER_QUIET_CONFIG settings
# -----------------------------------------------------------------------
#
function(ROCPROFILER_MESSAGE TYPE)
if(NOT ROCPROFILER_QUIET_CONFIG)
message(${TYPE} "[rocprofiler] ${ARGN}")
endif()
endfunction()
# -----------------------------------------------------------------------
# Save a set of variables with the given prefix
# -----------------------------------------------------------------------
macro(ROCPROFILER_SAVE_VARIABLES _PREFIX)
# parse args
cmake_parse_arguments(
SAVE
"" # options
"CONDITION" # single value args
"VARIABLES" # multiple value args
${ARGN})
if(DEFINED SAVE_CONDITION AND NOT "${SAVE_CONDITION}" STREQUAL "")
if(${SAVE_CONDITION})
foreach(_VAR ${SAVE_VARIABLES})
if(DEFINED ${_VAR})
set(${_PREFIX}_${_VAR} "${${_VAR}}")
else()
message(AUTHOR_WARNING "${_VAR} is not defined")
endif()
endforeach()
endif()
else()
foreach(_VAR ${SAVE_VARIABLES})
if(DEFINED ${_VAR})
set(${_PREFIX}_${_VAR} "${${_VAR}}")
else()
message(AUTHOR_WARNING "${_VAR} is not defined")
endif()
endforeach()
endif()
unset(SAVE_CONDITION)
unset(SAVE_VARIABLES)
endmacro()
# -----------------------------------------------------------------------
# Restore a set of variables with the given prefix
# -----------------------------------------------------------------------
macro(ROCPROFILER_RESTORE_VARIABLES _PREFIX)
# parse args
cmake_parse_arguments(
RESTORE
"" # options
"CONDITION" # single value args
"VARIABLES" # multiple value args
${ARGN})
if(DEFINED RESTORE_CONDITION AND NOT "${RESTORE_CONDITION}" STREQUAL "")
if(${RESTORE_CONDITION})
foreach(_VAR ${RESTORE_VARIABLES})
if(DEFINED ${_PREFIX}_${_VAR})
set(${_VAR} ${${_PREFIX}_${_VAR}})
unset(${_PREFIX}_${_VAR})
else()
message(AUTHOR_WARNING "${_PREFIX}_${_VAR} is not defined")
endif()
endforeach()
endif()
else()
foreach(_VAR ${RESTORE_VARIABLES})
if(DEFINED ${_PREFIX}_${_VAR})
set(${_VAR} ${${_PREFIX}_${_VAR}})
unset(${_PREFIX}_${_VAR})
else()
message(AUTHOR_WARNING "${_PREFIX}_${_VAR} is not defined")
endif()
endforeach()
endif()
unset(RESTORE_CONDITION)
unset(RESTORE_VARIABLES)
endmacro()
# -----------------------------------------------------------------------
# function - rocprofiler_capitalize - make a string capitalized (first letter is capital)
# usage: capitalize("SHARED" CShared) message(STATUS "-- CShared is \"${CShared}\"") $ --
# CShared is "Shared"
function(ROCPROFILER_CAPITALIZE str var)
# make string lower
string(TOLOWER "${str}" str)
string(SUBSTRING "${str}" 0 1 _first)
string(TOUPPER "${_first}" _first)
string(SUBSTRING "${str}" 1 -1 _remainder)
string(CONCAT str "${_first}" "${_remainder}")
set(${var}
"${str}"
PARENT_SCOPE)
endfunction()
# ------------------------------------------------------------------------------#
# function rocprofiler_strip_target(<TARGET> [FORCE] [EXPLICIT])
#
# Creates a post-build command which strips a binary. FORCE flag will override
#
function(ROCPROFILER_STRIP_TARGET)
cmake_parse_arguments(STRIP "FORCE;EXPLICIT" "" "ARGS" ${ARGN})
list(LENGTH STRIP_UNPARSED_ARGUMENTS NUM_UNPARSED)
if(NUM_UNPARSED EQUAL 1)
set(_TARGET "${STRIP_UNPARSED_ARGUMENTS}")
else()
rocprofiler_message(
FATAL_ERROR "rocprofiler_strip_target cannot deduce target from \"${ARGN}\"")
endif()
if(NOT TARGET "${_TARGET}")
rocprofiler_message(
FATAL_ERROR
"rocprofiler_strip_target not provided valid target: \"${_TARGET}\"")
endif()
if(CMAKE_STRIP AND (STRIP_FORCE OR ROCPROFILER_STRIP_LIBRARIES))
if(STRIP_EXPLICIT)
add_custom_command(
TARGET ${_TARGET}
POST_BUILD
COMMAND ${CMAKE_STRIP} ${STRIP_ARGS} $<TARGET_FILE:${_TARGET}>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Stripping ${_TARGET}...")
else()
add_custom_command(
TARGET ${_TARGET}
POST_BUILD
COMMAND
${CMAKE_STRIP} -w --keep-symbol="rocprofiler_init"
--keep-symbol="rocprofiler_finalize"
--keep-symbol="rocprofiler_push_trace"
--keep-symbol="rocprofiler_pop_trace"
--keep-symbol="rocprofiler_push_region"
--keep-symbol="rocprofiler_pop_region"
--keep-symbol="rocprofiler_set_env"
--keep-symbol="rocprofiler_set_mpi"
--keep-symbol="rocprofiler_reset_preload"
--keep-symbol="rocprofiler_set_instrumented"
--keep-symbol="rocprofiler_user_*" --keep-symbol="ompt_start_tool"
--keep-symbol="kokkosp_*" --keep-symbol="OnLoad"
--keep-symbol="OnUnload" --keep-symbol="OnLoadToolProp"
--keep-symbol="OnUnloadTool" --keep-symbol="__libc_start_main"
${STRIP_ARGS} $<TARGET_FILE:${_TARGET}>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Stripping ${_TARGET}...")
endif()
endif()
endfunction()
# ------------------------------------------------------------------------------#
# function add_rocprofiler_test_target()
#
# Creates a target which runs ctest but depends on all the tests being built.
#
function(ADD_ROCPROFILER_TEST_TARGET)
if(NOT TARGET rocprofiler-test)
add_custom_target(
rocprofiler-test
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR} --target test
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
COMMENT "Running tests...")
endif()
endfunction()
# ----------------------------------------------------------------------------------------#
# macro rocprofiler_checkout_git_submodule()
#
# Run "git submodule update" if a file in a submodule does not exist
#
# ARGS: RECURSIVE (option) -- add "--recursive" flag RELATIVE_PATH (one value) --
# typically the relative path to submodule from PROJECT_SOURCE_DIR WORKING_DIRECTORY (one
# value) -- (default: PROJECT_SOURCE_DIR) TEST_FILE (one value) -- file to check for
# (default: CMakeLists.txt) ADDITIONAL_CMDS (many value) -- any addition commands to pass
#
function(ROCPROFILER_CHECKOUT_GIT_SUBMODULE)
# parse args
cmake_parse_arguments(
CHECKOUT "RECURSIVE"
"RELATIVE_PATH;WORKING_DIRECTORY;TEST_FILE;REPO_URL;REPO_BRANCH"
"ADDITIONAL_CMDS" ${ARGN})
if(NOT CHECKOUT_WORKING_DIRECTORY)
set(CHECKOUT_WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
endif()
if(NOT CHECKOUT_TEST_FILE)
set(CHECKOUT_TEST_FILE "CMakeLists.txt")
endif()
# default assumption
if(NOT CHECKOUT_REPO_BRANCH)
set(CHECKOUT_REPO_BRANCH "master")
endif()
find_package(Git)
set(_DIR "${CHECKOUT_WORKING_DIRECTORY}/${CHECKOUT_RELATIVE_PATH}")
# ensure the (possibly empty) directory exists
if(NOT EXISTS "${_DIR}")
if(NOT CHECKOUT_REPO_URL)
message(FATAL_ERROR "submodule directory does not exist")
endif()
endif()
# if this file exists --> project has been checked out if not exists --> not been
# checked out
set(_TEST_FILE "${_DIR}/${CHECKOUT_TEST_FILE}")
# assuming a .gitmodules file exists
set(_SUBMODULE "${PROJECT_SOURCE_DIR}/.gitmodules")
set(_TEST_FILE_EXISTS OFF)
if(EXISTS "${_TEST_FILE}" AND NOT IS_DIRECTORY "${_TEST_FILE}")
set(_TEST_FILE_EXISTS ON)
endif()
if(_TEST_FILE_EXISTS)
return()
endif()
find_package(Git REQUIRED)
set(_SUBMODULE_EXISTS OFF)
if(EXISTS "${_SUBMODULE}" AND NOT IS_DIRECTORY "${_SUBMODULE}")
set(_SUBMODULE_EXISTS ON)
endif()
set(_HAS_REPO_URL OFF)
if(NOT "${CHECKOUT_REPO_URL}" STREQUAL "")
set(_HAS_REPO_URL ON)
endif()
# if the module has not been checked out
if(NOT _TEST_FILE_EXISTS AND _SUBMODULE_EXISTS)
# perform the checkout
execute_process(
COMMAND ${GIT_EXECUTABLE} submodule update --init ${_RECURSE}
${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_RELATIVE_PATH}
WORKING_DIRECTORY ${CHECKOUT_WORKING_DIRECTORY}
RESULT_VARIABLE RET)
# check the return code
if(RET GREATER 0)
set(_CMD "${GIT_EXECUTABLE} submodule update --init ${_RECURSE}
${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_RELATIVE_PATH}")
message(STATUS "function(rocprofiler_checkout_git_submodule) failed.")
message(FATAL_ERROR "Command: \"${_CMD}\"")
else()
set(_TEST_FILE_EXISTS ON)
endif()
endif()
if(NOT _TEST_FILE_EXISTS AND _HAS_REPO_URL)
message(
STATUS "Checking out '${CHECKOUT_REPO_URL}' @ '${CHECKOUT_REPO_BRANCH}'...")
# remove the existing directory
if(EXISTS "${_DIR}")
execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${_DIR})
endif()
# perform the checkout
execute_process(
COMMAND
${GIT_EXECUTABLE} clone -b ${CHECKOUT_REPO_BRANCH}
${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_REPO_URL} ${CHECKOUT_RELATIVE_PATH}
WORKING_DIRECTORY ${CHECKOUT_WORKING_DIRECTORY}
RESULT_VARIABLE RET)
# perform the submodule update
if(CHECKOUT_RECURSIVE
AND EXISTS "${_DIR}"
AND IS_DIRECTORY "${_DIR}")
execute_process(
COMMAND ${GIT_EXECUTABLE} submodule update --init ${_RECURSE}
WORKING_DIRECTORY ${_DIR}
RESULT_VARIABLE RET)
endif()
# check the return code
if(RET GREATER 0)
set(_CMD
"${GIT_EXECUTABLE} clone -b ${CHECKOUT_REPO_BRANCH}
${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_REPO_URL} ${CHECKOUT_RELATIVE_PATH}"
)
message(STATUS "function(rocprofiler_checkout_git_submodule) failed.")
message(FATAL_ERROR "Command: \"${_CMD}\"")
else()
set(_TEST_FILE_EXISTS ON)
endif()
endif()
if(NOT EXISTS "${_TEST_FILE}" OR NOT _TEST_FILE_EXISTS)
message(
FATAL_ERROR
"Error checking out submodule: '${CHECKOUT_RELATIVE_PATH}' to '${_DIR}'")
endif()
endfunction()
# ----------------------------------------------------------------------------------------#
# try to find a package quietly
#
function(ROCPROFILER_TEST_FIND_PACKAGE PACKAGE_NAME OUTPUT_VAR)
cmake_parse_arguments(PACKAGE "" "" "UNSET" ${ARGN})
find_package(${PACKAGE_NAME} QUIET ${PACKAGE_UNPARSED_ARGUMENTS})
if(NOT ${PACKAGE_NAME}_FOUND)
set(${OUTPUT_VAR}
OFF
PARENT_SCOPE)
else()
set(${OUTPUT_VAR}
ON
PARENT_SCOPE)
endif()
foreach(_ARG ${PACKAGE_UNSET} FIND_PACKAGE_MESSAGE_DETAILS_${PACKAGE_NAME})
unset(${_ARG} CACHE)
endforeach()
endfunction()
# ----------------------------------------------------------------------------------------#
# macro to add an interface lib
#
function(ROCPROFILER_ADD_INTERFACE_LIBRARY _TARGET _DESCRIPT)
add_library(${_TARGET} INTERFACE)
add_library(${PROJECT_NAME}::${_TARGET} ALIAS ${_TARGET})
set(_ARGS "${ARGN}")
if(NOT "INTERNAL" IN_LIST _ARGS)
install(
TARGETS ${_TARGET}
DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT core
EXPORT ${PROJECT_NAME}-library-targets
OPTIONAL)
endif()
endfunction()
# -----------------------------------------------------------------------
# function add_feature(<NAME> <DOCSTRING>) Add a project feature, whose activation is
# specified by the existence of the variable <NAME>, to the list of enabled/disabled
# features, plus a docstring describing the feature
#
function(ROCPROFILER_ADD_FEATURE _var _description)
set(EXTRA_DESC "")
foreach(currentArg ${ARGN})
if(NOT "${currentArg}" STREQUAL "${_var}"
AND NOT "${currentArg}" STREQUAL "${_description}"
AND NOT "${currentArg}" STREQUAL "CMAKE_DEFINE"
AND NOT "${currentArg}" STREQUAL "DOC")
set(EXTRA_DESC "${EXTA_DESC}${currentArg}")
endif()
endforeach()
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_FEATURES ${_var})
set_property(GLOBAL PROPERTY ${_var}_DESCRIPTION "${_description}${EXTRA_DESC}")
if("CMAKE_DEFINE" IN_LIST ARGN)
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_DEFINES
"${_var} @${_var}@")
if(ROCPROFILER_BUILD_DOCS)
set_property(
GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_OPTIONS_DOC
"${_var}` | ${_description}${EXTRA_DESC} |")
endif()
elseif("DOC" IN_LIST ARGN AND ROCPROFILER_BUILD_DOCS)
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_OPTIONS_DOC
"${_var}` | ${_description}${EXTRA_DESC} |")
endif()
endfunction()
# ----------------------------------------------------------------------------------------#
# function add_option(<OPTION_NAME> <DOCSRING> <DEFAULT_SETTING> [NO_FEATURE]) Add an
# option and add as a feature if NO_FEATURE is not provided
#
function(ROCPROFILER_ADD_OPTION _NAME _MESSAGE _DEFAULT)
option(${_NAME} "${_MESSAGE}" ${_DEFAULT})
if("NO_FEATURE" IN_LIST ARGN)
mark_as_advanced(${_NAME})
else()
rocprofiler_add_feature(${_NAME} "${_MESSAGE}")
if(ROCPROFILER_BUILD_DOCS)
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_OPTIONS_DOC
"${_NAME}` | ${_MESSAGE} |")
endif()
endif()
if("ADVANCED" IN_LIST ARGN)
mark_as_advanced(${_NAME})
endif()
if("CMAKE_DEFINE" IN_LIST ARGN)
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_DEFINES ${_NAME})
endif()
endfunction()
# ----------------------------------------------------------------------------------------#
# function rocprofiler_add_cache_option(<OPTION_NAME> <DOCSRING> <TYPE> <DEFAULT_VALUE>
# [NO_FEATURE] [ADVANCED] [CMAKE_DEFINE])
#
function(ROCPROFILER_ADD_CACHE_OPTION _NAME _DEFAULT _TYPE _MESSAGE)
set(_FORCE)
if("FORCE" IN_LIST ARGN)
set(_FORCE FORCE)
endif()
set(${_NAME}
"${_DEFAULT}"
CACHE ${_TYPE} "${_MESSAGE}" ${_FORCE})
if("NO_FEATURE" IN_LIST ARGN)
mark_as_advanced(${_NAME})
else()
rocprofiler_add_feature(${_NAME} "${_MESSAGE}")
if(ROCPROFILER_BUILD_DOCS)
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_OPTIONS_DOC
"${_NAME}` | ${_MESSAGE} |")
endif()
endif()
if("ADVANCED" IN_LIST ARGN)
mark_as_advanced(${_NAME})
endif()
if("CMAKE_DEFINE" IN_LIST ARGN)
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_DEFINES ${_NAME})
endif()
endfunction()
# ----------------------------------------------------------------------------------------#
# function rocprofiler_report_feature_changes() :: print changes in features
#
function(ROCPROFILER_REPORT_FEATURE_CHANGES)
get_property(_features GLOBAL PROPERTY ${PROJECT_NAME}_FEATURES)
if(NOT "${_features}" STREQUAL "")
list(REMOVE_DUPLICATES _features)
list(SORT _features)
endif()
foreach(_feature ${_features})
if("${ARGN}" STREQUAL "")
rocprofiler_watch_for_change(${_feature})
elseif("${_feature}" IN_LIST ARGN)
rocprofiler_watch_for_change(${_feature})
endif()
endforeach()
endfunction()
# ----------------------------------------------------------------------------------------#
# function print_enabled_features() Print enabled features plus their docstrings.
#
function(ROCPROFILER_PRINT_ENABLED_FEATURES)
set(_basemsg "The following features are defined/enabled (+):")
set(_currentFeatureText "${_basemsg}")
get_property(_features GLOBAL PROPERTY ${PROJECT_NAME}_FEATURES)
if(NOT "${_features}" STREQUAL "")
list(REMOVE_DUPLICATES _features)
list(SORT _features)
endif()
foreach(_feature ${_features})
if(${_feature})
# add feature to text
set(_currentFeatureText "${_currentFeatureText}\n ${_feature}")
# get description
get_property(_desc GLOBAL PROPERTY ${_feature}_DESCRIPTION)
# print description, if not standard ON/OFF, print what is set to
if(_desc)
if(NOT "${${_feature}}" STREQUAL "ON" AND NOT "${${_feature}}" STREQUAL
"TRUE")
set(_currentFeatureText
"${_currentFeatureText}: ${_desc} -- [\"${${_feature}}\"]")
else()
string(REGEX REPLACE "^${PROJECT_NAME}_USE_" "" _feature_tmp
"${_feature}")
string(TOLOWER "${_feature_tmp}" _feature_tmp_l)
rocprofiler_capitalize("${_feature_tmp}" _feature_tmp_c)
foreach(_var _feature _feature_tmp _feature_tmp_l _feature_tmp_c)
set(_ver "${${${_var}}_VERSION}")
if(NOT "${_ver}" STREQUAL "")
set(_desc "${_desc} -- [found version ${_ver}]")
break()
endif()
unset(_ver)
endforeach()
set(_currentFeatureText "${_currentFeatureText}: ${_desc}")
endif()
set(_desc NOTFOUND)
endif()
endif()
endforeach()
if(NOT "${_currentFeatureText}" STREQUAL "${_basemsg}")
message(STATUS "${_currentFeatureText}\n")
endif()
endfunction()
# ----------------------------------------------------------------------------------------#
# function print_disabled_features() Print disabled features plus their docstrings.
#
function(ROCPROFILER_PRINT_DISABLED_FEATURES)
set(_basemsg "The following features are NOT defined/enabled (-):")
set(_currentFeatureText "${_basemsg}")
get_property(_features GLOBAL PROPERTY ${PROJECT_NAME}_FEATURES)
if(NOT "${_features}" STREQUAL "")
list(REMOVE_DUPLICATES _features)
list(SORT _features)
endif()
foreach(_feature ${_features})
if(NOT ${_feature})
set(_currentFeatureText "${_currentFeatureText}\n ${_feature}")
get_property(_desc GLOBAL PROPERTY ${_feature}_DESCRIPTION)
if(_desc)
set(_currentFeatureText "${_currentFeatureText}: ${_desc}")
set(_desc NOTFOUND)
endif(_desc)
endif()
endforeach(_feature)
if(NOT "${_currentFeatureText}" STREQUAL "${_basemsg}")
message(STATUS "${_currentFeatureText}\n")
endif()
endfunction()
# ----------------------------------------------------------------------------------------#
# function print_features() Print all features plus their docstrings.
#
function(ROCPROFILER_PRINT_FEATURES)
rocprofiler_report_feature_changes()
rocprofiler_print_enabled_features()
rocprofiler_print_disabled_features()
endfunction()
# ----------------------------------------------------------------------------------------#
# this function is provided to easily select which files use alternative compiler:
#
# GLOBAL --> all files TARGET --> all files in a target SOURCE --> specific
# source files DIRECTORY --> all files in directory PROJECT --> all files/targets in
# a project/subproject
#
function(rocprofiler_custom_compilation)
cmake_parse_arguments(COMP "GLOBAL;PROJECT" "COMPILER" "DIRECTORY;TARGET;SOURCE"
${ARGN})
# find rocprofiler-launch-compiler
find_program(
ROCPROFILER_COMPILE_LAUNCHER
NAMES rocprofiler-launch-compiler
HINTS ${PROJECT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}
PATHS ${PROJECT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}
PATH_SUFFIXES scripts bin)
if(NOT COMP_COMPILER)
message(
FATAL_ERROR "rocprofiler_custom_compilation not provided COMPILER argument")
endif()
if(NOT ROCPROFILER_COMPILE_LAUNCHER)
message(
FATAL_ERROR
"rocprofiler could not find 'rocprofiler-launch-compiler'. Please set '-DROCPROFILER_COMPILE_LAUNCHER=/path/to/launcher'"
)
endif()
if(COMP_GLOBAL)
# if global, don't bother setting others
set_property(
GLOBAL
PROPERTY
RULE_LAUNCH_COMPILE
"${ROCPROFILER_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}")
set_property(
GLOBAL
PROPERTY
RULE_LAUNCH_LINK
"${ROCPROFILER_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}")
else()
foreach(_TYPE PROJECT DIRECTORY TARGET SOURCE)
# make project/subproject scoping easy, e.g.
# rocprofiler_custom_compilation(PROJECT) after project(...)
if("${_TYPE}" STREQUAL "PROJECT" AND COMP_${_TYPE})
list(APPEND COMP_DIRECTORY ${PROJECT_SOURCE_DIR})
unset(COMP_${_TYPE})
endif()
# set the properties if defined
if(COMP_${_TYPE})
foreach(_VAL ${COMP_${_TYPE}})
set_property(
${_TYPE} ${_VAL}
PROPERTY
RULE_LAUNCH_COMPILE
"${ROCPROFILER_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}"
)
set_property(
${_TYPE} ${_VAL}
PROPERTY
RULE_LAUNCH_LINK
"${ROCPROFILER_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}"
)
endforeach()
endif()
endforeach()
endif()
endfunction()
function(ROCPROFILER_WATCH_FOR_CHANGE _var)
list(LENGTH ARGN _NUM_EXTRA_ARGS)
if(_NUM_EXTRA_ARGS EQUAL 1)
set(_VAR ${ARGN})
else()
set(_VAR)
endif()
macro(update_var _VAL)
if(_VAR)
set(${_VAR}
${_VAL}
PARENT_SCOPE)
endif()
endmacro()
update_var(OFF)
set(_rocprofiler_watch_var_name ROCPROFILER_WATCH_VALUE_${_var})
if(DEFINED ${_rocprofiler_watch_var_name})
if("${${_var}}" STREQUAL "${${_rocprofiler_watch_var_name}}")
return()
else()
rocprofiler_message(
STATUS
"${_var} changed :: ${${_rocprofiler_watch_var_name}} --> ${${_var}}")
update_var(ON)
endif()
else()
if(NOT "${${_var}}" STREQUAL "")
rocprofiler_message(STATUS "${_var} :: ${${_var}}")
update_var(ON)
endif()
endif()
# store the value for the next run
set(${_rocprofiler_watch_var_name}
"${${_var}}"
CACHE INTERNAL "Last value of ${_var}" FORCE)
endfunction()
function(ROCPROFILER_DIRECTORY)
cmake_parse_arguments(F "MKDIR;FAIL;FORCE" "PREFIX;OUTPUT_VARIABLE;WORKING_DIRECTORY"
"PATHS" ${ARGN})
if(F_PREFIX AND NOT IS_ABSOLUTE "${F_PREFIX}")
if(F_WORKING_DIRECTORY)
rocprofiler_message(
STATUS
"PREFIX was specified as a relative path, using working directory + prefix :: '${F_WORKING_DIRECTORY}/${F_PREFIX}'..."
)
set(F_PREFIX ${F_WORKING_DIRECTORY}/${F_PREFIX})
else()
rocprofiler_message(
FATAL_ERROR
"PREFIX was specified but it is not an absolute path: ${F_PREFIX}")
endif()
endif()
if(NOT F_WORKING_DIRECTORY)
set(F_WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
endif()
foreach(_PATH ${F_PREFIX} ${F_PATHS})
if(F_PREFIX AND NOT "${_PATH}" STREQUAL "${F_PREFIX}")
# if path is relative, set to prefix + path
if(NOT IS_ABSOLUTE "${_PATH}")
set(_PATH ${F_PREFIX}/${_PATH})
endif()
list(APPEND _OUTPUT_VAR ${_PATH})
elseif(NOT F_PREFIX)
list(APPEND _OUTPUT_VAR ${_PATH})
endif()
if(NOT EXISTS "${_PATH}" AND F_FAIL)
rocprofiler_message(FATAL_ERROR "Directory '${_PATH}' does not exist")
elseif(NOT IS_DIRECTORY "${_PATH}" AND F_FAIL)
rocprofiler_message(FATAL_ERROR "'${_PATH}' exists but is not a directory")
elseif(NOT EXISTS "${_PATH}" AND F_MKDIR)
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${_PATH}
WORKING_DIRECTORY ${F_WORKING_DIRECTORY})
elseif(
EXISTS "${_PATH}"
AND NOT IS_DIRECTORY "${_PATH}"
AND F_MKDIR)
if(F_FORCE)
execute_process(COMMAND ${CMAKE_COMMAND} -E rm ${_PATH}
WORKING_DIRECTORY ${F_WORKING_DIRECTORY})
endif()
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${_PATH}
WORKING_DIRECTORY ${F_WORKING_DIRECTORY})
endif()
endforeach()
if(F_OUTPUT_VARIABLE)
set(${F_OUTPUT_VARIABLE}
"${_OUTPUT_VAR}"
PARENT_SCOPE)
endif()
endfunction()
function(ROCPROFILER_CHECK_PYTHON_DIRS_AND_VERSIONS)
cmake_parse_arguments(F "FAIL;UNSET" "RESULT_VARIABLE;OUTPUT_VARIABLE" "" ${ARGN})
list(LENGTH ROCPROFILER_PYTHON_VERSIONS _NUM_PYTHON_VERSIONS)
list(LENGTH ROCPROFILER_PYTHON_ROOT_DIRS _NUM_PYTHON_ROOT_DIRS)
if(NOT _NUM_PYTHON_VERSIONS EQUAL _NUM_PYTHON_ROOT_DIRS)
set(_RET 1)
else()
set(_RET 0)
if(F_OUTPUT_VARIABLE)
set(${F_OUTPUT_VARIABLE}
${_NUM_PYTHON_VERSIONS}
PARENT_SCOPE)
endif()
endif()
if(F_RESULT_VARIABLE)
set(${F_RESULT_VARIABLE}
${_RET}
PARENT_SCOPE)
endif()
if(NOT ${_RET} EQUAL 0)
if(F_FAIL)
rocprofiler_message(
WARNING
"Error! Number of python versions : ${_NUM_PYTHON_VERSIONS}. VERSIONS :: ${ROCPROFILER_PYTHON_VERSIONS}"
)
rocprofiler_message(
WARNING
"Error! Number of python root directories : ${_NUM_PYTHON_ROOT_DIRS}. ROOT DIRS :: ${ROCPROFILER_PYTHON_ROOT_DIRS}"
)
rocprofiler_message(
FATAL_ERROR
"Error! Number of python versions != number of python root directories")
elseif(F_UNSET)
unset(ROCPROFILER_PYTHON_VERSIONS CACHE)
unset(ROCPROFILER_PYTHON_ROOT_DIRS CACHE)
if(F_OUTPUT_VARIABLE)
set(${F_OUTPUT_VARIABLE} 0)
endif()
endif()
endif()
endfunction()
# ----------------------------------------------------------------------------
# Console scripts
#
function(ROCPROFILER_PYTHON_CONSOLE_SCRIPT SCRIPT_NAME SCRIPT_SUBMODULE)
set(options)
set(args VERSION ROOT_DIR)
set(kwargs)
cmake_parse_arguments(ARG "${options}" "${args}" "${kwargs}" ${ARGN})
if(ARG_VERSION AND ARG_ROOT_DIR)
set(Python3_ROOT_DIR "${ARG_ROOT_DIR}")
find_package(Python3 ${ARG_VERSION} EXACT QUIET MODULE COMPONENTS Interpreter)
set(PYTHON_EXECUTABLE "${Python3_EXECUTABLE}")
configure_file(${PROJECT_SOURCE_DIR}/cmake/Templates/console-script.in
${PROJECT_BINARY_DIR}/bin/${SCRIPT_NAME}-${ARG_VERSION} @ONLY)
if(CMAKE_INSTALL_PYTHONDIR)
install(
PROGRAMS ${PROJECT_BINARY_DIR}/bin/${SCRIPT_NAME}-${ARG_VERSION}
DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT python
OPTIONAL)
endif()
if(ROCPROFILER_BUILD_TESTING OR ROCPROFILER_BUILD_PYTHON)
add_test(
NAME ${SCRIPT_NAME}-console-script-test-${ARG_VERSION}
COMMAND ${PROJECT_BINARY_DIR}/bin/${SCRIPT_NAME}-${ARG_VERSION} --help
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(
${SCRIPT_NAME}-console-script-test-${ARG_VERSION}
PROPERTIES LABELS "python;python-${ARG_VERSION};console-script")
add_test(
NAME ${SCRIPT_NAME}-generic-console-script-test-${ARG_VERSION}
COMMAND ${PROJECT_BINARY_DIR}/bin/${SCRIPT_NAME} --help
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(
${SCRIPT_NAME}-generic-console-script-test-${ARG_VERSION}
PROPERTIES ENVIRONMENT "PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}" LABELS
"python;python-${ARG_VERSION};console-script")
endif()
else()
set(PYTHON_EXECUTABLE "python3")
configure_file(${PROJECT_SOURCE_DIR}/cmake/Templates/console-script.in
${PROJECT_BINARY_DIR}/bin/${SCRIPT_NAME} @ONLY)
if(CMAKE_INSTALL_PYTHONDIR)
install(
PROGRAMS ${PROJECT_BINARY_DIR}/bin/${SCRIPT_NAME}
DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT python
OPTIONAL)
endif()
endif()
endfunction()
function(ROCPROFILER_FIND_STATIC_LIBRARY)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
find_library(${ARGN})
endfunction()
function(ROCPROFILER_FIND_SHARED_LIBRARY)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX})
find_library(${ARGN})
endfunction()
function(ROCPROFILER_BUILDTREE_TPL _TPL_TARGET _NEW_NAME _BUILD_TREE_DIR)
get_target_property(_TPL_VERSION ${_TPL_TARGET} VERSION)
get_target_property(_TPL_SOVERSION ${_TPL_TARGET} SOVERSION)
get_target_property(_TPL_NAME ${_TPL_TARGET} OUTPUT_NAME)
set(_TPL_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX})
set(_TPL_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
foreach(_TAIL ${_TPL_SUFFIX} ${_TPL_SUFFIX}.${_TPL_SOVERSION}
${_TPL_SUFFIX}.${_TPL_VERSION})
set(_INP ${_TPL_PREFIX}${_TPL_NAME}${_TAIL})
set(_OUT ${_TPL_PREFIX}${_NEW_NAME}${_TAIL})
endforeach()
string(REPLACE " " "-" _TAIL "${ARGN}")
# build tree symbolic links
add_custom_target(
${_NEW_NAME}-build-tree-library${_TAIL} ALL
${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE:${_TPL_TARGET}>
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION}
COMMAND
${CMAKE_COMMAND} -E create_symlink
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION}
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
COMMAND
${CMAKE_COMMAND} -E create_symlink
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}
WORKING_DIRECTORY ${_BUILD_TREE_DIR}
DEPENDS ${_TPL_TARGET}
COMMENT "Creating ${_NEW_NAME} from ${_TPL_TARGET}...")
endfunction()
function(ROCPROFILER_INSTALL_TPL _TPL_TARGET _NEW_NAME _BUILD_TREE_DIR _COMPONENT)
get_target_property(_TPL_VERSION ${_TPL_TARGET} VERSION)
get_target_property(_TPL_SOVERSION ${_TPL_TARGET} SOVERSION)
get_target_property(_TPL_NAME ${_TPL_TARGET} OUTPUT_NAME)
set(_TPL_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX})
set(_TPL_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
foreach(_TAIL ${_TPL_SUFFIX} ${_TPL_SUFFIX}.${_TPL_SOVERSION}
${_TPL_SUFFIX}.${_TPL_VERSION})
set(_INP ${_TPL_PREFIX}${_TPL_NAME}${_TAIL})
set(_OUT ${_TPL_PREFIX}${_NEW_NAME}${_TAIL})
endforeach()
# build tree symbolic links
rocprofiler_buildtree_tpl("${_TPL_TARGET}" "${_NEW_NAME}" "${_BUILD_TREE_DIR}"
${ARGN})
install(
FILES $<TARGET_FILE:${_TPL_TARGET}>
DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT ${_COMPONENT}
RENAME ${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION})
install(
FILES
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}
DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT ${_COMPONENT})
endfunction()
function(COMPUTE_POW2_CEIL _OUTPUT _VALUE)
find_package(Python3 COMPONENTS Interpreter)
if(Python3_FOUND)
execute_process(
COMMAND
${Python3_EXECUTABLE} -c
"VALUE = ${_VALUE}; ispow2 = lambda x: x if (x and (not(x & (x - 1)))) else None; v = list(filter(ispow2, [x for x in range(VALUE, VALUE**2)])); print(v[0])"
RESULT_VARIABLE _POW2_RET
OUTPUT_VARIABLE _POW2_OUT
ERROR_VARIABLE _POW2_ERR
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(_POW2_RET EQUAL 0)
set(${_OUTPUT}
${_POW2_OUT}
PARENT_SCOPE)
else()
set(${_OUTPUT}
"-1"
PARENT_SCOPE)
endif()
else()
set(${_OUTPUT}
"-1"
PARENT_SCOPE)
endif()
endfunction()
cmake_policy(POP)
поставляемый
+29
Просмотреть файл
@@ -0,0 +1,29 @@
#
#
# External dependencies
#
#
if(ROCPROFILER_BUILD_TESTS)
set(INSTALL_GTEST
OFF
CACHE BOOL "")
set(BUILD_GMOCK
OFF
CACHE BOOL "")
add_subdirectory(googletest EXCLUDE_FROM_ALL)
if(NOT TARGET GTest::gtest)
message(FATAL_ERROR "missing GTest::gtest")
endif()
target_link_libraries(rocprofiler-googletest INTERFACE GTest::gtest)
target_include_directories(
rocprofiler-googletest SYSTEM
INTERFACE ${CMAKE_CURRENT_LSIT_DIR}/googletest/googletest/include)
mark_as_advanced(INSTALL_GTEST)
mark_as_advanced(BUILD_GMOCK)
mark_as_advanced(GTEST_HAS_ABSL)
endif()
поставляемый Подмодуль
+1
Submodule external/googletest added at 46db91ef6f
+25
Просмотреть файл
@@ -0,0 +1,25 @@
[tool.black]
line-length = 90
target-version = ['py36', 'py37', 'py38', 'py39', 'py310']
include = '\.py$'
exclude = '''
(
/(
\.eggs
| \.git
| \.github
| \.tox
| \.venv
| \.misc
| \.vscode
| \.cache
| \.pytest_cache
| dist
| external
| build
| build-release
| build-rocprofiler
)/
)
'''
+10
Просмотреть файл
@@ -0,0 +1,10 @@
barectf
bcrypt
CppHeaderParser
lxml
matplotlib
pandas
protobuf
pycparser
pyparsing
websockets
+1
Просмотреть файл
@@ -0,0 +1 @@
+6
Просмотреть файл
@@ -0,0 +1,6 @@
#
#
#
add_subdirectory(include)
add_subdirectory(lib)
add_subdirectory(bin)
+1
Просмотреть файл
@@ -0,0 +1 @@
+1
Просмотреть файл
@@ -0,0 +1 @@
+4
Просмотреть файл
@@ -0,0 +1,4 @@
#
#
#
add_subdirectory(rocprofiler)
+8
Просмотреть файл
@@ -0,0 +1,8 @@
#
#
# Installation of public headers
#
#
set(ROCPROFILER_INCLUDE_FILES config.h rocprofiler.h rocprofiler_plugin.h)
install(FILES ${ROCPROFILER_INCLUDE_FILES}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/rocprofiler)
+189
Просмотреть файл
@@ -0,0 +1,189 @@
#pragma once
#include <hip/hip_runtime.h>
#include <rocprofiler/rocprofiler.h>
#ifdef __cplusplus
extern "C" {
#endif
#define ROCPROFILER_API_VERSION_ID 1
#define ROCPROFILER_DOMAIN_OPS_MAX 512
#define ROCPROFILER_DOMAIN_OPS_RESERVED ((ROCPROFILER_DOMAIN_OPS_MAX * ACTIVITY_DOMAIN_NUMBER / 8))
typedef uint64_t (*rocprofiler_external_cid_cb_t)(rocprofiler_tracer_activity_domain_t,
uint32_t,
uint64_t);
typedef int (*rocprofiler_filter_name_t)(const char*);
typedef int (*rocprofiler_filter_op_id_t)(uint32_t);
typedef int (*rocprofiler_filter_range_t)(uint32_t, uint32_t);
typedef int (*rocprofiler_filter_dispatch_id_t)(uint64_t);
/// permits tools opportunity to modify the correlation id based on the domain, op, and
/// the rocprofiler generated correlation id
struct rocprofiler_correlation_config
{
rocprofiler_external_cid_cb_t external_id_callback;
};
/// how the tools specify the tracing domain and (optionally) which operations in the
/// domain they want to trace
struct rocprofiler_domain_config
{
rocprofiler_sync_callback_t callback;
char reserved0[sizeof(uint64_t)];
char reserved1[ROCPROFILER_DOMAIN_OPS_RESERVED];
};
/// for buffered callbacks, the tool provides a callback to create a buffer and the size
struct rocprofiler_buffer_config
{
rocprofiler_buffer_callback_t callback;
uint64_t buffer_size;
// void* reserved0;
char reserved1[sizeof(uint64_t)];
};
/// filters are available to make quick decisions about whether rocprofiler should
/// assemble the data necessary for a callback. This is more for convenience and
/// performance -- anything decisions here could be made in the callback but rocprofiler
/// has to first assemble all the infomation on the callback before it (eventually) gets
/// discarded because the tool has decided it (after configuration), that it no longer
/// wants info meeting certain requirements
struct rocprofiler_filter_config
{
// filter callbacks
rocprofiler_filter_name_t name;
rocprofiler_filter_op_id_t hip_function_id;
rocprofiler_filter_op_id_t hsa_function_id;
rocprofiler_filter_range_t range;
rocprofiler_filter_dispatch_id_t dispatch_id;
// reserved padding
char padding[24 * sizeof(void*)];
};
/// this is the "single source of truth" for the capabilities of rocprofiler.
/// you can one configuration that activates all the capabilities you want
/// and holistically start/stop the sum of those features. Alternatively,
/// you can have multiple configurations in order to activate certain features
/// modularly.
///
/// The general workflow is:
///
/// 1. invoke rocprofiler_allocate_config(...)
/// - rocprofiler allocates any space internally needed for the config
/// - rocprofiler sets a few initial values:
/// - "size" to the size of the config structure used internally
/// - "api_version" to the version id of the API in the rocprofiler library that
/// is being used.
/// - these two values can be used by the tool to identify any potential
/// incompatibilities that the tool might want to know about
/// - rocprofiler checks whether it is too late to configure the tool, e.g.
/// something went wrong and rocprofiler was not able to set itself up as
/// the intercepter
/// 2. tool sets up the configuration struct and sets the "size" variable to the size of
/// their configuration struct and sets the "compat_version" field to the
/// ROCPROFILER_API_VERSION_ID defined by the rocprofiler headers when the tool was
/// built
/// - in other words, the user can communicate to rocprofiler, don't read
/// past this distance in my configuration struct and I built against X version
/// so assume the default behavior and capabilties of version X.
/// 3. tool passes this struct to rocprofiler_validate_config(...)
/// - this step checks the config in isolation and will communicate any potential
/// warnings/issues with that configuration, e.g. rocprofiler_X_config is needed,
/// to HW counters XYZ are not available, etc. The tool then has an opportunity
/// to address these issues however they see fit.
/// 4. tool passes this struct to rocprofiler_start_config(...)
/// - internally, we make a call to rocprofiler_validate_config(...) and if any
/// issues still exist with the config in isolation, rocprofiler tells the app
/// to abort -- mechanisms were provided to prevent aborting prior to this call,
/// aborting the app at this point is to guard against rocprofiler "silently"
/// not working because error codes were ignored
/// - rocprofiler then checks whether this config can actually be activated
/// alongside any other active configuration, e.g. this config wants 4 HW counters
/// and another wants 4 HW counters but we can only activate 6 out of 8 of
/// them in this run. Any issues here will not abort execution but, instead,
/// the features of this configuration will not happen (i.e. config won't be
/// activated) and the issues will be communicated with error codes -- giving
/// the tool the opportunity to address the conflicts (i.e. only request tracing
/// and no HW counters) before attempting to activate the modified config.
/// - once rocprofiler determines all features of a config can be activated, it
/// makes an internal copy of the config and returns an identifier for that
/// configuration. The tool is then free to delete the config and any modification
/// to the config will NOT be reflected in the behavior of rocprofiler.
///
///
struct rocprofiler_config
{
// size is used to ensure that we never read past the end of the version
size_t size; // = sizeof(rocprofiler_config)
uint32_t compat_version; // set by user
uint32_t api_version; // set by rocprofiler
uint64_t reserved0; // internal field
void* user_data; // data passed to callbacks
struct rocprofiler_correlation_config* correlation_id; // = &my_cid_config (optional)
struct rocprofiler_buffer_config* buffer; // = &my_buffer_config (required)
struct rocprofiler_domain_config* domain; // = &my_domain_config (required)
struct rocprofiler_filter_config* filter; // = &my_filter_config (optional)
};
/// \brief returns a properly initialized config struct and allocates any data structures
/// necessary for the config to be used
///
/// \param [out] cfg may adjust config or assign values within structs.
rocprofiler_status_t
rocprofiler_allocate_config(struct rocprofiler_config* cfg);
/// \brief rocprofiler validates config, checks for conflicts, etc. Ensures that
/// the configuration is valid *in isolation*, e.g. it may check that the user
/// set the compat_version field and that required config fields, such as buffer
/// are set. This function will be called before \ref rocprofiler_start_config
/// but is provided to help the user validate one or more configs without starting
/// them
///
/// \param [in] cfg configuration to validate
rocprofiler_status_t
rocprofiler_validate_config(const struct rocprofiler_config* cfg);
/// \brief rocprofiler activates configuration and provides a session identifier
/// \param [in] cfg may adjust config or assign values within structs. If error
/// occurs, could nullptr valid sub-configs and leave the pointers to
/// invalid configs
/// \param [out] id the session identifier for this config.
rocprofiler_status_t
rocprofiler_start_config(struct rocprofiler_config*, rocprofiler_session_id_t* id);
/// \brief disable the configuration.
rocprofiler_status_t rocprofiler_stop_config(rocprofiler_session_id_t);
///
///
/// the following 4 functions may be changed to permit removing domain/ops and/or
/// identifying domains and operations via strings
///
///
rocprofiler_status_t
rocprofiler_domain_set_domain(struct rocprofiler_domain_config*,
rocprofiler_tracer_activity_domain_t);
rocprofiler_status_t
rocprofiler_domain_add_domains(struct rocprofiler_domain_config*,
rocprofiler_tracer_activity_domain_t*,
size_t);
rocprofiler_status_t
rocprofiler_domain_add_op(struct rocprofiler_domain_config*,
rocprofiler_tracer_activity_domain_t,
uint32_t);
rocprofiler_status_t
rocprofiler_domain_add_ops(struct rocprofiler_domain_config*,
rocprofiler_tracer_activity_domain_t,
uint32_t*,
size_t);
#ifdef __cplusplus
}
#endif
Разница между файлами не показана из-за своего большого размера Загрузить разницу
+142
Просмотреть файл
@@ -0,0 +1,142 @@
/* Copyright (c) 2022 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. */
/** \section rocprofiler_plugin_api ROCProfiler Plugin API
*
* The ROCProfiler Plugin API is used by the ROCProfiler Tool to output all
* profiling information. Different implementations of the ROCProfiler Plugin
* API can be developed that output the data in different formats. The
* ROCProfiler Tool can be configured to load a specific library that supports
* the user desired format.
*
* The API is not thread safe. It is the responsibility of the ROCProfiler Tool
* to ensure the operations are synchronized and not called concurrently. There
* is no requirement for the ROCProfiler Tool to report trace data in any
* specific order. If the format supported by plugin requires specific
* ordering, it is the responsibility of the plugin implementation to perform
* any necessary sorting.
*/
/**
* \file
* ROCProfiler Tool Plugin API interface.
*/
#ifndef ROCPROFILER_PLUGIN_H_
#define ROCPROFILER_PLUGIN_H_
#include <stdint.h>
#include "rocprofiler.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/** \defgroup rocprofiler_plugins ROCProfiler Plugin API Specification
* @{
*/
/** \defgroup initialization_group Initialization and Finalization
* \ingroup rocprofiler_plugins
*
* The ROCProfiler Plugin API must be initialized before using any of the
* operations to report trace data, and finalized after the last trace data has
* been reported.
*
* @{
*/
/**
* Initialize plugin.
* Must be called before any other operation.
*
* @param[in] rocprofiler_major_version The major version of the ROCProfiler API
* being used by the ROCProfiler Tool. An error is reported if this does not
* match the major version of the ROCProfiler API used to build the plugin
* library. This ensures compatibility of the trace data format.
* @param[in] rocprofiler_minor_version The minor version of the ROCProfiler API
* being used by the ROCProfiler Tool. An error is reported if the
* \p rocprofiler_major_version matches and this is greater than the minor
* version of the ROCProfiler API used to build the plugin library. This ensures
* compatibility of the trace data format.
* @param[in] data Pointer to the data passed to the ROCProfiler Plugin by the tool
* @return Returns 0 on success and -1 on error.
*/
ROCPROFILER_EXPORT int
rocprofiler_plugin_initialize(uint32_t rocprofiler_major_version,
uint32_t rocprofiler_minor_version,
void* data);
/**
* Finalize plugin.
* This must be called after ::rocprofiler_plugin_initialize and after all
* profiling data has been reported by
* ::rocprofiler_plugin_write_kernel_records
*/
ROCPROFILER_EXPORT void
rocprofiler_plugin_finalize();
/** @} */
/** \defgroup profiling_record_write_functions Profiling data reporting
* \ingroup rocprofiler_plugins
* Operations to output profiling data.
* @{
*/
// TODO(aelwazir): Recheck wording of the description
/**
* Report Buffer Records.
*
* @param[in] begin Pointer to the first record.
* @param[in] end Pointer to one past the last record.
* @param[in] session_id Session ID
* @param[in] buffer_id Buffer ID
* @return Returns 0 on success and -1 on error.
*/
ROCPROFILER_EXPORT int
rocprofiler_plugin_write_buffer_records(const rocprofiler_record_header_t* begin,
const rocprofiler_record_header_t* end,
rocprofiler_session_id_t session_id,
rocprofiler_buffer_id_t buffer_id);
/**
* Report Synchronous Record.
*
* @param[in] record Synchronous Tracer record.
* @param[in] data : api_data
* @param[in] tracer_data :Tracer record extra data such as function name and kernel name
* @return Returns 0 on success and -1 on error.
*/
ROCPROFILER_EXPORT int
rocprofiler_plugin_write_record(rocprofiler_record_tracer_t record);
/** @} */
/** @} */
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* ROCPROFILER_PLUGIN_H_ */
+10
Просмотреть файл
@@ -0,0 +1,10 @@
#
#
#
add_subdirectory(common)
add_subdirectory(rocprofiler)
add_subdirectory(plugins)
if(ROCPROFILER_BUILD_TESTS)
add_subdirectory(tests)
endif()
+26
Просмотреть файл
@@ -0,0 +1,26 @@
set(common_sources ${CMAKE_CURRENT_LIST_DIR}/config.cpp
${CMAKE_CURRENT_LIST_DIR}/helper.cpp)
set(common_headers
${CMAKE_CURRENT_LIST_DIR}/config.hpp ${CMAKE_CURRENT_LIST_DIR}/defines.hpp
${CMAKE_CURRENT_LIST_DIR}/environment.hpp ${CMAKE_CURRENT_LIST_DIR}/join.hpp
${CMAKE_CURRENT_LIST_DIR}/log.hpp ${CMAKE_CURRENT_LIST_DIR}/helper.hpp)
add_library(rocprofiler-common-library STATIC)
add_library(rocprofiler::rocprofiler-common-library ALIAS rocprofiler-common-library)
add_subdirectory(container)
target_sources(rocprofiler-common-library PRIVATE ${common_sources} ${common_headers})
target_include_directories(rocprofiler-common-library
PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/source>)
target_link_libraries(
rocprofiler-common-library
PUBLIC rocprofiler::rocprofiler-amd-comgr
$<BUILD_INTERFACE:rocprofiler::rocprofiler-build-flags>
$<BUILD_INTERFACE:rocprofiler::rocprofiler-memcheck>
$<BUILD_INTERFACE:rocprofiler::rocprofiler-stdcxxfs>
$<BUILD_INTERFACE:rocprofiler::rocprofiler-dl>)
set_target_properties(rocprofiler-common-library PROPERTIES OUTPUT_NAME
rocprofiler-common)
+433
Просмотреть файл
@@ -0,0 +1,433 @@
// 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/config.hpp"
#include "lib/common/environment.hpp"
#include "lib/common/join.hpp"
#include "lib/common/log.hpp"
#include "lib/common/helper.hpp"
#include <unistd.h>
#include <cstring>
#include <string>
#include <vector>
#include <ctime>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <regex>
#include <filesystem>
namespace rocprofiler
{
namespace common
{
namespace
{
std::time_t* launch_time = new std::time_t{std::time(nullptr)};
std::vector<std::string>
read_command_line(pid_t _pid)
{
auto _cmdline = std::vector<std::string>{};
auto fcmdline = std::stringstream{};
fcmdline << "/proc/" << _pid << "/cmdline";
auto ifs = std::ifstream{fcmdline.str().c_str()};
if(ifs)
{
char cstr;
std::string sarg;
while(!ifs.eof())
{
ifs >> cstr;
if(!ifs.eof())
{
if(cstr != '\0')
{
sarg += cstr;
}
else
{
_cmdline.push_back(sarg);
sarg = "";
}
}
}
ifs.close();
}
return _cmdline;
}
std::string
get_local_datetime(const char* dt_format, std::time_t* dt_curr)
{
char mbstr[512];
if(!dt_curr) dt_curr = launch_time;
if(std::strftime(mbstr, sizeof(mbstr), dt_format, std::localtime(dt_curr)) != 0)
return std::string{mbstr};
return std::string{};
}
inline bool
not_is_space(int ch)
{
return std::isspace(ch) == 0;
}
inline std::string
ltrim(std::string s, bool (*f)(int) = not_is_space)
{
s.erase(s.begin(), std::find_if(s.begin(), s.end(), f));
return s;
}
inline std::string
rtrim(std::string s, bool (*f)(int) = not_is_space)
{
s.erase(std::find_if(s.rbegin(), s.rend(), f).base(), s.end());
return s;
}
inline std::string
trim(std::string s, bool (*f)(int) = not_is_space)
{
ltrim(s, f);
rtrim(s, f);
return s;
}
inline std::vector<pid_t>
get_siblings(pid_t _id = getppid())
{
auto _data = std::vector<pid_t>{};
std::ifstream _ifs{"/proc/" + std::to_string(_id) + "/task/" + std::to_string(_id) +
"/children"};
while(_ifs)
{
pid_t _n = 0;
_ifs >> _n;
if(!_ifs || _n <= 0) break;
_data.emplace_back(_n);
}
return _data;
}
inline auto
get_num_siblings(pid_t _id = getppid())
{
return get_siblings(_id).size();
}
} // namespace
int
get_mpi_size()
{
static int _v = get_env<int>("OMPI_COMM_WORLD_SIZE",
get_env<int>("MV2_COMM_WORLD_SIZE", get_env<int>("MPI_SIZE", 0)));
return _v;
}
int
get_mpi_rank()
{
static int _v = get_env<int>("OMPI_COMM_WORLD_RANK",
get_env<int>("MV2_COMM_WORLD_RANK", get_env<int>("MPI_RANK", -1)));
return _v;
}
std::vector<output_key>
output_keys(std::string _tag)
{
using strpair_t = std::pair<std::string, std::string>;
auto _cmdline = read_command_line(getpid());
if(_tag.empty() && !_cmdline.empty()) _tag = ::basename(_cmdline.front().c_str());
std::string _argv_string = {}; // entire argv cmd
std::string _args_string = {}; // cmdline args
std::string _argt_string = _tag; // prefix + cmdline args
const std::string& _tag0_string = _tag; // only the basic prefix
auto _options = std::vector<output_key>{};
auto _replace = [](auto& _v, const strpair_t& pitr) {
auto pos = std::string::npos;
while((pos = _v.find(pitr.first)) != std::string::npos)
_v.replace(pos, pitr.first.length(), pitr.second);
};
if(_cmdline.size() > 1 && _cmdline.at(1) == "--") _cmdline.erase(_cmdline.begin() + 1);
for(auto& itr : _cmdline)
{
itr = trim(itr);
_replace(itr, {"/", "_"});
while(!itr.empty() && itr.at(0) == '.')
itr = itr.substr(1);
while(!itr.empty() && itr.at(0) == '_')
itr = itr.substr(1);
}
if(!_cmdline.empty())
{
for(size_t i = 0; i < _cmdline.size(); ++i)
{
const auto _l = std::string{(i == 0) ? "" : "_"};
auto _v = _cmdline.at(i);
_argv_string += _l + _v;
if(i > 0)
{
_argt_string += (i > 1) ? (_l + _v) : _v;
_args_string += (i > 1) ? (_l + _v) : _v;
}
}
}
auto* _launch_time = launch_time;
auto _time_format = get_env<std::string>("ROCP_TIME_FORMAT", "%F_%H.%M");
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 _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);
auto _launch_string = get_local_datetime(_time_format.c_str(), _launch_time);
auto _uniq_id = _proc_id;
if(get_env<int32_t>("SLURM_PROCID", -1) >= 0)
{
_uniq_id = _slurm_proc_id;
}
else if(_mpi_size > 0 || _mpi_rank >= 0)
{
_uniq_id = _dmp_rank;
}
for(auto&& itr : std::initializer_list<output_key>{
{"%argv%", _argv_string, "Entire command-line condensed into a single string"},
{"%argt%",
_argt_string,
"Similar to `%argv%` except basename of first command line argument"},
{"%args%", _args_string, "All command line arguments condensed into a single string"},
{"%tag%", _tag0_string, "Basename of first command line argument"}})
{
_options.emplace_back(itr);
}
if(!_cmdline.empty())
{
for(size_t i = 0; i < _cmdline.size(); ++i)
{
auto _v = _cmdline.at(i);
_options.emplace_back(join("", "%arg", i, "%"), _v, join("", "Argument #", i));
}
}
for(auto&& itr : std::initializer_list<output_key>{
{"%pid%", _proc_id, "Process identifier"},
{"%ppid%", _parent_id, "Parent process identifier"},
{"%pgid%", _pgroup_id, "Process group identifier"},
{"%psid%", _session_id, "Process session identifier"},
{"%psize%", _proc_size, "Number of sibling process"},
{"%job%", _slurm_job_id, "SLURM_JOB_ID env variable"},
{"%rank%", _slurm_proc_id, "MPI/UPC++ rank"},
{"%size%", _dmp_size, "MPI/UPC++ size"},
{"%nid%", _uniq_id, "%rank% if possible, otherwise %pid%"},
{"%launch_time%", _launch_string, "Data and/or time of run according to time format"},
})
{
_options.emplace_back(itr);
}
for(auto&& itr : std::initializer_list<output_key>{
{"%p", _proc_id, "Shorthand for %pid%"},
{"%j", _slurm_job_id, "Shorthand for %job%"},
{"%r", _slurm_proc_id, "Shorthand for %rank%"},
{"%s", _dmp_size, "Shorthand for %size"},
})
{
_options.emplace_back(itr);
}
return _options;
}
std::string
format(std::string _fpath, const std::string& _tag)
{
if(_fpath.find('%') == std::string::npos && _fpath.find('$') == std::string::npos)
return _fpath;
auto _replace = [](auto& _v, const output_key& pitr) {
auto pos = std::string::npos;
while((pos = _v.find(pitr.key)) != std::string::npos)
_v.replace(pos, pitr.key.length(), pitr.value);
};
for(auto&& itr : output_keys(_tag))
_replace(_fpath, itr);
// environment and configuration variables
try
{
for(const auto& _expr : {std::string{"(.*)%(env|ENV)\\{([A-Z0-9_]+)\\}%(.*)"},
std::string{"(.*)\\$(env|ENV)\\{([A-Z0-9_]+)\\}(.*)"}})
{
std::regex _re{_expr};
std::string _cbeg = (_expr.find("(.*)%") == 0) ? "%" : "$";
std::string _cend = (_expr.find("(.*)%") == 0) ? "}%" : "}";
bool _is_env = (_expr.find("(env|ENV)") != std::string::npos);
_cbeg += (_is_env) ? "env{" : "cfg{";
while(std::regex_search(_fpath, _re))
{
auto _var = std::regex_replace(_fpath, _re, "$3");
std::string _val = {};
if(_is_env)
{
_val = get_env<std::string>(_var, "");
}
auto _beg = std::regex_replace(_fpath, _re, "$1");
auto _end = std::regex_replace(_fpath, _re, "$4");
_fpath = join("", _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());
}
// remove %arg<N>% where N >= argc
try
{
std::regex _re{"(.*)%(arg[0-9]+)%([-/_]*)(.*)"};
while(std::regex_search(_fpath, _re))
_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());
}
return _fpath;
}
std::string
compose_filename(const config& _cfg)
{
auto _output_path = _cfg.output_path;
auto _output_file = _cfg.output_file;
auto _output_ext = _cfg.output_ext;
if(_output_path.empty()) _output_path = ".";
if(_cfg.mpi_size > 0)
{
if(_cfg.mpi_rank >= 0)
{
_output_file = join('.', _output_file, _cfg.mpi_rank);
}
else
{
_output_file = join('.', _output_file, getpid());
}
}
if(!_output_ext.empty())
{
if(_output_ext.find('.') == std::string::npos) _output_ext.insert(0, ".");
if(_output_file.length() < _output_ext.length() ||
_output_file.find(_output_ext) != _output_file.length() - _output_ext.length())
_output_file += _output_ext;
}
// join <OUTPUT_PATH>/<OUTPUT_FILE> and replace any keys with values
auto _prefix = format(std::filesystem::path{_output_path} / _output_file);
// return on empty
if(_prefix.empty()) return std::string{};
// get the absolute path
auto _fname = std::filesystem::absolute(std::filesystem::path{_prefix});
// create the directory if necessary
auto _fname_path = _fname.parent_path();
if(!std::filesystem::exists(_fname_path))
std::filesystem::create_directories(_fname.parent_path());
return _fname.string();
}
std::string
format_name(std::string_view _name, const config& _cfg)
{
if(_cfg.demangle && _cfg.truncate)
{
return truncate_name(cxx_demangle(_name));
}
if(_cfg.demangle)
{
return cxx_demangle(_name);
}
if(_cfg.truncate)
{
return truncate_name(_name);
}
return std::string{_name};
}
void
initialize()
{
(void) get_config<config_context::global>();
}
output_key::output_key(std::string _key, std::string _val, std::string _desc)
: key{std::move(_key)}
, value{std::move(_val)}
, description{std::move(_desc)}
{}
} // namespace common
} // namespace rocprofiler
+99
Просмотреть файл
@@ -0,0 +1,99 @@
// 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 "lib/common/environment.hpp"
#include <string>
#include <vector>
namespace rocprofiler
{
namespace common
{
enum class config_context
{
global = 0,
att_plugin,
cli_plugin,
ctf_plugin,
file_plugin,
perfetto_plugin,
};
int
get_mpi_size();
int
get_mpi_rank();
struct config
{
bool demangle = get_env("ROCP_DEMANGLE_KERNELS", true);
bool truncate = get_env("ROCP_TRUNCATE_KERNELS", false);
int mpi_size = get_mpi_size();
int mpi_rank = get_mpi_rank();
std::string output_path = get_env<std::string>("ROCP_OUTPUT_PATH", ".");
std::string output_file = get_env<std::string>("ROCP_OUTPUT_FILE", "results");
std::string output_ext = {};
};
template <config_context ContextT = config_context::global>
config&
get_config()
{
if constexpr(ContextT == config_context::global)
{
static auto _v = config{};
return _v;
}
else
{
// context specific config copied from global config
static auto _v = get_config<config_context::global>();
return _v;
}
}
struct output_key
{
output_key(std::string _key, std::string _val, std::string _desc = {});
operator std::pair<std::string, std::string>() const;
std::string key = {};
std::string value = {};
std::string description = {};
};
std::vector<output_key>
output_keys(std::string _tag = {});
std::string
compose_filename(const config&);
std::string
format(std::string _fpath, const std::string& _tag = {});
std::string
format_name(std::string_view _name, const config& = get_config<>());
void
initialize();
} // namespace common
} // namespace rocprofiler
+10
Просмотреть файл
@@ -0,0 +1,10 @@
#
set(containers_sources)
set(containers_headers atomic_ring_buffer.hpp c_array.hpp operators.hpp ring_buffer.hpp
stable_vector.hpp static_vector.hpp)
set(containers_sources atomic_ring_buffer.cpp ring_buffer.cpp)
target_sources(rocprofiler-common-library PRIVATE ${containers_sources}
${containers_headers})
+297
Просмотреть файл
@@ -0,0 +1,297 @@
// 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 "atomic_ring_buffer.hpp"
#include "lib/common/units.hpp"
#include "lib/common/environment.hpp"
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstdint>
#include <cstddef>
#include <sys/mman.h>
namespace rocprofiler
{
namespace common
{
namespace container
{
namespace base
{
atomic_ring_buffer::atomic_ring_buffer(size_t _size, bool _use_mmap)
{
set_use_mmap(_use_mmap);
init(_size);
}
atomic_ring_buffer::~atomic_ring_buffer() { destroy(); }
atomic_ring_buffer::atomic_ring_buffer(const atomic_ring_buffer& rhs)
: m_use_mmap{rhs.m_use_mmap}
, m_use_mmap_explicit{rhs.m_use_mmap_explicit}
{
init(rhs.m_size);
}
atomic_ring_buffer::atomic_ring_buffer(atomic_ring_buffer&& rhs) noexcept
: m_init{rhs.m_init}
, m_use_mmap{rhs.m_use_mmap}
, m_use_mmap_explicit{rhs.m_use_mmap_explicit}
, m_ptr{rhs.m_ptr}
, m_size{rhs.m_size}
, m_read_count{rhs.m_read_count.load()}
, m_write_count{rhs.m_write_count.load()}
{
rhs.reset();
}
atomic_ring_buffer&
atomic_ring_buffer::operator=(const atomic_ring_buffer& rhs)
{
if(this == &rhs) return *this;
destroy();
m_use_mmap = rhs.m_use_mmap;
m_use_mmap_explicit = rhs.m_use_mmap_explicit;
init(rhs.m_size);
return *this;
}
atomic_ring_buffer&
atomic_ring_buffer::operator=(atomic_ring_buffer&& rhs) noexcept
{
if(this == &rhs) return *this;
destroy();
m_init = rhs.m_init;
m_use_mmap = rhs.m_use_mmap;
m_use_mmap_explicit = rhs.m_use_mmap_explicit;
m_ptr = rhs.m_ptr;
m_size = rhs.m_size;
m_read_count = rhs.m_read_count.load();
m_write_count = rhs.m_write_count.load();
rhs.reset();
return *this;
}
void
atomic_ring_buffer::init(size_t _size)
{
if(m_init)
throw std::runtime_error(
"tim::base::atomic_ring_buffer::init(size_t) :: already initialized");
m_init = true;
// Round up to multiple of page size.
_size += units::get_page_size() - ((_size % units::get_page_size() > 0)
? (_size % units::get_page_size())
: units::get_page_size());
if((_size % units::get_page_size()) > 0)
{
std::ostringstream _oss{};
_oss << "Error! size is not a multiple of page size: " << _size << " % "
<< units::get_page_size() << " = " << (_size % units::get_page_size());
throw std::runtime_error(_oss.str());
}
m_size = _size;
m_read_count = 0;
m_write_count = 0;
if(!m_use_mmap_explicit) m_use_mmap = get_env("ROCPROFILER_USE_MMAP", m_use_mmap);
if(!m_use_mmap)
{
m_ptr = malloc(m_size * sizeof(char));
return;
}
// Map twice the buffer size.
if((m_ptr =
mmap(nullptr, m_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)) ==
MAP_FAILED)
{
destroy();
auto _err = errno;
// TIMEMORY_PRINTF_FATAL(stderr, "Error using mmap: %s\n", strerror(_err));
throw std::runtime_error(strerror(_err));
}
}
void
atomic_ring_buffer::destroy()
{
if(m_ptr && m_init)
{
if(!m_use_mmap)
{
::free(m_ptr);
}
else
{
// Unmap the mapped virtual memmory.
auto ret = munmap(m_ptr, m_size);
if(ret != 0) perror("munmap");
}
}
m_init = false;
m_size = 0;
m_read_count = 0;
m_write_count = 0;
m_ptr = nullptr;
}
void
atomic_ring_buffer::set_use_mmap(bool _v)
{
if(m_init)
throw std::runtime_error("tim::base::atomic_ring_buffer::set_use_mmap(bool) cannot be "
"called after initialization");
m_use_mmap = _v;
m_use_mmap_explicit = true;
}
std::string
atomic_ring_buffer::as_string() const
{
std::ostringstream ss{};
ss << std::boolalpha << "is_initialized: " << is_initialized() << ", capacity: " << capacity()
<< ", count: " << count() << ", free: " << free() << ", is_empty: " << is_empty()
<< ", is_full: " << is_full() << ", pointer: " << m_ptr << ", read count: " << m_read_count
<< ", write count: " << m_write_count;
return ss.str();
}
//
void*
atomic_ring_buffer::request(size_t _length)
{
if(m_ptr == nullptr || m_size == 0) return nullptr;
if(is_full()) return retrieve(_length);
// if write count is at the tail of buffer, bump to the end of buffer
size_t _write_count = 0;
size_t _offset = 0;
do
{
// Make sure we don't put in more than there's room for, by writing no
// more than there is free.
if(_length > free()) return nullptr;
_offset = 0;
_write_count = m_write_count.load();
auto _modulo = m_size - (_write_count % m_size);
if(_modulo < _length) _offset = _modulo;
} while(!m_write_count.compare_exchange_strong(
_write_count, _write_count + _length + _offset, std::memory_order_seq_cst));
// pointer in buffer
void* _out = write_ptr(_write_count);
return _out;
}
//
void*
atomic_ring_buffer::retrieve(size_t _length) const
{
if(m_ptr == nullptr || m_size == 0) return nullptr;
// Make sure we don't put in more than there's room for, by writing no
// more than there is free.
// if read count is at the tail of buffer, bump to the end of buffer
size_t _read_count = 0;
size_t _offset = 0;
do
{
if(_length > count()) return nullptr;
_offset = 0;
_read_count = m_read_count.load();
auto _modulo = m_size - (_read_count % m_size);
if(_modulo < _length) _offset = _modulo;
} while(!m_read_count.compare_exchange_strong(
_read_count, _read_count + _length + _offset, std::memory_order_seq_cst));
// pointer in buffer
void* _out = read_ptr(_read_count);
return _out;
}
//
void
atomic_ring_buffer::reset()
{
m_init = false;
m_size = 0;
m_ptr = nullptr;
m_read_count.store(0);
m_write_count.store(0);
}
//
void
atomic_ring_buffer::save(std::fstream& _fs)
{
auto _read_count = m_read_count.load();
auto _write_count = m_write_count.load();
_fs.write(reinterpret_cast<char*>(&m_use_mmap), sizeof(m_use_mmap));
_fs.write(reinterpret_cast<char*>(&m_use_mmap_explicit), sizeof(m_use_mmap_explicit));
_fs.write(reinterpret_cast<char*>(&m_size), sizeof(m_size));
_fs.write(reinterpret_cast<char*>(&_read_count), sizeof(_read_count));
_fs.write(reinterpret_cast<char*>(&_write_count), sizeof(_write_count));
_fs.write(reinterpret_cast<char*>(m_ptr), m_size * sizeof(char));
}
//
void
atomic_ring_buffer::load(std::fstream& _fs)
{
destroy();
size_t _read_count = 0;
size_t _write_count = 0;
_fs.read(reinterpret_cast<char*>(&m_use_mmap), sizeof(m_use_mmap));
_fs.read(reinterpret_cast<char*>(&m_use_mmap_explicit), sizeof(m_use_mmap_explicit));
_fs.read(reinterpret_cast<char*>(&m_size), sizeof(m_size));
init(m_size);
if(!m_ptr) m_ptr = malloc(m_size);
_fs.read(reinterpret_cast<char*>(&_read_count), sizeof(_read_count));
_fs.read(reinterpret_cast<char*>(&_write_count), sizeof(_write_count));
_fs.read(reinterpret_cast<char*>(m_ptr), m_size * sizeof(char));
m_read_count.store(_read_count);
m_write_count.store(_write_count);
}
} // namespace base
} // namespace container
} // namespace common
} // namespace rocprofiler
+426
Просмотреть файл
@@ -0,0 +1,426 @@
// 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.
#pragma once
#include "lib/common/units.hpp"
#include "lib/common/environment.hpp"
#include <algorithm>
#include <atomic>
#include <cmath>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <utility>
#include <vector>
#include <cstddef>
#include <cstdlib>
namespace rocprofiler
{
namespace common
{
namespace container
{
template <typename Tp>
struct atomic_ring_buffer;
//
namespace base
{
/// \struct tim::base::atomic_ring_buffer
/// \brief Ring buffer implementation, with support for mmap as backend (Linux only).
struct atomic_ring_buffer
{
template <typename Tp>
friend struct container::atomic_ring_buffer;
atomic_ring_buffer() = default;
explicit atomic_ring_buffer(bool _use_mmap) { set_use_mmap(_use_mmap); }
explicit atomic_ring_buffer(size_t _size) { init(_size); }
atomic_ring_buffer(size_t _size, bool _use_mmap);
~atomic_ring_buffer();
atomic_ring_buffer(const atomic_ring_buffer&);
atomic_ring_buffer& operator=(const atomic_ring_buffer&);
atomic_ring_buffer(atomic_ring_buffer&&) noexcept;
atomic_ring_buffer& operator=(atomic_ring_buffer&&) noexcept;
/// Returns whether the buffer has been allocated
bool is_initialized() const { return m_init; }
/// Get the total number of bytes supported
size_t capacity() const { return m_size; }
/// Creates new ring buffer.
void init(size_t size);
/// Destroy ring buffer.
void destroy();
/// Request a pointer for writing at least \param n bytes.
void* request(size_t n);
/// Retrieve a pointer for reading at least \param n bytes.
void* retrieve(size_t n) const;
/// Write class-type data to buffer (uses placement new).
template <typename Tp>
std::pair<size_t, Tp*> write(Tp* in, std::enable_if_t<std::is_class<Tp>::value, int> = 0);
/// Write non-class-type data to buffer (uses memcpy).
template <typename Tp>
std::pair<size_t, Tp*> write(Tp* in, std::enable_if_t<!std::is_class<Tp>::value, int> = 0);
/// Request a pointer to an allocation. This is similar to a "write" except the
/// memory is uninitialized. Typically used by allocators. If Tp is a class type,
/// be sure to use a placement new instead of a memcpy.
template <typename Tp>
Tp* request();
/// Read class-type data from buffer (uses placement new).
template <typename Tp>
std::pair<size_t, Tp*> read(Tp* _dest,
std::enable_if_t<std::is_class<Tp>::value, int> = 0) const;
/// Read non-class-type data from buffer (uses memcpy).
template <typename Tp>
std::pair<size_t, Tp*> read(Tp* _dest,
std::enable_if_t<!std::is_class<Tp>::value, int> = 0) const;
/// Retrieve a pointer to the head allocation (read).
template <typename Tp>
Tp* retrieve() const;
/// Returns number of bytes currently held by the buffer.
size_t count() const { return (m_write_count - m_read_count); }
/// Returns how many bytes are availiable in the buffer.
size_t free() const { return (m_size - count()); }
/// Returns if the buffer is empty.
bool is_empty() const { return (count() == 0); }
/// Returns if the buffer is full.
bool is_full() const { return (count() == m_size); }
/// explicitly configure to use mmap if avail
void set_use_mmap(bool);
/// query whether using mmap
bool get_use_mmap() const { return m_use_mmap; }
std::string as_string() const;
void save(std::fstream& _fs);
void load(std::fstream& _fs);
private:
/// Returns the current write pointer.
void* write_ptr(size_t _write_count) const
{
return static_cast<char*>(m_ptr) + (_write_count % m_size);
}
/// Returns the current read pointer.
void* read_ptr(size_t _read_count) const
{
return static_cast<char*>(m_ptr) + (_read_count % m_size);
}
void reset();
private:
bool m_init = false;
bool m_use_mmap = true;
bool m_use_mmap_explicit = false;
void* m_ptr = nullptr;
size_t m_size = 0;
mutable std::atomic<size_t> m_read_count = 0;
std::atomic<size_t> m_write_count = 0;
};
//
template <typename Tp>
std::pair<size_t, Tp*>
atomic_ring_buffer::write(Tp* in, std::enable_if_t<std::is_class<Tp>::value, int>)
{
if(in == nullptr || m_ptr == nullptr) return {0, nullptr};
auto _length = sizeof(Tp);
void* _out_p = request(_length);
if(_out_p == nullptr) return {0, nullptr};
// Copy in.
new(_out_p) Tp{std::move(*in)};
// pointer in buffer
Tp* _out = reinterpret_cast<Tp*>(_out_p);
return {_length, _out};
}
//
template <typename Tp>
std::pair<size_t, Tp*>
atomic_ring_buffer::write(Tp* in, std::enable_if_t<!std::is_class<Tp>::value, int>)
{
if(in == nullptr || m_ptr == nullptr) return {0, nullptr};
auto _length = sizeof(Tp);
void* _out_p = request(_length);
if(_out_p == nullptr) return {0, nullptr};
// Copy in.
memcpy(_out_p, in, _length);
// pointer in buffer
Tp* _out = reinterpret_cast<Tp*>(_out_p);
return {_length, _out};
}
//
template <typename Tp>
Tp*
atomic_ring_buffer::request()
{
if(m_ptr == nullptr) return nullptr;
return request(sizeof(Tp));
}
//
template <typename Tp>
std::pair<size_t, Tp*>
atomic_ring_buffer::read(Tp* _dest, std::enable_if_t<std::is_class<Tp>::value, int>) const
{
if(is_empty() || _dest == nullptr) return {0, nullptr};
auto _length = sizeof(Tp);
void* _out_p = retrieve(_length);
if(_out_p == nullptr) return {0, nullptr};
// pointer in buffer
Tp* in = reinterpret_cast<Tp*>(_out_p);
// Copy out for BYTE, nothing magic here.
*_dest = *in;
return {_length, in};
}
//
template <typename Tp>
std::pair<size_t, Tp*>
atomic_ring_buffer::read(Tp* _dest, std::enable_if_t<!std::is_class<Tp>::value, int>) const
{
if(is_empty() || _dest == nullptr) return {0, nullptr};
auto _length = sizeof(Tp);
void* _out_p = retrieve(_length);
if(_out_p == nullptr) return {0, nullptr};
// pointer in buffer
Tp* in = reinterpret_cast<Tp*>(_out_p);
using Up = typename std::remove_const<Tp>::type;
// Copy out for BYTE, nothing magic here.
Up* _out = const_cast<Up*>(_dest);
memcpy(_out, in, _length);
return {_length, in};
}
//
template <typename Tp>
Tp*
atomic_ring_buffer::retrieve() const
{
if(m_ptr == nullptr) return nullptr;
return retrieve(sizeof(Tp));
}
//
} // namespace base
//
/// \struct tim::data_storage::atomic_ring_buffer
/// \brief Ring buffer wrapper around \ref tim::base::atomic_ring_buffer for data of type
/// Tp. If the data object size is larger than the page size (typically 4KB), behavior is
/// undefined. During initialization, one requests a minimum number of objects and the
/// buffer will support that number of object + the remainder of the page, e.g. if a page
/// is 1000 bytes, the object is 1 byte, and the buffer is requested to support 1500
/// objects, then an allocation supporting 2000 objects (i.e. 2 pages) will be created.
template <typename Tp>
struct atomic_ring_buffer : private base::atomic_ring_buffer
{
using base_type = base::atomic_ring_buffer;
static size_t get_items_per_page();
atomic_ring_buffer() = default;
~atomic_ring_buffer() = default;
explicit atomic_ring_buffer(bool _use_mmap)
: base_type{_use_mmap}
{}
explicit atomic_ring_buffer(size_t _size)
: base_type{_size * sizeof(Tp)}
{}
atomic_ring_buffer(size_t _size, bool _use_mmap)
: base_type{_size * sizeof(Tp), _use_mmap}
{}
atomic_ring_buffer(const atomic_ring_buffer&);
atomic_ring_buffer(atomic_ring_buffer&&) noexcept = default;
atomic_ring_buffer& operator=(const atomic_ring_buffer&);
atomic_ring_buffer& operator=(atomic_ring_buffer&&) noexcept = default;
/// Returns whether the buffer has been allocated
bool is_initialized() const { return base_type::is_initialized(); }
/// Get the total number of Tp instances supported
size_t capacity() const { return (base_type::capacity()) / sizeof(Tp); }
/// Creates new ring buffer.
void init(size_t _size) { base_type::init(_size * sizeof(Tp)); }
/// Destroy ring buffer.
void destroy() { base_type::destroy(); }
/// Write data to buffer.
size_t data_size() const { return sizeof(Tp); }
/// Write data to buffer. Return pointer to location of write
Tp* write(Tp* in) { return base_type::write<Tp>(in).second; }
/// Read data from buffer. Return pointer to location of read
Tp* read(Tp* _dest) const { return base_type::read<Tp>(_dest).second; }
/// Get an uninitialized address at tail of buffer.
Tp* request() { return base_type::request<Tp>(); }
/// Read data from head of buffer.
Tp* retrieve() { return base_type::retrieve<Tp>(); }
/// Returns number of Tp instances currently held by the buffer.
size_t count() const { return (base_type::count()) / sizeof(Tp); }
/// Returns how many Tp instances are availiable in the buffer.
size_t free() const { return (base_type::free()) / sizeof(Tp); }
/// Returns if the buffer is empty.
bool is_empty() const { return base_type::is_empty(); }
/// Returns if the buffer is full.
bool is_full() const { return (base_type::free() < sizeof(Tp)); }
template <typename... Args>
auto emplace(Args&&... args)
{
Tp _obj{std::forward<Args>(args)...};
return write(&_obj);
}
using base_type::get_use_mmap;
using base_type::load;
using base_type::save;
using base_type::set_use_mmap;
std::string as_string() const
{
std::ostringstream ss{};
size_t _w = std::log10(base_type::capacity()) + 1;
ss << std::boolalpha << std::right << "data size: " << std::setw(_w) << data_size()
<< " B, is_initialized: " << std::setw(5) << is_initialized()
<< ", is_empty: " << std::setw(5) << is_empty() << ", is_full: " << std::setw(5)
<< is_full() << ", capacity: " << std::setw(_w) << capacity()
<< ", count: " << std::setw(_w) << count() << ", free: " << std::setw(_w) << free()
<< ", raw capacity: " << std::setw(_w) << base_type::capacity()
<< " B, raw count: " << std::setw(_w) << base_type::count()
<< " B, raw free: " << std::setw(_w) << base_type::free()
<< " B, pointer: " << std::setw(15) << base_type::m_ptr
<< ", raw read count: " << std::setw(_w) << base_type::m_read_count
<< ", raw write count: " << std::setw(_w) << base_type::m_write_count;
return ss.str();
}
friend std::ostream& operator<<(std::ostream& os, const atomic_ring_buffer& obj)
{
return os << obj.as_string();
}
};
//
template <typename Tp>
size_t
atomic_ring_buffer<Tp>::get_items_per_page()
{
return std::max<size_t>(units::get_page_size() / sizeof(Tp), 1);
}
//
template <typename Tp>
atomic_ring_buffer<Tp>::atomic_ring_buffer(const atomic_ring_buffer<Tp>& rhs)
: base_type{rhs}
{
size_t _n = rhs.count();
char* _end = static_cast<char*>(rhs.m_ptr) + rhs.m_size;
for(size_t i = 0; i < _n; ++i)
{
char* _addr = static_cast<char*>(rhs.read_ptr(m_read_count)) + (i * sizeof(Tp));
if((_addr + sizeof(Tp)) > _end) _addr = static_cast<char*>(rhs.m_ptr);
Tp* _in = static_cast<Tp*>(static_cast<void*>(_addr));
write(_in);
}
}
//
template <typename Tp>
atomic_ring_buffer<Tp>&
atomic_ring_buffer<Tp>::operator=(const atomic_ring_buffer<Tp>& rhs)
{
if(this == &rhs) return *this;
base_type::operator=(rhs);
size_t _n = rhs.count();
char* _end = static_cast<char*>(rhs.m_ptr) + rhs.m_size;
for(size_t i = 0; i < _n; ++i)
{
char* _addr = static_cast<char*>(rhs.read_ptr(m_read_count)) + (i * sizeof(Tp));
if((_addr + sizeof(Tp)) > _end) _addr = static_cast<char*>(rhs.m_ptr);
Tp* _in = static_cast<Tp*>(static_cast<void*>(_addr));
write(_in);
}
return *this;
}
//
} // namespace container
} // namespace common
} // namespace rocprofiler
+136
Просмотреть файл
@@ -0,0 +1,136 @@
// 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 <array>
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <stdexcept>
#include <vector>
namespace rocprofiler
{
namespace common
{
namespace container
{
template <typename Tp>
struct c_array
{
// Construct an array wrapper from a base pointer and array size
c_array(Tp* _base, size_t _size)
: m_base{_base}
, m_size{_size}
{}
~c_array() = default;
c_array(const c_array&) = default;
c_array& operator=(const c_array&) = default;
c_array& operator=(c_array&&) noexcept = default;
// Get the size of the wrapped array
size_t size() const { return m_size; }
// Access an element by index
Tp& operator[](size_t i) { return m_base[i]; }
// Access an element by index
const Tp& operator[](size_t i) const { return m_base[i]; }
// Access an element by index with bounds check
Tp& at(size_t i)
{
if(i < m_size) return m_base[i];
throw std::out_of_range(std::string{typeid(*this).name()} + std::to_string(i) +
" exceeds size " + std::to_string(m_size));
}
// Access an element by index with bounds check
const Tp& at(size_t i) const
{
if(i < m_size) return m_base[i];
throw std::out_of_range(std::string{typeid(*this).name()} + std::to_string(i) +
" exceeds size " + std::to_string(m_size));
}
// Get a slice of this array, from a start index (inclusive) to end index (exclusive)
c_array<Tp> slice(size_t start, size_t end) { return c_array<Tp>(&m_base[start], end - start); }
void pop_front()
{
++m_base;
--m_size;
}
void pop_back() { --m_size; }
operator Tp*() const { return m_base; }
// Iterator class for convenient range-based for loop support
template <typename Up>
struct iterator
{
// Start the iterator at a given pointer
explicit iterator(Tp* p)
: m_ptr{p}
{}
// Advance to the next element
void operator++() { ++m_ptr; }
void operator++(int) { m_ptr++; }
// Get the current element
Up& operator*() const { return *m_ptr; }
// Compare iterators
bool operator==(const iterator& rhs) const { return m_ptr == rhs.m_ptr; }
bool operator!=(const iterator& rhs) const { return m_ptr != rhs.m_ptr; }
private:
Tp* m_ptr = nullptr;
};
// Get an iterator positioned at the beginning of the wrapped array
iterator<Tp> begin() { return iterator<Tp>{m_base}; }
iterator<const Tp> begin() const { return iterator<const Tp>{m_base}; }
// Get an iterator positioned at the end of the wrapped array
iterator<Tp> end() { return iterator<Tp>{&m_base[m_size]}; }
iterator<const Tp> end() const { return iterator<const Tp>{&m_base[m_size]}; }
private:
Tp* m_base = nullptr;
size_t m_size = 0;
};
// Function for automatic template argument deduction
template <typename Tp>
c_array<Tp>
wrap_c_array(Tp* base, size_t size)
{
return c_array<Tp>(base, size);
}
} // namespace container
} // namespace common
} // namespace rocprofiler
+239
Просмотреть файл
@@ -0,0 +1,239 @@
// 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 <iterator>
#include <type_traits>
#define ROCPROFILER_IMPORT_TEMPLATE2(template_name)
#define ROCPROFILER_IMPORT_TEMPLATE1(template_name)
// Import a 2-type-argument operator template into boost (if necessary) and
// provide a specialization of 'is_chained_base<>' for it.
#define ROCPROFILER_OPERATOR_TEMPLATE2(template_name2) \
ROCPROFILER_IMPORT_TEMPLATE2(template_name2) \
template <typename T, typename U, typename B> \
struct is_chained_base<::rocprofiler::container::template_name2<T, U, B>> \
{ \
using value = ::rocprofiler::container::true_t; \
};
// Import a 1-type-argument operator template into boost (if necessary) and
// provide a specialization of 'is_chained_base<>' for it.
#define ROCPROFILER_OPERATOR_TEMPLATE1(template_name1) \
ROCPROFILER_IMPORT_TEMPLATE1(template_name1) \
template <typename T, typename B> \
struct is_chained_base<::rocprofiler::container::template_name1<T, B>> \
{ \
using value = ::rocprofiler::container::true_t; \
};
#define ROCPROFILER_OPERATOR_TEMPLATE(template_name) \
template <typename T, \
typename U = T, \
typename B = empty_base<T>, \
typename O = typename is_chained_base<U>::value> \
struct template_name; \
\
template <typename T, typename U, typename B> \
struct template_name<T, U, B, false_t> : template_name##2 < T \
, U \
, B > \
{}; \
\
template <typename T, typename U> \
struct template_name<T, U, empty_base<T>, true_t> : template_name##1 < T \
, U > \
{}; \
\
template <typename T, typename B> \
struct template_name<T, T, B, false_t> : template_name##1 < T \
, B > \
{}; \
\
template <typename T, typename U, typename B, typename O> \
struct is_chained_base<template_name<T, U, B, O>> \
{ \
using value = ::rocprofiler::container::true_t; \
}; \
\
ROCPROFILER_OPERATOR_TEMPLATE2(template_name##2) \
ROCPROFILER_OPERATOR_TEMPLATE1(template_name##1)
#define ROCPROFILER_BINARY_OPERATOR_COMMUTATIVE(NAME, OP) \
template <typename T, typename U, typename B = empty_base<T>> \
struct NAME##2 : B{friend T operator OP(T lhs, const U& rhs){return lhs OP## = rhs; \
} \
friend T operator OP(const U& lhs, T rhs) { return rhs OP## = lhs; } \
} \
; \
\
template <typename T, typename B = empty_base<T>> \
struct NAME##1 : B{friend T operator OP(T lhs, const T& rhs){return lhs OP## = rhs; \
} \
} \
;
#define ROCPROFILER_BINARY_OPERATOR_NON_COMMUTATIVE(NAME, OP) \
template <typename T, typename U, typename B = empty_base<T>> \
struct NAME##2 : B{friend T operator OP(T lhs, const U& rhs){return lhs OP## = rhs; \
} \
} \
;
namespace rocprofiler
{
namespace common
{
namespace container
{
struct true_t
{};
struct false_t
{};
template <typename T>
class empty_base
{};
template <typename T>
struct is_chained_base
{
using value = true_t;
};
ROCPROFILER_BINARY_OPERATOR_COMMUTATIVE(addable, +)
ROCPROFILER_BINARY_OPERATOR_NON_COMMUTATIVE(subtractable, -)
ROCPROFILER_OPERATOR_TEMPLATE(addable)
template <typename T, typename B = empty_base<T>>
struct incrementable : B
{
friend T operator++(T& x, int)
{
incrementable_type nrv(x);
++x;
return nrv;
}
private: // The use of this typedef works around a Borland bug
typedef T incrementable_type;
};
template <typename T, typename B = empty_base<T>>
struct decrementable : B
{
friend T operator--(T& x, int)
{
decrementable_type nrv(x);
--x;
return nrv;
}
private: // The use of this typedef works around a Borland bug
typedef T decrementable_type;
};
template <typename T, typename P, typename B = empty_base<T>>
struct dereferenceable : B
{
P operator->() const { return ::std::addressof(*static_cast<const T&>(*this)); }
};
template <typename T, typename I, typename R, typename B = empty_base<T>>
struct indexable : B
{
R operator[](I n) const { return *(static_cast<const T&>(*this) + n); }
};
template <typename T, typename B = empty_base<T>>
struct equality_comparable1 : B
{
friend bool operator!=(const T& x, const T& y) { return !static_cast<bool>(x == y); }
};
template <typename T, typename P, typename B = empty_base<T>>
struct input_iteratable : equality_comparable1<T, incrementable<T, dereferenceable<T, P, B>>>
{};
template <typename T, typename B = empty_base<T>>
struct output_iteratable : incrementable<T, B>
{};
template <typename T, typename P, typename B = empty_base<T>>
struct forward_iteratable : input_iteratable<T, P, B>
{};
template <typename T, typename P, typename B = empty_base<T>>
struct bidirectional_iteratable : forward_iteratable<T, P, decrementable<T, B>>
{};
// template <typename T, typename U, typename B = empty_base<T>>
// struct subtractable2;
template <typename T, typename U, typename B = empty_base<T>>
struct additive2 : addable2<T, U, subtractable2<T, U, B>>
{};
template <typename T, typename B = empty_base<T>>
struct less_than_comparable1 : B
{
friend bool operator>(const T& x, const T& y) { return y < x; }
friend bool operator<=(const T& x, const T& y) { return !static_cast<bool>(y < x); }
friend bool operator>=(const T& x, const T& y) { return !static_cast<bool>(x < y); }
};
// To avoid repeated derivation from equality_comparable,
// which is an indirect base typename of bidirectional_iterable,
// random_access_iteratable must not be derived from totally_ordered1
// but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
template <typename T, typename P, typename D, typename R, typename B = empty_base<T>>
struct random_access_iteratable
: bidirectional_iteratable<T, P, less_than_comparable1<T, additive2<T, D, indexable<T, D, R, B>>>>
{};
template <typename CategoryT,
typename Tp,
typename DistanceT = std::ptrdiff_t,
typename PointerT = Tp*,
typename ReferenceT = Tp&>
struct iterator_helper
{
using iterator_category = CategoryT;
using value_type = Tp;
using difference_type = DistanceT;
using pointer = PointerT;
using reference = ReferenceT;
};
template <typename T, typename V, typename D = std::ptrdiff_t, typename P = V*, typename R = V&>
struct random_access_iterator_helper
: random_access_iteratable<T, P, D, R, iterator_helper<std::random_access_iterator_tag, V, D, P, R>>
{
friend D requires_difference_operator(const T& x, const T& y) { return x - y; }
}; // random_access_iterator_helper
} // namespace container
} // namespace common
} // namespace rocprofiler
+289
Просмотреть файл
@@ -0,0 +1,289 @@
// 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 "ring_buffer.hpp"
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/mman.h>
namespace rocprofiler
{
namespace common
{
namespace container
{
namespace base
{
ring_buffer::ring_buffer(size_t _size, bool _use_mmap)
{
set_use_mmap(_use_mmap);
init(_size);
}
ring_buffer::~ring_buffer() { destroy(); }
ring_buffer::ring_buffer(const ring_buffer& rhs)
: m_use_mmap{rhs.m_use_mmap}
, m_use_mmap_explicit{rhs.m_use_mmap_explicit}
{
init(rhs.m_size);
}
ring_buffer::ring_buffer(ring_buffer&& rhs) noexcept
: m_init{rhs.m_init}
, m_use_mmap{rhs.m_use_mmap}
, m_use_mmap_explicit{rhs.m_use_mmap_explicit}
, m_ptr{rhs.m_ptr}
, m_size{rhs.m_size}
, m_read_count{rhs.m_read_count}
, m_write_count{rhs.m_write_count}
{
rhs.reset();
}
ring_buffer&
ring_buffer::operator=(const ring_buffer& rhs)
{
if(this == &rhs) return *this;
destroy();
m_use_mmap = rhs.m_use_mmap;
m_use_mmap_explicit = rhs.m_use_mmap_explicit;
init(rhs.m_size);
return *this;
}
ring_buffer&
ring_buffer::operator=(ring_buffer&& rhs) noexcept
{
if(this == &rhs) return *this;
destroy();
m_init = rhs.m_init;
m_use_mmap = rhs.m_use_mmap;
m_use_mmap_explicit = rhs.m_use_mmap_explicit;
m_ptr = rhs.m_ptr;
m_size = rhs.m_size;
m_read_count = rhs.m_read_count;
m_write_count = rhs.m_write_count;
rhs.reset();
return *this;
}
void
ring_buffer::init(size_t _size)
{
if(m_init)
throw std::runtime_error("tim::base::ring_buffer::init(size_t) :: already initialized");
m_init = true;
// Round up to multiple of page size.
_size += units::get_page_size() - ((_size % units::get_page_size() > 0)
? (_size % units::get_page_size())
: units::get_page_size());
if((_size % units::get_page_size()) > 0)
{
std::ostringstream _oss{};
_oss << "Error! size is not a multiple of page size: " << _size << " % "
<< units::get_page_size() << " = " << (_size % units::get_page_size());
throw std::runtime_error(_oss.str());
}
m_size = _size;
m_read_count = 0;
m_write_count = 0;
if(!m_use_mmap_explicit) m_use_mmap = get_env("ROCPROFILER_USE_MMAP", m_use_mmap);
if(!m_use_mmap)
{
m_ptr = malloc(m_size * sizeof(char));
return;
}
// Map twice the buffer size.
if((m_ptr =
mmap(nullptr, m_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)) ==
MAP_FAILED)
{
destroy();
auto _err = errno;
// TIMEMORY_PRINTF_FATAL(stderr, "Error using mmap: %s\n", strerror(_err));
throw std::runtime_error(strerror(_err));
}
}
void
ring_buffer::destroy()
{
if(m_ptr && m_init)
{
if(!m_use_mmap)
{
::free(m_ptr);
}
else
{
// Unmap the mapped virtual memmory.
auto ret = munmap(m_ptr, m_size);
if(ret != 0) perror("munmap");
}
}
m_init = false;
m_size = 0;
m_read_count = 0;
m_write_count = 0;
m_ptr = nullptr;
}
void
ring_buffer::set_use_mmap(bool _v)
{
if(!m_init)
{
m_use_mmap = _v;
m_use_mmap_explicit = true;
}
else
{
throw std::runtime_error("tim::base::ring_buffer::set_use_mmap(bool) cannot be "
"called after initialization");
}
}
std::string
ring_buffer::as_string() const
{
std::ostringstream ss{};
ss << std::boolalpha << "is_initialized: " << is_initialized() << ", capacity: " << capacity()
<< ", count: " << count() << ", free: " << free() << ", is_empty: " << is_empty()
<< ", is_full: " << is_full() << ", pointer: " << m_ptr << ", read count: " << m_read_count
<< ", write count: " << m_write_count;
return ss.str();
}
//
void*
ring_buffer::request(size_t _length)
{
if(m_ptr == nullptr) return nullptr;
// Make sure we don't put in more than there's room for, by writing no
// more than there is free.
if(_length > free())
throw std::runtime_error("heap-buffer-overflow :: ring buffer is full. read data "
"to avoid data corruption");
// if write count is at the tail of buffer, bump to the end of buffer
auto _modulo = m_size - (m_write_count % m_size);
if(_modulo < _length) m_write_count += _modulo;
// pointer in buffer
void* _out = write_ptr();
// Update write count
m_write_count += _length;
return _out;
}
//
void*
ring_buffer::retrieve(size_t _length)
{
if(m_ptr == nullptr) return nullptr;
// Make sure we don't put in more than there's room for, by writing no
// more than there is free.
if(_length > count()) throw std::runtime_error("ring buffer is empty");
// if read count is at the tail of buffer, bump to the end of buffer
auto _modulo = m_size - (m_read_count % m_size);
if(_modulo < _length) m_read_count += _modulo;
// pointer in buffer
void* _out = read_ptr();
// Update write count
m_read_count += _length;
return _out;
}
//
size_t
ring_buffer::rewind(size_t n) const
{
if(n > m_read_count) n = m_read_count;
m_read_count -= n;
return n;
}
//
void
ring_buffer::reset()
{
m_init = false;
m_ptr = nullptr;
m_size = 0;
m_read_count = 0;
m_write_count = 0;
}
//
void
ring_buffer::save(std::fstream& _fs)
{
_fs.write(reinterpret_cast<char*>(&m_use_mmap), sizeof(m_use_mmap));
_fs.write(reinterpret_cast<char*>(&m_use_mmap_explicit), sizeof(m_use_mmap_explicit));
_fs.write(reinterpret_cast<char*>(&m_size), sizeof(m_size));
_fs.write(reinterpret_cast<char*>(&m_read_count), sizeof(m_read_count));
_fs.write(reinterpret_cast<char*>(&m_write_count), sizeof(m_write_count));
_fs.write(reinterpret_cast<char*>(m_ptr), m_size * sizeof(char));
}
//
void
ring_buffer::load(std::fstream& _fs)
{
destroy();
_fs.read(reinterpret_cast<char*>(&m_use_mmap), sizeof(m_use_mmap));
_fs.read(reinterpret_cast<char*>(&m_use_mmap_explicit), sizeof(m_use_mmap_explicit));
_fs.read(reinterpret_cast<char*>(&m_size), sizeof(m_size));
init(m_size);
if(!m_ptr) m_ptr = malloc(m_size);
_fs.read(reinterpret_cast<char*>(&m_read_count), sizeof(m_read_count));
_fs.read(reinterpret_cast<char*>(&m_write_count), sizeof(m_write_count));
_fs.read(reinterpret_cast<char*>(m_ptr), m_size * sizeof(char));
}
} // namespace base
} // namespace container
} // namespace common
} // namespace rocprofiler
+495
Просмотреть файл
@@ -0,0 +1,495 @@
// 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.
#pragma once
#include "lib/common/environment.hpp"
#include "lib/common/units.hpp"
#include <algorithm>
#include <cmath>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <utility>
#include <vector>
namespace rocprofiler
{
namespace common
{
namespace container
{
template <typename Tp>
struct ring_buffer;
//
namespace base
{
/// \struct tim::base::ring_buffer
/// \brief Ring buffer implementation, with support for mmap as backend (Linux only).
struct ring_buffer
{
template <typename Tp>
friend struct container::ring_buffer;
ring_buffer() = default;
explicit ring_buffer(bool _use_mmap) { set_use_mmap(_use_mmap); }
explicit ring_buffer(size_t _size) { init(_size); }
ring_buffer(size_t _size, bool _use_mmap);
~ring_buffer();
ring_buffer(const ring_buffer&);
ring_buffer& operator=(const ring_buffer&);
ring_buffer(ring_buffer&&) noexcept;
ring_buffer& operator=(ring_buffer&&) noexcept;
/// Returns whether the buffer has been allocated
bool is_initialized() const { return m_init; }
/// Get the total number of bytes supported
size_t capacity() const { return m_size; }
/// Creates new ring buffer.
void init(size_t size);
/// Destroy ring buffer.
void destroy();
/// Write class-type data to buffer (uses placement new).
template <typename Tp>
std::pair<size_t, Tp*> write(Tp* in, std::enable_if_t<std::is_class<Tp>::value, int> = 0);
/// Write non-class-type data to buffer (uses memcpy).
template <typename Tp>
std::pair<size_t, Tp*> write(Tp* in, std::enable_if_t<!std::is_class<Tp>::value, int> = 0);
/// Request a pointer to an allocation. This is similar to a "write" except the
/// memory is uninitialized. Typically used by allocators. If Tp is a class type,
/// be sure to use a placement new instead of a memcpy.
template <typename Tp>
Tp* request();
/// Request a pointer to an allocation for at least \param n bytes.
void* request(size_t n);
/// Read class-type data from buffer (uses placement new).
template <typename Tp>
std::pair<size_t, Tp*> read(Tp* out, std::enable_if_t<std::is_class<Tp>::value, int> = 0) const;
/// Read non-class-type data from buffer (uses memcpy).
template <typename Tp>
std::pair<size_t, Tp*> read(Tp* out,
std::enable_if_t<!std::is_class<Tp>::value, int> = 0) const;
/// Retrieve a pointer to the head allocation (read).
template <typename Tp>
Tp* retrieve();
/// Retrieve a pointer to the head allocation of at least \param n bytes (read).
void* retrieve(size_t n);
/// Returns number of bytes currently held by the buffer.
size_t count() const { return (m_write_count - m_read_count); }
/// Returns how many bytes are availiable in the buffer.
size_t free() const { return (m_size - count()); }
/// Returns if the buffer is empty.
bool is_empty() const { return (count() == 0); }
/// Returns if the buffer is full.
bool is_full() const { return (count() == m_size); }
/// Rewind the read position n bytes
size_t rewind(size_t n) const;
/// explicitly configure to use mmap if avail
void set_use_mmap(bool);
/// query whether using mmap
bool get_use_mmap() const { return m_use_mmap; }
std::string as_string() const;
void save(std::fstream& _fs);
void load(std::fstream& _fs);
friend std::ostream& operator<<(std::ostream& os, const ring_buffer& obj)
{
return os << obj.as_string();
}
private:
/// Returns the current write pointer.
void* write_ptr() const { return static_cast<char*>(m_ptr) + (m_write_count % m_size); }
/// Returns the current read pointer.
void* read_ptr() const { return static_cast<char*>(m_ptr) + (m_read_count % m_size); }
void reset();
private:
bool m_init = false;
bool m_use_mmap = true;
bool m_use_mmap_explicit = false;
void* m_ptr = nullptr;
size_t m_size = 0;
mutable size_t m_read_count = 0;
size_t m_write_count = 0;
};
//
template <typename Tp>
std::pair<size_t, Tp*>
ring_buffer::write(Tp* in, std::enable_if_t<std::is_class<Tp>::value, int>)
{
if(in == nullptr || m_ptr == nullptr) return {0, nullptr};
auto _length = sizeof(Tp);
// Make sure we don't put in more than there's room for, by writing no
// more than there is free.
if(_length > free())
throw std::runtime_error("heap-buffer-overflow :: ring buffer is full. read data "
"to avoid data corruption");
// if write count is at the tail of buffer, bump to the end of buffer
auto _modulo = m_size - (m_write_count % m_size);
if(_modulo < _length) m_write_count += _modulo;
// pointer in buffer
Tp* out = reinterpret_cast<Tp*>(write_ptr());
// Copy in.
new((void*) out) Tp{std::move(*in)};
// Update write count
m_write_count += _length;
return {_length, out};
}
//
template <typename Tp>
std::pair<size_t, Tp*>
ring_buffer::write(Tp* in, std::enable_if_t<!std::is_class<Tp>::value, int>)
{
if(in == nullptr || m_ptr == nullptr) return {0, nullptr};
auto _length = sizeof(Tp);
// Make sure we don't put in more than there's room for, by writing no
// more than there is free.
if(_length > free())
throw std::runtime_error("heap-buffer-overflow :: ring buffer is full. read data "
"to avoid data corruption");
// if write count is at the tail of buffer, bump to the end of buffer
auto _modulo = m_size - (m_write_count % m_size);
if(_modulo < _length) m_write_count += _modulo;
// pointer in buffer
Tp* out = reinterpret_cast<Tp*>(write_ptr());
// Copy in.
memcpy((void*) out, in, _length);
// Update write count
m_write_count += _length;
return {_length, out};
}
//
template <typename Tp>
Tp*
ring_buffer::request()
{
if(m_ptr == nullptr) return nullptr;
auto _length = sizeof(Tp);
// Make sure we don't put in more than there's room for, by writing no
// more than there is free.
if(_length > free())
throw std::runtime_error("heap-buffer-overflow :: ring buffer is full. read data "
"to avoid data corruption");
// if write count is at the tail of buffer, bump to the end of buffer
auto _modulo = m_size - (m_write_count % m_size);
if(_modulo < _length) m_write_count += _modulo;
// pointer in buffer
Tp* _out = reinterpret_cast<Tp*>(write_ptr());
// Update write count
m_write_count += _length;
return _out;
}
//
template <typename Tp>
std::pair<size_t, Tp*>
ring_buffer::read(Tp* out, std::enable_if_t<std::is_class<Tp>::value, int>) const
{
if(is_empty() || out == nullptr) return {0, nullptr};
auto _length = sizeof(Tp);
// Make sure we do not read out more than there is actually in the buffer.
if(_length > count()) throw std::runtime_error("ring buffer is empty");
// if read count is at the tail of buffer, bump to the end of buffer
auto _modulo = m_size - (m_read_count % m_size);
if(_modulo < _length) m_read_count += _modulo;
// pointer in buffer
Tp* in = reinterpret_cast<Tp*>(read_ptr());
// Copy out for BYTE, nothing magic here.
*out = *in;
// Update read count.
m_read_count += _length;
return {_length, in};
}
//
template <typename Tp>
std::pair<size_t, Tp*>
ring_buffer::read(Tp* out, std::enable_if_t<!std::is_class<Tp>::value, int>) const
{
if(is_empty() || out == nullptr) return {0, nullptr};
auto _length = sizeof(Tp);
using Up = typename std::remove_const<Tp>::type;
// Make sure we do not read out more than there is actually in the buffer.
if(_length > count()) throw std::runtime_error("ring buffer is empty");
// if read count is at the tail of buffer, bump to the end of buffer
auto _modulo = m_size - (m_read_count % m_size);
if(_modulo < _length) m_read_count += _modulo;
// pointer in buffer
Tp* in = reinterpret_cast<Tp*>(read_ptr());
// Copy out for BYTE, nothing magic here.
Up* _out = const_cast<Up*>(out);
memcpy(_out, in, _length);
// Update read count.
m_read_count += _length;
return {_length, in};
}
//
template <typename Tp>
Tp*
ring_buffer::retrieve()
{
if(m_ptr == nullptr) return nullptr;
auto _length = sizeof(Tp);
// Make sure we don't put in more than there's room for, by writing no
// more than there is free.
if(_length > count()) throw std::runtime_error("ring buffer is empty");
// if read count is at the tail of buffer, bump to the end of buffer
auto _modulo = m_size - (m_read_count % m_size);
if(_modulo < _length) m_read_count += _modulo;
// pointer in buffer
Tp* _out = reinterpret_cast<Tp*>(read_ptr());
// Update write count
m_read_count += _length;
return _out;
}
//
} // namespace base
///
/// \struct rocprofiler::container::ring_buffer
/// \brief Ring buffer wrapper around \ref tim::base::ring_buffer for data of type Tp. If
/// the data object size is larger than the page size (typically 4KB), behavior is
/// undefined. During initialization, one requests a minimum number of objects and the
/// buffer will support that number of object + the remainder of the page, e.g. if a page
/// is 1000 bytes, the object is 1 byte, and the buffer is requested to support 1500
/// objects, then an allocation supporting 2000 objects (i.e. 2 pages) will be created.
template <typename Tp>
struct ring_buffer : private base::ring_buffer
{
using base_type = base::ring_buffer;
static size_t get_items_per_page();
ring_buffer() = default;
~ring_buffer() = default;
explicit ring_buffer(bool _use_mmap)
: base_type{_use_mmap}
{}
explicit ring_buffer(size_t _size)
: base_type{_size * sizeof(Tp)}
{}
ring_buffer(size_t _size, bool _use_mmap)
: base_type{_size * sizeof(Tp), _use_mmap}
{}
ring_buffer(const ring_buffer&);
ring_buffer(ring_buffer&&) noexcept = default;
ring_buffer& operator=(const ring_buffer&);
ring_buffer& operator=(ring_buffer&&) noexcept = default;
/// Returns whether the buffer has been allocated
bool is_initialized() const { return base_type::is_initialized(); }
/// Get the total number of Tp instances supported
size_t capacity() const { return (base_type::capacity()) / sizeof(Tp); }
/// Creates new ring buffer.
void init(size_t _size) { base_type::init(_size * sizeof(Tp)); }
/// Destroy ring buffer.
void destroy() { base_type::destroy(); }
/// Write data to buffer.
size_t data_size() const { return sizeof(Tp); }
/// Write data to buffer. Return pointer to location of write
Tp* write(Tp* in) { return base_type::write<Tp>(in).second; }
/// Read data from buffer. Return pointer to location of read
Tp* read(Tp* out) const { return base_type::read<Tp>(out).second; }
/// Get an uninitialized address at tail of buffer.
Tp* request() { return base_type::request<Tp>(); }
/// Read data from head of buffer.
Tp* retrieve() { return base_type::retrieve<Tp>(); }
/// Returns number of Tp instances currently held by the buffer.
size_t count() const { return (base_type::count()) / sizeof(Tp); }
/// Returns how many Tp instances are availiable in the buffer.
size_t free() const { return (base_type::free()) / sizeof(Tp); }
/// Returns if the buffer is empty.
bool is_empty() const { return base_type::is_empty(); }
/// Returns if the buffer is full.
bool is_full() const { return (base_type::free() < sizeof(Tp)); }
/// Rewinds the read pointer
size_t rewind(size_t n) const { return base_type::rewind(n); }
template <typename... Args>
auto emplace(Args&&... args)
{
Tp _obj{std::forward<Args>(args)...};
return write(&_obj);
}
using base_type::get_use_mmap;
using base_type::load;
using base_type::save;
using base_type::set_use_mmap;
std::string as_string() const
{
std::ostringstream ss{};
size_t _w = std::log10(base_type::capacity()) + 1;
ss << std::boolalpha << std::right << "data size: " << std::setw(_w) << data_size()
<< " B, is_initialized: " << std::setw(5) << is_initialized()
<< ", is_empty: " << std::setw(5) << is_empty() << ", is_full: " << std::setw(5)
<< is_full() << ", capacity: " << std::setw(_w) << capacity()
<< ", count: " << std::setw(_w) << count() << ", free: " << std::setw(_w) << free()
<< ", raw capacity: " << std::setw(_w) << base_type::capacity()
<< " B, raw count: " << std::setw(_w) << base_type::count()
<< " B, raw free: " << std::setw(_w) << base_type::free()
<< " B, pointer: " << std::setw(15) << base_type::m_ptr
<< ", raw read count: " << std::setw(_w) << base_type::m_read_count
<< ", raw write count: " << std::setw(_w) << base_type::m_write_count;
return ss.str();
}
friend std::ostream& operator<<(std::ostream& os, const ring_buffer& obj)
{
return os << obj.as_string();
}
};
//
template <typename Tp>
size_t
ring_buffer<Tp>::get_items_per_page()
{
return std::max<size_t>(units::get_page_size() / sizeof(Tp), 1);
}
//
template <typename Tp>
ring_buffer<Tp>::ring_buffer(const ring_buffer<Tp>& rhs)
: base_type{rhs}
{
size_t _n = rhs.count();
char* _end = static_cast<char*>(rhs.m_ptr) + rhs.m_size;
for(size_t i = 0; i < _n; ++i)
{
char* _addr = static_cast<char*>(rhs.read_ptr()) + (i * sizeof(Tp));
if((_addr + sizeof(Tp)) > _end) _addr = static_cast<char*>(rhs.m_ptr);
Tp* _in = static_cast<Tp*>(static_cast<void*>(_addr));
write(_in);
}
}
//
template <typename Tp>
ring_buffer<Tp>&
ring_buffer<Tp>::operator=(const ring_buffer<Tp>& rhs)
{
if(this == &rhs) return *this;
base_type::operator=(rhs);
size_t _n = rhs.count();
char* _end = static_cast<char*>(rhs.m_ptr) + rhs.m_size;
for(size_t i = 0; i < _n; ++i)
{
char* _addr = static_cast<char*>(rhs.read_ptr()) + (i * sizeof(Tp));
if((_addr + sizeof(Tp)) > _end) _addr = static_cast<char*>(rhs.m_ptr);
Tp* _in = static_cast<Tp*>(static_cast<void*>(_addr));
write(_in);
}
return *this;
}
//
} // namespace container
} // namespace common
} // namespace rocprofiler
+389
Просмотреть файл
@@ -0,0 +1,389 @@
// 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 "lib/common/container/operators.hpp"
#include "lib/common/container/static_vector.hpp"
#include <algorithm>
#include <initializer_list>
#include <iterator>
#include <memory>
#include <numeric>
#include <type_traits>
#include <vector>
namespace rocprofiler
{
namespace common
{
namespace container
{
template <typename Tp, size_t ChunkSizeV = 64>
class stable_vector
{
public:
using value_type = Tp;
using reference = value_type&;
using const_reference = const value_type&;
using pointer = value_type*;
using const_pointer = const value_type*;
using size_type = size_t;
using difference_type = std::ptrdiff_t;
static constexpr const size_t chunk_size = ChunkSizeV;
private:
template <size_t N>
struct is_pow2
{
static constexpr bool value = (N & (N - 1)) == 0;
};
static_assert(ChunkSizeV > 0, "ChunkSize needs to be greater than zero");
static_assert(is_pow2<ChunkSizeV>::value, "ChunkSize needs to be a power of 2");
using this_type = stable_vector<Tp, ChunkSizeV>;
using const_this_type = const stable_vector<Tp, ChunkSizeV>;
template <typename ContainerT>
struct iterator_base
{
iterator_base(ContainerT* c = nullptr, size_type i = 0)
: m_container(c)
, m_index(i)
{}
iterator_base& operator+=(size_type i)
{
m_index += i;
return *this;
}
iterator_base& operator-=(size_type i)
{
m_index -= i;
return *this;
}
iterator_base& operator++()
{
++m_index;
return *this;
}
iterator_base& operator--()
{
--m_index;
return *this;
}
difference_type operator-(const iterator_base& it)
{
assert(m_container == it.m_container);
return m_index - it.m_index;
}
bool operator<(const iterator_base& it) const
{
assert(m_container == it.m_container);
return m_index < it.m_index;
}
bool operator==(const iterator_base& it) const
{
return m_container == it.m_container && m_index == it.m_index;
}
protected:
ContainerT* m_container;
size_type m_index;
};
public:
struct const_iterator;
struct iterator
: public iterator_base<this_type>
//, std::iterator<std::random_access_iterator_tag, value_type>
, public random_access_iterator_helper<iterator, value_type>
{
using iterator_base<this_type>::iterator_base;
friend struct const_iterator;
reference operator*() { return (*this->m_container)[this->m_index]; }
};
struct const_iterator
: public iterator_base<const_this_type>
//, std::iterator<std::random_access_iterator_tag, const value_type>
, public random_access_iterator_helper<const_iterator, const value_type>
{
using iterator_base<const_this_type>::iterator_base;
explicit const_iterator(const iterator& it)
: iterator_base<const_this_type>(it.m_container, it.m_index)
{}
const_reference operator*() const { return (*this->m_container)[this->m_index]; }
bool operator==(const const_iterator& it) const
{
return iterator_base<const_this_type>::operator==(it);
}
friend bool operator==(const iterator& l, const const_iterator& r) { return r == l; }
};
stable_vector() = default;
explicit stable_vector(size_type count, const Tp& value);
explicit stable_vector(size_type count);
template <typename InputItrT,
typename = std::enable_if_t<
std::is_convertible<typename std::iterator_traits<InputItrT>::iterator_category,
std::input_iterator_tag>::value>>
stable_vector(InputItrT first, InputItrT last);
explicit stable_vector(std::initializer_list<Tp>);
stable_vector(const stable_vector& other);
stable_vector(stable_vector&& other) noexcept;
stable_vector& operator=(stable_vector v);
iterator begin() noexcept { return {this, 0}; }
const_iterator begin() const noexcept { return {this, 0}; }
const_iterator cbegin() const noexcept { return begin(); }
iterator end() noexcept { return {this, size()}; }
const_iterator end() const noexcept { return {this, size()}; }
const_iterator cend() const noexcept { return end(); }
size_type size() const noexcept
{
return empty() ? 0 : (m_chunks.size() - 1) * ChunkSizeV + m_chunks.back()->size();
}
size_type max_size() const noexcept { return std::numeric_limits<size_type>::max(); }
size_type capacity() const noexcept { return m_chunks.size() * ChunkSizeV; }
bool empty() const noexcept { return m_chunks.size() == 0; }
void reserve(size_type new_capacity);
void shrink_to_fit() noexcept {}
bool operator==(const this_type& c) const
{
return size() == c.size() && std::equal(cbegin(), cend(), c.cbegin());
}
bool operator!=(const this_type& c) const { return !operator==(c); }
void swap(this_type& v) { std::swap(m_chunks, v.m_chunks); }
friend void swap(this_type& l, this_type& r) { l.swap(r); }
reference front() { return m_chunks.front()->front(); }
const_reference front() const { return front(); }
reference back() { return m_chunks.back()->back(); }
const_reference back() const { return back(); }
void push_back(const Tp& t);
void push_back(Tp&& t);
template <typename... Args>
void emplace_back(Args&&... args);
reference operator[](size_type i);
const_reference operator[](size_type i) const;
reference at(size_type i);
const_reference at(size_type i) const;
private:
using chunk_type = container::static_vector<Tp, ChunkSizeV, true>;
using storage_type = std::vector<std::unique_ptr<chunk_type>>;
void add_chunk();
chunk_type& last_chunk();
storage_type m_chunks;
};
template <typename Tp, size_t ChunkSizeV>
stable_vector<Tp, ChunkSizeV>::stable_vector(size_type count, const Tp& value)
{
for(size_type i = 0; i < count; ++i)
{
push_back(value);
}
}
template <typename Tp, size_t ChunkSizeV>
stable_vector<Tp, ChunkSizeV>::stable_vector(size_type count)
{
for(size_type i = 0; i < count; ++i)
{
emplace_back();
}
}
template <typename Tp, size_t ChunkSizeV>
template <typename InputItrT, typename>
stable_vector<Tp, ChunkSizeV>::stable_vector(InputItrT first, InputItrT last)
{
for(; first != last; ++first)
{
push_back(*first);
}
}
template <typename Tp, size_t ChunkSizeV>
stable_vector<Tp, ChunkSizeV>::stable_vector(const stable_vector& other)
{
for(const auto& chunk : other.m_chunks)
{
m_chunks.emplace_back(std::make_unique<chunk_type>(*chunk));
}
}
template <typename Tp, size_t ChunkSizeV>
stable_vector<Tp, ChunkSizeV>::stable_vector(stable_vector&& other) noexcept
: m_chunks(std::move(other.m_chunks))
{}
template <typename Tp, size_t ChunkSizeV>
stable_vector<Tp, ChunkSizeV>::stable_vector(std::initializer_list<Tp> ilist)
{
for(const auto& t : ilist)
{
push_back(t);
}
}
template <typename Tp, size_t ChunkSizeV>
stable_vector<Tp, ChunkSizeV>&
stable_vector<Tp, ChunkSizeV>::operator=(stable_vector v)
{
swap(v);
return *this;
}
template <typename Tp, size_t ChunkSizeV>
void
stable_vector<Tp, ChunkSizeV>::add_chunk()
{
m_chunks.emplace_back(std::make_unique<chunk_type>());
}
template <typename Tp, size_t ChunkSizeV>
typename stable_vector<Tp, ChunkSizeV>::chunk_type&
stable_vector<Tp, ChunkSizeV>::last_chunk()
{
if(ROCPROFILER_UNLIKELY(m_chunks.empty() || m_chunks.back()->size() == ChunkSizeV))
{
add_chunk();
}
return *m_chunks.back();
}
template <typename Tp, size_t ChunkSizeV>
void
stable_vector<Tp, ChunkSizeV>::reserve(size_type new_capacity)
{
const size_t initial_capacity = capacity();
for(difference_type i = new_capacity - initial_capacity; i > 0; i -= ChunkSizeV)
{
add_chunk();
}
}
template <typename Tp, size_t ChunkSizeV>
void
stable_vector<Tp, ChunkSizeV>::push_back(const Tp& t)
{
last_chunk().push_back(t);
}
template <typename Tp, size_t ChunkSizeV>
void
stable_vector<Tp, ChunkSizeV>::push_back(Tp&& t)
{
last_chunk().push_back(std::move(t));
}
template <typename Tp, size_t ChunkSizeV>
template <typename... Args>
void
stable_vector<Tp, ChunkSizeV>::emplace_back(Args&&... args)
{
last_chunk().emplace_back(std::forward<Args>(args)...);
}
template <typename Tp, size_t ChunkSizeV>
typename stable_vector<Tp, ChunkSizeV>::reference
stable_vector<Tp, ChunkSizeV>::operator[](size_type i)
{
return (*m_chunks[i / ChunkSizeV])[i % ChunkSizeV];
}
template <typename Tp, size_t ChunkSizeV>
typename stable_vector<Tp, ChunkSizeV>::const_reference
stable_vector<Tp, ChunkSizeV>::operator[](size_type i) const
{
return const_cast<this_type&>(*this)[i];
}
template <typename Tp, size_t ChunkSizeV>
typename stable_vector<Tp, ChunkSizeV>::reference
stable_vector<Tp, ChunkSizeV>::at(size_type i)
{
if(ROCPROFILER_UNLIKELY(i >= size()))
{
throw ::rocprofiler::exception<std::out_of_range>("stable_vector::at(" + std::to_string(i) +
"). size is " + std::to_string(size()));
}
return operator[](i);
}
template <typename Tp, size_t ChunkSizeV>
typename stable_vector<Tp, ChunkSizeV>::const_reference
stable_vector<Tp, ChunkSizeV>::at(size_type i) const
{
return const_cast<this_type&>(*this).at(i);
}
template <typename Tp, size_t ChunkSizeV, typename... Args>
auto
resize(stable_vector<Tp, ChunkSizeV>& _v, size_t _n, Args&&... args)
{
if(_n > _v.capacity()) _v.reserve(_n);
while(_v.size() < _n)
_v.emplace_back(std::forward<Args>(args)...);
return _v.size();
}
} // namespace container
} // namespace common
} // namespace rocprofiler
+221
Просмотреть файл
@@ -0,0 +1,221 @@
// 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 "lib/common/container/c_array.hpp"
#include <array>
#include <atomic>
#include <cstdlib>
#include <initializer_list>
#include <cstddef>
namespace rocprofiler
{
namespace common
{
namespace container
{
template <typename Tp, size_t N, bool AtomicSizeV = false>
struct static_vector
{
using count_type = std::conditional_t<AtomicSizeV, std::atomic<size_t>, size_t>;
using this_type = static_vector<Tp, N>;
using value_type = Tp;
static_vector() = default;
static_vector(const static_vector&) = default;
static_vector(static_vector&&) noexcept = default;
static_vector& operator=(const static_vector&) = default;
static_vector& operator=(static_vector&&) noexcept = default;
explicit static_vector(size_t _n, Tp _v = {});
explicit static_vector(c_array<Tp>&&);
template <size_t M>
explicit static_vector(std::array<Tp, M>&&);
static_vector& operator=(std::initializer_list<Tp>&& _v);
static_vector& operator=(std::pair<std::array<Tp, N>, size_t>&&);
template <typename... Args>
value_type& emplace_back(Args&&... _v);
template <typename Up>
decltype(auto) push_back(Up&& _v)
{
return emplace_back(Tp{std::forward<Up>(_v)});
}
void pop_back() { --m_size; }
void clear();
void reserve(size_t) noexcept {}
void shrink_to_fit() noexcept {}
auto capacity() noexcept { return N; }
size_t size() const { return m_size; }
bool empty() const { return (size() == 0); }
auto begin() { return m_data.begin(); }
auto begin() const { return m_data.begin(); }
auto cbegin() const { return m_data.cbegin(); }
auto end() { return m_data.begin() + size(); }
auto end() const { return m_data.begin() + size(); }
auto cend() const { return m_data.cbegin() + size(); }
decltype(auto) operator[](size_t _idx) { return m_data[_idx]; }
decltype(auto) operator[](size_t _idx) const { return m_data[_idx]; }
decltype(auto) at(size_t _idx) { return m_data.at(_idx); }
decltype(auto) at(size_t _idx) const { return m_data.at(_idx); }
decltype(auto) front() { return m_data.front(); }
decltype(auto) front() const { return m_data.front(); }
decltype(auto) back() { return *(m_data.begin() + size() - 1); }
decltype(auto) back() const { return *(m_data.begin() + size() - 1); }
auto* data() { return m_data.data(); }
const auto* data() const { return m_data.data(); }
void swap(this_type& _v);
friend void swap(this_type& _lhs, this_type& _rhs) { _lhs.swap(_rhs); }
private:
void update_size(size_t);
private:
count_type m_size = count_type{0};
std::array<Tp, N> m_data = {};
};
template <typename Tp, size_t N, bool AtomicSizeV>
static_vector<Tp, N, AtomicSizeV>::static_vector(size_t _n, Tp _v)
{
m_data.fill(_v);
update_size(_n);
}
template <typename Tp, size_t N, bool AtomicSizeV>
static_vector<Tp, N, AtomicSizeV>::static_vector(c_array<Tp>&& _v)
{
auto _n = std::min<size_t>(N, _v.size());
for(size_t i = 0; i < _n; ++i, ++m_size)
m_data[i] = _v[i];
}
template <typename Tp, size_t N, bool AtomicSizeV>
template <size_t M>
static_vector<Tp, N, AtomicSizeV>::static_vector(std::array<Tp, M>&& _v)
{
auto _n = std::min<size_t>(N, M);
for(size_t i = 0; i < _n; ++i, ++m_size)
m_data[i] = _v[i];
}
template <typename Tp, size_t N, bool AtomicSizeV>
static_vector<Tp, N, AtomicSizeV>&
static_vector<Tp, N, AtomicSizeV>::operator=(std::initializer_list<Tp>&& _v)
{
if(ROCPROFILER_UNLIKELY(_v.size() > N))
{
throw exception<std::out_of_range>(
std::string{"static_vector::operator=(initializer_list) size > "} + std::to_string(N));
}
clear();
for(auto&& itr : _v)
m_data[m_size++] = itr;
return *this;
}
template <typename Tp, size_t N, bool AtomicSizeV>
static_vector<Tp, N, AtomicSizeV>&
static_vector<Tp, N, AtomicSizeV>::operator=(std::pair<std::array<Tp, N>, size_t>&& _v)
{
update_size(0);
m_data = std::move(_v.first);
update_size(_v.second);
return *this;
}
template <typename Tp, size_t N, bool AtomicSizeV>
void
static_vector<Tp, N, AtomicSizeV>::clear()
{
update_size(0);
}
template <typename Tp, size_t N, bool AtomicSizeV>
void
static_vector<Tp, N, AtomicSizeV>::swap(this_type& _v)
{
if constexpr(AtomicSizeV)
{
auto _t_size = m_size;
auto _v_size = _v.m_size;
std::swap(m_data, _v.m_data);
update_size(_v_size);
_v.update_size(_t_size);
}
else
{
std::swap(m_size, _v.m_size);
std::swap(m_data, _v.m_data);
}
}
template <typename Tp, size_t N, bool AtomicSizeV>
template <typename... Args>
Tp&
static_vector<Tp, N, AtomicSizeV>::emplace_back(Args&&... _v)
{
auto _idx = m_size++;
if(_idx >= N)
{
throw exception<std::out_of_range>(
std::string{"static_vector::emplace_back - reached capacity "} + std::to_string(N));
}
if constexpr(std::is_assignable<Tp, decltype(std::forward<Args>(_v))...>::value)
m_data[_idx] = {std::forward<Args>(_v)...};
else
m_data[_idx] = Tp{std::forward<Args>(_v)...};
return m_data[_idx];
}
template <typename Tp, size_t N, bool AtomicSizeV>
void
static_vector<Tp, N, AtomicSizeV>::update_size(size_t _n)
{
if constexpr(AtomicSizeV)
m_size.store(_n);
else
m_size = _n;
}
} // namespace container
} // namespace common
} // namespace rocprofiler
+65
Просмотреть файл
@@ -0,0 +1,65 @@
// Copyright (c) 2018-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
#define ROCPROFILER_ATTRIBUTE(...) __attribute__((__VA_ARGS__))
#define ROCPROFILER_VISIBILITY(MODE) ROCPROFILER_ATTRIBUTE(visibility(MODE))
#define ROCPROFILER_PUBLIC_API ROCPROFILER_VISIBILITY("default")
#define ROCPROFILER_HIDDEN_API ROCPROFILER_VISIBILITY("hidden")
#define ROCPROFILER_INTERNAL_API ROCPROFILER_VISIBILITY("internal")
#define ROCPROFILER_INLINE ROCPROFILER_ATTRIBUTE(always_inline) inline
#define ROCPROFILER_NOINLINE ROCPROFILER_ATTRIBUTE(noinline)
#define ROCPROFILER_HOT ROCPROFILER_ATTRIBUTE(hot)
#define ROCPROFILER_COLD ROCPROFILER_ATTRIBUTE(cold)
#define ROCPROFILER_CONST ROCPROFILER_ATTRIBUTE(const)
#define ROCPROFILER_PURE ROCPROFILER_ATTRIBUTE(pure)
#define ROCPROFILER_WEAK ROCPROFILER_ATTRIBUTE(weak)
#define ROCPROFILER_PACKED ROCPROFILER_ATTRIBUTE(__packed__)
#define ROCPROFILER_PACKED_ALIGN(VAL) ROCPROFILER_PACKED ROCPROFILER_ATTRIBUTE(__aligned__(VAL))
#define ROCPROFILER_LIKELY(...) __builtin_expect((__VA_ARGS__), 1)
#define ROCPROFILER_UNLIKELY(...) __builtin_expect((__VA_ARGS__), 0)
#if defined(ROCPROFILER_CI) && ROCPROFILER_CI > 0
# if defined(NDEBUG)
# undef NDEBUG
# endif
# if !defined(DEBUG)
# define DEBUG 1
# endif
# if defined(__cplusplus)
# include <cassert>
# else
# include <assert.h>
# endif
#endif
#define ROCPROFILER_STRINGIZE(X) ROCPROFILER_STRINGIZE2(X)
#define ROCPROFILER_STRINGIZE2(X) #X
#define ROCPROFILER_VAR_NAME_COMBINE(X, Y) X##Y
#define ROCPROFILER_VARIABLE(X, Y) ROCPROFILER_VAR_NAME_COMBINE(X, Y)
#define ROCPROFILER_LINESTR ROCPROFILER_STRINGIZE(__LINE__)
#define ROCPROFILER_ESC(...) __VA_ARGS__
#if defined(__cplusplus)
# if !defined(ROCPROFILER_FOLD_EXPRESSION)
# define ROCPROFILER_FOLD_EXPRESSION(...) ((__VA_ARGS__), ...)
# endif
#endif
+185
Просмотреть файл
@@ -0,0 +1,185 @@
// 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 "lib/common/log.hpp"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <type_traits>
#include <unistd.h>
#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
{
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};
}
inline std::string
get_env_impl(std::string_view env_id, const char* _default)
{
return get_env_impl(env_id, std::string_view{_default});
}
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;
}
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
template <typename Tp>
inline auto
get_env(std::string_view env_id, Tp&& _default)
{
if constexpr(std::is_enum<Tp>::value)
{
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)));
}
else
{
return get_env_impl(env_id, std::forward<Tp>(_default));
}
}
struct env_config
{
std::string env_name = {};
std::string env_value = {};
int override = 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);
}
};
} // namespace common
} // namespace rocprofiler
+373
Просмотреть файл
@@ -0,0 +1,373 @@
/* Copyright (c) 2022 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/helper.hpp"
#include <amd_comgr/amd_comgr.h>
#include <cstdio>
#include <cstdarg>
#include <cstring>
#include <cxxabi.h>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <set>
#define ENABLE_BACKTRACE
#if defined(ENABLE_BACKTRACE)
# include <backtrace.h>
#endif
#define amd_comgr_(call) \
do \
{ \
if(amd_comgr_status_t status = amd_comgr_##call; status != AMD_COMGR_STATUS_SUCCESS) \
{ \
const char* reason = ""; \
amd_comgr_status_string(status, &reason); \
fprintf(stderr, #call " failed: %s\n", reason); \
abort(); \
} \
} while(false)
namespace rocprofiler
{
namespace common
{
std::string
cxa_demangle(std::string_view _mangled_name, int* _status)
{
constexpr size_t buffer_len = 4096;
// return the mangled since there is no buffer
if(_mangled_name.empty())
{
*_status = -2;
return std::string{};
}
auto _demangled_name = std::string{_mangled_name};
// PARAMETERS to __cxa_demangle
// mangled_name:
// A NULL-terminated character string containing the name to be demangled.
// buffer:
// A region of memory, allocated with malloc, of *length bytes, into which the
// demangled name is stored. If output_buffer is not long enough, it is expanded
// using realloc. output_buffer may instead be NULL; in that case, the demangled
// name is placed in a region of memory allocated with malloc.
// _buflen:
// If length is non-NULL, the length of the buffer containing the demangled name
// is placed in *length.
// status:
// *status is set to one of the following values
size_t _demang_len = 0;
char* _demang = abi::__cxa_demangle(_demangled_name.c_str(), nullptr, &_demang_len, _status);
switch(*_status)
{
// 0 : The demangling operation succeeded.
// -1 : A memory allocation failure occurred.
// -2 : mangled_name is not a valid name under the C++ ABI mangling rules.
// -3 : One of the arguments is invalid.
case 0:
{
if(_demang) _demangled_name = std::string{_demang};
break;
}
case -1:
{
char _msg[buffer_len];
::memset(_msg, '\0', buffer_len * sizeof(char));
::snprintf(_msg,
buffer_len,
"memory allocation failure occurred demangling %s",
_demangled_name.c_str());
::perror(_msg);
break;
}
case -2: break;
case -3:
{
char _msg[buffer_len];
::memset(_msg, '\0', buffer_len * sizeof(char));
::snprintf(_msg,
buffer_len,
"Invalid argument in: (\"%s\", nullptr, nullptr, %p)",
_demangled_name.c_str(),
(void*) _status);
::perror(_msg);
break;
}
default: break;
};
// if it "demangled" but the length is zero, set the status to -2
if(_demang_len == 0 && *_status == 0) *_status = -2;
// free allocated buffer
::free(_demang);
return _demangled_name;
}
namespace
{
#if defined(ENABLE_BACKTRACE)
// struct BackTraceInfo
// {
// struct ::backtrace_state* state = nullptr;
// std::stringstream sstream{};
// int depth = 0;
// int error = 0;
// };
// void
// errorCallback(void* data, const char* message, int errnum)
// {
// BackTraceInfo* info = static_cast<BackTraceInfo*>(data);
// info->sstream << "ROCProfiler: error: " << message << '(' << errnum << ')';
// info->error = 1;
// }
// void
// syminfoCallback(void* data,
// uintptr_t /* pc */,
// const char* symname,
// uintptr_t /* symval */,
// uintptr_t /* symsize */)
// {
// BackTraceInfo* info = static_cast<BackTraceInfo*>(data);
// if(symname == nullptr) return;
// int status = 0;
// auto&& _demangled = cxa_demangle(symname, &status);
// info->sstream << ' '
// << (status == 0 ? std::string_view{_demangled} : std::string_view{symname});
// }
// 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'*/
std::string
truncate_name(std::string_view name)
{
auto rit = name.rbegin();
auto rend = name.rend();
uint32_t counter = 0;
char open_token = 0;
char close_token = 0;
while(rit != rend)
{
if(counter == 0)
{
switch(*rit)
{
case ')':
counter = 1;
open_token = ')';
close_token = '(';
break;
case '>':
counter = 1;
open_token = '>';
close_token = '<';
break;
case ']':
counter = 1;
open_token = ']';
close_token = '[';
break;
case ' ': ++rit; continue;
}
if(counter == 0) break;
}
else
{
if(*rit == open_token) counter++;
if(*rit == close_token) counter--;
}
++rit;
}
auto rbeg = rit;
while((rit != rend) && (*rit != ' ') && (*rit != ':'))
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
+68
Просмотреть файл
@@ -0,0 +1,68 @@
/* Copyright (c) 2022 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 <cstdio>
#include <cstdarg>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <cxxabi.h>
namespace rocprofiler
{
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
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);
} // namespace common
} // namespace rocprofiler
+183
Просмотреть файл
@@ -0,0 +1,183 @@
// 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
+140
Просмотреть файл
@@ -0,0 +1,140 @@
// 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 rhs
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR rhsWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR rhs 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
+376
Просмотреть файл
@@ -0,0 +1,376 @@
// 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 "lib/common/environment.hpp"
#include <cctype>
#include <cstdint>
#include <cstdlib>
#include <iostream>
#include <string>
#include <tuple>
#include <unordered_set>
#include <unistd.h>
namespace rocprofiler
{
namespace common
{
namespace units
{
static constexpr int64_t nsec = 1;
static constexpr int64_t usec = 1000 * nsec;
static constexpr int64_t msec = 1000 * usec;
static constexpr int64_t csec = 10 * msec;
static constexpr int64_t dsec = 10 * csec;
static constexpr int64_t sec = 10 * dsec;
static constexpr int64_t minute = 60 * sec;
static constexpr int64_t hour = 60 * minute;
static constexpr int64_t byte = 1;
static constexpr int64_t kilobyte = 1000 * byte;
static constexpr int64_t megabyte = 1000 * kilobyte;
static constexpr int64_t gigabyte = 1000 * megabyte;
static constexpr int64_t terabyte = 1000 * gigabyte;
static constexpr int64_t petabyte = 1000 * terabyte;
static constexpr int64_t kibibyte = 1024 * byte;
static constexpr int64_t mebibyte = 1024 * kibibyte;
static constexpr int64_t gibibyte = 1024 * mebibyte;
static constexpr int64_t tebibyte = 1024 * gibibyte;
static constexpr int64_t pebibyte = 1024 * tebibyte;
static constexpr int64_t B = 1;
static constexpr int64_t KB = 1000 * B;
static constexpr int64_t MB = 1000 * KB;
static constexpr int64_t GB = 1000 * MB;
static constexpr int64_t TB = 1000 * GB;
static constexpr int64_t PB = 1000 * TB;
static constexpr int64_t Bi = 1;
static constexpr int64_t KiB = 1024 * Bi;
static constexpr int64_t MiB = 1024 * KiB;
static constexpr int64_t GiB = 1024 * MiB;
static constexpr int64_t TiB = 1024 * GiB;
static constexpr int64_t PiB = 1024 * TiB;
static constexpr int64_t nanowatt = 1;
static constexpr int64_t microwatt = 1000 * nanowatt;
static constexpr int64_t milliwatt = 1000 * microwatt;
static constexpr int64_t watt = 1000 * milliwatt;
static constexpr int64_t kilowatt = 1000 * watt;
static constexpr int64_t megawatt = 1000 * kilowatt;
static constexpr int64_t gigawatt = 1000 * megawatt;
static constexpr int64_t hertz = 1;
static constexpr int64_t kilohertz = 1000 * hertz;
static constexpr int64_t megahertz = 1000 * kilohertz;
static constexpr int64_t gigahertz = 1000 * megahertz;
static constexpr int64_t Hz = 1;
static constexpr int64_t KHz = 1000 * Hz;
static constexpr int64_t MHz = 1000 * KHz;
static constexpr int64_t GHz = 1000 * MHz;
inline int64_t
get_page_size()
{
static auto _pagesz = sysconf(_SC_PAGESIZE);
return _pagesz;
}
const int64_t clocks_per_sec = sysconf(_SC_CLK_TCK);
//--------------------------------------------------------------------------------------//
inline std::string
time_repr(int64_t _unit)
{
switch(_unit)
{
case nsec: return "nsec"; break;
case usec: return "usec"; break;
case msec: return "msec"; break;
case csec: return "csec"; break;
case dsec: return "dsec"; break;
case sec: return "sec"; break;
default: return "UNK"; break;
}
return std::string{};
}
//--------------------------------------------------------------------------------------//
inline std::string
mem_repr(int64_t _unit)
{
switch(_unit)
{
case byte: return "B"; break;
case kilobyte: return "KB"; break;
case megabyte: return "MB"; break;
case gigabyte: return "GB"; break;
case terabyte: return "TB"; break;
case petabyte: return "PB"; break;
case kibibyte: return "KiB"; break;
case mebibyte: return "MiB"; break;
case gibibyte: return "GiB"; break;
case tebibyte: return "TiB"; break;
case pebibyte: return "PiB"; break;
default: return "UNK"; break;
}
return std::string{};
}
//--------------------------------------------------------------------------------------//
inline std::string
freq_repr(int64_t _unit)
{
switch(_unit)
{
case hertz: return "Hz"; break;
case kilohertz: return "KHz"; break;
case megahertz: return "MHz"; break;
case gigahertz: return "GHz"; break;
default: return "UNK"; break;
}
return std::string{};
}
//--------------------------------------------------------------------------------------//
inline std::string
power_repr(int64_t _unit)
{
switch(_unit)
{
case nanowatt: return "nanowatts"; break;
case microwatt: return "microwatts"; break;
case milliwatt: return "milliwatts"; break;
case watt: return "watts"; break;
case kilowatt: return "kilowatts"; break;
case megawatt: return "megawatts"; break;
case gigawatt: return "gigawatts"; break;
default: return "UNK"; break;
}
return std::string{};
}
//--------------------------------------------------------------------------------------//
inline std::tuple<std::string, int64_t>
get_memory_unit(std::string _unit)
{
using string_t = std::string;
using return_type = std::tuple<string_t, int64_t>;
using inner_t = std::tuple<string_t, string_t, int64_t>;
if(_unit.length() == 0) return return_type{"MB", units::megabyte};
for(auto& itr : _unit)
itr = tolower(itr);
for(const auto& itr : {inner_t{"byte", "b", units::byte},
inner_t{"kilobyte", "kb", units::kilobyte},
inner_t{"megabyte", "mb", units::megabyte},
inner_t{"gigabyte", "gb", units::gigabyte},
inner_t{"terabyte", "tb", units::terabyte},
inner_t{"petabyte", "pb", units::petabyte},
inner_t{"kibibyte", "kib", units::KiB},
inner_t{"mebibyte", "mib", units::MiB},
inner_t{"gibibyte", "gib", units::GiB},
inner_t{"tebibyte", "tib", units::TiB},
inner_t{"pebibyte", "pib", units::PiB}})
{
if(_unit == std::get<0>(itr) || _unit == std::get<1>(itr))
{
if(std::get<2>(itr) == units::byte)
return return_type{std::get<0>(itr), std::get<2>(itr)};
return return_type{mem_repr(std::get<2>(itr)), std::get<2>(itr)};
}
}
std::cerr << "Warning!! No memory unit matching \"" << _unit << "\". Using default..."
<< std::endl;
return return_type{"MB", units::megabyte};
}
//--------------------------------------------------------------------------------------//
inline std::tuple<std::string, int64_t>
get_timing_unit(std::string _unit)
{
using string_t = std::string;
using strset_t = std::unordered_set<string_t>;
using return_type = std::tuple<string_t, int64_t>;
using inner_t = std::tuple<string_t, strset_t, int64_t>;
if(_unit.length() == 0) return return_type{"sec", units::sec};
for(auto& itr : _unit)
itr = tolower(itr);
for(const auto& itr :
{inner_t{"nsec", strset_t{"ns", "nanosecond", "nanoseconds"}, units::nsec},
inner_t{"usec", strset_t{"us", "microsecond", "microseconds"}, units::usec},
inner_t{"msec", strset_t{"ms", "millisecond", "milliseconds"}, units::msec},
inner_t{"csec", strset_t{"cs", "centisecond", "centiseconds"}, units::csec},
inner_t{"dsec", strset_t{"ds", "decisecond", "deciseconds"}, units::dsec},
inner_t{"sec", strset_t{"s", "second", "seconds"}, units::sec},
inner_t{"min", strset_t{"minute", "minutes"}, units::minute},
inner_t{"hr", strset_t{"hr", "hour", "hours"}, units::hour}})
{
if(_unit == std::get<0>(itr) || std::get<1>(itr).find(_unit) != std::get<1>(itr).end())
{
return return_type{time_repr(std::get<2>(itr)), std::get<2>(itr)};
}
}
std::cerr << "Warning!! No timing unit matching \"" << _unit << "\". Using default..."
<< std::endl;
return return_type{"sec", units::sec};
}
//--------------------------------------------------------------------------------------//
inline std::tuple<std::string, int64_t>
get_frequncy_unit(std::string _unit)
{
using string_t = std::string;
using return_type = std::tuple<string_t, int64_t>;
using inner_t = std::tuple<string_t, string_t, int64_t>;
if(_unit.length() == 0) return return_type{"MHz", units::megahertz};
for(auto& itr : _unit)
itr = tolower(itr);
for(const auto& itr : {inner_t{"hertz", "hz", units::hertz},
inner_t{"kilohertz", "khz", units::kilohertz},
inner_t{"megahertz", "mhz", units::megahertz},
inner_t{"gigahertz", "ghz", units::gigahertz}})
{
if(_unit == std::get<0>(itr) || _unit == std::get<1>(itr))
{
return return_type{freq_repr(std::get<2>(itr)), std::get<2>(itr)};
}
}
std::cerr << "Warning!! No frequency unit matching \"" << _unit << "\". Using default..."
<< std::endl;
return return_type{"MHz", units::megahertz};
}
//--------------------------------------------------------------------------------------//
inline std::tuple<std::string, int64_t>
get_power_unit(const std::string& _unit)
{
using string_t = std::string;
using return_type = std::tuple<string_t, int64_t>;
using inner_t = std::tuple<string_t, string_t, int64_t>;
if(_unit.length() == 0) return return_type{"watts", units::watt};
auto _lunit = _unit;
for(auto& itr : _lunit)
itr = tolower(itr);
for(const auto& itr : {inner_t{"nanowatt", "nW", units::nanowatt},
inner_t{"microwatt", "uW", units::microwatt},
inner_t{"milliwatt", "mW", units::milliwatt},
inner_t{"watt", "W", units::watt},
inner_t{"kilowatt", "KW", units::kilowatt},
inner_t{"megawatt", "MW", units::megawatt},
inner_t{"gigawatt", "GW", units::gigawatt}})
{
if(_lunit == std::get<0>(itr) || _lunit + "s" == std::get<0>(itr) ||
_unit == std::get<1>(itr))
{
return return_type{power_repr(std::get<2>(itr)), std::get<2>(itr)};
}
}
std::cerr << "Warning!! No power unit matching \"" << _unit << "\". Using default..."
<< std::endl;
return return_type{"watts", units::watt};
}
//--------------------------------------------------------------------------------------//
namespace temperature
{
enum unit_system : int8_t
{
Celsius = 0,
Fahrenheit,
Kelvin
};
template <typename Tp>
Tp
convert(Tp _v, unit_system _from, unit_system _to)
{
switch(_from)
{
case Celsius:
{
switch(_to)
{
case Celsius: return _v;
case Fahrenheit: return static_cast<Tp>((_v * 1.8) + 32);
case Kelvin: return (_v - 273);
}
}
case Fahrenheit:
{
switch(_to)
{
case Celsius: return static_cast<Tp>((_v - 32) / 1.8);
case Fahrenheit: return _v;
case Kelvin: return (_v - 273);
}
}
case Kelvin:
{
switch(_to)
{
case Celsius: return (_v + 273);
case Fahrenheit: return static_cast<Tp>(((_v + 273) * 1.8) + 32);
case Kelvin: return _v;
}
}
}
}
} // namespace temperature
} // namespace units
} // namespace common
} // namespace rocprofiler
+1
Просмотреть файл
@@ -0,0 +1 @@
+30
Просмотреть файл
@@ -0,0 +1,30 @@
set(ROCPROFILER_LIB_HEADERS config_helpers.hpp config_internal.hpp tracer.hpp)
set(ROCPROFILER_LIB_SOURCES config_internal.cpp rocprofiler_config.cpp)
add_library(rocprofiler-library SHARED)
add_library(rocprofiler::rocprofiler-library ALIAS rocprofiler-library)
target_sources(rocprofiler-library PRIVATE ${ROCPROFILER_LIB_SOURCES}
${ROCPROFILER_LIB_HEADERS})
add_subdirectory(hsa)
target_link_libraries(
rocprofiler-library
PUBLIC rocprofiler::rocprofiler-headers
PRIVATE rocprofiler::rocprofiler-build-flags
rocprofiler::rocprofiler-memcheck
rocprofiler::rocprofiler-common-library
rocprofiler::rocprofiler-stdcxxfs
rocprofiler::rocprofiler-dl
rocprofiler::rocprofiler-hip
rocprofiler::rocprofiler-amd-comgr
rocprofiler::rocprofiler-hsa-runtime)
target_compile_definitions(
rocprofiler-library PRIVATE AMD_INTERNAL_BUILD=1 PROF_API_IMPL=1
HIP_PROF_HIP_API_STRING=1 __HIP_PLATFORM_AMD__=1)
set_target_properties(
rocprofiler-library
PROPERTIES OUTPUT_NAME rocprofiler64
SOVERSION ${PROJECT_VERSION_MAJOR}
VERSION ${PROJECT_VERSION})
+107
Просмотреть файл
@@ -0,0 +1,107 @@
#pragma once
#include <rocprofiler/rocprofiler.h>
#include <array>
#include <atomic>
#include <cstddef>
#include <utility>
namespace
{
inline size_t // NOLINTNEXTLINE
get_domain_max_op(rocprofiler_tracer_activity_domain_t _domain)
{
switch(_domain)
{
case ACTIVITY_DOMAIN_NONE: return -1;
case ACTIVITY_DOMAIN_HSA_API: return 0;
case ACTIVITY_DOMAIN_HSA_OPS: return 0;
case ACTIVITY_DOMAIN_HIP_OPS: return 0;
case ACTIVITY_DOMAIN_HIP_API: return 0;
case ACTIVITY_DOMAIN_KFD_API: return -1;
case ACTIVITY_DOMAIN_EXT_API: return -1;
case ACTIVITY_DOMAIN_ROCTX: return 0;
case ACTIVITY_DOMAIN_HSA_EVT: return 0;
case ACTIVITY_DOMAIN_NUMBER: return -1;
}
return -1;
}
template <typename Tp, size_t N = 8>
struct allocator
{
void construct(Tp* const _p, const Tp& _v) const { ::new((void*) _p) Tp{_v}; }
void construct(Tp* const _p, Tp&& _v) const { ::new((void*) _p) Tp{std::move(_v)}; }
void destroy(Tp* const _p) const { _p->~Tp(); }
static constexpr auto size = sizeof(Tp);
using buffer_value_t = char[size];
struct buffer_entry
{
std::atomic_flag flag = ATOMIC_FLAG_INIT;
buffer_value_t value = {};
void* get()
{
if(flag.test_and_set())
{
return &value[0];
}
return nullptr;
}
bool reset(void* p)
{
if(static_cast<void*>(&value[0]) == p)
{
flag.clear();
return true;
}
return false;
}
};
static auto& get_buffer()
{
static auto _v = std::array<buffer_entry, N>{};
return _v;
}
Tp* allocate(const size_t n) const
{
if(n == 0) return nullptr;
if(n == 1)
{
// try an find in buffer for data locality
for(auto& itr : get_buffer())
{
auto* _p = itr.get();
if(_p) return static_cast<Tp*>(_p);
}
}
auto* _p = new char[n * size];
return reinterpret_cast<Tp*>(_p);
}
void deallocate(Tp* const ptr, const size_t /*unused*/) const
{
for(auto& itr : get_buffer())
{
if(itr.reset(ptr)) return;
}
delete ptr;
}
Tp* allocate(const size_t n, const void* const /* hint */) const { return allocate(n); }
void reserve(const size_t) {}
};
} // namespace
+28
Просмотреть файл
@@ -0,0 +1,28 @@
#include "config_internal.hpp"
namespace rocprofiler
{
namespace internal
{
uint64_t
correlation_config::get_unique_record_id()
{
static auto _v = std::atomic<uint64_t>{};
return _v++;
}
bool
domain_config::operator()(rocprofiler_tracer_activity_domain_t _domain) const
{
return ((1 << _domain) & domains) == (1 << _domain);
}
bool
domain_config::operator()(rocprofiler_tracer_activity_domain_t _domain, uint32_t _op) const
{
auto _offset = (_domain * rocprofiler::internal::domain_ops_offset);
return (*this)(_domain) && (opcodes.none() || opcodes.test(_offset + _op));
}
} // namespace internal
} // namespace rocprofiler
+74
Просмотреть файл
@@ -0,0 +1,74 @@
#pragma once
#include <rocprofiler/config.h>
#include <rocprofiler/rocprofiler.h>
#include <array>
#include <atomic>
#include <bitset>
#include <cstddef>
#include <cstdint>
namespace rocprofiler
{
namespace internal
{
// number of bits to reserve all op codes
constexpr size_t domain_ops_offset = ROCPROFILER_DOMAIN_OPS_MAX;
constexpr size_t reserved_domain_size = ROCPROFILER_DOMAIN_OPS_RESERVED * 8;
constexpr size_t max_configs_count = 8;
struct correlation_config
{
uint64_t id = 0;
uint64_t external_id = 0;
::rocprofiler_external_cid_cb_t external_id_callback = nullptr;
static uint64_t get_unique_record_id();
};
struct domain_config
{
::rocprofiler_sync_callback_t user_sync_callback = nullptr;
int64_t domains = 0;
std::bitset<reserved_domain_size> opcodes = {};
/// check if domain is enabled
bool operator()(::rocprofiler_tracer_activity_domain_t) const;
/// check if op in a domain is enabled
bool operator()(::rocprofiler_tracer_activity_domain_t, uint32_t) const;
};
struct buffer_config
{
::rocprofiler_buffer_callback_t callback = nullptr;
uint64_t buffer_size;
// Memory::GenericBuffer* buffer = nullptr;
uint64_t buffer_idx = 0;
};
using filter_config = ::rocprofiler_filter_config;
struct config
{
// size is used to ensure that we never read past the end of the version
size_t size = 0; // = sizeof(rocprofiler_config)
uint32_t compat_version = 0; // set by user
uint32_t api_version = 0; // set by rocprofiler
uint64_t session_idx = 0; // session id index
void* user_data = nullptr; // user data passed to callbacks
correlation_config* correlation_id = nullptr; // &my_cid_config (optional)
buffer_config* buffer = nullptr; // = &my_buffer_config (required)
domain_config* domain = nullptr; // = &my_domain_config (required)
filter_config* filter = nullptr; // = &my_filter_config (optional)
};
std::array<rocprofiler::internal::config*, max_configs_count>&
get_registered_configs();
std::array<std::atomic<rocprofiler::internal::config*>, max_configs_count>&
get_active_configs();
} // namespace internal
} // namespace rocprofiler
+10
Просмотреть файл
@@ -0,0 +1,10 @@
set(ROCPROFILER_LIB_HSA_SOURCES hsa.cpp)
set(ROCPROFILER_LIB_HSA_HEADERS hsa.hpp hsa-defines.hpp hsa-types.h hsa-utils.hpp)
target_sources(rocprofiler-library PRIVATE ${ROCPROFILER_LIB_HSA_SOURCES}
${ROCPROFILER_LIB_HSA_HEADERS})
# add_executable(rocr-example hsa.cpp rocr.hpp) target_link_libraries(rocr-example PRIVATE
# rocprofiler-v2) target_include_directories( rocr-example PRIVATE ${PROJECT_SOURCE_DIR}
# ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/src ${PROJECT_BINARY_DIR}/src)
# target_compile_definitions( rocr-example PRIVATE AMD_INTERNAL_BUILD PROF_API_IMPL
# HIP_PROF_HIP_API_STRING=1 __HIP_PLATFORM_AMD__=1)
+266
Просмотреть файл
@@ -0,0 +1,266 @@
// Copyright (c) 2018-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
#define IMPL_DETAIL_EXPAND(X) X
#define IMPL_DETAIL_FOR_EACH_NARG(...) \
IMPL_DETAIL_FOR_EACH_NARG_(__VA_ARGS__, IMPL_DETAIL_FOR_EACH_RSEQ_N())
#define IMPL_DETAIL_FOR_EACH_NARG_(...) IMPL_DETAIL_EXPAND(IMPL_DETAIL_FOR_EACH_ARG_N(__VA_ARGS__))
#define IMPL_DETAIL_FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, N, ...) N
#define IMPL_DETAIL_FOR_EACH_RSEQ_N() 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#define IMPL_DETAIL_CONCATENATE(X, Y) X##Y
#define IMPL_DETAIL_FOR_EACH_(N, MACRO, PREFIX, ...) \
IMPL_DETAIL_EXPAND(IMPL_DETAIL_CONCATENATE(MACRO, N)(PREFIX, __VA_ARGS__))
#define IMPL_DETAIL_FOR_EACH(MACRO, PREFIX, ...) \
IMPL_DETAIL_FOR_EACH_(IMPL_DETAIL_FOR_EACH_NARG(__VA_ARGS__), MACRO, PREFIX, __VA_ARGS__)
#define MEMBER_0(...)
#define MEMBER_1(PREFIX, FIELD) PREFIX.FIELD
#define MEMBER_2(PREFIX, A, B) MEMBER_1(PREFIX, A), MEMBER_1(PREFIX, B)
#define MEMBER_3(PREFIX, A, B, C) MEMBER_2(PREFIX, A, B), MEMBER_1(PREFIX, C)
#define MEMBER_4(PREFIX, A, B, C, D) MEMBER_3(PREFIX, A, B, C), MEMBER_1(PREFIX, D)
#define MEMBER_5(PREFIX, A, B, C, D, E) MEMBER_4(PREFIX, A, B, C, D), MEMBER_1(PREFIX, E)
#define MEMBER_6(PREFIX, A, B, C, D, E, F) MEMBER_5(PREFIX, A, B, C, D, E), MEMBER_1(PREFIX, F)
#define MEMBER_7(PREFIX, A, B, C, D, E, F, G) \
MEMBER_6(PREFIX, A, B, C, D, E, F), MEMBER_1(PREFIX, G)
#define MEMBER_8(PREFIX, A, B, C, D, E, F, G, H) \
MEMBER_7(PREFIX, A, B, C, D, E, F, G), MEMBER_1(PREFIX, H)
#define MEMBER_9(PREFIX, A, B, C, D, E, F, G, H, I) \
MEMBER_8(PREFIX, A, B, C, D, E, F, G, H), MEMBER_1(PREFIX, I)
#define MEMBER_10(PREFIX, A, B, C, D, E, F, G, H, I, J) \
MEMBER_9(PREFIX, A, B, C, D, E, F, G, H, I), MEMBER_1(PREFIX, J)
#define MEMBER_11(PREFIX, A, B, C, D, E, F, G, H, I, J, K) \
MEMBER_10(PREFIX, A, B, C, D, E, F, G, H, I, J), MEMBER_1(PREFIX, K)
#define MEMBER_12(PREFIX, A, B, C, D, E, F, G, H, I, J, K, L) \
MEMBER_11(PREFIX, A, B, C, D, E, F, G, H, I, J, K), MEMBER_1(PREFIX, L)
#define NAMED_MEMBER_0(...)
#define NAMED_MEMBER_1(PREFIX, FIELD) std::make_pair(#FIELD, PREFIX.FIELD)
#define NAMED_MEMBER_2(PREFIX, A, B) NAMED_MEMBER_1(PREFIX, A), NAMED_MEMBER_1(PREFIX, B)
#define NAMED_MEMBER_3(PREFIX, A, B, C) NAMED_MEMBER_2(PREFIX, A, B), NAMED_MEMBER_1(PREFIX, C)
#define NAMED_MEMBER_4(PREFIX, A, B, C, D) \
NAMED_MEMBER_3(PREFIX, A, B, C), NAMED_MEMBER_1(PREFIX, D)
#define NAMED_MEMBER_5(PREFIX, A, B, C, D, E) \
NAMED_MEMBER_4(PREFIX, A, B, C, D), NAMED_MEMBER_1(PREFIX, E)
#define NAMED_MEMBER_6(PREFIX, A, B, C, D, E, F) \
NAMED_MEMBER_5(PREFIX, A, B, C, D, E), NAMED_MEMBER_1(PREFIX, F)
#define NAMED_MEMBER_7(PREFIX, A, B, C, D, E, F, G) \
NAMED_MEMBER_6(PREFIX, A, B, C, D, E, F), NAMED_MEMBER_1(PREFIX, G)
#define NAMED_MEMBER_8(PREFIX, A, B, C, D, E, F, G, H) \
NAMED_MEMBER_7(PREFIX, A, B, C, D, E, F, G), NAMED_MEMBER_1(PREFIX, H)
#define NAMED_MEMBER_9(PREFIX, A, B, C, D, E, F, G, H, I) \
NAMED_MEMBER_8(PREFIX, A, B, C, D, E, F, G, H), NAMED_MEMBER_1(PREFIX, I)
#define NAMED_MEMBER_10(PREFIX, A, B, C, D, E, F, G, H, I, J) \
NAMED_MEMBER_9(PREFIX, A, B, C, D, E, F, G, H, I), NAMED_MEMBER_1(PREFIX, J)
#define NAMED_MEMBER_11(PREFIX, A, B, C, D, E, F, G, H, I, J, K) \
NAMED_MEMBER_10(PREFIX, A, B, C, D, E, F, G, H, I, J), NAMED_MEMBER_1(PREFIX, K)
#define NAMED_MEMBER_12(PREFIX, A, B, C, D, E, F, G, H, I, J, K, L) \
NAMED_MEMBER_11(PREFIX, A, B, C, D, E, F, G, H, I, J, K), NAMED_MEMBER_1(PREFIX, L)
/// @def GET_MEMBER_FIELDS
/// @param VAR some struct instance
/// @param ... The member fields of the struct
///
/// @brief this macro is used to expand one variable (VAR) + one or more member fields (FIELDS)
/// into a sequence of something like: `(VAR.FIELD, ...)`
/// For example, `GET_MEMBER_FIELDS(foo, a, b, c)` would transform into `foo.a, foo.b, foo.c`:
///
/// @code{.cpp}
///
/// struct Foo
/// {
/// int a;
/// float b;
/// double c;
/// };
///
/// // some function taking int, float, and double
/// void some_function(int, float, double);
///
/// // overload to some_function accepting Foo instance and using
/// // the args to invoke "real" function
/// void some_function(Foo _foo_v)
/// {
/// some_function(GET_MEMBER_FIELDS(_foo_v, a, b, c));
/// }
///
/// int main()
/// {
/// Foo _foo_v = {-1, 0.5f, 2.0};
/// invoke_some_function(_foo_v);
/// }
///
/// @code
#define GET_MEMBER_FIELDS(VAR, ...) IMPL_DETAIL_FOR_EACH(MEMBER_, VAR, __VA_ARGS__)
#define GET_NAMED_MEMBER_FIELDS(VAR, ...) IMPL_DETAIL_FOR_EACH(NAMED_MEMBER_, VAR, __VA_ARGS__)
#define HSA_API_INFO_DEFINITION_0(HSA_DOMAIN, HSA_TABLE, HSA_API_ID, HSA_FUNC, HSA_FUNC_PTR) \
namespace rocprofiler \
{ \
namespace hsa \
{ \
template <> \
struct hsa_api_info<HSA_API_ID> \
{ \
static constexpr auto domain_idx = HSA_DOMAIN; \
static constexpr auto table_idx = HSA_TABLE; \
static constexpr auto operation_idx = HSA_API_ID; \
static constexpr auto name = #HSA_FUNC; \
\
using this_type = hsa_api_info<operation_idx>; \
using base_type = hsa_api_impl<operation_idx>; \
\
static auto& get_table() { return hsa_table_lookup<table_idx>{}(); } \
\
template <typename TableT> \
static auto& get_table(TableT& _v) \
{ \
return hsa_table_lookup<table_idx>{}(_v); \
} \
\
template <typename TableT> \
static auto& get_table_func(TableT& _table) \
{ \
if constexpr(std::is_pointer<TableT>::value) \
{ \
assert(_table != nullptr && "nullptr to HSA table for " #HSA_FUNC " function"); \
return _table->HSA_FUNC_PTR; \
} \
else \
{ \
return _table.HSA_FUNC_PTR; \
} \
} \
\
static auto& get_table_func() { return get_table_func(get_table()); } \
\
template <typename DataT> \
static auto& get_api_data_args(DataT& _data) \
{ \
return _data.api_data.args.HSA_FUNC; \
} \
\
template <typename RetT, typename... Args> \
static auto get_functor(RetT (*)(Args...)) \
{ \
if constexpr(std::is_void<RetT>::value) \
return [](Args... args) -> RetT { base_type::functor(args...); }; \
else \
return [](Args... args) -> RetT { return base_type::functor(args...); }; \
} \
\
static auto get_functor() { return get_functor(get_table_func()); } \
\
static std::string as_string(hsa_trace_data_t) { return std::string{name} + "()"; } \
\
static std::string as_named_string(hsa_trace_data_t) { return std::string{name} + "()"; } \
\
static std::vector<std::pair<std::string, std::string>> as_arg_list(hsa_trace_data_t) \
{ \
return {}; \
} \
}; \
} \
}
#define HSA_API_INFO_DEFINITION_V(HSA_DOMAIN, HSA_TABLE, HSA_API_ID, HSA_FUNC, HSA_FUNC_PTR, ...) \
namespace rocprofiler \
{ \
namespace hsa \
{ \
template <> \
struct hsa_api_info<HSA_API_ID> \
{ \
static constexpr auto domain_idx = HSA_DOMAIN; \
static constexpr auto table_idx = HSA_TABLE; \
static constexpr auto operation_idx = HSA_API_ID; \
static constexpr auto name = #HSA_FUNC; \
\
using this_type = hsa_api_info<operation_idx>; \
using base_type = hsa_api_impl<operation_idx>; \
\
static auto& get_table() { return hsa_table_lookup<table_idx>{}(); } \
\
template <typename TableT> \
static auto& get_table(TableT& _v) \
{ \
return hsa_table_lookup<table_idx>{}(_v); \
} \
\
template <typename TableT> \
static auto& get_table_func(TableT& _table) \
{ \
if constexpr(std::is_pointer<TableT>::value) \
{ \
assert(_table != nullptr && "nullptr to HSA table for " #HSA_FUNC " function"); \
return _table->HSA_FUNC_PTR; \
} \
else \
{ \
return _table.HSA_FUNC_PTR; \
} \
} \
\
static auto& get_table_func() { return get_table_func(get_table()); } \
\
template <typename DataT> \
static auto& get_api_data_args(DataT& _data) \
{ \
return _data.api_data.args.HSA_FUNC; \
} \
\
template <typename RetT, typename... Args> \
static auto get_functor(RetT (*)(Args...)) \
{ \
if constexpr(std::is_void<RetT>::value) \
return [](Args... args) -> RetT { base_type::functor(args...); }; \
else \
return [](Args... args) -> RetT { return base_type::functor(args...); }; \
} \
\
static auto get_functor() { return get_functor(get_table_func()); } \
\
static std::string as_string(hsa_trace_data_t trace_data) \
{ \
return utils::join(utils::join_args{std::string{name} + "(", ")", ", "}, \
GET_MEMBER_FIELDS(get_api_data_args(trace_data), __VA_ARGS__)); \
} \
\
static std::string as_named_string(hsa_trace_data_t trace_data) \
{ \
return utils::join( \
utils::join_args{std::string{name} + "(", ")", ", "}, \
GET_NAMED_MEMBER_FIELDS(get_api_data_args(trace_data), __VA_ARGS__)); \
} \
\
static auto as_arg_list(hsa_trace_data_t trace_data) \
{ \
return utils::stringize( \
GET_NAMED_MEMBER_FIELDS(get_api_data_args(trace_data), __VA_ARGS__)); \
} \
}; \
} \
}
Разница между файлами не показана из-за своего большого размера Загрузить разницу
Разница между файлами не показана из-за своего большого размера Загрузить разницу
+99
Просмотреть файл
@@ -0,0 +1,99 @@
// Copyright (c) 2018-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 <cstddef>
#include <cstdint>
#include <sstream>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
namespace rocprofiler
{
namespace hsa
{
namespace utils
{
struct join_args
{
std::string_view prefix = {};
std::string_view suffix = {};
std::string_view separator = {};
};
template <typename Tp>
auto
join_impl(const Tp& _v)
{
return _v;
}
template <typename LhsT, typename RhsT>
auto
join_impl(const std::pair<LhsT, RhsT>& _v)
{
auto _ss = std::stringstream{};
_ss << _v.first << "=" << _v.second;
return _ss.str();
}
template <typename... Args>
auto
join(join_args ja, Args... args)
{
auto _content = std::string{};
{
auto _ss = std::stringstream{};
((_ss << ja.separator << join_impl(args)), ...);
auto _v = _ss.str();
if(_v.length() > ja.separator.length()) _content = _v.substr(2);
}
return (std::stringstream{} << ja.prefix << _content << ja.suffix).str();
}
template <typename Tp>
auto
stringize_impl(const Tp& _v)
{
auto _ss = std::stringstream{};
_ss << _v;
return _ss.str();
}
template <typename LhsT, typename RhsT>
auto
stringize_impl(const std::pair<LhsT, RhsT>& _v)
{
return std::make_pair(stringize_impl(_v.first), stringize_impl(_v.second));
}
template <typename... Args>
auto
stringize(Args... args)
{
return std::vector<std::pair<std::string, std::string>>{stringize_impl(args)...};
}
} // namespace utils
} // namespace hsa
} // namespace rocprofiler
+485
Просмотреть файл
@@ -0,0 +1,485 @@
// Copyright (c) 2018-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 "hsa.hpp"
#include "hsa-types.h"
#include <hsa/hsa_api_trace.h>
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <sstream>
#include <type_traits>
#include <utility>
namespace rocprofiler
{
namespace hsa
{
namespace
{
std::atomic<activity_functor_t> report_activity = {};
auto&
get_saved_table()
{
static auto _core = CoreApiTable{};
static auto _amd_ext = AmdExtTable{};
static auto _img_ext = ImageExtTable{};
static auto _fini_ext = FinalizerExtTable{};
static auto _v = []() {
_core.version = {
HSA_CORE_API_TABLE_MAJOR_VERSION, sizeof(_core), HSA_CORE_API_TABLE_STEP_VERSION, 0};
_amd_ext.version = {HSA_AMD_EXT_API_TABLE_MAJOR_VERSION,
sizeof(_amd_ext),
HSA_AMD_EXT_API_TABLE_STEP_VERSION,
0};
_img_ext.version = {HSA_IMAGE_API_TABLE_MAJOR_VERSION,
sizeof(_img_ext),
HSA_IMAGE_API_TABLE_STEP_VERSION,
0};
_fini_ext.version = {HSA_FINALIZER_API_TABLE_MAJOR_VERSION,
sizeof(_fini_ext),
HSA_FINALIZER_API_TABLE_STEP_VERSION,
0};
auto _version = ApiTableVersion{
HSA_API_TABLE_MAJOR_VERSION, sizeof(HsaApiTable), HSA_API_TABLE_STEP_VERSION, 0};
auto _val = hsa_api_table_t{_version, &_core, &_amd_ext, &_fini_ext, &_img_ext};
return _val;
}();
return _v;
}
} // namespace
template <>
struct hsa_table_lookup<HSA_API_TABLE_ID_CoreApi>
{
auto& operator()(hsa_api_table_t& _v) const { return _v.core_; }
auto& operator()(hsa_api_table_t* _v) const { return _v->core_; }
auto& operator()() const { return (*this)(get_saved_table()); }
};
template <>
struct hsa_table_lookup<HSA_API_TABLE_ID_AmdExt>
{
auto& operator()(hsa_api_table_t& _v) const { return _v.amd_ext_; }
auto& operator()(hsa_api_table_t* _v) const { return _v->amd_ext_; }
auto& operator()() const { return (*this)(get_saved_table()); }
};
template <>
struct hsa_table_lookup<HSA_API_TABLE_ID_ImageExt>
{
auto& operator()(hsa_api_table_t& _v) const { return _v.image_ext_; }
auto& operator()(hsa_api_table_t* _v) const { return _v->image_ext_; }
auto& operator()() const { return (*this)(get_saved_table()); }
};
template <typename DataT, typename Tp>
void
set_data_retval(DataT& _data, Tp _val)
{
if constexpr(std::is_same<Tp, hsa_signal_value_t>::value)
{
_data.hsa_signal_value_t_retval = _val;
}
else if constexpr(std::is_same<Tp, uint64_t>::value)
{
_data.uint64_t_retval = _val;
}
else if constexpr(std::is_same<Tp, uint32_t>::value)
{
_data.uint32_t_retval = _val;
}
else if constexpr(std::is_same<Tp, hsa_status_t>::value)
{
_data.hsa_status_t_retval = _val;
}
else
{
static_assert(std::is_void<Tp>::value, "Error! unsupported return type");
}
}
template <size_t Idx>
template <typename DataT, typename DataArgsT, typename... Args>
auto
hsa_api_impl<Idx>::phase_enter(DataT& _data, DataArgsT& _data_args, Args... args)
{
using info_type = hsa_api_info<Idx>;
activity_functor_t _func = report_activity.load(std::memory_order_relaxed);
if(_func)
{
if constexpr(Idx == HSA_API_ID_hsa_amd_memory_async_copy_rect)
{
auto _tuple = std::make_tuple(args...);
_data.api_data.args.hsa_amd_memory_async_copy_rect.dst = std::get<0>(_tuple);
_data.api_data.args.hsa_amd_memory_async_copy_rect.dst_offset = std::get<1>(_tuple);
_data.api_data.args.hsa_amd_memory_async_copy_rect.src = std::get<2>(_tuple);
_data.api_data.args.hsa_amd_memory_async_copy_rect.src_offset = std::get<3>(_tuple);
_data.api_data.args.hsa_amd_memory_async_copy_rect.range = std::get<4>(_tuple);
_data.api_data.args.hsa_amd_memory_async_copy_rect.range__val = *(std::get<4>(_tuple));
_data.api_data.args.hsa_amd_memory_async_copy_rect.copy_agent = std::get<5>(_tuple);
_data.api_data.args.hsa_amd_memory_async_copy_rect.dir = std::get<6>(_tuple);
_data.api_data.args.hsa_amd_memory_async_copy_rect.num_dep_signals =
std::get<7>(_tuple);
_data.api_data.args.hsa_amd_memory_async_copy_rect.dep_signals = std::get<8>(_tuple);
_data.api_data.args.hsa_amd_memory_async_copy_rect.completion_signal =
std::get<9>(_tuple);
}
else
{
_data_args = DataArgsT{args...};
}
if(_func(info_type::domain_idx, info_type::operation_idx, &_data) == 0)
{
if(_data.phase_enter != nullptr) _data.phase_enter(info_type::operation_idx, &_data);
return true;
}
return false;
}
return false;
}
template <size_t Idx>
template <typename DataT, typename... Args>
auto
hsa_api_impl<Idx>::phase_exit(DataT& _data)
{
using info_type = hsa_api_info<Idx>;
if(_data.phase_exit != nullptr)
{
_data.phase_exit(info_type::operation_idx, &_data);
return true;
}
return false;
}
struct null_type
{};
template <size_t Idx>
template <typename DataT, typename FuncT, typename... Args>
auto
hsa_api_impl<Idx>::exec(DataT& _data, FuncT&& _func, Args&&... args)
{
using return_type = std::decay_t<std::invoke_result_t<FuncT, Args...>>;
if(_func)
{
static_assert(std::is_void<return_type>::value || std::is_enum<return_type>::value ||
std::is_integral<return_type>::value,
"Error! unsupported return type");
if constexpr(std::is_void<return_type>::value)
{
_func(std::forward<Args>(args)...);
return null_type{};
}
else
{
auto _ret = _func(std::forward<Args>(args)...);
set_data_retval(_data.api_data, _ret);
return _ret;
}
}
if constexpr(std::is_void<return_type>::value)
return null_type{};
else
return return_type{HSA_STATUS_ERROR};
}
template <size_t Idx>
template <typename... Args>
auto
hsa_api_impl<Idx>::functor(Args&&... args)
{
using info_type = hsa_api_info<Idx>;
auto trace_data = hsa_trace_data_t{};
auto _enabled = phase_enter(
trace_data, info_type::get_api_data_args(trace_data), std::forward<Args>(args)...);
auto _ret = exec(trace_data, info_type::get_table_func(), std::forward<Args>(args)...);
if(_enabled) phase_exit(trace_data);
if constexpr(!std::is_same<decltype(_ret), null_type>::value)
return _ret;
else
return HSA_STATUS_SUCCESS;
}
} // namespace hsa
} // namespace rocprofiler
#include "hsa.gen.cpp"
namespace rocprofiler
{
namespace hsa
{
namespace
{
template <size_t Idx, size_t... IdxTail>
const char*
hsa_api_name(const uint32_t id, std::index_sequence<Idx, IdxTail...>)
{
if(Idx == id) return hsa_api_info<Idx>::name;
if constexpr(sizeof...(IdxTail) > 0)
return hsa_api_name(id, std::index_sequence<IdxTail...>{});
else
return nullptr;
}
template <size_t Idx, size_t... IdxTail>
uint32_t
hsa_api_id_by_name(const char* name, std::index_sequence<Idx, IdxTail...>)
{
if(std::string_view{hsa_api_info<Idx>::name} == std::string_view{name})
return hsa_api_info<Idx>::operation_idx;
if constexpr(sizeof...(IdxTail) > 0)
return hsa_api_id_by_name(name, std::index_sequence<IdxTail...>{});
else
return HSA_API_ID_NONE;
}
template <size_t Idx, size_t... IdxTail>
std::string
hsa_api_data_string(const uint32_t id,
const hsa_trace_data_t& _data,
std::index_sequence<Idx, IdxTail...>)
{
if(Idx == id) return hsa_api_info<Idx>::as_string(_data);
if constexpr(sizeof...(IdxTail) > 0)
return hsa_api_data_string(id, _data, std::index_sequence<IdxTail...>{});
else
return std::string{};
}
template <size_t Idx, size_t... IdxTail>
std::string
hsa_api_named_data_string(const uint32_t id,
const hsa_trace_data_t& _data,
std::index_sequence<Idx, IdxTail...>)
{
if(Idx == id) return hsa_api_info<Idx>::as_named_string(_data);
if constexpr(sizeof...(IdxTail) > 0)
return hsa_api_named_data_string(id, _data, std::index_sequence<IdxTail...>{});
else
return std::string{};
}
template <size_t Idx, size_t... IdxTail>
void
hsa_api_iterate_args(const uint32_t id,
const hsa_trace_data_t& _data,
int (*_func)(const char*, const char*),
std::index_sequence<Idx, IdxTail...>)
{
if(Idx == id)
{
for(auto&& itr : hsa_api_info<Idx>::as_arg_list(_data))
{
_func(itr.first.c_str(), itr.second.c_str());
}
}
if constexpr(sizeof...(IdxTail) > 0)
hsa_api_iterate_args(id, _data, _func, std::index_sequence<IdxTail...>{});
}
template <size_t... Idx>
void
hsa_api_get_ids(std::vector<uint32_t>& _id_list, std::index_sequence<Idx...>)
{
auto _emplace = [](auto& _vec, uint32_t _v) {
if(_v < HSA_API_ID_DISPATCH) _vec.emplace_back(_v);
};
(_emplace(_id_list, hsa_api_info<Idx>::operation_idx), ...);
}
template <size_t... Idx>
void
hsa_api_get_names(std::vector<const char*>& _name_list, std::index_sequence<Idx...>)
{
auto _emplace = [](auto& _vec, const char* _v) {
if(_v != nullptr && strnlen(_v, 1) > 0) _vec.emplace_back(_v);
};
(_emplace(_name_list, hsa_api_info<Idx>::name), ...);
}
template <size_t... Idx>
void
hsa_api_update_table(hsa_api_table_t* _orig, std::index_sequence<Idx...>)
{
auto _update = [](hsa_api_table_t* _orig_v, auto _info) {
// 1. get the sub-table containing the function pointer
// 2. get reference to function pointer in sub-table
// 3. update function pointer with functor
auto& _table = _info.get_table(_orig_v);
auto& _func = _info.get_table_func(_table);
_func = _info.get_functor(_func);
};
(_update(_orig, hsa_api_info<Idx>{}), ...);
}
} // namespace
// check out the assembly here... this compiles to a switch statement
const char*
hsa_api_name(uint32_t id)
{
return hsa_api_name(id, std::make_index_sequence<HSA_API_ID_DISPATCH>{});
}
uint32_t
hsa_api_id_by_name(const char* name)
{
return hsa_api_id_by_name(name, std::make_index_sequence<HSA_API_ID_DISPATCH>{});
}
std::string
hsa_api_data_string(uint32_t id, const hsa_trace_data_t& _data)
{
return hsa_api_data_string(id, _data, std::make_index_sequence<HSA_API_ID_DISPATCH>{});
}
std::string
hsa_api_named_data_string(uint32_t id, const hsa_trace_data_t& _data)
{
return hsa_api_named_data_string(id, _data, std::make_index_sequence<HSA_API_ID_DISPATCH>{});
}
void
hsa_api_iterate_args(uint32_t id,
const hsa_trace_data_t& _data,
int (*_func)(const char*, const char*))
{
if(_func)
hsa_api_iterate_args(id, _data, _func, std::make_index_sequence<HSA_API_ID_DISPATCH>{});
}
std::vector<uint32_t>
hsa_api_get_ids()
{
auto _data = std::vector<uint32_t>{};
_data.reserve(HSA_API_ID_DISPATCH);
hsa_api_get_ids(_data, std::make_index_sequence<HSA_API_ID_DISPATCH>{});
return _data;
}
std::vector<const char*>
hsa_api_get_names()
{
auto _data = std::vector<const char*>{};
_data.reserve(HSA_API_ID_DISPATCH);
hsa_api_get_names(_data, std::make_index_sequence<HSA_API_ID_DISPATCH>{});
return _data;
}
void
hsa_api_set_callback(activity_functor_t _func)
{
auto&& _v = report_activity.load();
report_activity.compare_exchange_strong(_v, _func);
}
void
hsa_api_update_table(hsa_api_table_t* _orig)
{
if(_orig) hsa_api_update_table(_orig, std::make_index_sequence<HSA_API_ID_DISPATCH>{});
}
} // namespace hsa
} // namespace rocprofiler
extern "C" {
bool
OnLoad(HsaApiTable* table,
uint64_t runtime_version,
uint64_t failed_tool_count,
const char* const* failed_tool_names)
{
(void) runtime_version;
(void) failed_tool_count;
(void) failed_tool_names;
auto& _saved = rocprofiler::hsa::get_saved_table();
copyTables(table, &_saved);
rocprofiler::hsa::hsa_api_update_table(table);
return true;
}
}
/*
#include <iomanip>
int
main()
{
rocprofiler::hsa::activity_functor_t _cb =
[](rocprofiler_tracer_activity_domain_t domain, uint32_t operation_id, void* data) {
const auto* _name = rocprofiler::hsa::hsa_api_name(operation_id);
auto _name_id = rocprofiler::hsa::hsa_api_id_by_name(_name);
auto& _data = *static_cast<rocprofiler::hsa::hsa_trace_data_t*>(data);
std::cout << "[cb] domain=" << domain << ", op_id=" << operation_id << ", data=" << data
<< ", name=" << _name << ", name_id=" << _name_id << ", named_string='"
<< rocprofiler::hsa::hsa_api_named_data_string(operation_id, _data) << "'"
<< "\n";
auto _func = [](const char* name, const char* value) {
std::cout << " " << std::setw(20) << name << " = " << value << "\n";
return 0;
};
rocprofiler::hsa::hsa_api_iterate_args(operation_id, _data, _func);
return 0;
};
rocprofiler::hsa::report_activity.store(_cb);
{
double val = 40;
hsa_code_object_t code_object = {};
hsa_code_object_info_t attribute = HSA_CODE_OBJECT_INFO_TYPE;
void* value = &val;
auto _func =
rocprofiler::hsa::hsa_api_info<HSA_API_ID_hsa_code_object_get_info>::get_functor();
_func(code_object, attribute, value);
}
{
bool result = false;
uint16_t ext = 1;
uint16_t major = 4;
uint16_t minor = 2;
auto _func = rocprofiler::hsa::hsa_api_info<
HSA_API_ID_hsa_system_extension_supported>::get_functor();
_func(ext, major, minor, &result);
}
}
*/
+217
Просмотреть файл
@@ -0,0 +1,217 @@
// Copyright (c) 2018-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 "hsa.hpp"
// clang-format off
HSA_API_INFO_DEFINITION_0(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_init, hsa_init, hsa_init_fn)
HSA_API_INFO_DEFINITION_0(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_shut_down, hsa_shut_down, hsa_shut_down_fn)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_system_get_info, hsa_system_get_info, hsa_system_get_info_fn, attribute, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_system_extension_supported, hsa_system_extension_supported, hsa_system_extension_supported_fn, extension, version_major, version_minor, result)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_system_get_extension_table, hsa_system_get_extension_table, hsa_system_get_extension_table_fn, extension, version_major, version_minor, table)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_iterate_agents, hsa_iterate_agents, hsa_iterate_agents_fn, callback, data)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_agent_get_info, hsa_agent_get_info, hsa_agent_get_info_fn, agent, attribute, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_create, hsa_queue_create, hsa_queue_create_fn, agent, size, type, callback, data, private_segment_size, group_segment_size, queue)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_soft_queue_create, hsa_soft_queue_create, hsa_soft_queue_create_fn, region, size, type, features, doorbell_signal, queue)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_destroy, hsa_queue_destroy, hsa_queue_destroy_fn, queue)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_inactivate, hsa_queue_inactivate, hsa_queue_inactivate_fn, queue)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_load_read_index_scacquire, hsa_queue_load_read_index_scacquire, hsa_queue_load_read_index_scacquire_fn, queue)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_load_read_index_relaxed, hsa_queue_load_read_index_relaxed, hsa_queue_load_read_index_relaxed_fn, queue)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_load_write_index_scacquire, hsa_queue_load_write_index_scacquire, hsa_queue_load_write_index_scacquire_fn, queue)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_load_write_index_relaxed, hsa_queue_load_write_index_relaxed, hsa_queue_load_write_index_relaxed_fn, queue)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_store_write_index_relaxed, hsa_queue_store_write_index_relaxed, hsa_queue_store_write_index_relaxed_fn, queue, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_store_write_index_screlease, hsa_queue_store_write_index_screlease, hsa_queue_store_write_index_screlease_fn, queue, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_cas_write_index_scacq_screl, hsa_queue_cas_write_index_scacq_screl, hsa_queue_cas_write_index_scacq_screl_fn, queue, expected, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_cas_write_index_scacquire, hsa_queue_cas_write_index_scacquire, hsa_queue_cas_write_index_scacquire_fn, queue, expected, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_cas_write_index_relaxed, hsa_queue_cas_write_index_relaxed, hsa_queue_cas_write_index_relaxed_fn, queue, expected, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_cas_write_index_screlease, hsa_queue_cas_write_index_screlease, hsa_queue_cas_write_index_screlease_fn, queue, expected, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_add_write_index_scacq_screl, hsa_queue_add_write_index_scacq_screl, hsa_queue_add_write_index_scacq_screl_fn, queue, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_add_write_index_scacquire, hsa_queue_add_write_index_scacquire, hsa_queue_add_write_index_scacquire_fn, queue, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_add_write_index_relaxed, hsa_queue_add_write_index_relaxed, hsa_queue_add_write_index_relaxed_fn, queue, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_add_write_index_screlease, hsa_queue_add_write_index_screlease, hsa_queue_add_write_index_screlease_fn, queue, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_store_read_index_relaxed, hsa_queue_store_read_index_relaxed, hsa_queue_store_read_index_relaxed_fn, queue, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_queue_store_read_index_screlease, hsa_queue_store_read_index_screlease, hsa_queue_store_read_index_screlease_fn, queue, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_agent_iterate_regions, hsa_agent_iterate_regions, hsa_agent_iterate_regions_fn, agent, callback, data)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_region_get_info, hsa_region_get_info, hsa_region_get_info_fn, region, attribute, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_agent_get_exception_policies, hsa_agent_get_exception_policies, hsa_agent_get_exception_policies_fn, agent, profile, mask)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_agent_extension_supported, hsa_agent_extension_supported, hsa_agent_extension_supported_fn, extension, agent, version_major, version_minor, result)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_memory_register, hsa_memory_register, hsa_memory_register_fn, ptr, size)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_memory_deregister, hsa_memory_deregister, hsa_memory_deregister_fn, ptr, size)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_memory_allocate, hsa_memory_allocate, hsa_memory_allocate_fn, region, size, ptr)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_memory_free, hsa_memory_free, hsa_memory_free_fn, ptr)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_memory_copy, hsa_memory_copy, hsa_memory_copy_fn, dst, src, size)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_memory_assign_agent, hsa_memory_assign_agent, hsa_memory_assign_agent_fn, ptr, agent, access)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_create, hsa_signal_create, hsa_signal_create_fn, initial_value, num_consumers, consumers, signal)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_destroy, hsa_signal_destroy, hsa_signal_destroy_fn, signal)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_load_relaxed, hsa_signal_load_relaxed, hsa_signal_load_relaxed_fn, signal)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_load_scacquire, hsa_signal_load_scacquire, hsa_signal_load_scacquire_fn, signal)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_store_relaxed, hsa_signal_store_relaxed, hsa_signal_store_relaxed_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_store_screlease, hsa_signal_store_screlease, hsa_signal_store_screlease_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_wait_relaxed, hsa_signal_wait_relaxed, hsa_signal_wait_relaxed_fn, signal, condition, compare_value, timeout_hint, wait_state_hint)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_wait_scacquire, hsa_signal_wait_scacquire, hsa_signal_wait_scacquire_fn, signal, condition, compare_value, timeout_hint, wait_state_hint)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_and_relaxed, hsa_signal_and_relaxed, hsa_signal_and_relaxed_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_and_scacquire, hsa_signal_and_scacquire, hsa_signal_and_scacquire_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_and_screlease, hsa_signal_and_screlease, hsa_signal_and_screlease_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_and_scacq_screl, hsa_signal_and_scacq_screl, hsa_signal_and_scacq_screl_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_or_relaxed, hsa_signal_or_relaxed, hsa_signal_or_relaxed_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_or_scacquire, hsa_signal_or_scacquire, hsa_signal_or_scacquire_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_or_screlease, hsa_signal_or_screlease, hsa_signal_or_screlease_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_or_scacq_screl, hsa_signal_or_scacq_screl, hsa_signal_or_scacq_screl_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_xor_relaxed, hsa_signal_xor_relaxed, hsa_signal_xor_relaxed_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_xor_scacquire, hsa_signal_xor_scacquire, hsa_signal_xor_scacquire_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_xor_screlease, hsa_signal_xor_screlease, hsa_signal_xor_screlease_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_xor_scacq_screl, hsa_signal_xor_scacq_screl, hsa_signal_xor_scacq_screl_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_exchange_relaxed, hsa_signal_exchange_relaxed, hsa_signal_exchange_relaxed_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_exchange_scacquire, hsa_signal_exchange_scacquire, hsa_signal_exchange_scacquire_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_exchange_screlease, hsa_signal_exchange_screlease, hsa_signal_exchange_screlease_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_exchange_scacq_screl, hsa_signal_exchange_scacq_screl, hsa_signal_exchange_scacq_screl_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_add_relaxed, hsa_signal_add_relaxed, hsa_signal_add_relaxed_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_add_scacquire, hsa_signal_add_scacquire, hsa_signal_add_scacquire_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_add_screlease, hsa_signal_add_screlease, hsa_signal_add_screlease_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_add_scacq_screl, hsa_signal_add_scacq_screl, hsa_signal_add_scacq_screl_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_subtract_relaxed, hsa_signal_subtract_relaxed, hsa_signal_subtract_relaxed_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_subtract_scacquire, hsa_signal_subtract_scacquire, hsa_signal_subtract_scacquire_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_subtract_screlease, hsa_signal_subtract_screlease, hsa_signal_subtract_screlease_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_subtract_scacq_screl, hsa_signal_subtract_scacq_screl, hsa_signal_subtract_scacq_screl_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_cas_relaxed, hsa_signal_cas_relaxed, hsa_signal_cas_relaxed_fn, signal, expected, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_cas_scacquire, hsa_signal_cas_scacquire, hsa_signal_cas_scacquire_fn, signal, expected, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_cas_screlease, hsa_signal_cas_screlease, hsa_signal_cas_screlease_fn, signal, expected, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_cas_scacq_screl, hsa_signal_cas_scacq_screl, hsa_signal_cas_scacq_screl_fn, signal, expected, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_isa_from_name, hsa_isa_from_name, hsa_isa_from_name_fn, name, isa)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_isa_get_info, hsa_isa_get_info, hsa_isa_get_info_fn, isa, attribute, index, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_isa_compatible, hsa_isa_compatible, hsa_isa_compatible_fn, code_object_isa, agent_isa, result)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_code_object_serialize, hsa_code_object_serialize, hsa_code_object_serialize_fn, code_object, alloc_callback, callback_data, options, serialized_code_object, serialized_code_object_size)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_code_object_deserialize, hsa_code_object_deserialize, hsa_code_object_deserialize_fn, serialized_code_object, serialized_code_object_size, options, code_object)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_code_object_destroy, hsa_code_object_destroy, hsa_code_object_destroy_fn, code_object)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_code_object_get_info, hsa_code_object_get_info, hsa_code_object_get_info_fn, code_object, attribute, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_code_object_get_symbol, hsa_code_object_get_symbol, hsa_code_object_get_symbol_fn, code_object, symbol_name, symbol)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_code_symbol_get_info, hsa_code_symbol_get_info, hsa_code_symbol_get_info_fn, code_symbol, attribute, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_code_object_iterate_symbols, hsa_code_object_iterate_symbols, hsa_code_object_iterate_symbols_fn, code_object, callback, data)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_create, hsa_executable_create, hsa_executable_create_fn, profile, executable_state, options, executable)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_destroy, hsa_executable_destroy, hsa_executable_destroy_fn, executable)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_load_code_object, hsa_executable_load_code_object, hsa_executable_load_code_object_fn, executable, agent, code_object, options)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_freeze, hsa_executable_freeze, hsa_executable_freeze_fn, executable, options)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_get_info, hsa_executable_get_info, hsa_executable_get_info_fn, executable, attribute, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_global_variable_define, hsa_executable_global_variable_define, hsa_executable_global_variable_define_fn, executable, variable_name, address)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_agent_global_variable_define, hsa_executable_agent_global_variable_define, hsa_executable_agent_global_variable_define_fn, executable, agent, variable_name, address)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_readonly_variable_define, hsa_executable_readonly_variable_define, hsa_executable_readonly_variable_define_fn, executable, agent, variable_name, address)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_validate, hsa_executable_validate, hsa_executable_validate_fn, executable, result)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_get_symbol, hsa_executable_get_symbol, hsa_executable_get_symbol_fn, executable, module_name, symbol_name, agent, call_convention, symbol)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_symbol_get_info, hsa_executable_symbol_get_info, hsa_executable_symbol_get_info_fn, executable_symbol, attribute, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_iterate_symbols, hsa_executable_iterate_symbols, hsa_executable_iterate_symbols_fn, executable, callback, data)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_status_string, hsa_status_string, hsa_status_string_fn, status, status_string)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_extension_get_name, hsa_extension_get_name, hsa_extension_get_name_fn, extension, name)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_system_major_extension_supported, hsa_system_major_extension_supported, hsa_system_major_extension_supported_fn, extension, version_major, version_minor, result)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_system_get_major_extension_table, hsa_system_get_major_extension_table, hsa_system_get_major_extension_table_fn, extension, version_major, table_length, table)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_agent_major_extension_supported, hsa_agent_major_extension_supported, hsa_agent_major_extension_supported_fn, extension, agent, version_major, version_minor, result)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_cache_get_info, hsa_cache_get_info, hsa_cache_get_info_fn, cache, attribute, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_agent_iterate_caches, hsa_agent_iterate_caches, hsa_agent_iterate_caches_fn, agent, callback, data)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_silent_store_relaxed, hsa_signal_silent_store_relaxed, hsa_signal_silent_store_relaxed_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_silent_store_screlease, hsa_signal_silent_store_screlease, hsa_signal_silent_store_screlease_fn, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_group_create, hsa_signal_group_create, hsa_signal_group_create_fn, num_signals, signals, num_consumers, consumers, signal_group)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_group_destroy, hsa_signal_group_destroy, hsa_signal_group_destroy_fn, signal_group)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_group_wait_any_scacquire, hsa_signal_group_wait_any_scacquire, hsa_signal_group_wait_any_scacquire_fn, signal_group, conditions, compare_values, wait_state_hint, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_signal_group_wait_any_relaxed, hsa_signal_group_wait_any_relaxed, hsa_signal_group_wait_any_relaxed_fn, signal_group, conditions, compare_values, wait_state_hint, signal, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_agent_iterate_isas, hsa_agent_iterate_isas, hsa_agent_iterate_isas_fn, agent, callback, data)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_isa_get_info_alt, hsa_isa_get_info_alt, hsa_isa_get_info_alt_fn, isa, attribute, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_isa_get_exception_policies, hsa_isa_get_exception_policies, hsa_isa_get_exception_policies_fn, isa, profile, mask)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_isa_get_round_method, hsa_isa_get_round_method, hsa_isa_get_round_method_fn, isa, fp_type, flush_mode, round_method)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_wavefront_get_info, hsa_wavefront_get_info, hsa_wavefront_get_info_fn, wavefront, attribute, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_isa_iterate_wavefronts, hsa_isa_iterate_wavefronts, hsa_isa_iterate_wavefronts_fn, isa, callback, data)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_code_object_get_symbol_from_name, hsa_code_object_get_symbol_from_name, hsa_code_object_get_symbol_from_name_fn, code_object, module_name, symbol_name, symbol)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_code_object_reader_create_from_file, hsa_code_object_reader_create_from_file, hsa_code_object_reader_create_from_file_fn, file, code_object_reader)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_code_object_reader_create_from_memory, hsa_code_object_reader_create_from_memory, hsa_code_object_reader_create_from_memory_fn, code_object, size, code_object_reader)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_code_object_reader_destroy, hsa_code_object_reader_destroy, hsa_code_object_reader_destroy_fn, code_object_reader)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_create_alt, hsa_executable_create_alt, hsa_executable_create_alt_fn, profile, default_float_rounding_mode, options, executable)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_load_program_code_object, hsa_executable_load_program_code_object, hsa_executable_load_program_code_object_fn, executable, code_object_reader, options, loaded_code_object)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_load_agent_code_object, hsa_executable_load_agent_code_object, hsa_executable_load_agent_code_object_fn, executable, agent, code_object_reader, options, loaded_code_object)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_validate_alt, hsa_executable_validate_alt, hsa_executable_validate_alt_fn, executable, options, result)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_get_symbol_by_name, hsa_executable_get_symbol_by_name, hsa_executable_get_symbol_by_name_fn, executable, symbol_name, agent, symbol)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_iterate_agent_symbols, hsa_executable_iterate_agent_symbols, hsa_executable_iterate_agent_symbols_fn, executable, agent, callback, data)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_CoreApi, HSA_API_ID_hsa_executable_iterate_program_symbols, hsa_executable_iterate_program_symbols, hsa_executable_iterate_program_symbols_fn, executable, callback, data)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_coherency_get_type, hsa_amd_coherency_get_type, hsa_amd_coherency_get_type_fn, agent, type)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_coherency_set_type, hsa_amd_coherency_set_type, hsa_amd_coherency_set_type_fn, agent, type)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_profiling_set_profiler_enabled, hsa_amd_profiling_set_profiler_enabled, hsa_amd_profiling_set_profiler_enabled_fn, queue, enable)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_profiling_async_copy_enable, hsa_amd_profiling_async_copy_enable, hsa_amd_profiling_async_copy_enable_fn, enable)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_profiling_get_dispatch_time, hsa_amd_profiling_get_dispatch_time, hsa_amd_profiling_get_dispatch_time_fn, agent, signal, time)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_profiling_get_async_copy_time, hsa_amd_profiling_get_async_copy_time, hsa_amd_profiling_get_async_copy_time_fn, signal, time)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_profiling_convert_tick_to_system_domain, hsa_amd_profiling_convert_tick_to_system_domain, hsa_amd_profiling_convert_tick_to_system_domain_fn, agent, agent_tick, system_tick)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_signal_async_handler, hsa_amd_signal_async_handler, hsa_amd_signal_async_handler_fn, signal, cond, value, handler, arg)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_async_function, hsa_amd_async_function, hsa_amd_async_function_fn, callback, arg)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_signal_wait_any, hsa_amd_signal_wait_any, hsa_amd_signal_wait_any_fn, signal_count, signals, conds, values, timeout_hint, wait_hint, satisfying_value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_queue_cu_set_mask, hsa_amd_queue_cu_set_mask, hsa_amd_queue_cu_set_mask_fn, queue, num_cu_mask_count, cu_mask)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_memory_pool_get_info, hsa_amd_memory_pool_get_info, hsa_amd_memory_pool_get_info_fn, memory_pool, attribute, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_agent_iterate_memory_pools, hsa_amd_agent_iterate_memory_pools, hsa_amd_agent_iterate_memory_pools_fn, agent, callback, data)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_memory_pool_allocate, hsa_amd_memory_pool_allocate, hsa_amd_memory_pool_allocate_fn, memory_pool, size, flags, ptr)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_memory_pool_free, hsa_amd_memory_pool_free, hsa_amd_memory_pool_free_fn, ptr)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_memory_async_copy, hsa_amd_memory_async_copy, hsa_amd_memory_async_copy_fn, dst, dst_agent, src, src_agent, size, num_dep_signals, dep_signals, completion_signal)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_memory_async_copy_on_engine, hsa_amd_memory_async_copy_on_engine, hsa_amd_memory_async_copy_on_engine_fn, dst, dst_agent, src, src_agent, size, num_dep_signals, dep_signals, completion_signal, engine_id, force_copy_on_sdma)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_memory_copy_engine_status, hsa_amd_memory_copy_engine_status, hsa_amd_memory_copy_engine_status_fn, dst_agent, src_agent, engine_ids_mask)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_agent_memory_pool_get_info, hsa_amd_agent_memory_pool_get_info, hsa_amd_agent_memory_pool_get_info_fn, agent, memory_pool, attribute, value)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_agents_allow_access, hsa_amd_agents_allow_access, hsa_amd_agents_allow_access_fn, num_agents, agents, flags, ptr)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_memory_pool_can_migrate, hsa_amd_memory_pool_can_migrate, hsa_amd_memory_pool_can_migrate_fn, src_memory_pool, dst_memory_pool, result)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_memory_migrate, hsa_amd_memory_migrate, hsa_amd_memory_migrate_fn, ptr, memory_pool, flags)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_memory_lock, hsa_amd_memory_lock, hsa_amd_memory_lock_fn, host_ptr, size, agents, num_agent, agent_ptr)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_memory_unlock, hsa_amd_memory_unlock, hsa_amd_memory_unlock_fn, host_ptr)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_memory_fill, hsa_amd_memory_fill, hsa_amd_memory_fill_fn, ptr, value, count)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_interop_map_buffer, hsa_amd_interop_map_buffer, hsa_amd_interop_map_buffer_fn, num_agents, agents, interop_handle, flags, size, ptr, metadata_size, metadata)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_interop_unmap_buffer, hsa_amd_interop_unmap_buffer, hsa_amd_interop_unmap_buffer_fn, ptr)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_image_create, hsa_amd_image_create, hsa_amd_image_create_fn, agent, image_descriptor, image_layout, image_data, access_permission, image)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_pointer_info, hsa_amd_pointer_info, hsa_amd_pointer_info_fn, ptr, info, alloc, num_agents_accessible, accessible)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_pointer_info_set_userdata, hsa_amd_pointer_info_set_userdata, hsa_amd_pointer_info_set_userdata_fn, ptr, userdata)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_ipc_memory_create, hsa_amd_ipc_memory_create, hsa_amd_ipc_memory_create_fn, ptr, len, handle)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_ipc_memory_attach, hsa_amd_ipc_memory_attach, hsa_amd_ipc_memory_attach_fn, handle, len, num_agents, mapping_agents, mapped_ptr)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_ipc_memory_detach, hsa_amd_ipc_memory_detach, hsa_amd_ipc_memory_detach_fn, mapped_ptr)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_signal_create, hsa_amd_signal_create, hsa_amd_signal_create_fn, initial_value, num_consumers, consumers, attributes, signal)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_ipc_signal_create, hsa_amd_ipc_signal_create, hsa_amd_ipc_signal_create_fn, signal, handle)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_ipc_signal_attach, hsa_amd_ipc_signal_attach, hsa_amd_ipc_signal_attach_fn, handle, signal)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_register_system_event_handler, hsa_amd_register_system_event_handler, hsa_amd_register_system_event_handler_fn, callback, data)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_queue_set_priority, hsa_amd_queue_set_priority, hsa_amd_queue_set_priority_fn, queue, priority)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_memory_async_copy_rect, hsa_amd_memory_async_copy_rect, hsa_amd_memory_async_copy_rect_fn, dst, dst_offset, src, src_offset, range, copy_agent, dir, num_dep_signals, dep_signals, completion_signal)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_memory_lock_to_pool, hsa_amd_memory_lock_to_pool, hsa_amd_memory_lock_to_pool_fn, host_ptr, size, agents, num_agent, pool, flags, agent_ptr)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_register_deallocation_callback, hsa_amd_register_deallocation_callback, hsa_amd_register_deallocation_callback_fn, ptr, callback, user_data)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_deregister_deallocation_callback, hsa_amd_deregister_deallocation_callback, hsa_amd_deregister_deallocation_callback_fn, ptr, callback)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_signal_value_pointer, hsa_amd_signal_value_pointer, hsa_amd_signal_value_pointer_fn, signal, value_ptr)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_svm_attributes_set, hsa_amd_svm_attributes_set, hsa_amd_svm_attributes_set_fn, ptr, size, attribute_list, attribute_count)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_svm_attributes_get, hsa_amd_svm_attributes_get, hsa_amd_svm_attributes_get_fn, ptr, size, attribute_list, attribute_count)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_svm_prefetch_async, hsa_amd_svm_prefetch_async, hsa_amd_svm_prefetch_async_fn, ptr, size, agent, num_dep_signals, dep_signals, completion_signal)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_spm_acquire, hsa_amd_spm_acquire, hsa_amd_spm_acquire_fn, preferred_agent)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_spm_release, hsa_amd_spm_release, hsa_amd_spm_release_fn, preferred_agent)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_spm_set_dest_buffer, hsa_amd_spm_set_dest_buffer, hsa_amd_spm_set_dest_buffer_fn, preferred_agent, size_in_bytes, timeout, size_copied, dest, is_data_loss)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_queue_cu_get_mask, hsa_amd_queue_cu_get_mask, hsa_amd_queue_cu_get_mask_fn, queue, num_cu_mask_count, cu_mask)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_portable_export_dmabuf, hsa_amd_portable_export_dmabuf, hsa_amd_portable_export_dmabuf_fn, ptr, size, dmabuf, offset)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_portable_close_dmabuf, hsa_amd_portable_close_dmabuf, hsa_amd_portable_close_dmabuf_fn, dmabuf)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_ImageExt, HSA_API_ID_hsa_ext_image_get_capability, hsa_ext_image_get_capability, hsa_ext_image_get_capability_fn, agent, geometry, image_format, capability_mask)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_ImageExt, HSA_API_ID_hsa_ext_image_data_get_info, hsa_ext_image_data_get_info, hsa_ext_image_data_get_info_fn, agent, image_descriptor, access_permission, image_data_info)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_ImageExt, HSA_API_ID_hsa_ext_image_create, hsa_ext_image_create, hsa_ext_image_create_fn, agent, image_descriptor, image_data, access_permission, image)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_ImageExt, HSA_API_ID_hsa_ext_image_import, hsa_ext_image_import, hsa_ext_image_import_fn, agent, src_memory, src_row_pitch, src_slice_pitch, dst_image, image_region)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_ImageExt, HSA_API_ID_hsa_ext_image_export, hsa_ext_image_export, hsa_ext_image_export_fn, agent, src_image, dst_memory, dst_row_pitch, dst_slice_pitch, image_region)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_ImageExt, HSA_API_ID_hsa_ext_image_copy, hsa_ext_image_copy, hsa_ext_image_copy_fn, agent, src_image, src_offset, dst_image, dst_offset, range)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_ImageExt, HSA_API_ID_hsa_ext_image_clear, hsa_ext_image_clear, hsa_ext_image_clear_fn, agent, image, data, image_region)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_ImageExt, HSA_API_ID_hsa_ext_image_destroy, hsa_ext_image_destroy, hsa_ext_image_destroy_fn, agent, image)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_ImageExt, HSA_API_ID_hsa_ext_sampler_create, hsa_ext_sampler_create, hsa_ext_sampler_create_fn, agent, sampler_descriptor, sampler)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_ImageExt, HSA_API_ID_hsa_ext_sampler_destroy, hsa_ext_sampler_destroy, hsa_ext_sampler_destroy_fn, agent, sampler)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_ImageExt, HSA_API_ID_hsa_ext_image_get_capability_with_layout, hsa_ext_image_get_capability_with_layout, hsa_ext_image_get_capability_with_layout_fn, agent, geometry, image_format, image_data_layout, capability_mask)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_ImageExt, HSA_API_ID_hsa_ext_image_data_get_info_with_layout, hsa_ext_image_data_get_info_with_layout, hsa_ext_image_data_get_info_with_layout_fn, agent, image_descriptor, access_permission, image_data_layout, image_data_row_pitch, image_data_slice_pitch, image_data_info)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_ImageExt, HSA_API_ID_hsa_ext_image_create_with_layout, hsa_ext_image_create_with_layout, hsa_ext_image_create_with_layout_fn, agent, image_descriptor, image_data, access_permission, image_data_layout, image_data_row_pitch, image_data_slice_pitch, image)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_queue_intercept_create, hsa_amd_queue_intercept_create, hsa_amd_queue_intercept_create_fn, agent_handle, size, type, callback, data, private_segment_size, group_segment_size, queue)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_queue_intercept_register, hsa_amd_queue_intercept_register, hsa_amd_queue_intercept_register_fn, queue, callback, user_data)
HSA_API_INFO_DEFINITION_V(ACTIVITY_DOMAIN_HSA_API, HSA_API_TABLE_ID_AmdExt, HSA_API_ID_hsa_amd_runtime_queue_create_register, hsa_amd_runtime_queue_create_register, hsa_amd_runtime_queue_create_register_fn, callback, user_data)
// clang-format on
+124
Просмотреть файл
@@ -0,0 +1,124 @@
// Copyright (c) 2018-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 "lib/common/defines.hpp"
#include "lib/rocprofiler/hsa/hsa-defines.hpp"
#include "lib/rocprofiler/hsa/hsa-ostream.hpp"
#include "lib/rocprofiler/hsa/hsa-types.h"
#include "lib/rocprofiler/hsa/hsa-utils.hpp"
#include <hsa/hsa_api_trace.h>
#include <rocprofiler/rocprofiler.h>
#include <cstdint>
namespace rocprofiler
{
namespace hsa
{
using activity_functor_t = int (*)(rocprofiler_tracer_activity_domain_t domain,
uint32_t operation_id,
void* data);
using hsa_api_table_t = HsaApiTable;
struct hsa_trace_data_t
{
hsa_api_data_t api_data;
uint64_t phase_enter_timestamp;
uint64_t phase_data;
void (*phase_enter)(hsa_api_id_t operation_id, hsa_trace_data_t* data);
void (*phase_exit)(hsa_api_id_t operation_id, hsa_trace_data_t* data);
};
enum hsa_table_api_id_t
{
HSA_API_TABLE_ID_CoreApi,
HSA_API_TABLE_ID_AmdExt,
HSA_API_TABLE_ID_ImageExt,
HSA_API_TABLE_ID_NUMBER,
};
template <typename DataT, typename Tp>
void
set_data_retval(DataT&, Tp);
template <size_t Idx>
struct hsa_table_lookup;
template <size_t Idx>
struct hsa_api_impl
{
template <typename DataT, typename DataArgsT, typename... Args>
static auto phase_enter(DataT& _data, DataArgsT&, Args... args);
template <typename DataT, typename... Args>
static auto phase_exit(DataT& _data);
template <typename DataT, typename FuncT, typename... Args>
static auto exec(DataT& _data, FuncT&&, Args&&... args);
template <typename... Args>
static auto functor(Args&&... args);
};
template <size_t Idx>
struct hsa_api_info;
const char*
hsa_api_name(uint32_t id);
uint32_t
hsa_api_id_by_name(const char* name);
std::string
hsa_api_data_string(uint32_t id, const hsa_trace_data_t& _data);
std::string
hsa_api_named_data_string(uint32_t id, const hsa_trace_data_t& _data);
void
hsa_api_iterate_args(uint32_t id,
const hsa_trace_data_t& _data,
int (*_func)(const char*, const char*));
std::vector<const char*>
hsa_api_get_names();
std::vector<uint32_t>
hsa_api_get_ids();
void
hsa_api_set_callback(activity_functor_t _func);
} // namespace hsa
} // namespace rocprofiler
extern "C" {
using on_load_t = bool (*)(HsaApiTable*, uint64_t, uint64_t, const char* const*);
bool
OnLoad(HsaApiTable* table,
uint64_t runtime_version,
uint64_t failed_tool_count,
const char* const* failed_tool_names) ROCPROFILER_PUBLIC_API;
}
Разница между файлами не показана из-за своего большого размера Загрузить разницу
+515
Просмотреть файл
@@ -0,0 +1,515 @@
/* Copyright (c) 2018-2022 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 <hip/hip_runtime.h>
#include <hsa/hsa.h>
#include <hsa/hsa_ext_amd.h>
#include <rocprofiler/rocprofiler.h>
#include <cstddef>
#include <cstdint>
#include <optional>
#include <string>
typedef struct
{
rocprofiler_session_id_t session_id;
rocprofiler_buffer_id_t buffer_id;
} session_buffer_id_t;
typedef session_buffer_id_t roctracer_pool_t;
/* Correlation id */
typedef uint64_t activity_correlation_id_t;
typedef uint32_t activity_kind_t;
typedef uint32_t activity_op_t;
typedef uint64_t roctracer_timestamp_t;
typedef rocprofiler_tracer_activity_domain_t roctracer_domain_t;
typedef rocprofiler_tracer_activity_domain_t activity_domain_t;
// Prof_Protocol
/* Activity record type */
typedef struct activity_record_s
{
uint32_t domain; /* activity domain id */
activity_kind_t kind; /* activity kind */
activity_op_t op; /* activity op */
union
{
struct
{
activity_correlation_id_t correlation_id; /* activity ID */
roctracer_timestamp_t begin_ns; /* host begin timestamp */
roctracer_timestamp_t end_ns; /* host end timestamp */
};
struct
{
uint32_t se; /* sampled SE */
uint64_t cycle; /* sample cycle */
uint64_t pc; /* sample PC */
} pc_sample;
};
union
{
struct
{
int device_id; /* device id */
uint64_t queue_id; /* queue id */
};
struct
{
uint32_t process_id; /* device id */
uint32_t thread_id; /* thread id */
};
struct
{
activity_correlation_id_t external_id; /* external correlation id */
};
};
union
{
size_t bytes; /* data size bytes */
const char* kernel_name; /* kernel name */
const char* mark_message;
};
} activity_record_t;
typedef activity_record_t roctracer_record_t;
/* Activity sync callback type */
typedef void (*activity_sync_callback_t)(activity_domain_t cid,
activity_record_t* record,
const void* data,
void* arg);
/* Activity async callback type */
typedef void (*activity_async_callback_t)(activity_domain_t op, void* record, void* arg);
/* API callback type */
typedef void (*activity_rtapi_callback_t)(activity_domain_t domain,
uint32_t cid,
const void* data,
void* arg);
typedef activity_rtapi_callback_t roctracer_rtapi_callback_t;
typedef roctracer_timestamp_t (*roctracer_get_timestamp_t)();
typedef rocprofiler_timestamp_t (*rocprofiler_get_timestamp_t)();
typedef uint32_t activity_kind_t;
typedef uint32_t activity_op_t;
/* API callback phase */
typedef enum
{
ACTIVITY_API_PHASE_ENTER = 0,
ACTIVITY_API_PHASE_EXIT = 1
} activity_api_phase_t;
const char*
roctracer_op_string(uint32_t domain, uint32_t op);
/* Trace record types */
/**
* Memory pool allocator callback.
*
* If \p *ptr is NULL, then allocate memory of \p size bytes and save address
* in \p *ptr.
*
* If \p *ptr is non-NULL and size is non-0, then reallocate the memory at \p
* *ptr with size \p size and save the address in \p *ptr. The memory will have
* been allocated by the same callback.
*
* If \p *ptr is non-NULL and size is 0, then deallocate the memory at \p *ptr.
* The memory will have been allocated by the same callback.
*
* \p size is the size of the memory allocation or reallocation, or 0 if
* deallocating.
*
* \p arg Argument provided
*/
typedef void (*roctracer_allocator_t)(char** ptr, size_t size, void* arg);
/**
* Memory pool buffer callback.
*
* The callback that will be invoked when a memory pool buffer becomes full or
* is flushed.
*
* \p begin pointer to first entry entry in the buffer.
*
* \p end pointer to one past the end entry in the buffer.
*
* \p arg the argument specified when the callback was defined.
*/
typedef void (*roctracer_buffer_callback_t)(const char* begin, const char* end, void* arg);
/**
* Memory pool properties.
*
* Defines the properties when a tracer memory pool is created.
*/
typedef struct
{
/**
* ROC Tracer mode.
*/
uint32_t mode;
/**
* Size of buffer in bytes.
*/
size_t buffer_size;
/**
* The allocator function to use to allocate and deallocate the buffer. If
* NULL then \p malloc, \p realloc, and \p free are used.
*/
roctracer_allocator_t alloc_fun;
/**
* The argument to pass when invoking the \p alloc_fun allocator.
*/
void* alloc_arg;
/**
* The function to call when a buffer becomes full or is flushed.
*/
roctracer_buffer_callback_t buffer_callback_fun;
/**
* The argument to pass when invoking the \p buffer_callback_fun callback.
*/
void* buffer_callback_arg;
} roctracer_properties_t;
/**
* ROC Tracer API status codes.
*/
typedef enum
{
/**
* The function has executed successfully.
*/
ROCTRACER_STATUS_SUCCESS = 0,
/**
* A generic error has occurred.
*/
ROCTRACER_STATUS_ERROR = -1,
/**
* The domain ID is invalid.
*/
ROCTRACER_STATUS_ERROR_INVALID_DOMAIN_ID = -2,
/**
* An invalid argument was given to the function.
*/
ROCTRACER_STATUS_ERROR_INVALID_ARGUMENT = -3,
/**
* No default pool is defined.
*/
ROCTRACER_STATUS_ERROR_DEFAULT_POOL_UNDEFINED = -4,
/**
* The default pool is already defined.
*/
ROCTRACER_STATUS_ERROR_DEFAULT_POOL_ALREADY_DEFINED = -5,
/**
* Memory allocation error.
*/
ROCTRACER_STATUS_ERROR_MEMORY_ALLOCATION = -6,
/**
* External correlation ID pop mismatch.
*/
ROCTRACER_STATUS_ERROR_MISMATCHED_EXTERNAL_CORRELATION_ID = -7,
/**
* The operation is not currently implemented. This error may be reported by
* any function. Check the \ref known_limitations section to determine the
* status of the library implementation of the interface.
*/
ROCTRACER_STATUS_ERROR_NOT_IMPLEMENTED = -8,
/**
* Deprecated error code.
*/
ROCTRACER_STATUS_UNINIT = 2,
/**
* Deprecated error code.
*/
ROCTRACER_STATUS_BREAK = 3,
/**
* Deprecated error code.
*/
ROCTRACER_STATUS_BAD_DOMAIN = ROCTRACER_STATUS_ERROR_INVALID_DOMAIN_ID,
/**
* Deprecated error code.
*/
ROCTRACER_STATUS_BAD_PARAMETER = ROCTRACER_STATUS_ERROR_INVALID_ARGUMENT,
/**
* Deprecated error code.
*/
ROCTRACER_STATUS_HIP_API_ERR = 6,
/**
* Deprecated error code.
*/
ROCTRACER_STATUS_HIP_OPS_ERR = 7,
/**
* Deprecated error code.
*/
ROCTRACER_STATUS_HCC_OPS_ERR = ROCTRACER_STATUS_HIP_OPS_ERR,
/**
* Deprecated error code.
*/
ROCTRACER_STATUS_HSA_ERR = 7,
/**
* Deprecated error code.
*/
ROCTRACER_STATUS_ROCTX_ERR = 8,
} roctracer_status_t;
/**
* Query textual name of an operation of a domain.
* @param[in] domain Domain being queried.
* @param[in] op Operation within \p domain.
* @param[in] kind \todo Define kind.
* @return Returns the NUL terminated string for the operation name, or NULL if
* the domain or operation are invalid. The string is owned by the ROC Tracer
* library.
*/
const char*
roctracer_op_string(uint32_t domain, uint32_t op, uint32_t kind);
/**
* Query the operation code given a domain and the name of an operation.
* @param[in] domain The domain being queried.
* @param[in] str The NUL terminated name of the operation name being queried.
* @param[out] op The operation code.
* @param[out] kind If not NULL then the operation kind code.
*/
void
roctracer_op_code(uint32_t domain, const char* str, uint32_t* op, uint32_t* kind);
/**
* Set the properties of a domain.
* @param[in] domain The domain.
* @param[in] properties The properties. Each domain defines its own type for
* the properties. Some domains require the properties to be set before they
* can be enabled.
*/
void
roctracer_set_properties(roctracer_domain_t domain, void* properties);
/**
* Enable runtime API callback for a specific operation of a domain.
* @param domain The domain.
* @param op The operation ID in \p domain.
* @param callback The callback to invoke each time the operation is performed
* on entry and exit.
* @param pool Value to pass as last argument of \p callback.
*/
void
roctracer_enable_op_callback(roctracer_domain_t domain,
uint32_t op,
roctracer_rtapi_callback_t callback);
/**
* Enable runtime API callback for all operations of a domain.
* @param domain The domain
* @param callback The callback to invoke each time the operation is performed
* on entry and exit.
* @param arg Value to pass as last argument of \p callback.
*/
void
roctracer_enable_domain_callback(roctracer_domain_t domain,
roctracer_rtapi_callback_t callback,
void* user_data = nullptr);
/**
* Disable runtime API callback for a specific operation of a domain.
* @param domain The domain
* @param op The operation in \p domain.
*/
void
roctracer_disable_op_callback(roctracer_domain_t domain, uint32_t op);
/**
* Disable runtime API callback for all operations of a domain.
* @param domain The domain
*/
void
roctracer_disable_domain_callback(roctracer_domain_t domain);
/**
* Enable activity record logging for a specified operation of a domain using
* the default memory pool.
* @param[in] domain The domain.
* @param[in] op The activity operation ID in \p domain.
*/
void
roctracer_enable_op_activity(roctracer_domain_t domain, uint32_t op, roctracer_pool_t pool);
/**
* Enable activity record logging for all operations of a domain using the
* default memory pool.
* @param[in] domain The domain.
*/
void
roctracer_enable_domain_activity(roctracer_domain_t domain, roctracer_pool_t pool);
/**
* Disable activity record logging for a specified operation of a domain.
* @param[in] domain The domain.
* @param[in] op The activity operation ID in \p domain.
*/
void
roctracer_disable_op_activity(roctracer_domain_t domain, uint32_t op);
/**
* Disable activity record logging for all operations of a domain.
* @param[in] domain The domain.
*/
void
roctracer_disable_domain_activity(roctracer_domain_t domain);
// HIP Support
typedef enum
{
HIP_OP_ID_DISPATCH = 0,
HIP_OP_ID_COPY = 1,
HIP_OP_ID_BARRIER = 2,
HIP_OP_ID_NUMBER = 3
} hip_op_id_t;
// HSA Support
// HSA OP ID enumeration
enum hsa_op_id_t
{
HSA_OP_ID_DISPATCH = 0,
HSA_OP_ID_COPY = 1,
HSA_OP_ID_BARRIER = 2,
HSA_OP_ID_RESERVED1 = 3,
HSA_OP_ID_NUMBER
};
// HSA EVT ID enumeration
enum hsa_evt_id_t
{
HSA_EVT_ID_ALLOCATE = 0, // Memory allocate callback
HSA_EVT_ID_DEVICE = 1, // Device assign callback
HSA_EVT_ID_MEMCOPY = 2, // Memcopy callback
HSA_EVT_ID_SUBMIT = 3, // Packet submission callback
HSA_EVT_ID_KSYMBOL = 4, // Loading/unloading of kernel symbol
HSA_EVT_ID_CODEOBJ = 5, // Loading/unloading of device code object
HSA_EVT_ID_NUMBER
};
struct hsa_ops_properties_t
{
void* reserved1[4];
};
// ROCTx Support
typedef uint64_t roctx_range_id_t;
/**
* ROCTX API ID enumeration
*/
enum roctx_api_id_t
{
ROCTX_API_ID_roctxMarkA = 0,
ROCTX_API_ID_roctxRangePushA = 1,
ROCTX_API_ID_roctxRangePop = 2,
ROCTX_API_ID_roctxRangeStartA = 3,
ROCTX_API_ID_roctxRangeStop = 4,
ROCTX_API_ID_NUMBER,
};
/**
* ROCTX callbacks data type
*/
typedef struct roctx_api_data_s
{
union
{
struct
{
const char* message;
roctx_range_id_t id;
};
struct
{
const char* message;
} roctxMarkA;
struct
{
const char* message;
} roctxRangePushA;
struct
{
const char* message;
} roctxRangePop;
struct
{
const char* message;
roctx_range_id_t id;
} roctxRangeStartA;
struct
{
const char* message;
roctx_range_id_t id;
} roctxRangeStop;
} args;
} roctx_api_data_t;
// External Support
/* Extension opcodes */
typedef enum
{
ACTIVITY_EXT_OP_MARK = 0,
ACTIVITY_EXT_OP_EXTERN_ID = 1
} activity_ext_op_t;
typedef void (*roctracer_start_cb_t)();
typedef void (*roctracer_stop_cb_t)();
typedef struct
{
roctracer_start_cb_t start_cb;
roctracer_stop_cb_t stop_cb;
} roctracer_ext_properties_t;
// Tracing start
void
roctracer_start();
// Tracing stop
void
roctracer_stop();
// Notifies that the calling thread is entering an external region.
// Push an external correlation id for the calling thread.
void
roctracer_activity_push_external_correlation_id(activity_correlation_id_t id);
// Notifies that the calling thread is leaving an external region.
// Pop an external correlation id for the calling thread.
// 'lastId' returns the last external correlation if not NULL
void
roctracer_activity_pop_external_correlation_id(activity_correlation_id_t* last_id);
+1
Просмотреть файл
@@ -0,0 +1 @@
+1
Просмотреть файл
@@ -0,0 +1 @@