Add 'projects/rocprofiler-register/' from commit '37d7d920364c8b10ab592ff79e1c6811d114e6fa'

git-subtree-dir: projects/rocprofiler-register
git-subtree-mainline: 2e5bcec303
git-subtree-split: 37d7d92036
Цей коміт міститься в:
systems-assistant[bot]
2025-07-22 22:52:44 +00:00
джерело 2e5bcec303 37d7d92036
коміт 50a90550e9
96 змінених файлів з 8944 додано та 0 видалено
+39
Переглянути файл
@@ -0,0 +1,39 @@
resources:
repositories:
- repository: pipelines_repo
type: github
endpoint: ROCm
name: ROCm/ROCm
variables:
- group: common
- template: /.azuredevops/variables-global.yml@pipelines_repo
trigger:
batch: true
branches:
include:
- amd-mainline
- amd-staging
paths:
exclude:
- .github
- LICENSE
- README.md
- VERSION
pr:
autoCancel: true
branches:
include:
- amd-staging
paths:
exclude:
- .github
- LICENSE
- README.md
- VERSION
drafts: false
jobs:
- template: ${{ variables.CI_COMPONENT_PATH }}/rocprofiler-register.yml@pipelines_repo
+114
Переглянути файл
@@ -0,0 +1,114 @@
# clang-format v11
---
Language: Cpp
BasedOnStyle: Google
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true
AlignConsecutiveAssignments: true
AlignConsecutiveBitFields: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: TopLevel
AlwaysBreakAfterReturnType: TopLevel
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: Always
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: false
BeforeElse: true
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: true
BreakInheritanceList: BeforeComma
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakStringLiterals: true
ColumnLimit: 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
Переглянути файл
@@ -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
Переглянути файл
@@ -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: {}
+5
Переглянути файл
@@ -0,0 +1,5 @@
disabled: false
scmId: gh-emu-rocm
branchesToScan:
- amd-staging
- amd-mainline
+178
Переглянути файл
@@ -0,0 +1,178 @@
name: Continuous Integration
on:
push:
branches: [ amd-mainline, amd-staging ]
paths-ignore:
- '*.md'
pull_request:
branches: [ amd-mainline, amd-staging ]
paths-ignore:
- '*.md'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
ci:
strategy:
fail-fast: false
matrix:
compiler: ['clang-14', 'clang-15', 'gcc-11', 'gcc-12']
ci-args: ['']
ci-tag: ['']
include:
- compiler: 'gcc-12'
ci-args: '--coverage'
ci-tag: '-codecov'
- compiler: 'clang-15'
ci-args: '--linter clang-tidy'
ci-tag: '-clang-tidy'
- compiler: 'clang-13'
ci-args: ''
ci-tag: ''
- compiler: 'gcc-12'
ci-args: '--memcheck ThreadSanitizer'
ci-tag: '-thread-sanitizer'
- compiler: 'gcc-12'
ci-args: '--memcheck AddressSanitizer'
ci-tag: '-address-sanitizer'
- compiler: 'gcc-12'
ci-args: '--memcheck LeakSanitizer'
ci-tag: '-leak-sanitizer'
# - compiler: 'gcc-12'
# ci-args: '--memcheck UndefinedBehaviorSanitizer'
# ci-tag: '-undefined-behavior-sanitizer'
runs-on: rocprof-azure-emu-runner-set
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') &&
apt-get update &&
apt-get install -y build-essential python3 environment-modules ${{ matrix.compiler }} ${CXX} &&
update-alternatives --install /usr/bin/cc cc /usr/bin/${CC} 100 &&
update-alternatives --install /usr/bin/c++ c++ /usr/bin/${CXX} 100 &&
python3 -m pip install --upgrade pip &&
python3 -m pip install 'cmake==3.22.0' &&
python3 -m pip install -r requirements.txt
- name: Setup GCov
timeout-minutes: 25
if: ${{ matrix.compiler == 'gcc-12' }}
run: |
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: |
apt-get install -y clang-tidy-15
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 }}-azure-mi300x-${{ 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 Installed Packages
if: ${{ contains(matrix.compiler, 'clang-15') }}
timeout-minutes: 10
shell: bash
run: |
CMAKE_PREFIX_PATH=/opt/rocm cmake -B build-tests-deb /opt/rocm/share/rocprofiler-register/tests
cmake --build build-tests-deb --target all --parallel 16
ctest --test-dir build-tests-deb --output-on-failure
- 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}
+117
Переглянути файл
@@ -0,0 +1,117 @@
name: Formatting
on:
workflow_dispatch:
pull_request:
branches: [ amd-mainline, amd-staging ]
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: AMD-ROCm-Internal-dev1
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
source:
runs-on: AMD-ROCm-Internal-dev1
container: rocm/dev-ubuntu-22.04:latest
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
python:
runs-on: AMD-ROCm-Internal-dev1
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
+15
Переглянути файл
@@ -0,0 +1,15 @@
name: Rocm Validation Suite KWS
on:
push:
branches: [amd-staging]
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:
jobs:
kws:
if: ${{ github.event_name == 'pull_request' }}
uses: AMD-ROCm-Internal/rocm_ci_infra/.github/workflows/kws.yml@mainline
secrets: inherit
with:
pr_number: ${{github.event.pull_request.number}}
base_branch: ${{github.base_ref}}
+25
Переглянути файл
@@ -0,0 +1,25 @@
name: ROCm CI Caller
on:
pull_request:
branches: [amd-staging, release/rocm-rel-*]
types: [opened, reopened, synchronize]
push:
branches: [amd-mainline]
workflow_dispatch:
issue_comment:
types: [created]
jobs:
call-workflow:
if: github.event_name != 'issue_comment' ||(github.event_name == 'issue_comment' && github.event.issue.pull_request && (startsWith(github.event.comment.body, '!verify') || startsWith(github.event.comment.body, '!verify release') || startsWith(github.event.comment.body, '!verify retest')))
uses: AMD-ROCm-Internal/rocm_ci_infra/.github/workflows/rocm_ci.yml@mainline
secrets: inherit
with:
input_sha: ${{github.event_name == 'pull_request' && github.event.pull_request.head.sha || (github.event_name == 'push' && github.sha) || (github.event_name == 'issue_comment' && github.event.issue.pull_request.head.sha) || github.sha}}
input_pr_num: ${{github.event_name == 'pull_request' && github.event.pull_request.number || (github.event_name == 'issue_comment' && github.event.issue.number) || 0}}
input_pr_url: ${{github.event_name == 'pull_request' && github.event.pull_request.html_url || (github.event_name == 'issue_comment' && github.event.issue.pull_request.html_url) || ''}}
input_pr_title: ${{github.event_name == 'pull_request' && github.event.pull_request.title || (github.event_name == 'issue_comment' && github.event.issue.pull_request.title) || ''}}
repository_name: ${{ github.repository }}
base_ref: ${{github.event_name == 'pull_request' && github.event.pull_request.base.ref || (github.event_name == 'issue_comment' && github.event.issue.pull_request.base.ref) || github.ref}}
trigger_event_type: ${{ github.event_name }}
comment_text: ${{ github.event_name == 'issue_comment' && github.event.comment.body || '' }}
+18
Переглянути файл
@@ -0,0 +1,18 @@
name: Sync amd-mainline to public repository
on:
workflow_dispatch:
push:
branches: [ amd-mainline ]
jobs:
git-mirror:
runs-on: AMD-ROCm-Internal-dev1
steps:
- name: git-sync
uses: AMD-ROCm-Internal/rocprofiler-github-actions@git-sync-v3
with:
source_repo: "https://${{ secrets.TOKEN }}@github.com/AMD-ROCm-Internal/rocprofiler-register-internal.git"
source_branch: "amd-mainline"
destination_repo: "https://${{ secrets.EXT_TOKEN }}@github.com/ROCm/rocprofiler-register.git"
destination_branch: "amd-mainline"
+18
Переглянути файл
@@ -0,0 +1,18 @@
name: Sync amd-staging to public repository
on:
workflow_dispatch:
push:
branches: [ amd-staging ]
jobs:
git-mirror:
runs-on: AMD-ROCm-Internal-dev1
steps:
- name: git-sync
uses: AMD-ROCm-Internal/rocprofiler-github-actions@git-sync-v3
with:
source_repo: "https://${{ secrets.TOKEN }}@github.com/AMD-ROCm-Internal/rocprofiler-register-internal.git"
source_branch: "amd-staging"
destination_repo: "https://${{ secrets.EXT_TOKEN }}@github.com/ROCm/rocprofiler-register.git"
destination_branch: "amd-staging"
+41
Переглянути файл
@@ -0,0 +1,41 @@
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
# Build directories
/build*
/.cache
/compile_commands.json
# Github Workflows
.github/workflows/continuous-integration.yml
.github/workflows/*.yaml
+6
Переглянути файл
@@ -0,0 +1,6 @@
[submodule "external/glog"]
path = external/glog
url = https://github.com/google/glog.git
[submodule "external/fmt"]
path = external/fmt
url = https://github.com/fmtlib/fmt.git
+118
Переглянути файл
@@ -0,0 +1,118 @@
cmake_minimum_required(VERSION 3.22.0 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/rocprofiler-register-internal")
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME core)
# configure the version file so that if it changes, cmake automatically re-runs
configure_file(${PROJECT_SOURCE_DIR}/VERSION ${PROJECT_BINARY_DIR}/VERSION COPYONLY)
# 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
# ROCm does not use lib64
set(CMAKE_INSTALL_LIBDIR "lib")
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(external)
add_subdirectory(source)
include(rocprofiler_register_config_install)
if(ROCPROFILER_REGISTER_BUILD_TESTS)
add_subdirectory(tests)
endif()
if(ROCPROFILER_REGISTER_BUILD_SAMPLES)
add_subdirectory(samples)
endif()
include(rocprofiler_register_config_packaging)
rocprofiler_register_print_features()
+21
Переглянути файл
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 ROCm Developer Tools
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+70
Переглянути файл
@@ -0,0 +1,70 @@
# rocprofiler-register
## Overview
The rocprofiler-register library is a helper library that coordinates the modification of the intercept API table(s) of the HSA/HIP/ROCTx
runtime libraries by the ROCprofiler (v2) library. The purpose of this library is to provide a consistent and automated mechanism
of enabling performance analysis in the ROCm runtimes which does not rely on environment variables or unique methods for each runtime
library.
When a runtime is initialized (either explicitly and lazily) and the intercept API table is constructed, it passes this API table to
rocprofiler-register. Rocprofiler-register scans the symbols in the address space and if it detects there is at least one visible symbol named
`rocprofiler_configure` (which is a function provided by tools), it passes the intercept API table to the rocprofiler library (dlopening
the rocprofiler library if it is not already loaded). The rocprofiler library then does an extensive scan for _all_ the instances of
the `rocprofiler_configure` symbols and invokes each of them. The `rocprofiler_configure` function (again, provided by a tool) returns
effectively tells rocprofiler which behaviors it wants to be notified about, features it wants to use (e.g. API tracing, kernel dispatch timing),
etc.
## Environment Variables
| Environment Variable | Description | Default Value |
|-----------------------------------|---------------------------------------------------------------------------|----------------|
| `ROCP_TOOL_LIBRARIES` | List of rocprofiler-sdk tool libraries (space, comma, or colon separated) | Empty (string) |
| `ROCPROFILER_REGISTER_ENABLED` | Set to 0/false/no to disable rocprofiler-register | true (bool) |
| `ROCPROFILER_REGISTER_SECURE` | Additional checks to ensure authenticity of runtime libraries | false (bool) |
| `ROCPROFILER_REGISTER_FORCE_LOAD` | Load rocprofiler-sdk library regardless of whether there is a tool or not | false (bool) |
## Contributing
The default branch is `amd-mainline` but the only branch that should target that branch in a pull requests is the `amd-staging` branch.
> _**All pull-requests should target the `amd-staging` branch**_
### Creating a feature branch
```console
# fetch any updates
git fetch origin
# switch to staging branch
git checkout amd-staging
# update your copy of the staging branch
git pull --rebase
# create your feature branch off of amd-staging
git checkout -b <feature-branch>
```
In the event, your local clone of the repo has a `amd-staging` branch that diverges from the upstream branch,
do a hard reset of your local branch to match the upstream branch: `git reset --hard origin/amd-staging`.
Theoretically, you should never need to do this for `amd-mainline` but this can be applied to that
branch as well.
### Pulling in updates to `amd-staging` to your feature branch
Linear histories are preferred so if another PR is merged into `amd-staging` while your PR is still open, please
select the "Update with rebase" option (i.e. try to avoid a merge commit). From the command line, the git command
would be `git pull --rebase origin amd-staging`.
## Build and Installation
rocprofiler-register has a standard CMake build and install process. E.g. the following configure
rocprofiler-register to build with optimizations and without debug info in a `build-rocp-reg` subdirectory,
build using 4 jobs, and install to `/opt/rocprofiler-register`:
```console
cmake -B build-rocp-reg . -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/rocprofiler-register
cmake --build build-rocp-reg --target all --parallel 4
cmake --build build-rocp-reg --target install
```
+1
Переглянути файл
@@ -0,0 +1 @@
0.5.0
+16
Переглянути файл
@@ -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_LIBDIR@/cmake/@PROJECT_NAME@"
+36
Переглянути файл
@@ -0,0 +1,36 @@
# - 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@-config-version.cmake)
set(@PROJECT_NAME@_VERSION ${PACKAGE_VERSION})
@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)
if(NOT @PROJECT_NAME@_BUILD_TREE)
include("${@PROJECT_NAME@_CMAKE_DIR}/@PROJECT_NAME@-library-targets.cmake")
endif()
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
Переглянути файл
@@ -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_LIBDIR@/cmake/@PROJECT_NAME@
export @PROJECT_NAME_UNDERSCORED@_ROOT
export PATH
export LD_LIBRARY_PATH
export PYTHONPATH
export CMAKE_PREFIX_PATH
export @PROJECT_NAME_UNDERSCORED@_DIR
+106
Переглянути файл
@@ -0,0 +1,106 @@
# ########################################################################################
#
# 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
#
set(_WARN_STACK_USAGE)
if(NOT ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY)
set(_WARN_STACK_USAGE "-Wstack-usage=8192") # 2 KB
endif()
rocprofiler_register_target_compile_options(
rocprofiler-register-build-flags
INTERFACE "-W" "-Wall" "-Wno-unknown-pragmas" "-fstack-protector-strong"
"-Wstack-protector" ${_WARN_STACK_USAGE})
# ----------------------------------------------------------------------------------------#
# 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"
"-Wno-deprecated-declarations")
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()
+352
Переглянути файл
@@ -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()
+106
Переглянути файл
@@ -0,0 +1,106 @@
# include guard
include_guard(GLOBAL)
include(CMakePackageConfigHelpers)
install(
FILES ${PROJECT_SOURCE_DIR}/LICENSE
DESTINATION ${CMAKE_INSTALL_DOCDIR}
COMPONENT core)
install(
EXPORT rocprofiler-register-library-targets
FILE rocprofiler-register-library-targets.cmake
NAMESPACE rocprofiler-register::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
COMPONENT core)
install(
DIRECTORY ${PROJECT_SOURCE_DIR}/tests
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}
COMPONENT tests)
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 core)
install(
FILES
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/modulefiles/${PROJECT_NAME}/${PROJECT_VERSION}
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/modulefiles/${PROJECT_NAME}
COMPONENT core)
# ------------------------------------------------------------------------------#
# 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_LIBDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/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_LIBDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config-version.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMinorVersion)
install(
FILES
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config-version.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
OPTIONAL)
# ------------------------------------------------------------------------------#
# build tree
#
set(${PROJECT_NAME}_BUILD_TREE
ON
CACHE BOOL "" FORCE)
file(RELATIVE_PATH rocp_reg_bin2src_rel_path ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR})
string(REPLACE "//" "/" rocp_reg_inc_rel_path
"${rocp_reg_bin2src_rel_path}/source/include")
execute_process(
COMMAND ${CMAKE_COMMAND} -E create_symlink ${rocp_reg_inc_rel_path}
${PROJECT_BINARY_DIR}/include WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
set(_BUILDTREE_EXPORT_DIR
"${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/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)
+67
Переглянути файл
@@ -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()
+199
Переглянути файл
@@ -0,0 +1,199 @@
# 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 "ROCm Profiler Support <dl.ROCm-Profiler.support@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")
get_cmake_property(ROCPROFILER_REGISTER_PACKAGING_COMPONENTS COMPONENTS)
rocprofiler_register_add_feature(ROCPROFILER_REGISTER_PACKAGING_COMPONENTS
"Packaging components")
list(REMOVE_ITEM ROCPROFILER_REGISTER_PACKAGING_COMPONENTS "Development" "Unspecified"
"external" "fmt-core")
list(LENGTH ROCPROFILER_REGISTER_PACKAGING_COMPONENTS
NUM_ROCPROFILER_REGISTER_PACKAGING_COMPONENTS)
# the packages we will generate
set(ROCPROFILER_REGISTER_COMPONENT_GROUPS "core" "tests")
set(COMPONENT_GROUP_core_COMPONENTS "core" "Development" "Unspecified" "external")
set(COMPONENT_GROUP_tests_COMPONENTS "tests")
# variables for each component group. Note: eventually we will probably want to separate
# the core to just be the runtime libraries, development to be the headers and cmake
# files, the samples to just be the samples, and tools just be the tool files but right
# now we are just combining core, development, samples, and tools into one package
set(COMPONENT_NAME_core "")
set(COMPONENT_NAME_tests "tests")
set(COMPONENT_SEP_core "")
set(COMPONENT_SEP_tests "-")
set(COMPONENT_DEP_core "")
set(COMPONENT_DEP_tests "${PROJECT_NAME}")
set(COMPONENT_DESC_core "rocprofiler-register libraries and headers")
set(COMPONENT_DESC_tests "rocprofiler-register tests")
if(NOT NUM_ROCPROFILER_REGISTER_PACKAGING_COMPONENTS EQUAL 2)
message(
FATAL_ERROR
"Error new install component needs COMPONENT_NAME_* and COMPONENT_SEP_* entries. Expected 2, found ${NUM_ROCPROFILER_REGISTER_PACKAGING_COMPONENTS}: ${ROCPROFILER_REGISTER_PACKAGING_COMPONENTS}"
)
endif()
if(ROCM_DEP_ROCMCORE OR ROCPROFILER_REGISTER_DEP_ROCMCORE)
set(CPACK_DEBIAN_PACKAGE_DEPENDS "rocm-core")
set(CPACK_RPM_PACKAGE_REQUIRES "rocm-core")
else()
set(CPACK_DEBIAN_PACKAGE_DEPENDS "")
set(CPACK_RPM_PACKAGE_REQUIRES "")
endif()
foreach(COMPONENT_GROUP ${ROCPROFILER_REGISTER_COMPONENT_GROUPS})
set(_SEP "${COMPONENT_SEP_${COMPONENT_GROUP}}")
set(_DEP "${COMPONENT_DEP_${COMPONENT_GROUP}}")
set(_NAME "${COMPONENT_NAME_${COMPONENT_GROUP}}")
set(_DESC "${COMPONENT_DESC_${COMPONENT_GROUP}}")
cpack_add_component_group(
${COMPONENT_GROUP}
DISPLAY_NAME "${_NAME}"
DESCRIPTION "${_DESC}")
if(ROCM_DEP_ROCMCORE OR ROCPROFILER_REGISTER_DEP_ROCMCORE)
list(INSERT _DEP 0 "rocm-core")
endif()
# Dependency list should be separated by comma
string(REPLACE ";" ", " _DEP "${_DEP}")
string(TOUPPER "${COMPONENT_GROUP}" UCOMPONENT)
set(CPACK_DEBIAN_${UCOMPONENT}_PACKAGE_NAME "${PROJECT_NAME}${_SEP}${_NAME}")
set(CPACK_DEBIAN_${UCOMPONENT}_PACKAGE_DEPENDS "${_DEP}")
set(CPACK_RPM_${UCOMPONENT}_PACKAGE_NAME "${PROJECT_NAME}${_SEP}${_NAME}")
set(CPACK_RPM_${UCOMPONENT}_PACKAGE_REQUIRES "${_DEP}")
foreach(COMPONENT ${COMPONENT_GROUP_${COMPONENT_GROUP}_COMPONENTS})
cpack_add_component(${COMPONENT} REQUIRED GROUP "${COMPONENT_GROUP}")
endforeach()
endforeach()
# -------------------------------------------------------------------------------------- #
#
# Debian package specific variables
#
# -------------------------------------------------------------------------------------- #
set(CPACK_DEBIAN_PACKAGE_EPOCH 0)
set(CPACK_DEB_COMPONENT_INSTALL ON)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) # auto-generate deps based on shared libs
set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS ON) # generate list of shared libs provided by
# package
set(CPACK_DEBIAN_TESTS_PACKAGE_SHLIBDEPS OFF) # disable for tests package
set(CPACK_DEBIAN_TESTS_PACKAGE_GENERATE_SHLIBS OFF) # disable for tests package
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 "rocm-core")
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_EPOCH 0)
set(CPACK_RPM_COMPONENT_INSTALL ON)
set(CPACK_RPM_PACKAGE_AUTOREQ ON) # auto-generate deps based on shared libs
set(CPACK_RPM_PACKAGE_AUTOPROV ON) # generate list of shared libs provided by package
set(CPACK_RPM_TESTS_PACKAGE_AUTOREQ OFF) # disable for tests package
set(CPACK_RPM_TESTS_PACKAGE_AUTOPROV OFF) # disable for tests package
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()
set(_RPM_PACKAGE_DEPENDS "rocm-core")
string(REPLACE ";" ", " _RPM_PACKAGE_DEPENDS "${_RPM_PACKAGE_DEPENDS}")
set(CPACK_RPM_PACKAGE_REQUIRES
"${_RPM_PACKAGE_DEPENDS}"
CACHE STRING "RPM package dependencies" FORCE)
rocprofiler_register_add_feature(CPACK_RPM_PACKAGE_REQUIRES "RPM package dependencies")
# Get rpm distro
if(CPACK_RPM_PACKAGE_RELEASE)
set(CPACK_RPM_PACKAGE_RELEASE_DIST ON)
endif()
set(CPACK_RPM_FILE_NAME "RPM-DEFAULT")
set(CPACK_RPM_PACKAGE_LICENSE "MIT")
# -------------------------------------------------------------------------------------- #
#
# Prepare final version for the CPACK use
#
# -------------------------------------------------------------------------------------- #
set(CPACK_PACKAGE_VERSION
"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}"
)
if(DEFINED ENV{ROCM_LIBPATCH_VERSION})
set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}.$ENV{ROCM_LIBPATCH_VERSION}")
message("Using CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION}")
endif()
include(CPack)
+138
Переглянути файл
@@ -0,0 +1,138 @@
# ------------------------------------------------------------------------------#
#
# 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)
if(NOT ROCPROFILER_REGISTER_CLANG_FORMAT_EXE AND EXISTS
$ENV{HOME}/.local/bin/clang-format)
execute_process(
COMMAND $ENV{HOME}/.local/bin/clang-format --version
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
OUTPUT_VARIABLE _CLANG_FMT_OUT
RESULT_VARIABLE _CLANG_FMT_RET
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
if(_CLANG_FMT_RET EQUAL 0)
if("${_CLANG_FMT_OUT}" MATCHES "version 11\\.([0-9]+)\\.([0-9]+)")
set(ROCPROFILER_REGISTER_CLANG_FORMAT_EXE
"$ENV{HOME}/.local/bin/clang-format"
CACHE FILEPATH "clang-format exe")
endif()
endif()
endif()
find_program(
ROCPROFILER_REGISTER_CLANG_FORMAT_EXE
NAMES clang-format-11 clang-format-mp-11 clang-format
PATHS $ENV{HOME}/.local
HINTS $ENV{HOME}/.local
PATH_SUFFIXES bin)
find_program(
ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE
NAMES cmake-format
PATHS $ENV{HOME}/.local
HINTS $ENV{HOME}/.local
PATH_SUFFIXES bin)
find_program(
ROCPROFILER_REGISTER_BLACK_FORMAT_EXE
NAMES black
PATHS $ENV{HOME}/.local
HINTS $ENV{HOME}/.local
PATH_SUFFIXES bin)
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
${PROJECT_SOURCE_DIR}/external/CMakeLists.txt)
foreach(_DIR cmake samples source tests)
foreach(_TYPE header_files source_files cmake_files python_files)
set(${_TYPE})
endforeach()
file(GLOB_RECURSE header_files ${PROJECT_SOURCE_DIR}/${_DIR}/*.h
${PROJECT_SOURCE_DIR}/${_DIR}/*.hpp ${PROJECT_SOURCE_DIR}/${_DIR}/*.h.in
${PROJECT_SOURCE_DIR}/${_DIR}/*.hpp.in)
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
${PROJECT_SOURCE_DIR}/${_DIR}/*.py.in)
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 cmake)
if(TARGET format-rocprofiler-register-${_TYPE})
add_dependencies(format format-rocprofiler-register-${_TYPE})
endif()
endforeach()
endif()
+34
Переглянути файл
@@ -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)
+72
Переглянути файл
@@ -0,0 +1,72 @@
# ----------------------------------------------------------------------------------------#
#
# Clang Tidy
#
# ----------------------------------------------------------------------------------------#
include_guard(DIRECTORY)
if(NOT ROCPROFILER_REGISTER_CLANG_TIDY_EXE AND EXISTS $ENV{HOME}/.local/bin/clang-tidy)
execute_process(
COMMAND $ENV{HOME}/.local/bin/clang-tidy --version
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
OUTPUT_VARIABLE _CLANG_TIDY_OUT
RESULT_VARIABLE _CLANG_TIDY_RET
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
if(_CLANG_TIDY_RET EQUAL 0)
if("${_CLANG_TIDY_OUT}" MATCHES "version 1[5-9]\\.([0-9]+)\\.([0-9]+)")
set(ROCPROFILER_REGISTER_CLANG_TIDY_EXE
"$ENV{HOME}/.local/bin/clang-tidy"
CACHE FILEPATH "clang-tidy exe")
endif()
endif()
endif()
find_program(
ROCPROFILER_REGISTER_CLANG_TIDY_EXE
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
PATHS $ENV{HOME}/.local
HINTS $ENV{HOME}/.local
PATH_SUFFIXES bin)
macro(ROCPROFILER_REGISTER_ACTIVATE_CLANG_TIDY)
if(ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY)
if(NOT ROCPROFILER_REGISTER_CLANG_TIDY_EXE)
message(
FATAL_ERROR
"ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY is ON but clang-tidy is not found!"
)
endif()
rocprofiler_register_add_feature(ROCPROFILER_REGISTER_CLANG_TIDY_EXE
"path to clang-tidy executable")
set(CMAKE_CXX_CLANG_TIDY
${ROCPROFILER_REGISTER_CLANG_TIDY_EXE}
-header-filter=${PROJECT_SOURCE_DIR}/source/.*
--warnings-as-errors=*,-misc-header-include-cycle)
# 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()
+80
Переглянути файл
@@ -0,0 +1,80 @@
#
#
#
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}>)
target_link_options(rocprofiler-register-memcheck INTERFACE
$<BUILD_INTERFACE:-fsanitize=${_TYPE}>)
endfunction()
function(rocprofiler_register_set_memcheck_env _TYPE _LIB_BASE)
set(_LIBS ${_LIB_BASE})
foreach(
_N
8
7
6
5
4
3
2
1
0)
list(
APPEND _LIBS
${CMAKE_SHARED_LIBRARY_PREFIX}${_LIB_BASE}${CMAKE_SHARED_LIBRARY_SUFFIX}.${_N}
)
endforeach()
foreach(_LIB ${_LIBS})
if(NOT ${_TYPE}_LIBRARY)
find_library(${_TYPE}_LIBRARY NAMES ${_LIB} ${ARGN})
endif()
endforeach()
target_link_libraries(rocprofiler-register-memcheck INTERFACE ${_LIB_BASE})
if(${_TYPE}_LIBRARY)
set(ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_LIBRARY
"${${_TYPE}_LIBRARY}"
CACHE INTERNAL "LD_PRELOAD library for tests " FORCE)
set(ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_ENV
"LD_PRELOAD=${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_LIBRARY}"
CACHE INTERNAL "LD_PRELOAD env variable for tests " FORCE)
endif()
endfunction()
# always unset so that it doesn't preload if memcheck disabled
unset(ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_ENV CACHE)
if(ROCPROFILER_REGISTER_MEMCHECK STREQUAL "AddressSanitizer")
rocprofiler_register_add_memcheck_flags("address" "asan")
rocprofiler_register_set_memcheck_env("${ROCPROFILER_REGISTER_MEMCHECK}" "asan")
elseif(ROCPROFILER_REGISTER_MEMCHECK STREQUAL "LeakSanitizer")
rocprofiler_register_add_memcheck_flags("leak" "lsan")
rocprofiler_register_set_memcheck_env("${ROCPROFILER_REGISTER_MEMCHECK}" "lsan")
elseif(ROCPROFILER_REGISTER_MEMCHECK STREQUAL "ThreadSanitizer")
rocprofiler_register_add_memcheck_flags("thread" "tsan")
rocprofiler_register_set_memcheck_env("${ROCPROFILER_REGISTER_MEMCHECK}" "tsan")
elseif(ROCPROFILER_REGISTER_MEMCHECK STREQUAL "UndefinedBehaviorSanitizer")
rocprofiler_register_add_memcheck_flags("undefined" "ubsan")
rocprofiler_register_set_memcheck_env("${ROCPROFILER_REGISTER_MEMCHECK}" "ubsan")
endif()
+110
Переглянути файл
@@ -0,0 +1,110 @@
#
# 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)
set(ROCM_DEP_ROCMCORE
OFF
CACHE BOOL "DEB and RPM packages depend on rocm-core package")
mark_as_advanced(ROCM_DEP_ROCMCORE)
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)
rocprofiler_register_add_option(ROCPROFILER_REGISTER_BUILD_GLOG "Build GLOG" ON)
rocprofiler_register_add_option(ROCPROFILER_REGISTER_BUILD_FMT "Build FMT" ON)
rocprofiler_register_add_option(
ROCPROFILER_REGISTER_DEP_ROCMCORE "DEB and RPM package depend on rocm-core package"
${ROCM_DEP_ROCMCORE})
# In the future, we will do this even with clang-tidy enabled
if(ROCPROFILER_REGISTER_BUILD_CI
AND NOT ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY
AND NOT ROCPROFILER_REGISTER_BUILD_DEVELOPER)
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()
if((ROCM_DEP_ROCMCORE AND NOT ROCPROFILER_REGISTER_DEP_ROCMCORE)
OR (NOT ROCM_DEP_ROCMCORE AND ROCPROFILER_REGISTER_DEP_ROCMCORE))
message(
AUTHOR_WARNING
"Conflicting option values: ROCM_DEP_ROCMCORE = ${ROCM_DEP_ROCMCORE} and ROCPROFILER_REGISTER_DEP_ROCMCORE = ${ROCPROFILER_REGISTER_DEP_ROCMCORE}"
)
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)
+608
Переглянути файл
@@ -0,0 +1,608 @@
# 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()
# ----------------------------------------------------------------------------------------#
# function watch_for_change() Print the value of variable if it changed
#
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_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()
cmake_policy(POP)
+37
Переглянути файл
@@ -0,0 +1,37 @@
set(BUILD_TESTING OFF)
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME external)
if(ROCPROFILER_REGISTER_BUILD_GLOG)
# checkout submodule if not already checked out or clone repo if no .gitmodules file
rocprofiler_register_checkout_git_submodule(
RECURSIVE
RELATIVE_PATH glog
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
REPO_URL https://github.com/google/glog.git
REPO_BRANCH "master")
# May want to use GFLAGS in the future
set(WITH_GFLAGS OFF)
set(WITH_GTEST OFF)
set(WITH_UNWIND "none")
add_subdirectory(glog EXCLUDE_FROM_ALL)
else()
find_package(glog REQUIRED)
endif()
if(ROCPROFILER_REGISTER_BUILD_FMT)
# checkout submodule if not already checked out or clone repo if no .gitmodules file
rocprofiler_register_checkout_git_submodule(
RECURSIVE
RELATIVE_PATH fmt
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
REPO_URL https://github.com/fmtlib/fmt.git
REPO_BRANCH "master")
set(FMT_TEST OFF)
add_subdirectory(fmt EXCLUDE_FROM_ALL)
else()
find_package(fmt REQUIRED)
endif()
сторонній Підмодуль
+1
Підмодуль projects/rocprofiler-register/external/fmt додано в 123913715a
сторонній Підмодуль
+1
Підмодуль projects/rocprofiler-register/external/glog додано в 7b134a5c82
+25
Переглянути файл
@@ -0,0 +1,25 @@
[tool.black]
line-length = 90
target-version = ['py36', 'py37', 'py38', 'py39', 'py310']
include = '\.py$'
exclude = '''
(
/(
\.eggs
| \.git
| \.github
| \.tox
| \.venv
| \.misc
| \.vscode
| \.cache
| \.pytest_cache
| dist
| external
| build
| build-release
| build-rocprofiler
)/
)
'''
+5
Переглянути файл
@@ -0,0 +1,5 @@
black
clang-format>=11.0.0,<12.0.0
clang-tidy>=15.0.0,<19.0.0
cmake>=3.22.0
cmake-format
+8
Переглянути файл
@@ -0,0 +1,8 @@
#
# Samples
#
project(rocprofiler-register-samples LANGUAGES C CXX)
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME sample)
add_subdirectory(library-implementation)
+19
Переглянути файл
@@ -0,0 +1,19 @@
#
#
#
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
set(CMAKE_CXX_FLAGS_INIT "-W -Wall -Wextra")
project(rocprofiler-register-library-implementation LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(rocprofiler-register REQUIRED)
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)
+120
Переглянути файл
@@ -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
+37
Переглянути файл
@@ -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
Переглянути файл
@@ -0,0 +1,3 @@
#
# AddressSanitizer suppressions file for rocprofiler-register project.
#
+3
Переглянути файл
@@ -0,0 +1,3 @@
#
# LeakSanitizer suppressions file for rocprofiler-register project.
#
+463
Переглянути файл
@@ -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 = "cdash.rocprofiler.amd.com"
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 TRUE)
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
Переглянути файл
@@ -0,0 +1,3 @@
#
# ThreadSanitizer suppressions file for rocprofiler-register project.
#
+11
Переглянути файл
@@ -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
Переглянути файл
@@ -0,0 +1,4 @@
#
#
#
add_subdirectory(rocprofiler-register)
+15
Переглянути файл
@@ -0,0 +1,15 @@
#
#
# 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
COMPONENT core)
+224
Переглянути файл
@@ -0,0 +1,224 @@
// 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 <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
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;
/// @brief Struct containing the information about the libraries which have registered
/// with rocprofiler-register. @see rocprofiler_register_iterate_registration_info
typedef struct rocprofiler_register_registration_info_t
{
size_t size; ///< in case of future extensions
const char* common_name; ///< name of the library
uint32_t lib_version; ///< version
uint64_t api_table_length; ///< number of API tables
} rocprofiler_register_registration_info_t;
/**
* @brief Callback function for iterating over the libraries which have registered
* with rocprofiler-register. @see rocprofiler_register_iterate_registration_info
*
* @param [in] info Pointer to library registration instance. Invokee should make a copy
* for reference outside of callback.
* @param [in] data User data passed to ::rocprofiler_register_iterate_registration_info
* @return int
* @retval 0 If zero is returned from callback, rocprofiler-register will continue to next
* registration info, if one exists
* @retval -1 If -1 (or any value != 0) is returned from callback, rocprofiler-register
* will cease to iterate over the remaining registration info, if any exists
*/
typedef int (*rocprofiler_register_registration_info_cb_t)(
rocprofiler_register_registration_info_t* info,
void* data);
/**
* @brief Iterates over all the (valid) libraries which registered their API tables with
* rocprofiler-register. Any libraries which do not have an accepted common name, have an
* invalid import function address (in secure mode), or have registered too many instances
* are not reported by this function.
*
* @param [in] callback Callback function to invoke for each valid registered library
* @param [in] data User data to pass to the callback function
* @return ::rocprofiler_register_error_code_t
* @retval ::ROCP_REG_SUCCESS Always returned
*/
rocprofiler_register_error_code_t
rocprofiler_register_iterate_registration_info(
rocprofiler_register_registration_info_cb_t callback,
void* data)
ROCPROFILER_REGISTER_ATTRIBUTE(nonnull(1)) 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
+103
Переглянути файл
@@ -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
Переглянути файл
@@ -0,0 +1,4 @@
#
#
#
add_subdirectory(rocprofiler-register)
+37
Переглянути файл
@@ -0,0 +1,37 @@
#
# 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 fmt::fmt glog::glog 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)
+10
Переглянути файл
@@ -0,0 +1,10 @@
#
# builds the rocprofiler-register library
#
set(rocprofiler_register_details_sources dl.cpp logging.cpp utility.cpp)
set(rocprofiler_register_details_headers environment.hpp dl.hpp filesystem.hpp
logging.hpp utility.hpp)
target_sources(rocprofiler-register PRIVATE ${rocprofiler_register_details_sources}
${rocprofiler_register_details_headers})
+122
Переглянути файл
@@ -0,0 +1,122 @@
// 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 "filesystem.hpp"
#include "utility.hpp"
#include <fstream>
#include <optional>
#include <string>
#include <string_view>
#include <dlfcn.h>
#include <elf.h>
#include <fmt/core.h>
#include <link.h>
#include <sys/types.h>
#include <unistd.h>
namespace rocprofiler_register
{
namespace binary
{
namespace
{
const open_modes_vec_t default_link_open_modes = { (RTLD_LAZY | RTLD_NOLOAD) };
} // namespace
std::vector<segment_address_ranges>
get_segment_addresses(pid_t _pid)
{
auto _data = std::vector<segment_address_ranges>{};
auto _fname = fmt::format("/{}/{}/{}", "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
+60
Переглянути файл
@@ -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
+164
Переглянути файл
@@ -0,0 +1,164 @@
// 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 <fmt/core.h>
#include <glog/logging.h>
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <stdexcept>
#include <string>
#include <string_view>
#include <type_traits>
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)
{
LOG(ERROR) << fmt::format(
"[rocprofiler_register][get_env] Exception thrown converting getenv({}) "
"= {} to integer :: {}. Using default value of {}",
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;
}
inline int
set_env_impl(std::string_view env_id, bool value, int overwrite)
{
return ::setenv(env_id.data(), (value) ? "1" : "0", overwrite);
}
template <typename Tp>
int
set_env_impl(std::string_view env_id, Tp value, int overwrite)
{
auto str_value = std::stringstream{};
str_value << value;
return ::setenv(env_id.data(), str_value.str().c_str(), overwrite);
}
} // 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));
}
}
template <typename Tp>
inline auto
set_env(std::string_view env_id, Tp&& value, int overwrite = 0)
{
return set_env_impl(env_id, std::forward<Tp>(value), overwrite);
}
struct env_config
{
std::string env_name = {};
std::string env_value = {};
int overwrite = 0;
auto operator()() const
{
if(env_name.empty()) return -1;
LOG(INFO) << fmt::format(
"setenv({}, {}, {})", env_name.c_str(), env_value.c_str(), overwrite);
return setenv(env_name.c_str(), env_value.c_str(), overwrite);
}
};
} // namespace common
} // namespace rocprofiler_register
+48
Переглянути файл
@@ -0,0 +1,48 @@
// 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
#if defined __has_include
# if __has_include(<version>)
# include <version>
# endif
#endif
#if defined(__cpp_lib_filesystem)
# define ROCPROFILER_REGISTER_HAS_CPP_LIB_FILESYSTEM 1
#else
# if defined __has_include
# if __has_include(<filesystem>)
# include <filesystem>
# endif
# endif
#endif
#if defined(ROCPROFILER_REGISTER_HAS_CPP_LIB_FILESYSTEM) && \
ROCPROFILER_REGISTER_HAS_CPP_LIB_FILESYSTEM > 0
# include <filesystem>
namespace fs = ::std::filesystem; // NOLINT
#else
# include <experimental/filesystem>
namespace fs = ::std::experimental::filesystem; // NOLINT
#endif
+229
Переглянути файл
@@ -0,0 +1,229 @@
// 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 "logging.hpp"
#include "environment.hpp"
#include "filesystem.hpp"
#include <fmt/format.h>
#include <fmt/ranges.h>
#include <glog/logging.h>
#include <fstream>
#include <mutex>
#include <string>
#include <string_view>
#include <unordered_map>
#include <sys/types.h>
#include <unistd.h>
namespace rocprofiler_register
{
namespace logging
{
namespace
{
struct logging_config
{
bool logtostderr = true;
bool alsologtostderr = false;
bool logdir_gitignore = false; // add .gitignore to logdir
int32_t loglevel = google::WARNING;
std::string vlog_modules = {};
std::string name = {};
std::string logdir = {};
};
struct log_level_info
{
int32_t google_level = 0;
int32_t verbose_level = 0;
};
void
update_logging(const logging_config& cfg, bool setup_env = false, int env_override = 0)
{
static auto _mtx = std::mutex{};
auto _lk = std::unique_lock<std::mutex>{ _mtx };
FLAGS_timestamp_in_logfile_name = false;
FLAGS_logtostderr = cfg.logtostderr;
FLAGS_minloglevel = cfg.loglevel;
FLAGS_stderrthreshold = cfg.loglevel;
FLAGS_alsologtostderr = cfg.alsologtostderr;
// if(!cfg.logdir.empty()) FLAGS_log_dir = cfg.logdir.c_str();
if(!cfg.logdir.empty() && !fs::exists(cfg.logdir))
{
fs::create_directories(cfg.logdir);
if(cfg.logdir_gitignore)
{
auto ignore = fs::path{ cfg.logdir } / ".gitignore";
if(!fs::exists(ignore))
{
std::ofstream ofs{ ignore.string() };
ofs << "/**" << std::flush;
}
}
}
if(setup_env)
{
common::set_env("GLOG_minloglevel", cfg.loglevel, env_override);
common::set_env("GLOG_logtostderr", cfg.logtostderr ? 1 : 0, env_override);
common::set_env(
"GLOG_alsologtostderr", cfg.alsologtostderr ? 1 : 0, env_override);
common::set_env("GLOG_stderrthreshold", cfg.loglevel, env_override);
if(!cfg.logdir.empty())
{
common::set_env("GOOGLE_LOG_DIR", cfg.logdir, env_override);
common::set_env("GLOG_log_dir", cfg.logdir, env_override);
}
if(!cfg.vlog_modules.empty())
common::set_env("GLOG_vmodule", cfg.vlog_modules, env_override);
}
}
#define ROCP_REG_LOG_LEVEL_TRACE 4
#define ROCP_REG_LOG_LEVEL_INFO 3
#define ROCP_REG_LOG_LEVEL_WARNING 2
#define ROCP_REG_LOG_LEVEL_ERROR 1
#define ROCP_REG_LOG_LEVEL_NONE 0
void
init_logging(std::string_view env_prefix, logging_config cfg = logging_config{})
{
static auto _once = std::once_flag{};
std::call_once(_once, [env_prefix, &cfg]() {
auto get_argv0 = []() {
auto ifs = std::ifstream{ "/proc/self/cmdline" };
auto sarg = std::string{};
while(ifs && !ifs.eof())
{
ifs >> sarg;
if(!sarg.empty()) break;
}
return sarg;
};
auto to_lower = [](std::string val) {
for(auto& itr : val)
itr = tolower(itr);
return val;
};
const auto env_opts = std::unordered_map<std::string_view, log_level_info>{
{ "trace", { google::INFO, ROCP_REG_LOG_LEVEL_TRACE } },
{ "info", { google::INFO, ROCP_REG_LOG_LEVEL_INFO } },
{ "warning", { google::WARNING, ROCP_REG_LOG_LEVEL_WARNING } },
{ "error", { google::ERROR, ROCP_REG_LOG_LEVEL_ERROR } },
{ "fatal", { google::FATAL, ROCP_REG_LOG_LEVEL_NONE } }
};
auto supported = std::vector<std::string>{};
supported.reserve(env_opts.size());
for(auto itr : env_opts)
supported.emplace_back(itr.first);
if(cfg.name.empty()) cfg.name = to_lower(std::string{ env_prefix });
cfg.logdir = common::get_env(fmt::format("{}_LOG_DIR", env_prefix), cfg.logdir);
cfg.vlog_modules =
common::get_env(fmt::format("{}_vmodule", env_prefix), cfg.vlog_modules);
cfg.logtostderr = cfg.logdir.empty(); // log to stderr if no log dir set
// cfg.alsologtostderr = !cfg.logdir.empty(); // log to file if log dir set
auto loglvl =
to_lower(common::get_env(fmt::format("{}_LOG_LEVEL", env_prefix), ""));
// default to warning
auto& loglvl_v = cfg.loglevel;
if(!loglvl.empty() &&
loglvl.find_first_not_of("-0123456789") == std::string::npos)
{
auto val = std::stol(loglvl);
if(val < 0)
{
loglvl_v = google::FATAL;
}
else
{
// default to trace in case val > ROCP_REG_LOG_LEVEL_TRACE
auto itr = env_opts.at("trace");
for(auto oitr : env_opts)
{
if(oitr.second.verbose_level == val)
{
itr = oitr.second;
break;
}
}
loglvl_v = itr.google_level;
}
}
else if(!loglvl.empty())
{
if(env_opts.find(loglvl) == env_opts.end())
throw std::runtime_error{ fmt::format(
"invalid specifier for {}_LOG_LEVEL: {}. Supported: {}",
env_prefix,
loglvl,
fmt::format("{}",
fmt::join(supported.begin(), supported.end(), ", "))) };
else
{
loglvl_v = env_opts.at(loglvl).google_level;
}
}
update_logging(cfg, !google::IsGoogleLoggingInitialized());
if(!google::IsGoogleLoggingInitialized())
{
static auto argv0 = get_argv0();
// Prevent glog from crashing if vmodule is empty
if(FLAGS_vmodule.empty()) FLAGS_vmodule = " ";
google::InitGoogleLogging(argv0.c_str());
// Swap out memory to avoid leaking the string
if(!FLAGS_vmodule.empty()) std::string{}.swap(FLAGS_vmodule);
if(!FLAGS_log_dir.empty()) std::string{}.swap(FLAGS_log_dir);
}
update_logging(cfg);
LOG(INFO) << "logging initialized via " << fmt::format("{}_LOG_LEVEL", env_prefix)
<< ". Log Level: " << loglvl;
});
}
} // namespace
void
initialize()
{
init_logging("ROCPROFILER_REGISTER");
}
} // namespace logging
} // namespace rocprofiler_register
+37
Переглянути файл
@@ -0,0 +1,37 @@
// 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 logging
{
void
initialize();
} // namespace logging
} // namespace rocprofiler_register
+87
Переглянути файл
@@ -0,0 +1,87 @@
// MIT License
//
// Copyright (c) 2025 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 "fmt/core.h"
#include "glog/logging.h"
#include <functional>
#include <utility>
namespace rocprofiler_register
{
namespace common
{
struct scope_destructor
{
/// \fn scope_destructor(FuncT&& _fini, InitT&& _init)
/// \tparam FuncT "std::function<void()> or void (*)()"
/// \tparam InitT "std::function<void()> or void (*)()"
/// \param _fini Function to execute when object is destroyed
/// \param _init Function to execute when object is created (optional)
///
/// \brief Provides a utility to perform an operation when exiting a scope.
template <typename FuncT, typename InitT = void (*)()>
scope_destructor(
FuncT&& _fini,
InitT&& _init = []() {});
~scope_destructor() { m_functor(); }
// delete copy operations
scope_destructor(const scope_destructor&) = delete;
scope_destructor& operator=(const scope_destructor&) = delete;
// allow move operations
scope_destructor(scope_destructor&& rhs) noexcept;
scope_destructor& operator=(scope_destructor&& rhs) noexcept;
private:
std::function<void()> m_functor = []() {};
};
template <typename FuncT, typename InitT>
scope_destructor::scope_destructor(FuncT&& _fini, InitT&& _init)
: m_functor{ std::forward<FuncT>(_fini) }
{
_init();
}
inline scope_destructor::scope_destructor(scope_destructor&& rhs) noexcept
: m_functor{ std::move(rhs.m_functor) }
{
rhs.m_functor = []() {};
}
inline scope_destructor&
scope_destructor::operator=(scope_destructor&& rhs) noexcept
{
if(this != &rhs)
{
m_functor = std::move(rhs.m_functor);
rhs.m_functor = []() {};
}
return *this;
}
} // namespace common
} // namespace rocprofiler_register
+127
Переглянути файл
@@ -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(char delimiter : delimiters)
{
if(itr == delimiter) ++_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
+44
Переглянути файл
@@ -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
+24
Переглянути файл
@@ -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;
+663
Переглянути файл
@@ -0,0 +1,663 @@
// 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/filesystem.hpp"
#include "details/logging.hpp"
#include "details/scope_destructor.hpp"
#include <fmt/format.h>
#include <glog/logging.h>
#include <array>
#include <atomic>
#include <bitset>
#include <fstream>
#include <mutex>
#include <regex>
#include <stdexcept>
#include <string_view>
#include <utility>
#include <dlfcn.h>
#include <unistd.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_hip_compiler
#pragma weak rocprofiler_register_import_hip_compiler_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
typedef struct rocprofiler_client_id_t
{
const char* name; ///< clients should set this value for debugging
const uint32_t handle; ///< internal handle
} rocprofiler_client_id_t;
typedef void (*rocprofiler_client_finalize_t)(rocprofiler_client_id_t);
typedef int (*rocprofiler_tool_initialize_t)(rocprofiler_client_finalize_t finalize_func,
void* tool_data);
typedef void (*rocprofiler_tool_finalize_t)(void* tool_data);
typedef struct rocprofiler_tool_configure_result_t
{
size_t size; ///< in case of future extensions
rocprofiler_tool_initialize_t initialize; ///< context creation
rocprofiler_tool_finalize_t finalize; ///< cleanup
void* tool_data; ///< data to provide to init and fini callbacks
} rocprofiler_tool_configure_result_t;
extern rocprofiler_tool_configure_result_t*
rocprofiler_configure(uint32_t, const char*, uint32_t, rocprofiler_client_id_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_hip_compiler(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_hip_compiler_static(void);
extern uint32_t
rocprofiler_register_import_hsa_static(void);
extern uint32_t
rocprofiler_register_import_roctx_static(void);
}
namespace
{
using namespace rocprofiler_register;
using rocprofiler_set_api_table_t = decltype(::rocprofiler_set_api_table)*;
using rocp_set_api_table_data_t = std::tuple<void*, rocprofiler_set_api_table_t>;
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");
constexpr auto rocprofiler_lib_name = "librocprofiler-sdk.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_HIP_COMPILER,
ROCP_REG_RCCL,
ROCP_REG_ROCDECODE,
ROCP_REG_ROCJPEG,
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;
};
template <size_t Idx>
struct rocp_reg_error_message;
#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; \
};
#define ROCP_REG_DEFINE_ERROR_MESSAGE(ENUM, MSG) \
template <> \
struct rocp_reg_error_message<ENUM> \
{ \
static constexpr auto value = MSG; \
};
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\\.]+)")
ROCP_REG_DEFINE_LIBRARY_TRAITS(ROCP_REG_HIP_COMPILER,
"hip_compiler",
"rocprofiler_register_import_hip_compiler",
"libamdhip64.so.[6-9]($|\\.[0-9\\.]+)")
ROCP_REG_DEFINE_LIBRARY_TRAITS(ROCP_REG_RCCL,
"rccl",
"rocprofiler_register_import_rccl",
"librccl.so.[6-9]($|\\.[0-9\\.]+)")
ROCP_REG_DEFINE_LIBRARY_TRAITS(ROCP_REG_ROCDECODE,
"rocdecode",
"rocprofiler_register_import_rocdecode",
"librocdecode.so.[0-9]($|\\.[0-9\\.]+)")
ROCP_REG_DEFINE_LIBRARY_TRAITS(ROCP_REG_ROCJPEG,
"rocjpeg",
"rocprofiler_register_import_rocjpeg",
"librocjpeg.so.[0-9]($|\\.[0-9\\.]+)")
ROCP_REG_DEFINE_ERROR_MESSAGE(ROCP_REG_SUCCESS, "Success")
ROCP_REG_DEFINE_ERROR_MESSAGE(ROCP_REG_NO_TOOLS, "rocprofiler-register found no tools")
ROCP_REG_DEFINE_ERROR_MESSAGE(ROCP_REG_DEADLOCK, "rocprofiler-register deadlocked")
ROCP_REG_DEFINE_ERROR_MESSAGE(ROCP_REG_BAD_API_TABLE_LENGTH,
"Library passed an invalid number of API tables")
ROCP_REG_DEFINE_ERROR_MESSAGE(ROCP_REG_UNSUPPORTED_API, "Library's API is not supported")
ROCP_REG_DEFINE_ERROR_MESSAGE(ROCP_REG_INVALID_API_ADDRESS,
"Invalid API address (secure mode enabled)")
ROCP_REG_DEFINE_ERROR_MESSAGE(ROCP_REG_ROCPROFILER_ERROR,
"Unspecified rocprofiler-register error")
ROCP_REG_DEFINE_ERROR_MESSAGE(
ROCP_REG_EXCESS_API_INSTANCES,
"Too many instances of the same library API were registered")
auto
get_this_library_path()
{
auto _this_lib_path = binary::get_linked_path(rocprofiler_register_lib_name,
{ RTLD_NOLOAD | RTLD_LAZY });
LOG_IF(FATAL, !_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();
}
template <size_t Idx, size_t... Tail>
constexpr auto
rocprofiler_register_error_string(rocprofiler_register_error_code_t _ec,
std::index_sequence<Idx, Tail...>)
{
if(_ec == Idx) return rocp_reg_error_message<Idx>::value;
if constexpr(sizeof...(Tail) > 0)
{
return rocprofiler_register_error_string(_ec, std::index_sequence<Tail...>{});
}
else
{
return "rocprofiler_register_unknown_error";
}
}
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;
}
rocp_set_api_table_data_t
rocp_load_rocprofiler_lib(std::string _rocp_reg_lib);
struct rocp_scan_data
{
void* handle = nullptr;
rocprofiler_set_api_table_t set_api_table_fn = nullptr;
};
rocp_scan_data
rocp_reg_scan_for_tools()
{
auto* _configure_func = dlsym(RTLD_DEFAULT, "rocprofiler_configure");
auto _rocp_tool_libs = common::get_env("ROCP_TOOL_LIBRARIES", std::string{});
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() || !_rocp_tool_libs.empty());
bool _found_tool =
(rocprofiler_configure != nullptr || _configure_func != nullptr || _force_tool);
static void* rocprofiler_lib_handle = nullptr;
static rocprofiler_set_api_table_t rocprofiler_lib_config_fn = nullptr;
if(_found_tool)
{
if(rocprofiler_lib_handle && rocprofiler_lib_config_fn)
return rocp_scan_data{ rocprofiler_lib_handle, rocprofiler_lib_config_fn };
if(_rocp_reg_lib.empty()) _rocp_reg_lib = rocprofiler_lib_name;
std::tie(rocprofiler_lib_handle, rocprofiler_lib_config_fn) =
rocp_load_rocprofiler_lib(_rocp_reg_lib);
LOG_IF(FATAL, !rocprofiler_lib_config_fn)
<< rocprofiler_lib_register_entrypoint << " not found. Tried to dlopen "
<< _rocp_reg_lib;
}
else if(_found_tool && rocprofiler_set_api_table)
{
rocprofiler_lib_config_fn = &rocprofiler_set_api_table;
}
return rocp_scan_data{ rocprofiler_lib_handle, rocprofiler_lib_config_fn };
}
rocp_set_api_table_data_t
rocp_load_rocprofiler_lib(std::string _rocp_reg_lib)
{
void* rocprofiler_lib_handle = nullptr;
rocprofiler_set_api_table_t rocprofiler_lib_config_fn = nullptr;
if(rocprofiler_set_api_table) rocprofiler_lib_config_fn = &rocprofiler_set_api_table;
// return if found via LD_PRELOAD
if(rocprofiler_lib_config_fn)
return std::make_tuple(rocprofiler_lib_handle, rocprofiler_lib_config_fn);
// look to see if entrypoint function is already a symbol
*(void**) (&rocprofiler_lib_config_fn) =
dlsym(RTLD_DEFAULT, rocprofiler_lib_register_entrypoint);
// return if found via RTLD_DEFAULT
if(rocprofiler_lib_config_fn)
return std::make_tuple(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);
}
LOG(INFO) << "loaded " << _rocp_reg_lib_path_fname.string() << " library at "
<< _rocp_reg_lib_path.string();
LOG_IF(WARNING, rocprofiler_lib_handle == nullptr)
<< _rocp_reg_lib << " failed to load\n";
*(void**) (&rocprofiler_lib_config_fn) =
dlsym(rocprofiler_lib_handle, rocprofiler_lib_register_entrypoint);
LOG_IF(WARNING, rocprofiler_lib_config_fn == nullptr)
<< _rocp_reg_lib << " did not contain '" << rocprofiler_lib_register_entrypoint
<< "' symbol\n";
return std::make_tuple(rocprofiler_lib_handle, rocprofiler_lib_config_fn);
}
struct registered_library_api_table
{
bool propagated = false;
const char* common_name = nullptr;
rocprofiler_register_import_func_t import_func = nullptr;
uint32_t lib_version = 0;
std::vector<void*> api_tables = {};
uint64_t instance_value = 0;
};
constexpr auto instance_bits = sizeof(uint64_t) * 8; // bits in instance_counters
constexpr auto max_instances = instance_bits * ROCP_REG_LAST;
constexpr auto library_seq = std::make_index_sequence<ROCP_REG_LAST>{};
auto global_count = std::atomic<uint32_t>{ 0 };
auto import_info = rocp_reg_get_imports(library_seq);
auto instance_counters = std::array<std::atomic_uint64_t, ROCP_REG_LAST>{};
auto registered =
std::array<std::optional<registered_library_api_table>, max_instances>{};
struct scoped_count
{
scoped_count()
: value{ ++global_count }
{ }
~scoped_count() { --global_count; }
scoped_count(const scoped_count&) = delete;
scoped_count(scoped_count&&) noexcept = delete;
scoped_count& operator=(const scoped_count&) = delete;
scoped_count& operator=(scoped_count&&) noexcept = delete;
uint32_t value = 0;
};
std::optional<registered_library_api_table>*
rocp_add_registered_library_api_table(const char* common_name,
rocprofiler_register_import_func_t import_func,
uint32_t lib_version,
void** api_tables,
uint64_t api_tables_len,
uint64_t instance_val)
{
LOG(INFO) << fmt::format("rocprofiler-register library api table registration:\n\t-"
"name: {}\n\t- version: {}\n\t- # tables: {}",
common_name,
lib_version,
api_tables_len);
for(auto& itr : registered)
{
if(!itr)
{
auto _tables = std::vector<void*>{};
_tables.reserve(api_tables_len);
for(uint64_t i = 0; i < api_tables_len; ++i)
_tables.emplace_back(api_tables[i]);
itr = registered_library_api_table{
false, common_name, import_func,
lib_version, std::move(_tables), instance_val
};
return &itr;
}
}
return nullptr;
}
rocprofiler_register_error_code_t
rocp_invoke_registrations(bool invoke_all)
{
auto _count = scoped_count{};
if(_count.value > 1) return ROCP_REG_DEADLOCK;
for(auto& itr : registered)
{
if(itr && (!itr->propagated || invoke_all))
{
auto _scan_result = rocp_reg_scan_for_tools();
// rocprofiler_set_api_table has been found and we have pass the API data
auto _activate_rocprofiler = (_scan_result.set_api_table_fn != nullptr);
if(_activate_rocprofiler)
{
auto _ret = _scan_result.set_api_table_fn(itr->common_name,
itr->lib_version,
itr->instance_value,
itr->api_tables.data(),
itr->api_tables.size());
if(_ret != 0) return ROCP_REG_ROCPROFILER_ERROR;
itr->propagated = true;
}
}
}
return ROCP_REG_SUCCESS;
}
} // 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;
rocprofiler_register::logging::initialize();
// rocprofiler-register is disabled via environment
if(!common::get_env("ROCPROFILER_REGISTER_ENABLED", true))
{
LOG(INFO) << "rocprofiler-register disabled via ROCPROFILER_REGISTER_ENABLED=0";
return ROCP_REG_NO_TOOLS;
}
auto _count = scoped_count{};
if(_count.value > 1) 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 };
auto* reginfo = rocp_add_registered_library_api_table(common_name,
import_func,
lib_version,
api_tables,
api_table_length,
_instance_val);
LOG_IF(WARNING, !reginfo) << fmt::format(
"rocprofiler-register failed to create registration info for "
"{} version {} (instance {})",
common_name,
lib_version,
_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.set_api_table_fn != nullptr);
if(_activate_rocprofiler)
{
auto _ret = _scan_result.set_api_table_fn(
common_name, lib_version, _instance_val, api_tables, api_table_length);
if(_ret != 0) return ROCP_REG_ROCPROFILER_ERROR;
if(reginfo) (*reginfo)->propagated = true;
}
else
{
return ROCP_REG_NO_TOOLS;
}
return ROCP_REG_SUCCESS;
}
const char*
rocprofiler_register_error_string(rocprofiler_register_error_code_t _ec)
{
return rocprofiler_register_error_string(
_ec, std::make_index_sequence<ROCP_REG_ERROR_CODE_END>{});
}
rocprofiler_register_error_code_t
rocprofiler_register_iterate_registration_info(
rocprofiler_register_registration_info_cb_t callback,
void* data)
{
for(const auto& itr : registered)
{
if(itr)
{
auto _info = rocprofiler_register_registration_info_t{
.size = sizeof(rocprofiler_register_registration_info_t),
.common_name = itr->common_name,
.lib_version = itr->lib_version,
.api_table_length = itr->api_tables.size()
};
// invoke callback and break if the caller does not return zero
if(callback(&_info, data) != ROCP_REG_SUCCESS) break;
}
}
return ROCP_REG_SUCCESS;
}
rocprofiler_register_error_code_t
rocprofiler_register_invoke_nonpropagated_registrations() ROCPROFILER_REGISTER_PUBLIC_API;
//
// This function can be invoked by ptrace
rocprofiler_register_error_code_t
rocprofiler_register_invoke_nonpropagated_registrations()
{
return rocp_invoke_registrations(false);
}
rocprofiler_register_error_code_t
rocprofiler_register_invoke_all_registrations() ROCPROFILER_REGISTER_PUBLIC_API;
//
// This function can be invoked by ptrace
rocprofiler_register_error_code_t
rocprofiler_register_invoke_all_registrations()
{
return rocp_invoke_registrations(true);
}
}
+545
Переглянути файл
@@ -0,0 +1,545 @@
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
project(rocprofiler-register-tests LANGUAGES C CXX)
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME tests)
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()
if(NOT CMAKE_DL_LIBS)
find_library(DL_LIBRARY NAMES dl)
if(NOT DL_LIBRARY)
set(DL_LIBRARY dl)
endif()
set(CMAKE_DL_LIBS ${DL_LIBRARY})
endif()
#
# mock libraries
#
add_subdirectory(hsa-runtime)
add_subdirectory(amdhip)
add_subdirectory(roctx)
add_subdirectory(rccl)
add_subdirectory(rocdecode)
add_subdirectory(rocjpeg)
add_subdirectory(rocprofiler)
#
# mock tool library
#
add_subdirectory(generic-tool)
#
# test app
#
add_subdirectory(bin)
#
# 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++
${CMAKE_DL_LIBS})
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-tool INTERFACE)
target_link_options(rocprofiler-register-tests-tool INTERFACE -Wl,--no-as-needed)
target_link_libraries(rocprofiler-register-tests-tool
INTERFACE generic-tool::generic-tool)
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 generic-tool::generic-tool)
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-tool ALIAS rocprofiler-register-tests-tool)
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} "${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_ENV}"
"${RRTE_CORE_PASS_REGEX}" "${RRTE_CORE_FAIL_REGEX}")
rocp_register_add_test(
${_NAME}-preload ${_NAME}
"LD_PRELOAD=${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_LIBRARY}:libgeneric-tool.so"
"${RRTE_PRELOAD_PASS_REGEX}" "${RRTE_PRELOAD_FAIL_REGEX}")
rocp_register_add_test(
${_NAME}-env
${_NAME}
"ROCP_TOOL_LIBRARIES=libgeneric-tool.so;${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_ENV}"
"${RRTE_PRELOAD_PASS_REGEX}"
"${RRTE_PRELOAD_FAIL_REGEX}")
rocp_register_add_test(
${_NAME}-wrap ${_NAME}
"ROCP_REG_TEST_WRAP=1;${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_ENV}"
"${RRTE_WRAP_PASS_REGEX}" "${RRTE_WRAP_FAIL_REGEX}")
rocp_register_add_test(
${_NAME}-preload-wrap
${_NAME}
"LD_PRELOAD=${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_LIBRARY}:libgeneric-tool.so;ROCP_REG_TEST_WRAP=1"
"${RRTE_PRELOAD_WRAP_PASS_REGEX}"
"${RRTE_PRELOAD_WRAP_FAIL_REGEX}")
rocp_register_add_test(
${_NAME}-env-wrap
${_NAME}
"ROCP_TOOL_LIBRARIES=libgeneric-tool.so;ROCP_REG_TEST_WRAP=1;${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_ENV}"
"${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-tool
SOURCES test-amdhip-roctx.cpp
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip roctx::roctx
rocprofiler-register::tests-tool
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-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-tool
SOURCES test-amdhip-roctx.cpp
LIBRARIES rocprofiler-register::tests-weak rocprofiler-register::tests-tool
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"
)
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;${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_ENV}"
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;${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_ENV}"
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;${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_ENV}"
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=librocprofiler-sdk.so.0;ROCPROFILER_REGISTER_SECURE=yes;ROCPROFILER_REGISTER_VERBOSE=3;ROCPROFILER_REGISTER_MONOCHROME=true;${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_ENV}"
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}/librocprofiler-sdk.so.0;ROCPROFILER_REGISTER_SECURE=yes;ROCPROFILER_REGISTER_VERBOSE=3;ROCPROFILER_REGISTER_MONOCHROME=true;${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_ENV}"
LABELS
"dlopen;secure")
+39
Переглянути файл
@@ -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
Переглянути файл
@@ -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
Переглянути файл
@@ -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
+114
Переглянути файл
@@ -0,0 +1,114 @@
#
#
#
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Threads REQUIRED)
find_package(
hip
HINTS
${ROCM_PATH}
ENV
ROCM_PATH
/opt/rocm
PATHS
${ROCM_PATH}
ENV
ROCM_PATH
/opt/rocm)
if(hip_FOUND)
add_executable(simple-hip)
target_sources(simple-hip PRIVATE simple-hip.cpp)
target_compile_options(simple-hip PRIVATE -W -Wall -Wextra -Werror)
target_link_libraries(simple-hip PRIVATE Threads::Threads hip::host)
set(PRELOAD_TESTS_DISABLED OFF)
install(
TARGETS simple-hip
DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/tests/bin
COMPONENT tests)
else()
add_executable(simple-hip EXCLUDE_FROM_ALL)
target_sources(simple-hip PRIVATE simple-hip.cpp)
target_link_libraries(simple-hip PRIVATE Threads::Threads)
set(PRELOAD_TESTS_DISABLED ON)
endif()
#
# INSTALL
#
set(TEST_DESTDIR "${CMAKE_BINARY_DIR}/tests/install")
set(simple-hip-install-env "DESTDIR=${TEST_DESTDIR}")
add_test(
NAME test-simple-hip-install
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target install --parallel 4
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
set_tests_properties(
test-simple-hip-install
PROPERTIES TIMEOUT
120
LABELS
"integration-test"
ENVIRONMENT
"${simple-hip-install-env}"
DISABLED
${PRELOAD_TESTS_DISABLED}
FIXTURES_SETUP
"simple-hip-install")
#
# NORMAL (no profiling library)
#
string(REPLACE "//" "/" TEST_INSTALL_PREFIX "${TEST_DESTDIR}/${CMAKE_INSTALL_PREFIX}")
set(simple-hip-normal-env
"LD_LIBRARY_PATH=${TEST_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}:${ROCM_PATH}/${CMAKE_INSTALL_LIBDIR}"
"LD_PRELOAD=${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_LIBRARY}")
add_test(NAME test-simple-hip-normal COMMAND $<TARGET_FILE:simple-hip>)
set_tests_properties(
test-simple-hip-normal
PROPERTIES TIMEOUT
120
LABELS
"integration-test"
ENVIRONMENT
"${simple-hip-normal-env}"
DEPENDS
test-simple-hip-install
DISABLED
${PRELOAD_TESTS_DISABLED}
FIXTURES_SETUP
"simple-hip-works"
FIXTURES_REQUIRED
"simple-hip-install")
#
# PRELOAD
#
set(simple-hip-preload-env
${simple-hip-normal-env}
"LD_PRELOAD=${ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_LIBRARY}:$<TARGET_FILE:generic-tool::generic-tool>"
)
add_test(NAME test-simple-hip-preload COMMAND $<TARGET_FILE:simple-hip>)
set_tests_properties(
test-simple-hip-preload
PROPERTIES TIMEOUT
120
LABELS
"integration-test"
ENVIRONMENT
"${simple-hip-preload-env}"
DEPENDS
test-simple-hip-install
DISABLED
${PRELOAD_TESTS_DISABLED}
FIXTURES_REQUIRED
"simple-hip-install;simple-hip-works")
+174
Переглянути файл
@@ -0,0 +1,174 @@
// MIT License
//
// Copyright (c) 2023 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 <hip/hip_runtime_api.h>
#include <unistd.h>
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <mutex>
#include <random>
#include <stdexcept>
#include <thread>
#include <vector>
#define HIP_API_CALL(CALL) \
if(hipError_t error_ = (CALL); error_ != hipSuccess) \
{ \
auto _hip_api_print_lk = auto_lock_t{ print_lock }; \
fprintf(stderr, \
"%s:%d :: HIP error : %s\n", \
__FILE__, \
__LINE__, \
hipGetErrorString(error_)); \
fflush(stderr); \
std::exit(EXIT_FAILURE); \
}
static constexpr int64_t Bi = 1;
static constexpr int64_t KiB = 1024 * Bi;
static constexpr int64_t MiB = 1024 * KiB;
void
run(size_t rank, size_t tid, const char* prefix);
namespace
{
using auto_lock_t = std::unique_lock<std::mutex>;
auto print_lock = std::mutex{};
size_t xdim = 4960 * 2;
size_t ydim = 4960 * 2;
size_t nthreads = 2;
size_t nitr = 1;
} // namespace
int
main(int argc, char** argv)
{
for(int i = 1; i < argc; ++i)
{
auto _arg = std::string{ argv[i] };
if(_arg == "?" || _arg == "-h" || _arg == "--help")
{
fprintf(stderr,
"usage: %s [M (%zu)] [N (%zu)] [NUM_THREADS (%zu)] [NUM_ITERATION "
"(%zu)]\n",
::basename(argv[0]),
xdim,
ydim,
nthreads,
nitr);
exit(EXIT_SUCCESS);
}
}
if(argc > 1) xdim = atoll(argv[1]);
if(argc > 2) ydim = atoll(argv[2]);
if(argc > 3) nthreads = atoll(argv[3]);
if(argc > 4) nitr = atoll(argv[4]);
int ndevice = 0;
HIP_API_CALL(hipGetDeviceCount(&ndevice));
printf("[%s] Number of devices found: %i\n", ::basename(argv[0]), ndevice);
printf("[%s] Number of matrix: %zu x %zu\n", ::basename(argv[0]), xdim, ydim);
printf("[%s] Number of threads: %zu\n", ::basename(argv[0]), nthreads);
printf("[%s] Number of iterations: %zu\n", ::basename(argv[0]), nitr);
for(size_t j = 0; j < nitr; ++j)
{
printf("\n[%s] Iteration #%zu\n\n", ::basename(argv[0]), j);
auto threads = std::vector<std::thread>{};
threads.reserve(nthreads);
for(size_t i = 0; i < nthreads; ++i)
threads.emplace_back(run, getpid(), i, ::basename(argv[0]));
for(auto& itr : threads)
itr.join();
}
return 0;
}
template <typename Tp>
auto
allocate_memory(size_t M, size_t N, Tp val)
{
const auto sz = M * N;
const auto nb = sz * sizeof(Tp);
Tp* ptr = new Tp[M * N];
::memset(ptr, val, nb);
HIP_API_CALL(hipHostRegister(ptr, nb, hipHostRegisterDefault))
return ptr;
}
template <typename Tp>
auto
deallocate_memory(Tp* ptr)
{
HIP_API_CALL(hipHostUnregister(ptr))
delete[] ptr;
}
void
run(size_t rank, size_t tid, const char* label)
{
const auto M = xdim;
const auto N = ydim;
auto* inp = allocate_memory<int>(M, N, 0);
auto* out = allocate_memory<int>(M, N, 1);
auto _engine =
std::default_random_engine{ std::random_device{}() * (rank + 1) * (tid + 1) };
std::uniform_int_distribution<int> _dist{ 0, 1000 };
for(size_t i = 0; i < (M * N); i++)
inp[i] = _dist(_engine);
// lock during malloc to get more accurate memory info
{
auto_lock_t _lk{ print_lock };
size_t free_gpu_mem = 0;
size_t total_gpu_mem = 0;
HIP_API_CALL(hipMemGetInfo(&free_gpu_mem, &total_gpu_mem));
free_gpu_mem /= MiB;
total_gpu_mem /= MiB;
std::cout << "[" << label << "][" << rank << "][" << tid
<< "] Available GPU memory (MiB): " << std::setw(6) << free_gpu_mem
<< " / " << std::setw(6) << total_gpu_mem << std::endl;
}
deallocate_memory(inp);
deallocate_memory(out);
}
+68
Переглянути файл
@@ -0,0 +1,68 @@
#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
# pragma weak ncclGetVersion
# pragma weak rocDecCreateDecoder
# pragma weak rocJpegStreamCreate
#endif
extern void
hip_init(void);
extern void
hsa_init(void);
extern void
roctxRangePush(const char*);
extern void
roctxRangePop(const char*);
enum ncclResult_t
{
};
extern ncclResult_t
ncclGetVersion(int* version);
enum rocDecStatus
{
};
enum rocDecDecoderHandle
{
};
enum RocDecoderCreateInfo
{
};
extern rocDecStatus
rocDecCreateDecoder(rocDecDecoderHandle* decoder_handle,
RocDecoderCreateInfo* decoder_create_info);
enum RocJpegStatus
{
};
enum RocJpegStreamHandle
{
};
extern RocJpegStatus
rocJpegStreamCreate(RocJpegStreamHandle* jpeg_stream_handle);
#ifdef __cplusplus
}
#endif
+131
Переглянути файл
@@ -0,0 +1,131 @@
#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(ncclGetVersion)* ncclGetVersion_fn = nullptr;
decltype(roctxRangePush)* roctxRangePush_fn = nullptr;
decltype(roctxRangePush)* roctxRangePop_fn = nullptr;
decltype(rocDecCreateDecoder)* rocDecCreateDecoder_fn = nullptr;
decltype(rocJpegStreamCreate)* rocJpegStreamCreate_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),
ROCP_REG_TEST_RCCL = (1 << 3),
ROCP_REG_TEST_ROCDECODE = (1 << 4),
ROCP_REG_TEST_ROCJPEG = (1 << 5),
};
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;
void* rccl_handle = nullptr;
void* rocdecode_handle = nullptr;
void* rocjpeg_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");
}
if constexpr((Idx & ROCP_REG_TEST_RCCL) == ROCP_REG_TEST_RCCL)
{
ncclGetVersion_fn = ncclGetVersion;
if(!ncclGetVersion_fn) _resolve_dlopen(rccl_handle, "librccl.so");
_resolve_dlsym(ncclGetVersion_fn, rccl_handle, "ncclGetVersion");
}
if constexpr((Idx & ROCP_REG_TEST_ROCDECODE) == ROCP_REG_TEST_ROCDECODE)
{
rocDecCreateDecoder_fn = rocDecCreateDecoder;
if(!rocDecCreateDecoder_fn) _resolve_dlopen(rocdecode_handle, "librocdecode.so");
_resolve_dlsym(rocDecCreateDecoder_fn, rocdecode_handle, "rocDecCreateDecoder");
}
if constexpr((Idx & ROCP_REG_TEST_ROCJPEG) == ROCP_REG_TEST_ROCJPEG)
{
rocJpegStreamCreate_fn = rocJpegStreamCreate;
if(!rocJpegStreamCreate_fn) _resolve_dlopen(rocjpeg_handle, "librocjpeg.so");
_resolve_dlsym(rocJpegStreamCreate_fn, rocjpeg_handle, "rocJpegStreamCreate");
}
}
} // namespace
+11
Переглянути файл
@@ -0,0 +1,11 @@
#
# mock generic-tool library
#
add_library(generic-tool SHARED)
add_library(generic-tool::generic-tool ALIAS generic-tool)
target_sources(generic-tool PRIVATE generic-tool.cpp)
target_include_directories(
generic-tool PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>)
# target_link_libraries(generic-tool PRIVATE rocprofiler)
rocp_register_strip_target(generic-tool)
+46
Переглянути файл
@@ -0,0 +1,46 @@
#include <pthread.h>
#include <cstdint>
#include <stdexcept>
#include <string_view>
extern "C" {
typedef struct rocprofiler_client_id_t
{
const char* name; ///< clients should set this value for debugging
const uint32_t handle; ///< internal handle
} rocprofiler_client_id_t;
typedef void (*rocprofiler_client_finalize_t)(rocprofiler_client_id_t);
typedef int (*rocprofiler_tool_initialize_t)(rocprofiler_client_finalize_t finalize_func,
void* tool_data);
typedef void (*rocprofiler_tool_finalize_t)(void* tool_data);
typedef struct rocprofiler_tool_configure_result_t
{
size_t size; ///< in case of future extensions
rocprofiler_tool_initialize_t initialize; ///< context creation
rocprofiler_tool_finalize_t finalize; ///< cleanup
void* tool_data; ///< data to provide to init and fini callbacks
} rocprofiler_tool_configure_result_t;
rocprofiler_tool_configure_result_t*
rocprofiler_configure(uint32_t, const char*, uint32_t, rocprofiler_client_id_t*)
__attribute__((visibility("default")));
rocprofiler_tool_configure_result_t*
rocprofiler_configure(uint32_t version,
const char* runtime_version,
uint32_t priority,
rocprofiler_client_id_t* tool_id)
{
(void) version;
(void) runtime_version;
(void) priority;
(void) tool_id;
return nullptr;
}
}
+35
Переглянути файл
@@ -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
Переглянути файл
@@ -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
Переглянути файл
@@ -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
+33
Переглянути файл
@@ -0,0 +1,33 @@
#
#
#
if(NOT TARGET rocprofiler-register::rocprofiler-register)
# find_package(rocprofiler-register REQUIRED)
endif()
add_library(rccl SHARED)
add_library(rccl::rccl ALIAS rccl)
target_sources(rccl PRIVATE rccl.cpp rccl.hpp)
target_include_directories(rccl PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
target_link_libraries(rccl PRIVATE rocprofiler-register::rocprofiler-register)
set_target_properties(
rccl
PROPERTIES OUTPUT_NAME rccl
SOVERSION 1
VERSION 1.0)
rocp_register_strip_target(rccl)
add_library(rccl-invalid SHARED)
add_library(rccl::rccl-invalid ALIAS rccl-invalid)
target_sources(rccl-invalid PRIVATE rccl.cpp rccl.hpp)
target_include_directories(rccl-invalid
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
target_link_libraries(rccl-invalid PRIVATE rocprofiler-register::rocprofiler-register)
set_target_properties(
rccl-invalid
PROPERTIES OUTPUT_NAME rccl
SOVERSION 1
VERSION 1.0
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/invalid)
rocp_register_strip_target(rccl-invalid)
+149
Переглянути файл
@@ -0,0 +1,149 @@
#include "rccl.hpp"
#include <rocprofiler-register/rocprofiler-register.h>
#include <atomic>
#include <iostream>
#include <mutex>
#include <string_view>
#define ROCP_REG_VERSION \
ROCPROFILER_REGISTER_COMPUTE_VERSION_2(RCCL_API_TRACE_VERSION_MAJOR, \
RCCL_API_TRACE_VERSION_PATCH)
ROCPROFILER_REGISTER_DEFINE_IMPORT(rccl, 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 rccl
{
namespace
{
auto&
get_rccl_api_table_impl()
{
static auto _table = std::atomic<rcclApiFuncTable*>{ nullptr };
return _table;
}
void
register_profiler_impl()
{
static auto _const_api_table = rcclApiFuncTable{};
initialize_rccl_api_table(&_const_api_table);
// set this before any recursive opportunity arises
get_rccl_api_table_impl().exchange(&_const_api_table);
// create a copy of the api table for modification by registration
static auto _profiler_api_table = rcclApiFuncTable{};
copy_rccl_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("rccl",
&ROCPROFILER_REGISTER_IMPORT_FUNC(rccl),
ROCP_REG_VERSION,
&_profiler_api_table_v,
1,
&lib_id);
if(success == 0)
{
printf("[%s] rccl identifier %lu\n", ROCP_REG_FILE_NAME, lib_id.handle);
auto* _api_table = &_const_api_table;
if(!get_rccl_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 << "rccl 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 rccl API invokes a rccl 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
rcclApiFuncTable*
get_rccl_api_table()
{
register_profiler();
return get_rccl_api_table_impl().load(std::memory_order_relaxed);
}
void
rccl_init()
{
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
}
} // namespace rccl
extern "C" {
void
rccl_init(void)
{
rccl::get_rccl_api_table()->ncclGetVersion_fn({});
}
}
+46
Переглянути файл
@@ -0,0 +1,46 @@
#pragma once
#define RCCL_API_TRACE_VERSION_MAJOR 0
#define RCCL_API_TRACE_VERSION_PATCH 0
#include <cstddef>
#include <cstdint>
extern "C" {
// fake rccl function
typedef int ncclResult_t;
enum ncclDataType_t
{
};
ncclResult_t
ncclGetVersion(int* version) __attribute__((visibility("default")));
}
namespace rccl
{
struct rcclApiFuncTable
{
uint64_t size = 0;
decltype(::ncclGetVersion)* ncclGetVersion_fn = nullptr;
};
ncclResult_t
ncclGetVersion(int* version);
// populates rccl api table with function pointers
inline void
initialize_rccl_api_table(rcclApiFuncTable* dst)
{
dst->size = sizeof(rcclApiFuncTable);
dst->ncclGetVersion_fn = &::rccl::ncclGetVersion;
}
// copies the api table from src to dst
inline void
copy_rccl_api_table(rcclApiFuncTable* dst, const rcclApiFuncTable* src)
{
*dst = *src;
}
} // namespace rccl
+34
Переглянути файл
@@ -0,0 +1,34 @@
#
#
#
if(NOT TARGET rocprofiler-register::rocprofiler-register)
# find_package(rocprofiler-register REQUIRED)
endif()
add_library(rocdecode SHARED)
add_library(rocdecode::rocdecode ALIAS rocdecode)
target_sources(rocdecode PRIVATE rocdecode.cpp rocdecode.hpp)
target_include_directories(rocdecode PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
target_link_libraries(rocdecode PRIVATE rocprofiler-register::rocprofiler-register)
set_target_properties(
rocdecode
PROPERTIES OUTPUT_NAME rocdecode
SOVERSION 1
VERSION 1.0)
rocp_register_strip_target(rocdecode)
add_library(rocdecode-invalid SHARED)
add_library(rocdecode::rocdecode-invalid ALIAS rocdecode-invalid)
target_sources(rocdecode-invalid PRIVATE rocdecode.cpp rocdecode.hpp)
target_include_directories(rocdecode-invalid
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
target_link_libraries(rocdecode-invalid
PRIVATE rocprofiler-register::rocprofiler-register)
set_target_properties(
rocdecode-invalid
PROPERTIES OUTPUT_NAME rocdecode
SOVERSION 1
VERSION 1.0
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/invalid)
rocp_register_strip_target(rocdecode-invalid)
+171
Переглянути файл
@@ -0,0 +1,171 @@
// MIT License
//
// Copyright (c) 2023-2025 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 "rocdecode.hpp"
#include <rocprofiler-register/rocprofiler-register.h>
#include <atomic>
#include <iostream>
#include <mutex>
#include <string_view>
#define ROCP_REG_VERSION \
ROCPROFILER_REGISTER_COMPUTE_VERSION_2(ROCDECODE_RUNTIME_API_TABLE_MAJOR_VERSION, \
ROCDECODE_RUNTIME_API_TABLE_STEP_VERSION)
ROCPROFILER_REGISTER_DEFINE_IMPORT(rocdecode, 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 rocdecode
{
namespace
{
auto&
get_rocdecode_api_table_impl()
{
static auto _table = std::atomic<rocdecodeApiFuncTable*>{ nullptr };
return _table;
}
void
register_profiler_impl()
{
static auto _const_api_table = rocdecodeApiFuncTable{};
initialize_rocdecode_api_table(&_const_api_table);
// set this before any recursive opportunity arises
get_rocdecode_api_table_impl().exchange(&_const_api_table);
// create a copy of the api table for modification by registration
static auto _profiler_api_table = rocdecodeApiFuncTable{};
copy_rocdecode_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(
"rocdecode",
&ROCPROFILER_REGISTER_IMPORT_FUNC(rocdecode),
ROCP_REG_VERSION,
&_profiler_api_table_v,
1,
&lib_id);
if(success == 0)
{
printf("[%s] rocdecode identifier %lu\n", ROCP_REG_FILE_NAME, lib_id.handle);
auto* _api_table = &_const_api_table;
if(!get_rocdecode_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 << "rocdecode 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 rocdecode API invokes a rocdecode 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
rocdecodeApiFuncTable*
get_rocdecode_api_table()
{
register_profiler();
return get_rocdecode_api_table_impl().load(std::memory_order_relaxed);
}
void
rocdecode_init()
{
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
}
} // namespace rocdecode
extern "C" {
void
rocdecode_init(void)
{
rocdecode::get_rocdecode_api_table()->rocDecCreateDecoder_fn({}, {});
}
}
+77
Переглянути файл
@@ -0,0 +1,77 @@
// MIT License
//
// Copyright (c) 2023-2025 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma once
#define ROCDECODE_RUNTIME_API_TABLE_MAJOR_VERSION 0
#define ROCDECODE_RUNTIME_API_TABLE_STEP_VERSION 1
#include <cstddef>
#include <cstdint>
extern "C" {
// fake rccl function
enum rocDecStatus
{
};
enum rocDecDecoderHandle
{
};
enum RocDecoderCreateInfo
{
};
rocDecStatus
rocDecCreateDecoder(rocDecDecoderHandle* decoder_handle,
RocDecoderCreateInfo* decoder_create_info)
__attribute__((visibility("default")));
}
namespace rocdecode
{
struct rocdecodeApiFuncTable
{
uint64_t size = 0;
decltype(::rocDecCreateDecoder)* rocDecCreateDecoder_fn = nullptr;
};
rocDecStatus
rocDecCreateDecoder(rocDecDecoderHandle* decoder_handle,
RocDecoderCreateInfo* decoder_create_info);
// populates rocdecode api table with function pointers
inline void
initialize_rocdecode_api_table(rocdecodeApiFuncTable* dst)
{
dst->size = sizeof(rocdecodeApiFuncTable);
dst->rocDecCreateDecoder_fn = &::rocdecode::rocDecCreateDecoder;
}
// copies the api table from src to dst
inline void
copy_rocdecode_api_table(rocdecodeApiFuncTable* dst, const rocdecodeApiFuncTable* src)
{
*dst = *src;
}
} // namespace rocdecode
+33
Переглянути файл
@@ -0,0 +1,33 @@
#
#
#
if(NOT TARGET rocprofiler-register::rocprofiler-register)
# find_package(rocprofiler-register REQUIRED)
endif()
add_library(rocjpeg SHARED)
add_library(rocjpeg::rocjpeg ALIAS rocjpeg)
target_sources(rocjpeg PRIVATE rocjpeg.cpp rocjpeg.hpp)
target_include_directories(rocjpeg PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
target_link_libraries(rocjpeg PRIVATE rocprofiler-register::rocprofiler-register)
set_target_properties(
rocjpeg
PROPERTIES OUTPUT_NAME rocjpeg
SOVERSION 1
VERSION 1.0)
rocp_register_strip_target(rocjpeg)
add_library(rocjpeg-invalid SHARED)
add_library(rocjpeg::rocjpeg-invalid ALIAS rocjpeg-invalid)
target_sources(rocjpeg-invalid PRIVATE rocjpeg.cpp rocjpeg.hpp)
target_include_directories(rocjpeg-invalid
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
target_link_libraries(rocjpeg-invalid PRIVATE rocprofiler-register::rocprofiler-register)
set_target_properties(
rocjpeg-invalid
PROPERTIES OUTPUT_NAME rocjpeg
SOVERSION 1
VERSION 1.0
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/invalid)
rocp_register_strip_target(rocjpeg-invalid)
+171
Переглянути файл
@@ -0,0 +1,171 @@
// MIT License
//
// Copyright (c) 2023-2025 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 "rocjpeg.hpp"
#include <rocprofiler-register/rocprofiler-register.h>
#include <atomic>
#include <iostream>
#include <mutex>
#include <string_view>
#define ROCP_REG_VERSION \
ROCPROFILER_REGISTER_COMPUTE_VERSION_2(ROCDECODE_RUNTIME_API_TABLE_MAJOR_VERSION, \
ROCDECODE_RUNTIME_API_TABLE_STEP_VERSION)
ROCPROFILER_REGISTER_DEFINE_IMPORT(rocjpeg, 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 rocjpeg
{
namespace
{
auto&
get_rocjpeg_api_table_impl()
{
static auto _table = std::atomic<rocjpegApiFuncTable*>{ nullptr };
return _table;
}
void
register_profiler_impl()
{
static auto _const_api_table = rocjpegApiFuncTable{};
initialize_rocjpeg_api_table(&_const_api_table);
// set this before any recursive opportunity arises
get_rocjpeg_api_table_impl().exchange(&_const_api_table);
// create a copy of the api table for modification by registration
static auto _profiler_api_table = rocjpegApiFuncTable{};
copy_rocjpeg_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("rocjpeg",
&ROCPROFILER_REGISTER_IMPORT_FUNC(rocjpeg),
ROCP_REG_VERSION,
&_profiler_api_table_v,
1,
&lib_id);
if(success == 0)
{
printf("[%s] rocjpeg identifier %lu\n", ROCP_REG_FILE_NAME, lib_id.handle);
auto* _api_table = &_const_api_table;
if(!get_rocjpeg_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 << "rocjpeg 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 rocjpeg API invokes a rocjpeg 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
rocjpegApiFuncTable*
get_rocjpeg_api_table()
{
register_profiler();
return get_rocjpeg_api_table_impl().load(std::memory_order_relaxed);
}
void
rocjpeg_init()
{
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
}
} // namespace rocjpeg
extern "C" {
void
rocjpeg_init(void)
{
rocjpeg::get_rocjpeg_api_table()->rocJpegStreamCreate_fn({});
}
}
+71
Переглянути файл
@@ -0,0 +1,71 @@
// MIT License
//
// Copyright (c) 2023-2025 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#pragma once
#define ROCDECODE_RUNTIME_API_TABLE_MAJOR_VERSION 0
#define ROCDECODE_RUNTIME_API_TABLE_STEP_VERSION 1
#include <cstddef>
#include <cstdint>
extern "C" {
// fake rccl function
enum RocJpegStatus
{
};
enum RocJpegStreamHandle
{
};
RocJpegStatus
rocJpegStreamCreate(RocJpegStreamHandle* jpeg_stream_handle)
__attribute__((visibility("default")));
}
namespace rocjpeg
{
struct rocjpegApiFuncTable
{
uint64_t size = 0;
decltype(::rocJpegStreamCreate)* rocJpegStreamCreate_fn = nullptr;
};
RocJpegStatus
rocJpegStreamCreate(RocJpegStreamHandle* jpeg_stream_handle);
// populates rocjpeg api table with function pointers
inline void
initialize_rocjpeg_api_table(rocjpegApiFuncTable* dst)
{
dst->size = sizeof(rocjpegApiFuncTable);
dst->rocJpegStreamCreate_fn = &::rocjpeg::rocJpegStreamCreate;
}
// copies the api table from src to dst
inline void
copy_rocjpeg_api_table(rocjpegApiFuncTable* dst, const rocjpegApiFuncTable* src)
{
*dst = *src;
}
} // namespace rocjpeg
+31
Переглянути файл
@@ -0,0 +1,31 @@
#
# mock rocprofiler library
#
find_package(rocprofiler-register REQUIRED)
if(TARGET rocprofiler-register::rocprofiler-register-headers)
get_property(
rocp_reg_INCLUDE_DIR
TARGET rocprofiler-register::rocprofiler-register-headers
PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
else()
get_property(
rocp_reg_INCLUDE_DIR
TARGET rocprofiler-register::rocprofiler-register
PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
endif()
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}>
$<BUILD_INTERFACE:${rocp_reg_INCLUDE_DIR}>)
set_target_properties(
rocprofiler
PROPERTIES OUTPUT_NAME rocprofiler-sdk
SOVERSION 0
VERSION 0.0.0)
rocp_register_strip_target(rocprofiler)
+228
Переглянути файл
@@ -0,0 +1,228 @@
#include <rocprofiler-register/rocprofiler-register.h>
#include <amdhip/amdhip.hpp>
#include <hsa-runtime/hsa-runtime.hpp>
#include <rccl/rccl.hpp>
#include <rocdecode/rocdecode.hpp>
#include <rocjpeg/rocjpeg.hpp>
#include <roctx/roctx.hpp>
#include <dlfcn.h>
#include <pthread.h>
#include <sstream>
#include <stdexcept>
#include <string_view>
#include <tuple>
#include <vector>
#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__);
}
ncclResult_t
ncclGetVersion(int*)
{
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
return {};
}
rocDecStatus
rocDecCreateDecoder(rocDecDecoderHandle*, RocDecoderCreateInfo*)
{
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
return {};
}
RocJpegStatus
rocJpegStreamCreate(RocJpegStreamHandle* jpeg_stream_handle)
{
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
return {};
}
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);
}
using reginfo_vec_t = std::vector<rocprofiler_register_registration_info_t>;
bool
check_registration_info(const char* name,
uint64_t lib_version,
uint64_t num_tables,
const reginfo_vec_t& infovec)
{
for(const auto& itr : infovec)
{
if(std::string_view{ name } == std::string_view{ itr.common_name })
{
return std::tie(lib_version, num_tables) ==
std::tie(itr.lib_version, itr.api_table_length);
}
}
return false;
}
} // namespace rocprofiler
extern "C" {
int
rocprofiler_set_api_table(const char*, uint64_t, uint64_t, void**, uint64_t)
__attribute__((visibility("default")));
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);
auto* _tool_libs = std::getenv("ROCP_TOOL_LIBRARIES");
if(_tool_libs)
{
auto* _handle = dlopen(_tool_libs, RTLD_GLOBAL | RTLD_LAZY);
if(!_handle)
throw std::runtime_error{ std::string{ "error opening tool library " } +
_tool_libs };
auto* _sym = dlsym(_handle, "rocprofiler_configure");
if(!_sym)
throw std::runtime_error{ std::string{ "tool library " } +
std::string{ _tool_libs } +
" did not contain rocprofiler_configure symbol" };
}
auto registration_info = ::rocprofiler::reginfo_vec_t{};
{
auto* _handle =
dlopen("librocprofiler-register.so", RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
if(!_handle)
throw std::runtime_error{
"error opening librocprofiler-register.so library "
};
auto* _sym = dlsym(_handle, "rocprofiler_register_iterate_registration_info");
if(!_sym)
throw std::runtime_error{
"librocprofiler-register.so did not contain "
"rocprofiler_register_iterate_registration_info symbol"
};
auto _func = [](rocprofiler_register_registration_info_t* _info,
void* _vdata) -> int {
auto* _vec = static_cast<::rocprofiler::reginfo_vec_t*>(_vdata);
_vec->emplace_back(*_info);
return 0;
};
auto iterate_registration_info =
reinterpret_cast<decltype(&rocprofiler_register_iterate_registration_info)>(
_sym);
iterate_registration_info(_func, &registration_info);
}
using hip_table_t = hip::HipApiTable;
using hsa_table_t = hsa::HsaApiTable;
using roctx_table_t = roctx::ROCTxApiTable;
using rccl_table_t = rccl::rcclApiFuncTable;
using rocdecode_table_t = rocdecode::rocdecodeApiFuncTable;
using rocjpeg_table_t = rocjpeg::rocjpegApiFuncTable;
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;
}
else if(std::string_view{ name } == "rccl")
{
rccl_table_t* _table = static_cast<rccl_table_t*>(tables[0]);
_table->ncclGetVersion_fn = &::rocprofiler::ncclGetVersion;
}
else if(std::string_view{ name } == "rocdecode")
{
rocdecode_table_t* _table = static_cast<rocdecode_table_t*>(tables[0]);
_table->rocDecCreateDecoder_fn = &rocprofiler::rocDecCreateDecoder;
}
else if(std::string_view{ name } == "rocjpeg")
{
rocjpeg_table_t* _table = static_cast<rocjpeg_table_t*>(tables[0]);
_table->rocJpegStreamCreate_fn = &rocprofiler::rocJpegStreamCreate;
}
}
if(!::rocprofiler::check_registration_info(
name, lib_version, num_tables, registration_info))
{
auto ss = std::stringstream{};
ss << "no matching registration info for " << name << " "
<< " version " << lib_version << " (# tables = " << num_tables << ")";
throw std::runtime_error{ ss.str() };
}
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
Переглянути файл
@@ -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
Переглянути файл
@@ -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
Переглянути файл
@@ -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
Переглянути файл
@@ -0,0 +1,3 @@
#
#
#
+72
Переглянути файл
@@ -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
Переглянути файл
@@ -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
Переглянути файл
@@ -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
Переглянути файл
@@ -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
Переглянути файл
@@ -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;
}