Add 'projects/rocprofiler-register/' from commit '37d7d920364c8b10ab592ff79e1c6811d114e6fa'
git-subtree-dir: projects/rocprofiler-register git-subtree-mainline:2e5bcec303git-subtree-split:37d7d92036
Цей коміт міститься в:
@@ -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
|
||||
@@ -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
|
||||
...
|
||||
@@ -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'
|
||||
...
|
||||
@@ -0,0 +1,318 @@
|
||||
parse:
|
||||
additional_commands:
|
||||
rocprofiler_register_checkout_git_submodule:
|
||||
flags:
|
||||
- RECURSIVE
|
||||
kwargs:
|
||||
RELATIVE_PATH: '*'
|
||||
WORKING_DIRECTORY: '*'
|
||||
TEST_FILE: '*'
|
||||
REPO_URL: '*'
|
||||
REPO_BRANCH: '*'
|
||||
ADDITIONAL_COMMANDS: '*'
|
||||
rocprofiler_register_save_variables:
|
||||
kwargs:
|
||||
VARIABLES: '*'
|
||||
CONDITION: '*'
|
||||
rocprofiler_register_restore_variables:
|
||||
kwargs:
|
||||
VARIABLES: '*'
|
||||
CONDITION: '*'
|
||||
rocprofiler_register_target_compile_options:
|
||||
flags:
|
||||
- BUILD_INTERFACE
|
||||
- FORCE
|
||||
kwargs:
|
||||
PUBLIC: '*'
|
||||
PRIVATE: '*'
|
||||
INTERFACE: '*'
|
||||
LANGUAGES: '*'
|
||||
LINK_LANGUAGES: '*'
|
||||
rocprofiler_register_add_test:
|
||||
flags:
|
||||
- SKIP_BASELINE
|
||||
- SKIP_SAMPLING
|
||||
- SKIP_REWRITE
|
||||
- SKIP_RUNTIME
|
||||
kwargs:
|
||||
NAME: '*'
|
||||
TARGET: '*'
|
||||
MPI: '*'
|
||||
GPU: '*'
|
||||
NUM_PROCS: '*'
|
||||
REWRITE_TIMEOUT: '*'
|
||||
RUNTIME_TIMEOUT: '*'
|
||||
SAMPLING_TIMEOUT: '*'
|
||||
SAMPLING_ARGS: '*'
|
||||
REWRITE_ARGS: '*'
|
||||
RUNTIME_ARGS: '*'
|
||||
RUN_ARGS: '*'
|
||||
ENVIRONMENT: '*'
|
||||
LABELS: '*'
|
||||
PROPERTIES: '*'
|
||||
SAMPLING_PASS_REGEX: '*'
|
||||
SAMPLING_FAIL_REGEX: '*'
|
||||
RUNTIME_PASS_REGEX: '*'
|
||||
RUNTIME_FAIL_REGEX: '*'
|
||||
REWRITE_PASS_REGEX: '*'
|
||||
REWRITE_FAIL_REGEX: '*'
|
||||
BASELINE_PASS_REGEX: '*'
|
||||
BASELINE_FAIL_REGEX: '*'
|
||||
REWRITE_RUN_PASS_REGEX: '*'
|
||||
REWRITE_RUN_FAIL_REGEX: '*'
|
||||
rocprofiler_register_add_causal_test:
|
||||
flags:
|
||||
- SKIP_BASELINE
|
||||
kwargs:
|
||||
NAME: '*'
|
||||
TARGET: '*'
|
||||
CAUSAL_TIMEOUT: '*'
|
||||
CAUSAL_VALIDATE_TIMEOUT: '*'
|
||||
CAUSAL_MODE: '*'
|
||||
CAUSAL_ARGS: '*'
|
||||
CAUSAL_VALIDATE_ARGS: '*'
|
||||
RUNTIME_ARGS: '*'
|
||||
RUN_ARGS: '*'
|
||||
ENVIRONMENT: '*'
|
||||
LABELS: '*'
|
||||
PROPERTIES: '*'
|
||||
CAUSAL_PASS_REGEX: '*'
|
||||
CAUSAL_FAIL_REGEX: '*'
|
||||
BASELINE_PASS_REGEX: '*'
|
||||
BASELINE_FAIL_REGEX: '*'
|
||||
CAUSAL_VALIDATE_PASS_REGEX: '*'
|
||||
CAUSAL_VALIDATE_FAIL_REGEX: '*'
|
||||
rocprofiler_register_target_compile_definitions:
|
||||
kwargs:
|
||||
PUBLIC: '*'
|
||||
PRIVATE: '*'
|
||||
INTERFACE: '*'
|
||||
rocprofiler_register_add_bin_test:
|
||||
flags:
|
||||
- WILL_FAIL
|
||||
kwargs:
|
||||
NAME: '*'
|
||||
ARGS: '*'
|
||||
LABELS: '*'
|
||||
TARGET: '*'
|
||||
DEPENDS: '*'
|
||||
COMMAND: '*'
|
||||
TIMEOUT: '*'
|
||||
PROPERTIES: '*'
|
||||
ENVIRONMENT: '*'
|
||||
WORKING_DIRECTORY: '*'
|
||||
PASS_REGEX: '*'
|
||||
FAIL_REGEX: '*'
|
||||
SKIP_REGEX: '*'
|
||||
rocprofiler_register_add_python_test:
|
||||
flags:
|
||||
- STANDALONE
|
||||
kwargs:
|
||||
NAME: '*'
|
||||
FILE: '*'
|
||||
TIMEOUT: '*'
|
||||
PROFILE_ARGS: '*'
|
||||
RUN_ARGS: '*'
|
||||
ENVIRONMENT: '*'
|
||||
LABELS: '*'
|
||||
DEPENDS: '*'
|
||||
COMMAND: '*'
|
||||
PROPERTIES: '*'
|
||||
PYTHON_EXECUTABLE: '*'
|
||||
PYTHON_VERSION: '*'
|
||||
PASS_REGEX: '*'
|
||||
FAIL_REGEX: '*'
|
||||
SKIP_REGEX: '*'
|
||||
rocprofiler_register_add_python_validation_test:
|
||||
kwargs:
|
||||
NAME: '*'
|
||||
ARGS: '*'
|
||||
PERFETTO_FILE: '*'
|
||||
PERFETTO_METRIC: '*'
|
||||
TIMEMORY_FILE: '*'
|
||||
TIMEMORY_METRIC: '*'
|
||||
rocm_version_message:
|
||||
flags:
|
||||
- STATUS
|
||||
- WARNING
|
||||
- SEND_ERROR
|
||||
- FATAL_ERROR
|
||||
- AUTHOR_WARNING
|
||||
rocprofiler_register_find_python:
|
||||
flags:
|
||||
- REQUIRED
|
||||
- QUIET
|
||||
kwargs:
|
||||
VERSION: '*'
|
||||
ROOT_DIR: '*'
|
||||
COMPONENTS: '*'
|
||||
rocprofiler_register_python_console_script:
|
||||
kwargs:
|
||||
VERSION: '*'
|
||||
ROOT_DIR: '*'
|
||||
rocprofiler_register_pybind11_add_module:
|
||||
flags:
|
||||
- MODULE
|
||||
- SHARED
|
||||
- EXCLUDE_FROM_ALL
|
||||
- NO_EXTRAS
|
||||
- SYSTEM
|
||||
- THIN_LTO
|
||||
- LTO
|
||||
kwargs:
|
||||
PYTHON_VERSION: '*'
|
||||
CXX_STANDARD: '*'
|
||||
VISIBILITY: '*'
|
||||
rocprofiler_register_directory:
|
||||
flags:
|
||||
- MKDIR
|
||||
- FAIL
|
||||
kwargs:
|
||||
PREFIX: '*'
|
||||
OUTPUT_VARIABLE: '*'
|
||||
WORKING_DIRECTORY: '*'
|
||||
PATHS: '*'
|
||||
rocprofiler_register_check_python_dirs_and_versions:
|
||||
flags:
|
||||
- UNSET
|
||||
- FAIL
|
||||
kwargs:
|
||||
RESULT_VARIABLE: '*'
|
||||
OUTPUT_VARIABLE: '*'
|
||||
rocprofiler_register_find_static_library:
|
||||
flags:
|
||||
- NO_CACHE
|
||||
- REQUIRED
|
||||
- NO_DEFAULT_PATH
|
||||
- NO_PACKAGE_ROOT_PATH
|
||||
- NO_CMAKE_PATH
|
||||
- NO_CMAKE_ENVIRONMENT_PATH
|
||||
- NO_SYSTEM_ENVIRONMENT_PATH
|
||||
- CMAKE_FIND_ROOT_PATH_BOTH
|
||||
- ONLY_CMAKE_FIND_ROOT_PATH
|
||||
- NO_CMAKE_FIND_ROOT_PATH
|
||||
kwargs:
|
||||
NAMES: '*'
|
||||
NAMES_PER_DIR: '*'
|
||||
HINTS: '*'
|
||||
PATHS: '*'
|
||||
PATH_SUFFIXES: '*'
|
||||
DOC: '*'
|
||||
rocprofiler_register_find_shared_library:
|
||||
flags:
|
||||
- NO_CACHE
|
||||
- REQUIRED
|
||||
- NO_DEFAULT_PATH
|
||||
- NO_PACKAGE_ROOT_PATH
|
||||
- NO_CMAKE_PATH
|
||||
- NO_CMAKE_ENVIRONMENT_PATH
|
||||
- NO_SYSTEM_ENVIRONMENT_PATH
|
||||
- CMAKE_FIND_ROOT_PATH_BOTH
|
||||
- ONLY_CMAKE_FIND_ROOT_PATH
|
||||
- NO_CMAKE_FIND_ROOT_PATH
|
||||
kwargs:
|
||||
NAMES: '*'
|
||||
NAMES_PER_DIR: '*'
|
||||
HINTS: '*'
|
||||
PATHS: '*'
|
||||
PATH_SUFFIXES: '*'
|
||||
DOC: '*'
|
||||
rocprofiler_register_causal_example_executable:
|
||||
kwargs:
|
||||
TAG: '*'
|
||||
SOURCES: '*'
|
||||
DEFINITIONS: '*'
|
||||
LINK_LIBRARIES: '*'
|
||||
INCLUDE_DIRECTORIES: '*'
|
||||
rocprofiler_register_add_validation_test:
|
||||
kwargs:
|
||||
NAME: '*'
|
||||
ARGS: '*'
|
||||
LABELS: '*'
|
||||
TIMEOUT: '*'
|
||||
DEPENDS: '*'
|
||||
PROPERTIES: '*'
|
||||
PASS_REGEX: '*'
|
||||
FAIL_REGEX: '*'
|
||||
SKIP_REGEX: '*'
|
||||
ENVIRONMENT: '*'
|
||||
PERFETTO_FILE: '*'
|
||||
PERFETTO_METRIC: '*'
|
||||
TIMEMORY_FILE: '*'
|
||||
TIMEMORY_METRIC: '*'
|
||||
rocp_register_test_executable:
|
||||
kwargs:
|
||||
SECURE: '*'
|
||||
SOURCES: '*'
|
||||
LIBRARIES: '*'
|
||||
CORE_PASS_REGEX: '*'
|
||||
CORE_FAIL_REGEX: '*'
|
||||
PRELOAD_PASS_REGEX: '*'
|
||||
PRELOAD_FAIL_REGEX: '*'
|
||||
WRAP_PASS_REGEX: '*'
|
||||
WRAP_FAIL_REGEX: '*'
|
||||
PRELOAD_WRAP_PASS_REGEX: '*'
|
||||
PRELOAD_WRAP_FAIL_REGEX: '*'
|
||||
override_spec: {}
|
||||
vartags: []
|
||||
proptags: []
|
||||
format:
|
||||
disable: false
|
||||
line_width: 90
|
||||
tab_size: 4
|
||||
use_tabchars: false
|
||||
fractional_tab_policy: use-space
|
||||
max_subgroups_hwrap: 2
|
||||
max_pargs_hwrap: 8
|
||||
max_rows_cmdline: 2
|
||||
separate_ctrl_name_with_space: false
|
||||
separate_fn_name_with_space: false
|
||||
dangle_parens: false
|
||||
dangle_align: child
|
||||
min_prefix_chars: 4
|
||||
max_prefix_chars: 10
|
||||
max_lines_hwrap: 2
|
||||
line_ending: unix
|
||||
command_case: lower
|
||||
keyword_case: upper
|
||||
always_wrap: []
|
||||
enable_sort: true
|
||||
autosort: false
|
||||
require_valid_layout: false
|
||||
layout_passes: {}
|
||||
markup:
|
||||
bullet_char: '*'
|
||||
enum_char: .
|
||||
first_comment_is_literal: true
|
||||
literal_comment_pattern: ^#
|
||||
fence_pattern: ^\s*([`~]{3}[`~]*)(.*)$
|
||||
ruler_pattern: ^\s*[^\w\s]{3}.*[^\w\s]{3}$
|
||||
explicit_trailing_pattern: '#<'
|
||||
hashruler_min_length: 10
|
||||
canonicalize_hashrulers: true
|
||||
enable_markup: true
|
||||
lint:
|
||||
disabled_codes: []
|
||||
function_pattern: '[0-9a-z_]+'
|
||||
macro_pattern: '[0-9A-Z_]+'
|
||||
global_var_pattern: '[A-Z][0-9A-Z_]+'
|
||||
internal_var_pattern: _[A-Z][0-9A-Z_]+
|
||||
local_var_pattern: '[a-z][a-z0-9_]+'
|
||||
private_var_pattern: _[0-9a-z_]+
|
||||
public_var_pattern: '[A-Z][0-9A-Z_]+'
|
||||
argument_var_pattern: '[a-z][a-z0-9_]+'
|
||||
keyword_pattern: '[A-Z][0-9A-Z_]+'
|
||||
max_conditionals_custom_parser: 2
|
||||
min_statement_spacing: 1
|
||||
max_statement_spacing: 2
|
||||
max_returns: 6
|
||||
max_branches: 12
|
||||
max_arguments: 5
|
||||
max_localvars: 15
|
||||
max_statements: 50
|
||||
encode:
|
||||
emit_byteorder_mark: false
|
||||
input_encoding: utf-8
|
||||
output_encoding: utf-8
|
||||
misc:
|
||||
per_command: {}
|
||||
@@ -0,0 +1,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}
|
||||
@@ -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
|
||||
@@ -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}}
|
||||
@@ -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 || '' }}
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -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.
|
||||
@@ -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
|
||||
```
|
||||
@@ -0,0 +1 @@
|
||||
0.5.0
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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()
|
||||
@@ -0,0 +1,352 @@
|
||||
# include guard
|
||||
# ########################################################################################
|
||||
#
|
||||
# Compilers
|
||||
#
|
||||
# ########################################################################################
|
||||
#
|
||||
# sets (cached):
|
||||
#
|
||||
# CMAKE_C_COMPILER_IS_<TYPE> CMAKE_CXX_COMPILER_IS_<TYPE>
|
||||
#
|
||||
# where TYPE is: - GNU - CLANG - INTEL - INTEL_ICC - INTEL_ICPC - PGI - XLC - HP_ACC -
|
||||
# MIPS - MSVC
|
||||
#
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCSourceCompiles)
|
||||
include(CheckCSourceRuns)
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(CheckCXXSourceCompiles)
|
||||
include(CheckCXXSourceRuns)
|
||||
|
||||
include(CMakeParseArguments)
|
||||
|
||||
include(rocprofiler_register_utilities)
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# macro converting string to list
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
macro(ROCPROFILER_REGISTER_TO_LIST _VAR _STR)
|
||||
string(REPLACE " " " " ${_VAR} "${_STR}")
|
||||
string(REPLACE " " ";" ${_VAR} "${_STR}")
|
||||
endmacro()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# macro converting string to list
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
macro(ROCPROFILER_REGISTER_TO_STRING _VAR _STR)
|
||||
string(REPLACE ";" " " ${_VAR} "${_STR}")
|
||||
endmacro()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# Macro to add to string
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
macro(add _VAR _FLAG)
|
||||
if(NOT "${_FLAG}" STREQUAL "")
|
||||
if("${${_VAR}}" STREQUAL "")
|
||||
set(${_VAR} "${_FLAG}")
|
||||
else()
|
||||
set(${_VAR} "${${_VAR}} ${_FLAG}")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# call before running check_{c,cxx}_compiler_flag
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
macro(ROCPROFILER_REGISTER_BEGIN_FLAG_CHECK)
|
||||
if(ROCPROFILER_REGISTER_QUIET_CONFIG)
|
||||
if(NOT DEFINED CMAKE_REQUIRED_QUIET)
|
||||
set(CMAKE_REQUIRED_QUIET OFF)
|
||||
endif()
|
||||
rocprofiler_register_save_variables(FLAG_CHECK VARIABLES CMAKE_REQUIRED_QUIET)
|
||||
set(CMAKE_REQUIRED_QUIET ON)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# call after running check_{c,cxx}_compiler_flag
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
macro(ROCPROFILER_REGISTER_END_FLAG_CHECK)
|
||||
if(ROCPROFILER_REGISTER_QUIET_CONFIG)
|
||||
rocprofiler_register_restore_variables(FLAG_CHECK VARIABLES CMAKE_REQUIRED_QUIET)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# check flag
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
function(ROCPROFILER_REGISTER_TARGET_COMPILE_OPTIONS _TARG_TARGET)
|
||||
cmake_parse_arguments(_TARG "BUILD_INTERFACE;FORCE" ""
|
||||
"PUBLIC;INTERFACE;PRIVATE;LANGUAGES;LINK_LANGUAGES" ${ARGN})
|
||||
|
||||
if(NOT _TARG_MODE)
|
||||
set(_TARG_MODE INTERFACE)
|
||||
endif()
|
||||
|
||||
get_property(_ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||
set(_SUPPORTED_LANGUAGES "C" "CXX")
|
||||
|
||||
if(NOT _TARG_LANGUAGES)
|
||||
foreach(_LANG ${_ENABLED_LANGUAGES})
|
||||
if(_LANG IN_LIST _SUPPORTED_LANGUAGES)
|
||||
list(APPEND _TARG_LANGUAGES ${_LANG})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
string(TOLOWER "_${_TARG_TARGET}" _TARG_TARGET_LC)
|
||||
|
||||
function(rocprofiler_register_target_compile_option_impl _TARGET_IMPL
|
||||
_TARGET_MODE_IMPL _TARGET_LANG_IMPL _TARGET_FLAG_IMPL)
|
||||
if(_TARG_BUILD_INTERFACE)
|
||||
target_compile_options(
|
||||
${_TARGET_IMPL}
|
||||
${_TARGET_MODE_IMPL}
|
||||
$<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:${_TARGET_LANG_IMPL}>:${_TARGET_FLAG_IMPL}>>
|
||||
)
|
||||
else()
|
||||
target_compile_options(
|
||||
${_TARGET_IMPL} ${_TARGET_MODE_IMPL}
|
||||
$<$<COMPILE_LANGUAGE:${_TARGET_LANG_IMPL}>:${_TARGET_FLAG_IMPL}>)
|
||||
endif()
|
||||
|
||||
if("${_TARGET_LANG_IMPL}" IN_LIST _TARG_LINK_LANGUAGES)
|
||||
if(_TARG_BUILD_INTERFACE)
|
||||
target_link_options(
|
||||
${_TARGET_IMPL}
|
||||
${_TARGET_MODE_IMPL}
|
||||
$<BUILD_INTERFACE:$<$<LINK_LANGUAGE:${_TARGET_LANG_IMPL}>:${_TARGET_FLAG_IMPL}>>
|
||||
)
|
||||
else()
|
||||
target_link_options(
|
||||
${_TARGET_IMPL} ${_TARGET_MODE_IMPL}
|
||||
$<$<LINK_LANGUAGE:${_TARGET_LANG_IMPL}>:${_TARGET_FLAG_IMPL}>)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(rocprofiler_register_target_compile_option_patch_name _P_LANG _P_IN _P_OUT)
|
||||
string(TOLOWER "${_P_LANG}" _P_LANG)
|
||||
string(REGEX REPLACE "^(/|-)" "${_P_LANG}${_TARG_TARGET_LC}_" _NAME "${_P_IN}")
|
||||
string(REPLACE "-" "_" _NAME "${_NAME}")
|
||||
string(REPLACE " " "_" _NAME "${_NAME}")
|
||||
string(REPLACE "=" "_" _NAME "${_NAME}")
|
||||
set(${_P_OUT}
|
||||
"${_NAME}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if(NOT DEFINED rocprofiler_register_c_error AND NOT DEFINED
|
||||
rocprofiler_register_cxx_error)
|
||||
rocprofiler_register_begin_flag_check()
|
||||
check_c_compiler_flag("-Werror" c_rocprofiler_register_werror)
|
||||
check_cxx_compiler_flag("-Werror" cxx_rocprofiler_register_werror)
|
||||
rocprofiler_register_end_flag_check()
|
||||
endif()
|
||||
|
||||
foreach(_TARG_MODE PUBLIC INTERFACE PRIVATE)
|
||||
foreach(_FLAG ${_TARG_${_TARG_MODE}})
|
||||
foreach(_LANG ${_TARG_LANGUAGES})
|
||||
unset(FLAG_NAME)
|
||||
rocprofiler_register_target_compile_option_patch_name(${_LANG} "${_FLAG}"
|
||||
FLAG_NAME)
|
||||
|
||||
if(_TARG_FORCE)
|
||||
set(${FLAG_NAME}
|
||||
1
|
||||
CACHE INTERNAL "${_LANG} flag: ${_FLAG}")
|
||||
else()
|
||||
rocprofiler_register_begin_flag_check()
|
||||
|
||||
if("${_LANG}" STREQUAL "C")
|
||||
if(c_rocprofiler_register_werror)
|
||||
check_c_compiler_flag("${_FLAG} -Werror" ${FLAG_NAME})
|
||||
else()
|
||||
check_c_compiler_flag("${_FLAG}" ${FLAG_NAME})
|
||||
endif()
|
||||
elseif("${_LANG}" STREQUAL "CXX")
|
||||
if(cxx_rocprofiler_register_werror)
|
||||
check_cxx_compiler_flag("${_FLAG} -Werror" ${FLAG_NAME})
|
||||
else()
|
||||
check_cxx_compiler_flag("${_FLAG}" ${FLAG_NAME})
|
||||
endif()
|
||||
else()
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"rocprofiler_register_target_compile_option :: unknown language: ${_LANG}"
|
||||
)
|
||||
endif()
|
||||
|
||||
rocprofiler_register_end_flag_check()
|
||||
endif()
|
||||
|
||||
if(${FLAG_NAME})
|
||||
rocprofiler_register_target_compile_option_impl(
|
||||
${_TARG_TARGET} ${_TARG_MODE} ${_LANG} "${_FLAG}")
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# add to any language
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
function(ROCPROFILER_REGISTER_TARGET_USER_FLAGS _TARGET _LANGUAGE)
|
||||
|
||||
set(_FLAGS ${${_LANGUAGE}FLAGS} $ENV{${_LANGUAGE}FLAGS} ${${_LANGUAGE}_FLAGS}
|
||||
$ENV{${_LANGUAGE}_FLAGS})
|
||||
|
||||
string(REPLACE " " ";" _FLAGS "${_FLAGS}")
|
||||
|
||||
set(${PROJECT_NAME}_${_LANGUAGE}_FLAGS
|
||||
${${PROJECT_NAME}_${_LANGUAGE}_FLAGS} ${_FLAGS}
|
||||
PARENT_SCOPE)
|
||||
|
||||
set(${PROJECT_NAME}_${_LANGUAGE}_COMPILE_OPTIONS
|
||||
${${PROJECT_NAME}_${_LANGUAGE}_COMPILE_OPTIONS} ${_FLAGS}
|
||||
PARENT_SCOPE)
|
||||
|
||||
target_compile_options(${_TARGET}
|
||||
INTERFACE $<$<COMPILE_LANGUAGE:${_LANGUAGE}>:${_FLAGS}>)
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# add compiler definition
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
function(ROCPROFILER_REGISTER_TARGET_COMPILE_DEFINITIONS _TARG _VIS)
|
||||
foreach(_DEF ${ARGN})
|
||||
if(NOT "${_DEF}" MATCHES "[A-Za-z_]+=.*" AND "${_DEF}" MATCHES
|
||||
"^ROCPROFILER_REGISTER_")
|
||||
set(_DEF "${_DEF}=1")
|
||||
endif()
|
||||
target_compile_definitions(${_TARG} ${_VIS} $<$<COMPILE_LANGUAGE:CXX>:${_DEF}>)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# determine compiler types for each language
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||
foreach(LANG C CXX HIP CUDA)
|
||||
|
||||
if(NOT DEFINED CMAKE_${LANG}_COMPILER)
|
||||
set(CMAKE_${LANG}_COMPILER "")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_${LANG}_COMPILER_ID)
|
||||
set(CMAKE_${LANG}_COMPILER_ID "")
|
||||
endif()
|
||||
|
||||
function(SET_COMPILER_VAR VAR _BOOL)
|
||||
set(CMAKE_${LANG}_COMPILER_IS_${VAR}
|
||||
${_BOOL}
|
||||
CACHE INTERNAL "CMake ${LANG} compiler identification (${VAR})" FORCE)
|
||||
mark_as_advanced(CMAKE_${LANG}_COMPILER_IS_${VAR})
|
||||
endfunction()
|
||||
|
||||
if(("${LANG}" STREQUAL "C" AND CMAKE_COMPILER_IS_GNUCC)
|
||||
OR ("${LANG}" STREQUAL "CXX" AND CMAKE_COMPILER_IS_GNUCXX))
|
||||
|
||||
# GNU compiler
|
||||
set_compiler_var(GNU 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER MATCHES "icc.*")
|
||||
|
||||
# Intel icc compiler
|
||||
set_compiler_var(INTEL 1)
|
||||
set_compiler_var(INTEL_ICC 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER MATCHES "icpc.*")
|
||||
|
||||
# Intel icpc compiler
|
||||
set_compiler_var(INTEL 1)
|
||||
set_compiler_var(INTEL_ICPC 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "AppleClang")
|
||||
|
||||
# Clang/LLVM compiler
|
||||
set_compiler_var(CLANG 1)
|
||||
set_compiler_var(APPLE_CLANG 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "Clang")
|
||||
|
||||
# Clang/LLVM compiler
|
||||
set_compiler_var(CLANG 1)
|
||||
|
||||
# HIP Clang compiler
|
||||
if(CMAKE_${LANG}_COMPILER MATCHES "hipcc")
|
||||
set_compiler_var(HIPCC 1)
|
||||
endif()
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "PGI")
|
||||
|
||||
# PGI compiler
|
||||
set_compiler_var(PGI 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER MATCHES "xlC" AND UNIX)
|
||||
|
||||
# IBM xlC compiler
|
||||
set_compiler_var(XLC 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER MATCHES "aCC" AND UNIX)
|
||||
|
||||
# HP aC++ compiler
|
||||
set_compiler_var(HP_ACC 1)
|
||||
|
||||
elseif(
|
||||
CMAKE_${LANG}_COMPILER MATCHES "CC"
|
||||
AND CMAKE_SYSTEM_NAME MATCHES "IRIX"
|
||||
AND UNIX)
|
||||
|
||||
# IRIX MIPSpro CC Compiler
|
||||
set_compiler_var(MIPS 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "Intel")
|
||||
|
||||
set_compiler_var(INTEL 1)
|
||||
|
||||
set(CTYPE ICC)
|
||||
if("${LANG}" STREQUAL "CXX")
|
||||
set(CTYPE ICPC)
|
||||
endif()
|
||||
|
||||
set_compiler_var(INTEL_${CTYPE} 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER MATCHES "MSVC")
|
||||
|
||||
# Windows Visual Studio compiler
|
||||
set_compiler_var(MSVC 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "NVIDIA")
|
||||
|
||||
# NVCC
|
||||
set_compiler_var(NVIDIA 1)
|
||||
|
||||
endif()
|
||||
|
||||
# set other to no
|
||||
foreach(
|
||||
TYPE
|
||||
GNU
|
||||
INTEL
|
||||
INTEL_ICC
|
||||
INTEL_ICPC
|
||||
APPLE_CLANG
|
||||
CLANG
|
||||
PGI
|
||||
XLC
|
||||
HP_ACC
|
||||
MIPS
|
||||
MSVC
|
||||
NVIDIA
|
||||
HIPCC)
|
||||
if(NOT DEFINED CMAKE_${LANG}_COMPILER_IS_${TYPE})
|
||||
set_compiler_var(${TYPE} 0)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
endforeach()
|
||||
@@ -0,0 +1,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)
|
||||
@@ -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()
|
||||
@@ -0,0 +1,34 @@
|
||||
#
|
||||
#
|
||||
# Forward declaration of all INTERFACE targets
|
||||
#
|
||||
#
|
||||
|
||||
include(rocprofiler_register_utilities)
|
||||
|
||||
#
|
||||
# interfaces for build flags
|
||||
#
|
||||
rocprofiler_register_add_interface_library(
|
||||
rocprofiler-register-headers
|
||||
"Provides minimal set of include flags to compile with rocprofiler-register")
|
||||
rocprofiler_register_add_interface_library(
|
||||
rocprofiler-register-build-flags
|
||||
"Provides generalized build flags for rocprofiler-register" INTERNAL)
|
||||
rocprofiler_register_add_interface_library(rocprofiler-register-threading
|
||||
"Enables multithreading support" INTERNAL)
|
||||
rocprofiler_register_add_interface_library(
|
||||
rocprofiler-register-developer-flags
|
||||
"Compiler flags for developers (more warnings, etc.)" INTERNAL)
|
||||
rocprofiler_register_add_interface_library(rocprofiler-register-memcheck "Sanitizer"
|
||||
INTERNAL)
|
||||
|
||||
#
|
||||
# interfaces for libraries
|
||||
#
|
||||
rocprofiler_register_add_interface_library(
|
||||
rocprofiler-register-dl "Build flags for dynamic linking library" INTERNAL)
|
||||
rocprofiler_register_add_interface_library(rocprofiler-register-rt
|
||||
"Build flags for runtime library" INTERNAL)
|
||||
rocprofiler_register_add_interface_library(rocprofiler-register-stdcxxfs
|
||||
"C++ filesystem library" INTERNAL)
|
||||
@@ -0,0 +1,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()
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
@@ -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
|
||||
)/
|
||||
)
|
||||
'''
|
||||
@@ -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
|
||||
@@ -0,0 +1,8 @@
|
||||
#
|
||||
# Samples
|
||||
#
|
||||
project(rocprofiler-register-samples LANGUAGES C CXX)
|
||||
|
||||
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME sample)
|
||||
|
||||
add_subdirectory(library-implementation)
|
||||
@@ -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)
|
||||
@@ -0,0 +1,120 @@
|
||||
#include "demo.hpp"
|
||||
|
||||
#include <rocprofiler-register/rocprofiler-register.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
|
||||
#define ROCP_REG_VERSION \
|
||||
ROCPROFILER_REGISTER_COMPUTE_VERSION_3( \
|
||||
HIP_VERSION_MAJOR, HIP_VERSION_MINOR, HIP_VERSION_PATCH)
|
||||
|
||||
ROCPROFILER_REGISTER_DEFINE_IMPORT(hip, ROCP_REG_VERSION)
|
||||
|
||||
namespace hip
|
||||
{
|
||||
namespace
|
||||
{
|
||||
auto&
|
||||
get_hip_api_table_impl()
|
||||
{
|
||||
static auto _table = std::atomic<HipApiTable*>{ nullptr };
|
||||
return _table;
|
||||
}
|
||||
|
||||
void
|
||||
register_profiler_impl()
|
||||
{
|
||||
static auto _const_api_table = HipApiTable{};
|
||||
initialize_hip_api_table(&_const_api_table);
|
||||
|
||||
// set this before any recursive opportunity arises
|
||||
get_hip_api_table_impl().exchange(&_const_api_table);
|
||||
|
||||
// create a copy of the api table for modification by registration
|
||||
static auto _profiler_api_table = HipApiTable{};
|
||||
copy_hip_api_table(&_profiler_api_table, &_const_api_table);
|
||||
|
||||
void* _profiler_api_table_v = static_cast<void*>(&_profiler_api_table);
|
||||
|
||||
auto lib_id = rocprofiler_register_library_indentifier_t{};
|
||||
auto success =
|
||||
rocprofiler_register_library_api_table("hip",
|
||||
&ROCPROFILER_REGISTER_IMPORT_FUNC(hip),
|
||||
ROCP_REG_VERSION,
|
||||
&_profiler_api_table_v,
|
||||
1,
|
||||
&lib_id);
|
||||
|
||||
if(success == 0)
|
||||
{
|
||||
auto* _api_table = &_const_api_table;
|
||||
if(!get_hip_api_table_impl().compare_exchange_strong(_api_table,
|
||||
&_profiler_api_table))
|
||||
{
|
||||
// with the current impl, if we ever get here, someone is calling one the
|
||||
// functions in this anonymous namespace that shouldn't
|
||||
std::cerr
|
||||
<< "register_profiler_impl expected the API table to be the internal "
|
||||
"implementation and yet it is not. something went wrong.\n";
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
register_profiler()
|
||||
{
|
||||
// this registration scheme is designed to minimize overhead once
|
||||
// registered (only pay cost of checking atomic boolean)
|
||||
// once the profiler is registered. If the library has not
|
||||
// been registered and two or more threads try to register concurrently
|
||||
// the first thread to acquire the lock below, will block the
|
||||
// threads until registration is complete. However,
|
||||
// if the same thread performing the registration re-enters this function
|
||||
// i.e. this library's API is called during registration, this function
|
||||
// will prevent a deadlock by not attempting to re-enter the
|
||||
// the call-once and not releasing any waiting threads by flipping
|
||||
// the _is_registered field to true.
|
||||
static auto _is_registered = std::atomic<bool>{ false };
|
||||
|
||||
if(!_is_registered.load(std::memory_order_acquire))
|
||||
{
|
||||
using mutex_t = std::recursive_mutex;
|
||||
using auto_lock_t = std::unique_lock<mutex_t>;
|
||||
static auto _once = std::once_flag{};
|
||||
static auto _mutex = mutex_t{};
|
||||
|
||||
// defer the lock so we can check for recursion
|
||||
auto _lk = auto_lock_t{ _mutex, std::defer_lock };
|
||||
|
||||
// this will be true if the same thread currently executing the call_once invokes
|
||||
// the library's API while registering the profiler (e.g. tool which wants to
|
||||
// instrument HIP API invokes a HIP function while registering with the profiler)
|
||||
// we allow this thread to proceed and access the "const" API table but
|
||||
// return so it does not flip _is_registered to true, which would result
|
||||
// in any subsequent threads not waiting until the library is fully registered,
|
||||
// resulting in missed callbacks for the tools
|
||||
if(_lk.owns_lock()) return;
|
||||
|
||||
// ensures any subsequent threads wait until the first thread
|
||||
// finishes registration
|
||||
_lk.lock();
|
||||
// call_once to ensure that we only register once
|
||||
std::call_once(_once, register_profiler_impl);
|
||||
// the first thread has completed registration and all
|
||||
// threads waiting on lock will be released and this
|
||||
// block will not be entered again
|
||||
_is_registered.exchange(true, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
HipApiTable*
|
||||
get_hip_api_table()
|
||||
{
|
||||
register_profiler();
|
||||
return get_hip_api_table_impl().load(std::memory_order_relaxed);
|
||||
}
|
||||
} // namespace hip
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#define HIP_VERSION_MAJOR 1
|
||||
#define HIP_VERSION_MINOR 0
|
||||
#define HIP_VERSION_PATCH 0
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
extern "C" {
|
||||
// fake hip function
|
||||
void
|
||||
hip_init(void);
|
||||
}
|
||||
|
||||
namespace hip
|
||||
{
|
||||
struct HipApiTable
|
||||
{
|
||||
uint64_t size = 0;
|
||||
void (*functor)() = nullptr;
|
||||
};
|
||||
|
||||
// populates hip api table with function pointers
|
||||
inline void
|
||||
initialize_hip_api_table(HipApiTable* dst)
|
||||
{
|
||||
dst->size = sizeof(HipApiTable);
|
||||
dst->functor = &hip_init;
|
||||
}
|
||||
|
||||
// copies the api table from src to dst
|
||||
inline void
|
||||
copy_hip_api_table(HipApiTable* dst, const HipApiTable* src)
|
||||
{
|
||||
*dst = *src;
|
||||
}
|
||||
} // namespace hip
|
||||
@@ -0,0 +1,3 @@
|
||||
#
|
||||
# AddressSanitizer suppressions file for rocprofiler-register project.
|
||||
#
|
||||
@@ -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)
|
||||
@@ -0,0 +1,3 @@
|
||||
#
|
||||
# ThreadSanitizer suppressions file for rocprofiler-register project.
|
||||
#
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -0,0 +1,4 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
add_subdirectory(rocprofiler-register)
|
||||
@@ -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})
|
||||
@@ -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
|
||||
@@ -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*>(®ister_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);
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
@@ -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)
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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")
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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({});
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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({}, {});
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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({});
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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, ®istration_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__);
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Посилання в новій задачі
Заблокувати користувача