Initial Implementation: include (#10)
* Initial Implementation: include * Initial Implementation: lib details (#11) * Initial Implementation: lib details * Initial Implementation: lib (#12) * Initial Implementation: lib * Initial Implementation: source (#13) * Initial Implementation: source * Initial Implementation: samples (#14) * Initial Implementation: samples * Initial Implementation: tests (#15) * Initial Implementation: tests * Initial Implementation: scripts (#16) * Initial Implementation: scripts * Initial Implementation: cmake (#17) * Initial Implementation: cmake * Initial Implementation: top-level files (#18) * Initial Implementation: top-level files - clang-format - clang-tidy - cmake-format - ignore build and cache directories - main CMakeLists.txt - pyproject.toml (python formatting) - VERSION file * Initial Implementation: workflow (#19) * Fix unused variable - rocprofiler_register_warn_level
This commit is contained in:
zatwierdzone przez
GitHub
rodzic
53a9547670
commit
fa4295db6b
@@ -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,172 @@
|
||||
name: Continuous Integration
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
pull_request:
|
||||
branches: [ main, develop ]
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
runner: ['ubuntu-latest']
|
||||
compiler: ['clang-13', 'clang-14', 'clang-15', 'gcc-11', 'gcc-12']
|
||||
ci-args: ['']
|
||||
ci-tag: ['']
|
||||
include:
|
||||
- runner: 'ubuntu-latest'
|
||||
compiler: 'gcc-12'
|
||||
ci-args: '--coverage'
|
||||
ci-tag: '-codecov'
|
||||
- runner: 'ubuntu-latest'
|
||||
compiler: 'clang-15'
|
||||
ci-args: '--linter clang-tidy'
|
||||
ci-tag: '-clang-tidy'
|
||||
# - runner: 'ubuntu-latest'
|
||||
# compiler: 'gcc-12'
|
||||
# ci-args: '--memcheck ThreadSanitizer'
|
||||
# ci-tag: '-thread-sanitizer'
|
||||
# - runner: 'ubuntu-latest'
|
||||
# compiler: 'gcc-12'
|
||||
# ci-args: '--memcheck AddressSanitizer'
|
||||
# ci-tag: '-address-sanitizer'
|
||||
# - runner: 'ubuntu-latest'
|
||||
# compiler: 'gcc-12'
|
||||
# ci-args: '--memcheck LeakSanitizer'
|
||||
# ci-tag: '-leak-sanitizer'
|
||||
# - runner: 'ubuntu-latest'
|
||||
# compiler: 'gcc-12'
|
||||
# ci-args: '--memcheck UndefinedBehaviorSanitizer'
|
||||
# ci-tag: '-undefined-behavior-sanitizer'
|
||||
|
||||
runs-on: ${{ matrix.runner }}
|
||||
|
||||
env:
|
||||
BUILD_TYPE: RelWithDebInfo
|
||||
INSTALL_PREFIX: /opt/rocprofiler-register
|
||||
PACKAGING_INSTALL_PREFIX: /opt/rocm
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install Packages
|
||||
timeout-minutes: 25
|
||||
run: |
|
||||
CC=${{ matrix.compiler }} &&
|
||||
CXX=$(echo ${{ matrix.compiler }} | sed 's/clang-/clang++-/1' | sed 's/gcc-/g++-/1') &&
|
||||
sudo apt-get update &&
|
||||
sudo apt-get install -y build-essential python3 environment-modules ${{ matrix.compiler }} ${CXX} &&
|
||||
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/${CC} 100 &&
|
||||
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/${CXX} 100 &&
|
||||
python3 -m pip install --upgrade pip &&
|
||||
python3 -m pip install 'cmake==3.21.4'
|
||||
|
||||
- name: Setup GCov
|
||||
timeout-minutes: 25
|
||||
if: ${{ matrix.compiler == 'gcc-12' }}
|
||||
run: |
|
||||
sudo update-alternatives --install /usr/bin/gcov gcov /usr/bin/gcov-12 100
|
||||
|
||||
- name: Setup Clang-Tidy
|
||||
timeout-minutes: 25
|
||||
if: ${{ matrix.compiler == 'clang-15' }}
|
||||
run: |
|
||||
sudo apt-get install -y clang-tidy-15
|
||||
sudo update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-15 100
|
||||
|
||||
- name: Configure, Build, and Test
|
||||
timeout-minutes: 115
|
||||
shell: bash
|
||||
run:
|
||||
cmake --version &&
|
||||
python3 ./scripts/run-ci.py -B build
|
||||
--name ${{ github.repository_owner }}-${{ github.ref_name }}-${{ matrix.runner }}-${{ matrix.compiler }}${{ matrix.ci-tag }}
|
||||
--build-jobs 2
|
||||
--site GitHub
|
||||
${{ matrix.ci-args }}
|
||||
--disable-cdash
|
||||
--
|
||||
-DCMAKE_C_COMPILER=/usr/bin/cc
|
||||
-DCMAKE_CXX_COMPILER=/usr/bin/c++
|
||||
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}
|
||||
-DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_PREFIX }}
|
||||
-DROCPROFILER_REGISTER_BUILD_TESTS=ON
|
||||
-DROCPROFILER_REGISTER_BUILD_SAMPLES=ON
|
||||
--
|
||||
-VV
|
||||
|
||||
- name: Install
|
||||
timeout-minutes: 10
|
||||
run:
|
||||
cmake --build build --target install --parallel 2
|
||||
|
||||
- name: CPack and Install
|
||||
run: |
|
||||
cd build
|
||||
cpack -G STGZ
|
||||
mkdir -p ${{ env.PACKAGING_INSTALL_PREFIX }}
|
||||
./rocprofiler-register-*-Linux.sh --prefix=${{ env.PACKAGING_INSTALL_PREFIX }} --exclude-subdir --skip-license
|
||||
|
||||
- name: Test Install Modulefile
|
||||
timeout-minutes: 15
|
||||
shell: bash
|
||||
run: |
|
||||
set -v
|
||||
source /usr/share/modules/init/$(basename ${SHELL})
|
||||
module use ${{ env.INSTALL_PREFIX }}/share/modulefiles
|
||||
module avail
|
||||
module load rocprofiler-register
|
||||
pushd tests
|
||||
BUILD_DIR=${PWD}/build-rocp-reg-modulefile
|
||||
cmake -B ${BUILD_DIR} .
|
||||
cmake --build ${BUILD_DIR} --target all
|
||||
rm -rf ${BUILD_DIR}
|
||||
|
||||
- name: Test Install Setup Env
|
||||
timeout-minutes: 15
|
||||
shell: bash
|
||||
run: |
|
||||
set -v
|
||||
source ${{ env.INSTALL_PREFIX }}/share/rocprofiler-register/setup-env.sh
|
||||
pushd samples/library-implementation
|
||||
BUILD_DIR=${PWD}/build-rocp-reg-setup-env
|
||||
cmake -B ${BUILD_DIR} .
|
||||
cmake --build ${BUILD_DIR} --target all
|
||||
rm -rf ${BUILD_DIR}
|
||||
|
||||
- name: Test Install CPack Modulefile
|
||||
timeout-minutes: 15
|
||||
shell: bash
|
||||
run: |
|
||||
set -v
|
||||
source /usr/share/modules/init/$(basename ${SHELL})
|
||||
module use ${{ env.PACKAGING_INSTALL_PREFIX }}/share/modulefiles
|
||||
module avail
|
||||
module load rocprofiler-register
|
||||
pushd tests
|
||||
BUILD_DIR=${PWD}/build-rocp-reg-modulefile-cpack
|
||||
cmake -B ${BUILD_DIR} .
|
||||
cmake --build ${BUILD_DIR} --target all
|
||||
rm -rf ${BUILD_DIR}
|
||||
|
||||
- name: Test Install CPack Setup Env
|
||||
timeout-minutes: 15
|
||||
shell: bash
|
||||
run: |
|
||||
set -v
|
||||
source ${{ env.PACKAGING_INSTALL_PREFIX }}/share/rocprofiler-register/setup-env.sh
|
||||
pushd samples/library-implementation
|
||||
BUILD_DIR=${PWD}/build-rocp-reg-setup-env-cpack
|
||||
cmake -B ${BUILD_DIR} .
|
||||
cmake --build ${BUILD_DIR} --target all
|
||||
rm -rf ${BUILD_DIR}
|
||||
@@ -0,0 +1,146 @@
|
||||
|
||||
name: Formatting
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
paths-ignore:
|
||||
- '.github/workflows/pull_*.yml'
|
||||
- '.github/workflows/linting.yml'
|
||||
- '.github/workflows/markdown_lint.yml'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
cmake:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Extract branch name
|
||||
shell: bash
|
||||
run: |
|
||||
echo "branch=${GITHUB_HEAD_REF:-${GITHUB_HEAD_REF#refs/heads/}}" >> $GITHUB_OUTPUT
|
||||
id: extract_branch
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y python3-pip
|
||||
python3 -m pip install -U cmake-format
|
||||
|
||||
- name: Run cmake-format
|
||||
run: |
|
||||
set +e
|
||||
cmake-format -i $(find . -type f | egrep 'CMakeLists.txt|\.cmake$')
|
||||
if [ $(git diff | wc -l) -ne 0 ]; then
|
||||
echo -e "\nError! CMake code not formatted. Run cmake-format...\n"
|
||||
echo -e "\nFiles:\n"
|
||||
git diff --name-only
|
||||
echo -e "\nFull diff:\n"
|
||||
git diff
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Create pull request
|
||||
if: failure()
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
commit-message: "cmake formatting (cmake-format)"
|
||||
branch: ${{ steps.extract_branch.outputs.branch }}-cmake-format
|
||||
delete-branch: true
|
||||
title: "Format cmake code (via cmake-format) on ${{ steps.extract_branch.outputs.branch }}"
|
||||
base: ${{ steps.extract_branch.outputs.branch }}
|
||||
|
||||
source:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
DISTRIB_CODENAME=$(cat /etc/lsb-release | grep DISTRIB_CODENAME | awk -F '=' '{print $NF}')
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y software-properties-common wget curl clang-format-11
|
||||
|
||||
- name: Extract branch name
|
||||
shell: bash
|
||||
run: |
|
||||
echo "branch=${GITHUB_HEAD_REF:-${GITHUB_HEAD_REF#refs/heads/}}" >> $GITHUB_OUTPUT
|
||||
id: extract_branch
|
||||
|
||||
- name: Run clang-format
|
||||
run: |
|
||||
set +e
|
||||
FILES=$(find samples source tests -type f | egrep '\.(h|hpp|hh|c|cc|cpp)(|\.in)$')
|
||||
FORMAT_OUT=$(clang-format-11 -i ${FILES})
|
||||
if [ $(git diff | wc -l) -ne 0 ]; then
|
||||
echo -e "\nError! Code not formatted. Run clang-format (version 11)...\n"
|
||||
echo -e "\nFiles:\n"
|
||||
git diff --name-only
|
||||
echo -e "\nFull diff:\n"
|
||||
git diff
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Create pull request
|
||||
if: failure()
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
commit-message: "source formatting (clang-format v11)"
|
||||
branch: ${{ steps.extract_branch.outputs.branch }}-clang-format
|
||||
delete-branch: true
|
||||
title: "Format source code (via clang-format v11) on ${{ steps.extract_branch.outputs.branch }}"
|
||||
base: ${{ steps.extract_branch.outputs.branch }}
|
||||
|
||||
python:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ['3.10']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Extract branch name
|
||||
shell: bash
|
||||
run: |
|
||||
echo "branch=${GITHUB_HEAD_REF:-${GITHUB_HEAD_REF#refs/heads/}}" >> $GITHUB_OUTPUT
|
||||
id: extract_branch
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
python -m pip install black
|
||||
|
||||
- name: black format
|
||||
run: |
|
||||
black .
|
||||
if [ $(git diff | wc -l) -ne 0 ]; then
|
||||
echo -e "\nError! Python code not formatted. Run black...\n"
|
||||
echo -e "\nFiles:\n"
|
||||
git diff --name-only
|
||||
echo -e "\nFull diff:\n"
|
||||
git diff
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Create pull request
|
||||
if: failure()
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
commit-message: "python formatting (black)"
|
||||
branch: ${{ steps.extract_branch.outputs.branch }}-python-format
|
||||
delete-branch: true
|
||||
title: "Format python code (via black) on ${{ steps.extract_branch.outputs.branch }}"
|
||||
base: ${{ steps.extract_branch.outputs.branch }}
|
||||
@@ -30,3 +30,7 @@
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Build directories
|
||||
/build*
|
||||
/.cache
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||
|
||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND CMAKE_CURRENT_SOURCE_DIR STREQUAL
|
||||
CMAKE_SOURCE_DIR)
|
||||
set(MSG "")
|
||||
message(STATUS "Warning! Building from the source directory is not recommended")
|
||||
message(STATUS "If unintended, please remove 'CMakeCache.txt' and 'CMakeFiles'")
|
||||
message(STATUS "and build from a separate directory")
|
||||
message(AUTHOR_WARNING "In-source build")
|
||||
endif()
|
||||
|
||||
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" FULL_VERSION_STRING LIMIT_COUNT 1)
|
||||
string(REGEX REPLACE "(\n|\r)" "" FULL_VERSION_STRING "${FULL_VERSION_STRING}")
|
||||
string(REGEX REPLACE "([0-9]+)\.([0-9]+)\.([0-9]+)(.*)" "\\1.\\2.\\3"
|
||||
ROCPROFILER_REGISTER_VERSION "${FULL_VERSION_STRING}")
|
||||
|
||||
foreach(_LANG C CXX)
|
||||
set(CMAKE_${_LANG}_FLAGS_COVERAGE_INIT
|
||||
"-Og -g3 -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-inline-functions -fprofile-abs-path -fprofile-arcs -ftest-coverage --coverage"
|
||||
CACHE STRING "${_LANG} flags for code coverage builds")
|
||||
|
||||
set(CMAKE_${_LANG}_FLAGS_COVERAGE
|
||||
"${CMAKE_${_LANG}_FLAGS_COVERAGE_INIT}"
|
||||
CACHE STRING "${_LANG} flags for code coverage builds")
|
||||
endforeach()
|
||||
|
||||
project(
|
||||
rocprofiler-register
|
||||
LANGUAGES C CXX
|
||||
VERSION ${ROCPROFILER_REGISTER_VERSION}
|
||||
DESCRIPTION "Registration library for rocprofiler"
|
||||
HOMEPAGE_URL "https://github.com/ROCm-Developer-Tools/rocprofiler-register-internal")
|
||||
|
||||
# needed for modulefile and setup-env.sh
|
||||
string(REPLACE "-" "_" PROJECT_NAME_UNDERSCORED "${PROJECT_NAME}")
|
||||
|
||||
find_package(Git)
|
||||
|
||||
if(Git_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe --tags
|
||||
OUTPUT_VARIABLE ROCPROFILER_REGISTER_GIT_DESCRIBE
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE _GIT_DESCRIBE_RESULT
|
||||
ERROR_QUIET)
|
||||
|
||||
if(NOT _GIT_DESCRIBE_RESULT EQUAL 0)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe
|
||||
OUTPUT_VARIABLE ROCPROFILER_REGISTER_GIT_DESCRIBE
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
RESULT_VARIABLE _GIT_DESCRIBE_RESULT
|
||||
ERROR_QUIET)
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
|
||||
OUTPUT_VARIABLE ROCPROFILER_REGISTER_GIT_REVISION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
|
||||
else()
|
||||
set(ROCPROFILER_REGISTER_GIT_DESCRIBE "v${ROCPROFILER_REGISTER_VERSION}")
|
||||
set(ROCPROFILER_REGISTER_GIT_REVISION "")
|
||||
endif()
|
||||
|
||||
message(
|
||||
STATUS
|
||||
"[${PROJECT_NAME}] version ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} (${FULL_VERSION_STRING})"
|
||||
)
|
||||
message(STATUS "[${PROJECT_NAME}] git revision: ${ROCPROFILER_REGISTER_GIT_REVISION}")
|
||||
message(STATUS "[${PROJECT_NAME}] git describe: ${ROCPROFILER_REGISTER_GIT_DESCRIBE}")
|
||||
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${PROJECT_SOURCE_DIR}/cmake/Modules
|
||||
${CMAKE_MODULE_PATH})
|
||||
|
||||
include(GNUInstallDirs) # install directories
|
||||
|
||||
include(rocprofiler_register_utilities) # various functions/macros
|
||||
include(rocprofiler_register_interfaces) # interface libraries
|
||||
include(rocprofiler_register_compilers) # compiler identification
|
||||
include(rocprofiler_register_options) # project options
|
||||
include(rocprofiler_register_build_settings) # build flags
|
||||
include(rocprofiler_register_formatting) # formatting
|
||||
include(rocprofiler_register_linting) # clang-tidy
|
||||
include(rocprofiler_register_config_interfaces) # configure interface libraries
|
||||
|
||||
set(CMAKE_C_VISIBILITY_PRESET "hidden")
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
|
||||
set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
|
||||
|
||||
enable_testing()
|
||||
include(CTest)
|
||||
|
||||
add_subdirectory(source)
|
||||
|
||||
if(ROCPROFILER_REGISTER_BUILD_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if(ROCPROFILER_REGISTER_BUILD_SAMPLES)
|
||||
add_subdirectory(samples)
|
||||
endif()
|
||||
|
||||
#
|
||||
include(rocprofiler_register_config_install)
|
||||
include(rocprofiler_register_config_packaging)
|
||||
|
||||
rocprofiler_register_print_features()
|
||||
@@ -0,0 +1 @@
|
||||
0.1.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_DATAROOTDIR@/cmake/@PROJECT_NAME_UNDERSCORED@"
|
||||
@@ -0,0 +1,32 @@
|
||||
# - Config file for @PROJECT_NAME@ and its component libraries
|
||||
# It defines the following variables:
|
||||
#
|
||||
# @PROJECT_NAME@_INCLUDE_DIRS
|
||||
# @PROJECT_NAME@_LIBRARIES
|
||||
# @PROJECT_NAME@_INTERNAL_DEFINES - used by the test suite
|
||||
|
||||
# compute paths
|
||||
get_filename_component(@PROJECT_NAME@_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
|
||||
# version
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-version.cmake)
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
|
||||
set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_LIB_INSTALL_DIR@")
|
||||
get_filename_component(@PROJECT_NAME@_ROOT_DIR ${@PROJECT_NAME@_INCLUDE_DIR} PATH)
|
||||
|
||||
include("${@PROJECT_NAME@_CMAKE_DIR}/@PROJECT_NAME@-library-targets.cmake")
|
||||
|
||||
if(TARGET @PROJECT_NAME@::@PROJECT_NAME@)
|
||||
set(@PROJECT_NAME@_LIBRARIES @PROJECT_NAME@::@PROJECT_NAME@)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(
|
||||
@PROJECT_NAME@
|
||||
FOUND_VAR @PROJECT_NAME@_FOUND
|
||||
REQUIRED_VARS @PROJECT_NAME@_ROOT_DIR @PROJECT_NAME@_INCLUDE_DIR @PROJECT_NAME@_LIBRARIES
|
||||
VERSION_VAR @PROJECT_NAME@_VERSION
|
||||
HANDLE_COMPONENTS)
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
BASEDIR=$(dirname ${BASH_SOURCE[0]})
|
||||
command -v realpath &> /dev/null && BASEDIR=$(realpath ${BASEDIR}/../..) || BASEDIR=$(cd ${BASEDIR}/../.. && pwd)
|
||||
|
||||
if [ ! -d "${BASEDIR}" ]; then
|
||||
echo "${BASEDIR} does not exist"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@PROJECT_NAME_UNDERSCORED@_ROOT=${BASEDIR}
|
||||
PATH=${BASEDIR}/bin:${PATH}
|
||||
LD_LIBRARY_PATH=${BASEDIR}/@CMAKE_INSTALL_LIBDIR@:${LD_LIBRARY_PATH}
|
||||
PYTHONPATH=${BASEDIR}/@CMAKE_INSTALL_PYTHONDIR@:${PYTHONPATH}
|
||||
CMAKE_PREFIX_PATH=${BASEDIR}:${CMAKE_PREFIX_PATH}
|
||||
@PROJECT_NAME_UNDERSCORED@_DIR=${BASEDIR}/@CMAKE_INSTALL_DATAROOTDIR@/cmake/@PROJECT_NAME_UNDERSCORED@
|
||||
|
||||
export @PROJECT_NAME_UNDERSCORED@_ROOT
|
||||
export PATH
|
||||
export LD_LIBRARY_PATH
|
||||
export PYTHONPATH
|
||||
export CMAKE_PREFIX_PATH
|
||||
export @PROJECT_NAME_UNDERSCORED@_DIR
|
||||
@@ -0,0 +1,107 @@
|
||||
# ########################################################################################
|
||||
#
|
||||
# Handles the build settings
|
||||
#
|
||||
# ########################################################################################
|
||||
|
||||
include_guard(DIRECTORY)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
include(rocprofiler_register_compilers)
|
||||
include(rocprofiler_register_utilities)
|
||||
|
||||
target_compile_definitions(rocprofiler-register-build-flags
|
||||
INTERFACE $<$<CONFIG:DEBUG>:DEBUG>)
|
||||
|
||||
if(ROCPROFILER_REGISTER_BUILD_CI)
|
||||
rocprofiler_register_target_compile_definitions(rocprofiler-register-build-flags
|
||||
INTERFACE ROCPROFILER_REGISTER_CI)
|
||||
endif()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# dynamic linking and runtime libraries
|
||||
#
|
||||
if(CMAKE_DL_LIBS AND NOT "${CMAKE_DL_LIBS}" STREQUAL "dl")
|
||||
# if cmake provides dl library, use that
|
||||
set(dl_LIBRARY
|
||||
${CMAKE_DL_LIBS}
|
||||
CACHE FILEPATH "dynamic linking system library")
|
||||
endif()
|
||||
|
||||
foreach(_TYPE dl rt)
|
||||
if(NOT ${_TYPE}_LIBRARY)
|
||||
find_library(${_TYPE}_LIBRARY NAMES ${_TYPE})
|
||||
find_package_handle_standard_args(${_TYPE}-library REQUIRED_VARS ${_TYPE}_LIBRARY)
|
||||
if(${_TYPE}-library_FOUND)
|
||||
string(TOUPPER "${_TYPE}" _TYPE_UC)
|
||||
rocprofiler_register_target_compile_definitions(
|
||||
rocprofiler-register-${_TYPE}
|
||||
INTERFACE ROCPROFILER_REGISTER_${_TYPE_UC}=1)
|
||||
target_link_libraries(rocprofiler-register-${_TYPE}
|
||||
INTERFACE ${${_TYPE}_LIBRARY})
|
||||
if("${_TYPE}" STREQUAL "dl" AND NOT ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY)
|
||||
# This instructs the linker to add all symbols, not only used ones, to the
|
||||
# dynamic symbol table. This option is needed for some uses of dlopen or
|
||||
# to allow obtaining backtraces from within a program.
|
||||
rocprofiler_register_target_compile_options(
|
||||
rocprofiler-register-${_TYPE}
|
||||
LANGUAGES C CXX
|
||||
LINK_LANGUAGES C CXX
|
||||
INTERFACE "-rdynamic")
|
||||
endif()
|
||||
else()
|
||||
rocprofiler_register_target_compile_definitions(
|
||||
rocprofiler-register-${_TYPE}
|
||||
INTERFACE ROCPROFILER_REGISTER_${_TYPE_UC}=0)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
target_link_libraries(rocprofiler-register-build-flags INTERFACE rocprofiler-register::dl)
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# set the compiler flags
|
||||
#
|
||||
rocprofiler_register_target_compile_options(
|
||||
rocprofiler-register-build-flags
|
||||
INTERFACE "-W" "-Wall" "-Wno-unknown-pragmas" "-fstack-protector-strong"
|
||||
"-Wstack-protector")
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# debug-safe optimizations
|
||||
#
|
||||
rocprofiler_register_target_compile_options(
|
||||
rocprofiler-register-build-flags
|
||||
LANGUAGES CXX
|
||||
INTERFACE "-faligned-new")
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# developer build flags
|
||||
#
|
||||
rocprofiler_register_target_compile_options(
|
||||
rocprofiler-register-developer-flags
|
||||
LANGUAGES C CXX
|
||||
INTERFACE "-Werror" "-Wdouble-promotion" "-Wshadow" "-Wextra")
|
||||
|
||||
if(NOT ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY)
|
||||
rocprofiler_register_target_compile_options(
|
||||
rocprofiler-register-developer-flags
|
||||
LANGUAGES C CXX
|
||||
INTERFACE "-Wstack-usage=524288" # 512 KB
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ROCPROFILER_REGISTER_BUILD_DEVELOPER)
|
||||
target_link_libraries(rocprofiler-register-build-flags
|
||||
INTERFACE rocprofiler-register::developer-flags)
|
||||
endif()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# user customization
|
||||
#
|
||||
get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||
|
||||
if(NOT APPLE OR "$ENV{CONDA_PYTHON_EXE}" STREQUAL "")
|
||||
rocprofiler_register_target_user_flags(rocprofiler-register-build-flags "CXX")
|
||||
endif()
|
||||
@@ -0,0 +1,352 @@
|
||||
# include guard
|
||||
# ########################################################################################
|
||||
#
|
||||
# Compilers
|
||||
#
|
||||
# ########################################################################################
|
||||
#
|
||||
# sets (cached):
|
||||
#
|
||||
# CMAKE_C_COMPILER_IS_<TYPE> CMAKE_CXX_COMPILER_IS_<TYPE>
|
||||
#
|
||||
# where TYPE is: - GNU - CLANG - INTEL - INTEL_ICC - INTEL_ICPC - PGI - XLC - HP_ACC -
|
||||
# MIPS - MSVC
|
||||
#
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCSourceCompiles)
|
||||
include(CheckCSourceRuns)
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(CheckCXXSourceCompiles)
|
||||
include(CheckCXXSourceRuns)
|
||||
|
||||
include(CMakeParseArguments)
|
||||
|
||||
include(rocprofiler_register_utilities)
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# macro converting string to list
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
macro(ROCPROFILER_REGISTER_TO_LIST _VAR _STR)
|
||||
string(REPLACE " " " " ${_VAR} "${_STR}")
|
||||
string(REPLACE " " ";" ${_VAR} "${_STR}")
|
||||
endmacro()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# macro converting string to list
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
macro(ROCPROFILER_REGISTER_TO_STRING _VAR _STR)
|
||||
string(REPLACE ";" " " ${_VAR} "${_STR}")
|
||||
endmacro()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# Macro to add to string
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
macro(add _VAR _FLAG)
|
||||
if(NOT "${_FLAG}" STREQUAL "")
|
||||
if("${${_VAR}}" STREQUAL "")
|
||||
set(${_VAR} "${_FLAG}")
|
||||
else()
|
||||
set(${_VAR} "${${_VAR}} ${_FLAG}")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# call before running check_{c,cxx}_compiler_flag
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
macro(ROCPROFILER_REGISTER_BEGIN_FLAG_CHECK)
|
||||
if(ROCPROFILER_REGISTER_QUIET_CONFIG)
|
||||
if(NOT DEFINED CMAKE_REQUIRED_QUIET)
|
||||
set(CMAKE_REQUIRED_QUIET OFF)
|
||||
endif()
|
||||
rocprofiler_register_save_variables(FLAG_CHECK VARIABLES CMAKE_REQUIRED_QUIET)
|
||||
set(CMAKE_REQUIRED_QUIET ON)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# call after running check_{c,cxx}_compiler_flag
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
macro(ROCPROFILER_REGISTER_END_FLAG_CHECK)
|
||||
if(ROCPROFILER_REGISTER_QUIET_CONFIG)
|
||||
rocprofiler_register_restore_variables(FLAG_CHECK VARIABLES CMAKE_REQUIRED_QUIET)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# check flag
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
function(ROCPROFILER_REGISTER_TARGET_COMPILE_OPTIONS _TARG_TARGET)
|
||||
cmake_parse_arguments(_TARG "BUILD_INTERFACE;FORCE" ""
|
||||
"PUBLIC;INTERFACE;PRIVATE;LANGUAGES;LINK_LANGUAGES" ${ARGN})
|
||||
|
||||
if(NOT _TARG_MODE)
|
||||
set(_TARG_MODE INTERFACE)
|
||||
endif()
|
||||
|
||||
get_property(_ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||
set(_SUPPORTED_LANGUAGES "C" "CXX")
|
||||
|
||||
if(NOT _TARG_LANGUAGES)
|
||||
foreach(_LANG ${_ENABLED_LANGUAGES})
|
||||
if(_LANG IN_LIST _SUPPORTED_LANGUAGES)
|
||||
list(APPEND _TARG_LANGUAGES ${_LANG})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
string(TOLOWER "_${_TARG_TARGET}" _TARG_TARGET_LC)
|
||||
|
||||
function(rocprofiler_register_target_compile_option_impl _TARGET_IMPL
|
||||
_TARGET_MODE_IMPL _TARGET_LANG_IMPL _TARGET_FLAG_IMPL)
|
||||
if(_TARG_BUILD_INTERFACE)
|
||||
target_compile_options(
|
||||
${_TARGET_IMPL}
|
||||
${_TARGET_MODE_IMPL}
|
||||
$<BUILD_INTERFACE:$<$<COMPILE_LANGUAGE:${_TARGET_LANG_IMPL}>:${_TARGET_FLAG_IMPL}>>
|
||||
)
|
||||
else()
|
||||
target_compile_options(
|
||||
${_TARGET_IMPL} ${_TARGET_MODE_IMPL}
|
||||
$<$<COMPILE_LANGUAGE:${_TARGET_LANG_IMPL}>:${_TARGET_FLAG_IMPL}>)
|
||||
endif()
|
||||
|
||||
if("${_TARGET_LANG_IMPL}" IN_LIST _TARG_LINK_LANGUAGES)
|
||||
if(_TARG_BUILD_INTERFACE)
|
||||
target_link_options(
|
||||
${_TARGET_IMPL}
|
||||
${_TARGET_MODE_IMPL}
|
||||
$<BUILD_INTERFACE:$<$<LINK_LANGUAGE:${_TARGET_LANG_IMPL}>:${_TARGET_FLAG_IMPL}>>
|
||||
)
|
||||
else()
|
||||
target_link_options(
|
||||
${_TARGET_IMPL} ${_TARGET_MODE_IMPL}
|
||||
$<$<LINK_LANGUAGE:${_TARGET_LANG_IMPL}>:${_TARGET_FLAG_IMPL}>)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(rocprofiler_register_target_compile_option_patch_name _P_LANG _P_IN _P_OUT)
|
||||
string(TOLOWER "${_P_LANG}" _P_LANG)
|
||||
string(REGEX REPLACE "^(/|-)" "${_P_LANG}${_TARG_TARGET_LC}_" _NAME "${_P_IN}")
|
||||
string(REPLACE "-" "_" _NAME "${_NAME}")
|
||||
string(REPLACE " " "_" _NAME "${_NAME}")
|
||||
string(REPLACE "=" "_" _NAME "${_NAME}")
|
||||
set(${_P_OUT}
|
||||
"${_NAME}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if(NOT DEFINED rocprofiler_register_c_error AND NOT DEFINED
|
||||
rocprofiler_register_cxx_error)
|
||||
rocprofiler_register_begin_flag_check()
|
||||
check_c_compiler_flag("-Werror" c_rocprofiler_register_werror)
|
||||
check_cxx_compiler_flag("-Werror" cxx_rocprofiler_register_werror)
|
||||
rocprofiler_register_end_flag_check()
|
||||
endif()
|
||||
|
||||
foreach(_TARG_MODE PUBLIC INTERFACE PRIVATE)
|
||||
foreach(_FLAG ${_TARG_${_TARG_MODE}})
|
||||
foreach(_LANG ${_TARG_LANGUAGES})
|
||||
unset(FLAG_NAME)
|
||||
rocprofiler_register_target_compile_option_patch_name(${_LANG} "${_FLAG}"
|
||||
FLAG_NAME)
|
||||
|
||||
if(_TARG_FORCE)
|
||||
set(${FLAG_NAME}
|
||||
1
|
||||
CACHE INTERNAL "${_LANG} flag: ${_FLAG}")
|
||||
else()
|
||||
rocprofiler_register_begin_flag_check()
|
||||
|
||||
if("${_LANG}" STREQUAL "C")
|
||||
if(c_rocprofiler_register_werror)
|
||||
check_c_compiler_flag("${_FLAG} -Werror" ${FLAG_NAME})
|
||||
else()
|
||||
check_c_compiler_flag("${_FLAG}" ${FLAG_NAME})
|
||||
endif()
|
||||
elseif("${_LANG}" STREQUAL "CXX")
|
||||
if(cxx_rocprofiler_register_werror)
|
||||
check_cxx_compiler_flag("${_FLAG} -Werror" ${FLAG_NAME})
|
||||
else()
|
||||
check_cxx_compiler_flag("${_FLAG}" ${FLAG_NAME})
|
||||
endif()
|
||||
else()
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"rocprofiler_register_target_compile_option :: unknown language: ${_LANG}"
|
||||
)
|
||||
endif()
|
||||
|
||||
rocprofiler_register_end_flag_check()
|
||||
endif()
|
||||
|
||||
if(${FLAG_NAME})
|
||||
rocprofiler_register_target_compile_option_impl(
|
||||
${_TARG_TARGET} ${_TARG_MODE} ${_LANG} "${_FLAG}")
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# add to any language
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
function(ROCPROFILER_REGISTER_TARGET_USER_FLAGS _TARGET _LANGUAGE)
|
||||
|
||||
set(_FLAGS ${${_LANGUAGE}FLAGS} $ENV{${_LANGUAGE}FLAGS} ${${_LANGUAGE}_FLAGS}
|
||||
$ENV{${_LANGUAGE}_FLAGS})
|
||||
|
||||
string(REPLACE " " ";" _FLAGS "${_FLAGS}")
|
||||
|
||||
set(${PROJECT_NAME}_${_LANGUAGE}_FLAGS
|
||||
${${PROJECT_NAME}_${_LANGUAGE}_FLAGS} ${_FLAGS}
|
||||
PARENT_SCOPE)
|
||||
|
||||
set(${PROJECT_NAME}_${_LANGUAGE}_COMPILE_OPTIONS
|
||||
${${PROJECT_NAME}_${_LANGUAGE}_COMPILE_OPTIONS} ${_FLAGS}
|
||||
PARENT_SCOPE)
|
||||
|
||||
target_compile_options(${_TARGET}
|
||||
INTERFACE $<$<COMPILE_LANGUAGE:${_LANGUAGE}>:${_FLAGS}>)
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# add compiler definition
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
function(ROCPROFILER_REGISTER_TARGET_COMPILE_DEFINITIONS _TARG _VIS)
|
||||
foreach(_DEF ${ARGN})
|
||||
if(NOT "${_DEF}" MATCHES "[A-Za-z_]+=.*" AND "${_DEF}" MATCHES
|
||||
"^ROCPROFILER_REGISTER_")
|
||||
set(_DEF "${_DEF}=1")
|
||||
endif()
|
||||
target_compile_definitions(${_TARG} ${_VIS} $<$<COMPILE_LANGUAGE:CXX>:${_DEF}>)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# determine compiler types for each language
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES)
|
||||
foreach(LANG C CXX HIP CUDA)
|
||||
|
||||
if(NOT DEFINED CMAKE_${LANG}_COMPILER)
|
||||
set(CMAKE_${LANG}_COMPILER "")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_${LANG}_COMPILER_ID)
|
||||
set(CMAKE_${LANG}_COMPILER_ID "")
|
||||
endif()
|
||||
|
||||
function(SET_COMPILER_VAR VAR _BOOL)
|
||||
set(CMAKE_${LANG}_COMPILER_IS_${VAR}
|
||||
${_BOOL}
|
||||
CACHE INTERNAL "CMake ${LANG} compiler identification (${VAR})" FORCE)
|
||||
mark_as_advanced(CMAKE_${LANG}_COMPILER_IS_${VAR})
|
||||
endfunction()
|
||||
|
||||
if(("${LANG}" STREQUAL "C" AND CMAKE_COMPILER_IS_GNUCC)
|
||||
OR ("${LANG}" STREQUAL "CXX" AND CMAKE_COMPILER_IS_GNUCXX))
|
||||
|
||||
# GNU compiler
|
||||
set_compiler_var(GNU 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER MATCHES "icc.*")
|
||||
|
||||
# Intel icc compiler
|
||||
set_compiler_var(INTEL 1)
|
||||
set_compiler_var(INTEL_ICC 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER MATCHES "icpc.*")
|
||||
|
||||
# Intel icpc compiler
|
||||
set_compiler_var(INTEL 1)
|
||||
set_compiler_var(INTEL_ICPC 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "AppleClang")
|
||||
|
||||
# Clang/LLVM compiler
|
||||
set_compiler_var(CLANG 1)
|
||||
set_compiler_var(APPLE_CLANG 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "Clang")
|
||||
|
||||
# Clang/LLVM compiler
|
||||
set_compiler_var(CLANG 1)
|
||||
|
||||
# HIP Clang compiler
|
||||
if(CMAKE_${LANG}_COMPILER MATCHES "hipcc")
|
||||
set_compiler_var(HIPCC 1)
|
||||
endif()
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "PGI")
|
||||
|
||||
# PGI compiler
|
||||
set_compiler_var(PGI 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER MATCHES "xlC" AND UNIX)
|
||||
|
||||
# IBM xlC compiler
|
||||
set_compiler_var(XLC 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER MATCHES "aCC" AND UNIX)
|
||||
|
||||
# HP aC++ compiler
|
||||
set_compiler_var(HP_ACC 1)
|
||||
|
||||
elseif(
|
||||
CMAKE_${LANG}_COMPILER MATCHES "CC"
|
||||
AND CMAKE_SYSTEM_NAME MATCHES "IRIX"
|
||||
AND UNIX)
|
||||
|
||||
# IRIX MIPSpro CC Compiler
|
||||
set_compiler_var(MIPS 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "Intel")
|
||||
|
||||
set_compiler_var(INTEL 1)
|
||||
|
||||
set(CTYPE ICC)
|
||||
if("${LANG}" STREQUAL "CXX")
|
||||
set(CTYPE ICPC)
|
||||
endif()
|
||||
|
||||
set_compiler_var(INTEL_${CTYPE} 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER MATCHES "MSVC")
|
||||
|
||||
# Windows Visual Studio compiler
|
||||
set_compiler_var(MSVC 1)
|
||||
|
||||
elseif(CMAKE_${LANG}_COMPILER_ID MATCHES "NVIDIA")
|
||||
|
||||
# NVCC
|
||||
set_compiler_var(NVIDIA 1)
|
||||
|
||||
endif()
|
||||
|
||||
# set other to no
|
||||
foreach(
|
||||
TYPE
|
||||
GNU
|
||||
INTEL
|
||||
INTEL_ICC
|
||||
INTEL_ICPC
|
||||
APPLE_CLANG
|
||||
CLANG
|
||||
PGI
|
||||
XLC
|
||||
HP_ACC
|
||||
MIPS
|
||||
MSVC
|
||||
NVIDIA
|
||||
HIPCC)
|
||||
if(NOT DEFINED CMAKE_${LANG}_COMPILER_IS_${TYPE})
|
||||
set_compiler_var(${TYPE} 0)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
endforeach()
|
||||
@@ -0,0 +1,87 @@
|
||||
# include guard
|
||||
include_guard(GLOBAL)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
|
||||
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME config)
|
||||
|
||||
install(
|
||||
EXPORT rocprofiler-register-library-targets
|
||||
FILE rocprofiler-register-library-targets.cmake
|
||||
NAMESPACE rocprofiler-register::
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/rocprofiler-register)
|
||||
|
||||
configure_file(
|
||||
${PROJECT_SOURCE_DIR}/cmake/Templates/setup-env.sh.in
|
||||
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/setup-env.sh @ONLY)
|
||||
|
||||
configure_file(
|
||||
${PROJECT_SOURCE_DIR}/cmake/Templates/modulefile.in
|
||||
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/modulefiles/${PROJECT_NAME}/${PROJECT_VERSION}
|
||||
@ONLY)
|
||||
|
||||
install(
|
||||
FILES ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/setup-env.sh
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}
|
||||
COMPONENT setup)
|
||||
|
||||
install(
|
||||
FILES
|
||||
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/modulefiles/${PROJECT_NAME}/${PROJECT_VERSION}
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/modulefiles/${PROJECT_NAME}
|
||||
COMPONENT setup)
|
||||
|
||||
# ------------------------------------------------------------------------------#
|
||||
# install tree
|
||||
#
|
||||
set(PROJECT_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
|
||||
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
configure_package_config_file(
|
||||
${PROJECT_SOURCE_DIR}/cmake/Templates/${PROJECT_NAME}-config.cmake.in
|
||||
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/rocprofiler-register
|
||||
INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
|
||||
PATH_VARS PROJECT_INSTALL_DIR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR)
|
||||
|
||||
write_basic_package_version_file(
|
||||
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-version.cmake
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY SameMinorVersion)
|
||||
|
||||
install(
|
||||
FILES
|
||||
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake
|
||||
${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-version.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}
|
||||
OPTIONAL)
|
||||
|
||||
export(PACKAGE ${PROJECT_NAME})
|
||||
|
||||
# ------------------------------------------------------------------------------#
|
||||
# build tree
|
||||
#
|
||||
set(_BUILDTREE_EXPORT_DIR
|
||||
"${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/cmake/rocprofiler-register")
|
||||
|
||||
if(NOT EXISTS "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
|
||||
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${_BUILDTREE_EXPORT_DIR}")
|
||||
file(MAKE_DIRECTORY "${_BUILDTREE_EXPORT_DIR}")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${_BUILDTREE_EXPORT_DIR}/rocprofiler-register-library-targets.cmake")
|
||||
file(TOUCH "${_BUILDTREE_EXPORT_DIR}/rocprofiler-register-library-targets.cmake")
|
||||
endif()
|
||||
|
||||
export(
|
||||
EXPORT rocprofiler-register-library-targets
|
||||
NAMESPACE rocprofiler-register::
|
||||
FILE "${_BUILDTREE_EXPORT_DIR}/rocprofiler-register-library-targets.cmake")
|
||||
|
||||
set(rocprofiler_register_DIR
|
||||
"${_BUILDTREE_EXPORT_DIR}"
|
||||
CACHE PATH "rocprofiler-register" FORCE)
|
||||
@@ -0,0 +1,67 @@
|
||||
# include guard
|
||||
include_guard(DIRECTORY)
|
||||
|
||||
# ########################################################################################
|
||||
#
|
||||
# External Packages are found here
|
||||
#
|
||||
# ########################################################################################
|
||||
|
||||
target_include_directories(
|
||||
rocprofiler-register-headers
|
||||
INTERFACE $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/source/include>
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/source/include>
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/source>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
|
||||
|
||||
# ensure the env overrides the appending /opt/rocm later
|
||||
string(REPLACE ":" ";" CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH};${CMAKE_PREFIX_PATH}")
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
#
|
||||
# Threading
|
||||
#
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD ON)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG OFF)
|
||||
|
||||
find_package(Threads ${rocprofiler_register_FIND_QUIETLY}
|
||||
${rocprofiler_register_FIND_REQUIREMENT})
|
||||
if(Threads_FOUND)
|
||||
target_link_libraries(rocprofiler-register-threading
|
||||
INTERFACE $<BUILD_INTERFACE:Threads::Threads>)
|
||||
endif()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
#
|
||||
# dynamic linking (dl) and runtime (rt) libraries
|
||||
#
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
|
||||
foreach(_LIB dl rt)
|
||||
find_library(${_LIB}_LIBRARY NAMES ${_LIB})
|
||||
find_package_handle_standard_args(${_LIB}-library REQUIRED_VARS ${_LIB}_LIBRARY)
|
||||
if(${_LIB}_LIBRARY)
|
||||
target_link_libraries(
|
||||
rocprofiler-register-${_LIB} INTERFACE $<BUILD_INTERFACE:${${_LIB}_LIBRARY}>
|
||||
$<INSTALL_INTERFACE:${_LIB}>)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
#
|
||||
# stdc++fs (filesystem) library
|
||||
#
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
|
||||
find_library(stdcxxfs_LIBRARY NAMES stdc++fs)
|
||||
find_package_handle_standard_args(stdcxxfs-library REQUIRED_VARS stdcxxfs_LIBRARY)
|
||||
|
||||
if(stdcxxfs_LIBRARY)
|
||||
target_link_libraries(rocprofiler-register-stdcxxfs
|
||||
INTERFACE $<BUILD_INTERFACE:${stdcxxfs_LIBRARY}>)
|
||||
else()
|
||||
target_link_libraries(rocprofiler-register-stdcxxfs
|
||||
INTERFACE $<BUILD_INTERFACE:stdc++fs>)
|
||||
endif()
|
||||
@@ -0,0 +1,100 @@
|
||||
# configure packaging
|
||||
|
||||
# Add packaging directives
|
||||
set(CPACK_PACKAGE_NAME ${PROJECT_NAME})
|
||||
set(CPACK_PACKAGE_VENDOR "Advanced Micro Devices, Inc.")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_DESCRIPTION}")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
|
||||
set(CPACK_PACKAGE_CONTACT "jonathan.madsen@amd.com")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
|
||||
set(ROCPROFILER_REGISTER_CPACK_SYSTEM_NAME
|
||||
"${CMAKE_SYSTEM_NAME}"
|
||||
CACHE STRING "System name, e.g. Linux or <OS>-<VERSION>")
|
||||
set(ROCPROFILER_REGISTER_CPACK_PACKAGE_SUFFIX
|
||||
""
|
||||
CACHE STRING "Package suffix")
|
||||
|
||||
set(CPACK_PACKAGE_FILE_NAME
|
||||
"${CPACK_PACKAGE_NAME}-${ROCPROFILER_REGISTER_VERSION}-${ROCPROFILER_REGISTER_CPACK_SYSTEM_NAME}${ROCPROFILER_REGISTER_CPACK_PACKAGE_SUFFIX}"
|
||||
)
|
||||
if(DEFINED ENV{CPACK_PACKAGE_FILE_NAME})
|
||||
set(CPACK_PACKAGE_FILE_NAME $ENV{CPACK_PACKAGE_FILE_NAME})
|
||||
endif()
|
||||
|
||||
set(ROCPROFILER_REGISTER_PACKAGE_FILE_NAME
|
||||
${CPACK_PACKAGE_NAME}-${ROCPROFILER_REGISTER_VERSION}-${ROCPROFILER_REGISTER_CPACK_SYSTEM_NAME}${ROCPROFILER_REGISTER_CPACK_PACKAGE_SUFFIX}
|
||||
)
|
||||
rocprofiler_register_add_feature(ROCPROFILER_REGISTER_PACKAGE_FILE_NAME "CPack filename")
|
||||
|
||||
# -------------------------------------------------------------------------------------- #
|
||||
#
|
||||
# Debian package specific variables
|
||||
#
|
||||
# -------------------------------------------------------------------------------------- #
|
||||
|
||||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "${PROJECT_HOMEPAGE_URL}")
|
||||
set(CPACK_DEBIAN_PACKAGE_RELEASE
|
||||
"${ROCPROFILER_REGISTER_CPACK_SYSTEM_NAME}${ROCPROFILER_REGISTER_CPACK_PACKAGE_SUFFIX}"
|
||||
)
|
||||
string(REGEX REPLACE "([a-zA-Z])-([0-9])" "\\1\\2" CPACK_DEBIAN_PACKAGE_RELEASE
|
||||
"${CPACK_DEBIAN_PACKAGE_RELEASE}")
|
||||
string(REPLACE "-" "~" CPACK_DEBIAN_PACKAGE_RELEASE "${CPACK_DEBIAN_PACKAGE_RELEASE}")
|
||||
if(DEFINED ENV{CPACK_DEBIAN_PACKAGE_RELEASE})
|
||||
set(CPACK_DEBIAN_PACKAGE_RELEASE $ENV{CPACK_DEBIAN_PACKAGE_RELEASE})
|
||||
endif()
|
||||
|
||||
set(_DEBIAN_PACKAGE_DEPENDS "")
|
||||
if(rocm_version_FOUND)
|
||||
set(_ROCPROFILER_REGISTER_SUFFIX " (>= 1.0.0.${rocm_version_NUMERIC_VERSION})")
|
||||
set(_ROCTRACER_SUFFIX " (>= 1.0.0.${rocm_version_NUMERIC_VERSION})")
|
||||
set(_ROCM_SMI_SUFFIX
|
||||
" (>= ${rocm_version_MAJOR_VERSION}.0.0.${rocm_version_NUMERIC_VERSION})")
|
||||
endif()
|
||||
string(REPLACE ";" ", " _DEBIAN_PACKAGE_DEPENDS "${_DEBIAN_PACKAGE_DEPENDS}")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS
|
||||
"${_DEBIAN_PACKAGE_DEPENDS}"
|
||||
CACHE STRING "Debian package dependencies" FORCE)
|
||||
rocprofiler_register_add_feature(CPACK_DEBIAN_PACKAGE_DEPENDS
|
||||
"Debian package dependencies")
|
||||
set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT")
|
||||
|
||||
# -------------------------------------------------------------------------------------- #
|
||||
#
|
||||
# RPM package specific variables
|
||||
#
|
||||
# -------------------------------------------------------------------------------------- #
|
||||
|
||||
if(DEFINED CPACK_PACKAGING_INSTALL_PREFIX)
|
||||
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "${CPACK_PACKAGING_INSTALL_PREFIX}")
|
||||
endif()
|
||||
|
||||
set(CPACK_RPM_PACKAGE_RELEASE
|
||||
"${ROCPROFILER_REGISTER_CPACK_SYSTEM_NAME}${ROCPROFILER_REGISTER_CPACK_PACKAGE_SUFFIX}"
|
||||
)
|
||||
string(REGEX REPLACE "([a-zA-Z])-([0-9])" "\\1\\2" CPACK_RPM_PACKAGE_RELEASE
|
||||
"${CPACK_RPM_PACKAGE_RELEASE}")
|
||||
string(REPLACE "-" "~" CPACK_RPM_PACKAGE_RELEASE "${CPACK_RPM_PACKAGE_RELEASE}")
|
||||
if(DEFINED ENV{CPACK_RPM_PACKAGE_RELEASE})
|
||||
set(CPACK_RPM_PACKAGE_RELEASE $ENV{CPACK_RPM_PACKAGE_RELEASE})
|
||||
endif()
|
||||
|
||||
# Get rpm distro
|
||||
if(CPACK_RPM_PACKAGE_RELEASE)
|
||||
set(CPACK_RPM_PACKAGE_RELEASE_DIST ON)
|
||||
endif()
|
||||
set(CPACK_RPM_FILE_NAME "RPM-DEFAULT")
|
||||
|
||||
# -------------------------------------------------------------------------------------- #
|
||||
#
|
||||
# Prepare final version for the CPACK use
|
||||
#
|
||||
# -------------------------------------------------------------------------------------- #
|
||||
|
||||
set(CPACK_PACKAGE_VERSION
|
||||
"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}"
|
||||
)
|
||||
|
||||
include(CPack)
|
||||
@@ -0,0 +1,104 @@
|
||||
# ------------------------------------------------------------------------------#
|
||||
#
|
||||
# creates following targets to format code:
|
||||
# - format
|
||||
# - format-source
|
||||
# - format-cmake
|
||||
# - format-python
|
||||
# - format-rocprofiler-register-source
|
||||
# - format-rocprofiler-register-cmake
|
||||
# - format-rocprofiler-register-python
|
||||
#
|
||||
# ------------------------------------------------------------------------------#
|
||||
|
||||
include_guard(DIRECTORY)
|
||||
|
||||
find_program(ROCPROFILER_REGISTER_CLANG_FORMAT_EXE NAMES clang-format-11
|
||||
clang-format-mp-11)
|
||||
find_program(ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE NAMES cmake-format)
|
||||
find_program(ROCPROFILER_REGISTER_BLACK_FORMAT_EXE NAMES black)
|
||||
|
||||
add_custom_target(format-rocprofiler-register)
|
||||
if(NOT TARGET format)
|
||||
add_custom_target(format)
|
||||
endif()
|
||||
foreach(_TYPE source python cmake)
|
||||
if(NOT TARGET format-${_TYPE})
|
||||
add_custom_target(format-${_TYPE})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(ROCPROFILER_REGISTER_CLANG_FORMAT_EXE
|
||||
OR ROCPROFILER_REGISTER_BLACK_FORMAT_EXE
|
||||
OR ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE)
|
||||
|
||||
set(rocp_source_files)
|
||||
set(rocp_header_files)
|
||||
set(rocp_python_files)
|
||||
set(rocp_cmake_files ${PROJECT_SOURCE_DIR}/CMakeLists.txt)
|
||||
|
||||
foreach(_DIR cmake samples source tests)
|
||||
foreach(_TYPE header_files source_files cmake_files python_files)
|
||||
set(${_TYPE})
|
||||
endforeach()
|
||||
file(GLOB_RECURSE header_files ${PROJECT_SOURCE_DIR}/${_DIR}/*.h
|
||||
${PROJECT_SOURCE_DIR}/${_DIR}/*.hpp)
|
||||
file(GLOB_RECURSE source_files ${PROJECT_SOURCE_DIR}/${_DIR}/*.c
|
||||
${PROJECT_SOURCE_DIR}/${_DIR}/*.cpp)
|
||||
file(GLOB_RECURSE cmake_files ${PROJECT_SOURCE_DIR}/${_DIR}/*CMakeLists.txt
|
||||
${PROJECT_SOURCE_DIR}/${_DIR}/*.cmake)
|
||||
file(GLOB_RECURSE python_files ${PROJECT_SOURCE_DIR}/${_DIR}/*.py)
|
||||
foreach(_TYPE header_files source_files cmake_files python_files)
|
||||
list(APPEND rocp_${_TYPE} ${${_TYPE}})
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
foreach(_TYPE header_files source_files cmake_files python_files)
|
||||
if(rocp_${_TYPE})
|
||||
list(REMOVE_DUPLICATES rocp_${_TYPE})
|
||||
list(SORT rocp_${_TYPE})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(ROCPROFILER_REGISTER_CLANG_FORMAT_EXE AND (rocp_source_files OR rocp_header_files))
|
||||
add_custom_target(
|
||||
format-rocprofiler-register-source
|
||||
${ROCPROFILER_REGISTER_CLANG_FORMAT_EXE} -i ${rocp_header_files}
|
||||
${rocp_source_files}
|
||||
COMMENT
|
||||
"[rocprofiler-register] Running source formatter ${ROCPROFILER_REGISTER_CLANG_FORMAT_EXE}..."
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ROCPROFILER_REGISTER_BLACK_FORMAT_EXE AND rocp_python_files)
|
||||
add_custom_target(
|
||||
format-rocprofiler-register-python
|
||||
${ROCPROFILER_REGISTER_BLACK_FORMAT_EXE} -q ${rocp_python_files}
|
||||
COMMENT
|
||||
"[rocprofiler-register] Running Python formatter ${ROCPROFILER_REGISTER_BLACK_FORMAT_EXE}..."
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE AND rocp_cmake_files)
|
||||
add_custom_target(
|
||||
format-rocprofiler-register-cmake
|
||||
${ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE} -i ${rocp_cmake_files}
|
||||
COMMENT
|
||||
"[rocprofiler-register] Running CMake formatter ${ROCPROFILER_REGISTER_CMAKE_FORMAT_EXE}..."
|
||||
)
|
||||
endif()
|
||||
|
||||
foreach(_TYPE source python cmake)
|
||||
if(TARGET format-rocprofiler-register-${_TYPE})
|
||||
add_dependencies(format-rocprofiler-register
|
||||
format-rocprofiler-register-${_TYPE})
|
||||
add_dependencies(format-${_TYPE} format-rocprofiler-register-${_TYPE})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(_TYPE source python)
|
||||
if(TARGET format-rocprofiler-register-${_TYPE})
|
||||
add_dependencies(format format-rocprofiler-register-${_TYPE})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
@@ -0,0 +1,34 @@
|
||||
#
|
||||
#
|
||||
# Forward declaration of all INTERFACE targets
|
||||
#
|
||||
#
|
||||
|
||||
include(rocprofiler_register_utilities)
|
||||
|
||||
#
|
||||
# interfaces for build flags
|
||||
#
|
||||
rocprofiler_register_add_interface_library(
|
||||
rocprofiler-register-headers
|
||||
"Provides minimal set of include flags to compile with rocprofiler-register")
|
||||
rocprofiler_register_add_interface_library(
|
||||
rocprofiler-register-build-flags
|
||||
"Provides generalized build flags for rocprofiler-register" INTERNAL)
|
||||
rocprofiler_register_add_interface_library(rocprofiler-register-threading
|
||||
"Enables multithreading support" INTERNAL)
|
||||
rocprofiler_register_add_interface_library(
|
||||
rocprofiler-register-developer-flags
|
||||
"Compiler flags for developers (more warnings, etc.)" INTERNAL)
|
||||
rocprofiler_register_add_interface_library(rocprofiler-register-memcheck "Sanitizer"
|
||||
INTERNAL)
|
||||
|
||||
#
|
||||
# interfaces for libraries
|
||||
#
|
||||
rocprofiler_register_add_interface_library(
|
||||
rocprofiler-register-dl "Build flags for dynamic linking library" INTERNAL)
|
||||
rocprofiler_register_add_interface_library(rocprofiler-register-rt
|
||||
"Build flags for runtime library" INTERNAL)
|
||||
rocprofiler_register_add_interface_library(rocprofiler-register-stdcxxfs
|
||||
"C++ filesystem library" INTERNAL)
|
||||
@@ -0,0 +1,47 @@
|
||||
include_guard(GLOBAL)
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
#
|
||||
# Clang Tidy
|
||||
#
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
|
||||
find_program(
|
||||
ROCPROFILER_REGISTER_CLANG_TIDY_COMMAND
|
||||
NAMES clang-tidy-18
|
||||
clang-tidy-17
|
||||
clang-tidy-16
|
||||
clang-tidy-15
|
||||
clang-tidy-14
|
||||
clang-tidy-13
|
||||
clang-tidy-12
|
||||
clang-tidy-11
|
||||
clang-tidy)
|
||||
|
||||
macro(ROCPROFILER_REGISTER_ACTIVATE_CLANG_TIDY)
|
||||
if(ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY)
|
||||
if(NOT ROCPROFILER_REGISTER_CLANG_TIDY_COMMAND)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY is ON but clang-tidy is not found!"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_CLANG_TIDY ${ROCPROFILER_REGISTER_CLANG_TIDY_COMMAND}
|
||||
-header-filter=${PROJECT_SOURCE_DIR}/.*)
|
||||
|
||||
# Create a preprocessor definition that depends on .clang-tidy content so the
|
||||
# compile command will change when .clang-tidy changes. This ensures that a
|
||||
# subsequent build re-runs clang-tidy on all sources even if they do not otherwise
|
||||
# need to be recompiled. Nothing actually uses this definition. We add it to
|
||||
# targets on which we run clang-tidy just to get the build dependency on the
|
||||
# .clang-tidy file.
|
||||
file(SHA1 ${PROJECT_SOURCE_DIR}/.clang-tidy clang_tidy_sha1)
|
||||
set(CLANG_TIDY_DEFINITIONS "CLANG_TIDY_SHA1=${clang_tidy_sha1}")
|
||||
unset(clang_tidy_sha1)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(ROCPROFILER_REGISTER_DEACTIVATE_CLANG_TIDY)
|
||||
set(CMAKE_CXX_CLANG_TIDY)
|
||||
endmacro()
|
||||
@@ -0,0 +1,40 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
set(ROCPROFILER_REGISTER_MEMCHECK_TYPES "ThreadSanitizer" "AddressSanitizer"
|
||||
"LeakSanitizer" "UndefinedBehaviorSanitizer")
|
||||
|
||||
if(ROCPROFILER_REGISTER_MEMCHECK AND NOT ROCPROFILER_REGISTER_MEMCHECK IN_LIST
|
||||
ROCPROFILER_REGISTER_MEMCHECK_TYPES)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Unsupported memcheck type '${ROCPROFILER_REGISTER_MEMCHECK}'. Options: ${ROCPROFILER_REGISTER_MEMCHECK_TYPES}"
|
||||
)
|
||||
endif()
|
||||
|
||||
set_property(CACHE ROCPROFILER_REGISTER_MEMCHECK
|
||||
PROPERTY STRINGS "${ROCPROFILER_REGISTER_MEMCHECK_TYPES}")
|
||||
|
||||
function(rocprofiler_register_add_memcheck_flags _TYPE _LIB)
|
||||
target_compile_options(
|
||||
rocprofiler-register-memcheck
|
||||
INTERFACE $<BUILD_INTERFACE:-g3 -Og -fno-omit-frame-pointer
|
||||
-fno-optimize-sibling-calls -fno-inline-functions -fsanitize=${_TYPE}>
|
||||
-static-lib${_LIB})
|
||||
target_link_options(
|
||||
rocprofiler-register-memcheck INTERFACE $<BUILD_INTERFACE:-fsanitize=${_TYPE}
|
||||
-static-lib${_LIB} -Wl,--no-undefined>)
|
||||
endfunction()
|
||||
|
||||
# always unset so that it doesn't preload if memcheck disabled
|
||||
unset(ROCPROFILER_REGISTER_MEMCHECK_PRELOAD_ENV CACHE)
|
||||
|
||||
if(ROCPROFILER_REGISTER_MEMCHECK STREQUAL "AddressSanitizer")
|
||||
rocprofiler_register_add_memcheck_flags("address" "asan")
|
||||
elseif(ROCPROFILER_REGISTER_MEMCHECK STREQUAL "LeakSanitizer")
|
||||
rocprofiler_register_add_memcheck_flags("leak" "lsan")
|
||||
elseif(ROCPROFILER_REGISTER_MEMCHECK STREQUAL "ThreadSanitizer")
|
||||
rocprofiler_register_add_memcheck_flags("thread" "tsan")
|
||||
elseif(ROCPROFILER_REGISTER_MEMCHECK STREQUAL "UndefinedBehaviorSanitizer")
|
||||
rocprofiler_register_add_memcheck_flags("undefined" "ubsan")
|
||||
endif()
|
||||
@@ -0,0 +1,90 @@
|
||||
#
|
||||
# rocprofiler_register_options.cmake
|
||||
#
|
||||
# Configure miscellaneous settings
|
||||
#
|
||||
# standard cmake options
|
||||
rocprofiler_register_add_option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||||
rocprofiler_register_add_option(BUILD_STATIC_LIBS "Build static libraries" OFF)
|
||||
rocprofiler_register_add_option(CMAKE_POSITION_INDEPENDENT_CODE
|
||||
"Build position independent code" ON)
|
||||
|
||||
# export compile commands in the project
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
rocprofiler_register_add_option(ROCPROFILER_REGISTER_BUILD_TESTS
|
||||
"Enable building the tests" OFF)
|
||||
rocprofiler_register_add_option(ROCPROFILER_REGISTER_BUILD_SAMPLES "Enable building the
|
||||
code samples" OFF)
|
||||
rocprofiler_register_add_option(ROCPROFILER_REGISTER_BUILD_CI
|
||||
"Enable continuous integration additions" OFF ADVANCED)
|
||||
rocprofiler_register_add_option(ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY
|
||||
"Enable clang-tidy checks" OFF ADVANCED)
|
||||
rocprofiler_register_add_option(
|
||||
ROCPROFILER_REGISTER_BUILD_DEVELOPER "Extra build flags for development like -Werror"
|
||||
${ROCPROFILER_REGISTER_BUILD_CI} ADVANCED)
|
||||
|
||||
# In the future, we will do this even with clang-tidy enabled
|
||||
if(ROCPROFILER_REGISTER_BUILD_CI AND NOT ROCPROFILER_REGISTER_ENABLE_CLANG_TIDY)
|
||||
message(
|
||||
STATUS
|
||||
"Forcing ROCPROFILER_REGISTER_BUILD_DEVELOPER=ON because ROCPROFILER_REGISTER_BUILD_CI=ON"
|
||||
)
|
||||
set(ROCPROFILER_REGISTER_BUILD_DEVELOPER
|
||||
ON
|
||||
CACHE
|
||||
BOOL
|
||||
"Any compiler warnings are errors (forced due ROCPROFILER_REGISTER_BUILD_CI=ON)"
|
||||
FORCE)
|
||||
endif()
|
||||
|
||||
set(ROCPROFILER_REGISTER_BUILD_TYPES "Release" "RelWithDebInfo" "Debug" "MinSizeRel"
|
||||
"Coverage")
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE
|
||||
"Release"
|
||||
CACHE STRING "Build type" FORCE)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE IN_LIST ROCPROFILER_REGISTER_BUILD_TYPES)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Unsupported build type '${CMAKE_BUILD_TYPE}'. Options: ${ROCPROFILER_REGISTER_BUILD_TYPES}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(ROCPROFILER_REGISTER_BUILD_CI)
|
||||
foreach(_BUILD_TYPE ${ROCPROFILER_REGISTER_BUILD_TYPES})
|
||||
string(TOUPPER "${_BUILD_TYPE}" _BUILD_TYPE)
|
||||
|
||||
# remove NDEBUG preprocessor def so that asserts are triggered
|
||||
string(REGEX REPLACE ".DNDEBUG" "" CMAKE_C_FLAGS_${_BUILD_TYPE}
|
||||
"${CMAKE_C_FLAGS_${_BUILD_TYPE}}")
|
||||
string(REGEX REPLACE ".DNDEBUG" "" CMAKE_CXX_FLAGS_${_BUILD_TYPE}
|
||||
"${CMAKE_CXX_FLAGS_${_BUILD_TYPE}}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
||||
"${ROCPROFILER_REGISTER_BUILD_TYPES}")
|
||||
endif()
|
||||
|
||||
rocprofiler_register_add_cache_option(ROCPROFILER_REGISTER_MEMCHECK "" STRING
|
||||
"Memory checker type" ADVANCED)
|
||||
|
||||
# ASAN is defined by testing team on Jenkins
|
||||
if(ASAN)
|
||||
set(ROCPROFILER_REGISTER_MEMCHECK
|
||||
"AddressSanitizer"
|
||||
CACHE STRING "Memory checker type (forced by ASAN defined)" FORCE)
|
||||
endif()
|
||||
|
||||
include(rocprofiler_register_memcheck)
|
||||
@@ -0,0 +1,941 @@
|
||||
# include guard
|
||||
include_guard(GLOBAL)
|
||||
|
||||
# MacroUtilities - useful macros and functions for generic tasks
|
||||
#
|
||||
|
||||
cmake_policy(PUSH)
|
||||
cmake_policy(SET CMP0054 NEW)
|
||||
cmake_policy(SET CMP0057 NEW)
|
||||
|
||||
include(CMakeDependentOption)
|
||||
include(CMakeParseArguments)
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# message which handles ROCPROFILER_REGISTER_QUIET_CONFIG settings
|
||||
# -----------------------------------------------------------------------
|
||||
#
|
||||
function(ROCPROFILER_REGISTER_MESSAGE TYPE)
|
||||
if(NOT ROCPROFILER_REGISTER_QUIET_CONFIG)
|
||||
message(${TYPE} "[rocprofiler-register] ${ARGN}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Save a set of variables with the given prefix
|
||||
# -----------------------------------------------------------------------
|
||||
macro(ROCPROFILER_REGISTER_SAVE_VARIABLES _PREFIX)
|
||||
# parse args
|
||||
cmake_parse_arguments(
|
||||
SAVE
|
||||
"" # options
|
||||
"CONDITION" # single value args
|
||||
"VARIABLES" # multiple value args
|
||||
${ARGN})
|
||||
if(DEFINED SAVE_CONDITION AND NOT "${SAVE_CONDITION}" STREQUAL "")
|
||||
if(${SAVE_CONDITION})
|
||||
foreach(_VAR ${SAVE_VARIABLES})
|
||||
if(DEFINED ${_VAR})
|
||||
set(${_PREFIX}_${_VAR} "${${_VAR}}")
|
||||
else()
|
||||
message(AUTHOR_WARNING "${_VAR} is not defined")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
else()
|
||||
foreach(_VAR ${SAVE_VARIABLES})
|
||||
if(DEFINED ${_VAR})
|
||||
set(${_PREFIX}_${_VAR} "${${_VAR}}")
|
||||
else()
|
||||
message(AUTHOR_WARNING "${_VAR} is not defined")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
unset(SAVE_CONDITION)
|
||||
unset(SAVE_VARIABLES)
|
||||
endmacro()
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# Restore a set of variables with the given prefix
|
||||
# -----------------------------------------------------------------------
|
||||
macro(ROCPROFILER_REGISTER_RESTORE_VARIABLES _PREFIX)
|
||||
# parse args
|
||||
cmake_parse_arguments(
|
||||
RESTORE
|
||||
"" # options
|
||||
"CONDITION" # single value args
|
||||
"VARIABLES" # multiple value args
|
||||
${ARGN})
|
||||
if(DEFINED RESTORE_CONDITION AND NOT "${RESTORE_CONDITION}" STREQUAL "")
|
||||
if(${RESTORE_CONDITION})
|
||||
foreach(_VAR ${RESTORE_VARIABLES})
|
||||
if(DEFINED ${_PREFIX}_${_VAR})
|
||||
set(${_VAR} ${${_PREFIX}_${_VAR}})
|
||||
unset(${_PREFIX}_${_VAR})
|
||||
else()
|
||||
message(AUTHOR_WARNING "${_PREFIX}_${_VAR} is not defined")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
else()
|
||||
foreach(_VAR ${RESTORE_VARIABLES})
|
||||
if(DEFINED ${_PREFIX}_${_VAR})
|
||||
set(${_VAR} ${${_PREFIX}_${_VAR}})
|
||||
unset(${_PREFIX}_${_VAR})
|
||||
else()
|
||||
message(AUTHOR_WARNING "${_PREFIX}_${_VAR} is not defined")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
unset(RESTORE_CONDITION)
|
||||
unset(RESTORE_VARIABLES)
|
||||
endmacro()
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# function - rocprofiler_register_capitalize - make a string capitalized (first letter is
|
||||
# capital) usage: capitalize("SHARED" CShared) message(STATUS "-- CShared is
|
||||
# \"${CShared}\"") $ -- CShared is "Shared"
|
||||
function(ROCPROFILER_REGISTER_CAPITALIZE str var)
|
||||
# make string lower
|
||||
string(TOLOWER "${str}" str)
|
||||
string(SUBSTRING "${str}" 0 1 _first)
|
||||
string(TOUPPER "${_first}" _first)
|
||||
string(SUBSTRING "${str}" 1 -1 _remainder)
|
||||
string(CONCAT str "${_first}" "${_remainder}")
|
||||
set(${var}
|
||||
"${str}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# ------------------------------------------------------------------------------#
|
||||
# function rocprofiler_register_strip_target(<TARGET> [FORCE] [EXPLICIT])
|
||||
#
|
||||
# Creates a post-build command which strips a binary. FORCE flag will override
|
||||
#
|
||||
function(ROCPROFILER_REGISTER_STRIP_TARGET)
|
||||
cmake_parse_arguments(STRIP "FORCE;EXPLICIT" "" "ARGS" ${ARGN})
|
||||
|
||||
list(LENGTH STRIP_UNPARSED_ARGUMENTS NUM_UNPARSED)
|
||||
|
||||
if(NUM_UNPARSED EQUAL 1)
|
||||
set(_TARGET "${STRIP_UNPARSED_ARGUMENTS}")
|
||||
else()
|
||||
rocprofiler_register_message(
|
||||
FATAL_ERROR
|
||||
"rocprofiler_register_strip_target cannot deduce target from \"${ARGN}\"")
|
||||
endif()
|
||||
|
||||
if(NOT TARGET "${_TARGET}")
|
||||
rocprofiler_register_message(
|
||||
FATAL_ERROR
|
||||
"rocprofiler_register_strip_target not provided valid target: \"${_TARGET}\"")
|
||||
endif()
|
||||
|
||||
if(CMAKE_STRIP AND (STRIP_FORCE OR ROCPROFILER_REGISTER_STRIP_LIBRARIES))
|
||||
if(STRIP_EXPLICIT)
|
||||
add_custom_command(
|
||||
TARGET ${_TARGET}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_STRIP} ${STRIP_ARGS} $<TARGET_FILE:${_TARGET}>
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Stripping ${_TARGET}...")
|
||||
else()
|
||||
add_custom_command(
|
||||
TARGET ${_TARGET}
|
||||
POST_BUILD
|
||||
COMMAND
|
||||
${CMAKE_STRIP} -w --keep-symbol="rocprofiler_register_init"
|
||||
--keep-symbol="rocprofiler_register_finalize"
|
||||
--keep-symbol="rocprofiler_register_push_trace"
|
||||
--keep-symbol="rocprofiler_register_pop_trace"
|
||||
--keep-symbol="rocprofiler_register_push_region"
|
||||
--keep-symbol="rocprofiler_register_pop_region"
|
||||
--keep-symbol="rocprofiler_register_set_env"
|
||||
--keep-symbol="rocprofiler_register_set_mpi"
|
||||
--keep-symbol="rocprofiler_register_reset_preload"
|
||||
--keep-symbol="rocprofiler_register_set_instrumented"
|
||||
--keep-symbol="rocprofiler_register_user_*"
|
||||
--keep-symbol="ompt_start_tool" --keep-symbol="kokkosp_*"
|
||||
--keep-symbol="OnLoad" --keep-symbol="OnUnload"
|
||||
--keep-symbol="OnLoadToolProp" --keep-symbol="OnUnloadTool"
|
||||
--keep-symbol="__libc_start_main" ${STRIP_ARGS}
|
||||
$<TARGET_FILE:${_TARGET}>
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Stripping ${_TARGET}...")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# ------------------------------------------------------------------------------#
|
||||
# function add_rocprofiler_register_test_target()
|
||||
#
|
||||
# Creates a target which runs ctest but depends on all the tests being built.
|
||||
#
|
||||
function(ADD_ROCPROFILER_REGISTER_TEST_TARGET)
|
||||
if(NOT TARGET rocprofiler-register-test)
|
||||
add_custom_target(
|
||||
rocprofiler-register-test
|
||||
COMMAND ${CMAKE_COMMAND} --build ${PROJECT_BINARY_DIR} --target test
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
COMMENT "Running tests...")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# macro rocprofiler_register_checkout_git_submodule()
|
||||
#
|
||||
# Run "git submodule update" if a file in a submodule does not exist
|
||||
#
|
||||
# ARGS: RECURSIVE (option) -- add "--recursive" flag RELATIVE_PATH (one value) --
|
||||
# typically the relative path to submodule from PROJECT_SOURCE_DIR WORKING_DIRECTORY (one
|
||||
# value) -- (default: PROJECT_SOURCE_DIR) TEST_FILE (one value) -- file to check for
|
||||
# (default: CMakeLists.txt) ADDITIONAL_CMDS (many value) -- any addition commands to pass
|
||||
#
|
||||
function(ROCPROFILER_REGISTER_CHECKOUT_GIT_SUBMODULE)
|
||||
# parse args
|
||||
cmake_parse_arguments(
|
||||
CHECKOUT "RECURSIVE"
|
||||
"RELATIVE_PATH;WORKING_DIRECTORY;TEST_FILE;REPO_URL;REPO_BRANCH"
|
||||
"ADDITIONAL_CMDS" ${ARGN})
|
||||
|
||||
if(NOT CHECKOUT_WORKING_DIRECTORY)
|
||||
set(CHECKOUT_WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
if(NOT CHECKOUT_TEST_FILE)
|
||||
set(CHECKOUT_TEST_FILE "CMakeLists.txt")
|
||||
endif()
|
||||
|
||||
# default assumption
|
||||
if(NOT CHECKOUT_REPO_BRANCH)
|
||||
set(CHECKOUT_REPO_BRANCH "master")
|
||||
endif()
|
||||
|
||||
find_package(Git)
|
||||
set(_DIR "${CHECKOUT_WORKING_DIRECTORY}/${CHECKOUT_RELATIVE_PATH}")
|
||||
# ensure the (possibly empty) directory exists
|
||||
if(NOT EXISTS "${_DIR}")
|
||||
if(NOT CHECKOUT_REPO_URL)
|
||||
message(FATAL_ERROR "submodule directory does not exist")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# if this file exists --> project has been checked out if not exists --> not been
|
||||
# checked out
|
||||
set(_TEST_FILE "${_DIR}/${CHECKOUT_TEST_FILE}")
|
||||
# assuming a .gitmodules file exists
|
||||
set(_SUBMODULE "${PROJECT_SOURCE_DIR}/.gitmodules")
|
||||
|
||||
set(_TEST_FILE_EXISTS OFF)
|
||||
if(EXISTS "${_TEST_FILE}" AND NOT IS_DIRECTORY "${_TEST_FILE}")
|
||||
set(_TEST_FILE_EXISTS ON)
|
||||
endif()
|
||||
|
||||
if(_TEST_FILE_EXISTS)
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(Git REQUIRED)
|
||||
|
||||
set(_SUBMODULE_EXISTS OFF)
|
||||
if(EXISTS "${_SUBMODULE}" AND NOT IS_DIRECTORY "${_SUBMODULE}")
|
||||
set(_SUBMODULE_EXISTS ON)
|
||||
endif()
|
||||
|
||||
set(_HAS_REPO_URL OFF)
|
||||
if(NOT "${CHECKOUT_REPO_URL}" STREQUAL "")
|
||||
set(_HAS_REPO_URL ON)
|
||||
endif()
|
||||
|
||||
# if the module has not been checked out
|
||||
if(NOT _TEST_FILE_EXISTS AND _SUBMODULE_EXISTS)
|
||||
# perform the checkout
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} submodule update --init ${_RECURSE}
|
||||
${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_RELATIVE_PATH}
|
||||
WORKING_DIRECTORY ${CHECKOUT_WORKING_DIRECTORY}
|
||||
RESULT_VARIABLE RET)
|
||||
|
||||
# check the return code
|
||||
if(RET GREATER 0)
|
||||
set(_CMD "${GIT_EXECUTABLE} submodule update --init ${_RECURSE}
|
||||
${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_RELATIVE_PATH}")
|
||||
message(
|
||||
STATUS "function(rocprofiler_register_checkout_git_submodule) failed.")
|
||||
message(FATAL_ERROR "Command: \"${_CMD}\"")
|
||||
else()
|
||||
set(_TEST_FILE_EXISTS ON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT _TEST_FILE_EXISTS AND _HAS_REPO_URL)
|
||||
message(
|
||||
STATUS "Checking out '${CHECKOUT_REPO_URL}' @ '${CHECKOUT_REPO_BRANCH}'...")
|
||||
|
||||
# remove the existing directory
|
||||
if(EXISTS "${_DIR}")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${_DIR})
|
||||
endif()
|
||||
|
||||
# perform the checkout
|
||||
execute_process(
|
||||
COMMAND
|
||||
${GIT_EXECUTABLE} clone -b ${CHECKOUT_REPO_BRANCH}
|
||||
${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_REPO_URL} ${CHECKOUT_RELATIVE_PATH}
|
||||
WORKING_DIRECTORY ${CHECKOUT_WORKING_DIRECTORY}
|
||||
RESULT_VARIABLE RET)
|
||||
|
||||
# perform the submodule update
|
||||
if(CHECKOUT_RECURSIVE
|
||||
AND EXISTS "${_DIR}"
|
||||
AND IS_DIRECTORY "${_DIR}")
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} submodule update --init ${_RECURSE}
|
||||
WORKING_DIRECTORY ${_DIR}
|
||||
RESULT_VARIABLE RET)
|
||||
endif()
|
||||
|
||||
# check the return code
|
||||
if(RET GREATER 0)
|
||||
set(_CMD
|
||||
"${GIT_EXECUTABLE} clone -b ${CHECKOUT_REPO_BRANCH}
|
||||
${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_REPO_URL} ${CHECKOUT_RELATIVE_PATH}"
|
||||
)
|
||||
message(
|
||||
STATUS "function(rocprofiler_register_checkout_git_submodule) failed.")
|
||||
message(FATAL_ERROR "Command: \"${_CMD}\"")
|
||||
else()
|
||||
set(_TEST_FILE_EXISTS ON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${_TEST_FILE}" OR NOT _TEST_FILE_EXISTS)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Error checking out submodule: '${CHECKOUT_RELATIVE_PATH}' to '${_DIR}'")
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# try to find a package quietly
|
||||
#
|
||||
function(ROCPROFILER_REGISTER_TEST_FIND_PACKAGE PACKAGE_NAME OUTPUT_VAR)
|
||||
cmake_parse_arguments(PACKAGE "" "" "UNSET" ${ARGN})
|
||||
find_package(${PACKAGE_NAME} QUIET ${PACKAGE_UNPARSED_ARGUMENTS})
|
||||
if(NOT ${PACKAGE_NAME}_FOUND)
|
||||
set(${OUTPUT_VAR}
|
||||
OFF
|
||||
PARENT_SCOPE)
|
||||
else()
|
||||
set(${OUTPUT_VAR}
|
||||
ON
|
||||
PARENT_SCOPE)
|
||||
endif()
|
||||
foreach(_ARG ${PACKAGE_UNSET} FIND_PACKAGE_MESSAGE_DETAILS_${PACKAGE_NAME})
|
||||
unset(${_ARG} CACHE)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# macro to add an interface lib
|
||||
#
|
||||
function(ROCPROFILER_REGISTER_ADD_INTERFACE_LIBRARY _TARGET _DESCRIPT)
|
||||
add_library(${_TARGET} INTERFACE)
|
||||
string(REPLACE "${PROJECT_NAME}-" "" _ALIAS_TARGET "${_TARGET}")
|
||||
add_library(${PROJECT_NAME}::${_ALIAS_TARGET} ALIAS ${_TARGET})
|
||||
add_library(${PROJECT_NAME}::${_TARGET} ALIAS ${_TARGET})
|
||||
set(_ARGS "${ARGN}")
|
||||
if(NOT "INTERNAL" IN_LIST _ARGS)
|
||||
install(
|
||||
TARGETS ${_TARGET}
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
COMPONENT core
|
||||
EXPORT ${PROJECT_NAME}-library-targets
|
||||
OPTIONAL)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# function add_feature(<NAME> <DOCSTRING>) Add a project feature, whose activation is
|
||||
# specified by the existence of the variable <NAME>, to the list of enabled/disabled
|
||||
# features, plus a docstring describing the feature
|
||||
#
|
||||
function(ROCPROFILER_REGISTER_ADD_FEATURE _var _description)
|
||||
set(EXTRA_DESC "")
|
||||
foreach(currentArg ${ARGN})
|
||||
if(NOT "${currentArg}" STREQUAL "${_var}"
|
||||
AND NOT "${currentArg}" STREQUAL "${_description}"
|
||||
AND NOT "${currentArg}" STREQUAL "CMAKE_DEFINE"
|
||||
AND NOT "${currentArg}" STREQUAL "DOC")
|
||||
set(EXTRA_DESC "${EXTA_DESC}${currentArg}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_FEATURES ${_var})
|
||||
set_property(GLOBAL PROPERTY ${_var}_DESCRIPTION "${_description}${EXTRA_DESC}")
|
||||
|
||||
if("CMAKE_DEFINE" IN_LIST ARGN)
|
||||
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_DEFINES
|
||||
"${_var} @${_var}@")
|
||||
if(ROCPROFILER_REGISTER_BUILD_DOCS)
|
||||
set_property(
|
||||
GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_OPTIONS_DOC
|
||||
"${_var}` | ${_description}${EXTRA_DESC} |")
|
||||
endif()
|
||||
elseif("DOC" IN_LIST ARGN AND ROCPROFILER_REGISTER_BUILD_DOCS)
|
||||
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_OPTIONS_DOC
|
||||
"${_var}` | ${_description}${EXTRA_DESC} |")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# function add_option(<OPTION_NAME> <DOCSRING> <DEFAULT_SETTING> [NO_FEATURE]) Add an
|
||||
# option and add as a feature if NO_FEATURE is not provided
|
||||
#
|
||||
function(ROCPROFILER_REGISTER_ADD_OPTION _NAME _MESSAGE _DEFAULT)
|
||||
option(${_NAME} "${_MESSAGE}" ${_DEFAULT})
|
||||
if("NO_FEATURE" IN_LIST ARGN)
|
||||
mark_as_advanced(${_NAME})
|
||||
else()
|
||||
rocprofiler_register_add_feature(${_NAME} "${_MESSAGE}")
|
||||
if(ROCPROFILER_REGISTER_BUILD_DOCS)
|
||||
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_OPTIONS_DOC
|
||||
"${_NAME}` | ${_MESSAGE} |")
|
||||
endif()
|
||||
endif()
|
||||
if("ADVANCED" IN_LIST ARGN)
|
||||
mark_as_advanced(${_NAME})
|
||||
endif()
|
||||
if("CMAKE_DEFINE" IN_LIST ARGN)
|
||||
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_DEFINES ${_NAME})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# function rocprofiler_register_add_cache_option(<OPTION_NAME> <DOCSRING> <TYPE>
|
||||
# <DEFAULT_VALUE> [NO_FEATURE] [ADVANCED] [CMAKE_DEFINE])
|
||||
#
|
||||
function(ROCPROFILER_REGISTER_ADD_CACHE_OPTION _NAME _DEFAULT _TYPE _MESSAGE)
|
||||
set(_FORCE)
|
||||
if("FORCE" IN_LIST ARGN)
|
||||
set(_FORCE FORCE)
|
||||
endif()
|
||||
|
||||
set(${_NAME}
|
||||
"${_DEFAULT}"
|
||||
CACHE ${_TYPE} "${_MESSAGE}" ${_FORCE})
|
||||
|
||||
if("NO_FEATURE" IN_LIST ARGN)
|
||||
mark_as_advanced(${_NAME})
|
||||
else()
|
||||
rocprofiler_register_add_feature(${_NAME} "${_MESSAGE}")
|
||||
|
||||
if(ROCPROFILER_REGISTER_BUILD_DOCS)
|
||||
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_OPTIONS_DOC
|
||||
"${_NAME}` | ${_MESSAGE} |")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if("ADVANCED" IN_LIST ARGN)
|
||||
mark_as_advanced(${_NAME})
|
||||
endif()
|
||||
|
||||
if("CMAKE_DEFINE" IN_LIST ARGN)
|
||||
set_property(GLOBAL APPEND PROPERTY ${PROJECT_NAME}_CMAKE_DEFINES ${_NAME})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# function rocprofiler_register_report_feature_changes() :: print changes in features
|
||||
#
|
||||
function(ROCPROFILER_REGISTER_REPORT_FEATURE_CHANGES)
|
||||
get_property(_features GLOBAL PROPERTY ${PROJECT_NAME}_FEATURES)
|
||||
if(NOT "${_features}" STREQUAL "")
|
||||
list(REMOVE_DUPLICATES _features)
|
||||
list(SORT _features)
|
||||
endif()
|
||||
foreach(_feature ${_features})
|
||||
if("${ARGN}" STREQUAL "")
|
||||
rocprofiler_register_watch_for_change(${_feature})
|
||||
elseif("${_feature}" IN_LIST ARGN)
|
||||
rocprofiler_register_watch_for_change(${_feature})
|
||||
endif()
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# function print_enabled_features() Print enabled features plus their docstrings.
|
||||
#
|
||||
function(ROCPROFILER_REGISTER_PRINT_ENABLED_FEATURES)
|
||||
set(_basemsg "The following features are defined/enabled (+):")
|
||||
set(_currentFeatureText "${_basemsg}")
|
||||
get_property(_features GLOBAL PROPERTY ${PROJECT_NAME}_FEATURES)
|
||||
if(NOT "${_features}" STREQUAL "")
|
||||
list(REMOVE_DUPLICATES _features)
|
||||
list(SORT _features)
|
||||
endif()
|
||||
foreach(_feature ${_features})
|
||||
if(${_feature})
|
||||
# add feature to text
|
||||
set(_currentFeatureText "${_currentFeatureText}\n ${_feature}")
|
||||
# get description
|
||||
get_property(_desc GLOBAL PROPERTY ${_feature}_DESCRIPTION)
|
||||
# print description, if not standard ON/OFF, print what is set to
|
||||
if(_desc)
|
||||
if(NOT "${${_feature}}" STREQUAL "ON" AND NOT "${${_feature}}" STREQUAL
|
||||
"TRUE")
|
||||
set(_currentFeatureText
|
||||
"${_currentFeatureText}: ${_desc} -- [\"${${_feature}}\"]")
|
||||
else()
|
||||
string(REGEX REPLACE "^${PROJECT_NAME}_USE_" "" _feature_tmp
|
||||
"${_feature}")
|
||||
string(TOLOWER "${_feature_tmp}" _feature_tmp_l)
|
||||
rocprofiler_register_capitalize("${_feature_tmp}" _feature_tmp_c)
|
||||
foreach(_var _feature _feature_tmp _feature_tmp_l _feature_tmp_c)
|
||||
set(_ver "${${${_var}}_VERSION}")
|
||||
if(NOT "${_ver}" STREQUAL "")
|
||||
set(_desc "${_desc} -- [found version ${_ver}]")
|
||||
break()
|
||||
endif()
|
||||
unset(_ver)
|
||||
endforeach()
|
||||
set(_currentFeatureText "${_currentFeatureText}: ${_desc}")
|
||||
endif()
|
||||
set(_desc NOTFOUND)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT "${_currentFeatureText}" STREQUAL "${_basemsg}")
|
||||
message(STATUS "${_currentFeatureText}\n")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# function print_disabled_features() Print disabled features plus their docstrings.
|
||||
#
|
||||
function(ROCPROFILER_REGISTER_PRINT_DISABLED_FEATURES)
|
||||
set(_basemsg "The following features are NOT defined/enabled (-):")
|
||||
set(_currentFeatureText "${_basemsg}")
|
||||
get_property(_features GLOBAL PROPERTY ${PROJECT_NAME}_FEATURES)
|
||||
if(NOT "${_features}" STREQUAL "")
|
||||
list(REMOVE_DUPLICATES _features)
|
||||
list(SORT _features)
|
||||
endif()
|
||||
foreach(_feature ${_features})
|
||||
if(NOT ${_feature})
|
||||
set(_currentFeatureText "${_currentFeatureText}\n ${_feature}")
|
||||
|
||||
get_property(_desc GLOBAL PROPERTY ${_feature}_DESCRIPTION)
|
||||
|
||||
if(_desc)
|
||||
set(_currentFeatureText "${_currentFeatureText}: ${_desc}")
|
||||
set(_desc NOTFOUND)
|
||||
endif(_desc)
|
||||
endif()
|
||||
endforeach(_feature)
|
||||
|
||||
if(NOT "${_currentFeatureText}" STREQUAL "${_basemsg}")
|
||||
message(STATUS "${_currentFeatureText}\n")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# function print_features() Print all features plus their docstrings.
|
||||
#
|
||||
function(ROCPROFILER_REGISTER_PRINT_FEATURES)
|
||||
rocprofiler_register_report_feature_changes()
|
||||
rocprofiler_register_print_enabled_features()
|
||||
rocprofiler_register_print_disabled_features()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------------------#
|
||||
# this function is provided to easily select which files use alternative compiler:
|
||||
#
|
||||
# GLOBAL --> all files TARGET --> all files in a target SOURCE --> specific
|
||||
# source files DIRECTORY --> all files in directory PROJECT --> all files/targets in
|
||||
# a project/subproject
|
||||
#
|
||||
function(rocprofiler_register_custom_compilation)
|
||||
cmake_parse_arguments(COMP "GLOBAL;PROJECT" "COMPILER" "DIRECTORY;TARGET;SOURCE"
|
||||
${ARGN})
|
||||
|
||||
# find rocprofiler-register-launch-compiler
|
||||
find_program(
|
||||
ROCPROFILER_REGISTER_COMPILE_LAUNCHER
|
||||
NAMES rocprofiler-register-launch-compiler
|
||||
HINTS ${PROJECT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}
|
||||
PATHS ${PROJECT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}
|
||||
PATH_SUFFIXES scripts bin)
|
||||
|
||||
if(NOT COMP_COMPILER)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"rocprofiler_register_custom_compilation not provided COMPILER argument")
|
||||
endif()
|
||||
|
||||
if(NOT ROCPROFILER_REGISTER_COMPILE_LAUNCHER)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"rocprofiler-register could not find 'rocprofiler-register-launch-compiler'. Please set '-DROCPROFILER_REGISTER_COMPILE_LAUNCHER=/path/to/launcher'"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(COMP_GLOBAL)
|
||||
# if global, don't bother setting others
|
||||
set_property(
|
||||
GLOBAL
|
||||
PROPERTY
|
||||
RULE_LAUNCH_COMPILE
|
||||
"${ROCPROFILER_REGISTER_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}"
|
||||
)
|
||||
set_property(
|
||||
GLOBAL
|
||||
PROPERTY
|
||||
RULE_LAUNCH_LINK
|
||||
"${ROCPROFILER_REGISTER_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}"
|
||||
)
|
||||
else()
|
||||
foreach(_TYPE PROJECT DIRECTORY TARGET SOURCE)
|
||||
# make project/subproject scoping easy, e.g.
|
||||
# rocprofiler_register_custom_compilation(PROJECT) after project(...)
|
||||
if("${_TYPE}" STREQUAL "PROJECT" AND COMP_${_TYPE})
|
||||
list(APPEND COMP_DIRECTORY ${PROJECT_SOURCE_DIR})
|
||||
unset(COMP_${_TYPE})
|
||||
endif()
|
||||
# set the properties if defined
|
||||
if(COMP_${_TYPE})
|
||||
foreach(_VAL ${COMP_${_TYPE}})
|
||||
set_property(
|
||||
${_TYPE} ${_VAL}
|
||||
PROPERTY
|
||||
RULE_LAUNCH_COMPILE
|
||||
"${ROCPROFILER_REGISTER_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}"
|
||||
)
|
||||
set_property(
|
||||
${_TYPE} ${_VAL}
|
||||
PROPERTY
|
||||
RULE_LAUNCH_LINK
|
||||
"${ROCPROFILER_REGISTER_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}"
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(ROCPROFILER_REGISTER_WATCH_FOR_CHANGE _var)
|
||||
list(LENGTH ARGN _NUM_EXTRA_ARGS)
|
||||
if(_NUM_EXTRA_ARGS EQUAL 1)
|
||||
set(_VAR ${ARGN})
|
||||
else()
|
||||
set(_VAR)
|
||||
endif()
|
||||
|
||||
macro(update_var _VAL)
|
||||
if(_VAR)
|
||||
set(${_VAR}
|
||||
${_VAL}
|
||||
PARENT_SCOPE)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
update_var(OFF)
|
||||
|
||||
set(_rocprofiler_register_watch_var_name ROCPROFILER_REGISTER_WATCH_VALUE_${_var})
|
||||
if(DEFINED ${_rocprofiler_register_watch_var_name})
|
||||
if("${${_var}}" STREQUAL "${${_rocprofiler_register_watch_var_name}}")
|
||||
return()
|
||||
else()
|
||||
rocprofiler_register_message(
|
||||
STATUS
|
||||
"${_var} changed :: ${${_rocprofiler_register_watch_var_name}} --> ${${_var}}"
|
||||
)
|
||||
update_var(ON)
|
||||
endif()
|
||||
else()
|
||||
if(NOT "${${_var}}" STREQUAL "")
|
||||
rocprofiler_register_message(STATUS "${_var} :: ${${_var}}")
|
||||
update_var(ON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# store the value for the next run
|
||||
set(${_rocprofiler_register_watch_var_name}
|
||||
"${${_var}}"
|
||||
CACHE INTERNAL "Last value of ${_var}" FORCE)
|
||||
endfunction()
|
||||
|
||||
function(ROCPROFILER_REGISTER_DIRECTORY)
|
||||
cmake_parse_arguments(F "MKDIR;FAIL;FORCE" "PREFIX;OUTPUT_VARIABLE;WORKING_DIRECTORY"
|
||||
"PATHS" ${ARGN})
|
||||
|
||||
if(F_PREFIX AND NOT IS_ABSOLUTE "${F_PREFIX}")
|
||||
if(F_WORKING_DIRECTORY)
|
||||
rocprofiler_register_message(
|
||||
STATUS
|
||||
"PREFIX was specified as a relative path, using working directory + prefix :: '${F_WORKING_DIRECTORY}/${F_PREFIX}'..."
|
||||
)
|
||||
set(F_PREFIX ${F_WORKING_DIRECTORY}/${F_PREFIX})
|
||||
else()
|
||||
rocprofiler_register_message(
|
||||
FATAL_ERROR
|
||||
"PREFIX was specified but it is not an absolute path: ${F_PREFIX}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT F_WORKING_DIRECTORY)
|
||||
set(F_WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
foreach(_PATH ${F_PREFIX} ${F_PATHS})
|
||||
if(F_PREFIX AND NOT "${_PATH}" STREQUAL "${F_PREFIX}")
|
||||
# if path is relative, set to prefix + path
|
||||
if(NOT IS_ABSOLUTE "${_PATH}")
|
||||
set(_PATH ${F_PREFIX}/${_PATH})
|
||||
endif()
|
||||
list(APPEND _OUTPUT_VAR ${_PATH})
|
||||
elseif(NOT F_PREFIX)
|
||||
list(APPEND _OUTPUT_VAR ${_PATH})
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${_PATH}" AND F_FAIL)
|
||||
rocprofiler_register_message(FATAL_ERROR
|
||||
"Directory '${_PATH}' does not exist")
|
||||
elseif(NOT IS_DIRECTORY "${_PATH}" AND F_FAIL)
|
||||
rocprofiler_register_message(FATAL_ERROR
|
||||
"'${_PATH}' exists but is not a directory")
|
||||
elseif(NOT EXISTS "${_PATH}" AND F_MKDIR)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${_PATH}
|
||||
WORKING_DIRECTORY ${F_WORKING_DIRECTORY})
|
||||
elseif(
|
||||
EXISTS "${_PATH}"
|
||||
AND NOT IS_DIRECTORY "${_PATH}"
|
||||
AND F_MKDIR)
|
||||
if(F_FORCE)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E rm ${_PATH}
|
||||
WORKING_DIRECTORY ${F_WORKING_DIRECTORY})
|
||||
endif()
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${_PATH}
|
||||
WORKING_DIRECTORY ${F_WORKING_DIRECTORY})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(F_OUTPUT_VARIABLE)
|
||||
set(${F_OUTPUT_VARIABLE}
|
||||
"${_OUTPUT_VAR}"
|
||||
PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(ROCPROFILER_REGISTER_CHECK_PYTHON_DIRS_AND_VERSIONS)
|
||||
cmake_parse_arguments(F "FAIL;UNSET" "RESULT_VARIABLE;OUTPUT_VARIABLE" "" ${ARGN})
|
||||
|
||||
list(LENGTH ROCPROFILER_REGISTER_PYTHON_VERSIONS _NUM_PYTHON_VERSIONS)
|
||||
list(LENGTH ROCPROFILER_REGISTER_PYTHON_ROOT_DIRS _NUM_PYTHON_ROOT_DIRS)
|
||||
|
||||
if(NOT _NUM_PYTHON_VERSIONS EQUAL _NUM_PYTHON_ROOT_DIRS)
|
||||
set(_RET 1)
|
||||
else()
|
||||
set(_RET 0)
|
||||
if(F_OUTPUT_VARIABLE)
|
||||
set(${F_OUTPUT_VARIABLE}
|
||||
${_NUM_PYTHON_VERSIONS}
|
||||
PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(F_RESULT_VARIABLE)
|
||||
set(${F_RESULT_VARIABLE}
|
||||
${_RET}
|
||||
PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if(NOT ${_RET} EQUAL 0)
|
||||
if(F_FAIL)
|
||||
rocprofiler_register_message(
|
||||
WARNING
|
||||
"Error! Number of python versions : ${_NUM_PYTHON_VERSIONS}. VERSIONS :: ${ROCPROFILER_REGISTER_PYTHON_VERSIONS}"
|
||||
)
|
||||
rocprofiler_register_message(
|
||||
WARNING
|
||||
"Error! Number of python root directories : ${_NUM_PYTHON_ROOT_DIRS}. ROOT DIRS :: ${ROCPROFILER_REGISTER_PYTHON_ROOT_DIRS}"
|
||||
)
|
||||
rocprofiler_register_message(
|
||||
FATAL_ERROR
|
||||
"Error! Number of python versions != number of python root directories")
|
||||
elseif(F_UNSET)
|
||||
unset(ROCPROFILER_REGISTER_PYTHON_VERSIONS CACHE)
|
||||
unset(ROCPROFILER_REGISTER_PYTHON_ROOT_DIRS CACHE)
|
||||
if(F_OUTPUT_VARIABLE)
|
||||
set(${F_OUTPUT_VARIABLE} 0)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Console scripts
|
||||
#
|
||||
function(ROCPROFILER_REGISTER_PYTHON_CONSOLE_SCRIPT SCRIPT_NAME SCRIPT_SUBMODULE)
|
||||
set(options)
|
||||
set(args VERSION ROOT_DIR)
|
||||
set(kwargs)
|
||||
cmake_parse_arguments(ARG "${options}" "${args}" "${kwargs}" ${ARGN})
|
||||
|
||||
if(ARG_VERSION AND ARG_ROOT_DIR)
|
||||
set(Python3_ROOT_DIR "${ARG_ROOT_DIR}")
|
||||
find_package(Python3 ${ARG_VERSION} EXACT QUIET MODULE COMPONENTS Interpreter)
|
||||
set(PYTHON_EXECUTABLE "${Python3_EXECUTABLE}")
|
||||
configure_file(${PROJECT_SOURCE_DIR}/cmake/Templates/console-script.in
|
||||
${PROJECT_BINARY_DIR}/bin/${SCRIPT_NAME}-${ARG_VERSION} @ONLY)
|
||||
|
||||
if(CMAKE_INSTALL_PYTHONDIR)
|
||||
install(
|
||||
PROGRAMS ${PROJECT_BINARY_DIR}/bin/${SCRIPT_NAME}-${ARG_VERSION}
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
COMPONENT python
|
||||
OPTIONAL)
|
||||
endif()
|
||||
|
||||
if(ROCPROFILER_REGISTER_BUILD_TESTING OR ROCPROFILER_REGISTER_BUILD_PYTHON)
|
||||
add_test(
|
||||
NAME ${SCRIPT_NAME}-console-script-test-${ARG_VERSION}
|
||||
COMMAND ${PROJECT_BINARY_DIR}/bin/${SCRIPT_NAME}-${ARG_VERSION} --help
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
set_tests_properties(
|
||||
${SCRIPT_NAME}-console-script-test-${ARG_VERSION}
|
||||
PROPERTIES LABELS "python;python-${ARG_VERSION};console-script")
|
||||
add_test(
|
||||
NAME ${SCRIPT_NAME}-generic-console-script-test-${ARG_VERSION}
|
||||
COMMAND ${PROJECT_BINARY_DIR}/bin/${SCRIPT_NAME} --help
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
set_tests_properties(
|
||||
${SCRIPT_NAME}-generic-console-script-test-${ARG_VERSION}
|
||||
PROPERTIES ENVIRONMENT "PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}" LABELS
|
||||
"python;python-${ARG_VERSION};console-script")
|
||||
endif()
|
||||
else()
|
||||
set(PYTHON_EXECUTABLE "python3")
|
||||
|
||||
configure_file(${PROJECT_SOURCE_DIR}/cmake/Templates/console-script.in
|
||||
${PROJECT_BINARY_DIR}/bin/${SCRIPT_NAME} @ONLY)
|
||||
|
||||
if(CMAKE_INSTALL_PYTHONDIR)
|
||||
install(
|
||||
PROGRAMS ${PROJECT_BINARY_DIR}/bin/${SCRIPT_NAME}
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
COMPONENT python
|
||||
OPTIONAL)
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(ROCPROFILER_REGISTER_FIND_STATIC_LIBRARY)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
find_library(${ARGN})
|
||||
endfunction()
|
||||
|
||||
function(ROCPROFILER_REGISTER_FIND_SHARED_LIBRARY)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
find_library(${ARGN})
|
||||
endfunction()
|
||||
|
||||
function(ROCPROFILER_REGISTER_BUILDTREE_TPL _TPL_TARGET _NEW_NAME _BUILD_TREE_DIR)
|
||||
get_target_property(_TPL_VERSION ${_TPL_TARGET} VERSION)
|
||||
get_target_property(_TPL_SOVERSION ${_TPL_TARGET} SOVERSION)
|
||||
get_target_property(_TPL_NAME ${_TPL_TARGET} OUTPUT_NAME)
|
||||
set(_TPL_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX})
|
||||
set(_TPL_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
|
||||
foreach(_TAIL ${_TPL_SUFFIX} ${_TPL_SUFFIX}.${_TPL_SOVERSION}
|
||||
${_TPL_SUFFIX}.${_TPL_VERSION})
|
||||
set(_INP ${_TPL_PREFIX}${_TPL_NAME}${_TAIL})
|
||||
set(_OUT ${_TPL_PREFIX}${_NEW_NAME}${_TAIL})
|
||||
endforeach()
|
||||
|
||||
string(REPLACE " " "-" _TAIL "${ARGN}")
|
||||
|
||||
# build tree symbolic links
|
||||
add_custom_target(
|
||||
${_NEW_NAME}-build-tree-library${_TAIL} ALL
|
||||
${CMAKE_COMMAND} -E create_symlink $<TARGET_FILE:${_TPL_TARGET}>
|
||||
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION}
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E create_symlink
|
||||
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION}
|
||||
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E create_symlink
|
||||
${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
|
||||
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}
|
||||
WORKING_DIRECTORY ${_BUILD_TREE_DIR}
|
||||
DEPENDS ${_TPL_TARGET}
|
||||
COMMENT "Creating ${_NEW_NAME} from ${_TPL_TARGET}...")
|
||||
endfunction()
|
||||
|
||||
function(ROCPROFILER_REGISTER_INSTALL_TPL _TPL_TARGET _NEW_NAME _BUILD_TREE_DIR
|
||||
_COMPONENT)
|
||||
get_target_property(_TPL_VERSION ${_TPL_TARGET} VERSION)
|
||||
get_target_property(_TPL_SOVERSION ${_TPL_TARGET} SOVERSION)
|
||||
get_target_property(_TPL_NAME ${_TPL_TARGET} OUTPUT_NAME)
|
||||
set(_TPL_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX})
|
||||
set(_TPL_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
|
||||
foreach(_TAIL ${_TPL_SUFFIX} ${_TPL_SUFFIX}.${_TPL_SOVERSION}
|
||||
${_TPL_SUFFIX}.${_TPL_VERSION})
|
||||
set(_INP ${_TPL_PREFIX}${_TPL_NAME}${_TAIL})
|
||||
set(_OUT ${_TPL_PREFIX}${_NEW_NAME}${_TAIL})
|
||||
endforeach()
|
||||
|
||||
# build tree symbolic links
|
||||
rocprofiler_register_buildtree_tpl("${_TPL_TARGET}" "${_NEW_NAME}"
|
||||
"${_BUILD_TREE_DIR}" ${ARGN})
|
||||
|
||||
install(
|
||||
FILES $<TARGET_FILE:${_TPL_TARGET}>
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
COMPONENT ${_COMPONENT}
|
||||
RENAME ${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_VERSION})
|
||||
|
||||
install(
|
||||
FILES
|
||||
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}.${_TPL_SOVERSION}
|
||||
${_BUILD_TREE_DIR}/${_TPL_PREFIX}${_NEW_NAME}${_TPL_SUFFIX}
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
COMPONENT ${_COMPONENT})
|
||||
|
||||
endfunction()
|
||||
|
||||
function(COMPUTE_POW2_CEIL _OUTPUT _VALUE)
|
||||
find_package(Python3 COMPONENTS Interpreter)
|
||||
|
||||
if(Python3_FOUND)
|
||||
execute_process(
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE} -c
|
||||
"VALUE = ${_VALUE}; ispow2 = lambda x: x if (x and (not(x & (x - 1)))) else None; v = list(filter(ispow2, [x for x in range(VALUE, VALUE**2)])); print(v[0])"
|
||||
RESULT_VARIABLE _POW2_RET
|
||||
OUTPUT_VARIABLE _POW2_OUT
|
||||
ERROR_VARIABLE _POW2_ERR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if(_POW2_RET EQUAL 0)
|
||||
set(${_OUTPUT}
|
||||
${_POW2_OUT}
|
||||
PARENT_SCOPE)
|
||||
else()
|
||||
set(${_OUTPUT}
|
||||
"-1"
|
||||
PARENT_SCOPE)
|
||||
endif()
|
||||
else()
|
||||
set(${_OUTPUT}
|
||||
"-1"
|
||||
PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
cmake_policy(POP)
|
||||
@@ -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,6 @@
|
||||
#
|
||||
# Samples
|
||||
#
|
||||
project(rocprofiler-register-samples LANGUAGES C CXX)
|
||||
|
||||
add_subdirectory(library-implementation)
|
||||
@@ -0,0 +1,18 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||
|
||||
project(rocprofiler-register-library-implementation LANGUAGES C CXX)
|
||||
|
||||
if("${CMAKE_PROJECT_NAME}" STREQUAL "${PROJECT_NAME}")
|
||||
find_package(rocprofiler-register REQUIRED)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
endif()
|
||||
|
||||
add_library(rocp-reg-hip-demo SHARED)
|
||||
target_sources(rocp-reg-hip-demo PRIVATE demo.cpp demo.hpp)
|
||||
target_link_libraries(rocp-reg-hip-demo
|
||||
PRIVATE rocprofiler-register::rocprofiler-register)
|
||||
@@ -0,0 +1,120 @@
|
||||
#include "demo.hpp"
|
||||
|
||||
#include <rocprofiler-register/rocprofiler-register.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
|
||||
#define ROCP_REG_VERSION \
|
||||
ROCPROFILER_REGISTER_COMPUTE_VERSION_3( \
|
||||
HIP_VERSION_MAJOR, HIP_VERSION_MINOR, HIP_VERSION_PATCH)
|
||||
|
||||
ROCPROFILER_REGISTER_DEFINE_IMPORT(hip, ROCP_REG_VERSION)
|
||||
|
||||
namespace hip
|
||||
{
|
||||
namespace
|
||||
{
|
||||
auto&
|
||||
get_hip_api_table_impl()
|
||||
{
|
||||
static auto _table = std::atomic<HipApiTable*>{ nullptr };
|
||||
return _table;
|
||||
}
|
||||
|
||||
void
|
||||
register_profiler_impl()
|
||||
{
|
||||
static auto _const_api_table = HipApiTable{};
|
||||
initialize_hip_api_table(&_const_api_table);
|
||||
|
||||
// set this before any recursive opportunity arises
|
||||
get_hip_api_table_impl().exchange(&_const_api_table);
|
||||
|
||||
// create a copy of the api table for modification by registration
|
||||
static auto _profiler_api_table = HipApiTable{};
|
||||
copy_hip_api_table(&_profiler_api_table, &_const_api_table);
|
||||
|
||||
void* _profiler_api_table_v = static_cast<void*>(&_profiler_api_table);
|
||||
|
||||
auto lib_id = rocprofiler_register_library_indentifier_t{};
|
||||
auto success =
|
||||
rocprofiler_register_library_api_table("hip",
|
||||
&ROCPROFILER_REGISTER_IMPORT_FUNC(hip),
|
||||
ROCP_REG_VERSION,
|
||||
&_profiler_api_table_v,
|
||||
1,
|
||||
&lib_id);
|
||||
|
||||
if(success == 0)
|
||||
{
|
||||
auto* _api_table = &_const_api_table;
|
||||
if(!get_hip_api_table_impl().compare_exchange_strong(_api_table,
|
||||
&_profiler_api_table))
|
||||
{
|
||||
// with the current impl, if we ever get here, someone is calling one the
|
||||
// functions in this anonymous namespace that shouldn't
|
||||
std::cerr
|
||||
<< "register_profiler_impl expected the API table to be the internal "
|
||||
"implementation and yet it is not. something went wrong.\n";
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
register_profiler()
|
||||
{
|
||||
// this registration scheme is designed to minimize overhead once
|
||||
// registered (only pay cost of checking atomic boolean)
|
||||
// once the profiler is registered. If the library has not
|
||||
// been registered and two or more threads try to register concurrently
|
||||
// the first thread to acquire the lock below, will block the
|
||||
// threads until registration is complete. However,
|
||||
// if the same thread performing the registration re-enters this function
|
||||
// i.e. this library's API is called during registration, this function
|
||||
// will prevent a deadlock by not attempting to re-enter the
|
||||
// the call-once and not releasing any waiting threads by flipping
|
||||
// the _is_registered field to true.
|
||||
static auto _is_registered = std::atomic<bool>{ false };
|
||||
|
||||
if(!_is_registered.load(std::memory_order_acquire))
|
||||
{
|
||||
using mutex_t = std::recursive_mutex;
|
||||
using auto_lock_t = std::unique_lock<mutex_t>;
|
||||
static auto _once = std::once_flag{};
|
||||
static auto _mutex = mutex_t{};
|
||||
|
||||
// defer the lock so we can check for recursion
|
||||
auto _lk = auto_lock_t{ _mutex, std::defer_lock };
|
||||
|
||||
// this will be true if the same thread currently executing the call_once invokes
|
||||
// the library's API while registering the profiler (e.g. tool which wants to
|
||||
// instrument HIP API invokes a HIP function while registering with the profiler)
|
||||
// we allow this thread to proceed and access the "const" API table but
|
||||
// return so it does not flip _is_registered to true, which would result
|
||||
// in any subsequent threads not waiting until the library is fully registered,
|
||||
// resulting in missed callbacks for the tools
|
||||
if(_lk.owns_lock()) return;
|
||||
|
||||
// ensures any subsequent threads wait until the first thread
|
||||
// finishes registration
|
||||
_lk.lock();
|
||||
// call_once to ensure that we only register once
|
||||
std::call_once(_once, register_profiler_impl);
|
||||
// the first thread has completed registration and all
|
||||
// threads waiting on lock will be released and this
|
||||
// block will not be entered again
|
||||
_is_registered.exchange(true, std::memory_order_release);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
HipApiTable*
|
||||
get_hip_api_table()
|
||||
{
|
||||
register_profiler();
|
||||
return get_hip_api_table_impl().load(std::memory_order_relaxed);
|
||||
}
|
||||
} // namespace hip
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#define HIP_VERSION_MAJOR 1
|
||||
#define HIP_VERSION_MINOR 0
|
||||
#define HIP_VERSION_PATCH 0
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
extern "C" {
|
||||
// fake hip function
|
||||
void
|
||||
hip_init(void);
|
||||
}
|
||||
|
||||
namespace hip
|
||||
{
|
||||
struct HipApiTable
|
||||
{
|
||||
uint64_t size = 0;
|
||||
void (*functor)() = nullptr;
|
||||
};
|
||||
|
||||
// populates hip api table with function pointers
|
||||
inline void
|
||||
initialize_hip_api_table(HipApiTable* dst)
|
||||
{
|
||||
dst->size = sizeof(HipApiTable);
|
||||
dst->functor = &hip_init;
|
||||
}
|
||||
|
||||
// copies the api table from src to dst
|
||||
inline void
|
||||
copy_hip_api_table(HipApiTable* dst, const HipApiTable* src)
|
||||
{
|
||||
*dst = *src;
|
||||
}
|
||||
} // namespace hip
|
||||
@@ -0,0 +1,3 @@
|
||||
#
|
||||
# AddressSanitizer suppressions file for rocprofiler-register project.
|
||||
#
|
||||
@@ -0,0 +1,3 @@
|
||||
#
|
||||
# LeakSanitizer suppressions file for rocprofiler-register project.
|
||||
#
|
||||
Executable
+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 = "10.194.116.31/cdash"
|
||||
|
||||
|
||||
def which(cmd, require):
|
||||
v = shutil.which(cmd)
|
||||
if require and v is None:
|
||||
raise RuntimeError(f"{cmd} not found")
|
||||
return v if v is not None else ""
|
||||
|
||||
|
||||
def generate_custom(args, cmake_args, ctest_args):
|
||||
if not os.path.exists(args.binary_dir):
|
||||
os.makedirs(args.binary_dir)
|
||||
|
||||
if args.memcheck is not None:
|
||||
if args.coverage:
|
||||
raise ValueError(
|
||||
f"Enabling --memcheck={args.memcheck} and --coverage not supported"
|
||||
)
|
||||
cmake_args += [f"-DROCPROFILER_REGISTER_MEMCHECK={args.memcheck}"]
|
||||
|
||||
NAME = args.name
|
||||
SITE = args.site
|
||||
BUILD_JOBS = args.build_jobs
|
||||
SUBMIT_URL = args.submit_url
|
||||
SOURCE_DIR = os.path.realpath(args.source_dir)
|
||||
BINARY_DIR = os.path.realpath(args.binary_dir)
|
||||
CMAKE_ARGS = " ".join(cmake_args)
|
||||
CTEST_ARGS = " ".join(ctest_args)
|
||||
|
||||
GIT_CMD = which("git", require=True)
|
||||
GCOV_CMD = which("gcov", require=False)
|
||||
CMAKE_CMD = which("cmake", require=True)
|
||||
# CTEST_CMD = which("ctest", require=True)
|
||||
|
||||
NAME = re.sub(r"(.*)-([0-9]+)/merge", "PR_\\2_\\1", NAME)
|
||||
|
||||
DEFAULT_CMAKE_ARGS = " ".join(
|
||||
[f"-DROCPROFILER_REGISTER_BUILD_{x}=ON" for x in ["CI", "TESTS", "SAMPLES"]]
|
||||
)
|
||||
|
||||
MEMCHECK_TYPE = "" if args.memcheck is None else args.memcheck
|
||||
|
||||
MEMCHECK_SANITIZER_OPTIONS = ""
|
||||
MEMCHECK_SUPPRESSION_FILE = ""
|
||||
|
||||
if MEMCHECK_TYPE == "AddressSanitizer":
|
||||
MEMCHECK_SANITIZER_OPTIONS = "detect_leaks=0 use_sigaltstack=0"
|
||||
MEMCHECK_SUPPRESSION_FILE = f"{SOURCE_DIR}/scripts/address-sanitizer-suppr.txt"
|
||||
elif MEMCHECK_TYPE == "LeakSanitizer":
|
||||
MEMCHECK_SUPPRESSION_FILE = f"{SOURCE_DIR}/scripts/leak-sanitizer-suppr.txt"
|
||||
elif MEMCHECK_TYPE == "ThreadSanitizer":
|
||||
external_symbolizer_path = ""
|
||||
for version in range(8, 20):
|
||||
_symbolizer = shutil.which(f"llvm-symbolizer-{version}")
|
||||
if _symbolizer:
|
||||
external_symbolizer_path = f"external_symbolizer_path={_symbolizer}"
|
||||
os.environ["TSAN_OPTIONS"] = " ".join(
|
||||
[
|
||||
"history_size=5",
|
||||
"second_deadlock_stack=1",
|
||||
f"suppressions={SOURCE_DIR}/scripts/thread-sanitizer-suppr.txt",
|
||||
external_symbolizer_path,
|
||||
os.environ.get("TSAN_OPTIONS", ""),
|
||||
]
|
||||
)
|
||||
|
||||
return f"""
|
||||
set(CTEST_PROJECT_NAME "{_PROJECT_NAME}")
|
||||
set(CTEST_NIGHTLY_START_TIME "05:00:00 UTC")
|
||||
|
||||
set(CTEST_DROP_METHOD "http")
|
||||
set(CTEST_DROP_SITE_CDASH TRUE)
|
||||
set(CTEST_SUBMIT_URL "http://{SUBMIT_URL}")
|
||||
|
||||
set(CTEST_UPDATE_TYPE git)
|
||||
set(CTEST_UPDATE_VERSION_ONLY TRUE)
|
||||
set(CTEST_GIT_COMMAND {GIT_CMD})
|
||||
set(CTEST_GIT_INIT_SUBMODULES FALSE)
|
||||
|
||||
set(CTEST_OUTPUT_ON_FAILURE TRUE)
|
||||
set(CTEST_USE_LAUNCHERS TRUE)
|
||||
set(CMAKE_CTEST_ARGUMENTS --output-on-failure {CTEST_ARGS})
|
||||
|
||||
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS "100")
|
||||
set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS "100")
|
||||
set(CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE "51200")
|
||||
set(CTEST_CUSTOM_COVERAGE_EXCLUDE "/usr/.*;/opt/.*;.*external/.*;.*samples/.*;.*tests/.*")
|
||||
|
||||
set(CTEST_MEMORYCHECK_TYPE "{MEMCHECK_TYPE}")
|
||||
set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE "{MEMCHECK_SUPPRESSION_FILE}")
|
||||
set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS "{MEMCHECK_SANITIZER_OPTIONS}")
|
||||
|
||||
set(CTEST_SITE "{SITE}")
|
||||
set(CTEST_BUILD_NAME "{NAME}")
|
||||
|
||||
set(CTEST_SOURCE_DIRECTORY {SOURCE_DIR})
|
||||
set(CTEST_BINARY_DIRECTORY {BINARY_DIR})
|
||||
|
||||
set(CTEST_CONFIGURE_COMMAND "{CMAKE_CMD} -B {BINARY_DIR} {SOURCE_DIR} {DEFAULT_CMAKE_ARGS} {CMAKE_ARGS}")
|
||||
set(CTEST_BUILD_COMMAND "{CMAKE_CMD} --build {BINARY_DIR} --target all --parallel {BUILD_JOBS}")
|
||||
set(CTEST_COVERAGE_COMMAND {GCOV_CMD})
|
||||
"""
|
||||
|
||||
|
||||
def generate_dashboard_script(args):
|
||||
CODECOV = 1 if args.coverage else 0
|
||||
DASHBOARD_MODE = args.mode
|
||||
SOURCE_DIR = os.path.realpath(args.source_dir)
|
||||
BINARY_DIR = os.path.realpath(args.binary_dir)
|
||||
MEMCHECK = 1 if args.memcheck is not None else 0
|
||||
SUBMIT = 0 if args.disable_cdash else 1
|
||||
ARGN = "${ARGN}"
|
||||
|
||||
if args.memcheck == "ThreadSanitizer":
|
||||
MEMCHECK = 0
|
||||
|
||||
_script = f"""
|
||||
macro(dashboard_submit)
|
||||
if("{SUBMIT}" GREATER 0)
|
||||
ctest_submit({ARGN})
|
||||
endif()
|
||||
endmacro()
|
||||
"""
|
||||
|
||||
_script += """
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/CTestCustom.cmake")
|
||||
|
||||
macro(handle_error _message _ret)
|
||||
if(NOT ${${_ret}} EQUAL 0)
|
||||
dashboard_submit(PARTS Done RETURN_VALUE _submit_ret)
|
||||
message(FATAL_ERROR "${_message} failed: ${${_ret}}")
|
||||
endif()
|
||||
endmacro()
|
||||
"""
|
||||
|
||||
_script += f"""
|
||||
ctest_start({DASHBOARD_MODE})
|
||||
ctest_update(SOURCE "{SOURCE_DIR}" RETURN_VALUE _update_ret
|
||||
CAPTURE_CMAKE_ERROR _update_err)
|
||||
ctest_configure(BUILD "{BINARY_DIR}" RETURN_VALUE _configure_ret)
|
||||
dashboard_submit(PARTS Start Update Configure RETURN_VALUE _submit_ret)
|
||||
|
||||
if(NOT _update_err EQUAL 0)
|
||||
message(WARNING "ctest_update failed")
|
||||
endif()
|
||||
|
||||
handle_error("Configure" _configure_ret)
|
||||
|
||||
ctest_build(BUILD "{BINARY_DIR}" RETURN_VALUE _build_ret)
|
||||
dashboard_submit(PARTS Build RETURN_VALUE _submit_ret)
|
||||
|
||||
handle_error("Build" _build_ret)
|
||||
|
||||
if("{MEMCHECK}" GREATER 0)
|
||||
ctest_memcheck(BUILD "{BINARY_DIR}" RETURN_VALUE _test_ret)
|
||||
dashboard_submit(PARTS Test RETURN_VALUE _submit_ret)
|
||||
else()
|
||||
ctest_test(BUILD "{BINARY_DIR}" RETURN_VALUE _test_ret)
|
||||
dashboard_submit(PARTS Test RETURN_VALUE _submit_ret)
|
||||
endif()
|
||||
|
||||
if("{CODECOV}" GREATER 0)
|
||||
ctest_coverage(
|
||||
BUILD "{BINARY_DIR}"
|
||||
RETURN_VALUE _coverage_ret
|
||||
CAPTURE_CMAKE_ERROR _coverage_err)
|
||||
dashboard_submit(PARTS Coverage RETURN_VALUE _submit_ret)
|
||||
endif()
|
||||
|
||||
handle_error("Testing" _test_ret)
|
||||
|
||||
dashboard_submit(PARTS Done RETURN_VALUE _submit_ret)
|
||||
"""
|
||||
return _script
|
||||
|
||||
|
||||
def parse_cdash_args(args):
|
||||
BUILD_JOBS = multiprocessing.cpu_count()
|
||||
DASHBOARD_MODE = "Continuous"
|
||||
DASHBOARD_STAGES = [
|
||||
"Start",
|
||||
"Update",
|
||||
"Configure",
|
||||
"Build",
|
||||
"Test",
|
||||
"MemCheck",
|
||||
"Coverage",
|
||||
"Submit",
|
||||
]
|
||||
SOURCE_DIR = os.getcwd()
|
||||
BINARY_DIR = os.path.join(SOURCE_DIR, "build")
|
||||
SITE = socket.gethostname()
|
||||
SUBMIT_URL = f"{_BASE_URL}/submit.php?project={_PROJECT_NAME}"
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument(
|
||||
"-n", "--name", help="Job name", default=None, type=str, required=True
|
||||
)
|
||||
parser.add_argument("-s", "--site", help="Site name", default=SITE, type=str)
|
||||
parser.add_argument(
|
||||
"-q", "--quiet", help="Disable printing logs", action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-c", "--coverage", help="Enable code coverage", action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-j",
|
||||
"--build-jobs",
|
||||
help="Number of build tasks",
|
||||
default=BUILD_JOBS,
|
||||
type=int,
|
||||
)
|
||||
parser.add_argument(
|
||||
"-B",
|
||||
"--binary-dir",
|
||||
help="Build directory",
|
||||
default=BINARY_DIR,
|
||||
type=str,
|
||||
)
|
||||
parser.add_argument(
|
||||
"-S",
|
||||
"--source-dir",
|
||||
help="Source directory",
|
||||
default=SOURCE_DIR,
|
||||
type=str,
|
||||
)
|
||||
parser.add_argument(
|
||||
"-F",
|
||||
"--clean",
|
||||
help="Remove existing build directory",
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-M",
|
||||
"--mode",
|
||||
help="Dashboard mode",
|
||||
default=DASHBOARD_MODE,
|
||||
choices=("Continuous", "Nightly", "Experimental"),
|
||||
type=str,
|
||||
)
|
||||
parser.add_argument(
|
||||
"-T",
|
||||
"--stages",
|
||||
help="Dashboard stages",
|
||||
nargs="+",
|
||||
default=DASHBOARD_STAGES,
|
||||
choices=DASHBOARD_STAGES,
|
||||
type=str,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--submit-url",
|
||||
help="CDash submission site",
|
||||
default=SUBMIT_URL,
|
||||
type=str,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--repeat-until-pass",
|
||||
help="<N> for --repeat until-pass:<N>",
|
||||
default=None,
|
||||
type=int,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--repeat-until-fail",
|
||||
help="<N> for --repeat until-fail:<N>",
|
||||
default=None,
|
||||
type=int,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--repeat-after-timeout",
|
||||
help="<N> for --repeat after-timeout:<N>",
|
||||
default=None,
|
||||
type=int,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--disable-cdash",
|
||||
help="Disable submitting results to CDash dashboard",
|
||||
action="store_true",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--memcheck",
|
||||
help="Run dynamic analysis tool",
|
||||
default=None,
|
||||
type=str,
|
||||
choices=(
|
||||
"ThreadSanitizer",
|
||||
"AddressSanitizer",
|
||||
"LeakSanitizer",
|
||||
"UndefinedBehaviorSanitizer",
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--linter",
|
||||
help="Enable linting tool",
|
||||
default=None,
|
||||
type=str,
|
||||
choices=("clang-tidy",),
|
||||
)
|
||||
|
||||
return parser.parse_args(args)
|
||||
|
||||
|
||||
def parse_args(args=None):
|
||||
if args is None:
|
||||
args = sys.argv[1:]
|
||||
|
||||
index = 0
|
||||
input_args = []
|
||||
ctest_args = []
|
||||
cmake_args = []
|
||||
data = [input_args, cmake_args, ctest_args]
|
||||
cmd = os.path.basename(sys.argv[0])
|
||||
|
||||
for itr in args:
|
||||
if itr == "--":
|
||||
index += 1
|
||||
if index > 2:
|
||||
raise RuntimeError(
|
||||
f"Usage: {cmd} <options> -- <cmake-args> -- <ctest-args>"
|
||||
)
|
||||
else:
|
||||
data[index].append(itr)
|
||||
|
||||
cdash_args = parse_cdash_args(input_args)
|
||||
|
||||
if cdash_args.coverage:
|
||||
cmake_args += ["-DROCPROFILER_REGISTER_BUILD_CODECOV=ON"]
|
||||
|
||||
if cdash_args.linter == "clang-tidy":
|
||||
cmake_args += ["-DROCPROFILER_REGISTER_ENABLE_CLANG_TIDY=ON"]
|
||||
|
||||
def get_repeat_val(_param):
|
||||
_value = getattr(cdash_args, f"repeat_{_param}".replace("-", "_"))
|
||||
return [f"{_param}:{_value}"] if _value is not None and _value > 1 else []
|
||||
|
||||
repeat_args = (
|
||||
get_repeat_val("until-pass")
|
||||
+ get_repeat_val("until-fail")
|
||||
+ get_repeat_val("after-timeout")
|
||||
)
|
||||
ctest_args += ["--repeat"] + repeat_args if len(repeat_args) > 0 else []
|
||||
|
||||
return [cdash_args, cmake_args, ctest_args]
|
||||
|
||||
|
||||
def run(*args, **kwargs):
|
||||
import subprocess
|
||||
|
||||
return subprocess.run(*args, **kwargs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args, cmake_args, ctest_args = parse_args()
|
||||
|
||||
if args.clean and os.path.exists(args.binary_dir):
|
||||
if args.source_dir == args.binary_dir:
|
||||
raise RuntimeError(
|
||||
f"cannot clean binary directory == source directory ({args.source_dir})"
|
||||
)
|
||||
|
||||
shutil.rmtree(args.binary_dir)
|
||||
|
||||
if not os.path.exists(args.binary_dir):
|
||||
os.makedirs(args.binary_dir)
|
||||
|
||||
from textwrap import dedent
|
||||
|
||||
_config = dedent(generate_custom(args, cmake_args, ctest_args))
|
||||
_script = dedent(generate_dashboard_script(args))
|
||||
|
||||
if not args.quiet:
|
||||
sys.stderr.write(f"##### CTestCustom.cmake #####\n\n{_config}\n\n")
|
||||
sys.stderr.write(f"##### dashboard.cmake #####\n\n{_script}\n\n")
|
||||
|
||||
with open(os.path.join(args.binary_dir, "CTestCustom.cmake"), "w") as f:
|
||||
f.write(f"{_config}\n")
|
||||
|
||||
with open(os.path.join(args.binary_dir, "dashboard.cmake"), "w") as f:
|
||||
f.write(f"{_script}\n")
|
||||
|
||||
CTEST_CMD = which("ctest", require=True)
|
||||
|
||||
dashboard_args = ["-D"]
|
||||
for itr in args.stages:
|
||||
dashboard_args.append(f"{args.mode}{itr}")
|
||||
|
||||
try:
|
||||
if not args.quiet and len(ctest_args) == 0:
|
||||
ctest_args = ["--output-on-failure", "-V"]
|
||||
|
||||
run(
|
||||
[CTEST_CMD]
|
||||
+ dashboard_args
|
||||
+ [
|
||||
"-S",
|
||||
os.path.join(args.binary_dir, "dashboard.cmake"),
|
||||
]
|
||||
+ ctest_args,
|
||||
check=True,
|
||||
)
|
||||
finally:
|
||||
echo_files = []
|
||||
if "-VV" not in ctest_args and not args.quiet:
|
||||
for file in glob.glob(
|
||||
os.path.join(args.binary_dir, "Testing/Temporary/**"),
|
||||
recursive=True,
|
||||
):
|
||||
if not os.path.isfile(file):
|
||||
continue
|
||||
if re.match(
|
||||
r"Last(Start|Update|Configure|Build|Test).*\.log$",
|
||||
os.path.basename(file),
|
||||
) is None and "MemoryChecker" not in os.path.basename(file):
|
||||
continue
|
||||
|
||||
echo_files.append(file)
|
||||
|
||||
if echo_files:
|
||||
# sort alphabetically
|
||||
echo_files = sorted(echo_files)
|
||||
echo_files_sorted = []
|
||||
# loop over order we want
|
||||
for key in [
|
||||
"LastStart",
|
||||
"LastUpdate",
|
||||
"LastConfigure",
|
||||
"LastBuild",
|
||||
"LastTest",
|
||||
]:
|
||||
for file in echo_files:
|
||||
# if key in file, append
|
||||
if key in file:
|
||||
echo_files_sorted.append(file)
|
||||
echo_files_sorted += [x for x in echo_files if x not in echo_files_sorted]
|
||||
for file in echo_files_sorted:
|
||||
print(f"\n\n\n###### Reading {file}... ######\n\n\n")
|
||||
with open(file, "r") as inpf:
|
||||
fdata = inpf.read()
|
||||
oname = os.path.basename(file)
|
||||
if "LastTest" not in oname and "Coverage" not in oname:
|
||||
print(fdata)
|
||||
if oname.endswith(".log"):
|
||||
oname += ".log"
|
||||
with open(os.path.join(args.binary_dir, oname), "w") as outf:
|
||||
print(f"\n\n###### Writing {oname}... ######\n\n")
|
||||
outf.write(fdata)
|
||||
@@ -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)
|
||||
@@ -0,0 +1,13 @@
|
||||
#
|
||||
#
|
||||
# Installation of public headers
|
||||
#
|
||||
#
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/version.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/version.h @ONLY)
|
||||
|
||||
set(ROCPROFILER_REGISTER_INCLUDE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rocprofiler-register.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/version.h)
|
||||
|
||||
install(FILES ${ROCPROFILER_REGISTER_INCLUDE_FILES}
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/rocprofiler-register)
|
||||
@@ -0,0 +1,188 @@
|
||||
// Copyright (c) 2023 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <rocprofiler-register/version.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int (*rocprofiler_configure_callback_t)(void*);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
rocprofiler_configure_callback_t initialize;
|
||||
rocprofiler_configure_callback_t finalize;
|
||||
void* user_data;
|
||||
} rocprofiler_configure_result_t;
|
||||
|
||||
typedef uint32_t (*rocprofiler_register_import_func_t)(void);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t handle;
|
||||
} rocprofiler_register_library_indentifier_t;
|
||||
|
||||
/// @enum rocprofiler_register_error_code_t
|
||||
/// @brief enumeration of error codes
|
||||
///
|
||||
/// @var ROCP_REG_SUCCESS
|
||||
/// @brief Successful call to rocprofiler-register
|
||||
///
|
||||
/// @var ROCP_REG_NO_TOOLS
|
||||
/// @brief API table was not passed to rocprofiler because no rocprofiler tool
|
||||
/// configuration symbols were requested
|
||||
///
|
||||
/// @var ROCP_REG_DEADLOCK
|
||||
/// @brief The thread that is currently communicating the API tables to rocprofiler
|
||||
/// re-entered \ref rocprofiler_register_library_api_table
|
||||
///
|
||||
/// @var ROCP_REG_BAD_API_TABLE_LENGTH
|
||||
/// @brief Library provided an invalid API table length (likely zero)
|
||||
///
|
||||
/// @var ROCP_REG_UNSUPPORTED_API
|
||||
/// @brief Library is providing an API table name that is not supported
|
||||
///
|
||||
/// @var ROCP_REG_ROCPROFILER_ERROR
|
||||
/// @brief Rocprofiler returned an error when passing the API tables
|
||||
///
|
||||
/// @var ROCP_REG_EXCESS_API_INSTANCES
|
||||
/// @brief The same API has been registered too many times
|
||||
///
|
||||
typedef enum rocprofiler_register_error_code_t // NOLINT(performance-enum-size)
|
||||
{
|
||||
ROCP_REG_SUCCESS = 0,
|
||||
ROCP_REG_NO_TOOLS,
|
||||
ROCP_REG_DEADLOCK,
|
||||
ROCP_REG_BAD_API_TABLE_LENGTH,
|
||||
ROCP_REG_UNSUPPORTED_API,
|
||||
ROCP_REG_INVALID_API_ADDRESS,
|
||||
ROCP_REG_ROCPROFILER_ERROR,
|
||||
ROCP_REG_EXCESS_API_INSTANCES,
|
||||
ROCP_REG_ERROR_CODE_END,
|
||||
} rocprofiler_register_error_code_t;
|
||||
|
||||
/// @fn rocprofiler_register_error_code_t rocprofiler_register_library_api_table(
|
||||
/// const char* lib_name,
|
||||
/// rocprofiler_register_import_func_t import_func,
|
||||
/// uint32_t lib_version,
|
||||
/// void* api_tables,
|
||||
/// uint64_t api_table_length,
|
||||
/// rocprofiler_register_library_indentifier_t* register_id)
|
||||
/// @param[in] lib_name string identifier for the library registering the API table
|
||||
/// @param[in] import_func function pointer to rocprofiler_register_import_<lib_name>
|
||||
/// symbol
|
||||
/// @param[in] lib_version lib version in form of (10000 * major ) + (100 * minor) + patch
|
||||
/// @param[in] api_tables pointer to one or more API table pointers
|
||||
/// @param[in] api_table_length number of API tables that are being passed in. Must be > 0
|
||||
/// @param[out] register_id a unique identifier for this library encoding the API category
|
||||
/// and the priority in the event that multiple libraries register with the same name
|
||||
/// @returns value of type @ref rocprofiler_register_error_code_t
|
||||
///
|
||||
/// @brief primary function call that needs to be performed when the API table of the
|
||||
/// library is initialized.
|
||||
///
|
||||
rocprofiler_register_error_code_t
|
||||
rocprofiler_register_library_api_table(
|
||||
const char* lib_name,
|
||||
rocprofiler_register_import_func_t import_func,
|
||||
uint32_t lib_version,
|
||||
void** api_tables,
|
||||
uint64_t api_table_length,
|
||||
rocprofiler_register_library_indentifier_t* register_id)
|
||||
ROCPROFILER_REGISTER_ATTRIBUTE(nonnull(4, 6)) ROCPROFILER_REGISTER_PUBLIC_API;
|
||||
|
||||
const char* rocprofiler_register_error_string(rocprofiler_register_error_code_t)
|
||||
ROCPROFILER_REGISTER_PUBLIC_API;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @def ROCPROFILER_REGISTER_COMPUTE_VERSION_1
|
||||
/// @param[in] MAJOR_VERSION major version of library (integral)
|
||||
/// @brief Helper macro for users to generate versioning int expected by
|
||||
/// rocprofiler-register when the library only maintains a major version number
|
||||
#define ROCPROFILER_REGISTER_COMPUTE_VERSION_1(MAJOR_VERSION) (10000 * MAJOR_VERSION)
|
||||
|
||||
/// @def ROCPROFILER_REGISTER_COMPUTE_VERSION_
|
||||
/// @param[in] MAJOR_VERSION major version of library (integral)
|
||||
/// @param[in] MINOR_VERSION minor version of library (integral)
|
||||
/// @brief Helper macro for users to generate versioning int expected by
|
||||
/// rocprofiler-register when the library only maintains a major and minor version number
|
||||
#define ROCPROFILER_REGISTER_COMPUTE_VERSION_2(MAJOR_VERSION, MINOR_VERSION) \
|
||||
(ROCPROFILER_REGISTER_COMPUTE_VERSION_1(MAJOR_VERSION) + (100 * MINOR_VERSION))
|
||||
|
||||
/// @def ROCPROFILER_REGISTER_COMPUTE_VERSION_3
|
||||
/// @param[in] MAJOR_VERSION major version of library (integral)
|
||||
/// @param[in] MINOR_VERSION minor version of library (integral)
|
||||
/// @param[in] PATCH_VERSION patch version of library (integral)
|
||||
/// @brief Helper macro for users to generate versioning int expected by
|
||||
/// rocprofiler-register when the library maintains a major, minor, and patch version
|
||||
/// numbers
|
||||
#define ROCPROFILER_REGISTER_COMPUTE_VERSION_3( \
|
||||
MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION) \
|
||||
(ROCPROFILER_REGISTER_COMPUTE_VERSION_2(MAJOR_VERSION, MINOR_VERSION) + \
|
||||
(PATCH_VERSION))
|
||||
|
||||
/// @def ROCPROFILER_REGISTER_COMPUTE_VERSION_4
|
||||
/// @param[in] MAJOR_VERSION major version of library (integral)
|
||||
/// @param[in] MINOR_VERSION minor version of library (integral)
|
||||
/// @param[in] PATCH_VERSION patch version of library (integral)
|
||||
/// @param[in] TWEAK_VERSION tweak version of library which will be ignored
|
||||
/// @brief Helper macro for users to generate versioning int expected by
|
||||
/// rocprofiler-register when the library maintains a major, minor, patch, and tweak
|
||||
/// version numbers
|
||||
#define ROCPROFILER_REGISTER_COMPUTE_VERSION_3( \
|
||||
MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION) \
|
||||
(ROCPROFILER_REGISTER_COMPUTE_VERSION_2(MAJOR_VERSION, MINOR_VERSION) + \
|
||||
(PATCH_VERSION))
|
||||
|
||||
/// @def ROCPROFILER_REGISTER_IMPORT_FUNC(NAME)
|
||||
/// @param[in] NAME the string identifier for the library
|
||||
/// @brief Helper macro for retrieving the name of the import function which is used by
|
||||
/// rocprofiler-register to identify the location and priority of the registering library
|
||||
#define ROCPROFILER_REGISTER_IMPORT_FUNC(NAME) \
|
||||
ROCPROFILER_REGISTER_PP_COMBINE(rocprofiler_register_import_, NAME)
|
||||
|
||||
/// @def ROCPROFILER_REGISTER_DEFINE_IMPORT(NAME, VERSION)
|
||||
/// @param[in] NAME the unquoted string identifier for the library, e.g. hip
|
||||
/// @brief Helper macro for declaring a visible import symbol for rocprofiler-register
|
||||
/// which returns the version.
|
||||
///
|
||||
#ifdef __cplusplus
|
||||
# define ROCPROFILER_REGISTER_DEFINE_IMPORT(NAME, VERSION) \
|
||||
extern "C" { \
|
||||
uint32_t ROCPROFILER_REGISTER_IMPORT_FUNC(NAME)() \
|
||||
ROCPROFILER_REGISTER_ATTRIBUTE(visibility("default")); \
|
||||
\
|
||||
uint32_t ROCPROFILER_REGISTER_IMPORT_FUNC(NAME)() { return VERSION; } \
|
||||
}
|
||||
#else
|
||||
# define ROCPROFILER_REGISTER_DEFINE_IMPORT(NAME, VERSION) \
|
||||
uint32_t ROCPROFILER_REGISTER_IMPORT_FUNC(NAME)(void) \
|
||||
ROCPROFILER_REGISTER_ATTRIBUTE(visibility("default")); \
|
||||
\
|
||||
uint32_t ROCPROFILER_REGISTER_IMPORT_FUNC(NAME)(void) { return VERSION; }
|
||||
#endif
|
||||
@@ -0,0 +1,103 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
#define ROCPROFILER_REGISTER_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
|
||||
#define ROCPROFILER_REGISTER_VERSION_MINOR @PROJECT_VERSION_MINOR@
|
||||
#define ROCPROFILER_REGISTER_VERSION_PATCH @PROJECT_VERSION_PATCH@
|
||||
#define ROCPROFILER_REGISTER_VERSION_STRING "@FULL_VERSION_STRING@"
|
||||
#define ROCPROFILER_REGISTER_SOVERSION "@PROJECT_VERSION_MAJOR@"
|
||||
#define ROCPROFILER_REGISTER_GIT_DESCRIBE "@ROCPROFILER_REGISTER_GIT_DESCRIBE@"
|
||||
#define ROCPROFILER_REGISTER_GIT_REVISION "@ROCPROFILER_REGISTER_GIT_REVISION@"
|
||||
|
||||
// system info during compilation
|
||||
#define ROCPROFILER_REGISTER_LIBRARY_ARCH "@CMAKE_LIBRARY_ARCHITECTURE@"
|
||||
#define ROCPROFILER_REGISTER_SYSTEM_NAME "@CMAKE_SYSTEM_NAME@"
|
||||
#define ROCPROFILER_REGISTER_SYSTEM_PROCESSOR "@CMAKE_SYSTEM_PROCESSOR@"
|
||||
#define ROCPROFILER_REGISTER_SYSTEM_VERSION "@CMAKE_SYSTEM_VERSION@"
|
||||
|
||||
// compiler information
|
||||
#define ROCPROFILER_REGISTER_COMPILER_ID "@CMAKE_CXX_COMPILER_ID@"
|
||||
#define ROCPROFILER_REGISTER_COMPILER_VERSION "@CMAKE_CXX_COMPILER_VERSION@"
|
||||
#define ROCPROFILER_REGISTER_COMPILER_STRING ROCPROFILER_REGISTER_COMPILER_ID " v" ROCPROFILER_REGISTER_COMPILER_VERSION
|
||||
// clang-format on
|
||||
|
||||
#define ROCPROFILER_REGISTER_VERSION \
|
||||
((10000 * ROCPROFILER_REGISTER_VERSION_MAJOR) + \
|
||||
(100 * ROCPROFILER_REGISTER_VERSION_MINOR) + ROCPROFILER_REGISTER_VERSION_PATCH)
|
||||
|
||||
#define ROCPROFILER_REGISTER_ATTRIBUTE(...) __attribute__((__VA_ARGS__))
|
||||
#define ROCPROFILER_REGISTER_PP_COMBINE(X, Y) X##Y
|
||||
|
||||
#if defined(rocprofiler_register_EXPORTS)
|
||||
// only defined in build tree
|
||||
# define ROCPROFILER_REGISTER_VISIBILITY(MODE) \
|
||||
ROCPROFILER_REGISTER_ATTRIBUTE(visibility(MODE))
|
||||
# define ROCPROFILER_REGISTER_PUBLIC_API ROCPROFILER_REGISTER_VISIBILITY("default")
|
||||
# define ROCPROFILER_REGISTER_HIDDEN_API ROCPROFILER_REGISTER_VISIBILITY("hidden")
|
||||
# define ROCPROFILER_REGISTER_INTERNAL_API ROCPROFILER_REGISTER_VISIBILITY("internal")
|
||||
# define ROCPROFILER_REGISTER_INLINE \
|
||||
ROCPROFILER_REGISTER_ATTRIBUTE(always_inline) inline
|
||||
# define ROCPROFILER_REGISTER_NOINLINE ROCPROFILER_REGISTER_ATTRIBUTE(noinline)
|
||||
# define ROCPROFILER_REGISTER_HOT ROCPROFILER_REGISTER_ATTRIBUTE(hot)
|
||||
# define ROCPROFILER_REGISTER_COLD ROCPROFILER_REGISTER_ATTRIBUTE(cold)
|
||||
# define ROCPROFILER_REGISTER_CONST ROCPROFILER_REGISTER_ATTRIBUTE(const)
|
||||
# define ROCPROFILER_REGISTER_PURE ROCPROFILER_REGISTER_ATTRIBUTE(pure)
|
||||
# define ROCPROFILER_REGISTER_WEAK ROCPROFILER_REGISTER_ATTRIBUTE(weak)
|
||||
# define ROCPROFILER_REGISTER_PACKED ROCPROFILER_REGISTER_ATTRIBUTE(__packed__)
|
||||
# define ROCPROFILER_REGISTER_PACKED_ALIGN(VAL) \
|
||||
ROCPROFILER_REGISTER_PACKED ROCPROFILER_REGISTER_ATTRIBUTE(__aligned__(VAL))
|
||||
# define ROCPROFILER_REGISTER_LIKELY(...) __builtin_expect((__VA_ARGS__), 1)
|
||||
# define ROCPROFILER_REGISTER_UNLIKELY(...) __builtin_expect((__VA_ARGS__), 0)
|
||||
|
||||
# if defined(ROCPROFILER_REGISTER_CI) && ROCPROFILER_REGISTER_CI > 0
|
||||
# if defined(NDEBUG)
|
||||
# undef NDEBUG
|
||||
# endif
|
||||
# if !defined(DEBUG)
|
||||
# define DEBUG 1
|
||||
# endif
|
||||
# if defined(__cplusplus)
|
||||
# include <cassert> // NOLINT
|
||||
# else
|
||||
# include <assert.h>
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# define ROCPROFILER_REGISTER_STRINGIZE(X) ROCPROFILER_REGISTER_STRINGIZE2(X)
|
||||
# define ROCPROFILER_REGISTER_STRINGIZE2(X) # X
|
||||
# define ROCPROFILER_REGISTER_LINESTR ROCPROFILER_REGISTER_STRINGIZE(__LINE__)
|
||||
# define ROCPROFILER_REGISTER_ESC(...) __VA_ARGS__
|
||||
|
||||
# if defined(__cplusplus)
|
||||
# if !defined(ROCPROFILER_REGISTER_FOLD_EXPRESSION)
|
||||
# define ROCPROFILER_REGISTER_FOLD_EXPRESSION(...) ((__VA_ARGS__), ...)
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# define ROCPROFILER_REGISTER_VISIBILITY(MODE)
|
||||
# define ROCPROFILER_REGISTER_PUBLIC_API
|
||||
# define ROCPROFILER_REGISTER_HIDDEN_API
|
||||
# define ROCPROFILER_REGISTER_INTERNAL_API
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
#
|
||||
#
|
||||
#
|
||||
add_subdirectory(rocprofiler-register)
|
||||
@@ -0,0 +1,36 @@
|
||||
#
|
||||
# builds the rocprofiler-register library
|
||||
#
|
||||
add_library(rocprofiler-register SHARED)
|
||||
add_library(rocprofiler-register::rocprofiler-register ALIAS rocprofiler-register)
|
||||
|
||||
add_subdirectory(details)
|
||||
|
||||
target_sources(rocprofiler-register PRIVATE rocprofiler_register.cpp)
|
||||
|
||||
if(ROCPROFILER_REGISTER_BUILD_TESTS)
|
||||
# make sure header is C-compatible
|
||||
target_sources(rocprofiler-register PRIVATE rocprofiler_register.c)
|
||||
endif()
|
||||
|
||||
target_include_directories(
|
||||
rocprofiler-register PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/source
|
||||
${PROJECT_BINARY_DIR}/source)
|
||||
|
||||
target_link_libraries(
|
||||
rocprofiler-register
|
||||
PUBLIC rocprofiler-register::headers
|
||||
PRIVATE rocprofiler-register::build-flags rocprofiler-register::memcheck
|
||||
rocprofiler-register::stdcxxfs rocprofiler-register::dl)
|
||||
|
||||
set_target_properties(
|
||||
rocprofiler-register
|
||||
PROPERTIES OUTPUT_NAME rocprofiler-register
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
VERSION ${PROJECT_VERSION})
|
||||
|
||||
install(
|
||||
TARGETS rocprofiler-register
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
COMPONENT core
|
||||
EXPORT ${PROJECT_NAME}-library-targets)
|
||||
@@ -0,0 +1,10 @@
|
||||
#
|
||||
# builds the rocprofiler-register library
|
||||
#
|
||||
set(rocprofiler_register_details_sources dl.cpp utility.cpp)
|
||||
|
||||
set(rocprofiler_register_details_headers environment.hpp join.hpp dl.hpp log.hpp
|
||||
utility.hpp)
|
||||
|
||||
target_sources(rocprofiler-register PRIVATE ${rocprofiler_register_details_sources}
|
||||
${rocprofiler_register_details_headers})
|
||||
@@ -0,0 +1,125 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#define GNU_SOURCE 1
|
||||
|
||||
#include "dl.hpp"
|
||||
#include "join.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <elf.h>
|
||||
#include <link.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace fs = ::std::filesystem;
|
||||
|
||||
namespace rocprofiler_register
|
||||
{
|
||||
namespace binary
|
||||
{
|
||||
namespace
|
||||
{
|
||||
const open_modes_vec_t default_link_open_modes = { (RTLD_LAZY | RTLD_NOLOAD),
|
||||
(RTLD_LAZY | RTLD_LOCAL) };
|
||||
} // namespace
|
||||
|
||||
std::vector<segment_address_ranges>
|
||||
get_segment_addresses(pid_t _pid)
|
||||
{
|
||||
auto _data = std::vector<segment_address_ranges>{};
|
||||
auto _fname = common::join('/', "/proc", _pid, "maps");
|
||||
auto ifs = std::ifstream{ _fname };
|
||||
if(!ifs)
|
||||
{
|
||||
fprintf(stderr, "Failure opening %s\n", _fname.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto _get_entry = [&_data](std::string_view _name) -> segment_address_ranges& {
|
||||
for(auto& itr : _data)
|
||||
{
|
||||
if(itr.filepath == _name) return itr;
|
||||
}
|
||||
return _data.emplace_back(
|
||||
segment_address_ranges{ .filepath = std::string{ _name } });
|
||||
};
|
||||
|
||||
while(ifs)
|
||||
{
|
||||
std::string _line = {};
|
||||
if(std::getline(ifs, _line) && !_line.empty())
|
||||
{
|
||||
auto _delim = utility::delimit(_line, " \t\n\r");
|
||||
if(_delim.size() > 5 && fs::exists(fs::path{ _delim.back() }))
|
||||
{
|
||||
auto& _entry = _get_entry(_delim.back());
|
||||
auto _addr = utility::delimit(_delim.front(), "-");
|
||||
auto load_address = std::stoull(_addr.front(), nullptr, 16);
|
||||
auto last_address = std::stoull(_addr.back(), nullptr, 16);
|
||||
_entry.ranges.emplace_back(
|
||||
address_range{ load_address, last_address });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return _data;
|
||||
}
|
||||
|
||||
std::optional<std::string>
|
||||
get_linked_path(std::string_view _name, open_modes_vec_t&& _open_modes)
|
||||
{
|
||||
if(_name.empty()) return fs::current_path().string();
|
||||
|
||||
if(_open_modes.empty()) _open_modes = default_link_open_modes;
|
||||
|
||||
void* _handle = nullptr;
|
||||
bool _noload = false;
|
||||
for(auto _mode : _open_modes)
|
||||
{
|
||||
_handle = dlopen(_name.data(), _mode);
|
||||
_noload = (_mode & RTLD_NOLOAD) == RTLD_NOLOAD;
|
||||
if(_handle) break;
|
||||
}
|
||||
|
||||
if(_handle)
|
||||
{
|
||||
struct link_map* _link_map = nullptr;
|
||||
dlinfo(_handle, RTLD_DI_LINKMAP, &_link_map);
|
||||
if(_link_map != nullptr && !std::string_view{ _link_map->l_name }.empty())
|
||||
{
|
||||
return fs::absolute(fs::path{ _link_map->l_name }).string();
|
||||
}
|
||||
if(_noload == false) dlclose(_handle);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
} // namespace binary
|
||||
} // namespace rocprofiler_register
|
||||
@@ -0,0 +1,60 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace rocprofiler_register
|
||||
{
|
||||
namespace binary
|
||||
{
|
||||
using open_modes_vec_t = std::vector<int>;
|
||||
|
||||
struct address_range
|
||||
{
|
||||
uintptr_t start = 0;
|
||||
uintptr_t last = 0;
|
||||
};
|
||||
|
||||
struct segment_address_ranges
|
||||
{
|
||||
std::string filepath = {};
|
||||
std::vector<address_range> ranges = {};
|
||||
};
|
||||
|
||||
std::vector<segment_address_ranges>
|
||||
get_segment_addresses(pid_t _pid = getpid());
|
||||
|
||||
// helper function for translating generic lib name to resolved path
|
||||
std::optional<std::string>
|
||||
get_linked_path(std::string_view, open_modes_vec_t&& = {});
|
||||
} // namespace binary
|
||||
} // namespace rocprofiler_register
|
||||
@@ -0,0 +1,191 @@
|
||||
// Copyright (c) 2023 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "log.hpp"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(ROCPROFILER_REGISTER_ENVIRON_LOG_NAME)
|
||||
# if defined(ROCPROFILER_REGISTER_COMMON_LIBRARY_NAME)
|
||||
# define ROCPROFILER_REGISTER_ENVIRON_LOG_NAME \
|
||||
"[" ROCPROFILER_REGISTER_COMMON_LIBRARY_NAME "]"
|
||||
# else
|
||||
# define ROCPROFILER_REGISTER_ENVIRON_LOG_NAME "[environ]"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(ROCPROFILER_REGISTER_ENVIRON_LOG_START)
|
||||
# if defined(ROCPROFILER_REGISTER_COMMON_LIBRARY_LOG_START)
|
||||
# define ROCPROFILER_REGISTER_ENVIRON_LOG_START \
|
||||
ROCPROFILER_REGISTER_COMMON_LIBRARY_LOG_START
|
||||
# elif defined(ROCPROFILER_REGISTER_LOG_COLORS_AVAILABLE)
|
||||
# define ROCPROFILER_REGISTER_ENVIRON_LOG_START \
|
||||
fprintf(stderr, "%s", ::rocprofiler_register::log::color::dmesg());
|
||||
# else
|
||||
# define ROCPROFILER_REGISTER_ENVIRON_LOG_START
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(ROCPROFILER_REGISTER_ENVIRON_LOG_END)
|
||||
# if defined(ROCPROFILER_REGISTER_COMMON_LIBRARY_LOG_END)
|
||||
# define ROCPROFILER_REGISTER_ENVIRON_LOG_END \
|
||||
ROCPROFILER_REGISTER_COMMON_LIBRARY_LOG_END
|
||||
# elif defined(ROCPROFILER_REGISTER_LOG_COLORS_AVAILABLE)
|
||||
# define ROCPROFILER_REGISTER_ENVIRON_LOG_END \
|
||||
fprintf(stderr, "%s", ::rocprofiler_register::log::color::end());
|
||||
# else
|
||||
# define ROCPROFILER_REGISTER_ENVIRON_LOG_END
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define ROCPROFILER_REGISTER_ENVIRON_LOG(CONDITION, ...) \
|
||||
if(CONDITION) \
|
||||
{ \
|
||||
fflush(stderr); \
|
||||
ROCPROFILER_REGISTER_ENVIRON_LOG_START \
|
||||
fprintf(stderr, \
|
||||
"[rocprofiler-register]" ROCPROFILER_REGISTER_ENVIRON_LOG_NAME "[%i] ", \
|
||||
getpid()); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
ROCPROFILER_REGISTER_ENVIRON_LOG_END \
|
||||
fflush(stderr); \
|
||||
}
|
||||
|
||||
namespace rocprofiler_register
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
namespace
|
||||
{
|
||||
inline std::string
|
||||
get_env_impl(std::string_view env_id, std::string_view _default)
|
||||
{
|
||||
if(env_id.empty()) return std::string{ _default };
|
||||
char* env_var = ::std::getenv(env_id.data());
|
||||
if(env_var) return std::string{ env_var };
|
||||
return std::string{ _default };
|
||||
}
|
||||
|
||||
inline std::string
|
||||
get_env_impl(std::string_view env_id, const char* _default)
|
||||
{
|
||||
return get_env_impl(env_id, std::string_view{ _default });
|
||||
}
|
||||
|
||||
inline int
|
||||
get_env_impl(std::string_view env_id, int _default)
|
||||
{
|
||||
if(env_id.empty()) return _default;
|
||||
char* env_var = ::std::getenv(env_id.data());
|
||||
if(env_var)
|
||||
{
|
||||
try
|
||||
{
|
||||
return std::stoi(env_var);
|
||||
} catch(std::exception& _e)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"[rocprofiler_register][get_env] Exception thrown converting "
|
||||
"getenv(\"%s\") = "
|
||||
"%s to integer :: %s. Using default value of %i\n",
|
||||
env_id.data(),
|
||||
env_var,
|
||||
_e.what(),
|
||||
_default);
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
|
||||
inline bool
|
||||
get_env_impl(std::string_view env_id, bool _default)
|
||||
{
|
||||
if(env_id.empty()) return _default;
|
||||
char* env_var = ::std::getenv(env_id.data());
|
||||
if(env_var)
|
||||
{
|
||||
if(std::string_view{ env_var }.empty())
|
||||
{
|
||||
throw std::runtime_error(std::string{ "No boolean value provided for " } +
|
||||
std::string{ env_id });
|
||||
}
|
||||
|
||||
if(std::string_view{ env_var }.find_first_not_of("0123456789") ==
|
||||
std::string_view::npos)
|
||||
{
|
||||
return static_cast<bool>(std::stoi(env_var));
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < strlen(env_var); ++i)
|
||||
env_var[i] = tolower(env_var[i]);
|
||||
for(const auto& itr : { "off", "false", "no", "n", "f", "0" })
|
||||
if(strcmp(env_var, itr) == 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
return _default;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
template <typename Tp>
|
||||
inline auto
|
||||
get_env(std::string_view env_id, Tp&& _default)
|
||||
{
|
||||
if constexpr(std::is_enum<Tp>::value)
|
||||
{
|
||||
using Up = std::underlying_type_t<Tp>;
|
||||
// cast to underlying type -> get_env -> cast to enum type
|
||||
return static_cast<Tp>(get_env_impl(env_id, static_cast<Up>(_default)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_env_impl(env_id, std::forward<Tp>(_default));
|
||||
}
|
||||
}
|
||||
|
||||
struct env_config
|
||||
{
|
||||
std::string env_name = {};
|
||||
std::string env_value = {};
|
||||
int override = 0;
|
||||
|
||||
auto operator()(bool _verbose = false) const
|
||||
{
|
||||
if(env_name.empty()) return -1;
|
||||
ROCPROFILER_REGISTER_ENVIRON_LOG(_verbose,
|
||||
"setenv(\"%s\", \"%s\", %i)\n",
|
||||
env_name.c_str(),
|
||||
env_value.c_str(),
|
||||
override);
|
||||
return setenv(env_name.c_str(), env_value.c_str(), override);
|
||||
}
|
||||
};
|
||||
} // namespace common
|
||||
} // namespace rocprofiler_register
|
||||
@@ -0,0 +1,184 @@
|
||||
// Copyright (c) 2023 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <initializer_list>
|
||||
#include <ios>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
#if !defined(ROCPROFILER_REGISTER_FOLD_EXPRESSION)
|
||||
# define ROCPROFILER_REGISTER_FOLD_EXPRESSION(...) ((__VA_ARGS__), ...)
|
||||
#endif
|
||||
|
||||
namespace rocprofiler_register
|
||||
{
|
||||
namespace common
|
||||
{
|
||||
namespace
|
||||
{
|
||||
template <typename Tp>
|
||||
struct is_string_impl : std::false_type
|
||||
{ };
|
||||
|
||||
template <>
|
||||
struct is_string_impl<std::string> : std::true_type
|
||||
{ };
|
||||
|
||||
template <>
|
||||
struct is_string_impl<std::string_view> : std::true_type
|
||||
{ };
|
||||
|
||||
template <>
|
||||
struct is_string_impl<const char*> : std::true_type
|
||||
{ };
|
||||
|
||||
template <>
|
||||
struct is_string_impl<char*> : std::true_type
|
||||
{ };
|
||||
|
||||
template <typename Tp>
|
||||
struct is_string : is_string_impl<std::remove_cv_t<std::decay_t<Tp>>>
|
||||
{ };
|
||||
|
||||
template <typename ArgT>
|
||||
auto
|
||||
as_string(ArgT&& _v, std::enable_if_t<is_string<ArgT>::value, int> = 0)
|
||||
{
|
||||
if constexpr(std::is_pointer<std::decay_t<ArgT>>::value)
|
||||
{
|
||||
return (_v == nullptr) ? std::string{ "\"\"" }
|
||||
: (std::string{ "\"" } + _v + std::string{ "\"" });
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::string{ "\"" } + _v + std::string{ "\"" };
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ArgT>
|
||||
auto
|
||||
as_string(ArgT&& _v, std::enable_if_t<!is_string<ArgT>::value, long> = 0)
|
||||
{
|
||||
return _v;
|
||||
}
|
||||
|
||||
template <typename DelimT, typename... Args>
|
||||
auto
|
||||
join(DelimT&& _delim, Args&&... _args)
|
||||
{
|
||||
using delim_type = std::remove_cv_t<std::remove_reference_t<DelimT>>;
|
||||
|
||||
std::stringstream _ss{};
|
||||
_ss << std::boolalpha;
|
||||
|
||||
if constexpr(std::is_same<delim_type, char>::value)
|
||||
{
|
||||
const char _delim_c[2] = { _delim, '\0' };
|
||||
ROCPROFILER_REGISTER_FOLD_EXPRESSION(_ss << _delim_c << _args);
|
||||
auto _ret = _ss.str();
|
||||
return (_ret.length() > 1) ? _ret.substr(1) : std::string{};
|
||||
}
|
||||
else
|
||||
{
|
||||
ROCPROFILER_REGISTER_FOLD_EXPRESSION(_ss << _delim << _args);
|
||||
auto _ret = _ss.str();
|
||||
auto&& _len = std::string{ _delim }.length();
|
||||
return (_ret.length() > _len) ? _ret.substr(_len) : std::string{};
|
||||
}
|
||||
}
|
||||
|
||||
struct QuoteStrings
|
||||
{ };
|
||||
|
||||
template <typename DelimT, typename... Args>
|
||||
auto
|
||||
join(QuoteStrings&&, DelimT&& _delim, Args&&... _args)
|
||||
{
|
||||
using delim_type = std::remove_cv_t<std::remove_reference_t<DelimT>>;
|
||||
|
||||
std::stringstream _ss{};
|
||||
_ss << std::boolalpha;
|
||||
|
||||
if constexpr(std::is_same<delim_type, char>::value)
|
||||
{
|
||||
const char _delim_c[2] = { _delim, '\0' };
|
||||
ROCPROFILER_REGISTER_FOLD_EXPRESSION(_ss << _delim_c << as_string(_args));
|
||||
auto _ret = _ss.str();
|
||||
return (_ret.length() > 1) ? _ret.substr(1) : std::string{};
|
||||
}
|
||||
else
|
||||
{
|
||||
ROCPROFILER_REGISTER_FOLD_EXPRESSION(_ss << _delim << as_string(_args));
|
||||
auto _ret = _ss.str();
|
||||
auto&& _len = std::string{ _delim }.length();
|
||||
return (_ret.length() > _len) ? _ret.substr(_len) : std::string{};
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
auto
|
||||
join(std::array<std::string_view, 3>&& _delim, Args&&... _args)
|
||||
{
|
||||
return join("",
|
||||
std::get<0>(_delim),
|
||||
join(std::get<1>(_delim), std::forward<Args>(_args)...),
|
||||
std::get<2>(_delim));
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
auto
|
||||
join(QuoteStrings&&, std::array<std::string_view, 3>&& _delim, Args&&... _args)
|
||||
{
|
||||
return join(QuoteStrings{},
|
||||
"",
|
||||
std::get<0>(_delim),
|
||||
join(std::get<1>(_delim), std::forward<Args>(_args)...),
|
||||
std::get<2>(_delim));
|
||||
}
|
||||
|
||||
template <typename DelimB, typename DelimT, typename DelimE, typename... Args>
|
||||
auto
|
||||
join(std::tuple<DelimB, DelimT, DelimE>&& _delim, Args&&... _args)
|
||||
{
|
||||
return join("",
|
||||
std::get<0>(_delim),
|
||||
join(std::get<1>(_delim), std::forward<Args>(_args)...),
|
||||
std::get<2>(_delim));
|
||||
}
|
||||
|
||||
template <typename DelimB, typename DelimT, typename DelimE, typename... Args>
|
||||
auto
|
||||
join(QuoteStrings&&, std::tuple<DelimB, DelimT, DelimE>&& _delim, Args&&... _args)
|
||||
{
|
||||
return join(QuoteStrings{},
|
||||
"",
|
||||
std::get<0>(_delim),
|
||||
join(std::get<1>(_delim), std::forward<Args>(_args)...),
|
||||
std::get<2>(_delim));
|
||||
}
|
||||
} // namespace
|
||||
} // namespace common
|
||||
} // namespace rocprofiler_register
|
||||
@@ -0,0 +1,518 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2020, The Regents of the University of California,
|
||||
// through Lawrence Berkeley National Laboratory (subject to receipt of any
|
||||
// required approvals from the U.S. Dept. of Energy). All rights reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR rhs
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR rhsWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR rhs DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <rocprofiler-register/version.h>
|
||||
|
||||
#ifndef ROCPROFILER_REGISTER_LOG_COLORS_AVAILABLE
|
||||
# define ROCPROFILER_REGISTER_LOG_COLORS_AVAILABLE 1
|
||||
#endif
|
||||
|
||||
#ifndef ROCPROFILER_REGISTER_PROJECT_NAME
|
||||
# define ROCPROFILER_REGISTER_PROJECT_NAME "rocprofiler-register"
|
||||
#endif
|
||||
|
||||
#ifndef ROCP_REG_FILE_NAME
|
||||
# define ROCP_REG_FILE_NAME \
|
||||
::std::string{ __FILE__ } \
|
||||
.substr(::std::string_view{ __FILE__ }.find_last_of('/') + 1) \
|
||||
.c_str()
|
||||
#endif
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace rocprofiler_register
|
||||
{
|
||||
namespace log
|
||||
{
|
||||
bool&
|
||||
monochrome();
|
||||
|
||||
inline bool&
|
||||
monochrome()
|
||||
{
|
||||
static bool _v = []() {
|
||||
auto _val = false;
|
||||
const char* _env_cstr = nullptr;
|
||||
_env_cstr = std::getenv("ROCPROFILER_REGISTER_MONOCHROME");
|
||||
|
||||
if(!_env_cstr) _env_cstr = std::getenv("MONOCHROME");
|
||||
|
||||
if(_env_cstr)
|
||||
{
|
||||
auto _env = std::string{ _env_cstr };
|
||||
|
||||
// check if numeric
|
||||
if(_env.find_first_not_of("0123456789") == std::string::npos)
|
||||
{
|
||||
return _env.length() > 1 || _env[0] != '0';
|
||||
}
|
||||
|
||||
for(auto& itr : _env)
|
||||
itr = tolower(itr);
|
||||
|
||||
// check for matches to acceptable forms of false
|
||||
for(const auto& itr : { "off", "false", "no", "n", "f" })
|
||||
{
|
||||
if(_env == itr) return false;
|
||||
}
|
||||
|
||||
// check for matches to acceptable forms of true
|
||||
for(const auto& itr : { "on", "true", "yes", "y", "t" })
|
||||
{
|
||||
if(_env == itr) return true;
|
||||
}
|
||||
}
|
||||
return _val;
|
||||
}();
|
||||
return _v;
|
||||
}
|
||||
|
||||
namespace color
|
||||
{
|
||||
static constexpr auto info_value = "\033[01;34m";
|
||||
static constexpr auto warning_value = "\033[01;33m";
|
||||
static constexpr auto fatal_value = "\033[01;31m";
|
||||
static constexpr auto source_value = "\033[01;32m";
|
||||
static constexpr auto dmesg_value = "\033[01;37m";
|
||||
static constexpr auto end_value = "\033[0m";
|
||||
|
||||
inline const char*
|
||||
info()
|
||||
{
|
||||
return (log::monochrome()) ? "" : info_value;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
warning()
|
||||
{
|
||||
return (log::monochrome()) ? "" : warning_value;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
fatal()
|
||||
{
|
||||
return (log::monochrome()) ? "" : fatal_value;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
source()
|
||||
{
|
||||
return (log::monochrome()) ? "" : source_value;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
dmesg()
|
||||
{
|
||||
return (log::monochrome()) ? "" : dmesg_value;
|
||||
}
|
||||
|
||||
inline const char*
|
||||
end()
|
||||
{
|
||||
return (log::monochrome()) ? "" : end_value;
|
||||
}
|
||||
} // namespace color
|
||||
} // namespace log
|
||||
} // namespace rocprofiler_register
|
||||
|
||||
namespace rocprofiler_register
|
||||
{
|
||||
namespace log
|
||||
{
|
||||
struct base
|
||||
{
|
||||
public:
|
||||
static base indent(size_t, size_t = 2) { return base{}; }
|
||||
|
||||
template <typename Tp>
|
||||
auto operator<<(Tp&&)
|
||||
{
|
||||
return base{};
|
||||
}
|
||||
};
|
||||
|
||||
struct logger : public base
|
||||
{
|
||||
logger() = default;
|
||||
|
||||
explicit logger(bool _exit)
|
||||
: m_exit{ _exit }
|
||||
{ }
|
||||
|
||||
~logger()
|
||||
{
|
||||
if(m_done)
|
||||
{
|
||||
std::cerr << color::end() << "\n";
|
||||
if(m_exit) abort();
|
||||
}
|
||||
}
|
||||
|
||||
logger(logger&& rhs) noexcept
|
||||
{
|
||||
m_exit = rhs.m_exit;
|
||||
m_done = rhs.m_done;
|
||||
rhs.m_done = false;
|
||||
}
|
||||
|
||||
logger& operator=(logger&& rhs) noexcept
|
||||
{
|
||||
m_exit = rhs.m_exit;
|
||||
m_done = rhs.m_done;
|
||||
rhs.m_done = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
logger&& indent(size_t _n, size_t _tab_size = 4)
|
||||
{
|
||||
for(size_t i = 0; i < _n; i++)
|
||||
for(size_t j = 0; j < _tab_size; j++)
|
||||
std::cerr << " ";
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
template <typename Tp>
|
||||
logger&& operator<<(Tp&& _v)
|
||||
{
|
||||
std::cerr << std::forward<Tp>(_v);
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_exit = false;
|
||||
bool m_done = true;
|
||||
};
|
||||
|
||||
template <typename Tp>
|
||||
inline auto&
|
||||
get_color_hist()
|
||||
{
|
||||
static thread_local std::vector<std::pair<Tp*, const char*>> _v{};
|
||||
return _v;
|
||||
}
|
||||
|
||||
template <typename Tp>
|
||||
inline auto
|
||||
push_color_hist(Tp* _v, const char* _c)
|
||||
{
|
||||
if(!monochrome()) get_color_hist<Tp>().emplace_back(_v, _c);
|
||||
return _c;
|
||||
}
|
||||
|
||||
template <typename Tp>
|
||||
inline std::string
|
||||
pop_color_hist(Tp* _v)
|
||||
{
|
||||
if(monochrome()) return std::string{};
|
||||
|
||||
auto& _hist = get_color_hist<Tp>();
|
||||
for(auto itr = _hist.rbegin(); itr != _hist.rend(); ++itr)
|
||||
{
|
||||
Tp* _addr = itr->first;
|
||||
if(_addr == _v)
|
||||
{
|
||||
auto fitr = _hist.begin();
|
||||
std::advance(fitr, std::distance(_hist.rbegin(), itr));
|
||||
_hist.erase(fitr);
|
||||
}
|
||||
}
|
||||
for(auto itr = _hist.rbegin(); itr != _hist.rend(); ++itr)
|
||||
{
|
||||
if(itr->first == _v) return itr->second;
|
||||
}
|
||||
return color::end();
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
info(std::basic_ostream<CharT, Traits>& os)
|
||||
{
|
||||
return (os << push_color_hist(&os, color::info()));
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
warning(std::basic_ostream<CharT, Traits>& os)
|
||||
{
|
||||
return (os << push_color_hist(&os, color::warning()));
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
fatal(std::basic_ostream<CharT, Traits>& os)
|
||||
{
|
||||
return (os << push_color_hist(&os, color::fatal()));
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
source(std::basic_ostream<CharT, Traits>& os)
|
||||
{
|
||||
return (os << push_color_hist(&os, color::source()));
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
end(std::basic_ostream<CharT, Traits>& os)
|
||||
{
|
||||
return (os << push_color_hist(&os, color::end()));
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
pop(std::basic_ostream<CharT, Traits>& os)
|
||||
{
|
||||
return (os << pop_color_hist(&os));
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
reset(std::basic_ostream<CharT, Traits>& os)
|
||||
{
|
||||
pop_color_hist(&os);
|
||||
return (os << color::end());
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
flush(std::basic_ostream<CharT, Traits>& os)
|
||||
{
|
||||
return (os << pop << std::flush);
|
||||
}
|
||||
|
||||
template <typename CharT, typename Traits>
|
||||
std::basic_ostream<CharT, Traits>&
|
||||
endl(std::basic_ostream<CharT, Traits>& os)
|
||||
{
|
||||
return (os << pop << "\n" << std::flush);
|
||||
}
|
||||
|
||||
template <typename StreamT>
|
||||
struct stream_base
|
||||
{
|
||||
stream_base(StreamT& _os, const char* _color)
|
||||
: m_os{ _os }
|
||||
{
|
||||
m_os << push_color_hist(&_os, _color);
|
||||
}
|
||||
|
||||
~stream_base() { m_os << pop_color_hist(&m_os); }
|
||||
|
||||
stream_base(const stream_base&) = delete;
|
||||
stream_base& operator=(const stream_base&) = delete;
|
||||
|
||||
stream_base(stream_base&& rhs) noexcept = default;
|
||||
stream_base& operator=(stream_base&& rhs) noexcept = default;
|
||||
|
||||
template <typename Tp>
|
||||
stream_base& operator<<(Tp&& _v)
|
||||
{
|
||||
m_os << std::forward<Tp>(_v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename Tp>
|
||||
stream_base& operator<<(Tp& _v)
|
||||
{
|
||||
m_os << _v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
stream_base& put(char _c)
|
||||
{
|
||||
m_os.put(_c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
stream_base& endl()
|
||||
{
|
||||
m_os << std::endl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
stream_base& write(Args&&... _args)
|
||||
{
|
||||
m_os.write(std::forward<Args>(_args)...);
|
||||
return *this;
|
||||
}
|
||||
|
||||
stream_base& flush()
|
||||
{
|
||||
m_os << std::flush;
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto tellp() { return m_os.tellp(); }
|
||||
|
||||
template <typename... Args>
|
||||
stream_base& seekp(Args&&... _args)
|
||||
{
|
||||
m_os.seekp(std::forward<Args>(_args)...);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
StreamT& m_os;
|
||||
};
|
||||
|
||||
template <typename StreamT>
|
||||
stream_base<StreamT>
|
||||
stream(StreamT& _os, const char* _color)
|
||||
{
|
||||
return stream_base<StreamT>{ _os, _color };
|
||||
}
|
||||
|
||||
template <typename StreamT>
|
||||
stream_base<StreamT>
|
||||
info_stream(StreamT& _os)
|
||||
{
|
||||
return stream_base<StreamT>{ _os, color::info() };
|
||||
}
|
||||
|
||||
template <typename StreamT>
|
||||
stream_base<StreamT>
|
||||
source_stream(StreamT& _os)
|
||||
{
|
||||
return stream_base<StreamT>{ _os, color::source() };
|
||||
}
|
||||
|
||||
template <typename StreamT>
|
||||
stream_base<StreamT>
|
||||
warning_stream(StreamT& _os)
|
||||
{
|
||||
return stream_base<StreamT>{ _os, color::warning() };
|
||||
}
|
||||
|
||||
template <typename StreamT>
|
||||
stream_base<StreamT>
|
||||
fatal_stream(StreamT& _os)
|
||||
{
|
||||
return stream_base<StreamT>{ _os, color::fatal() };
|
||||
}
|
||||
|
||||
inline std::string
|
||||
string(const char* _color, std::string_view _v)
|
||||
{
|
||||
return std::string{ _color } + std::string{ _v } + std::string{ color::end() };
|
||||
}
|
||||
|
||||
inline std::string
|
||||
string(const char* _color, std::stringstream& _v)
|
||||
{
|
||||
return std::string{ _color } + _v.str() + std::string{ color::end() };
|
||||
}
|
||||
|
||||
inline std::string
|
||||
string(const char* _color, std::stringstream&& _v)
|
||||
{
|
||||
return std::string{ _color } + _v.str() + std::string{ color::end() };
|
||||
}
|
||||
|
||||
template <typename Tp>
|
||||
inline auto
|
||||
info_string(Tp&& _v)
|
||||
{
|
||||
return string(color::info(), std::forward<Tp>(_v));
|
||||
}
|
||||
|
||||
template <typename Tp>
|
||||
inline auto
|
||||
source_string(Tp&& _v)
|
||||
{
|
||||
return string(color::source(), std::forward<Tp>(_v));
|
||||
}
|
||||
|
||||
template <typename Tp>
|
||||
inline auto
|
||||
warning_string(Tp&& _v)
|
||||
{
|
||||
return string(color::warning(), std::forward<Tp>(_v));
|
||||
}
|
||||
|
||||
template <typename Tp>
|
||||
inline auto
|
||||
fatal_string(Tp&& _v)
|
||||
{
|
||||
return string(color::fatal(), std::forward<Tp>(_v));
|
||||
}
|
||||
} // namespace log
|
||||
} // namespace rocprofiler_register
|
||||
|
||||
#if !defined(ROCPROFILER_REGISTER_LOG)
|
||||
# define ROCPROFILER_REGISTER_LOG(COLOR, EXIT_CODE) \
|
||||
(::rocprofiler_register::log::logger(EXIT_CODE) \
|
||||
<< ::rocprofiler_register::log::color::end() \
|
||||
<< ::rocprofiler_register::log::color::source() << "[" \
|
||||
<< ROCPROFILER_REGISTER_PROJECT_NAME << "][" << ROCP_REG_FILE_NAME << ":" \
|
||||
<< __LINE__ << "][" << getpid() << "] " \
|
||||
<< ::rocprofiler_register::log::color::end() << COLOR)
|
||||
#endif
|
||||
|
||||
#if defined(NDEBUG)
|
||||
# if !defined(ROCPROFILER_REGISTER_INFO)
|
||||
# define ROCPROFILER_REGISTER_INFO (::rocprofiler_register::log::base())
|
||||
# endif
|
||||
# if !defined(ROCPROFILER_REGISTER_ASSERT)
|
||||
# define ROCPROFILER_REGISTER_ASSERT(COND) (::rocprofiler_register::log::base())
|
||||
# endif
|
||||
#else
|
||||
# if !defined(ROCPROFILER_REGISTER_INFO)
|
||||
# define ROCPROFILER_REGISTER_INFO \
|
||||
ROCPROFILER_REGISTER_LOG(::rocprofiler_register::log::color::info(), false)
|
||||
# endif
|
||||
# if !defined(ROCPROFILER_REGISTER_ASSERT)
|
||||
# define ROCPROFILER_REGISTER_ASSERT(COND) \
|
||||
(COND) ? ::rocprofiler_register::log::base() : ROCPROFILER_REGISTER_FATAL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(ROCPROFILER_REGISTER_WARNING)
|
||||
# define ROCPROFILER_REGISTER_WARNING \
|
||||
ROCPROFILER_REGISTER_LOG(::rocprofiler_register::log::color::warning(), false)
|
||||
#endif
|
||||
|
||||
#if !defined(ROCPROFILER_REGISTER_FATAL)
|
||||
# define ROCPROFILER_REGISTER_FATAL \
|
||||
ROCPROFILER_REGISTER_LOG(::rocprofiler_register::log::color::fatal(), true)
|
||||
#endif
|
||||
|
||||
#if !defined(ROCPROFILER_REGISTER_PREFER)
|
||||
# define ROCPROFILER_REGISTER_PREFER(COND) \
|
||||
(COND) ? ::rocprofiler_register::log::base() : ROCPROFILER_REGISTER_WARNING
|
||||
#endif
|
||||
|
||||
#if !defined(ROCPROFILER_REGISTER_REQUIRE)
|
||||
# define ROCPROFILER_REGISTER_REQUIRE(COND) \
|
||||
(COND) ? ::rocprofiler_register::log::base() : ROCPROFILER_REGISTER_FATAL
|
||||
#endif
|
||||
@@ -0,0 +1,127 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#include "utility.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace rocprofiler_register
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
namespace
|
||||
{
|
||||
template <typename ContainerT, typename... Args>
|
||||
inline auto
|
||||
emplace_impl(ContainerT& _c, int, Args&&... _args)
|
||||
-> decltype(_c.emplace_back(std::forward<Args>(_args)...))
|
||||
{
|
||||
return _c.emplace_back(std::forward<Args>(_args)...);
|
||||
}
|
||||
|
||||
template <typename ContainerT, typename... Args>
|
||||
inline auto
|
||||
emplace_impl(ContainerT& _c, long, Args&&... _args)
|
||||
-> decltype(_c.emplace(std::forward<Args>(_args)...))
|
||||
{
|
||||
return _c.emplace(std::forward<Args>(_args)...);
|
||||
}
|
||||
|
||||
template <typename ContainerT, typename... Args>
|
||||
inline auto
|
||||
emplace(ContainerT& _c, Args&&... _args)
|
||||
{
|
||||
return emplace_impl(_c, 0, std::forward<Args>(_args)...);
|
||||
}
|
||||
|
||||
template <typename ContainerT, typename ArgT>
|
||||
inline auto
|
||||
reserve_impl(ContainerT& _c, int, ArgT _arg) -> decltype(_c.reserve(_arg), bool())
|
||||
{
|
||||
_c.reserve(_arg);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename ContainerT, typename ArgT>
|
||||
inline auto
|
||||
reserve_impl(ContainerT&, long, ArgT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename ContainerT, typename ArgT>
|
||||
inline auto
|
||||
reserve(ContainerT& _c, ArgT _arg)
|
||||
{
|
||||
return reserve_impl(_c, 0, _arg);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
template <typename ContainerT>
|
||||
ContainerT
|
||||
delimit(const std::string& line, std::string_view delimiters)
|
||||
{
|
||||
ContainerT _result{};
|
||||
size_t _beginp = 0; // position that is the beginning of the new string
|
||||
size_t _delimp = 0; // position of the delimiter in the string
|
||||
if(reserve(_result, 0))
|
||||
{
|
||||
size_t _nmax = 0;
|
||||
for(char itr : line)
|
||||
{
|
||||
for(size_t j = 0; j < delimiters.length(); ++j)
|
||||
{
|
||||
if(itr == delimiters.at(j)) ++_nmax;
|
||||
}
|
||||
}
|
||||
reserve(_result, _nmax);
|
||||
}
|
||||
while(_beginp < line.length() && _delimp < line.length())
|
||||
{
|
||||
// find the first character (starting at _delimp) that is not a delimiter
|
||||
_beginp = line.find_first_not_of(delimiters, _delimp);
|
||||
// if no a character after or at _end that is not a delimiter is not found
|
||||
// then we are done
|
||||
if(_beginp == std::string::npos) break;
|
||||
// starting at the position of the new string, find the next delimiter
|
||||
_delimp = line.find_first_of(delimiters, _beginp);
|
||||
std::string _tmp{};
|
||||
// starting at the position of the new string, get the characters
|
||||
// between this position and the next delimiter
|
||||
_tmp = line.substr(_beginp, _delimp - _beginp);
|
||||
// don't add empty strings
|
||||
if(!_tmp.empty()) emplace(_result, _tmp);
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
|
||||
template std::vector<std::string>
|
||||
delimit(const std::string&, std::string_view);
|
||||
|
||||
template std::set<std::string>
|
||||
delimit(const std::string&, std::string_view);
|
||||
} // namespace utility
|
||||
} // namespace rocprofiler_register
|
||||
@@ -0,0 +1,44 @@
|
||||
// MIT License
|
||||
//
|
||||
// Copyright (c) 2022 Advanced Micro Devices, Inc. All Rights Reserved.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace rocprofiler_register
|
||||
{
|
||||
namespace utility
|
||||
{
|
||||
template <typename ContainerT = std::vector<std::string>>
|
||||
ContainerT
|
||||
delimit(const std::string& line, std::string_view delimiters = "\"',;: ");
|
||||
|
||||
extern template std::vector<std::string>
|
||||
delimit(const std::string&, std::string_view);
|
||||
|
||||
extern template std::set<std::string>
|
||||
delimit(const std::string&, std::string_view);
|
||||
} // namespace utility
|
||||
} // namespace rocprofiler_register
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2023 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include <rocprofiler-register/rocprofiler-register.h>
|
||||
#include <rocprofiler-register/version.h>
|
||||
|
||||
int ROCPROFILER_REGISTER_INTERNAL_API rocp_register_sym = 0;
|
||||
@@ -0,0 +1,374 @@
|
||||
// Copyright (c) 2023 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#define GNU_SOURCE 1
|
||||
|
||||
#include <rocprofiler-register/rocprofiler-register.h>
|
||||
|
||||
#include "details/dl.hpp"
|
||||
#include "details/environment.hpp"
|
||||
#include "details/log.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <bitset>
|
||||
#include <filesystem>
|
||||
#include <mutex>
|
||||
#include <regex>
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
extern "C" {
|
||||
#pragma weak rocprofiler_configure
|
||||
#pragma weak rocprofiler_set_api_table
|
||||
#pragma weak rocprofiler_register_import_hip
|
||||
#pragma weak rocprofiler_register_import_hip_static
|
||||
#pragma weak rocprofiler_register_import_hsa
|
||||
#pragma weak rocprofiler_register_import_hsa_static
|
||||
#pragma weak rocprofiler_register_import_roctx
|
||||
#pragma weak rocprofiler_register_import_roctx_static
|
||||
|
||||
extern rocprofiler_configure_result_t*
|
||||
rocprofiler_configure(uint32_t, const char*, uint32_t, uint32_t);
|
||||
|
||||
extern int
|
||||
rocprofiler_set_api_table(const char*, uint64_t, uint64_t, void**, uint64_t);
|
||||
|
||||
extern uint32_t
|
||||
rocprofiler_register_import_hip(void);
|
||||
|
||||
extern uint32_t
|
||||
rocprofiler_register_import_hsa(void);
|
||||
|
||||
extern uint32_t
|
||||
rocprofiler_register_import_roctx(void);
|
||||
|
||||
extern uint32_t
|
||||
rocprofiler_register_import_hip_static(void);
|
||||
|
||||
extern uint32_t
|
||||
rocprofiler_register_import_hsa_static(void);
|
||||
|
||||
extern uint32_t
|
||||
rocprofiler_register_import_roctx_static(void);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
namespace fs = ::std::filesystem;
|
||||
using namespace rocprofiler_register;
|
||||
using rocprofiler_set_api_table_t = decltype(::rocprofiler_set_api_table)*;
|
||||
using bitset_t = std::bitset<sizeof(rocprofiler_register_library_indentifier_t::handle)>;
|
||||
|
||||
static_assert(sizeof(bitset_t) ==
|
||||
sizeof(rocprofiler_register_library_indentifier_t::handle),
|
||||
"bitset should be same at uint64_t");
|
||||
|
||||
int rocprofiler_register_verbose = common::get_env("ROCPROFILER_REGISTER_VERBOSE", 0);
|
||||
constexpr int rocprofiler_register_info_level = 2;
|
||||
constexpr auto rocprofiler_lib_name = "librocprofiler64.so";
|
||||
constexpr auto rocprofiler_lib_register_entrypoint = "rocprofiler_set_api_table";
|
||||
constexpr auto rocprofiler_register_lib_name =
|
||||
"librocprofiler-register.so." ROCPROFILER_REGISTER_SOVERSION;
|
||||
|
||||
enum rocp_reg_supported_library // NOLINT(performance-enum-size)
|
||||
{
|
||||
ROCP_REG_HSA = 0,
|
||||
ROCP_REG_HIP,
|
||||
ROCP_REG_ROCTX,
|
||||
ROCP_REG_LAST,
|
||||
};
|
||||
|
||||
template <size_t>
|
||||
struct supported_library_trait
|
||||
{
|
||||
static constexpr bool specialized = false;
|
||||
static constexpr auto value = ROCP_REG_LAST;
|
||||
static constexpr const char* const common_name = nullptr;
|
||||
static constexpr const char* const symbol_name = nullptr;
|
||||
static constexpr const char* const library_name = nullptr;
|
||||
};
|
||||
|
||||
#define ROCP_REG_DEFINE_LIBRARY_TRAITS(ENUM, NAME, SYM_NAME, LIB_NAME) \
|
||||
template <> \
|
||||
struct supported_library_trait<ENUM> \
|
||||
{ \
|
||||
static constexpr bool specialized = true; \
|
||||
static constexpr auto value = ENUM; \
|
||||
static constexpr auto common_name = NAME; \
|
||||
static constexpr auto symbol_name = SYM_NAME; \
|
||||
static constexpr auto library_name = LIB_NAME; \
|
||||
};
|
||||
|
||||
ROCP_REG_DEFINE_LIBRARY_TRAITS(ROCP_REG_HSA,
|
||||
"hsa",
|
||||
"rocprofiler_register_import_hsa",
|
||||
"libhsa-runtime64.so.[2-9]($|\\.[0-9\\.]+)")
|
||||
|
||||
ROCP_REG_DEFINE_LIBRARY_TRAITS(ROCP_REG_HIP,
|
||||
"hip",
|
||||
"rocprofiler_register_import_hip",
|
||||
"libamdhip64.so.[6-9]($|\\.[0-9\\.]+)")
|
||||
|
||||
ROCP_REG_DEFINE_LIBRARY_TRAITS(ROCP_REG_ROCTX,
|
||||
"roctx",
|
||||
"rocprofiler_register_import_roctx",
|
||||
"libroctx64.so.[4-9]($|\\.[0-9\\.]+)")
|
||||
|
||||
auto
|
||||
get_this_library_path()
|
||||
{
|
||||
auto _this_lib_path = binary::get_linked_path(rocprofiler_register_lib_name,
|
||||
{ RTLD_NOLOAD | RTLD_LAZY });
|
||||
ROCPROFILER_REGISTER_REQUIRE(_this_lib_path)
|
||||
<< rocprofiler_register_lib_name
|
||||
<< " could not locate itself in the list of loaded libraries";
|
||||
return fs::path{ *_this_lib_path }.parent_path().string();
|
||||
}
|
||||
|
||||
struct rocp_import
|
||||
{
|
||||
rocp_reg_supported_library library_idx = ROCP_REG_LAST;
|
||||
std::string_view common_name = {};
|
||||
std::string_view symbol_name = {};
|
||||
std::string_view library_name = {};
|
||||
};
|
||||
|
||||
template <size_t... Idx>
|
||||
auto rocp_reg_get_imports(std::index_sequence<Idx...>)
|
||||
{
|
||||
auto _data = std::vector<rocp_import>{};
|
||||
auto _import_scan = [&_data](auto _info) {
|
||||
if(_info.specialized)
|
||||
{
|
||||
_data.emplace_back(rocp_import{
|
||||
_info.value, _info.common_name, _info.symbol_name, _info.library_name });
|
||||
}
|
||||
};
|
||||
|
||||
(_import_scan(supported_library_trait<Idx>{}), ...);
|
||||
return _data;
|
||||
}
|
||||
|
||||
auto
|
||||
rocp_reg_scan_for_tools()
|
||||
{
|
||||
auto _rocp_reg_lib = common::get_env("ROCPROFILER_REGISTER_LIBRARY", std::string{});
|
||||
bool _force_tool =
|
||||
common::get_env("ROCPROFILER_REGISTER_FORCE_LOAD", !_rocp_reg_lib.empty());
|
||||
bool _found_tool = (rocprofiler_configure != nullptr || _force_tool);
|
||||
|
||||
static void* rocprofiler_lib_handle = nullptr;
|
||||
static rocprofiler_set_api_table_t rocprofiler_lib_config_fn = nullptr;
|
||||
|
||||
if(_force_tool)
|
||||
{
|
||||
if(rocprofiler_lib_handle && rocprofiler_lib_config_fn)
|
||||
return std::make_pair(rocprofiler_lib_handle, rocprofiler_lib_config_fn);
|
||||
|
||||
if(_rocp_reg_lib.empty()) _rocp_reg_lib = rocprofiler_lib_name;
|
||||
|
||||
auto _rocp_reg_lib_path = fs::path{ _rocp_reg_lib };
|
||||
auto _rocp_reg_lib_path_fname = _rocp_reg_lib_path.filename();
|
||||
auto _rocp_reg_lib_path_abs =
|
||||
(_rocp_reg_lib_path.is_absolute())
|
||||
? _rocp_reg_lib_path
|
||||
: (fs::path{ get_this_library_path() } / _rocp_reg_lib_path_fname);
|
||||
|
||||
// check to see if the rocprofiler library is already loaded
|
||||
rocprofiler_lib_handle =
|
||||
dlopen(_rocp_reg_lib_path.c_str(), RTLD_NOLOAD | RTLD_LAZY);
|
||||
|
||||
// try to load with the given path
|
||||
if(!rocprofiler_lib_handle)
|
||||
{
|
||||
rocprofiler_lib_handle =
|
||||
dlopen(_rocp_reg_lib_path.c_str(), RTLD_GLOBAL | RTLD_LAZY);
|
||||
}
|
||||
|
||||
// try to load with the absoulte path
|
||||
if(!rocprofiler_lib_handle)
|
||||
{
|
||||
_rocp_reg_lib_path = _rocp_reg_lib_path_abs;
|
||||
rocprofiler_lib_handle =
|
||||
dlopen(_rocp_reg_lib_path.c_str(), RTLD_GLOBAL | RTLD_LAZY);
|
||||
}
|
||||
|
||||
// try to load with the basename path
|
||||
if(!rocprofiler_lib_handle)
|
||||
{
|
||||
_rocp_reg_lib_path = _rocp_reg_lib_path_fname;
|
||||
rocprofiler_lib_handle =
|
||||
dlopen(_rocp_reg_lib_path.c_str(), RTLD_GLOBAL | RTLD_LAZY);
|
||||
}
|
||||
|
||||
if(rocprofiler_register_verbose >= rocprofiler_register_info_level)
|
||||
ROCPROFILER_REGISTER_INFO << "loaded " << _rocp_reg_lib_path_fname.string()
|
||||
<< " library at " << _rocp_reg_lib_path.string();
|
||||
|
||||
ROCPROFILER_REGISTER_REQUIRE(rocprofiler_lib_handle)
|
||||
<< _rocp_reg_lib << " failed to load\n";
|
||||
|
||||
*(void**) (&rocprofiler_lib_config_fn) =
|
||||
dlsym(rocprofiler_lib_handle, rocprofiler_lib_register_entrypoint);
|
||||
|
||||
ROCPROFILER_REGISTER_REQUIRE(rocprofiler_lib_config_fn)
|
||||
<< _rocp_reg_lib << " did not contain '"
|
||||
<< rocprofiler_lib_register_entrypoint << "' symbol\n";
|
||||
}
|
||||
else if(_found_tool && rocprofiler_set_api_table)
|
||||
{
|
||||
rocprofiler_lib_config_fn = &rocprofiler_set_api_table;
|
||||
}
|
||||
|
||||
return std::make_pair(rocprofiler_lib_handle, rocprofiler_lib_config_fn);
|
||||
}
|
||||
|
||||
constexpr auto library_seq = std::make_index_sequence<ROCP_REG_LAST>{};
|
||||
auto global_mutex = std::recursive_mutex{};
|
||||
auto import_info = rocp_reg_get_imports(library_seq);
|
||||
auto instance_counters = std::array<std::atomic_uint64_t, ROCP_REG_LAST>{};
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
rocprofiler_register_error_code_t
|
||||
rocprofiler_register_library_api_table(
|
||||
const char* common_name,
|
||||
rocprofiler_register_import_func_t import_func,
|
||||
uint32_t lib_version,
|
||||
void** api_tables,
|
||||
uint64_t api_table_length,
|
||||
rocprofiler_register_library_indentifier_t* register_id)
|
||||
{
|
||||
if(api_table_length < 1) return ROCP_REG_BAD_API_TABLE_LENGTH;
|
||||
|
||||
(void) lib_version;
|
||||
(void) api_tables;
|
||||
|
||||
auto _lk = std::unique_lock<std::recursive_mutex>{ global_mutex, std::defer_lock };
|
||||
if(_lk.owns_lock()) return ROCP_REG_DEADLOCK;
|
||||
|
||||
auto _scan_result = rocp_reg_scan_for_tools();
|
||||
|
||||
rocp_import* _import_match = nullptr;
|
||||
for(auto& itr : import_info)
|
||||
{
|
||||
if(itr.common_name == common_name)
|
||||
{
|
||||
_import_match = &itr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// not a supported library name
|
||||
if(!_import_match || _import_match->library_idx == ROCP_REG_LAST)
|
||||
return ROCP_REG_UNSUPPORTED_API;
|
||||
|
||||
if(import_func != nullptr &&
|
||||
common::get_env<bool>("ROCPROFILER_REGISTER_SECURE", false))
|
||||
{
|
||||
auto _import_func_addr = reinterpret_cast<uintptr_t>(import_func);
|
||||
auto _segment_addresses = binary::get_segment_addresses();
|
||||
auto _in_address_range = [](uintptr_t _addr,
|
||||
const std::vector<binary::address_range>& _range) {
|
||||
for(auto ritr : _range)
|
||||
{
|
||||
if(_addr >= ritr.start && _addr < ritr.last) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// check that the address of the import function is within the expected library
|
||||
// name
|
||||
bool _valid_addr = false;
|
||||
for(const auto& itr : _segment_addresses)
|
||||
{
|
||||
if(_in_address_range(_import_func_addr, itr.ranges))
|
||||
{
|
||||
if(std::regex_search(fs::path{ itr.filepath }.filename().string(),
|
||||
std::regex{ _import_match->library_name.data() }))
|
||||
{
|
||||
_valid_addr = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the library provided
|
||||
if(!_valid_addr) return ROCP_REG_INVALID_API_ADDRESS;
|
||||
}
|
||||
|
||||
constexpr auto offset_factor = 64 / std::max<size_t>(ROCP_REG_LAST, 8);
|
||||
// if ROCP_REG_LAST > 8, then we can no longer encode 8 instances per lib
|
||||
// because we ran out of bits (i.e. max of 8 * 8 = 64)
|
||||
static_assert((offset_factor * ROCP_REG_LAST) <= sizeof(uint64_t) * 8,
|
||||
"ROCP_REG_LAST has exceeded the max allowable size");
|
||||
|
||||
// too many instances of the same library
|
||||
if(instance_counters.at(_import_match->library_idx) >= offset_factor)
|
||||
return ROCP_REG_EXCESS_API_INSTANCES;
|
||||
|
||||
auto _instance_val = instance_counters.at(_import_match->library_idx)++;
|
||||
auto& _bits = *reinterpret_cast<bitset_t*>(®ister_id->handle);
|
||||
_bits = bitset_t{ (offset_factor * _import_match->library_idx) + _instance_val };
|
||||
|
||||
if(_bits.to_ulong() != register_id->handle)
|
||||
throw std::runtime_error("error encoding register_id");
|
||||
|
||||
// rocprofiler library is dlopened and we have the functor to pass the API data
|
||||
auto _activate_rocprofiler = (_scan_result.second != nullptr);
|
||||
|
||||
if(_activate_rocprofiler)
|
||||
{
|
||||
auto _ret = _scan_result.second(
|
||||
common_name, lib_version, _instance_val, api_tables, api_table_length);
|
||||
if(_ret != 0) return ROCP_REG_ROCPROFILER_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ROCP_REG_NO_TOOLS;
|
||||
}
|
||||
|
||||
return ROCP_REG_SUCCESS;
|
||||
}
|
||||
|
||||
const char*
|
||||
rocprofiler_register_error_string(rocprofiler_register_error_code_t _ec)
|
||||
{
|
||||
switch(_ec)
|
||||
{
|
||||
case ROCP_REG_SUCCESS: return "rocprofiler_register_success";
|
||||
case ROCP_REG_NO_TOOLS: return "rocprofiler_register_no_tools";
|
||||
case ROCP_REG_DEADLOCK: return "rocprofiler_register_deadlock";
|
||||
case ROCP_REG_BAD_API_TABLE_LENGTH:
|
||||
return "rocprofiler_register_bad_api_table_length";
|
||||
case ROCP_REG_UNSUPPORTED_API: return "rocprofiler_register_unsupported_api";
|
||||
case ROCP_REG_INVALID_API_ADDRESS:
|
||||
return "rocprofiler_register_invalid_api_address";
|
||||
case ROCP_REG_ROCPROFILER_ERROR: return "rocprofiler_register_rocprofiler_error";
|
||||
case ROCP_REG_EXCESS_API_INSTANCES:
|
||||
return "rocprofiler_register_excess_api_instances";
|
||||
case ROCP_REG_ERROR_CODE_END: return "rocprofiler_register_unknown_error";
|
||||
}
|
||||
return "rocprofiler_register_unknown_error";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,465 @@
|
||||
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||
|
||||
project(rocprofiler-register-tests LANGUAGES C CXX)
|
||||
|
||||
include(CMakeParseArguments)
|
||||
include(GNUInstallDirs)
|
||||
|
||||
if("${CMAKE_PROJECT_NAME}" STREQUAL "${PROJECT_NAME}")
|
||||
find_package(rocprofiler-register REQUIRED)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_VISIBILITY_PRESET "hidden")
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
|
||||
set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}")
|
||||
enable_testing()
|
||||
include(CTest)
|
||||
endif()
|
||||
|
||||
function(rocp_register_strip_target)
|
||||
if(CMAKE_BUILD_TYPE MATCHES "(DEBUG|Debug)")
|
||||
return()
|
||||
endif()
|
||||
|
||||
cmake_parse_arguments(STRIP "" "" "ARGS" ${ARGN})
|
||||
|
||||
list(LENGTH STRIP_UNPARSED_ARGUMENTS NUM_UNPARSED)
|
||||
|
||||
if(NUM_UNPARSED EQUAL 1)
|
||||
set(_TARGET "${STRIP_UNPARSED_ARGUMENTS}")
|
||||
else()
|
||||
message(
|
||||
FATAL_ERROR "rocp_register_strip_target cannot deduce target from \"${ARGN}\""
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT TARGET "${_TARGET}")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"rocp_register_strip_target not provided valid target: \"${_TARGET}\"")
|
||||
endif()
|
||||
|
||||
if(CMAKE_STRIP)
|
||||
add_custom_command(
|
||||
TARGET ${_TARGET}
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_STRIP} ${STRIP_ARGS} $<TARGET_FILE:${_TARGET}>
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
COMMENT "Stripping ${_TARGET}...")
|
||||
else()
|
||||
message(WARNING "CMAKE_STRIP not set... Not stripping ${_TARGET}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
#
|
||||
# mock libraries
|
||||
#
|
||||
add_subdirectory(hsa-runtime)
|
||||
add_subdirectory(amdhip)
|
||||
add_subdirectory(roctx)
|
||||
add_subdirectory(rocprofiler)
|
||||
|
||||
#
|
||||
# common to multiple tests
|
||||
#
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
add_library(rocprofiler-register-tests-common INTERFACE)
|
||||
target_include_directories(rocprofiler-register-tests-common
|
||||
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>)
|
||||
target_link_libraries(rocprofiler-register-tests-common INTERFACE Threads::Threads stdc++)
|
||||
|
||||
add_library(rocprofiler-register-tests-strong INTERFACE)
|
||||
target_compile_definitions(rocprofiler-register-tests-strong
|
||||
INTERFACE ROCP_REG_TEST_WEAK=0)
|
||||
|
||||
add_library(rocprofiler-register-tests-weak INTERFACE)
|
||||
target_compile_definitions(rocprofiler-register-tests-weak INTERFACE ROCP_REG_TEST_WEAK=1)
|
||||
|
||||
add_library(rocprofiler-register-tests-rocp INTERFACE)
|
||||
target_link_options(rocprofiler-register-tests-rocp INTERFACE -Wl,--no-as-needed)
|
||||
target_link_libraries(rocprofiler-register-tests-rocp INTERFACE rocprofiler::rocprofiler)
|
||||
|
||||
add_library(rocprofiler-register::tests-common ALIAS rocprofiler-register-tests-common)
|
||||
add_library(rocprofiler-register::tests-strong ALIAS rocprofiler-register-tests-strong)
|
||||
add_library(rocprofiler-register::tests-weak ALIAS rocprofiler-register-tests-weak)
|
||||
add_library(rocprofiler-register::tests-rocp ALIAS rocprofiler-register-tests-rocp)
|
||||
|
||||
#
|
||||
# test scenarios
|
||||
#
|
||||
function(rocp_register_test_executable _NAME)
|
||||
set(_SV_ARGS)
|
||||
foreach(_TYPE "CORE" "PRELOAD" "WRAP" "PRELOAD_WRAP")
|
||||
list(APPEND _SV_ARGS "${_TYPE}_PASS_REGEX" "${_TYPE}_FAIL_REGEX")
|
||||
endforeach()
|
||||
cmake_parse_arguments(
|
||||
RRTE
|
||||
"" # options
|
||||
"SECURE;${_SV_ARGS}" # single value args
|
||||
"SOURCES;LIBRARIES" # multiple value args
|
||||
${ARGN})
|
||||
|
||||
add_executable(${_NAME})
|
||||
target_sources(${_NAME} PRIVATE ${RRTE_SOURCES})
|
||||
target_link_libraries(${_NAME} PRIVATE rocprofiler-register::tests-common
|
||||
${RRTE_LIBRARIES})
|
||||
|
||||
function(rocp_register_add_test _TEST_NAME _TARGET _ENV _PASS _FAIL)
|
||||
if(RRTE_SECURE)
|
||||
list(APPEND _ENV "ROCPROFILER_REGISTER_SECURE=true")
|
||||
set(_LABELS "secure")
|
||||
else()
|
||||
set(_LABELS "insecure")
|
||||
endif()
|
||||
add_test(
|
||||
NAME ${_TEST_NAME}
|
||||
COMMAND $<TARGET_FILE:${_TARGET}>
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
set_tests_properties(
|
||||
${_TEST_NAME}
|
||||
PROPERTIES ENVIRONMENT
|
||||
"LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY};${_ENV}"
|
||||
PASS_REGULAR_EXPRESSION
|
||||
"${_PASS}"
|
||||
FAIL_REGULAR_EXPRESSION
|
||||
"${_FAIL}"
|
||||
LABELS
|
||||
"${_LABELS}"
|
||||
${ARGN})
|
||||
endfunction()
|
||||
|
||||
rocp_register_add_test(${_NAME} ${_NAME} "" "${RRTE_CORE_PASS_REGEX}"
|
||||
"${RRTE_CORE_FAIL_REGEX}")
|
||||
|
||||
rocp_register_add_test(${_NAME}-preload ${_NAME} "LD_PRELOAD=librocprofiler64.so"
|
||||
"${RRTE_PRELOAD_PASS_REGEX}" "${RRTE_PRELOAD_FAIL_REGEX}")
|
||||
|
||||
rocp_register_add_test(${_NAME}-wrap ${_NAME} "ROCP_REG_TEST_WRAP=1"
|
||||
"${RRTE_WRAP_PASS_REGEX}" "${RRTE_WRAP_FAIL_REGEX}")
|
||||
|
||||
rocp_register_add_test(
|
||||
${_NAME}-preload-wrap ${_NAME}
|
||||
"LD_PRELOAD=librocprofiler64.so;ROCP_REG_TEST_WRAP=1"
|
||||
"${RRTE_PRELOAD_WRAP_PASS_REGEX}" "${RRTE_PRELOAD_WRAP_FAIL_REGEX}")
|
||||
|
||||
endfunction()
|
||||
|
||||
# serial
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-roctx
|
||||
SECURE ON
|
||||
SOURCES test-amdhip-roctx.cpp
|
||||
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip roctx::roctx
|
||||
CORE_PASS_REGEX
|
||||
".hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
|
||||
WRAP_PASS_REGEX
|
||||
".hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-main\n.rocprofiler.cpp..pop. thread-main\n"
|
||||
)
|
||||
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-roctx-weak
|
||||
SOURCES test-amdhip-roctx.cpp
|
||||
LIBRARIES rocprofiler-register::tests-weak
|
||||
CORE_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
|
||||
WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-main\n.rocprofiler.cpp..pop. thread-main\n"
|
||||
)
|
||||
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-roctx-rocp
|
||||
SOURCES test-amdhip-roctx.cpp
|
||||
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip roctx::roctx
|
||||
rocprofiler-register::tests-rocp
|
||||
CORE_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
|
||||
WRAP_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-main\n.rocprofiler.cpp..pop. thread-main\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-main\n.rocprofiler.cpp..pop. thread-main\n"
|
||||
)
|
||||
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-roctx-weak-rocp
|
||||
SOURCES test-amdhip-roctx.cpp
|
||||
LIBRARIES rocprofiler-register::tests-weak rocprofiler-register::tests-rocp
|
||||
CORE_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-main\n.roctx.cpp..pop. thread-main\n"
|
||||
WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-main\n.rocprofiler.cpp..pop. thread-main\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-main\n.rocprofiler.cpp..pop. thread-main\n"
|
||||
)
|
||||
|
||||
# multithreaded
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-roctx-mt
|
||||
SOURCES test-amdhip-roctx-mt.cpp
|
||||
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip roctx::roctx
|
||||
CORE_PASS_REGEX
|
||||
".hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
|
||||
WRAP_PASS_REGEX
|
||||
".hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n"
|
||||
)
|
||||
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-roctx-mt-weak
|
||||
SOURCES test-amdhip-roctx-mt.cpp
|
||||
LIBRARIES rocprofiler-register::tests-weak
|
||||
CORE_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
|
||||
WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n"
|
||||
)
|
||||
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-roctx-mt-rocp
|
||||
SOURCES test-amdhip-roctx-mt.cpp
|
||||
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip roctx::roctx
|
||||
rocprofiler-register::tests-rocp
|
||||
CORE_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
|
||||
WRAP_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n"
|
||||
)
|
||||
|
||||
# 29
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-roctx-mt-weak-rocp
|
||||
SOURCES test-amdhip-roctx-mt.cpp
|
||||
LIBRARIES rocprofiler-register::tests-weak rocprofiler-register::tests-rocp
|
||||
CORE_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..push. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n.roctx.cpp..pop. thread-[0-3]\n"
|
||||
WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libroctx64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. roctx :: 40601 :: 0 :: 1\n.roctx.cpp. roctx identifier 16\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..push. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n.rocprofiler.cpp..pop. thread-[0-3]\n"
|
||||
)
|
||||
|
||||
# constructor
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-ctor
|
||||
SOURCES test-amdhip-ctor.cpp
|
||||
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip
|
||||
CORE_PASS_REGEX
|
||||
".hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n"
|
||||
WRAP_PASS_REGEX
|
||||
".hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n"
|
||||
)
|
||||
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-ctor-weak
|
||||
SOURCES test-amdhip-ctor.cpp
|
||||
LIBRARIES rocprofiler-register::tests-weak
|
||||
CORE_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n"
|
||||
WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n"
|
||||
)
|
||||
|
||||
# 41
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-ctor-rocp
|
||||
SOURCES test-amdhip-ctor.cpp
|
||||
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip
|
||||
rocprofiler-register::tests-rocp
|
||||
CORE_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n"
|
||||
WRAP_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n"
|
||||
)
|
||||
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-ctor-weak-rocp
|
||||
SOURCES test-amdhip-ctor.cpp
|
||||
LIBRARIES rocprofiler-register::tests-weak rocprofiler-register::tests-rocp
|
||||
CORE_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n"
|
||||
WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.fwd.hpp. dlopen libhsa-runtime64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n"
|
||||
)
|
||||
|
||||
# constructor + mt
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-ctor-mt
|
||||
SOURCES test-amdhip-ctor-mt.cpp
|
||||
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip
|
||||
CORE_PASS_REGEX
|
||||
".hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
|
||||
WRAP_PASS_REGEX
|
||||
".hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n"
|
||||
)
|
||||
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-ctor-mt-weak
|
||||
SOURCES test-amdhip-ctor-mt.cpp
|
||||
LIBRARIES rocprofiler-register::tests-weak
|
||||
CORE_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
|
||||
WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.hsa-runtime.cpp. hsa_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n"
|
||||
)
|
||||
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-ctor-mt-rocp
|
||||
SOURCES test-amdhip-ctor-mt.cpp
|
||||
LIBRARIES rocprofiler-register::tests-strong amdhip::amdhip
|
||||
rocprofiler-register::tests-rocp
|
||||
CORE_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
|
||||
WRAP_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n"
|
||||
)
|
||||
|
||||
rocp_register_test_executable(
|
||||
test-amdhip-ctor-mt-weak-rocp
|
||||
SOURCES test-amdhip-ctor-mt.cpp
|
||||
LIBRARIES rocprofiler-register::tests-weak rocprofiler-register::tests-rocp
|
||||
CORE_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
|
||||
PRELOAD_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.hsa-runtime.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n.amdhip.cpp. hip_init\n"
|
||||
WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n"
|
||||
PRELOAD_WRAP_PASS_REGEX
|
||||
".fwd.hpp. dlopen libamdhip64.so, 1\n.rocprofiler.cpp. rocp_ctor\n.rocprofiler.cpp. hsa :: 20100 :: 0 :: 1\n.hsa-runtime.cpp. hsa identifier 0\n.rocprofiler.cpp. hsa_init\n.rocprofiler.cpp. hip :: 60001 :: 0 :: 1\n.amdhip.cpp. hip identifier 8\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n.rocprofiler.cpp. hip_init\n"
|
||||
)
|
||||
|
||||
add_executable(test-invalid-hsa-runtime)
|
||||
target_sources(test-invalid-hsa-runtime PRIVATE test-amdhip-roctx.cpp)
|
||||
target_link_libraries(
|
||||
test-invalid-hsa-runtime PRIVATE rocprofiler-register::tests-common roctx::roctx
|
||||
amdhip::amdhip-invalid)
|
||||
|
||||
add_test(
|
||||
NAME test-secure-invalid-hsa-runtime
|
||||
COMMAND $<TARGET_FILE:test-invalid-hsa-runtime>
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
|
||||
set_tests_properties(
|
||||
test-secure-invalid-hsa-runtime
|
||||
PROPERTIES
|
||||
ENVIRONMENT
|
||||
"LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/invalid:${CMAKE_LIBRARY_OUTPUT_DIRECTORY};ROCPROFILER_REGISTER_SECURE=1"
|
||||
LABELS
|
||||
"secure"
|
||||
WILL_FAIL
|
||||
ON)
|
||||
|
||||
add_test(
|
||||
NAME test-insecure-invalid-hsa-runtime
|
||||
COMMAND $<TARGET_FILE:test-invalid-hsa-runtime>
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
|
||||
set_tests_properties(
|
||||
test-insecure-invalid-hsa-runtime
|
||||
PROPERTIES
|
||||
ENVIRONMENT
|
||||
"LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/invalid:${CMAKE_LIBRARY_OUTPUT_DIRECTORY};ROCPROFILER_REGISTER_SECURE=0"
|
||||
LABELS
|
||||
"insecure")
|
||||
|
||||
add_executable(test-amdhip-hsart-roctx)
|
||||
target_sources(test-amdhip-hsart-roctx PRIVATE test-amdhip-hsart-roctx.cpp)
|
||||
target_link_libraries(
|
||||
test-amdhip-hsart-roctx PRIVATE rocprofiler-register::tests-common
|
||||
hsa-runtime::hsa-runtime amdhip::amdhip roctx::roctx)
|
||||
|
||||
add_test(
|
||||
NAME test-force-rocprofiler-dlopen
|
||||
COMMAND $<TARGET_FILE:test-amdhip-hsart-roctx>
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
|
||||
set_tests_properties(
|
||||
test-force-rocprofiler-dlopen
|
||||
PROPERTIES
|
||||
ENVIRONMENT
|
||||
"LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY};ROCPROFILER_REGISTER_FORCE_LOAD=1;ROCPROFILER_REGISTER_SECURE=yes;ROCPROFILER_REGISTER_VERBOSE=3"
|
||||
LABELS
|
||||
"dlopen;secure")
|
||||
|
||||
add_test(
|
||||
NAME test-rocprofiler-register-library-base-path
|
||||
COMMAND $<TARGET_FILE:test-amdhip-hsart-roctx>
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
|
||||
set_tests_properties(
|
||||
test-rocprofiler-register-library-base-path
|
||||
PROPERTIES
|
||||
ENVIRONMENT
|
||||
"LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY};ROCPROFILER_REGISTER_LIBRARY=librocprofiler64.so;ROCPROFILER_REGISTER_SECURE=yes;ROCPROFILER_REGISTER_VERBOSE=3;ROCPROFILER_REGISTER_MONOCHROME=true"
|
||||
LABELS
|
||||
"dlopen;secure")
|
||||
|
||||
add_test(
|
||||
NAME test-rocprofiler-register-library-absolute-path
|
||||
COMMAND $<TARGET_FILE:test-amdhip-hsart-roctx>
|
||||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR})
|
||||
|
||||
set_tests_properties(
|
||||
test-rocprofiler-register-library-absolute-path
|
||||
PROPERTIES
|
||||
ENVIRONMENT
|
||||
"LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY};ROCPROFILER_REGISTER_LIBRARY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/librocprofiler64.so;ROCPROFILER_REGISTER_SECURE=yes;ROCPROFILER_REGISTER_VERBOSE=3;ROCPROFILER_REGISTER_MONOCHROME=true"
|
||||
LABELS
|
||||
"dlopen;secure")
|
||||
@@ -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,31 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(ROCP_REG_TEST_WEAK) && ROCP_REG_TEST_WEAK > 0
|
||||
# pragma weak hip_init
|
||||
# pragma weak hsa_init
|
||||
# pragma weak roctxRangePush
|
||||
# pragma weak roctxRangePop
|
||||
#endif
|
||||
|
||||
extern void
|
||||
hip_init(void);
|
||||
|
||||
extern void
|
||||
hsa_init(void);
|
||||
|
||||
extern void
|
||||
roctxRangePush(const char*);
|
||||
|
||||
extern void
|
||||
roctxRangePop(const char*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,101 @@
|
||||
#pragma once
|
||||
|
||||
#include "fwd.h"
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#ifndef ROCP_REG_FILE_NAME
|
||||
# define ROCP_REG_FILE_NAME \
|
||||
::std::string{ __FILE__ } \
|
||||
.substr(::std::string_view{ __FILE__ }.find_last_of('/') + 1) \
|
||||
.c_str()
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
decltype(hip_init)* hip_init_fn = nullptr;
|
||||
decltype(hsa_init)* hsa_init_fn = nullptr;
|
||||
decltype(roctxRangePush)* roctxRangePush_fn = nullptr;
|
||||
decltype(roctxRangePush)* roctxRangePop_fn = nullptr;
|
||||
|
||||
enum rocp_reg_test_modes : uint8_t
|
||||
{
|
||||
ROCP_REG_TEST_NONE = 0x0,
|
||||
ROCP_REG_TEST_HIP = (1 << 0),
|
||||
ROCP_REG_TEST_HSA = (1 << 1),
|
||||
ROCP_REG_TEST_ROCTX = (1 << 2),
|
||||
};
|
||||
|
||||
template <uint8_t Idx = ROCP_REG_TEST_NONE>
|
||||
inline void
|
||||
resolve_symbols(int _open_mode = RTLD_LOCAL | RTLD_LAZY)
|
||||
{
|
||||
auto* _open_mode_env = std::getenv("ROCP_REG_TEST_OPEN_MODE");
|
||||
if(_open_mode_env)
|
||||
{
|
||||
constexpr auto npos = std::string_view::npos;
|
||||
auto _open_mode_v = std::string_view{ _open_mode_env };
|
||||
if(_open_mode_v.find("RTLD_GLOBAL") != npos)
|
||||
_open_mode = RTLD_GLOBAL;
|
||||
else if(_open_mode_v.find("RTLD_NOLOAD") != npos)
|
||||
_open_mode = RTLD_NOLOAD;
|
||||
else
|
||||
_open_mode = RTLD_LOCAL;
|
||||
|
||||
if(_open_mode_v.find("RTLD_NOW") != npos)
|
||||
_open_mode |= RTLD_NOW;
|
||||
else
|
||||
_open_mode |= RTLD_LAZY;
|
||||
}
|
||||
|
||||
auto _resolve_dlopen = [_open_mode](void*& _handle, const char* _lib_name) {
|
||||
fprintf(
|
||||
stderr, "[%s] dlopen %s, %i\n", ROCP_REG_FILE_NAME, _lib_name, _open_mode);
|
||||
_handle = dlopen(_lib_name, _open_mode);
|
||||
if(!_handle)
|
||||
{
|
||||
fprintf(stderr, "Failure opening '%s'\n", _lib_name);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
};
|
||||
|
||||
auto _resolve_dlsym = [](auto& _func, void* _handle, const char* _func_name) {
|
||||
if(!_func && _handle && _func_name)
|
||||
{
|
||||
auto* _func_v = dlsym(_handle, _func_name);
|
||||
if(_func_v) *(void**) (&_func) = _func_v;
|
||||
}
|
||||
};
|
||||
|
||||
void* amdhip_handle = nullptr;
|
||||
void* hsart_handle = nullptr;
|
||||
void* roctx_handle = nullptr;
|
||||
|
||||
if constexpr((Idx & ROCP_REG_TEST_HIP) == ROCP_REG_TEST_HIP)
|
||||
{
|
||||
hip_init_fn = hip_init;
|
||||
if(!hip_init_fn) _resolve_dlopen(amdhip_handle, "libamdhip64.so");
|
||||
_resolve_dlsym(hip_init_fn, amdhip_handle, "hip_init");
|
||||
}
|
||||
|
||||
if constexpr((Idx & ROCP_REG_TEST_HSA) == ROCP_REG_TEST_HSA)
|
||||
{
|
||||
hsa_init_fn = hsa_init;
|
||||
if(!hsa_init_fn) _resolve_dlopen(hsart_handle, "libhsa-runtime64.so");
|
||||
_resolve_dlsym(hsa_init_fn, hsart_handle, "hsa_init");
|
||||
}
|
||||
|
||||
if constexpr((Idx & ROCP_REG_TEST_ROCTX) == ROCP_REG_TEST_ROCTX)
|
||||
{
|
||||
roctxRangePush_fn = roctxRangePush;
|
||||
roctxRangePop_fn = roctxRangePop;
|
||||
if(!roctxRangePush_fn || !roctxRangePop_fn)
|
||||
_resolve_dlopen(roctx_handle, "libroctx64.so");
|
||||
_resolve_dlsym(roctxRangePush_fn, roctx_handle, "roctxRangePush");
|
||||
_resolve_dlsym(roctxRangePop_fn, roctx_handle, "roctxRangePop");
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
@@ -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,14 @@
|
||||
#
|
||||
# mock rocprofiler library
|
||||
#
|
||||
add_library(rocprofiler SHARED)
|
||||
add_library(rocprofiler::rocprofiler ALIAS rocprofiler)
|
||||
target_sources(rocprofiler PRIVATE rocprofiler.cpp)
|
||||
target_include_directories(rocprofiler PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>
|
||||
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>)
|
||||
set_target_properties(
|
||||
rocprofiler
|
||||
PROPERTIES OUTPUT_NAME rocprofiler64
|
||||
SOVERSION 2
|
||||
VERSION 2.0.0)
|
||||
rocp_register_strip_target(rocprofiler)
|
||||
@@ -0,0 +1,135 @@
|
||||
|
||||
#include <amdhip/amdhip.hpp>
|
||||
#include <hsa-runtime/hsa-runtime.hpp>
|
||||
#include <roctx/roctx.hpp>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
|
||||
#ifndef ROCP_REG_FILE_NAME
|
||||
# define ROCP_REG_FILE_NAME \
|
||||
::std::string{ __FILE__ } \
|
||||
.substr(::std::string_view{ __FILE__ }.find_last_of('/') + 1) \
|
||||
.c_str()
|
||||
#endif
|
||||
|
||||
namespace rocprofiler
|
||||
{
|
||||
void
|
||||
hip_init()
|
||||
{
|
||||
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
hsa_init()
|
||||
{
|
||||
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
roctx_range_push(const char* name)
|
||||
{
|
||||
printf("[%s][push] %s\n", ROCP_REG_FILE_NAME, name);
|
||||
}
|
||||
|
||||
void
|
||||
roctx_range_pop(const char* name)
|
||||
{
|
||||
printf("[%s][pop] %s\n", ROCP_REG_FILE_NAME, name);
|
||||
}
|
||||
} // namespace rocprofiler
|
||||
|
||||
extern "C" {
|
||||
struct rocprofiler_configure_result_t
|
||||
{
|
||||
int (*initialize)(void*) = nullptr;
|
||||
int (*finalize)(void*) = nullptr;
|
||||
void* data = nullptr;
|
||||
};
|
||||
|
||||
rocprofiler_configure_result_t*
|
||||
rocprofiler_configure(uint32_t, const char*, uint32_t, uint32_t)
|
||||
__attribute__((visibility("default")));
|
||||
|
||||
int
|
||||
rocprofiler_set_api_table(const char*, uint64_t, uint64_t, void**, uint64_t)
|
||||
__attribute__((visibility("default")));
|
||||
|
||||
rocprofiler_configure_result_t*
|
||||
rocprofiler_configure(uint32_t version,
|
||||
const char* runtime_version,
|
||||
uint32_t priority,
|
||||
uint32_t tool_id)
|
||||
{
|
||||
(void) version;
|
||||
(void) runtime_version;
|
||||
(void) priority;
|
||||
(void) tool_id;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int
|
||||
rocprofiler_set_api_table(const char* name,
|
||||
uint64_t lib_version,
|
||||
uint64_t lib_instance,
|
||||
void** tables,
|
||||
uint64_t num_tables)
|
||||
{
|
||||
printf("[%s] %s :: %lu :: %lu :: %lu\n",
|
||||
ROCP_REG_FILE_NAME,
|
||||
name,
|
||||
lib_version,
|
||||
lib_instance,
|
||||
num_tables);
|
||||
|
||||
using hip_table_t = hip::HipApiTable;
|
||||
using hsa_table_t = hsa::HsaApiTable;
|
||||
using roctx_table_t = roctx::ROCTxApiTable;
|
||||
|
||||
auto* _wrap_v = std::getenv("ROCP_REG_TEST_WRAP");
|
||||
bool _wrap = (_wrap_v != nullptr && std::stoi(_wrap_v) != 0);
|
||||
|
||||
if(_wrap)
|
||||
{
|
||||
if(num_tables != 1)
|
||||
throw std::runtime_error{ std::string{ "unexpected number of tables: " } +
|
||||
std::to_string(num_tables) };
|
||||
|
||||
if(tables == nullptr) throw std::runtime_error{ "nullptr to tables" };
|
||||
if(tables[0] == nullptr) throw std::runtime_error{ "nullptr to tables[0]" };
|
||||
|
||||
if(std::string_view{ name } == "hip")
|
||||
{
|
||||
hip_table_t* _table = static_cast<hip_table_t*>(tables[0]);
|
||||
_table->hip_init_fn = &rocprofiler::hip_init;
|
||||
}
|
||||
else if(std::string_view{ name } == "hsa")
|
||||
{
|
||||
hsa_table_t* _table = static_cast<hsa_table_t*>(tables[0]);
|
||||
_table->hsa_init_fn = &rocprofiler::hsa_init;
|
||||
}
|
||||
else if(std::string_view{ name } == "roctx")
|
||||
{
|
||||
roctx_table_t* _table = static_cast<roctx_table_t*>(tables[0]);
|
||||
_table->roctxRangePush_fn = &rocprofiler::roctx_range_push;
|
||||
_table->roctxRangePop_fn = &rocprofiler::roctx_range_pop;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rocp_ctor(void) __attribute__((constructor));
|
||||
bool rocprofiler_test_lib_link = false;
|
||||
|
||||
void
|
||||
rocp_ctor()
|
||||
{
|
||||
rocprofiler_test_lib_link = true;
|
||||
printf("[%s] %s\n", ROCP_REG_FILE_NAME, __FUNCTION__);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user