Initial Implementation: include (#10)

* Initial Implementation: include

* Initial Implementation: lib details (#11)

* Initial Implementation: lib details

* Initial Implementation: lib (#12)

* Initial Implementation: lib

* Initial Implementation: source (#13)

* Initial Implementation: source

* Initial Implementation: samples (#14)

* Initial Implementation: samples

* Initial Implementation: tests (#15)

* Initial Implementation: tests

* Initial Implementation: scripts (#16)

* Initial Implementation: scripts

* Initial Implementation: cmake (#17)

* Initial Implementation: cmake

* Initial Implementation: top-level files (#18)

* Initial Implementation: top-level files

- clang-format
- clang-tidy
- cmake-format
- ignore build and cache directories
- main CMakeLists.txt
- pyproject.toml (python formatting)
- VERSION file

* Initial Implementation: workflow (#19)

* Fix unused variable

- rocprofiler_register_warn_level
This commit is contained in:
Jonathan R. Madsen
2023-08-17 14:59:24 -05:00
zatwierdzone przez GitHub
rodzic 53a9547670
commit fa4295db6b
68 zmienionych plików z 7367 dodań i 0 usunięć
+114
Wyświetl plik
@@ -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: 90
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: true
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 0
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
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: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: Never
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Auto
TabWidth: 4
UseTab: Never
...
+55
Wyświetl plik
@@ -0,0 +1,55 @@
---
Checks: "-*,\
misc-*,\
-misc-incorrect-roundings,\
-misc-macro-parentheses,\
-misc-misplaced-widening-cast,\
-misc-static-assert,\
-misc-no-recursion,\
-misc-non-private-member-variables-in-classes,\
-misc-include-cleaner,\
-misc-const-correctness,\
modernize-*,\
-modernize-deprecated-headers,\
-modernize-raw-string-literal,\
-modernize-return-braced-init-list,\
-modernize-use-transparent-functors,\
-modernize-use-trailing-return-type,\
-modernize-avoid-c-arrays,\
-modernize-redundant-void-arg,\
-modernize-use-using,\
-modernize-use-auto,\
-modernize-concat-nested-namespaces,\
-modernize-use-nodiscard,\
-modernize-macro-to-enum,\
-modernize-type-traits,\
performance-*,\
readability-*,\
-readability-function-size,\
-readability-identifier-naming,\
-readability-implicit-bool-cast,\
-readability-inconsistent-declaration-parameter-name,\
-readability-named-parameter,\
-readability-magic-numbers,\
-readability-redundant-declaration,\
-readability-redundant-member-init,\
-readability-simplify-boolean-expr,\
-readability-uppercase-literal-suffix,\
-readability-braces-around-statements,\
-readability-avoid-const-params-in-decls,\
-readability-else-after-return,\
-readability-isolate-declaration,\
-readability-redundant-string-cstr,\
-readability-static-accessed-through-instance,\
-readability-const-return-type,\
-readability-redundant-access-specifiers,\
-readability-function-cognitive-complexity,\
-readability-identifier-length,\
-readability-use-anyofallof,\
"
CheckOptions:
- key: readability-braces-around-statements.ShortStatementLines
value: '2'
- key: readability-implicit-bool-conversion.AllowPointerConditions
value: '1'
...
+318
Wyświetl plik
@@ -0,0 +1,318 @@
parse:
additional_commands:
rocprofiler_register_checkout_git_submodule:
flags:
- RECURSIVE
kwargs:
RELATIVE_PATH: '*'
WORKING_DIRECTORY: '*'
TEST_FILE: '*'
REPO_URL: '*'
REPO_BRANCH: '*'
ADDITIONAL_COMMANDS: '*'
rocprofiler_register_save_variables:
kwargs:
VARIABLES: '*'
CONDITION: '*'
rocprofiler_register_restore_variables:
kwargs:
VARIABLES: '*'
CONDITION: '*'
rocprofiler_register_target_compile_options:
flags:
- BUILD_INTERFACE
- FORCE
kwargs:
PUBLIC: '*'
PRIVATE: '*'
INTERFACE: '*'
LANGUAGES: '*'
LINK_LANGUAGES: '*'
rocprofiler_register_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_register_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_register_target_compile_definitions:
kwargs:
PUBLIC: '*'
PRIVATE: '*'
INTERFACE: '*'
rocprofiler_register_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_register_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_register_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_register_find_python:
flags:
- REQUIRED
- QUIET
kwargs:
VERSION: '*'
ROOT_DIR: '*'
COMPONENTS: '*'
rocprofiler_register_python_console_script:
kwargs:
VERSION: '*'
ROOT_DIR: '*'
rocprofiler_register_pybind11_add_module:
flags:
- MODULE
- SHARED
- EXCLUDE_FROM_ALL
- NO_EXTRAS
- SYSTEM
- THIN_LTO
- LTO
kwargs:
PYTHON_VERSION: '*'
CXX_STANDARD: '*'
VISIBILITY: '*'
rocprofiler_register_directory:
flags:
- MKDIR
- FAIL
kwargs:
PREFIX: '*'
OUTPUT_VARIABLE: '*'
WORKING_DIRECTORY: '*'
PATHS: '*'
rocprofiler_register_check_python_dirs_and_versions:
flags:
- UNSET
- FAIL
kwargs:
RESULT_VARIABLE: '*'
OUTPUT_VARIABLE: '*'
rocprofiler_register_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_register_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_register_causal_example_executable:
kwargs:
TAG: '*'
SOURCES: '*'
DEFINITIONS: '*'
LINK_LIBRARIES: '*'
INCLUDE_DIRECTORIES: '*'
rocprofiler_register_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: '*'
rocp_register_test_executable:
kwargs:
SECURE: '*'
SOURCES: '*'
LIBRARIES: '*'
CORE_PASS_REGEX: '*'
CORE_FAIL_REGEX: '*'
PRELOAD_PASS_REGEX: '*'
PRELOAD_FAIL_REGEX: '*'
WRAP_PASS_REGEX: '*'
WRAP_FAIL_REGEX: '*'
PRELOAD_WRAP_PASS_REGEX: '*'
PRELOAD_WRAP_FAIL_REGEX: '*'
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: {}
@@ -0,0 +1,172 @@
name: Continuous Integration
on:
push:
branches: [ main, develop ]
paths-ignore:
- '*.md'
pull_request:
branches: [ main, develop ]
paths-ignore:
- '*.md'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
ci:
strategy:
fail-fast: false
matrix:
runner: ['ubuntu-latest']
compiler: ['clang-13', 'clang-14', 'clang-15', 'gcc-11', 'gcc-12']
ci-args: ['']
ci-tag: ['']
include:
- runner: 'ubuntu-latest'
compiler: 'gcc-12'
ci-args: '--coverage'
ci-tag: '-codecov'
- runner: 'ubuntu-latest'
compiler: 'clang-15'
ci-args: '--linter clang-tidy'
ci-tag: '-clang-tidy'
# - runner: 'ubuntu-latest'
# compiler: 'gcc-12'
# ci-args: '--memcheck ThreadSanitizer'
# ci-tag: '-thread-sanitizer'
# - runner: 'ubuntu-latest'
# compiler: 'gcc-12'
# ci-args: '--memcheck AddressSanitizer'
# ci-tag: '-address-sanitizer'
# - runner: 'ubuntu-latest'
# compiler: 'gcc-12'
# ci-args: '--memcheck LeakSanitizer'
# ci-tag: '-leak-sanitizer'
# - runner: 'ubuntu-latest'
# compiler: 'gcc-12'
# ci-args: '--memcheck UndefinedBehaviorSanitizer'
# ci-tag: '-undefined-behavior-sanitizer'
runs-on: ${{ matrix.runner }}
env:
BUILD_TYPE: RelWithDebInfo
INSTALL_PREFIX: /opt/rocprofiler-register
PACKAGING_INSTALL_PREFIX: /opt/rocm
steps:
- uses: actions/checkout@v3
- name: Install Packages
timeout-minutes: 25
run: |
CC=${{ matrix.compiler }} &&
CXX=$(echo ${{ matrix.compiler }} | sed 's/clang-/clang++-/1' | sed 's/gcc-/g++-/1') &&
sudo apt-get update &&
sudo apt-get install -y build-essential python3 environment-modules ${{ matrix.compiler }} ${CXX} &&
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/${CC} 100 &&
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/${CXX} 100 &&
python3 -m pip install --upgrade pip &&
python3 -m pip install 'cmake==3.21.4'
- name: Setup GCov
timeout-minutes: 25
if: ${{ matrix.compiler == 'gcc-12' }}
run: |
sudo update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-12 100
- name: Setup Clang-Tidy
timeout-minutes: 25
if: ${{ matrix.compiler == 'clang-15' }}
run: |
sudo apt-get install -y clang-tidy-15
sudo update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-15 100
- name: Configure, Build, and Test
timeout-minutes: 115
shell: bash
run:
cmake --version &&
python3 ./scripts/run-ci.py -B build
--name ${{ github.repository_owner }}-${{ github.ref_name }}-${{ matrix.runner }}-${{ matrix.compiler }}${{ matrix.ci-tag }}
--build-jobs 2
--site GitHub
${{ matrix.ci-args }}
--disable-cdash
--
-DCMAKE_C_COMPILER=/usr/bin/cc
-DCMAKE_CXX_COMPILER=/usr/bin/c++
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}
-DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_PREFIX }}
-DROCPROFILER_REGISTER_BUILD_TESTS=ON
-DROCPROFILER_REGISTER_BUILD_SAMPLES=ON
--
-VV
- name: Install
timeout-minutes: 10
run:
cmake --build build --target install --parallel 2
- name: CPack and Install
run: |
cd build
cpack -G STGZ
mkdir -p ${{ env.PACKAGING_INSTALL_PREFIX }}
./rocprofiler-register-*-Linux.sh --prefix=${{ env.PACKAGING_INSTALL_PREFIX }} --exclude-subdir --skip-license
- name: Test Install Modulefile
timeout-minutes: 15
shell: bash
run: |
set -v
source /usr/share/modules/init/$(basename ${SHELL})
module use ${{ env.INSTALL_PREFIX }}/share/modulefiles
module avail
module load rocprofiler-register
pushd tests
BUILD_DIR=${PWD}/build-rocp-reg-modulefile
cmake -B ${BUILD_DIR} .
cmake --build ${BUILD_DIR} --target all
rm -rf ${BUILD_DIR}
- name: Test Install Setup Env
timeout-minutes: 15
shell: bash
run: |
set -v
source ${{ env.INSTALL_PREFIX }}/share/rocprofiler-register/setup-env.sh
pushd samples/library-implementation
BUILD_DIR=${PWD}/build-rocp-reg-setup-env
cmake -B ${BUILD_DIR} .
cmake --build ${BUILD_DIR} --target all
rm -rf ${BUILD_DIR}
- name: Test Install CPack Modulefile
timeout-minutes: 15
shell: bash
run: |
set -v
source /usr/share/modules/init/$(basename ${SHELL})
module use ${{ env.PACKAGING_INSTALL_PREFIX }}/share/modulefiles
module avail
module load rocprofiler-register
pushd tests
BUILD_DIR=${PWD}/build-rocp-reg-modulefile-cpack
cmake -B ${BUILD_DIR} .
cmake --build ${BUILD_DIR} --target all
rm -rf ${BUILD_DIR}
- name: Test Install CPack Setup Env
timeout-minutes: 15
shell: bash
run: |
set -v
source ${{ env.PACKAGING_INSTALL_PREFIX }}/share/rocprofiler-register/setup-env.sh
pushd samples/library-implementation
BUILD_DIR=${PWD}/build-rocp-reg-setup-env-cpack
cmake -B ${BUILD_DIR} .
cmake --build ${BUILD_DIR} --target all
rm -rf ${BUILD_DIR}
+146
Wyświetl plik
@@ -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 }}
+4
Wyświetl plik
@@ -30,3 +30,7 @@
*.exe
*.out
*.app
# Build directories
/build*
/.cache
+110
Wyświetl plik
@@ -0,0 +1,110 @@
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_REGISTER_VERSION "${FULL_VERSION_STRING}")
foreach(_LANG C CXX)
set(CMAKE_${_LANG}_FLAGS_COVERAGE_INIT
"-Og -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-inline-functions -fprofile-abs-path -fprofile-arcs -ftest-coverage --coverage"
CACHE STRING "${_LANG} flags for code coverage builds")
set(CMAKE_${_LANG}_FLAGS_COVERAGE
"${CMAKE_${_LANG}_FLAGS_COVERAGE_INIT}"
CACHE STRING "${_LANG} flags for code coverage builds")
endforeach()
project(
rocprofiler-register
LANGUAGES C CXX
VERSION ${ROCPROFILER_REGISTER_VERSION}
DESCRIPTION "Registration library for rocprofiler"
HOMEPAGE_URL "https://github.com/ROCm-Developer-Tools/rocprofiler-register-internal")
# needed for modulefile and setup-env.sh
string(REPLACE "-" "_" PROJECT_NAME_UNDERSCORED "${PROJECT_NAME}")
find_package(Git)
if(Git_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --tags
OUTPUT_VARIABLE ROCPROFILER_REGISTER_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_REGISTER_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_REGISTER_GIT_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
else()
set(ROCPROFILER_REGISTER_GIT_DESCRIBE "v${ROCPROFILER_REGISTER_VERSION}")
set(ROCPROFILER_REGISTER_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_REGISTER_GIT_REVISION}")
message(STATUS "[${PROJECT_NAME}] git describe: ${ROCPROFILER_REGISTER_GIT_DESCRIBE}")
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${PROJECT_SOURCE_DIR}/cmake/Modules
${CMAKE_MODULE_PATH})
include(GNUInstallDirs) # install directories
include(rocprofiler_register_utilities) # various functions/macros
include(rocprofiler_register_interfaces) # interface libraries
include(rocprofiler_register_compilers) # compiler identification
include(rocprofiler_register_options) # project options
include(rocprofiler_register_build_settings) # build flags
include(rocprofiler_register_formatting) # formatting
include(rocprofiler_register_linting) # clang-tidy
include(rocprofiler_register_config_interfaces) # configure interface libraries
set(CMAKE_C_VISIBILITY_PRESET "hidden")
set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
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}")
enable_testing()
include(CTest)
add_subdirectory(source)
if(ROCPROFILER_REGISTER_BUILD_TESTS)
add_subdirectory(tests)
endif()
if(ROCPROFILER_REGISTER_BUILD_SAMPLES)
add_subdirectory(samples)
endif()
#
include(rocprofiler_register_config_install)
include(rocprofiler_register_config_packaging)
rocprofiler_register_print_features()
+1
Wyświetl plik
@@ -0,0 +1 @@
0.1.0
+16
Wyświetl plik
@@ -0,0 +1,16 @@
#%Module1.0
module-whatis "@PROJECT_NAME_UNDERSCORED@ (version @PROJECT_VERSION@)"
proc ModulesHelp { } {
puts stderr "Loads @PROJECT_NAME_UNDERSCORED@ v@PROJECT_VERSION@"
}
set ROOT [file normalize [file dirname [file normalize ${ModulesCurrentModulefile}]]/../../..]
setenv @PROJECT_NAME_UNDERSCORED@_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_UNDERSCORED@_DIR "${ROOT}/@CMAKE_INSTALL_DATAROOTDIR@/cmake/@PROJECT_NAME_UNDERSCORED@"
@@ -0,0 +1,32 @@
# - 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)
include("${@PROJECT_NAME@_CMAKE_DIR}/@PROJECT_NAME@-library-targets.cmake")
if(TARGET @PROJECT_NAME@::@PROJECT_NAME@)
set(@PROJECT_NAME@_LIBRARIES @PROJECT_NAME@::@PROJECT_NAME@)
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
Wyświetl plik
@@ -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_UNDERSCORED@_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_UNDERSCORED@_DIR=${BASEDIR}/@CMAKE_INSTALL_DATAROOTDIR@/cmake/@PROJECT_NAME_UNDERSCORED@
export @PROJECT_NAME_UNDERSCORED@_ROOT
export PATH
export LD_LIBRARY_PATH
export PYTHONPATH
export CMAKE_PREFIX_PATH
export @PROJECT_NAME_UNDERSCORED@_DIR
@@ -0,0 +1,107 @@
# ########################################################################################
#
# Handles the build settings
#
# ########################################################################################
include_guard(DIRECTORY)
include(GNUInstallDirs)
include(FindPackageHandleStandardArgs)
include(rocprofiler_register_compilers)
include(rocprofiler_register_utilities)
target_compile_definitions(rocprofiler-register-build-flags
INTERFACE $<$<CONFIG:DEBUG>:DEBUG>)
if(ROCPROFILER_REGISTER_BUILD_CI)
rocprofiler_register_target_compile_definitions(rocprofiler-register-build-flags
INTERFACE ROCPROFILER_REGISTER_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_register_target_compile_definitions(
rocprofiler-register-${_TYPE}
INTERFACE ROCPROFILER_REGISTER_${_TYPE_UC}=1)
target_link_libraries(rocprofiler-register-${_TYPE}
INTERFACE ${${_TYPE}_LIBRARY})
if("${_TYPE}" STREQUAL "dl" AND NOT ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY)
# 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_register_target_compile_options(
rocprofiler-register-${_TYPE}
LANGUAGES C CXX
LINK_LANGUAGES C CXX
INTERFACE "-rdynamic")
endif()
else()
rocprofiler_register_target_compile_definitions(
rocprofiler-register-${_TYPE}
INTERFACE ROCPROFILER_REGISTER_${_TYPE_UC}=0)
endif()
endif()
endforeach()
target_link_libraries(rocprofiler-register-build-flags INTERFACE rocprofiler-register::dl)
# ----------------------------------------------------------------------------------------#
# set the compiler flags
#
rocprofiler_register_target_compile_options(
rocprofiler-register-build-flags
INTERFACE "-W" "-Wall" "-Wno-unknown-pragmas" "-fstack-protector-strong"
"-Wstack-protector")
# ----------------------------------------------------------------------------------------#
# debug-safe optimizations
#
rocprofiler_register_target_compile_options(
rocprofiler-register-build-flags
LANGUAGES CXX
INTERFACE "-faligned-new")
# ----------------------------------------------------------------------------------------#
# developer build flags
#
rocprofiler_register_target_compile_options(
rocprofiler-register-developer-flags
LANGUAGES C CXX
INTERFACE "-Werror" "-Wdouble-promotion" "-Wshadow" "-Wextra")
if(NOT ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY)
rocprofiler_register_target_compile_options(
rocprofiler-register-developer-flags
LANGUAGES C CXX
INTERFACE "-Wstack-usage=524288" # 512 KB
)
endif()
if(ROCPROFILER_REGISTER_BUILD_DEVELOPER)
target_link_libraries(rocprofiler-register-build-flags
INTERFACE rocprofiler-register::developer-flags)
endif()
# ----------------------------------------------------------------------------------------#
# user customization
#
get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
if(NOT APPLE OR "$ENV{CONDA_PYTHON_EXE}" STREQUAL "")
rocprofiler_register_target_user_flags(rocprofiler-register-build-flags "CXX")
endif()
@@ -0,0 +1,352 @@
# 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_register_utilities)
# ----------------------------------------------------------------------------------------#
# macro converting string to list
# ----------------------------------------------------------------------------------------#
macro(ROCPROFILER_REGISTER_TO_LIST _VAR _STR)
string(REPLACE " " " " ${_VAR} "${_STR}")
string(REPLACE " " ";" ${_VAR} "${_STR}")
endmacro()
# ----------------------------------------------------------------------------------------#
# macro converting string to list
# ----------------------------------------------------------------------------------------#
macro(ROCPROFILER_REGISTER_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_REGISTER_BEGIN_FLAG_CHECK)
if(ROCPROFILER_REGISTER_QUIET_CONFIG)
if(NOT DEFINED CMAKE_REQUIRED_QUIET)
set(CMAKE_REQUIRED_QUIET OFF)
endif()
rocprofiler_register_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_REGISTER_END_FLAG_CHECK)
if(ROCPROFILER_REGISTER_QUIET_CONFIG)
rocprofiler_register_restore_variables(FLAG_CHECK VARIABLES CMAKE_REQUIRED_QUIET)
endif()
endmacro()
# ----------------------------------------------------------------------------------------#
# check flag
# ----------------------------------------------------------------------------------------#
function(ROCPROFILER_REGISTER_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_register_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_register_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_register_c_error AND NOT DEFINED
rocprofiler_register_cxx_error)
rocprofiler_register_begin_flag_check()
check_c_compiler_flag("-Werror" c_rocprofiler_register_werror)
check_cxx_compiler_flag("-Werror" cxx_rocprofiler_register_werror)
rocprofiler_register_end_flag_check()
endif()
foreach(_TARG_MODE PUBLIC INTERFACE PRIVATE)
foreach(_FLAG ${_TARG_${_TARG_MODE}})
foreach(_LANG ${_TARG_LANGUAGES})
unset(FLAG_NAME)
rocprofiler_register_target_compile_option_patch_name(${_LANG} "${_FLAG}"
FLAG_NAME)
if(_TARG_FORCE)
set(${FLAG_NAME}
1
CACHE INTERNAL "${_LANG} flag: ${_FLAG}")
else()
rocprofiler_register_begin_flag_check()
if("${_LANG}" STREQUAL "C")
if(c_rocprofiler_register_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_register_werror)
check_cxx_compiler_flag("${_FLAG} -Werror" ${FLAG_NAME})
else()
check_cxx_compiler_flag("${_FLAG}" ${FLAG_NAME})
endif()
else()
message(
FATAL_ERROR
"rocprofiler_register_target_compile_option :: unknown language: ${_LANG}"
)
endif()
rocprofiler_register_end_flag_check()
endif()
if(${FLAG_NAME})
rocprofiler_register_target_compile_option_impl(
${_TARG_TARGET} ${_TARG_MODE} ${_LANG} "${_FLAG}")
endif()
endforeach()
endforeach()
endforeach()
endfunction()
# ----------------------------------------------------------------------------------------#
# add to any language
# ----------------------------------------------------------------------------------------#
function(ROCPROFILER_REGISTER_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_REGISTER_TARGET_COMPILE_DEFINITIONS _TARG _VIS)
foreach(_DEF ${ARGN})
if(NOT "${_DEF}" MATCHES "[A-Za-z_]+=.*" AND "${_DEF}" MATCHES
"^ROCPROFILER_REGISTER_")
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()
@@ -0,0 +1,87 @@
# include guard
include_guard(GLOBAL)
include(CMakePackageConfigHelpers)
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME config)
install(
EXPORT rocprofiler-register-library-targets
FILE rocprofiler-register-library-targets.cmake
NAMESPACE rocprofiler-register::
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/rocprofiler-register)
configure_file(
${PROJECT_SOURCE_DIR}/cmake/Templates/setup-env.sh.in
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/setup-env.sh @ONLY)
configure_file(
${PROJECT_SOURCE_DIR}/cmake/Templates/modulefile.in
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/modulefiles/${PROJECT_NAME}/${PROJECT_VERSION}
@ONLY)
install(
FILES ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/setup-env.sh
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}
COMPONENT setup)
install(
FILES
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/modulefiles/${PROJECT_NAME}/${PROJECT_VERSION}
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/modulefiles/${PROJECT_NAME}
COMPONENT setup)
# ------------------------------------------------------------------------------#
# install tree
#
set(PROJECT_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR})
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-register
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-register")
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-register-library-targets.cmake")
file(TOUCH "${_BUILDTREE_EXPORT_DIR}/rocprofiler-register-library-targets.cmake")
endif()
export(
EXPORT rocprofiler-register-library-targets
NAMESPACE rocprofiler-register::
FILE "${_BUILDTREE_EXPORT_DIR}/rocprofiler-register-library-targets.cmake")
set(rocprofiler_register_DIR
"${_BUILDTREE_EXPORT_DIR}"
CACHE PATH "rocprofiler-register" FORCE)
@@ -0,0 +1,67 @@
# include guard
include_guard(DIRECTORY)
# ########################################################################################
#
# External Packages are found here
#
# ########################################################################################
target_include_directories(
rocprofiler-register-headers
INTERFACE $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/source/include>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/source/include>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/source>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
# ensure the env overrides the appending /opt/rocm later
string(REPLACE ":" ";" CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH};${CMAKE_PREFIX_PATH}")
# ----------------------------------------------------------------------------------------#
#
# Threading
#
# ----------------------------------------------------------------------------------------#
set(CMAKE_THREAD_PREFER_PTHREAD ON)
set(THREADS_PREFER_PTHREAD_FLAG OFF)
find_package(Threads ${rocprofiler_register_FIND_QUIETLY}
${rocprofiler_register_FIND_REQUIREMENT})
if(Threads_FOUND)
target_link_libraries(rocprofiler-register-threading
INTERFACE $<BUILD_INTERFACE:Threads::Threads>)
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-register-${_LIB} INTERFACE $<BUILD_INTERFACE:${${_LIB}_LIBRARY}>
$<INSTALL_INTERFACE:${_LIB}>)
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-register-stdcxxfs
INTERFACE $<BUILD_INTERFACE:${stdcxxfs_LIBRARY}>)
else()
target_link_libraries(rocprofiler-register-stdcxxfs
INTERFACE $<BUILD_INTERFACE:stdc++fs>)
endif()
@@ -0,0 +1,100 @@
# configure packaging
# 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_REGISTER_CPACK_SYSTEM_NAME
"${CMAKE_SYSTEM_NAME}"
CACHE STRING "System name, e.g. Linux or <OS>-<VERSION>")
set(ROCPROFILER_REGISTER_CPACK_PACKAGE_SUFFIX
""
CACHE STRING "Package suffix")
set(CPACK_PACKAGE_FILE_NAME
"${CPACK_PACKAGE_NAME}-${ROCPROFILER_REGISTER_VERSION}-${ROCPROFILER_REGISTER_CPACK_SYSTEM_NAME}${ROCPROFILER_REGISTER_CPACK_PACKAGE_SUFFIX}"
)
if(DEFINED ENV{CPACK_PACKAGE_FILE_NAME})
set(CPACK_PACKAGE_FILE_NAME $ENV{CPACK_PACKAGE_FILE_NAME})
endif()
set(ROCPROFILER_REGISTER_PACKAGE_FILE_NAME
${CPACK_PACKAGE_NAME}-${ROCPROFILER_REGISTER_VERSION}-${ROCPROFILER_REGISTER_CPACK_SYSTEM_NAME}${ROCPROFILER_REGISTER_CPACK_PACKAGE_SUFFIX}
)
rocprofiler_register_add_feature(ROCPROFILER_REGISTER_PACKAGE_FILE_NAME "CPack filename")
# -------------------------------------------------------------------------------------- #
#
# Debian package specific variables
#
# -------------------------------------------------------------------------------------- #
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "${PROJECT_HOMEPAGE_URL}")
set(CPACK_DEBIAN_PACKAGE_RELEASE
"${ROCPROFILER_REGISTER_CPACK_SYSTEM_NAME}${ROCPROFILER_REGISTER_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_REGISTER_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_register_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_REGISTER_CPACK_SYSTEM_NAME}${ROCPROFILER_REGISTER_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)
@@ -0,0 +1,104 @@
# ------------------------------------------------------------------------------#
#
# creates following targets to format code:
# - format
# - format-source
# - format-cmake
# - format-python
# - format-rocprofiler-register-source
# - format-rocprofiler-register-cmake
# - format-rocprofiler-register-python
#
# ------------------------------------------------------------------------------#
include_guard(DIRECTORY)
find_program(ROCPROFILER_REGISTER_CLANG_FORMAT_EXE NAMES clang-format-11
clang-format-mp-11)
find_program(ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE NAMES cmake-format)
find_program(ROCPROFILER_REGISTER_BLACK_FORMAT_EXE NAMES black)
add_custom_target(format-rocprofiler-register)
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_REGISTER_CLANG_FORMAT_EXE
OR ROCPROFILER_REGISTER_BLACK_FORMAT_EXE
OR ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE)
set(rocp_source_files)
set(rocp_header_files)
set(rocp_python_files)
set(rocp_cmake_files ${PROJECT_SOURCE_DIR}/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_REGISTER_CLANG_FORMAT_EXE AND (rocp_source_files OR rocp_header_files))
add_custom_target(
format-rocprofiler-register-source
${ROCPROFILER_REGISTER_CLANG_FORMAT_EXE} -i ${rocp_header_files}
${rocp_source_files}
COMMENT
"[rocprofiler-register] Running source formatter ${ROCPROFILER_REGISTER_CLANG_FORMAT_EXE}..."
)
endif()
if(ROCPROFILER_REGISTER_BLACK_FORMAT_EXE AND rocp_python_files)
add_custom_target(
format-rocprofiler-register-python
${ROCPROFILER_REGISTER_BLACK_FORMAT_EXE} -q ${rocp_python_files}
COMMENT
"[rocprofiler-register] Running Python formatter ${ROCPROFILER_REGISTER_BLACK_FORMAT_EXE}..."
)
endif()
if(ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE AND rocp_cmake_files)
add_custom_target(
format-rocprofiler-register-cmake
${ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE} -i ${rocp_cmake_files}
COMMENT
"[rocprofiler-register] Running CMake formatter ${ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE}..."
)
endif()
foreach(_TYPE source python cmake)
if(TARGET format-rocprofiler-register-${_TYPE})
add_dependencies(format-rocprofiler-register
format-rocprofiler-register-${_TYPE})
add_dependencies(format-${_TYPE} format-rocprofiler-register-${_TYPE})
endif()
endforeach()
foreach(_TYPE source python)
if(TARGET format-rocprofiler-register-${_TYPE})
add_dependencies(format format-rocprofiler-register-${_TYPE})
endif()
endforeach()
endif()
@@ -0,0 +1,34 @@
#
#
# Forward declaration of all INTERFACE targets
#
#
include(rocprofiler_register_utilities)
#
# interfaces for build flags
#
rocprofiler_register_add_interface_library(
rocprofiler-register-headers
"Provides minimal set of include flags to compile with rocprofiler-register")
rocprofiler_register_add_interface_library(
rocprofiler-register-build-flags
"Provides generalized build flags for rocprofiler-register" INTERNAL)
rocprofiler_register_add_interface_library(rocprofiler-register-threading
"Enables multithreading support" INTERNAL)
rocprofiler_register_add_interface_library(
rocprofiler-register-developer-flags
"Compiler flags for developers (more warnings, etc.)" INTERNAL)
rocprofiler_register_add_interface_library(rocprofiler-register-memcheck "Sanitizer"
INTERNAL)
#
# interfaces for libraries
#
rocprofiler_register_add_interface_library(
rocprofiler-register-dl "Build flags for dynamic linking library" INTERNAL)
rocprofiler_register_add_interface_library(rocprofiler-register-rt
"Build flags for runtime library" INTERNAL)
rocprofiler_register_add_interface_library(rocprofiler-register-stdcxxfs
"C++ filesystem library" INTERNAL)
@@ -0,0 +1,47 @@
include_guard(GLOBAL)
# ----------------------------------------------------------------------------------------#
#
# Clang Tidy
#
# ----------------------------------------------------------------------------------------#
find_program(
ROCPROFILER_REGISTER_CLANG_TIDY_COMMAND
NAMES clang-tidy-18
clang-tidy-17
clang-tidy-16
clang-tidy-15
clang-tidy-14
clang-tidy-13
clang-tidy-12
clang-tidy-11
clang-tidy)
macro(ROCPROFILER_REGISTER_ACTIVATE_CLANG_TIDY)
if(ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY)
if(NOT ROCPROFILER_REGISTER_CLANG_TIDY_COMMAND)
message(
FATAL_ERROR
"ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY is ON but clang-tidy is not found!"
)
endif()
set(CMAKE_CXX_CLANG_TIDY ${ROCPROFILER_REGISTER_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_REGISTER_DEACTIVATE_CLANG_TIDY)
set(CMAKE_CXX_CLANG_TIDY)
endmacro()
@@ -0,0 +1,40 @@
#
#
#
set(ROCPROFILER_REGISTER_MEMCHECK_TYPES "ThreadSanitizer" "AddressSanitizer"
"LeakSanitizer" "UndefinedBehaviorSanitizer")
if(ROCPROFILER_REGISTER_MEMCHECK AND NOT ROCPROFILER_REGISTER_MEMCHECK IN_LIST
ROCPROFILER_REGISTER_MEMCHECK_TYPES)
message(
FATAL_ERROR
"Unsupported memcheck type '${ROCPROFILER_REGISTER_MEMCHECK}'. Options: ${ROCPROFILER_REGISTER_MEMCHECK_TYPES}"
)
endif()
set_property(CACHE ROCPROFILER_REGISTER_MEMCHECK
PROPERTY STRINGS "${ROCPROFILER_REGISTER_MEMCHECK_TYPES}")
function(rocprofiler_register_add_memcheck_flags _TYPE _LIB)
target_compile_options(
rocprofiler-register-memcheck
INTERFACE $<BUILD_INTERFACE:-g3 -Og -fno-omit-frame-pointer
-fno-optimize-sibling-calls -fno-inline-functions -fsanitize=${_TYPE}>
-static-lib${_LIB})
target_link_options(
rocprofiler-register-memcheck INTERFACE $<BUILD_INTERFACE:-fsanitize=${_TYPE}
-static-lib${_LIB} -Wl,--no-undefined>)
endfunction()
# always unset so that it doesn't preload if memcheck disabled
unset(ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_ENV CACHE)
if(ROCPROFILER_REGISTER_MEMCHECK STREQUAL "AddressSanitizer")
rocprofiler_register_add_memcheck_flags("address" "asan")
elseif(ROCPROFILER_REGISTER_MEMCHECK STREQUAL "LeakSanitizer")
rocprofiler_register_add_memcheck_flags("leak" "lsan")
elseif(ROCPROFILER_REGISTER_MEMCHECK STREQUAL "ThreadSanitizer")
rocprofiler_register_add_memcheck_flags("thread" "tsan")
elseif(ROCPROFILER_REGISTER_MEMCHECK STREQUAL "UndefinedBehaviorSanitizer")
rocprofiler_register_add_memcheck_flags("undefined" "ubsan")
endif()
@@ -0,0 +1,90 @@
#
# rocprofiler_register_options.cmake
#
# Configure miscellaneous settings
#
# standard cmake options
rocprofiler_register_add_option(BUILD_SHARED_LIBS "Build shared libraries" ON)
rocprofiler_register_add_option(BUILD_STATIC_LIBS "Build static libraries" OFF)
rocprofiler_register_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_register_add_option(ROCPROFILER_REGISTER_BUILD_TESTS
"Enable building the tests" OFF)
rocprofiler_register_add_option(ROCPROFILER_REGISTER_BUILD_SAMPLES "Enable building the
code samples" OFF)
rocprofiler_register_add_option(ROCPROFILER_REGISTER_BUILD_CI
"Enable continuous integration additions" OFF ADVANCED)
rocprofiler_register_add_option(ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY
"Enable clang-tidy checks" OFF ADVANCED)
rocprofiler_register_add_option(
ROCPROFILER_REGISTER_BUILD_DEVELOPER "Extra build flags for development like -Werror"
${ROCPROFILER_REGISTER_BUILD_CI} ADVANCED)
# In the future, we will do this even with clang-tidy enabled
if(ROCPROFILER_REGISTER_BUILD_CI AND NOT ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY)
message(
STATUS
"Forcing ROCPROFILER_REGISTER_BUILD_DEVELOPER=ON because ROCPROFILER_REGISTER_BUILD_CI=ON"
)
set(ROCPROFILER_REGISTER_BUILD_DEVELOPER
ON
CACHE
BOOL
"Any compiler warnings are errors (forced due ROCPROFILER_REGISTER_BUILD_CI=ON)"
FORCE)
endif()
set(ROCPROFILER_REGISTER_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_REGISTER_BUILD_TYPES)
message(
FATAL_ERROR
"Unsupported build type '${CMAKE_BUILD_TYPE}'. Options: ${ROCPROFILER_REGISTER_BUILD_TYPES}"
)
endif()
if(ROCPROFILER_REGISTER_BUILD_CI)
foreach(_BUILD_TYPE ${ROCPROFILER_REGISTER_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_REGISTER_BUILD_TYPES}")
endif()
rocprofiler_register_add_cache_option(ROCPROFILER_REGISTER_MEMCHECK "" STRING
"Memory checker type" ADVANCED)
# ASAN is defined by testing team on Jenkins
if(ASAN)
set(ROCPROFILER_REGISTER_MEMCHECK
"AddressSanitizer"
CACHE STRING "Memory checker type (forced by ASAN defined)" FORCE)
endif()
include(rocprofiler_register_memcheck)
@@ -0,0 +1,941 @@
# 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_REGISTER_QUIET_CONFIG settings
# -----------------------------------------------------------------------
#
function(ROCPROFILER_REGISTER_MESSAGE TYPE)
if(NOT ROCPROFILER_REGISTER_QUIET_CONFIG)
message(${TYPE} "[rocprofiler-register] ${ARGN}")
endif()
endfunction()
# -----------------------------------------------------------------------
# Save a set of variables with the given prefix
# -----------------------------------------------------------------------
macro(ROCPROFILER_REGISTER_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_REGISTER_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_register_capitalize - make a string capitalized (first letter is
# capital) usage: capitalize("SHARED" CShared) message(STATUS "-- CShared is
# \"${CShared}\"") $ -- CShared is "Shared"
function(ROCPROFILER_REGISTER_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_register_strip_target(<TARGET> [FORCE] [EXPLICIT])
#
# Creates a post-build command which strips a binary. FORCE flag will override
#
function(ROCPROFILER_REGISTER_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_register_message(
FATAL_ERROR
"rocprofiler_register_strip_target cannot deduce target from \"${ARGN}\"")
endif()
if(NOT TARGET "${_TARGET}")
rocprofiler_register_message(
FATAL_ERROR
"rocprofiler_register_strip_target not provided valid target: \"${_TARGET}\"")
endif()
if(CMAKE_STRIP AND (STRIP_FORCE OR ROCPROFILER_REGISTER_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_register_init"
--keep-symbol="rocprofiler_register_finalize"
--keep-symbol="rocprofiler_register_push_trace"
--keep-symbol="rocprofiler_register_pop_trace"
--keep-symbol="rocprofiler_register_push_region"
--keep-symbol="rocprofiler_register_pop_region"
--keep-symbol="rocprofiler_register_set_env"
--keep-symbol="rocprofiler_register_set_mpi"
--keep-symbol="rocprofiler_register_reset_preload"
--keep-symbol="rocprofiler_register_set_instrumented"
--keep-symbol="rocprofiler_register_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_register_test_target()
#
# Creates a target which runs ctest but depends on all the tests being built.
#
function(ADD_ROCPROFILER_REGISTER_TEST_TARGET)
if(NOT TARGET rocprofiler-register-test)
add_custom_target(
rocprofiler-register-test
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR} --target test
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
COMMENT "Running tests...")
endif()
endfunction()
# ----------------------------------------------------------------------------------------#
# macro rocprofiler_register_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_REGISTER_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_register_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_register_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_REGISTER_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_REGISTER_ADD_INTERFACE_LIBRARY _TARGET _DESCRIPT)
add_library(${_TARGET} INTERFACE)
string(REPLACE "${PROJECT_NAME}-" "" _ALIAS_TARGET "${_TARGET}")
add_library(${PROJECT_NAME}::${_ALIAS_TARGET} ALIAS ${_TARGET})
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_REGISTER_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_REGISTER_BUILD_DOCS)
set_property(
GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_OPTIONS_DOC
"${_var}` | ${_description}${EXTRA_DESC} |")
endif()
elseif("DOC" IN_LIST ARGN AND ROCPROFILER_REGISTER_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_REGISTER_ADD_OPTION _NAME _MESSAGE _DEFAULT)
option(${_NAME} "${_MESSAGE}" ${_DEFAULT})
if("NO_FEATURE" IN_LIST ARGN)
mark_as_advanced(${_NAME})
else()
rocprofiler_register_add_feature(${_NAME} "${_MESSAGE}")
if(ROCPROFILER_REGISTER_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_register_add_cache_option(<OPTION_NAME> <DOCSRING> <TYPE>
# <DEFAULT_VALUE> [NO_FEATURE] [ADVANCED] [CMAKE_DEFINE])
#
function(ROCPROFILER_REGISTER_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_register_add_feature(${_NAME} "${_MESSAGE}")
if(ROCPROFILER_REGISTER_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_register_report_feature_changes() :: print changes in features
#
function(ROCPROFILER_REGISTER_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_register_watch_for_change(${_feature})
elseif("${_feature}" IN_LIST ARGN)
rocprofiler_register_watch_for_change(${_feature})
endif()
endforeach()
endfunction()
# ----------------------------------------------------------------------------------------#
# function print_enabled_features() Print enabled features plus their docstrings.
#
function(ROCPROFILER_REGISTER_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_register_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_REGISTER_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_REGISTER_PRINT_FEATURES)
rocprofiler_register_report_feature_changes()
rocprofiler_register_print_enabled_features()
rocprofiler_register_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_register_custom_compilation)
cmake_parse_arguments(COMP "GLOBAL;PROJECT" "COMPILER" "DIRECTORY;TARGET;SOURCE"
${ARGN})
# find rocprofiler-register-launch-compiler
find_program(
ROCPROFILER_REGISTER_COMPILE_LAUNCHER
NAMES rocprofiler-register-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_register_custom_compilation not provided COMPILER argument")
endif()
if(NOT ROCPROFILER_REGISTER_COMPILE_LAUNCHER)
message(
FATAL_ERROR
"rocprofiler-register could not find 'rocprofiler-register-launch-compiler'. Please set '-DROCPROFILER_REGISTER_COMPILE_LAUNCHER=/path/to/launcher'"
)
endif()
if(COMP_GLOBAL)
# if global, don't bother setting others
set_property(
GLOBAL
PROPERTY
RULE_LAUNCH_COMPILE
"${ROCPROFILER_REGISTER_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}"
)
set_property(
GLOBAL
PROPERTY
RULE_LAUNCH_LINK
"${ROCPROFILER_REGISTER_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}"
)
else()
foreach(_TYPE PROJECT DIRECTORY TARGET SOURCE)
# make project/subproject scoping easy, e.g.
# rocprofiler_register_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_REGISTER_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}"
)
set_property(
${_TYPE} ${_VAL}
PROPERTY
RULE_LAUNCH_LINK
"${ROCPROFILER_REGISTER_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}"
)
endforeach()
endif()
endforeach()
endif()
endfunction()
function(ROCPROFILER_REGISTER_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_register_watch_var_name ROCPROFILER_REGISTER_WATCH_VALUE_${_var})
if(DEFINED ${_rocprofiler_register_watch_var_name})
if("${${_var}}" STREQUAL "${${_rocprofiler_register_watch_var_name}}")
return()
else()
rocprofiler_register_message(
STATUS
"${_var} changed :: ${${_rocprofiler_register_watch_var_name}} --> ${${_var}}"
)
update_var(ON)
endif()
else()
if(NOT "${${_var}}" STREQUAL "")
rocprofiler_register_message(STATUS "${_var} :: ${${_var}}")
update_var(ON)
endif()
endif()
# store the value for the next run
set(${_rocprofiler_register_watch_var_name}
"${${_var}}"
CACHE INTERNAL "Last value of ${_var}" FORCE)
endfunction()
function(ROCPROFILER_REGISTER_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_register_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_register_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_register_message(FATAL_ERROR
"Directory '${_PATH}' does not exist")
elseif(NOT IS_DIRECTORY "${_PATH}" AND F_FAIL)
rocprofiler_register_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_REGISTER_CHECK_PYTHON_DIRS_AND_VERSIONS)
cmake_parse_arguments(F "FAIL;UNSET" "RESULT_VARIABLE;OUTPUT_VARIABLE" "" ${ARGN})
list(LENGTH ROCPROFILER_REGISTER_PYTHON_VERSIONS _NUM_PYTHON_VERSIONS)
list(LENGTH ROCPROFILER_REGISTER_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_register_message(
WARNING
"Error! Number of python versions : ${_NUM_PYTHON_VERSIONS}. VERSIONS :: ${ROCPROFILER_REGISTER_PYTHON_VERSIONS}"
)
rocprofiler_register_message(
WARNING
"Error! Number of python root directories : ${_NUM_PYTHON_ROOT_DIRS}. ROOT DIRS :: ${ROCPROFILER_REGISTER_PYTHON_ROOT_DIRS}"
)
rocprofiler_register_message(
FATAL_ERROR
"Error! Number of python versions != number of python root directories")
elseif(F_UNSET)
unset(ROCPROFILER_REGISTER_PYTHON_VERSIONS CACHE)
unset(ROCPROFILER_REGISTER_PYTHON_ROOT_DIRS CACHE)
if(F_OUTPUT_VARIABLE)
set(${F_OUTPUT_VARIABLE} 0)
endif()
endif()
endif()
endfunction()
# ----------------------------------------------------------------------------
# Console scripts
#
function(ROCPROFILER_REGISTER_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_REGISTER_BUILD_TESTING OR ROCPROFILER_REGISTER_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_REGISTER_FIND_STATIC_LIBRARY)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
find_library(${ARGN})
endfunction()
function(ROCPROFILER_REGISTER_FIND_SHARED_LIBRARY)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX})
find_library(${ARGN})
endfunction()
function(ROCPROFILER_REGISTER_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_REGISTER_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_register_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)
+25
Wyświetl plik
@@ -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
)/
)
'''
+6
Wyświetl plik
@@ -0,0 +1,6 @@
#
# Samples
#
project(rocprofiler-register-samples LANGUAGES C CXX)
add_subdirectory(library-implementation)
@@ -0,0 +1,18 @@
#
#
#
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
project(rocprofiler-register-library-implementation LANGUAGES C CXX)
if("${CMAKE_PROJECT_NAME}" STREQUAL "${PROJECT_NAME}")
find_package(rocprofiler-register REQUIRED)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
endif()
add_library(rocp-reg-hip-demo SHARED)
target_sources(rocp-reg-hip-demo PRIVATE demo.cpp demo.hpp)
target_link_libraries(rocp-reg-hip-demo
PRIVATE rocprofiler-register::rocprofiler-register)
@@ -0,0 +1,120 @@
#include "demo.hpp"
#include <rocprofiler-register/rocprofiler-register.h>
#include <atomic>
#include <iostream>
#include <mutex>
#define ROCP_REG_VERSION \
ROCPROFILER_REGISTER_COMPUTE_VERSION_3( \
HIP_VERSION_MAJOR, HIP_VERSION_MINOR, HIP_VERSION_PATCH)
ROCPROFILER_REGISTER_DEFINE_IMPORT(hip, ROCP_REG_VERSION)
namespace hip
{
namespace
{
auto&
get_hip_api_table_impl()
{
static auto _table = std::atomic<HipApiTable*>{ nullptr };
return _table;
}
void
register_profiler_impl()
{
static auto _const_api_table = HipApiTable{};
initialize_hip_api_table(&_const_api_table);
// set this before any recursive opportunity arises
get_hip_api_table_impl().exchange(&_const_api_table);
// create a copy of the api table for modification by registration
static auto _profiler_api_table = HipApiTable{};
copy_hip_api_table(&_profiler_api_table, &_const_api_table);
void* _profiler_api_table_v = static_cast<void*>(&_profiler_api_table);
auto lib_id = rocprofiler_register_library_indentifier_t{};
auto success =
rocprofiler_register_library_api_table("hip",
&ROCPROFILER_REGISTER_IMPORT_FUNC(hip),
ROCP_REG_VERSION,
&_profiler_api_table_v,
1,
&lib_id);
if(success == 0)
{
auto* _api_table = &_const_api_table;
if(!get_hip_api_table_impl().compare_exchange_strong(_api_table,
&_profiler_api_table))
{
// with the current impl, if we ever get here, someone is calling one the
// functions in this anonymous namespace that shouldn't
std::cerr
<< "register_profiler_impl expected the API table to be the internal "
"implementation and yet it is not. something went wrong.\n";
abort();
}
}
}
void
register_profiler()
{
// this registration scheme is designed to minimize overhead once
// registered (only pay cost of checking atomic boolean)
// once the profiler is registered. If the library has not
// been registered and two or more threads try to register concurrently
// the first thread to acquire the lock below, will block the
// threads until registration is complete. However,
// if the same thread performing the registration re-enters this function
// i.e. this library's API is called during registration, this function
// will prevent a deadlock by not attempting to re-enter the
// the call-once and not releasing any waiting threads by flipping
// the _is_registered field to true.
static auto _is_registered = std::atomic<bool>{ false };
if(!_is_registered.load(std::memory_order_acquire))
{
using mutex_t = std::recursive_mutex;
using auto_lock_t = std::unique_lock<mutex_t>;
static auto _once = std::once_flag{};
static auto _mutex = mutex_t{};
// defer the lock so we can check for recursion
auto _lk = auto_lock_t{ _mutex, std::defer_lock };
// this will be true if the same thread currently executing the call_once invokes
// the library's API while registering the profiler (e.g. tool which wants to
// instrument HIP API invokes a HIP function while registering with the profiler)
// we allow this thread to proceed and access the "const" API table but
// return so it does not flip _is_registered to true, which would result
// in any subsequent threads not waiting until the library is fully registered,
// resulting in missed callbacks for the tools
if(_lk.owns_lock()) return;
// ensures any subsequent threads wait until the first thread
// finishes registration
_lk.lock();
// call_once to ensure that we only register once
std::call_once(_once, register_profiler_impl);
// the first thread has completed registration and all
// threads waiting on lock will be released and this
// block will not be entered again
_is_registered.exchange(true, std::memory_order_release);
}
}
} // namespace
HipApiTable*
get_hip_api_table()
{
register_profiler();
return get_hip_api_table_impl().load(std::memory_order_relaxed);
}
} // namespace hip
@@ -0,0 +1,37 @@
#pragma once
#define HIP_VERSION_MAJOR 1
#define HIP_VERSION_MINOR 0
#define HIP_VERSION_PATCH 0
#include <cstdint>
extern "C" {
// fake hip function
void
hip_init(void);
}
namespace hip
{
struct HipApiTable
{
uint64_t size = 0;
void (*functor)() = nullptr;
};
// populates hip api table with function pointers
inline void
initialize_hip_api_table(HipApiTable* dst)
{
dst->size = sizeof(HipApiTable);
dst->functor = &hip_init;
}
// copies the api table from src to dst
inline void
copy_hip_api_table(HipApiTable* dst, const HipApiTable* src)
{
*dst = *src;
}
} // namespace hip
+3
Wyświetl plik
@@ -0,0 +1,3 @@
#
# AddressSanitizer suppressions file for rocprofiler-register project.
#
+3
Wyświetl plik
@@ -0,0 +1,3 @@
#
# LeakSanitizer suppressions file for rocprofiler-register project.
#
+463
Wyświetl plik
@@ -0,0 +1,463 @@
#!/usr/bin/env python3
import os
import re
import sys
import glob
import socket
import shutil
import argparse
import multiprocessing
# this constant is used to define CTEST_PROJECT_NAME
# and default value for CTEST_SUBMIT_URL
_PROJECT_NAME = "rocprofiler-register"
_BASE_URL = "10.194.116.31/cdash"
def which(cmd, require):
v = shutil.which(cmd)
if require and v is None:
raise RuntimeError(f"{cmd} not found")
return v if v is not None else ""
def generate_custom(args, cmake_args, ctest_args):
if not os.path.exists(args.binary_dir):
os.makedirs(args.binary_dir)
if args.memcheck is not None:
if args.coverage:
raise ValueError(
f"Enabling --memcheck={args.memcheck} and --coverage not supported"
)
cmake_args += [f"-DROCPROFILER_REGISTER_MEMCHECK={args.memcheck}"]
NAME = args.name
SITE = args.site
BUILD_JOBS = args.build_jobs
SUBMIT_URL = args.submit_url
SOURCE_DIR = os.path.realpath(args.source_dir)
BINARY_DIR = os.path.realpath(args.binary_dir)
CMAKE_ARGS = " ".join(cmake_args)
CTEST_ARGS = " ".join(ctest_args)
GIT_CMD = which("git", require=True)
GCOV_CMD = which("gcov", require=False)
CMAKE_CMD = which("cmake", require=True)
# CTEST_CMD = which("ctest", require=True)
NAME = re.sub(r"(.*)-([0-9]+)/merge", "PR_\\2_\\1", NAME)
DEFAULT_CMAKE_ARGS = " ".join(
[f"-DROCPROFILER_REGISTER_BUILD_{x}=ON" for x in ["CI", "TESTS", "SAMPLES"]]
)
MEMCHECK_TYPE = "" if args.memcheck is None else args.memcheck
MEMCHECK_SANITIZER_OPTIONS = ""
MEMCHECK_SUPPRESSION_FILE = ""
if MEMCHECK_TYPE == "AddressSanitizer":
MEMCHECK_SANITIZER_OPTIONS = "detect_leaks=0 use_sigaltstack=0"
MEMCHECK_SUPPRESSION_FILE = f"{SOURCE_DIR}/scripts/address-sanitizer-suppr.txt"
elif MEMCHECK_TYPE == "LeakSanitizer":
MEMCHECK_SUPPRESSION_FILE = f"{SOURCE_DIR}/scripts/leak-sanitizer-suppr.txt"
elif MEMCHECK_TYPE == "ThreadSanitizer":
external_symbolizer_path = ""
for version in range(8, 20):
_symbolizer = shutil.which(f"llvm-symbolizer-{version}")
if _symbolizer:
external_symbolizer_path = f"external_symbolizer_path={_symbolizer}"
os.environ["TSAN_OPTIONS"] = " ".join(
[
"history_size=5",
"second_deadlock_stack=1",
f"suppressions={SOURCE_DIR}/scripts/thread-sanitizer-suppr.txt",
external_symbolizer_path,
os.environ.get("TSAN_OPTIONS", ""),
]
)
return f"""
set(CTEST_PROJECT_NAME "{_PROJECT_NAME}")
set(CTEST_NIGHTLY_START_TIME "05:00:00 UTC")
set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE_CDASH TRUE)
set(CTEST_SUBMIT_URL "http://{SUBMIT_URL}")
set(CTEST_UPDATE_TYPE git)
set(CTEST_UPDATE_VERSION_ONLY TRUE)
set(CTEST_GIT_COMMAND {GIT_CMD})
set(CTEST_GIT_INIT_SUBMODULES FALSE)
set(CTEST_OUTPUT_ON_FAILURE TRUE)
set(CTEST_USE_LAUNCHERS TRUE)
set(CMAKE_CTEST_ARGUMENTS --output-on-failure {CTEST_ARGS})
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS "100")
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS "100")
set(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE "51200")
set(CTEST_CUSTOM_COVERAGE_EXCLUDE "/usr/.*;/opt/.*;.*external/.*;.*samples/.*;.*tests/.*")
set(CTEST_MEMORYCHECK_TYPE "{MEMCHECK_TYPE}")
set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE "{MEMCHECK_SUPPRESSION_FILE}")
set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS "{MEMCHECK_SANITIZER_OPTIONS}")
set(CTEST_SITE "{SITE}")
set(CTEST_BUILD_NAME "{NAME}")
set(CTEST_SOURCE_DIRECTORY {SOURCE_DIR})
set(CTEST_BINARY_DIRECTORY {BINARY_DIR})
set(CTEST_CONFIGURE_COMMAND "{CMAKE_CMD} -B {BINARY_DIR} {SOURCE_DIR} {DEFAULT_CMAKE_ARGS} {CMAKE_ARGS}")
set(CTEST_BUILD_COMMAND "{CMAKE_CMD} --build {BINARY_DIR} --target all --parallel {BUILD_JOBS}")
set(CTEST_COVERAGE_COMMAND {GCOV_CMD})
"""
def generate_dashboard_script(args):
CODECOV = 1 if args.coverage else 0
DASHBOARD_MODE = args.mode
SOURCE_DIR = os.path.realpath(args.source_dir)
BINARY_DIR = os.path.realpath(args.binary_dir)
MEMCHECK = 1 if args.memcheck is not None else 0
SUBMIT = 0 if args.disable_cdash else 1
ARGN = "${ARGN}"
if args.memcheck == "ThreadSanitizer":
MEMCHECK = 0
_script = f"""
macro(dashboard_submit)
if("{SUBMIT}" GREATER 0)
ctest_submit({ARGN})
endif()
endmacro()
"""
_script += """
include("${CMAKE_CURRENT_LIST_DIR}/CTestCustom.cmake")
macro(handle_error _message _ret)
if(NOT ${${_ret}} EQUAL 0)
dashboard_submit(PARTS Done RETURN_VALUE _submit_ret)
message(FATAL_ERROR "${_message} failed: ${${_ret}}")
endif()
endmacro()
"""
_script += f"""
ctest_start({DASHBOARD_MODE})
ctest_update(SOURCE "{SOURCE_DIR}" RETURN_VALUE _update_ret
CAPTURE_CMAKE_ERROR _update_err)
ctest_configure(BUILD "{BINARY_DIR}" RETURN_VALUE _configure_ret)
dashboard_submit(PARTS Start Update Configure RETURN_VALUE _submit_ret)
if(NOT _update_err EQUAL 0)
message(WARNING "ctest_update failed")
endif()
handle_error("Configure" _configure_ret)
ctest_build(BUILD "{BINARY_DIR}" RETURN_VALUE _build_ret)
dashboard_submit(PARTS Build RETURN_VALUE _submit_ret)
handle_error("Build" _build_ret)
if("{MEMCHECK}" GREATER 0)
ctest_memcheck(BUILD "{BINARY_DIR}" RETURN_VALUE _test_ret)
dashboard_submit(PARTS Test RETURN_VALUE _submit_ret)
else()
ctest_test(BUILD "{BINARY_DIR}" RETURN_VALUE _test_ret)
dashboard_submit(PARTS Test RETURN_VALUE _submit_ret)
endif()
if("{CODECOV}" GREATER 0)
ctest_coverage(
BUILD "{BINARY_DIR}"
RETURN_VALUE _coverage_ret
CAPTURE_CMAKE_ERROR _coverage_err)
dashboard_submit(PARTS Coverage RETURN_VALUE _submit_ret)
endif()
handle_error("Testing" _test_ret)
dashboard_submit(PARTS Done RETURN_VALUE _submit_ret)
"""
return _script
def parse_cdash_args(args):
BUILD_JOBS = multiprocessing.cpu_count()
DASHBOARD_MODE = "Continuous"
DASHBOARD_STAGES = [
"Start",
"Update",
"Configure",
"Build",
"Test",
"MemCheck",
"Coverage",
"Submit",
]
SOURCE_DIR = os.getcwd()
BINARY_DIR = os.path.join(SOURCE_DIR, "build")
SITE = socket.gethostname()
SUBMIT_URL = f"{_BASE_URL}/submit.php?project={_PROJECT_NAME}"
parser = argparse.ArgumentParser()
parser.add_argument(
"-n", "--name", help="Job name", default=None, type=str, required=True
)
parser.add_argument("-s", "--site", help="Site name", default=SITE, type=str)
parser.add_argument(
"-q", "--quiet", help="Disable printing logs", action="store_true"
)
parser.add_argument(
"-c", "--coverage", help="Enable code coverage", action="store_true"
)
parser.add_argument(
"-j",
"--build-jobs",
help="Number of build tasks",
default=BUILD_JOBS,
type=int,
)
parser.add_argument(
"-B",
"--binary-dir",
help="Build directory",
default=BINARY_DIR,
type=str,
)
parser.add_argument(
"-S",
"--source-dir",
help="Source directory",
default=SOURCE_DIR,
type=str,
)
parser.add_argument(
"-F",
"--clean",
help="Remove existing build directory",
action="store_true",
)
parser.add_argument(
"-M",
"--mode",
help="Dashboard mode",
default=DASHBOARD_MODE,
choices=("Continuous", "Nightly", "Experimental"),
type=str,
)
parser.add_argument(
"-T",
"--stages",
help="Dashboard stages",
nargs="+",
default=DASHBOARD_STAGES,
choices=DASHBOARD_STAGES,
type=str,
)
parser.add_argument(
"--submit-url",
help="CDash submission site",
default=SUBMIT_URL,
type=str,
)
parser.add_argument(
"--repeat-until-pass",
help="<N> for --repeat until-pass:<N>",
default=None,
type=int,
)
parser.add_argument(
"--repeat-until-fail",
help="<N> for --repeat until-fail:<N>",
default=None,
type=int,
)
parser.add_argument(
"--repeat-after-timeout",
help="<N> for --repeat after-timeout:<N>",
default=None,
type=int,
)
parser.add_argument(
"--disable-cdash",
help="Disable submitting results to CDash dashboard",
action="store_true",
)
parser.add_argument(
"--memcheck",
help="Run dynamic analysis tool",
default=None,
type=str,
choices=(
"ThreadSanitizer",
"AddressSanitizer",
"LeakSanitizer",
"UndefinedBehaviorSanitizer",
),
)
parser.add_argument(
"--linter",
help="Enable linting tool",
default=None,
type=str,
choices=("clang-tidy",),
)
return parser.parse_args(args)
def parse_args(args=None):
if args is None:
args = sys.argv[1:]
index = 0
input_args = []
ctest_args = []
cmake_args = []
data = [input_args, cmake_args, ctest_args]
cmd = os.path.basename(sys.argv[0])
for itr in args:
if itr == "--":
index += 1
if index > 2:
raise RuntimeError(
f"Usage: {cmd} <options> -- <cmake-args> -- <ctest-args>"
)
else:
data[index].append(itr)
cdash_args = parse_cdash_args(input_args)
if cdash_args.coverage:
cmake_args += ["-DROCPROFILER_REGISTER_BUILD_CODECOV=ON"]
if cdash_args.linter == "clang-tidy":
cmake_args += ["-DROCPROFILER_REGISTER_ENABLE_CLANG_TIDY=ON"]
def get_repeat_val(_param):
_value = getattr(cdash_args, f"repeat_{_param}".replace("-", "_"))
return [f"{_param}:{_value}"] if _value is not None and _value > 1 else []
repeat_args = (
get_repeat_val("until-pass")
+ get_repeat_val("until-fail")
+ get_repeat_val("after-timeout")
)
ctest_args += ["--repeat"] + repeat_args if len(repeat_args) > 0 else []
return [cdash_args, cmake_args, ctest_args]
def run(*args, **kwargs):
import subprocess
return subprocess.run(*args, **kwargs)
if __name__ == "__main__":
args, cmake_args, ctest_args = parse_args()
if args.clean and os.path.exists(args.binary_dir):
if args.source_dir == args.binary_dir:
raise RuntimeError(
f"cannot clean binary directory == source directory ({args.source_dir})"
)
shutil.rmtree(args.binary_dir)
if not os.path.exists(args.binary_dir):
os.makedirs(args.binary_dir)
from textwrap import dedent
_config = dedent(generate_custom(args, cmake_args, ctest_args))
_script = dedent(generate_dashboard_script(args))
if not args.quiet:
sys.stderr.write(f"##### CTestCustom.cmake #####\n\n{_config}\n\n")
sys.stderr.write(f"##### dashboard.cmake #####\n\n{_script}\n\n")
with open(os.path.join(args.binary_dir, "CTestCustom.cmake"), "w") as f:
f.write(f"{_config}\n")
with open(os.path.join(args.binary_dir, "dashboard.cmake"), "w") as f:
f.write(f"{_script}\n")
CTEST_CMD = which("ctest", require=True)
dashboard_args = ["-D"]
for itr in args.stages:
dashboard_args.append(f"{args.mode}{itr}")
try:
if not args.quiet and len(ctest_args) == 0:
ctest_args = ["--output-on-failure", "-V"]
run(
[CTEST_CMD]
+ dashboard_args
+ [
"-S",
os.path.join(args.binary_dir, "dashboard.cmake"),
]
+ ctest_args,
check=True,
)
finally:
echo_files = []
if "-VV" not in ctest_args and not args.quiet:
for file in glob.glob(
os.path.join(args.binary_dir, "Testing/Temporary/**"),
recursive=True,
):
if not os.path.isfile(file):
continue
if re.match(
r"Last(Start|Update|Configure|Build|Test).*\.log$",
os.path.basename(file),
) is None and "MemoryChecker" not in os.path.basename(file):
continue
echo_files.append(file)
if echo_files:
# sort alphabetically
echo_files = sorted(echo_files)
echo_files_sorted = []
# loop over order we want
for key in [
"LastStart",
"LastUpdate",
"LastConfigure",
"LastBuild",
"LastTest",
]:
for file in echo_files:
# if key in file, append
if key in file:
echo_files_sorted.append(file)
echo_files_sorted += [x for x in echo_files if x not in echo_files_sorted]
for file in echo_files_sorted:
print(f"\n\n\n###### Reading {file}... ######\n\n\n")
with open(file, "r") as inpf:
fdata = inpf.read()
oname = os.path.basename(file)
if "LastTest" not in oname and "Coverage" not in oname:
print(fdata)
if oname.endswith(".log"):
oname += ".log"
with open(os.path.join(args.binary_dir, oname), "w") as outf:
print(f"\n\n###### Writing {oname}... ######\n\n")
outf.write(fdata)
+3
Wyświetl plik
@@ -0,0 +1,3 @@
#
# ThreadSanitizer suppressions file for rocprofiler-register project.
#
+11
Wyświetl plik
@@ -0,0 +1,11 @@
#
#
#
rocprofiler_register_activate_clang_tidy()
if(ROCPROFILER_REGISTER_BUILD_CODECOV)
set(CMAKE_BUILD_TYPE "Coverage")
endif()
add_subdirectory(include)
add_subdirectory(lib)
+4
Wyświetl plik
@@ -0,0 +1,4 @@
#
#
#
add_subdirectory(rocprofiler-register)
@@ -0,0 +1,13 @@
#
#
# Installation of public headers
#
#
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.in
${CMAKE_CURRENT_BINARY_DIR}/version.h @ONLY)
set(ROCPROFILER_REGISTER_INCLUDE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rocprofiler-register.h
${CMAKE_CURRENT_BINARY_DIR}/version.h)
install(FILES ${ROCPROFILER_REGISTER_INCLUDE_FILES}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/rocprofiler-register)
@@ -0,0 +1,188 @@
// 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 <rocprofiler-register/version.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef int (*rocprofiler_configure_callback_t)(void*);
typedef struct
{
rocprofiler_configure_callback_t initialize;
rocprofiler_configure_callback_t finalize;
void* user_data;
} rocprofiler_configure_result_t;
typedef uint32_t (*rocprofiler_register_import_func_t)(void);
typedef struct
{
uint64_t handle;
} rocprofiler_register_library_indentifier_t;
/// @enum rocprofiler_register_error_code_t
/// @brief enumeration of error codes
///
/// @var ROCP_REG_SUCCESS
/// @brief Successful call to rocprofiler-register
///
/// @var ROCP_REG_NO_TOOLS
/// @brief API table was not passed to rocprofiler because no rocprofiler tool
/// configuration symbols were requested
///
/// @var ROCP_REG_DEADLOCK
/// @brief The thread that is currently communicating the API tables to rocprofiler
/// re-entered \ref rocprofiler_register_library_api_table
///
/// @var ROCP_REG_BAD_API_TABLE_LENGTH
/// @brief Library provided an invalid API table length (likely zero)
///
/// @var ROCP_REG_UNSUPPORTED_API
/// @brief Library is providing an API table name that is not supported
///
/// @var ROCP_REG_ROCPROFILER_ERROR
/// @brief Rocprofiler returned an error when passing the API tables
///
/// @var ROCP_REG_EXCESS_API_INSTANCES
/// @brief The same API has been registered too many times
///
typedef enum rocprofiler_register_error_code_t // NOLINT(performance-enum-size)
{
ROCP_REG_SUCCESS = 0,
ROCP_REG_NO_TOOLS,
ROCP_REG_DEADLOCK,
ROCP_REG_BAD_API_TABLE_LENGTH,
ROCP_REG_UNSUPPORTED_API,
ROCP_REG_INVALID_API_ADDRESS,
ROCP_REG_ROCPROFILER_ERROR,
ROCP_REG_EXCESS_API_INSTANCES,
ROCP_REG_ERROR_CODE_END,
} rocprofiler_register_error_code_t;
/// @fn rocprofiler_register_error_code_t rocprofiler_register_library_api_table(
/// const char* lib_name,
/// rocprofiler_register_import_func_t import_func,
/// uint32_t lib_version,
/// void* api_tables,
/// uint64_t api_table_length,
/// rocprofiler_register_library_indentifier_t* register_id)
/// @param[in] lib_name string identifier for the library registering the API table
/// @param[in] import_func function pointer to rocprofiler_register_import_<lib_name>
/// symbol
/// @param[in] lib_version lib version in form of (10000 * major ) + (100 * minor) + patch
/// @param[in] api_tables pointer to one or more API table pointers
/// @param[in] api_table_length number of API tables that are being passed in. Must be > 0
/// @param[out] register_id a unique identifier for this library encoding the API category
/// and the priority in the event that multiple libraries register with the same name
/// @returns value of type @ref rocprofiler_register_error_code_t
///
/// @brief primary function call that needs to be performed when the API table of the
/// library is initialized.
///
rocprofiler_register_error_code_t
rocprofiler_register_library_api_table(
const char* lib_name,
rocprofiler_register_import_func_t import_func,
uint32_t lib_version,
void** api_tables,
uint64_t api_table_length,
rocprofiler_register_library_indentifier_t* register_id)
ROCPROFILER_REGISTER_ATTRIBUTE(nonnull(4, 6)) ROCPROFILER_REGISTER_PUBLIC_API;
const char* rocprofiler_register_error_string(rocprofiler_register_error_code_t)
ROCPROFILER_REGISTER_PUBLIC_API;
#ifdef __cplusplus
}
#endif
/// @def ROCPROFILER_REGISTER_COMPUTE_VERSION_1
/// @param[in] MAJOR_VERSION major version of library (integral)
/// @brief Helper macro for users to generate versioning int expected by
/// rocprofiler-register when the library only maintains a major version number
#define ROCPROFILER_REGISTER_COMPUTE_VERSION_1(MAJOR_VERSION) (10000 * MAJOR_VERSION)
/// @def ROCPROFILER_REGISTER_COMPUTE_VERSION_
/// @param[in] MAJOR_VERSION major version of library (integral)
/// @param[in] MINOR_VERSION minor version of library (integral)
/// @brief Helper macro for users to generate versioning int expected by
/// rocprofiler-register when the library only maintains a major and minor version number
#define ROCPROFILER_REGISTER_COMPUTE_VERSION_2(MAJOR_VERSION, MINOR_VERSION) \
(ROCPROFILER_REGISTER_COMPUTE_VERSION_1(MAJOR_VERSION) + (100 * MINOR_VERSION))
/// @def ROCPROFILER_REGISTER_COMPUTE_VERSION_3
/// @param[in] MAJOR_VERSION major version of library (integral)
/// @param[in] MINOR_VERSION minor version of library (integral)
/// @param[in] PATCH_VERSION patch version of library (integral)
/// @brief Helper macro for users to generate versioning int expected by
/// rocprofiler-register when the library maintains a major, minor, and patch version
/// numbers
#define ROCPROFILER_REGISTER_COMPUTE_VERSION_3( \
MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION) \
(ROCPROFILER_REGISTER_COMPUTE_VERSION_2(MAJOR_VERSION, MINOR_VERSION) + \
(PATCH_VERSION))
/// @def ROCPROFILER_REGISTER_COMPUTE_VERSION_4
/// @param[in] MAJOR_VERSION major version of library (integral)
/// @param[in] MINOR_VERSION minor version of library (integral)
/// @param[in] PATCH_VERSION patch version of library (integral)
/// @param[in] TWEAK_VERSION tweak version of library which will be ignored
/// @brief Helper macro for users to generate versioning int expected by
/// rocprofiler-register when the library maintains a major, minor, patch, and tweak
/// version numbers
#define ROCPROFILER_REGISTER_COMPUTE_VERSION_3( \
MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION) \
(ROCPROFILER_REGISTER_COMPUTE_VERSION_2(MAJOR_VERSION, MINOR_VERSION) + \
(PATCH_VERSION))
/// @def ROCPROFILER_REGISTER_IMPORT_FUNC(NAME)
/// @param[in] NAME the string identifier for the library
/// @brief Helper macro for retrieving the name of the import function which is used by
/// rocprofiler-register to identify the location and priority of the registering library
#define ROCPROFILER_REGISTER_IMPORT_FUNC(NAME) \
ROCPROFILER_REGISTER_PP_COMBINE(rocprofiler_register_import_, NAME)
/// @def ROCPROFILER_REGISTER_DEFINE_IMPORT(NAME, VERSION)
/// @param[in] NAME the unquoted string identifier for the library, e.g. hip
/// @brief Helper macro for declaring a visible import symbol for rocprofiler-register
/// which returns the version.
///
#ifdef __cplusplus
# define ROCPROFILER_REGISTER_DEFINE_IMPORT(NAME, VERSION) \
extern "C" { \
uint32_t ROCPROFILER_REGISTER_IMPORT_FUNC(NAME)() \
ROCPROFILER_REGISTER_ATTRIBUTE(visibility("default")); \
\
uint32_t ROCPROFILER_REGISTER_IMPORT_FUNC(NAME)() { return VERSION; } \
}
#else
# define ROCPROFILER_REGISTER_DEFINE_IMPORT(NAME, VERSION) \
uint32_t ROCPROFILER_REGISTER_IMPORT_FUNC(NAME)(void) \
ROCPROFILER_REGISTER_ATTRIBUTE(visibility("default")); \
\
uint32_t ROCPROFILER_REGISTER_IMPORT_FUNC(NAME)(void) { return VERSION; }
#endif
@@ -0,0 +1,103 @@
// 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
// clang-format off
#define ROCPROFILER_REGISTER_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
#define ROCPROFILER_REGISTER_VERSION_MINOR @PROJECT_VERSION_MINOR@
#define ROCPROFILER_REGISTER_VERSION_PATCH @PROJECT_VERSION_PATCH@
#define ROCPROFILER_REGISTER_VERSION_STRING "@FULL_VERSION_STRING@"
#define ROCPROFILER_REGISTER_SOVERSION "@PROJECT_VERSION_MAJOR@"
#define ROCPROFILER_REGISTER_GIT_DESCRIBE "@ROCPROFILER_REGISTER_GIT_DESCRIBE@"
#define ROCPROFILER_REGISTER_GIT_REVISION "@ROCPROFILER_REGISTER_GIT_REVISION@"
// system info during compilation
#define ROCPROFILER_REGISTER_LIBRARY_ARCH "@CMAKE_LIBRARY_ARCHITECTURE@"
#define ROCPROFILER_REGISTER_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@"
#define ROCPROFILER_REGISTER_SYSTEM_PROCESSOR "@CMAKE_SYSTEM_PROCESSOR@"
#define ROCPROFILER_REGISTER_SYSTEM_VERSION "@CMAKE_SYSTEM_VERSION@"
// compiler information
#define ROCPROFILER_REGISTER_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@"
#define ROCPROFILER_REGISTER_COMPILER_VERSION "@CMAKE_CXX_COMPILER_VERSION@"
#define ROCPROFILER_REGISTER_COMPILER_STRING ROCPROFILER_REGISTER_COMPILER_ID " v" ROCPROFILER_REGISTER_COMPILER_VERSION
// clang-format on
#define ROCPROFILER_REGISTER_VERSION \
((10000 * ROCPROFILER_REGISTER_VERSION_MAJOR) + \
(100 * ROCPROFILER_REGISTER_VERSION_MINOR) + ROCPROFILER_REGISTER_VERSION_PATCH)
#define ROCPROFILER_REGISTER_ATTRIBUTE(...) __attribute__((__VA_ARGS__))
#define ROCPROFILER_REGISTER_PP_COMBINE(X, Y) X##Y
#if defined(rocprofiler_register_EXPORTS)
// only defined in build tree
# define ROCPROFILER_REGISTER_VISIBILITY(MODE) \
ROCPROFILER_REGISTER_ATTRIBUTE(visibility(MODE))
# define ROCPROFILER_REGISTER_PUBLIC_API ROCPROFILER_REGISTER_VISIBILITY("default")
# define ROCPROFILER_REGISTER_HIDDEN_API ROCPROFILER_REGISTER_VISIBILITY("hidden")
# define ROCPROFILER_REGISTER_INTERNAL_API ROCPROFILER_REGISTER_VISIBILITY("internal")
# define ROCPROFILER_REGISTER_INLINE \
ROCPROFILER_REGISTER_ATTRIBUTE(always_inline) inline
# define ROCPROFILER_REGISTER_NOINLINE ROCPROFILER_REGISTER_ATTRIBUTE(noinline)
# define ROCPROFILER_REGISTER_HOT ROCPROFILER_REGISTER_ATTRIBUTE(hot)
# define ROCPROFILER_REGISTER_COLD ROCPROFILER_REGISTER_ATTRIBUTE(cold)
# define ROCPROFILER_REGISTER_CONST ROCPROFILER_REGISTER_ATTRIBUTE(const)
# define ROCPROFILER_REGISTER_PURE ROCPROFILER_REGISTER_ATTRIBUTE(pure)
# define ROCPROFILER_REGISTER_WEAK ROCPROFILER_REGISTER_ATTRIBUTE(weak)
# define ROCPROFILER_REGISTER_PACKED ROCPROFILER_REGISTER_ATTRIBUTE(__packed__)
# define ROCPROFILER_REGISTER_PACKED_ALIGN(VAL) \
ROCPROFILER_REGISTER_PACKED ROCPROFILER_REGISTER_ATTRIBUTE(__aligned__(VAL))
# define ROCPROFILER_REGISTER_LIKELY(...) __builtin_expect((__VA_ARGS__), 1)
# define ROCPROFILER_REGISTER_UNLIKELY(...) __builtin_expect((__VA_ARGS__), 0)
# if defined(ROCPROFILER_REGISTER_CI) && ROCPROFILER_REGISTER_CI > 0
# if defined(NDEBUG)
# undef NDEBUG
# endif
# if !defined(DEBUG)
# define DEBUG 1
# endif
# if defined(__cplusplus)
# include <cassert> // NOLINT
# else
# include <assert.h>
# endif
# endif
# define ROCPROFILER_REGISTER_STRINGIZE(X) ROCPROFILER_REGISTER_STRINGIZE2(X)
# define ROCPROFILER_REGISTER_STRINGIZE2(X) # X
# define ROCPROFILER_REGISTER_LINESTR ROCPROFILER_REGISTER_STRINGIZE(__LINE__)
# define ROCPROFILER_REGISTER_ESC(...) __VA_ARGS__
# if defined(__cplusplus)
# if !defined(ROCPROFILER_REGISTER_FOLD_EXPRESSION)
# define ROCPROFILER_REGISTER_FOLD_EXPRESSION(...) ((__VA_ARGS__), ...)
# endif
# endif
#else
# define ROCPROFILER_REGISTER_VISIBILITY(MODE)
# define ROCPROFILER_REGISTER_PUBLIC_API
# define ROCPROFILER_REGISTER_HIDDEN_API
# define ROCPROFILER_REGISTER_INTERNAL_API
#endif
+4
Wyświetl plik
@@ -0,0 +1,4 @@
#
#
#
add_subdirectory(rocprofiler-register)
@@ -0,0 +1,36 @@
#
# builds the rocprofiler-register library
#
add_library(rocprofiler-register SHARED)
add_library(rocprofiler-register::rocprofiler-register ALIAS rocprofiler-register)
add_subdirectory(details)
target_sources(rocprofiler-register PRIVATE rocprofiler_register.cpp)
if(ROCPROFILER_REGISTER_BUILD_TESTS)
# make sure header is C-compatible
target_sources(rocprofiler-register PRIVATE rocprofiler_register.c)
endif()
target_include_directories(
rocprofiler-register PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/source
${PROJECT_BINARY_DIR}/source)
target_link_libraries(
rocprofiler-register
PUBLIC rocprofiler-register::headers
PRIVATE rocprofiler-register::build-flags rocprofiler-register::memcheck
rocprofiler-register::stdcxxfs rocprofiler-register::dl)
set_target_properties(
rocprofiler-register
PROPERTIES OUTPUT_NAME rocprofiler-register
SOVERSION ${PROJECT_VERSION_MAJOR}
VERSION ${PROJECT_VERSION})
install(
TARGETS rocprofiler-register
DESTINATION ${CMAKE_INSTALL_LIBDIR}
COMPONENT core
EXPORT ${PROJECT_NAME}-library-targets)
@@ -0,0 +1,10 @@
#
# builds the rocprofiler-register library
#
set(rocprofiler_register_details_sources dl.cpp utility.cpp)
set(rocprofiler_register_details_headers environment.hpp join.hpp dl.hpp log.hpp
utility.hpp)
target_sources(rocprofiler-register PRIVATE ${rocprofiler_register_details_sources}
${rocprofiler_register_details_headers})
@@ -0,0 +1,125 @@
// MIT License
//
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#define GNU_SOURCE 1
#include "dl.hpp"
#include "join.hpp"
#include "utility.hpp"
#include <filesystem>
#include <fstream>
#include <optional>
#include <string>
#include <string_view>
#include <dlfcn.h>
#include <elf.h>
#include <link.h>
#include <sys/types.h>
#include <unistd.h>
namespace fs = ::std::filesystem;
namespace rocprofiler_register
{
namespace binary
{
namespace
{
const open_modes_vec_t default_link_open_modes = { (RTLD_LAZY | RTLD_NOLOAD),
(RTLD_LAZY | RTLD_LOCAL) };
} // namespace
std::vector<segment_address_ranges>
get_segment_addresses(pid_t _pid)
{
auto _data = std::vector<segment_address_ranges>{};
auto _fname = common::join('/', "/proc", _pid, "maps");
auto ifs = std::ifstream{ _fname };
if(!ifs)
{
fprintf(stderr, "Failure opening %s\n", _fname.c_str());
}
else
{
auto _get_entry = [&_data](std::string_view _name) -> segment_address_ranges& {
for(auto& itr : _data)
{
if(itr.filepath == _name) return itr;
}
return _data.emplace_back(
segment_address_ranges{ .filepath = std::string{ _name } });
};
while(ifs)
{
std::string _line = {};
if(std::getline(ifs, _line) && !_line.empty())
{
auto _delim = utility::delimit(_line, " \t\n\r");
if(_delim.size() > 5 && fs::exists(fs::path{ _delim.back() }))
{
auto& _entry = _get_entry(_delim.back());
auto _addr = utility::delimit(_delim.front(), "-");
auto load_address = std::stoull(_addr.front(), nullptr, 16);
auto last_address = std::stoull(_addr.back(), nullptr, 16);
_entry.ranges.emplace_back(
address_range{ load_address, last_address });
}
}
}
}
return _data;
}
std::optional<std::string>
get_linked_path(std::string_view _name, open_modes_vec_t&& _open_modes)
{
if(_name.empty()) return fs::current_path().string();
if(_open_modes.empty()) _open_modes = default_link_open_modes;
void* _handle = nullptr;
bool _noload = false;
for(auto _mode : _open_modes)
{
_handle = dlopen(_name.data(), _mode);
_noload = (_mode & RTLD_NOLOAD) == RTLD_NOLOAD;
if(_handle) break;
}
if(_handle)
{
struct link_map* _link_map = nullptr;
dlinfo(_handle, RTLD_DI_LINKMAP, &_link_map);
if(_link_map != nullptr && !std::string_view{ _link_map->l_name }.empty())
{
return fs::absolute(fs::path{ _link_map->l_name }).string();
}
if(_noload == false) dlclose(_handle);
}
return std::nullopt;
}
} // namespace binary
} // namespace rocprofiler_register
@@ -0,0 +1,60 @@
// 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 <cstdint>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
#include <dlfcn.h>
#include <sys/types.h>
#include <unistd.h>
namespace rocprofiler_register
{
namespace binary
{
using open_modes_vec_t = std::vector<int>;
struct address_range
{
uintptr_t start = 0;
uintptr_t last = 0;
};
struct segment_address_ranges
{
std::string filepath = {};
std::vector<address_range> ranges = {};
};
std::vector<segment_address_ranges>
get_segment_addresses(pid_t _pid = getpid());
// helper function for translating generic lib name to resolved path
std::optional<std::string>
get_linked_path(std::string_view, open_modes_vec_t&& = {});
} // namespace binary
} // namespace rocprofiler_register
@@ -0,0 +1,191 @@
// 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 "log.hpp"
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <stdexcept>
#include <string>
#include <string_view>
#include <type_traits>
#if !defined(ROCPROFILER_REGISTER_ENVIRON_LOG_NAME)
# if defined(ROCPROFILER_REGISTER_COMMON_LIBRARY_NAME)
# define ROCPROFILER_REGISTER_ENVIRON_LOG_NAME \
"[" ROCPROFILER_REGISTER_COMMON_LIBRARY_NAME "]"
# else
# define ROCPROFILER_REGISTER_ENVIRON_LOG_NAME "[environ]"
# endif
#endif
#if !defined(ROCPROFILER_REGISTER_ENVIRON_LOG_START)
# if defined(ROCPROFILER_REGISTER_COMMON_LIBRARY_LOG_START)
# define ROCPROFILER_REGISTER_ENVIRON_LOG_START \
ROCPROFILER_REGISTER_COMMON_LIBRARY_LOG_START
# elif defined(ROCPROFILER_REGISTER_LOG_COLORS_AVAILABLE)
# define ROCPROFILER_REGISTER_ENVIRON_LOG_START \
fprintf(stderr, "%s", ::rocprofiler_register::log::color::dmesg());
# else
# define ROCPROFILER_REGISTER_ENVIRON_LOG_START
# endif
#endif
#if !defined(ROCPROFILER_REGISTER_ENVIRON_LOG_END)
# if defined(ROCPROFILER_REGISTER_COMMON_LIBRARY_LOG_END)
# define ROCPROFILER_REGISTER_ENVIRON_LOG_END \
ROCPROFILER_REGISTER_COMMON_LIBRARY_LOG_END
# elif defined(ROCPROFILER_REGISTER_LOG_COLORS_AVAILABLE)
# define ROCPROFILER_REGISTER_ENVIRON_LOG_END \
fprintf(stderr, "%s", ::rocprofiler_register::log::color::end());
# else
# define ROCPROFILER_REGISTER_ENVIRON_LOG_END
# endif
#endif
#define ROCPROFILER_REGISTER_ENVIRON_LOG(CONDITION, ...) \
if(CONDITION) \
{ \
fflush(stderr); \
ROCPROFILER_REGISTER_ENVIRON_LOG_START \
fprintf(stderr, \
"[rocprofiler-register]" ROCPROFILER_REGISTER_ENVIRON_LOG_NAME "[%i] ", \
getpid()); \
fprintf(stderr, __VA_ARGS__); \
ROCPROFILER_REGISTER_ENVIRON_LOG_END \
fflush(stderr); \
}
namespace rocprofiler_register
{
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_register][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_REGISTER_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_register
@@ -0,0 +1,184 @@
// 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_REGISTER_FOLD_EXPRESSION)
# define ROCPROFILER_REGISTER_FOLD_EXPRESSION(...) ((__VA_ARGS__), ...)
#endif
namespace rocprofiler_register
{
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_REGISTER_FOLD_EXPRESSION(_ss << _delim_c << _args);
auto _ret = _ss.str();
return (_ret.length() > 1) ? _ret.substr(1) : std::string{};
}
else
{
ROCPROFILER_REGISTER_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_REGISTER_FOLD_EXPRESSION(_ss << _delim_c << as_string(_args));
auto _ret = _ss.str();
return (_ret.length() > 1) ? _ret.substr(1) : std::string{};
}
else
{
ROCPROFILER_REGISTER_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_register
@@ -0,0 +1,518 @@
// 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
#include <rocprofiler-register/version.h>
#ifndef ROCPROFILER_REGISTER_LOG_COLORS_AVAILABLE
# define ROCPROFILER_REGISTER_LOG_COLORS_AVAILABLE 1
#endif
#ifndef ROCPROFILER_REGISTER_PROJECT_NAME
# define ROCPROFILER_REGISTER_PROJECT_NAME "rocprofiler-register"
#endif
#ifndef ROCP_REG_FILE_NAME
# define ROCP_REG_FILE_NAME \
::std::string{ __FILE__ } \
.substr(::std::string_view{ __FILE__ }.find_last_of('/') + 1) \
.c_str()
#endif
#include <cstdlib>
#include <iostream>
#include <ostream>
#include <sstream>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
namespace rocprofiler_register
{
namespace log
{
bool&
monochrome();
inline bool&
monochrome()
{
static bool _v = []() {
auto _val = false;
const char* _env_cstr = nullptr;
_env_cstr = std::getenv("ROCPROFILER_REGISTER_MONOCHROME");
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 rocprofiler_register
namespace rocprofiler_register
{
namespace log
{
struct base
{
public:
static base indent(size_t, size_t = 2) { return base{}; }
template <typename Tp>
auto operator<<(Tp&&)
{
return base{};
}
};
struct logger : public base
{
logger() = default;
explicit logger(bool _exit)
: m_exit{ _exit }
{ }
~logger()
{
if(m_done)
{
std::cerr << color::end() << "\n";
if(m_exit) abort();
}
}
logger(logger&& rhs) noexcept
{
m_exit = rhs.m_exit;
m_done = rhs.m_done;
rhs.m_done = false;
}
logger& operator=(logger&& rhs) noexcept
{
m_exit = rhs.m_exit;
m_done = rhs.m_done;
rhs.m_done = false;
return *this;
}
logger&& indent(size_t _n, size_t _tab_size = 4)
{
for(size_t i = 0; i < _n; i++)
for(size_t j = 0; j < _tab_size; j++)
std::cerr << " ";
return std::move(*this);
}
template <typename Tp>
logger&& operator<<(Tp&& _v)
{
std::cerr << std::forward<Tp>(_v);
return std::move(*this);
}
private:
bool m_exit = false;
bool m_done = true;
};
template <typename Tp>
inline auto&
get_color_hist()
{
static thread_local std::vector<std::pair<Tp*, const char*>> _v{};
return _v;
}
template <typename Tp>
inline auto
push_color_hist(Tp* _v, const char* _c)
{
if(!monochrome()) get_color_hist<Tp>().emplace_back(_v, _c);
return _c;
}
template <typename Tp>
inline std::string
pop_color_hist(Tp* _v)
{
if(monochrome()) return std::string{};
auto& _hist = get_color_hist<Tp>();
for(auto itr = _hist.rbegin(); itr != _hist.rend(); ++itr)
{
Tp* _addr = itr->first;
if(_addr == _v)
{
auto fitr = _hist.begin();
std::advance(fitr, std::distance(_hist.rbegin(), itr));
_hist.erase(fitr);
}
}
for(auto itr = _hist.rbegin(); itr != _hist.rend(); ++itr)
{
if(itr->first == _v) return itr->second;
}
return color::end();
}
template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>&
info(std::basic_ostream<CharT, Traits>& os)
{
return (os << push_color_hist(&os, color::info()));
}
template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>&
warning(std::basic_ostream<CharT, Traits>& os)
{
return (os << push_color_hist(&os, color::warning()));
}
template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>&
fatal(std::basic_ostream<CharT, Traits>& os)
{
return (os << push_color_hist(&os, color::fatal()));
}
template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>&
source(std::basic_ostream<CharT, Traits>& os)
{
return (os << push_color_hist(&os, color::source()));
}
template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>&
end(std::basic_ostream<CharT, Traits>& os)
{
return (os << push_color_hist(&os, color::end()));
}
template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>&
pop(std::basic_ostream<CharT, Traits>& os)
{
return (os << pop_color_hist(&os));
}
template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>&
reset(std::basic_ostream<CharT, Traits>& os)
{
pop_color_hist(&os);
return (os << color::end());
}
template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>&
flush(std::basic_ostream<CharT, Traits>& os)
{
return (os << pop << std::flush);
}
template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>&
endl(std::basic_ostream<CharT, Traits>& os)
{
return (os << pop << "\n" << std::flush);
}
template <typename StreamT>
struct stream_base
{
stream_base(StreamT& _os, const char* _color)
: m_os{ _os }
{
m_os << push_color_hist(&_os, _color);
}
~stream_base() { m_os << pop_color_hist(&m_os); }
stream_base(const stream_base&) = delete;
stream_base& operator=(const stream_base&) = delete;
stream_base(stream_base&& rhs) noexcept = default;
stream_base& operator=(stream_base&& rhs) noexcept = default;
template <typename Tp>
stream_base& operator<<(Tp&& _v)
{
m_os << std::forward<Tp>(_v);
return *this;
}
template <typename Tp>
stream_base& operator<<(Tp& _v)
{
m_os << _v;
return *this;
}
stream_base& put(char _c)
{
m_os.put(_c);
return *this;
}
stream_base& endl()
{
m_os << std::endl;
return *this;
}
template <typename... Args>
stream_base& write(Args&&... _args)
{
m_os.write(std::forward<Args>(_args)...);
return *this;
}
stream_base& flush()
{
m_os << std::flush;
return *this;
}
auto tellp() { return m_os.tellp(); }
template <typename... Args>
stream_base& seekp(Args&&... _args)
{
m_os.seekp(std::forward<Args>(_args)...);
return *this;
}
private:
StreamT& m_os;
};
template <typename StreamT>
stream_base<StreamT>
stream(StreamT& _os, const char* _color)
{
return stream_base<StreamT>{ _os, _color };
}
template <typename StreamT>
stream_base<StreamT>
info_stream(StreamT& _os)
{
return stream_base<StreamT>{ _os, color::info() };
}
template <typename StreamT>
stream_base<StreamT>
source_stream(StreamT& _os)
{
return stream_base<StreamT>{ _os, color::source() };
}
template <typename StreamT>
stream_base<StreamT>
warning_stream(StreamT& _os)
{
return stream_base<StreamT>{ _os, color::warning() };
}
template <typename StreamT>
stream_base<StreamT>
fatal_stream(StreamT& _os)
{
return stream_base<StreamT>{ _os, color::fatal() };
}
inline std::string
string(const char* _color, std::string_view _v)
{
return std::string{ _color } + std::string{ _v } + std::string{ color::end() };
}
inline std::string
string(const char* _color, std::stringstream& _v)
{
return std::string{ _color } + _v.str() + std::string{ color::end() };
}
inline std::string
string(const char* _color, std::stringstream&& _v)
{
return std::string{ _color } + _v.str() + std::string{ color::end() };
}
template <typename Tp>
inline auto
info_string(Tp&& _v)
{
return string(color::info(), std::forward<Tp>(_v));
}
template <typename Tp>
inline auto
source_string(Tp&& _v)
{
return string(color::source(), std::forward<Tp>(_v));
}
template <typename Tp>
inline auto
warning_string(Tp&& _v)
{
return string(color::warning(), std::forward<Tp>(_v));
}
template <typename Tp>
inline auto
fatal_string(Tp&& _v)
{
return string(color::fatal(), std::forward<Tp>(_v));
}
} // namespace log
} // namespace rocprofiler_register
#if !defined(ROCPROFILER_REGISTER_LOG)
# define ROCPROFILER_REGISTER_LOG(COLOR, EXIT_CODE) \
(::rocprofiler_register::log::logger(EXIT_CODE) \
<< ::rocprofiler_register::log::color::end() \
<< ::rocprofiler_register::log::color::source() << "[" \
<< ROCPROFILER_REGISTER_PROJECT_NAME << "][" << ROCP_REG_FILE_NAME << ":" \
<< __LINE__ << "][" << getpid() << "] " \
<< ::rocprofiler_register::log::color::end() << COLOR)
#endif
#if defined(NDEBUG)
# if !defined(ROCPROFILER_REGISTER_INFO)
# define ROCPROFILER_REGISTER_INFO (::rocprofiler_register::log::base())
# endif
# if !defined(ROCPROFILER_REGISTER_ASSERT)
# define ROCPROFILER_REGISTER_ASSERT(COND) (::rocprofiler_register::log::base())
# endif
#else
# if !defined(ROCPROFILER_REGISTER_INFO)
# define ROCPROFILER_REGISTER_INFO \
ROCPROFILER_REGISTER_LOG(::rocprofiler_register::log::color::info(), false)
# endif
# if !defined(ROCPROFILER_REGISTER_ASSERT)
# define ROCPROFILER_REGISTER_ASSERT(COND) \
(COND) ? ::rocprofiler_register::log::base() : ROCPROFILER_REGISTER_FATAL
# endif
#endif
#if !defined(ROCPROFILER_REGISTER_WARNING)
# define ROCPROFILER_REGISTER_WARNING \
ROCPROFILER_REGISTER_LOG(::rocprofiler_register::log::color::warning(), false)
#endif
#if !defined(ROCPROFILER_REGISTER_FATAL)
# define ROCPROFILER_REGISTER_FATAL \
ROCPROFILER_REGISTER_LOG(::rocprofiler_register::log::color::fatal(), true)
#endif
#if !defined(ROCPROFILER_REGISTER_PREFER)
# define ROCPROFILER_REGISTER_PREFER(COND) \
(COND) ? ::rocprofiler_register::log::base() : ROCPROFILER_REGISTER_WARNING
#endif
#if !defined(ROCPROFILER_REGISTER_REQUIRE)
# define ROCPROFILER_REGISTER_REQUIRE(COND) \
(COND) ? ::rocprofiler_register::log::base() : ROCPROFILER_REGISTER_FATAL
#endif
@@ -0,0 +1,127 @@
// MIT License
//
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include "utility.hpp"
#include <string>
#include <string_view>
#include <sys/types.h>
#include <unistd.h>
namespace rocprofiler_register
{
namespace utility
{
namespace
{
template <typename ContainerT, typename... Args>
inline auto
emplace_impl(ContainerT& _c, int, Args&&... _args)
-> decltype(_c.emplace_back(std::forward<Args>(_args)...))
{
return _c.emplace_back(std::forward<Args>(_args)...);
}
template <typename ContainerT, typename... Args>
inline auto
emplace_impl(ContainerT& _c, long, Args&&... _args)
-> decltype(_c.emplace(std::forward<Args>(_args)...))
{
return _c.emplace(std::forward<Args>(_args)...);
}
template <typename ContainerT, typename... Args>
inline auto
emplace(ContainerT& _c, Args&&... _args)
{
return emplace_impl(_c, 0, std::forward<Args>(_args)...);
}
template <typename ContainerT, typename ArgT>
inline auto
reserve_impl(ContainerT& _c, int, ArgT _arg) -> decltype(_c.reserve(_arg), bool())
{
_c.reserve(_arg);
return true;
}
template <typename ContainerT, typename ArgT>
inline auto
reserve_impl(ContainerT&, long, ArgT)
{
return false;
}
template <typename ContainerT, typename ArgT>
inline auto
reserve(ContainerT& _c, ArgT _arg)
{
return reserve_impl(_c, 0, _arg);
}
} // namespace
template <typename ContainerT>
ContainerT
delimit(const std::string& line, std::string_view delimiters)
{
ContainerT _result{};
size_t _beginp = 0; // position that is the beginning of the new string
size_t _delimp = 0; // position of the delimiter in the string
if(reserve(_result, 0))
{
size_t _nmax = 0;
for(char itr : line)
{
for(size_t j = 0; j < delimiters.length(); ++j)
{
if(itr == delimiters.at(j)) ++_nmax;
}
}
reserve(_result, _nmax);
}
while(_beginp < line.length() && _delimp < line.length())
{
// find the first character (starting at _delimp) that is not a delimiter
_beginp = line.find_first_not_of(delimiters, _delimp);
// if no a character after or at _end that is not a delimiter is not found
// then we are done
if(_beginp == std::string::npos) break;
// starting at the position of the new string, find the next delimiter
_delimp = line.find_first_of(delimiters, _beginp);
std::string _tmp{};
// starting at the position of the new string, get the characters
// between this position and the next delimiter
_tmp = line.substr(_beginp, _delimp - _beginp);
// don't add empty strings
if(!_tmp.empty()) emplace(_result, _tmp);
}
return _result;
}
template std::vector<std::string>
delimit(const std::string&, std::string_view);
template std::set<std::string>
delimit(const std::string&, std::string_view);
} // namespace utility
} // namespace rocprofiler_register
@@ -0,0 +1,44 @@
// 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 <set>
#include <string>
#include <string_view>
#include <vector>
namespace rocprofiler_register
{
namespace utility
{
template <typename ContainerT = std::vector<std::string>>
ContainerT
delimit(const std::string& line, std::string_view delimiters = "\"',;: ");
extern template std::vector<std::string>
delimit(const std::string&, std::string_view);
extern template std::set<std::string>
delimit(const std::string&, std::string_view);
} // namespace utility
} // namespace rocprofiler_register
@@ -0,0 +1,24 @@
// 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 <rocprofiler-register/rocprofiler-register.h>
#include <rocprofiler-register/version.h>
int ROCPROFILER_REGISTER_INTERNAL_API rocp_register_sym = 0;
@@ -0,0 +1,374 @@
// 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.
#define GNU_SOURCE 1
#include <rocprofiler-register/rocprofiler-register.h>
#include "details/dl.hpp"
#include "details/environment.hpp"
#include "details/log.hpp"
#include <array>
#include <atomic>
#include <bitset>
#include <filesystem>
#include <mutex>
#include <regex>
#include <stdexcept>
#include <string_view>
#include <utility>
#include <dlfcn.h>
extern "C" {
#pragma weak rocprofiler_configure
#pragma weak rocprofiler_set_api_table
#pragma weak rocprofiler_register_import_hip
#pragma weak rocprofiler_register_import_hip_static
#pragma weak rocprofiler_register_import_hsa
#pragma weak rocprofiler_register_import_hsa_static
#pragma weak rocprofiler_register_import_roctx
#pragma weak rocprofiler_register_import_roctx_static
extern rocprofiler_configure_result_t*
rocprofiler_configure(uint32_t, const char*, uint32_t, uint32_t);
extern int
rocprofiler_set_api_table(const char*, uint64_t, uint64_t, void**, uint64_t);
extern uint32_t
rocprofiler_register_import_hip(void);
extern uint32_t
rocprofiler_register_import_hsa(void);
extern uint32_t
rocprofiler_register_import_roctx(void);
extern uint32_t
rocprofiler_register_import_hip_static(void);
extern uint32_t
rocprofiler_register_import_hsa_static(void);
extern uint32_t
rocprofiler_register_import_roctx_static(void);
}
namespace
{
namespace fs = ::std::filesystem;
using namespace rocprofiler_register;
using rocprofiler_set_api_table_t = decltype(::rocprofiler_set_api_table)*;
using bitset_t = std::bitset<sizeof(rocprofiler_register_library_indentifier_t::handle)>;
static_assert(sizeof(bitset_t) ==
sizeof(rocprofiler_register_library_indentifier_t::handle),
"bitset should be same at uint64_t");
int rocprofiler_register_verbose = common::get_env("ROCPROFILER_REGISTER_VERBOSE", 0);
constexpr int rocprofiler_register_info_level = 2;
constexpr auto rocprofiler_lib_name = "librocprofiler64.so";
constexpr auto rocprofiler_lib_register_entrypoint = "rocprofiler_set_api_table";
constexpr auto rocprofiler_register_lib_name =
"librocprofiler-register.so." ROCPROFILER_REGISTER_SOVERSION;
enum rocp_reg_supported_library // NOLINT(performance-enum-size)
{
ROCP_REG_HSA = 0,
ROCP_REG_HIP,
ROCP_REG_ROCTX,
ROCP_REG_LAST,
};
template <size_t>
struct supported_library_trait
{
static constexpr bool specialized = false;
static constexpr auto value = ROCP_REG_LAST;
static constexpr const char* const common_name = nullptr;
static constexpr const char* const symbol_name = nullptr;
static constexpr const char* const library_name = nullptr;
};
#define ROCP_REG_DEFINE_LIBRARY_TRAITS(ENUM, NAME, SYM_NAME, LIB_NAME) \
template <> \
struct supported_library_trait<ENUM> \
{ \
static constexpr bool specialized = true; \
static constexpr auto value = ENUM; \
static constexpr auto common_name = NAME; \
static constexpr auto symbol_name = SYM_NAME; \
static constexpr auto library_name = LIB_NAME; \
};
ROCP_REG_DEFINE_LIBRARY_TRAITS(ROCP_REG_HSA,
"hsa",
"rocprofiler_register_import_hsa",
"libhsa-runtime64.so.[2-9]($|\\.[0-9\\.]+)")
ROCP_REG_DEFINE_LIBRARY_TRAITS(ROCP_REG_HIP,
"hip",
"rocprofiler_register_import_hip",
"libamdhip64.so.[6-9]($|\\.[0-9\\.]+)")
ROCP_REG_DEFINE_LIBRARY_TRAITS(ROCP_REG_ROCTX,
"roctx",
"rocprofiler_register_import_roctx",
"libroctx64.so.[4-9]($|\\.[0-9\\.]+)")
auto
get_this_library_path()
{
auto _this_lib_path = binary::get_linked_path(rocprofiler_register_lib_name,
{ RTLD_NOLOAD | RTLD_LAZY });
ROCPROFILER_REGISTER_REQUIRE(_this_lib_path)
<< rocprofiler_register_lib_name
<< " could not locate itself in the list of loaded libraries";
return fs::path{ *_this_lib_path }.parent_path().string();
}
struct rocp_import
{
rocp_reg_supported_library library_idx = ROCP_REG_LAST;
std::string_view common_name = {};
std::string_view symbol_name = {};
std::string_view library_name = {};
};
template <size_t... Idx>
auto rocp_reg_get_imports(std::index_sequence<Idx...>)
{
auto _data = std::vector<rocp_import>{};
auto _import_scan = [&_data](auto _info) {
if(_info.specialized)
{
_data.emplace_back(rocp_import{
_info.value, _info.common_name, _info.symbol_name, _info.library_name });
}
};
(_import_scan(supported_library_trait<Idx>{}), ...);
return _data;
}
auto
rocp_reg_scan_for_tools()
{
auto _rocp_reg_lib = common::get_env("ROCPROFILER_REGISTER_LIBRARY", std::string{});
bool _force_tool =
common::get_env("ROCPROFILER_REGISTER_FORCE_LOAD", !_rocp_reg_lib.empty());
bool _found_tool = (rocprofiler_configure != nullptr || _force_tool);
static void* rocprofiler_lib_handle = nullptr;
static rocprofiler_set_api_table_t rocprofiler_lib_config_fn = nullptr;
if(_force_tool)
{
if(rocprofiler_lib_handle && rocprofiler_lib_config_fn)
return std::make_pair(rocprofiler_lib_handle, rocprofiler_lib_config_fn);
if(_rocp_reg_lib.empty()) _rocp_reg_lib = rocprofiler_lib_name;
auto _rocp_reg_lib_path = fs::path{ _rocp_reg_lib };
auto _rocp_reg_lib_path_fname = _rocp_reg_lib_path.filename();
auto _rocp_reg_lib_path_abs =
(_rocp_reg_lib_path.is_absolute())
? _rocp_reg_lib_path
: (fs::path{ get_this_library_path() } / _rocp_reg_lib_path_fname);
// check to see if the rocprofiler library is already loaded
rocprofiler_lib_handle =
dlopen(_rocp_reg_lib_path.c_str(), RTLD_NOLOAD | RTLD_LAZY);
// try to load with the given path
if(!rocprofiler_lib_handle)
{
rocprofiler_lib_handle =
dlopen(_rocp_reg_lib_path.c_str(), RTLD_GLOBAL | RTLD_LAZY);
}
// try to load with the absoulte path
if(!rocprofiler_lib_handle)
{
_rocp_reg_lib_path = _rocp_reg_lib_path_abs;
rocprofiler_lib_handle =
dlopen(_rocp_reg_lib_path.c_str(), RTLD_GLOBAL | RTLD_LAZY);
}
// try to load with the basename path
if(!rocprofiler_lib_handle)
{
_rocp_reg_lib_path = _rocp_reg_lib_path_fname;
rocprofiler_lib_handle =
dlopen(_rocp_reg_lib_path.c_str(), RTLD_GLOBAL | RTLD_LAZY);
}
if(rocprofiler_register_verbose >= rocprofiler_register_info_level)
ROCPROFILER_REGISTER_INFO << "loaded " << _rocp_reg_lib_path_fname.string()
<< " library at " << _rocp_reg_lib_path.string();
ROCPROFILER_REGISTER_REQUIRE(rocprofiler_lib_handle)
<< _rocp_reg_lib << " failed to load\n";
*(void**) (&rocprofiler_lib_config_fn) =
dlsym(rocprofiler_lib_handle, rocprofiler_lib_register_entrypoint);
ROCPROFILER_REGISTER_REQUIRE(rocprofiler_lib_config_fn)
<< _rocp_reg_lib << " did not contain '"
<< rocprofiler_lib_register_entrypoint << "' symbol\n";
}
else if(_found_tool && rocprofiler_set_api_table)
{
rocprofiler_lib_config_fn = &rocprofiler_set_api_table;
}
return std::make_pair(rocprofiler_lib_handle, rocprofiler_lib_config_fn);
}
constexpr auto library_seq = std::make_index_sequence<ROCP_REG_LAST>{};
auto global_mutex = std::recursive_mutex{};
auto import_info = rocp_reg_get_imports(library_seq);
auto instance_counters = std::array<std::atomic_uint64_t, ROCP_REG_LAST>{};
} // namespace
extern "C" {
rocprofiler_register_error_code_t
rocprofiler_register_library_api_table(
const char* common_name,
rocprofiler_register_import_func_t import_func,
uint32_t lib_version,
void** api_tables,
uint64_t api_table_length,
rocprofiler_register_library_indentifier_t* register_id)
{
if(api_table_length < 1) return ROCP_REG_BAD_API_TABLE_LENGTH;
(void) lib_version;
(void) api_tables;
auto _lk = std::unique_lock<std::recursive_mutex>{ global_mutex, std::defer_lock };
if(_lk.owns_lock()) return ROCP_REG_DEADLOCK;
auto _scan_result = rocp_reg_scan_for_tools();
rocp_import* _import_match = nullptr;
for(auto& itr : import_info)
{
if(itr.common_name == common_name)
{
_import_match = &itr;
break;
}
}
// not a supported library name
if(!_import_match || _import_match->library_idx == ROCP_REG_LAST)
return ROCP_REG_UNSUPPORTED_API;
if(import_func != nullptr &&
common::get_env<bool>("ROCPROFILER_REGISTER_SECURE", false))
{
auto _import_func_addr = reinterpret_cast<uintptr_t>(import_func);
auto _segment_addresses = binary::get_segment_addresses();
auto _in_address_range = [](uintptr_t _addr,
const std::vector<binary::address_range>& _range) {
for(auto ritr : _range)
{
if(_addr >= ritr.start && _addr < ritr.last) return true;
}
return false;
};
// check that the address of the import function is within the expected library
// name
bool _valid_addr = false;
for(const auto& itr : _segment_addresses)
{
if(_in_address_range(_import_func_addr, itr.ranges))
{
if(std::regex_search(fs::path{ itr.filepath }.filename().string(),
std::regex{ _import_match->library_name.data() }))
{
_valid_addr = true;
}
}
}
// the library provided
if(!_valid_addr) return ROCP_REG_INVALID_API_ADDRESS;
}
constexpr auto offset_factor = 64 / std::max<size_t>(ROCP_REG_LAST, 8);
// if ROCP_REG_LAST > 8, then we can no longer encode 8 instances per lib
// because we ran out of bits (i.e. max of 8 * 8 = 64)
static_assert((offset_factor * ROCP_REG_LAST) <= sizeof(uint64_t) * 8,
"ROCP_REG_LAST has exceeded the max allowable size");
// too many instances of the same library
if(instance_counters.at(_import_match->library_idx) >= offset_factor)
return ROCP_REG_EXCESS_API_INSTANCES;
auto _instance_val = instance_counters.at(_import_match->library_idx)++;
auto& _bits = *reinterpret_cast<bitset_t*>(&register_id->handle);
_bits = bitset_t{ (offset_factor * _import_match->library_idx) + _instance_val };
if(_bits.to_ulong() != register_id->handle)
throw std::runtime_error("error encoding register_id");
// rocprofiler library is dlopened and we have the functor to pass the API data
auto _activate_rocprofiler = (_scan_result.second != nullptr);
if(_activate_rocprofiler)
{
auto _ret = _scan_result.second(
common_name, lib_version, _instance_val, api_tables, api_table_length);
if(_ret != 0) return ROCP_REG_ROCPROFILER_ERROR;
}
else
{
return ROCP_REG_NO_TOOLS;
}
return ROCP_REG_SUCCESS;
}
const char*
rocprofiler_register_error_string(rocprofiler_register_error_code_t _ec)
{
switch(_ec)
{
case ROCP_REG_SUCCESS: return "rocprofiler_register_success";
case ROCP_REG_NO_TOOLS: return "rocprofiler_register_no_tools";
case ROCP_REG_DEADLOCK: return "rocprofiler_register_deadlock";
case ROCP_REG_BAD_API_TABLE_LENGTH:
return "rocprofiler_register_bad_api_table_length";
case ROCP_REG_UNSUPPORTED_API: return "rocprofiler_register_unsupported_api";
case ROCP_REG_INVALID_API_ADDRESS:
return "rocprofiler_register_invalid_api_address";
case ROCP_REG_ROCPROFILER_ERROR: return "rocprofiler_register_rocprofiler_error";
case ROCP_REG_EXCESS_API_INSTANCES:
return "rocprofiler_register_excess_api_instances";
case ROCP_REG_ERROR_CODE_END: return "rocprofiler_register_unknown_error";
}
return "rocprofiler_register_unknown_error";
}
}
+465
Wyświetl plik
@@ -0,0 +1,465 @@
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
project(rocprofiler-register-tests LANGUAGES C CXX)
include(CMakeParseArguments)
include(GNUInstallDirs)
if("${CMAKE_PROJECT_NAME}" STREQUAL "${PROJECT_NAME}")
find_package(rocprofiler-register REQUIRED)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_C_VISIBILITY_PRESET "hidden")
set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
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}")
enable_testing()
include(CTest)
endif()
function(rocp_register_strip_target)
if(CMAKE_BUILD_TYPE MATCHES "(DEBUG|Debug)")
return()
endif()
cmake_parse_arguments(STRIP "" "" "ARGS" ${ARGN})
list(LENGTH STRIP_UNPARSED_ARGUMENTS NUM_UNPARSED)
if(NUM_UNPARSED EQUAL 1)
set(_TARGET "${STRIP_UNPARSED_ARGUMENTS}")
else()
message(
FATAL_ERROR "rocp_register_strip_target cannot deduce target from \"${ARGN}\""
)
endif()
if(NOT TARGET "${_TARGET}")
message(
FATAL_ERROR
"rocp_register_strip_target not provided valid target: \"${_TARGET}\"")
endif()
if(CMAKE_STRIP)
add_custom_command(
TARGET ${_TARGET}
POST_BUILD
COMMAND ${CMAKE_STRIP} ${STRIP_ARGS} $<TARGET_FILE:${_TARGET}>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMENT "Stripping ${_TARGET}...")
else()
message(WARNING "CMAKE_STRIP not set... Not stripping ${_TARGET}")
endif()
endfunction()
#
# mock libraries
#
add_subdirectory(hsa-runtime)
add_subdirectory(amdhip)
add_subdirectory(roctx)
add_subdirectory(rocprofiler)
#
# common to multiple tests
#
find_package(Threads REQUIRED)
add_library(rocprofiler-register-tests-common INTERFACE)
target_include_directories(rocprofiler-register-tests-common
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
target_link_libraries(rocprofiler-register-tests-common INTERFACE Threads::Threads stdc++)
add_library(rocprofiler-register-tests-strong INTERFACE)
target_compile_definitions(rocprofiler-register-tests-strong
INTERFACE ROCP_REG_TEST_WEAK=0)
add_library(rocprofiler-register-tests-weak INTERFACE)
target_compile_definitions(rocprofiler-register-tests-weak INTERFACE ROCP_REG_TEST_WEAK=1)
add_library(rocprofiler-register-tests-rocp INTERFACE)
target_link_options(rocprofiler-register-tests-rocp INTERFACE -Wl,--no-as-needed)
target_link_libraries(rocprofiler-register-tests-rocp INTERFACE rocprofiler::rocprofiler)
add_library(rocprofiler-register::tests-common ALIAS rocprofiler-register-tests-common)
add_library(rocprofiler-register::tests-strong ALIAS rocprofiler-register-tests-strong)
add_library(rocprofiler-register::tests-weak ALIAS rocprofiler-register-tests-weak)
add_library(rocprofiler-register::tests-rocp ALIAS rocprofiler-register-tests-rocp)
#
# test scenarios
#
function(rocp_register_test_executable _NAME)
set(_SV_ARGS)
foreach(_TYPE "CORE" "PRELOAD" "WRAP" "PRELOAD_WRAP")
list(APPEND _SV_ARGS "${_TYPE}_PASS_REGEX" "${_TYPE}_FAIL_REGEX")
endforeach()
cmake_parse_arguments(
RRTE
"" # options
"SECURE;${_SV_ARGS}" # single value args
"SOURCES;LIBRARIES" # multiple value args
${ARGN})
add_executable(${_NAME})
target_sources(${_NAME} PRIVATE ${RRTE_SOURCES})
target_link_libraries(${_NAME} PRIVATE rocprofiler-register::tests-common
${RRTE_LIBRARIES})
function(rocp_register_add_test _TEST_NAME _TARGET _ENV _PASS _FAIL)
if(RRTE_SECURE)
list(APPEND _ENV "ROCPROFILER_REGISTER_SECURE=true")
set(_LABELS "secure")
else()
set(_LABELS "insecure")
endif()
add_test(
NAME ${_TEST_NAME}
COMMAND $<TARGET_FILE:${_TARGET}>
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(
${_TEST_NAME}
PROPERTIES ENVIRONMENT
"LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY};${_ENV}"
PASS_REGULAR_EXPRESSION
"${_PASS}"
FAIL_REGULAR_EXPRESSION
"${_FAIL}"
LABELS
"${_LABELS}"
${ARGN})
endfunction()
rocp_register_add_test(${_NAME} ${_NAME} "" "${RRTE_CORE_PASS_REGEX}"
"${RRTE_CORE_FAIL_REGEX}")
rocp_register_add_test(${_NAME}-preload ${_NAME} "LD_PRELOAD=librocprofiler64.so"
"${RRTE_PRELOAD_PASS_REGEX}" "${RRTE_PRELOAD_FAIL_REGEX}")
rocp_register_add_test(${_NAME}-wrap ${_NAME} "ROCP_REG_TEST_WRAP=1"
"${RRTE_WRAP_PASS_REGEX}" "${RRTE_WRAP_FAIL_REGEX}")
rocp_register_add_test(
${_NAME}-preload-wrap ${_NAME}
"LD_PRELOAD=librocprofiler64.so;ROCP_REG_TEST_WRAP=1"
"${RRTE_PRELOAD_WRAP_PASS_REGEX}" "${RRTE_PRELOAD_WRAP_FAIL_REGEX}")
endfunction()
# serial
rocp_register_test_executable(
test-amdhip-roctx
SECURE ON
SOURCES test-amdhip-roctx.cpp
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip roctx::roctx
CORE_PASS_REGEX
".hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
PRELOAD_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
WRAP_PASS_REGEX
".hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
PRELOAD_WRAP_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-main\n.rocprofiler.cpp..pop. thread-main\n"
)
rocp_register_test_executable(
test-amdhip-roctx-weak
SOURCES test-amdhip-roctx.cpp
LIBRARIES rocprofiler-register::tests-weak
CORE_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
PRELOAD_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
PRELOAD_WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-main\n.rocprofiler.cpp..pop. thread-main\n"
)
rocp_register_test_executable(
test-amdhip-roctx-rocp
SOURCES test-amdhip-roctx.cpp
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip roctx::roctx
rocprofiler-register::tests-rocp
CORE_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
PRELOAD_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
WRAP_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-main\n.rocprofiler.cpp..pop. thread-main\n"
PRELOAD_WRAP_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-main\n.rocprofiler.cpp..pop. thread-main\n"
)
rocp_register_test_executable(
test-amdhip-roctx-weak-rocp
SOURCES test-amdhip-roctx.cpp
LIBRARIES rocprofiler-register::tests-weak rocprofiler-register::tests-rocp
CORE_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
PRELOAD_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-main\n.rocprofiler.cpp..pop. thread-main\n"
PRELOAD_WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-main\n.rocprofiler.cpp..pop. thread-main\n"
)
# multithreaded
rocp_register_test_executable(
test-amdhip-roctx-mt
SOURCES test-amdhip-roctx-mt.cpp
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip roctx::roctx
CORE_PASS_REGEX
".hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
PRELOAD_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
WRAP_PASS_REGEX
".hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
PRELOAD_WRAP_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n"
)
rocp_register_test_executable(
test-amdhip-roctx-mt-weak
SOURCES test-amdhip-roctx-mt.cpp
LIBRARIES rocprofiler-register::tests-weak
CORE_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
PRELOAD_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
PRELOAD_WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n"
)
rocp_register_test_executable(
test-amdhip-roctx-mt-rocp
SOURCES test-amdhip-roctx-mt.cpp
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip roctx::roctx
rocprofiler-register::tests-rocp
CORE_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
PRELOAD_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
WRAP_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n"
PRELOAD_WRAP_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n"
)
# 29
rocp_register_test_executable(
test-amdhip-roctx-mt-weak-rocp
SOURCES test-amdhip-roctx-mt.cpp
LIBRARIES rocprofiler-register::tests-weak rocprofiler-register::tests-rocp
CORE_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
PRELOAD_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n"
PRELOAD_WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n"
)
# constructor
rocp_register_test_executable(
test-amdhip-ctor
SOURCES test-amdhip-ctor.cpp
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip
CORE_PASS_REGEX
".hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n"
PRELOAD_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n"
WRAP_PASS_REGEX
".hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n"
PRELOAD_WRAP_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n"
)
rocp_register_test_executable(
test-amdhip-ctor-weak
SOURCES test-amdhip-ctor.cpp
LIBRARIES rocprofiler-register::tests-weak
CORE_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n"
PRELOAD_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n"
WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n"
PRELOAD_WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n"
)
# 41
rocp_register_test_executable(
test-amdhip-ctor-rocp
SOURCES test-amdhip-ctor.cpp
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip
rocprofiler-register::tests-rocp
CORE_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n"
PRELOAD_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n"
WRAP_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n"
PRELOAD_WRAP_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n"
)
rocp_register_test_executable(
test-amdhip-ctor-weak-rocp
SOURCES test-amdhip-ctor.cpp
LIBRARIES rocprofiler-register::tests-weak rocprofiler-register::tests-rocp
CORE_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n"
PRELOAD_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n"
WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n"
PRELOAD_WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n"
)
# constructor + mt
rocp_register_test_executable(
test-amdhip-ctor-mt
SOURCES test-amdhip-ctor-mt.cpp
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip
CORE_PASS_REGEX
".hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
PRELOAD_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
WRAP_PASS_REGEX
".hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
PRELOAD_WRAP_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n"
)
rocp_register_test_executable(
test-amdhip-ctor-mt-weak
SOURCES test-amdhip-ctor-mt.cpp
LIBRARIES rocprofiler-register::tests-weak
CORE_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
PRELOAD_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
PRELOAD_WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n"
)
rocp_register_test_executable(
test-amdhip-ctor-mt-rocp
SOURCES test-amdhip-ctor-mt.cpp
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip
rocprofiler-register::tests-rocp
CORE_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
PRELOAD_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
WRAP_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n"
PRELOAD_WRAP_PASS_REGEX
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n"
)
rocp_register_test_executable(
test-amdhip-ctor-mt-weak-rocp
SOURCES test-amdhip-ctor-mt.cpp
LIBRARIES rocprofiler-register::tests-weak rocprofiler-register::tests-rocp
CORE_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
PRELOAD_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n"
PRELOAD_WRAP_PASS_REGEX
".fwd.hpp. dlopen libamdhip64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n"
)
add_executable(test-invalid-hsa-runtime)
target_sources(test-invalid-hsa-runtime PRIVATE test-amdhip-roctx.cpp)
target_link_libraries(
test-invalid-hsa-runtime PRIVATE rocprofiler-register::tests-common roctx::roctx
amdhip::amdhip-invalid)
add_test(
NAME test-secure-invalid-hsa-runtime
COMMAND $<TARGET_FILE:test-invalid-hsa-runtime>
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(
test-secure-invalid-hsa-runtime
PROPERTIES
ENVIRONMENT
"LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/invalid:${CMAKE_LIBRARY_OUTPUT_DIRECTORY};ROCPROFILER_REGISTER_SECURE=1"
LABELS
"secure"
WILL_FAIL
ON)
add_test(
NAME test-insecure-invalid-hsa-runtime
COMMAND $<TARGET_FILE:test-invalid-hsa-runtime>
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(
test-insecure-invalid-hsa-runtime
PROPERTIES
ENVIRONMENT
"LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/invalid:${CMAKE_LIBRARY_OUTPUT_DIRECTORY};ROCPROFILER_REGISTER_SECURE=0"
LABELS
"insecure")
add_executable(test-amdhip-hsart-roctx)
target_sources(test-amdhip-hsart-roctx PRIVATE test-amdhip-hsart-roctx.cpp)
target_link_libraries(
test-amdhip-hsart-roctx PRIVATE rocprofiler-register::tests-common
hsa-runtime::hsa-runtime amdhip::amdhip roctx::roctx)
add_test(
NAME test-force-rocprofiler-dlopen
COMMAND $<TARGET_FILE:test-amdhip-hsart-roctx>
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(
test-force-rocprofiler-dlopen
PROPERTIES
ENVIRONMENT
"LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY};ROCPROFILER_REGISTER_FORCE_LOAD=1;ROCPROFILER_REGISTER_SECURE=yes;ROCPROFILER_REGISTER_VERBOSE=3"
LABELS
"dlopen;secure")
add_test(
NAME test-rocprofiler-register-library-base-path
COMMAND $<TARGET_FILE:test-amdhip-hsart-roctx>
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(
test-rocprofiler-register-library-base-path
PROPERTIES
ENVIRONMENT
"LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY};ROCPROFILER_REGISTER_LIBRARY=librocprofiler64.so;ROCPROFILER_REGISTER_SECURE=yes;ROCPROFILER_REGISTER_VERBOSE=3;ROCPROFILER_REGISTER_MONOCHROME=true"
LABELS
"dlopen;secure")
add_test(
NAME test-rocprofiler-register-library-absolute-path
COMMAND $<TARGET_FILE:test-amdhip-hsart-roctx>
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set_tests_properties(
test-rocprofiler-register-library-absolute-path
PROPERTIES
ENVIRONMENT
"LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY};ROCPROFILER_REGISTER_LIBRARY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/librocprofiler64.so;ROCPROFILER_REGISTER_SECURE=yes;ROCPROFILER_REGISTER_VERBOSE=3;ROCPROFILER_REGISTER_MONOCHROME=true"
LABELS
"dlopen;secure")
+39
Wyświetl plik
@@ -0,0 +1,39 @@
#
#
#
if(NOT TARGET rocprofiler-register::rocprofiler-register)
find_package(rocprofiler-register REQUIRED)
endif()
add_library(amdhip SHARED)
add_library(amdhip::amdhip ALIAS amdhip)
target_sources(amdhip PRIVATE amdhip.cpp amdhip.hpp)
target_include_directories(amdhip PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
target_link_libraries(
amdhip
PRIVATE rocprofiler-register::rocprofiler-register
PUBLIC hsa-runtime::hsa-runtime)
set_target_properties(
amdhip
PROPERTIES OUTPUT_NAME amdhip64
SOVERSION 6
VERSION 6.0.1)
rocp_register_strip_target(amdhip)
add_library(amdhip-invalid SHARED)
add_library(amdhip::amdhip-invalid ALIAS amdhip-invalid)
target_sources(amdhip-invalid PRIVATE amdhip.cpp amdhip.hpp)
target_include_directories(amdhip-invalid
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
target_link_libraries(
amdhip-invalid
PRIVATE rocprofiler-register::rocprofiler-register
PUBLIC hsa-runtime::hsa-runtime-invalid)
set_target_properties(
amdhip-invalid
PROPERTIES OUTPUT_NAME amdhip64
SOVERSION 6
VERSION 6.0.1
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/invalid")
rocp_register_strip_target(amdhip-invalid)
+154
Wyświetl plik
@@ -0,0 +1,154 @@
#include "amdhip.hpp"
#include "hsa-runtime.hpp"
#include <rocprofiler-register/rocprofiler-register.h>
#include <atomic>
#include <iostream>
#include <mutex>
#include <string_view>
#define ROCP_REG_VERSION \
ROCPROFILER_REGISTER_COMPUTE_VERSION_3( \
HIP_VERSION_MAJOR, HIP_VERSION_MINOR, HIP_VERSION_PATCH)
ROCPROFILER_REGISTER_DEFINE_IMPORT(hip, ROCP_REG_VERSION)
#ifndef ROCP_REG_FILE_NAME
# define ROCP_REG_FILE_NAME \
::std::string{ __FILE__ } \
.substr(::std::string_view{ __FILE__ }.find_last_of('/') + 1) \
.c_str()
#endif
namespace hip
{
namespace
{
auto&
get_hip_api_table_impl()
{
static auto _table = std::atomic<HipApiTable*>{ nullptr };
return _table;
}
void
register_profiler_impl()
{
static auto _const_api_table = HipApiTable{};
initialize_hip_api_table(&_const_api_table);
// set this before any recursive opportunity arises
get_hip_api_table_impl().exchange(&_const_api_table);
// create a copy of the api table for modification by registration
static auto _profiler_api_table = HipApiTable{};
copy_hip_api_table(&_profiler_api_table, &_const_api_table);
void* _profiler_api_table_v = static_cast<void*>(&_profiler_api_table);
auto lib_id = rocprofiler_register_library_indentifier_t{};
auto success =
rocprofiler_register_library_api_table("hip",
&ROCPROFILER_REGISTER_IMPORT_FUNC(hip),
ROCP_REG_VERSION,
&_profiler_api_table_v,
1,
&lib_id);
if(success == ROCP_REG_SUCCESS)
{
printf("[%s] hip identifier %lu\n", ROCP_REG_FILE_NAME, lib_id.handle);
auto* _api_table = &_const_api_table;
if(!get_hip_api_table_impl().compare_exchange_strong(_api_table,
&_profiler_api_table))
{
// with the current impl, if we ever get here, someone is calling one the
// functions in this anonymous namespace that shouldn't
std::cerr
<< "register_profiler_impl expected the API table to be the internal "
"implementation and yet it is not. something went wrong.\n";
abort();
}
}
else if(success != ROCP_REG_NO_TOOLS)
{
std::cerr << "HIP library failed to register with rocprofiler-register: "
<< rocprofiler_register_error_string(success) << "\n";
exit(EXIT_FAILURE);
}
}
void
register_profiler()
{
// this registration scheme is designed to minimize overhead once
// registered (only pay cost of checking atomic boolean)
// once the profiler is registered. If the library has not
// been registered and two or more threads try to register concurrently
// the first thread to acquire the lock below, will block the
// threads until registration is complete. However,
// if the same thread performing the registration re-enters this function
// i.e. this library's API is called during registration, this function
// will prevent a deadlock by not attempting to re-enter the
// the call-once and not releasing any waiting threads by flipping
// the _is_registered field to true.
static auto _is_registered = std::atomic<bool>{ false };
if(!_is_registered.load(std::memory_order_acquire))
{
using mutex_t = std::recursive_mutex;
using auto_lock_t = std::unique_lock<mutex_t>;
static auto _once = std::once_flag{};
static auto _mutex = mutex_t{};
// defer the lock so we can check for recursion
auto _lk = auto_lock_t{ _mutex, std::defer_lock };
// this will be true if the same thread currently executing the call_once invokes
// the library's API while registering the profiler (e.g. tool which wants to
// instrument HIP API invokes a HIP function while registering with the profiler)
// we allow this thread to proceed and access the "const" API table but
// return so it does not flip _is_registered to true, which would result
// in any subsequent threads not waiting until the library is fully registered,
// resulting in missed callbacks for the tools
if(_lk.owns_lock()) return;
// ensures any subsequent threads wait until the first thread
// finishes registration
_lk.lock();
// call_once to ensure that we only register once
std::call_once(_once, register_profiler_impl);
// the first thread has completed registration and all
// threads waiting on lock will be released and this
// block will not be entered again
_is_registered.exchange(true, std::memory_order_release);
}
}
} // namespace
HipApiTable*
get_hip_api_table()
{
static auto _once = std::once_flag{};
std::call_once(_once, hsa_init);
register_profiler();
return get_hip_api_table_impl().load(std::memory_order_relaxed);
}
void
hip_init()
{
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
}
bool _constructed = true;
} // namespace hip
extern "C" {
void
hip_init(void)
{
if(hip::_constructed) hip::get_hip_api_table()->hip_init_fn();
}
}
+40
Wyświetl plik
@@ -0,0 +1,40 @@
#pragma once
#define HIP_VERSION_MAJOR 6
#define HIP_VERSION_MINOR 0
#define HIP_VERSION_PATCH 1
#include <cstdint>
extern "C" {
// fake hip function
void
hip_init(void) __attribute__((visibility("default")));
}
namespace hip
{
struct HipApiTable
{
uint64_t size = 0;
decltype(::hip_init)* hip_init_fn = nullptr;
};
void
hip_init();
// populates hip api table with function pointers
inline void
initialize_hip_api_table(HipApiTable* dst)
{
dst->size = sizeof(HipApiTable);
dst->hip_init_fn = &::hip::hip_init;
}
// copies the api table from src to dst
inline void
copy_hip_api_table(HipApiTable* dst, const HipApiTable* src)
{
*dst = *src;
}
} // namespace hip
+31
Wyświetl plik
@@ -0,0 +1,31 @@
#pragma once
#include <dlfcn.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(ROCP_REG_TEST_WEAK) && ROCP_REG_TEST_WEAK > 0
# pragma weak hip_init
# pragma weak hsa_init
# pragma weak roctxRangePush
# pragma weak roctxRangePop
#endif
extern void
hip_init(void);
extern void
hsa_init(void);
extern void
roctxRangePush(const char*);
extern void
roctxRangePop(const char*);
#ifdef __cplusplus
}
#endif
+101
Wyświetl plik
@@ -0,0 +1,101 @@
#pragma once
#include "fwd.h"
#include <dlfcn.h>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#ifndef ROCP_REG_FILE_NAME
# define ROCP_REG_FILE_NAME \
::std::string{ __FILE__ } \
.substr(::std::string_view{ __FILE__ }.find_last_of('/') + 1) \
.c_str()
#endif
namespace
{
decltype(hip_init)* hip_init_fn = nullptr;
decltype(hsa_init)* hsa_init_fn = nullptr;
decltype(roctxRangePush)* roctxRangePush_fn = nullptr;
decltype(roctxRangePush)* roctxRangePop_fn = nullptr;
enum rocp_reg_test_modes : uint8_t
{
ROCP_REG_TEST_NONE = 0x0,
ROCP_REG_TEST_HIP = (1 << 0),
ROCP_REG_TEST_HSA = (1 << 1),
ROCP_REG_TEST_ROCTX = (1 << 2),
};
template <uint8_t Idx = ROCP_REG_TEST_NONE>
inline void
resolve_symbols(int _open_mode = RTLD_LOCAL | RTLD_LAZY)
{
auto* _open_mode_env = std::getenv("ROCP_REG_TEST_OPEN_MODE");
if(_open_mode_env)
{
constexpr auto npos = std::string_view::npos;
auto _open_mode_v = std::string_view{ _open_mode_env };
if(_open_mode_v.find("RTLD_GLOBAL") != npos)
_open_mode = RTLD_GLOBAL;
else if(_open_mode_v.find("RTLD_NOLOAD") != npos)
_open_mode = RTLD_NOLOAD;
else
_open_mode = RTLD_LOCAL;
if(_open_mode_v.find("RTLD_NOW") != npos)
_open_mode |= RTLD_NOW;
else
_open_mode |= RTLD_LAZY;
}
auto _resolve_dlopen = [_open_mode](void*& _handle, const char* _lib_name) {
fprintf(
stderr, "[%s] dlopen %s, %i\n", ROCP_REG_FILE_NAME, _lib_name, _open_mode);
_handle = dlopen(_lib_name, _open_mode);
if(!_handle)
{
fprintf(stderr, "Failure opening '%s'\n", _lib_name);
exit(EXIT_FAILURE);
}
};
auto _resolve_dlsym = [](auto& _func, void* _handle, const char* _func_name) {
if(!_func && _handle && _func_name)
{
auto* _func_v = dlsym(_handle, _func_name);
if(_func_v) *(void**) (&_func) = _func_v;
}
};
void* amdhip_handle = nullptr;
void* hsart_handle = nullptr;
void* roctx_handle = nullptr;
if constexpr((Idx & ROCP_REG_TEST_HIP) == ROCP_REG_TEST_HIP)
{
hip_init_fn = hip_init;
if(!hip_init_fn) _resolve_dlopen(amdhip_handle, "libamdhip64.so");
_resolve_dlsym(hip_init_fn, amdhip_handle, "hip_init");
}
if constexpr((Idx & ROCP_REG_TEST_HSA) == ROCP_REG_TEST_HSA)
{
hsa_init_fn = hsa_init;
if(!hsa_init_fn) _resolve_dlopen(hsart_handle, "libhsa-runtime64.so");
_resolve_dlsym(hsa_init_fn, hsart_handle, "hsa_init");
}
if constexpr((Idx & ROCP_REG_TEST_ROCTX) == ROCP_REG_TEST_ROCTX)
{
roctxRangePush_fn = roctxRangePush;
roctxRangePop_fn = roctxRangePop;
if(!roctxRangePush_fn || !roctxRangePop_fn)
_resolve_dlopen(roctx_handle, "libroctx64.so");
_resolve_dlsym(roctxRangePush_fn, roctx_handle, "roctxRangePush");
_resolve_dlsym(roctxRangePop_fn, roctx_handle, "roctxRangePop");
}
}
} // namespace
+35
Wyświetl plik
@@ -0,0 +1,35 @@
#
#
#
if(NOT TARGET rocprofiler-register::rocprofiler-register)
# find_package(rocprofiler-register REQUIRED)
endif()
add_library(hsa-runtime SHARED)
add_library(hsa-runtime::hsa-runtime ALIAS hsa-runtime)
target_sources(hsa-runtime PRIVATE hsa-runtime.cpp hsa-runtime.hpp)
target_include_directories(hsa-runtime
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
target_link_libraries(hsa-runtime PRIVATE rocprofiler-register::rocprofiler-register)
set_target_properties(
hsa-runtime
PROPERTIES OUTPUT_NAME hsa-runtime64
SOVERSION 2
VERSION 2.1.0)
rocp_register_strip_target(hsa-runtime)
add_library(hsa-runtime-invalid SHARED)
add_library(hsa-runtime::hsa-runtime-invalid ALIAS hsa-runtime-invalid)
target_sources(hsa-runtime-invalid PRIVATE hsa-runtime.cpp hsa-runtime.hpp)
target_include_directories(hsa-runtime-invalid
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
target_link_libraries(hsa-runtime-invalid
PRIVATE rocprofiler-register::rocprofiler-register)
set_target_properties(
hsa-runtime-invalid
PROPERTIES OUTPUT_NAME hsa-runtime64
SOVERSION 1
VERSION 1.2.3
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/invalid)
rocp_register_strip_target(hsa-runtime-invalid)
+149
Wyświetl plik
@@ -0,0 +1,149 @@
#include "hsa-runtime.hpp"
#include <rocprofiler-register/rocprofiler-register.h>
#include <atomic>
#include <iostream>
#include <mutex>
#include <string_view>
#define ROCP_REG_VERSION \
ROCPROFILER_REGISTER_COMPUTE_VERSION_3( \
HSA_VERSION_MAJOR, HSA_VERSION_MINOR, HSA_VERSION_PATCH)
ROCPROFILER_REGISTER_DEFINE_IMPORT(hsa, ROCP_REG_VERSION)
#ifndef ROCP_REG_FILE_NAME
# define ROCP_REG_FILE_NAME \
::std::string{ __FILE__ } \
.substr(::std::string_view{ __FILE__ }.find_last_of('/') + 1) \
.c_str()
#endif
namespace hsa
{
namespace
{
auto&
get_hsa_api_table_impl()
{
static auto _table = std::atomic<HsaApiTable*>{ nullptr };
return _table;
}
void
register_profiler_impl()
{
static auto _const_api_table = HsaApiTable{};
initialize_hsa_api_table(&_const_api_table);
// set this before any recursive opportunity arises
get_hsa_api_table_impl().exchange(&_const_api_table);
// create a copy of the api table for modification by registration
static auto _profiler_api_table = HsaApiTable{};
copy_hsa_api_table(&_profiler_api_table, &_const_api_table);
void* _profiler_api_table_v = static_cast<void*>(&_profiler_api_table);
auto lib_id = rocprofiler_register_library_indentifier_t{};
auto success =
rocprofiler_register_library_api_table("hsa",
&ROCPROFILER_REGISTER_IMPORT_FUNC(hsa),
ROCP_REG_VERSION,
&_profiler_api_table_v,
1,
&lib_id);
if(success == 0)
{
printf("[%s] hsa identifier %lu\n", ROCP_REG_FILE_NAME, lib_id.handle);
auto* _api_table = &_const_api_table;
if(!get_hsa_api_table_impl().compare_exchange_strong(_api_table,
&_profiler_api_table))
{
// with the current impl, if we ever get here, someone is calling one the
// functions in this anonymous namespace that shouldn't
std::cerr
<< "register_profiler_impl expected the API table to be the internal "
"implementation and yet it is not. something went wrong.\n";
abort();
}
}
else if(success != ROCP_REG_NO_TOOLS)
{
std::cerr << "HSA library failed to register with rocprofiler-register: "
<< rocprofiler_register_error_string(success) << "\n";
exit(EXIT_FAILURE);
}
}
void
register_profiler()
{
// this registration scheme is designed to minimize overhead once
// registered (only pay cost of checking atomic boolean)
// once the profiler is registered. If the library has not
// been registered and two or more threads try to register concurrently
// the first thread to acquire the lock below, will block the
// threads until registration is complete. However,
// if the same thread performing the registration re-enters this function
// i.e. this library's API is called during registration, this function
// will prevent a deadlock by not attempting to re-enter the
// the call-once and not releasing any waiting threads by flipping
// the _is_registered field to true.
static auto _is_registered = std::atomic<bool>{ false };
if(!_is_registered.load(std::memory_order_acquire))
{
using mutex_t = std::recursive_mutex;
using auto_lock_t = std::unique_lock<mutex_t>;
static auto _once = std::once_flag{};
static auto _mutex = mutex_t{};
// defer the lock so we can check for recursion
auto _lk = auto_lock_t{ _mutex, std::defer_lock };
// this will be true if the same thread currently executing the call_once invokes
// the library's API while registering the profiler (e.g. tool which wants to
// instrument HSA API invokes a HSA function while registering with the profiler)
// we allow this thread to proceed and access the "const" API table but
// return so it does not flip _is_registered to true, which would result
// in any subsequent threads not waiting until the library is fully registered,
// resulting in missed callbacks for the tools
if(_lk.owns_lock()) return;
// ensures any subsequent threads wait until the first thread
// finishes registration
_lk.lock();
// call_once to ensure that we only register once
std::call_once(_once, register_profiler_impl);
// the first thread has completed registration and all
// threads waiting on lock will be released and this
// block will not be entered again
_is_registered.exchange(true, std::memory_order_release);
}
}
} // namespace
HsaApiTable*
get_hsa_api_table()
{
register_profiler();
return get_hsa_api_table_impl().load(std::memory_order_relaxed);
}
void
hsa_init()
{
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
}
} // namespace hsa
extern "C" {
void
hsa_init(void)
{
hsa::get_hsa_api_table()->hsa_init_fn();
}
}
+40
Wyświetl plik
@@ -0,0 +1,40 @@
#pragma once
#define HSA_VERSION_MAJOR 2
#define HSA_VERSION_MINOR 1
#define HSA_VERSION_PATCH 0
#include <cstdint>
extern "C" {
// fake hsa function
void
hsa_init(void) __attribute__((visibility("default")));
}
namespace hsa
{
struct HsaApiTable
{
uint64_t size = 0;
decltype(::hsa_init)* hsa_init_fn = nullptr;
};
void
hsa_init();
// populates hsa api table with function pointers
inline void
initialize_hsa_api_table(HsaApiTable* dst)
{
dst->size = sizeof(HsaApiTable);
dst->hsa_init_fn = &::hsa::hsa_init;
}
// copies the api table from src to dst
inline void
copy_hsa_api_table(HsaApiTable* dst, const HsaApiTable* src)
{
*dst = *src;
}
} // namespace hsa
+14
Wyświetl plik
@@ -0,0 +1,14 @@
#
# mock rocprofiler library
#
add_library(rocprofiler SHARED)
add_library(rocprofiler::rocprofiler ALIAS rocprofiler)
target_sources(rocprofiler PRIVATE rocprofiler.cpp)
target_include_directories(rocprofiler PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>)
set_target_properties(
rocprofiler
PROPERTIES OUTPUT_NAME rocprofiler64
SOVERSION 2
VERSION 2.0.0)
rocp_register_strip_target(rocprofiler)
+135
Wyświetl plik
@@ -0,0 +1,135 @@
#include <amdhip/amdhip.hpp>
#include <hsa-runtime/hsa-runtime.hpp>
#include <roctx/roctx.hpp>
#include <pthread.h>
#include <stdexcept>
#include <string_view>
#ifndef ROCP_REG_FILE_NAME
# define ROCP_REG_FILE_NAME \
::std::string{ __FILE__ } \
.substr(::std::string_view{ __FILE__ }.find_last_of('/') + 1) \
.c_str()
#endif
namespace rocprofiler
{
void
hip_init()
{
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
}
void
hsa_init()
{
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
}
void
roctx_range_push(const char* name)
{
printf("[%s][push] %s\n", ROCP_REG_FILE_NAME, name);
}
void
roctx_range_pop(const char* name)
{
printf("[%s][pop] %s\n", ROCP_REG_FILE_NAME, name);
}
} // namespace rocprofiler
extern "C" {
struct rocprofiler_configure_result_t
{
int (*initialize)(void*) = nullptr;
int (*finalize)(void*) = nullptr;
void* data = nullptr;
};
rocprofiler_configure_result_t*
rocprofiler_configure(uint32_t, const char*, uint32_t, uint32_t)
__attribute__((visibility("default")));
int
rocprofiler_set_api_table(const char*, uint64_t, uint64_t, void**, uint64_t)
__attribute__((visibility("default")));
rocprofiler_configure_result_t*
rocprofiler_configure(uint32_t version,
const char* runtime_version,
uint32_t priority,
uint32_t tool_id)
{
(void) version;
(void) runtime_version;
(void) priority;
(void) tool_id;
return nullptr;
}
int
rocprofiler_set_api_table(const char* name,
uint64_t lib_version,
uint64_t lib_instance,
void** tables,
uint64_t num_tables)
{
printf("[%s] %s :: %lu :: %lu :: %lu\n",
ROCP_REG_FILE_NAME,
name,
lib_version,
lib_instance,
num_tables);
using hip_table_t = hip::HipApiTable;
using hsa_table_t = hsa::HsaApiTable;
using roctx_table_t = roctx::ROCTxApiTable;
auto* _wrap_v = std::getenv("ROCP_REG_TEST_WRAP");
bool _wrap = (_wrap_v != nullptr && std::stoi(_wrap_v) != 0);
if(_wrap)
{
if(num_tables != 1)
throw std::runtime_error{ std::string{ "unexpected number of tables: " } +
std::to_string(num_tables) };
if(tables == nullptr) throw std::runtime_error{ "nullptr to tables" };
if(tables[0] == nullptr) throw std::runtime_error{ "nullptr to tables[0]" };
if(std::string_view{ name } == "hip")
{
hip_table_t* _table = static_cast<hip_table_t*>(tables[0]);
_table->hip_init_fn = &rocprofiler::hip_init;
}
else if(std::string_view{ name } == "hsa")
{
hsa_table_t* _table = static_cast<hsa_table_t*>(tables[0]);
_table->hsa_init_fn = &rocprofiler::hsa_init;
}
else if(std::string_view{ name } == "roctx")
{
roctx_table_t* _table = static_cast<roctx_table_t*>(tables[0]);
_table->roctxRangePush_fn = &rocprofiler::roctx_range_push;
_table->roctxRangePop_fn = &rocprofiler::roctx_range_pop;
}
}
return 0;
}
}
void
rocp_ctor(void) __attribute__((constructor));
bool rocprofiler_test_lib_link = false;
void
rocp_ctor()
{
rocprofiler_test_lib_link = true;
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
}
+19
Wyświetl plik
@@ -0,0 +1,19 @@
#
#
#
if(NOT TARGET rocprofiler-register::rocprofiler-register)
find_package(rocprofiler-register REQUIRED)
endif()
add_library(roctx SHARED)
add_library(roctx::roctx ALIAS roctx)
target_sources(roctx PRIVATE roctx.cpp roctx.hpp)
target_include_directories(roctx PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
target_link_libraries(roctx PRIVATE rocprofiler-register::rocprofiler-register)
set_target_properties(
roctx
PROPERTIES OUTPUT_NAME roctx64
SOVERSION 4
VERSION 4.6.1)
rocp_register_strip_target(roctx)
+170
Wyświetl plik
@@ -0,0 +1,170 @@
#ifdef NDEBUG
# undef NDEBUG
#endif
#include "roctx.hpp"
#include <rocprofiler-register/rocprofiler-register.h>
#include <atomic>
#include <cassert>
#include <iostream>
#include <mutex>
#include <string_view>
#define ROCP_REG_VERSION \
ROCPROFILER_REGISTER_COMPUTE_VERSION_3( \
ROCTX_VERSION_MAJOR, ROCTX_VERSION_MINOR, ROCTX_VERSION_PATCH)
ROCPROFILER_REGISTER_DEFINE_IMPORT(roctx, ROCP_REG_VERSION)
#ifndef ROCP_REG_FILE_NAME
# define ROCP_REG_FILE_NAME \
::std::string{ __FILE__ } \
.substr(::std::string_view{ __FILE__ }.find_last_of('/') + 1) \
.c_str()
#endif
namespace roctx
{
namespace
{
auto&
get_roctx_api_table_impl()
{
static auto _table = std::atomic<ROCTxApiTable*>{ nullptr };
return _table;
}
void
register_profiler_impl()
{
static auto _const_api_table = ROCTxApiTable{};
initialize_roctx_api_table(&_const_api_table);
// set this before any recursive opportunity arises
get_roctx_api_table_impl().exchange(&_const_api_table);
// create a copy of the api table for modification by registration
static auto _profiler_api_table = ROCTxApiTable{};
copy_roctx_api_table(&_profiler_api_table, &_const_api_table);
void* _profiler_api_table_v = static_cast<void*>(&_profiler_api_table);
auto lib_id = rocprofiler_register_library_indentifier_t{};
auto success =
rocprofiler_register_library_api_table("roctx",
&ROCPROFILER_REGISTER_IMPORT_FUNC(roctx),
ROCP_REG_VERSION,
&_profiler_api_table_v,
1,
&lib_id);
if(success == 0)
{
printf("[%s] roctx identifier %lu\n", ROCP_REG_FILE_NAME, lib_id.handle);
auto* _api_table = &_const_api_table;
if(!get_roctx_api_table_impl().compare_exchange_strong(_api_table,
&_profiler_api_table))
{
// with the current impl, if we ever get here, someone is calling one the
// functions in this anonymous namespace that shouldn't
std::cerr
<< "register_profiler_impl expected the API table to be the internal "
"implementation and yet it is not. something went wrong.\n";
abort();
}
}
else if(success != ROCP_REG_NO_TOOLS)
{
std::cerr << "ROCTx library failed to register with rocprofiler-register: "
<< rocprofiler_register_error_string(success) << "\n";
exit(EXIT_FAILURE);
}
}
void
register_profiler()
{
// this registration scheme is designed to minimize overhead once
// registered (only pay cost of checking atomic boolean)
// once the profiler is registered. If the library has not
// been registered and two or more threads try to register concurrently
// the first thread to acquire the lock below, will block the
// threads until registration is complete. However,
// if the same thread performing the registration re-enters this function
// i.e. this library's API is called during registration, this function
// will prevent a deadlock by not attempting to re-enter the
// the call-once and not releasing any waiting threads by flipping
// the _is_registered field to true.
static auto _is_registered = std::atomic<bool>{ false };
if(!_is_registered.load(std::memory_order_acquire))
{
using mutex_t = std::recursive_mutex;
using auto_lock_t = std::unique_lock<mutex_t>;
static auto _once = std::once_flag{};
static auto _mutex = mutex_t{};
// defer the lock so we can check for recursion
auto _lk = auto_lock_t{ _mutex, std::defer_lock };
// this will be true if the same thread currently executing the call_once invokes
// the library's API while registering the profiler (e.g. tool which wants to
// instrument ROCTX API invokes a ROCTX function while registering with the
// profiler) we allow this thread to proceed and access the "const" API table but
// return so it does not flip _is_registered to true, which would result
// in any subsequent threads not waiting until the library is fully registered,
// resulting in missed callbacks for the tools
if(_lk.owns_lock()) return;
// ensures any subsequent threads wait until the first thread
// finishes registration
_lk.lock();
// call_once to ensure that we only register once
std::call_once(_once, register_profiler_impl);
// the first thread has completed registration and all
// threads waiting on lock will be released and this
// block will not be entered again
_is_registered.exchange(true, std::memory_order_release);
}
}
} // namespace
ROCTxApiTable*
get_roctx_api_table()
{
register_profiler();
return get_roctx_api_table_impl().load(std::memory_order_relaxed);
}
void
roctx_range_push(const char* name)
{
printf("[%s][push] %s\n", ROCP_REG_FILE_NAME, name);
}
void
roctx_range_pop(const char* name)
{
printf("[%s][pop] %s\n", ROCP_REG_FILE_NAME, name);
}
} // namespace roctx
extern "C" {
void
roctxRangePush(const char* name)
{
auto&& _func = roctx::get_roctx_api_table()->roctxRangePush_fn;
assert(_func != nullptr);
_func(name);
}
void
roctxRangePop(const char* name)
{
auto&& _func = roctx::get_roctx_api_table()->roctxRangePop_fn;
if(_func == nullptr) throw std::runtime_error("nullptr");
_func(name);
}
}
+46
Wyświetl plik
@@ -0,0 +1,46 @@
#pragma once
#define ROCTX_VERSION_MAJOR 4
#define ROCTX_VERSION_MINOR 6
#define ROCTX_VERSION_PATCH 1
#include <cstdint>
extern "C" {
void
roctxRangePush(const char*) __attribute__((visibility("default")));
void
roctxRangePop(const char*) __attribute__((visibility("default")));
}
namespace roctx
{
struct ROCTxApiTable
{
uint64_t size = 0;
decltype(::roctxRangePush)* roctxRangePush_fn = nullptr;
decltype(::roctxRangePop)* roctxRangePop_fn = nullptr;
};
void
roctx_range_push(const char*);
void
roctx_range_pop(const char*);
// populates roctx api table with function pointers
inline void
initialize_roctx_api_table(ROCTxApiTable* dst)
{
dst->size = sizeof(ROCTxApiTable);
dst->roctxRangePush_fn = &::roctx::roctx_range_push;
dst->roctxRangePop_fn = &::roctx::roctx_range_pop;
}
// copies the api table from src to dst
inline void
copy_roctx_api_table(ROCTxApiTable* dst, const ROCTxApiTable* src)
{
*dst = *src;
}
} // namespace roctx
+3
Wyświetl plik
@@ -0,0 +1,3 @@
#
#
#
+72
Wyświetl plik
@@ -0,0 +1,72 @@
#include <dlfcn.h>
#include <pthread.h>
#include <cstdlib>
#include <string>
#include <thread>
#include <vector>
#include "common/fwd.hpp"
void
run(const std::string& name, pthread_barrier_t* _barrier)
{
if(_barrier) pthread_barrier_wait(_barrier);
if(hsa_init_fn)
{
if(_barrier) pthread_barrier_wait(_barrier);
hsa_init_fn();
}
if(hip_init_fn)
{
if(_barrier) pthread_barrier_wait(_barrier);
hip_init_fn();
}
if(roctxRangePush_fn)
{
if(_barrier) pthread_barrier_wait(_barrier);
roctxRangePush_fn(name.c_str());
}
if(roctxRangePop_fn)
{
if(_barrier) pthread_barrier_wait(_barrier);
roctxRangePop_fn(name.c_str());
}
}
auto
run_threads(unsigned long n)
{
resolve_symbols<ROCP_REG_TEST_HIP>();
auto threads = std::vector<std::thread>{};
auto names = std::vector<std::string>{};
for(unsigned long i = 0; i < n; ++i)
names.emplace_back(std::string{ "thread-" } + std::to_string(i));
auto _barrier = pthread_barrier_t{};
pthread_barrier_init(&_barrier, nullptr, n);
for(unsigned long i = 0; i < n; ++i)
threads.emplace_back(run, names.at(i), &_barrier);
for(auto& itr : threads)
itr.join();
pthread_barrier_destroy(&_barrier);
return n;
}
auto run_n = run_threads(4);
int
main()
{
return (run_n == 4) ? EXIT_SUCCESS : EXIT_FAILURE;
}
+42
Wyświetl plik
@@ -0,0 +1,42 @@
#include <dlfcn.h>
#include <cstdlib>
#include <string>
#include "common/fwd.hpp"
std::string
run(const std::string& name)
{
resolve_symbols<ROCP_REG_TEST_HSA | ROCP_REG_TEST_HIP>();
if(hsa_init_fn)
{
hsa_init_fn();
}
if(hip_init_fn)
{
hip_init_fn();
}
if(roctxRangePush_fn)
{
roctxRangePush_fn(name.c_str());
}
if(roctxRangePop_fn)
{
roctxRangePop_fn(name.c_str());
}
return name;
}
auto run_name = run("thread-ctor");
int
main()
{
return (run_name == "thread-ctor") ? EXIT_SUCCESS : EXIT_FAILURE;
}
+43
Wyświetl plik
@@ -0,0 +1,43 @@
#include <dlfcn.h>
#include <string>
#include "common/fwd.hpp"
void
run(const std::string& name)
{
if(hip_init_fn)
{
hip_init_fn();
}
if(hsa_init_fn)
{
hsa_init_fn();
}
if(roctxRangePush_fn)
{
roctxRangePush_fn(name.c_str());
}
if(roctxRangePop_fn)
{
roctxRangePop_fn(name.c_str());
}
}
int
main(int argc, char** argv)
{
unsigned long n = 1;
if(argc > 1) n = std::stoul(argv[1]);
resolve_symbols<ROCP_REG_TEST_HSA | ROCP_REG_TEST_HIP | ROCP_REG_TEST_ROCTX>();
for(unsigned long i = 0; i < n; ++i)
run("thread-main");
return 0;
}
+72
Wyświetl plik
@@ -0,0 +1,72 @@
#include <dlfcn.h>
#include <pthread.h>
#include <string>
#include <thread>
#include <vector>
#include "common/fwd.hpp"
void
run(const std::string& name, pthread_barrier_t* _barrier)
{
if(_barrier) pthread_barrier_wait(_barrier);
if(hip_init_fn)
{
if(_barrier) pthread_barrier_wait(_barrier);
hip_init_fn();
}
if(hsa_init_fn)
{
if(_barrier) pthread_barrier_wait(_barrier);
hsa_init_fn();
}
if(roctxRangePush_fn)
{
if(_barrier) pthread_barrier_wait(_barrier);
roctxRangePush_fn(name.c_str());
}
if(roctxRangePop_fn)
{
if(_barrier) pthread_barrier_wait(_barrier);
roctxRangePop_fn(name.c_str());
}
}
void
run_threads(unsigned long n)
{
auto threads = std::vector<std::thread>{};
auto names = std::vector<std::string>{};
for(unsigned long i = 0; i < n; ++i)
names.emplace_back(std::string{ "thread-" } + std::to_string(i));
auto _barrier = pthread_barrier_t{};
pthread_barrier_init(&_barrier, nullptr, n);
for(unsigned long i = 0; i < n; ++i)
threads.emplace_back(run, names.at(i), &_barrier);
for(auto& itr : threads)
itr.join();
pthread_barrier_destroy(&_barrier);
}
int
main(int argc, char** argv)
{
unsigned long n = 4;
if(argc > 1) n = std::stoul(argv[1]);
resolve_symbols<ROCP_REG_TEST_HIP | ROCP_REG_TEST_ROCTX>();
run_threads(n);
return 0;
}
+43
Wyświetl plik
@@ -0,0 +1,43 @@
#include <dlfcn.h>
#include <string>
#include "common/fwd.hpp"
void
run(const std::string& name)
{
if(hip_init_fn)
{
hip_init_fn();
}
if(hsa_init_fn)
{
hsa_init_fn();
}
if(roctxRangePush_fn)
{
roctxRangePush_fn(name.c_str());
}
if(roctxRangePop_fn)
{
roctxRangePop_fn(name.c_str());
}
}
int
main(int argc, char** argv)
{
unsigned long n = 1;
if(argc > 1) n = std::stoul(argv[1]);
resolve_symbols<ROCP_REG_TEST_HIP | ROCP_REG_TEST_ROCTX>();
for(unsigned long i = 0; i < n; ++i)
run("thread-main");
return 0;
}