diff --git a/projects/rocprofiler-systems/.azuredevops/rocm-ci.yml b/projects/rocprofiler-systems/.azuredevops/rocm-ci.yml new file mode 100644 index 0000000000..046cd556f4 --- /dev/null +++ b/projects/rocprofiler-systems/.azuredevops/rocm-ci.yml @@ -0,0 +1,46 @@ +resources: + repositories: + - repository: pipelines_repo + type: github + endpoint: ROCm + name: ROCm/ROCm + +variables: +- group: common +- template: /.azuredevops/variables-global.yml@pipelines_repo + +trigger: + batch: true + branches: + include: + - amd-staging + - amd-mainline + paths: + exclude: + - .github + - docs + - '.*.y*ml' + - '*.md' + - LICENSE + - VERSION + - .wordlist.txt + +pr: + autoCancel: true + branches: + include: + - amd-staging + - amd-mainline + paths: + exclude: + - .github + - docs + - '.*.y*ml' + - '*.md' + - LICENSE + - VERSION + - .wordlist.txt + drafts: false + +jobs: + - template: ${{ variables.CI_COMPONENT_PATH }}/rocprofiler-systems.yml@pipelines_repo diff --git a/projects/rocprofiler-systems/.clang-format b/projects/rocprofiler-systems/.clang-format new file mode 100644 index 0000000000..d026af09ed --- /dev/null +++ b/projects/rocprofiler-systems/.clang-format @@ -0,0 +1,148 @@ +# clang-format v18 +--- +Language: Cpp +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: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: Always + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: false + 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 +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 90 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: true +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 0 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: false +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + - Regex: '.*' + Priority: 1 + SortPriority: 0 +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: true +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: AfterHash +IndentExternBlock: AfterExternBlock +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertTrailingCommas: None +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: false +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +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: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Latest +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 4 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE +... diff --git a/projects/rocprofiler-systems/.clang-tidy b/projects/rocprofiler-systems/.clang-tidy new file mode 100644 index 0000000000..1d384b8488 --- /dev/null +++ b/projects/rocprofiler-systems/.clang-tidy @@ -0,0 +1,50 @@ +--- +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,\ +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,\ +performance-*,\ +readability-*,\ +-readability-function-size,\ +-readability-identifier-naming,\ +-readability-identifier-length,\ +-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,\ +" +CheckOptions: + - key: readability-braces-around-statements.ShortStatementLines + value: '2' + - key: readability-implicit-bool-conversion.AllowPointerConditions + value: '1' +... diff --git a/projects/rocprofiler-systems/.gersemirc b/projects/rocprofiler-systems/.gersemirc new file mode 100644 index 0000000000..49555be6e5 --- /dev/null +++ b/projects/rocprofiler-systems/.gersemirc @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/BlankSpruce/gersemi/0.19.3/gersemi/configuration.schema.json + +warn_about_unknown_commands: false +indent: 4 +line_length: 90 diff --git a/projects/rocprofiler-systems/.github/CODEOWNERS b/projects/rocprofiler-systems/.github/CODEOWNERS new file mode 100644 index 0000000000..7718f62c65 --- /dev/null +++ b/projects/rocprofiler-systems/.github/CODEOWNERS @@ -0,0 +1,8 @@ +* @ROCm/rocprof-sys @jrmadsen + +# Documentation files +docs/** @ROCm/rocm-documentation +*.md @ROCm/rocm-documentation +*.rst @ROCm/rocm-documentation +.readthedocs.yaml @ROCm/rocm-documentation +docs/sphinx/* @samjwu diff --git a/projects/rocprofiler-systems/.github/dependabot.yml b/projects/rocprofiler-systems/.github/dependabot.yml new file mode 100644 index 0000000000..d24c82f8f3 --- /dev/null +++ b/projects/rocprofiler-systems/.github/dependabot.yml @@ -0,0 +1,17 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "pip" # See documentation for possible values + directory: "/docs/sphinx" # Location of package manifests + open-pull-requests-limit: 10 + schedule: + interval: "daily" + labels: + - "documentation" + - "dependencies" + reviewers: + - "samjwu" diff --git a/projects/rocprofiler-systems/.github/pull_request_template.md b/projects/rocprofiler-systems/.github/pull_request_template.md new file mode 100644 index 0000000000..97a81a3e76 --- /dev/null +++ b/projects/rocprofiler-systems/.github/pull_request_template.md @@ -0,0 +1,35 @@ +# rocprofiler-systems Pull Request + +## Related Issue + +- [ ] Closes # + +## What type of PR is this? (check all that apply) + +- [ ] Bug Fix +- [ ] Cherry Pick +- [ ] Continuous Integration +- [ ] Documentation Update +- [ ] Feature +- [ ] Optimization +- [ ] Refactor +- [ ] Other (please specify) + +## Technical Details + + +## Have you added or updated tests to validate functionality? + +- [ ] Yes +- [ ] No - does not apply to this PR + +## Added / Updated documentation? + +- [ ] Yes +- [ ] No - does not apply to this PR + +## Have you updated CHANGELOG? + +- [ ] Yes +- [ ] No - does not apply to this PR diff --git a/projects/rocprofiler-systems/.github/workflows/containers.yml b/projects/rocprofiler-systems/.github/workflows/containers.yml new file mode 100644 index 0000000000..2362b8d38a --- /dev/null +++ b/projects/rocprofiler-systems/.github/workflows/containers.yml @@ -0,0 +1,189 @@ +name: Continuous Integration Containers +run-name: ci-containers + +# nightly build +on: + workflow_dispatch: + schedule: + - cron: 0 5 * * * + push: + branches: [amd-staging, amd-mainline] + paths: + - '.github/workflows/containers.yml' + - 'docker/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + GIT_DISCOVERY_ACROSS_FILESYSTEM: 1 + +jobs: + rocprofiler-systems-ci: + if: github.repository == 'ROCm/rocprofiler-systems' + + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + include: + - distro: "ubuntu" + version: "20.04" + - distro: "ubuntu" + version: "22.04" + - distro: "ubuntu" + version: "24.04" + - distro: "opensuse" + version: "15.5" + - distro: "opensuse" + version: "15.6" + - distro: "rhel" + version: "8.10" + - distro: "rhel" + version: "9.3" + - distro: "rhel" + version: "9.4" + - distro: "rhel" + version: "9.5" + + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build CI Container + timeout-minutes: 45 + uses: nick-fields/retry@v3 + with: + retry_wait_seconds: 60 + timeout_minutes: 45 + max_attempts: 3 + command: | + pushd docker + ./build-docker-ci.sh --distro ${{ matrix.distro }} --versions ${{ matrix.version }} --user ${{ secrets.DOCKERHUB_USERNAME }} --push --jobs 2 --elfutils-version 0.186 --boost-version 1.79.0 + popd + + rocprofiler-systems-release: + if: github.repository == 'ROCm/rocprofiler-systems' + + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + include: + # ubuntu 20.04 + - os-distro: "ubuntu" + os-version: "20.04" + rocm-version: "0.0" + - os-distro: "ubuntu" + os-version: "20.04" + rocm-version: "6.3" + # ubuntu 22.04 + - os-distro: "ubuntu" + os-version: "22.04" + rocm-version: "0.0" + - os-distro: "ubuntu" + os-version: "22.04" + rocm-version: "6.3" + - os-distro: "ubuntu" + os-version: "22.04" + rocm-version: "6.4" + # ubuntu 24.04 + - os-distro: "ubuntu" + os-version: "24.04" + rocm-version: "0.0" + - os-distro: "ubuntu" + os-version: "24.04" + rocm-version: "6.3" + - os-distro: "ubuntu" + os-version: "24.04" + rocm-version: "6.4" + # opensuse 15.5 + - os-distro: "opensuse" + os-version: "15.5" + rocm-version: "0.0" + - os-distro: "opensuse" + os-version: "15.5" + rocm-version: "6.3" + # opensuse 15.6 + - os-distro: "opensuse" + os-version: "15.6" + rocm-version: "0.0" + - os-distro: "opensuse" + os-version: "15.6" + rocm-version: "6.3" + - os-distro: "opensuse" + os-version: "15.6" + rocm-version: "6.4" + # RHEL 8.10 + - os-distro: "rhel" + os-version: "8.10" + rocm-version: "0.0" + - os-distro: "rhel" + os-version: "8.10" + rocm-version: "6.3" + - os-distro: "rhel" + os-version: "8.10" + rocm-version: "6.4" + # RHEL 9.4 + - os-distro: "rhel" + os-version: "9.4" + rocm-version: "0.0" + - os-distro: "rhel" + os-version: "9.4" + rocm-version: "6.3" + - os-distro: "rhel" + os-version: "9.4" + rocm-version: "6.4" + # RHEL 9.5 + - os-distro: "rhel" + os-version: "9.5" + rocm-version: "0.0" + - os-distro: "rhel" + os-version: "9.5" + rocm-version: "6.3" + - os-distro: "rhel" + os-version: "9.5" + rocm-version: "6.4" + + steps: + - uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build Base Container + timeout-minutes: 45 + uses: nick-fields/retry@v3 + with: + retry_wait_seconds: 60 + timeout_minutes: 45 + max_attempts: 3 + command: | + pushd docker + ./build-docker.sh --distro ${{ matrix.os-distro }} --versions ${{ matrix.os-version }} --rocm-versions ${{ matrix.rocm-version }} --user ${{ secrets.DOCKERHUB_USERNAME }} --push + popd diff --git a/projects/rocprofiler-systems/.github/workflows/cpack.yml b/projects/rocprofiler-systems/.github/workflows/cpack.yml new file mode 100644 index 0000000000..8caab6a979 --- /dev/null +++ b/projects/rocprofiler-systems/.github/workflows/cpack.yml @@ -0,0 +1,191 @@ +name: Installer Packaging (CPack) +run-name: cpack + +on: + workflow_dispatch: + push: + branches: [amd-staging, amd-mainline, release/**] + tags: + - "v[1-9].[0-9]+.[0-9]+*" + - "rocm-[1-9].[0-9]+.[0-9]+*" + paths-ignore: + - '*.md' + - 'docs/**' + - 'source/docs/**' + pull_request: + branches: [amd-staging, amd-mainline, release/**] + paths: + - '.github/workflows/cpack.yml' + - 'docker/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + GIT_DISCOVERY_ACROSS_FILESYSTEM: 1 + +jobs: + installers: + if: github.repository == 'ROCm/rocprofiler-systems' + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + # ubuntu 20.04 + - os-distro: "ubuntu" + os-version: "20.04" + rocm-version: "0.0" + - os-distro: "ubuntu" + os-version: "20.04" + rocm-version: "6.3" + # ubuntu 22.04 + - os-distro: "ubuntu" + os-version: "22.04" + rocm-version: "0.0" + - os-distro: "ubuntu" + os-version: "22.04" + rocm-version: "6.3" + - os-distro: "ubuntu" + os-version: "22.04" + rocm-version: "6.4" + # ubuntu 24.04 + - os-distro: "ubuntu" + os-version: "24.04" + rocm-version: "0.0" + - os-distro: "ubuntu" + os-version: "24.04" + rocm-version: "6.3" + - os-distro: "ubuntu" + os-version: "24.04" + rocm-version: "6.4" + # opensuse 15.5 + - os-distro: "opensuse" + os-version: "15.5" + rocm-version: "0.0" + - os-distro: "opensuse" + os-version: "15.5" + rocm-version: "6.3" + # opensuse 15.6 + - os-distro: "opensuse" + os-version: "15.6" + rocm-version: "0.0" + - os-distro: "opensuse" + os-version: "15.6" + rocm-version: "6.3" + - os-distro: "opensuse" + os-version: "15.6" + rocm-version: "6.4" + # RHEL 8.10 + - os-distro: "rhel" + os-version: "8.10" + rocm-version: "0.0" + - os-distro: "rhel" + os-version: "8.10" + rocm-version: "6.3" + - os-distro: "rhel" + os-version: "8.10" + rocm-version: "6.4" + # RHEL 9.4 + - os-distro: "rhel" + os-version: "9.4" + rocm-version: "0.0" + - os-distro: "rhel" + os-version: "9.4" + rocm-version: "6.3" + - os-distro: "rhel" + os-version: "9.4" + rocm-version: "6.4" + # RHEL 9.5 + - os-distro: "rhel" + os-version: "9.5" + rocm-version: "0.0" + - os-distro: "rhel" + os-version: "9.5" + rocm-version: "6.3" + - os-distro: "rhel" + os-version: "9.5" + rocm-version: "6.4" + + steps: + - name: Free Disk Space + uses: jlumbroso/free-disk-space@v1.2.0 + with: + tool-cache: false + android: true + dotnet: true + haskell: true + large-packages: false + swap-storage: false + + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Configure ROCm Version + if: ${{ matrix.rocm-version == 0 }} + run: | + echo "CI_SCRIPT_ARGS=--core +python" >> $GITHUB_ENV + + - name: Configure ROCm Version + if: ${{ matrix.rocm-version > 0 }} + run: | + echo "CI_SCRIPT_ARGS=--rocm +python" >> $GITHUB_ENV + + - name: Configure Generators + run: | + echo "CI_GENERATOR_ARGS=--generators STGZ" >> $GITHUB_ENV + + - name: Build Base Container + timeout-minutes: 30 + run: | + pushd docker + ./build-docker.sh --distro ${{ matrix.os-distro }} --versions ${{ matrix.os-version }} --rocm-versions ${{ matrix.rocm-version }} + popd + + - name: Build Release + timeout-minutes: 150 + run: | + pushd docker + ./build-docker-release.sh --distro ${{ matrix.os-distro }} --versions ${{ matrix.os-version }} --rocm-versions ${{ matrix.rocm-version }} -- ${CI_SCRIPT_ARGS} ${CI_GENERATOR_ARGS} + popd + + - name: List Files + timeout-minutes: 10 + run: | + find build-release -type f | egrep '\.(sh|deb|rpm)$' + + - name: STGZ Artifacts + timeout-minutes: 10 + uses: actions/upload-artifact@v4 + with: + name: rocprofiler-systems-stgz-${{ matrix.os-distro }}-${{ matrix.os-version }}-rocm-${{ matrix.rocm-version }}-installer + path: | + build-release/stgz/*.sh + + # before testing remove any artifacts of the build + - name: Remove Build + timeout-minutes: 10 + run: | + shopt -s nullglob + for i in $(find build-release -type f | egrep '/(stgz|deb|rpm)/.*\.(sh|deb|rpm)$'); do mv ${i} ./; done + sudo rm -rf build-release + sudo rm -rf /opt/rocprofiler-systems + + - name: Test STGZ Install + timeout-minutes: 20 + run: | + set -v + for i in rocprofiler-systems-*.sh + do + ./docker/test-docker-release.sh --distro ${{ matrix.os-distro }} --versions ${{ matrix.os-version }} --rocm-versions ${{ matrix.rocm-version }} -- --stgz ${i} + done + + - name: Upload STGZ Release Assets + uses: softprops/action-gh-release@v2 + if: startsWith(github.ref, 'refs/tags/') && github.repository == 'ROCm/rocprofiler-systems' + with: + fail_on_unmatched_files: True + files: | + rocprofiler-systems-*.sh diff --git a/projects/rocprofiler-systems/.github/workflows/formatting.yml b/projects/rocprofiler-systems/.github/workflows/formatting.yml new file mode 100644 index 0000000000..993fca0446 --- /dev/null +++ b/projects/rocprofiler-systems/.github/workflows/formatting.yml @@ -0,0 +1,104 @@ + +name: Formatting +run-name: formatting + +on: + push: + branches: [ amd-mainline, amd-staging, release/** ] + pull_request: + branches: [ amd-mainline, amd-staging, release/** ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + + call-workflow-passing-data: + name: Documentation + uses: ROCm/rocm-docs-core/.github/workflows/linting.yml@develop + + python: + runs-on: ubuntu-22.04 + strategy: + matrix: + python-version: [3.8] + + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install black + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: black format + run: | + black --diff --check . + + cmake: + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@v4 + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y python3-pip + python3 -m pip install gersemi + - name: gersemi + run: | + set +e + gersemi -i $(find . -type f ! -path '*/external/*' | grep -E 'CMakeLists.txt|\.cmake$') + if [ $(git diff | wc -l) -gt 0 ]; then + echo -e "\nError! CMake code not formatted. Run gersemi ...\n" + echo -e "\nFiles:\n" + git diff --name-only + echo -e "\nFull diff:\n" + git diff + exit 1 + fi + + source: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - 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-18 + - name: clang-format + run: | + set +e + FILES=$(find source examples tests -type f | egrep '\.(h|hpp|c|cpp)(|\.in)$') + FORMAT_OUT=$(clang-format-18 -output-replacements-xml ${FILES}) + RET=$(echo ${FORMAT_OUT} | grep -c '> $GITHUB_ENV && + echo "CXX=${{ matrix.compiler }}" >> $GITHUB_ENV && + echo "/opt/rocprofiler-systems/bin:${HOME}/.local/bin" >> $GITHUB_PATH && + echo "LD_LIBRARY_PATH=/opt/rocprofiler-systems/lib:${LD_LIBRARY_PATH}" >> $GITHUB_ENV + + - name: Configure, Build, and Test + timeout-minutes: 115 + shell: bash + run: + git config --global --add safe.directory ${PWD} && + cmake --version && + python3 ./scripts/run-ci.py -B build + --name ${{ github.repository_owner }}-${{ github.ref_name }}-opensuse-${{ matrix.os-release }}-${{ matrix.compiler }}-nompi-python + --build-jobs 2 + --site GitHub + -- + -DCMAKE_C_COMPILER=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g') + -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} + -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} + -DCMAKE_INSTALL_PREFIX=/opt/rocprofiler-systems + -DROCPROFSYS_BUILD_TESTING=ON + -DROCPROFSYS_USE_MPI=OFF + -DROCPROFSYS_USE_ROCM=OFF + -DROCPROFSYS_USE_OMPT=OFF + -DROCPROFSYS_USE_PYTHON=ON + -DROCPROFSYS_BUILD_DYNINST=ON + -DROCPROFSYS_BUILD_BOOST=ON + -DROCPROFSYS_BUILD_TBB=ON + -DROCPROFSYS_BUILD_ELFUTILS=ON + -DROCPROFSYS_BUILD_LIBIBERTY=ON + -DROCPROFSYS_INSTALL_PERFETTO_TOOLS=OFF + -DROCPROFSYS_USE_MPI_HEADERS=ON + -DROCPROFSYS_PYTHON_PREFIX=/opt/conda/envs + -DROCPROFSYS_PYTHON_ENVS="py3.6;py3.7;py3.8;py3.9;py3.10;py3.11" + -DROCPROFSYS_CI_MPI_RUN_AS_ROOT=ON + -DROCPROFSYS_MAX_THREADS=64 + -DROCPROFSYS_DISABLE_EXAMPLES="transpose;rccl;openmp-target;videodecode;jpegdecode" + -DROCPROFSYS_BUILD_NUMBER=${{ github.run_attempt }} + -- + -LE "transpose|rccl|videodecode|jpegdecode|network|mpi" + + - name: Install + timeout-minutes: 10 + run: + cmake --build build --target install --parallel 2 + + - name: Test Install + timeout-minutes: 10 + run: | + set -v + export ROCPROFSYS_DEBUG=ON + which rocprof-sys-avail + ldd $(which rocprof-sys-avail) + rocprof-sys-avail --help + rocprof-sys-avail -a + which rocprof-sys-instrument + ldd $(which rocprof-sys-instrument) + rocprof-sys-instrument --help + rocprof-sys-instrument -e -v 1 -o ls.inst --simulate -- ls + for i in $(find rocprofsys-ls.inst-output -type f); do echo -e "\n\n --> ${i} \n\n"; cat ${i}; done + rocprof-sys-instrument -e -v 1 -o ls.inst -- ls + rocprof-sys-run -- ./ls.inst + rocprof-sys-instrument -e -v 1 --simulate -- ls + for i in $(find rocprofsys-ls-output -type f); do echo -e "\n\n --> ${i} \n\n"; cat ${i}; done + rocprof-sys-instrument -e -v 1 -- ls + + - name: Test User API + timeout-minutes: 10 + run: | + set -v + ./scripts/test-find-package.sh --install-dir /opt/rocprofiler-systems + + - name: CTest Artifacts + if: failure() + continue-on-error: True + uses: actions/upload-artifact@v4 + with: + name: ctest-${{ github.job }}-${{ strategy.job-index }}-log + path: | + build/*.log + + - name: Data Artifacts + if: failure() + continue-on-error: True + uses: actions/upload-artifact@v4 + with: + name: data-${{ github.job }}-${{ strategy.job-index }}-files + path: | + build/rocprofsys-tests-config/*.cfg + build/rocprofsys-tests-output/**/*.txt + build/rocprofsys-tests-output/**/*-instr*.json + + - name: Kill Perfetto + if: success() || failure() + continue-on-error: True + run: | + set +e + RUNNING_PROCS=$(pgrep trace_processor_shell) + if [ -n "${RUNNING_PROCS}" ]; then kill -s 9 ${RUNNING_PROCS}; fi diff --git a/projects/rocprofiler-systems/.github/workflows/python.yml b/projects/rocprofiler-systems/.github/workflows/python.yml new file mode 100644 index 0000000000..8edbedd503 --- /dev/null +++ b/projects/rocprofiler-systems/.github/workflows/python.yml @@ -0,0 +1,45 @@ +name: Python +run-name: Python + +on: + push: + branches: [ amd-mainline, amd-staging ] + paths: + - 'source/python/gui/*.py' + - 'source/python/gui/**/*.py' + pull_request: + branches: [ amd-mainline, amd-staging ] + paths: + - 'source/python/gui/*.py' + - 'source/python/gui/**/*.py' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + linting: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.7", "3.8", "3.9", "3.10"] + + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + working-directory: ${{ github.workspace }}/source/python/gui + run: | + python -m pip install --upgrade pip + pip install flake8 + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Lint with flake8 + working-directory: ${{ github.workspace }}/source/python/gui + run: | + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # flake8 options are defined in setup.cfg + flake8 . --count --statistics diff --git a/projects/rocprofiler-systems/.github/workflows/redhat.yml b/projects/rocprofiler-systems/.github/workflows/redhat.yml new file mode 100644 index 0000000000..6de49268eb --- /dev/null +++ b/projects/rocprofiler-systems/.github/workflows/redhat.yml @@ -0,0 +1,180 @@ +name: RedHat Linux (GCC, Python, ROCm) +run-name: redhat + +on: + push: + branches: [ amd-mainline, amd-staging, release/** ] + paths-ignore: + - '*.md' + - 'docs/**' + - 'source/docs/**' + - 'source/python/gui/**' + - '.github/workflows/docs.yml' + - '.github/workflows/cpack.yml' + - '.github/workflows/containers.yml' + - '.github/workflows/formatting.yml' + - '.github/workflows/weekly-mainline-sync.yml' + - 'docker/**' + - .wordlist.txt + - CMakePresets.json + pull_request: + branches: [ amd-mainline, amd-staging, release/** ] + paths-ignore: + - '*.md' + - 'docs/**' + - 'source/docs/**' + - 'source/python/gui/**' + - '.github/workflows/docs.yml' + - '.github/workflows/cpack.yml' + - '.github/workflows/containers.yml' + - '.github/workflows/formatting.yml' + - '.github/workflows/weekly-mainline-sync.yml' + - 'docker/**' + - .wordlist.txt + - CMakePresets.json + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + ROCPROFSYS_CI: ON + ROCPROFSYS_TMPDIR: "%env{PWD}%/testing-tmp" + +jobs: + rhel: + runs-on: ubuntu-latest + container: + image: dgaliffiamd/rocprofiler-systems:ci-base-rhel-${{ matrix.os-release }} + strategy: + fail-fast: false + matrix: + compiler: ['g++'] + os-release: [ '8.10', '9.3', '9.4' ] + rocm-version: [ '0.0', '6.3', '6.4' ] + build-type: ['Release'] + + steps: + - uses: actions/checkout@v4 + + - name: Configure Env + shell: bash + run: + echo "CC=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g')" >> $GITHUB_ENV && + echo "CXX=${{ matrix.compiler }}" >> $GITHUB_ENV && + echo "OS_VERSION_MAJOR=$(cat /etc/os-release | grep 'VERSION_ID' | sed 's/=/ /1' | awk '{print $NF}' | sed 's/"//g' | sed 's/\./ /g' | awk '{print $1}')" >> $GITHUB_ENV && + env + + - name: Install Packages + shell: bash + run: | + if [ $OS_VERSION_MAJOR -eq 8 ]; then + wget https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/linux-amd64/trace_processor_shell -P /opt/trace_processor/bin && + chmod +x /opt/trace_processor/bin/trace_processor_shell + fi + python3 -m pip install --upgrade pip && + python3 -m pip install --upgrade numpy perfetto dataclasses && + python3 -m pip install 'cmake==3.21' && + for i in 6 7 8 9 10 11; do /opt/conda/envs/py3.${i}/bin/python -m pip install --upgrade numpy perfetto dataclasses; done + + - name: Install ROCm Packages + if: ${{ matrix.rocm-version > 0 }} + timeout-minutes: 30 + shell: bash + run: | + RPM_TAG=".el${OS_VERSION_MAJOR}" + ROCM_VERSION=${{ matrix.rocm-version }} + ROCM_MAJOR=$(echo ${ROCM_VERSION} | sed 's/\./ /g' | awk '{print $1}') + ROCM_MINOR=$(echo ${ROCM_VERSION} | sed 's/\./ /g' | awk '{print $2}') + ROCM_VERSN=$(( (${ROCM_MAJOR}*10000)+(${ROCM_MINOR}*100) )) + if [ "${OS_VERSION_MAJOR}" -eq 8 ]; then PERL_REPO=powertools; else PERL_REPO=crb; fi + dnf -y --enablerepo=${PERL_REPO} install perl-File-BaseDir + yum install -y https://repo.radeon.com/amdgpu-install/${{ matrix.rocm-version }}/rhel/${{ matrix.os-release }}/amdgpu-install-${ROCM_MAJOR}.${ROCM_MINOR}.${ROCM_VERSN}-1${RPM_TAG}.noarch.rpm + yum install -y rocm-dev rocdecode-devel + if [ "${OS_VERSION_MAJOR}" -gt 8 ]; then dnf install -y libavcodec-free-devel libavformat-free-devel; fi + + - name: Configure, Build, and Test + timeout-minutes: 115 + shell: bash + run: + git config --global --add safe.directory ${PWD} && + cmake --version && + TAG="${{ github.repository_owner }}-${{ github.ref_name }}-rhel-${{ matrix.os-release }}-${{ matrix.compiler }}-python-mpip" && + USE_HIP=OFF && + if [ ${{ matrix.rocm-version }} != "0.0" ]; then USE_HIP=ON; TAG="${TAG}-rocm-${{ matrix.rocm-version }}"; fi && + python3 ./scripts/run-ci.py -B build + --name ${TAG} + --build-jobs 2 + --site GitHub + -- + -DCMAKE_C_COMPILER=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g') + -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} + -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} + -DCMAKE_INSTALL_PREFIX=/opt/rocprofiler-systems + -DROCPROFSYS_BUILD_TESTING=ON + -DROCPROFSYS_USE_MPI=OFF + -DROCPROFSYS_USE_ROCM=${USE_HIP} + -DROCPROFSYS_USE_OMPT=OFF + -DROCPROFSYS_USE_PYTHON=ON + -DROCPROFSYS_BUILD_DYNINST=ON + -DROCPROFSYS_BUILD_BOOST=ON + -DROCPROFSYS_BUILD_TBB=ON + -DROCPROFSYS_BUILD_ELFUTILS=ON + -DROCPROFSYS_BUILD_LIBIBERTY=ON + -DROCPROFSYS_USE_MPI_HEADERS=ON + -DROCPROFSYS_CI_MPI_RUN_AS_ROOT=ON + -DROCPROFSYS_MAX_THREADS=64 + -DROCPROFSYS_INSTALL_PERFETTO_TOOLS=OFF + -DROCPROFSYS_PYTHON_PREFIX=/opt/conda/envs + -DROCPROFSYS_PYTHON_ENVS="py3.6;py3.7;py3.8;py3.9;py3.10;py3.11" + -DROCPROFSYS_DISABLE_EXAMPLES="transpose;rccl;openmp-target" + -DROCPROFSYS_BUILD_NUMBER=${{ github.run_attempt }} + -- + -LE "transpose|rccl|videodecode|jpegdecode|network" + + - name: Install + timeout-minutes: 10 + run: + cmake --build build --target install --parallel 2 + + - name: Test Install + timeout-minutes: 10 + shell: bash + run: | + set -v + source /opt/rocprofiler-systems/share/rocprofiler-systems/setup-env.sh + ./scripts/test-install.sh --test-rocprof-sys-{instrument,avail,sample,rewrite,runtime,python}=1 + + - name: Test User API + timeout-minutes: 10 + run: | + set -v + ./scripts/test-find-package.sh --install-dir /opt/rocprofiler-systems + + - name: CTest Artifacts + if: failure() + continue-on-error: True + uses: actions/upload-artifact@v4 + with: + name: ctest-${{ github.job }}-${{ strategy.job-index }}-log + path: | + build/*.log + + - name: Data Artifacts + if: failure() + continue-on-error: True + uses: actions/upload-artifact@v4 + with: + name: data-${{ github.job }}-${{ strategy.job-index }}-files + path: | + build/rocprofsys-tests-config/*.cfg + build/rocprofsys-tests-output/**/*.txt + build/rocprofsys-tests-output/**/*-instr*.json + + - name: Kill Perfetto + if: success() || failure() + continue-on-error: True + run: | + set +e + RUNNING_PROCS=$(pgrep trace_processor_shell) + if [ -n "${RUNNING_PROCS}" ]; then kill -s 9 ${RUNNING_PROCS}; fi diff --git a/projects/rocprofiler-systems/.github/workflows/release.yml b/projects/rocprofiler-systems/.github/workflows/release.yml new file mode 100644 index 0000000000..1d9dda52f9 --- /dev/null +++ b/projects/rocprofiler-systems/.github/workflows/release.yml @@ -0,0 +1,40 @@ +name: Release + +on: + workflow_dispatch: + push: + tags: + - "v[1-9].[0-9]+.[0-9]+*" + - "rocm-[1-9].[0-9]+.[0-9]+*" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + GIT_DISCOVERY_ACROSS_FILESYSTEM: 1 + +jobs: + release: + if: github.repository == 'ROCm/rocprofiler-systems' + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Generate generic installer script + shell: bash + run: | + sudo apt-get update + sudo apt-get install -y cmake + cmake -D OUTPUT_DIR=${PWD} -P scripts/write-rocprof-sys-install.cmake + - name: Generate Release + uses: softprops/action-gh-release@v1 + with: + draft: False + generate_release_notes: True + fail_on_unmatched_files: True + files: | + rocprofiler-systems-install.py diff --git a/projects/rocprofiler-systems/.github/workflows/ubuntu-focal.yml b/projects/rocprofiler-systems/.github/workflows/ubuntu-focal.yml new file mode 100644 index 0000000000..be18f9c894 --- /dev/null +++ b/projects/rocprofiler-systems/.github/workflows/ubuntu-focal.yml @@ -0,0 +1,487 @@ +name: Ubuntu 20.04 (GCC, Python, ROCm, MPICH, OpenMPI) +run-name: ubuntu-focal + +on: + push: + branches: [ amd-mainline, amd-staging, release/** ] + paths-ignore: + - '*.md' + - 'docs/**' + - 'source/docs/**' + - 'source/python/gui/**' + - '.github/workflows/docs.yml' + - '.github/workflows/cpack.yml' + - '.github/workflows/containers.yml' + - '.github/workflows/formatting.yml' + - '.github/workflows/weekly-mainline-sync.yml' + - 'docker/**' + - .wordlist.txt + - CMakePresets.json + pull_request: + branches: [ amd-mainline, amd-staging, release/** ] + paths-ignore: + - '*.md' + - 'docs/**' + - 'source/docs/**' + - 'source/python/gui/**' + - '.github/workflows/docs.yml' + - '.github/workflows/cpack.yml' + - '.github/workflows/containers.yml' + - '.github/workflows/formatting.yml' + - '.github/workflows/weekly-mainline-sync.yml' + - 'docker/**' + - .wordlist.txt + - CMakePresets.json + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + ROCPROFSYS_CI: ON + ROCPROFSYS_TMPDIR: "%env{PWD}%/testing-tmp" + +jobs: + ubuntu-focal-external: + runs-on: ubuntu-latest + container: + image: dgaliffiamd/rocprofiler-systems:ci-base-ubuntu-20.04 + strategy: + fail-fast: false + matrix: + compiler: ['g++-7', 'g++-8'] + lto: ['OFF'] + strip: ['OFF'] + python: ['OFF'] + build-type: ['Release'] + mpi-headers: ['OFF'] + static-libgcc: ['OFF'] + static-libstdcxx: ['OFF'] + include: + - compiler: 'g++-9' + lto: 'OFF' + strip: 'ON' + python: 'OFF' + build-type: 'Release' + mpi-headers: 'ON' + static-libgcc: 'ON' + static-libstdcxx: 'ON' + - compiler: 'g++-10' + lto: 'OFF' + strip: 'ON' + python: 'ON' + build-type: 'Release' + mpi-headers: 'ON' + static-libgcc: 'ON' + static-libstdcxx: 'OFF' + - compiler: 'g++-11' + lto: 'ON' + strip: 'ON' + python: 'OFF' + build-type: 'Release' + mpi-headers: 'ON' + static-libgcc: 'ON' + static-libstdcxx: 'OFF' + + steps: + - uses: actions/checkout@v4 + + - name: Install Packages + timeout-minutes: 25 + uses: nick-fields/retry@v3 + with: + retry_wait_seconds: 30 + timeout_minutes: 25 + max_attempts: 5 + command: | + apt-get update && + apt-get install -y software-properties-common && + add-apt-repository -y ppa:ubuntu-toolchain-r/test && + apt-get update && + apt-get upgrade -y && + apt-get install -y autoconf bison build-essential clang environment-modules gettext libiberty-dev libmpich-dev libtool m4 mpich python3-pip texinfo ${{ matrix.compiler }} && + wget https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/linux-amd64/trace_processor_shell -P /opt/trace_processor/bin && + chmod +x /opt/trace_processor/bin/trace_processor_shell && + python3 -m pip install --upgrade pip && + python3 -m pip install --upgrade numpy perfetto dataclasses && + python3 -m pip install 'cmake==3.21' && + for i in 6 7 8 9 10 11; do /opt/conda/envs/py3.${i}/bin/python -m pip install --upgrade numpy perfetto dataclasses; done && + apt-get -y --purge autoremove && + apt-get -y clean && + /opt/conda/bin/conda clean -y -a + + + - name: Test Environment Modules + timeout-minutes: 15 + shell: bash + run: | + set -v + source /usr/share/modules/init/$(basename ${SHELL}) + module avail + + - name: Configure Env + run: + echo "CC=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g')" >> $GITHUB_ENV && + echo "CXX=${{ matrix.compiler }}" >> $GITHUB_ENV + + - name: Configure, Build, and Test + timeout-minutes: 115 + shell: bash + run: + git config --global --add safe.directory ${PWD} && + TAG="" && + append-tagname() { if [ "${1}" == "ON" ]; then TAG="${TAG}-${2}"; fi; } && + append-tagname ${{ matrix.lto }} lto && + append-tagname ${{ matrix.strip }} strip && + append-tagname ${{ matrix.python }} python && + append-tagname ${{ matrix.mpi-headers }} mpip && + append-tagname ${{ matrix.static-libgcc }} libgcc && + append-tagname ${{ matrix.static-libstdcxx }} libstdcxx && + cmake --version && + python3 ./scripts/run-ci.py -B build + --name ${{ github.repository_owner }}-${{ github.ref_name }}-ubuntu-focal-${{ matrix.compiler }}${TAG} + --build-jobs 2 + --site GitHub + -- + -DCMAKE_C_COMPILER=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g') + -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} + -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} + -DCMAKE_INSTALL_PREFIX=/opt/rocprofiler-systems + -DROCPROFSYS_BUILD_TESTING=ON + -DROCPROFSYS_USE_MPI=OFF + -DROCPROFSYS_USE_ROCM=OFF + -DROCPROFSYS_USE_OMPT=OFF + -DROCPROFSYS_USE_PAPI=OFF + -DROCPROFSYS_BUILD_DYNINST=ON + -DROCPROFSYS_BUILD_BOOST=ON + -DROCPROFSYS_BUILD_TBB=ON + -DROCPROFSYS_BUILD_ELFUTILS=ON + -DROCPROFSYS_BUILD_LIBIBERTY=ON + -DROCPROFSYS_USE_PYTHON=${{ matrix.python }} + -DROCPROFSYS_USE_MPI_HEADERS=${{ matrix.mpi-headers }} + -DROCPROFSYS_STRIP_LIBRARIES=${{ matrix.strip }} + -DROCPROFSYS_BUILD_LTO=${{ matrix.lto }} + -DROCPROFSYS_BUILD_STATIC_LIBGCC=${{ matrix.static-libgcc }} + -DROCPROFSYS_BUILD_STATIC_LIBSTDCXX=${{ matrix.static-libstdcxx }} + -DROCPROFSYS_PYTHON_PREFIX=/opt/conda/envs + -DROCPROFSYS_PYTHON_ENVS="py3.6;py3.7;py3.8;py3.9;py3.10;py3.11" + -DROCPROFSYS_MAX_THREADS=64 + -DROCPROFSYS_DISABLE_EXAMPLES="transpose;rccl;videodecode;jpegdecode;openmp-target" + -DROCPROFSYS_BUILD_NUMBER=${{ github.run_attempt }} + -DMPI_HEADERS_ALLOW_MPICH=OFF + -- + -LE "transpose|rccl|videodecode|jpegdecode|network" + + - name: Test Build-Tree Module + timeout-minutes: 45 + shell: bash + run: | + cd build + source /usr/share/modules/init/$(basename ${SHELL}) + module use ./share/modulefiles + module avail + module load rocprofiler-systems + echo $(which rocprof-sys-instrument) + ldd $(which rocprof-sys-instrument) + rocprof-sys-instrument --help + rocprof-sys-avail --help + rocprof-sys-sample --help + + - name: Test Build-Tree Source Script + timeout-minutes: 45 + shell: bash + run: | + cd build + source ./share/rocprofiler-systems/setup-env.sh + echo $(which rocprof-sys-instrument) + ldd $(which rocprof-sys-instrument) + rocprof-sys-instrument --help + rocprof-sys-avail --help + rocprof-sys-sample --help + + - name: Install + timeout-minutes: 10 + run: + cmake --build build --target install --parallel 2 + + - name: Test Install + timeout-minutes: 15 + shell: bash + run: | + source /usr/share/modules/init/$(basename ${SHELL}) + module use /opt/rocprofiler-systems/share/modulefiles + module avail + module load rocprofiler-systems + ./scripts/test-install.sh --test-rocprof-sys-{instrument,avail,sample,rewrite,runtime}=1 --test-rocprof-sys-python=${{ matrix.python }} + + - name: Test User API + timeout-minutes: 10 + run: | + set -v + ./scripts/test-find-package.sh --install-dir /opt/rocprofiler-systems + + - name: CTest Artifacts + if: failure() + continue-on-error: True + uses: actions/upload-artifact@v4 + with: + name: ctest-${{ github.job }}-${{ strategy.job-index }}-log + path: | + build/*.log + + - name: Data Artifacts + if: failure() + continue-on-error: True + uses: actions/upload-artifact@v4 + with: + name: data-${{ github.job }}-${{ strategy.job-index }}-files + path: | + build/rocprofsys-tests-config/*.cfg + build/rocprofsys-tests-output/**/*.txt + build/rocprofsys-tests-output/**/*-instr*.json + + - name: Kill Perfetto + if: success() || failure() + continue-on-error: True + run: | + set +e + RUNNING_PROCS=$(pgrep trace_processor_shell) + if [ -n "${RUNNING_PROCS}" ]; then kill -s 9 ${RUNNING_PROCS}; fi + + ubuntu-focal-external-rocm: + runs-on: ubuntu-latest + container: + image: dgaliffiamd/rocprofiler-systems:ci-base-ubuntu-20.04 + strategy: + fail-fast: false + matrix: + compiler: ['g++'] + rocm-version: ['6.3'] + mpi-headers: ['OFF'] + build-jobs: ['3'] + ctest-exclude: ['-LE "transpose|videodecode|jpegdecode|network"'] + + env: + BUILD_TYPE: MinSizeRel + OMPI_ALLOW_RUN_AS_ROOT: 1 + OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1 + + steps: + - uses: actions/checkout@v4 + + - name: Install Packages + timeout-minutes: 25 + uses: nick-fields/retry@v3 + with: + retry_wait_seconds: 30 + timeout_minutes: 25 + max_attempts: 5 + command: | + apt-get update && + apt-get install -y software-properties-common wget gnupg2 && + ROCM_VERSION=${{ matrix.rocm-version }} && + ROCM_MAJOR=$(echo ${ROCM_VERSION} | sed 's/\./ /g' | awk '{print $1}') && + ROCM_MINOR=$(echo ${ROCM_VERSION} | sed 's/\./ /g' | awk '{print $2}') && + ROCM_VERSN=$(( (${ROCM_MAJOR}*10000)+(${ROCM_MINOR}*100) )) && + echo "ROCM_MAJOR=${ROCM_MAJOR} ROCM_MINOR=${ROCM_MINOR} ROCM_VERSN=${ROCM_VERSN}" && + wget -q https://repo.radeon.com/amdgpu-install/${{ matrix.rocm-version }}/ubuntu/focal/amdgpu-install_${ROCM_MAJOR}.${ROCM_MINOR}.${ROCM_VERSN}-1_all.deb && + apt-get install -y ./amdgpu-install_${ROCM_MAJOR}.${ROCM_MINOR}.${ROCM_VERSN}-1_all.deb && + apt-get update && + apt-get install -y autoconf bison build-essential clang curl gettext libfabric-dev libnuma1 libomp-dev libopenmpi-dev libpapi-dev libtool libudev1 m4 openmpi-bin python3-pip rocm-dev texinfo && + apt-get install -y rocdecode-dev libavformat-dev libavcodec-dev && + wget https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/linux-amd64/trace_processor_shell -P /opt/trace_processor/bin && + chmod +x /opt/trace_processor/bin/trace_processor_shell && + python3 -m pip install --upgrade pip && + python3 -m pip install --upgrade numpy perfetto dataclasses && + python3 -m pip install 'cmake==3.21' && + for i in 6 7 8 9 10 11; do /opt/conda/envs/py3.${i}/bin/python -m pip install --upgrade numpy perfetto dataclasses; done && + apt-get -y --purge autoremove && + apt-get -y clean && + /opt/conda/bin/conda clean -y -a + + + - name: Configure Env + run: | + echo "CC=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g')" >> $GITHUB_ENV + echo "CXX=${{ matrix.compiler }}" >> $GITHUB_ENV + echo "CMAKE_PREFIX_PATH=/opt/dyninst:${CMAKE_PREFIX_PATH}" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=/opt/rocm/lib:/usr/local/lib:${LD_LIBRARY_PATH}" >> $GITHUB_ENV + cat << EOF > test-install.cfg + ROCPROFSYS_PROFILE = ON + ROCPROFSYS_TRACE = ON + ROCPROFSYS_USE_PID = OFF + ROCPROFSYS_USE_SAMPLING = OFF + ROCPROFSYS_USE_PROCESS_SAMPLING = OFF + ROCPROFSYS_COUT_OUTPUT = ON + ROCPROFSYS_TIME_OUTPUT = OFF + ROCPROFSYS_TIMEMORY_COMPONENTS = cpu_clock cpu_util current_peak_rss kernel_mode_time monotonic_clock monotonic_raw_clock network_stats num_io_in num_io_out num_major_page_faults num_minor_page_faults page_rss peak_rss priority_context_switch process_cpu_clock process_cpu_util read_bytes read_char system_clock thread_cpu_clock thread_cpu_util timestamp trip_count user_clock user_mode_time virtual_memory voluntary_context_switch wall_clock written_bytes written_char + ROCPROFSYS_OUTPUT_PATH = rocprofsys-tests-output + ROCPROFSYS_OUTPUT_PREFIX = %tag%/ + ROCPROFSYS_DEBUG = OFF + ROCPROFSYS_VERBOSE = 3 + ROCPROFSYS_DL_VERBOSE = 3 + ROCPROFSYS_PERFETTO_BACKEND = system + EOF + realpath test-install.cfg + cat test-install.cfg + + - name: Configure, Build, and Test + timeout-minutes: 115 + shell: bash + run: + git config --global --add safe.directory ${PWD} && + cmake --version && + TAG="-rocm-${{ matrix.rocm-version }}" && + TAG="$(echo ${TAG} | sed 's/debian/latest/g')" && + python3 ./scripts/run-ci.py -B build + --name ${{ github.repository_owner }}-${{ github.ref_name }}-ubuntu-focal-rocm-${{ matrix.compiler }}${TAG} + --build-jobs 2 + --site GitHub + -- + -DCMAKE_C_COMPILER=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g') + -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} + -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} + -DCMAKE_INSTALL_PREFIX=/opt/rocprofiler-systems + -DROCPROFSYS_BUILD_TESTING=ON + -DROCPROFSYS_BUILD_DEVELOPER=ON + -DROCPROFSYS_BUILD_EXTRA_OPTIMIZATIONS=OFF + -DROCPROFSYS_BUILD_LTO=OFF + -DROCPROFSYS_USE_MPI=OFF + -DROCPROFSYS_USE_ROCM=ON + -DROCPROFSYS_MAX_THREADS=64 + -DROCPROFSYS_USE_PAPI=OFF + -DROCPROFSYS_USE_OMPT=OFF + -DROCPROFSYS_USE_PYTHON=ON + -DROCPROFSYS_USE_MPI_HEADERS=${{ matrix.mpi-headers }} + -DROCPROFSYS_BUILD_DYNINST=ON + -DROCPROFSYS_BUILD_BOOST=ON + -DROCPROFSYS_BUILD_TBB=ON + -DROCPROFSYS_BUILD_ELFUTILS=ON + -DROCPROFSYS_BUILD_LIBIBERTY=ON + -DROCPROFSYS_USE_SANITIZER=OFF + -DROCPROFSYS_PYTHON_PREFIX=/opt/conda/envs + -DROCPROFSYS_PYTHON_ENVS="py3.6;py3.7;py3.8;py3.9;py3.10;py3.11" + -DROCPROFSYS_CI_MPI_RUN_AS_ROOT=${{ matrix.mpi-headers }} + -DROCPROFSYS_CI_GPU=OFF + -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=OFF + -DROCPROFSYS_BUILD_NUMBER=${{ github.run_attempt }} + -- + ${{ matrix.ctest-exclude }} + + - name: Install + run: + cmake --build build --target install --parallel 2 + + - name: Test Install + timeout-minutes: 15 + shell: bash + run: | + source /opt/rocprofiler-systems/share/rocprofiler-systems/setup-env.sh + ./scripts/test-install.sh --test-rocprof-sys-{instrument,avail,sample,python,rewrite,runtime}=1 + + - name: Test User API + timeout-minutes: 10 + run: | + set -v + ./scripts/test-find-package.sh --install-dir /opt/rocprofiler-systems + + - name: CTest Artifacts + if: failure() + continue-on-error: True + uses: actions/upload-artifact@v4 + with: + name: ctest-${{ github.job }}-${{ strategy.job-index }}-log + path: | + build/*.log + + - name: Data Artifacts + if: failure() + continue-on-error: True + uses: actions/upload-artifact@v4 + with: + name: data-${{ github.job }}-${{ strategy.job-index }}-files + path: | + rocprofsys-tests-output/**/*.txt + build/rocprofsys-tests-config/*.cfg + build/rocprofsys-tests-output/**/*.txt + build/rocprofsys-tests-output/**/*-instr*.json + + - name: Kill Perfetto + if: success() || failure() + continue-on-error: True + run: | + set +e + RUNNING_PROCS=$(pgrep trace_processor_shell) + if [ -n "${RUNNING_PROCS}" ]; then kill -s 9 ${RUNNING_PROCS}; fi + + ubuntu-focal-codecov: + runs-on: ubuntu-latest + + container: + image: dgaliffiamd/rocprofiler-systems:ci-base-ubuntu-20.04 + options: --cap-add CAP_SYS_ADMIN + + env: + ROCPROFSYS_VERBOSE: 2 + ROCPROFSYS_CAUSAL_BACKEND: perf + + steps: + - uses: actions/checkout@v4 + + - name: Install Packages + timeout-minutes: 25 + uses: nick-fields/retry@v3 + with: + retry_wait_seconds: 30 + timeout_minutes: 25 + max_attempts: 5 + command: | + apt-get update && + apt-get install -y autoconf bison build-essential clang environment-modules gcc g++ libmpich-dev libomp-dev libtool m4 mpich python3-pip texinfo && + wget https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v47.0/linux-amd64/trace_processor_shell -P /opt/trace_processor/bin && + chmod +x /opt/trace_processor/bin/trace_processor_shell && + python3 -m pip install --upgrade pip && + python3 -m pip install --upgrade numpy perfetto dataclasses && + python3 -m pip install 'cmake==3.21' && + for i in 6 7 8 9 10 11; do /opt/conda/envs/py3.${i}/bin/python -m pip install --upgrade numpy perfetto dataclasses; done && + apt-get -y --purge autoremove && + apt-get -y clean && + /opt/conda/bin/conda clean -y -a + + - name: Configure Env + run: + echo "${HOME}/.local/bin" >> $GITHUB_PATH + + - name: Configure, Build, and Test + timeout-minutes: 115 + shell: bash + run: + git config --global --add safe.directory ${PWD} && + cmake --version && + python3 ./scripts/run-ci.py -B build + --name ${{ github.repository_owner }}-${{ github.ref_name }}-ubuntu-focal-codecov-mpi-python-ompt-papi + --build-jobs 2 + --site GitHub + --coverage + -- + -DCMAKE_INSTALL_PREFIX=/opt/rocprofiler-systems + -DROCPROFSYS_BUILD_CI=OFF + -DROCPROFSYS_BUILD_TESTING=ON + -DROCPROFSYS_BUILD_DYNINST=ON + -DROCPROFSYS_BUILD_BOOST=ON + -DROCPROFSYS_BUILD_TBB=ON + -DROCPROFSYS_BUILD_ELFUTILS=ON + -DROCPROFSYS_BUILD_LIBIBERTY=ON + -DROCPROFSYS_BUILD_DEBUG=OFF + -DROCPROFSYS_BUILD_HIDDEN_VISIBILITY=OFF + -DROCPROFSYS_USE_MPI=ON + -DROCPROFSYS_USE_PYTHON=ON + -DROCPROFSYS_USE_OMPT=ON + -DROCPROFSYS_USE_PAPI=ON + -DROCPROFSYS_USE_ROCM=OFF + -DROCPROFSYS_USE_RCCL=OFF + -DROCPROFSYS_MAX_THREADS=64 + -DROCPROFSYS_DISABLE_EXAMPLES="transpose;rccl;videodecode;jpegdecode;openmp-target" + -DROCPROFSYS_BUILD_NUMBER=${{ github.run_attempt }} + -- + -LE "transpose|rccl|videodecode|jpegdecode|network" diff --git a/projects/rocprofiler-systems/.github/workflows/ubuntu-jammy.yml b/projects/rocprofiler-systems/.github/workflows/ubuntu-jammy.yml new file mode 100644 index 0000000000..02a21ec52d --- /dev/null +++ b/projects/rocprofiler-systems/.github/workflows/ubuntu-jammy.yml @@ -0,0 +1,381 @@ +name: Ubuntu 22.04 (GCC, Python, ROCm) +run-name: ubuntu-jammy + +on: + push: + branches: [ amd-mainline, amd-staging, release/** ] + paths-ignore: + - '*.md' + - 'docs/**' + - 'source/docs/**' + - 'source/python/gui/**' + - '.github/workflows/docs.yml' + - '.github/workflows/cpack.yml' + - '.github/workflows/containers.yml' + - '.github/workflows/formatting.yml' + - '.github/workflows/weekly-mainline-sync.yml' + - 'docker/**' + - .wordlist.txt + - CMakePresets.json + pull_request: + branches: [ amd-mainline, amd-staging, release/** ] + paths-ignore: + - '*.md' + - 'docs/**' + - 'source/docs/**' + - 'source/python/gui/**' + - '.github/workflows/docs.yml' + - '.github/workflows/cpack.yml' + - '.github/workflows/containers.yml' + - '.github/workflows/formatting.yml' + - '.github/workflows/weekly-mainline-sync.yml' + - 'docker/**' + - .wordlist.txt + - CMakePresets.json + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + ROCPROFSYS_CI: ON + ROCPROFSYS_TMPDIR: "%env{PWD}%/testing-tmp" + +jobs: + ubuntu-jammy-external: + runs-on: ubuntu-latest + container: + image: dgaliffiamd/rocprofiler-systems:ci-base-ubuntu-22.04 + strategy: + fail-fast: false + matrix: + compiler: ['g++-11', 'g++-12'] + rocm: ['OFF'] + mpi: ['OFF'] + ompt: ['OFF'] + papi: ['OFF'] + python: ['ON'] + strip: ['OFF'] + hidden: ['ON', 'OFF'] + build-type: ['Release'] + mpi-headers: ['ON', 'OFF'] + build-dyninst: ['ON'] + rocm-version: ['0.0'] + + env: + OMPI_ALLOW_RUN_AS_ROOT: 1 + OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1 + ROCPROFSYS_CI: 'ON' + + steps: + - uses: actions/checkout@v4 + + - name: Install Packages + timeout-minutes: 25 + uses: nick-fields/retry@v3 + with: + retry_wait_seconds: 30 + timeout_minutes: 25 + max_attempts: 5 + command: | + apt-get update && + apt-get install -y software-properties-common && + apt-get upgrade -y && + apt-get install -y autoconf bison build-essential clang environment-modules \ + gettext libfabric-dev libiberty-dev libomp-dev libopenmpi-dev libtool m4 \ + openmpi-bin python3-pip texinfo ${{ matrix.compiler }} && + python3 -m pip install --upgrade pip && + python3 -m pip install --upgrade numpy perfetto dataclasses && + python3 -m pip install 'cmake==3.21' && + for i in 6 7 8 9 10 11; do /opt/conda/envs/py3.${i}/bin/python -m pip install --upgrade numpy perfetto dataclasses; done + + - name: Test Environment Modules + timeout-minutes: 15 + shell: bash + run: | + set -v + source /usr/share/modules/init/$(basename ${SHELL}) + module avail + + - name: Configure Env + run: | + echo "CC=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g')" >> $GITHUB_ENV + echo "CXX=${{ matrix.compiler }}" >> $GITHUB_ENV + + - name: Configure, Build, and Test + timeout-minutes: 115 + shell: bash + run: + git config --global --add safe.directory ${PWD} && + cmake --version && + TAG="" && + append-tagname() { if [ "${1}" == "ON" ]; then TAG="${TAG}-${2}"; fi; } && + append-tagname ${{ matrix.mpi }} mpi && + append-tagname ${{ matrix.ompt }} ompt && + append-tagname ${{ matrix.papi }} papi && + append-tagname ${{ matrix.python }} python && + append-tagname ${{ matrix.mpi-headers }} mpip && + append-tagname ${{ matrix.build-dyninst }} internal-dyninst && + append-tagname ${{ matrix.strip }} strip && + append-tagname ${{ matrix.hidden }} hidden-viz && + python3 ./scripts/run-ci.py -B build + --name ${{ github.repository_owner }}-${{ github.ref_name }}-ubuntu-jammy-${{ matrix.compiler }}${TAG} + --build-jobs 2 + --site GitHub + -- + -DCMAKE_C_COMPILER=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g') + -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} + -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} + -DCMAKE_INSTALL_PREFIX=/opt/rocprofiler-systems-dev + -DROCPROFSYS_BUILD_TESTING=ON + -DROCPROFSYS_USE_MPI=${{ matrix.mpi }} + -DROCPROFSYS_USE_ROCM=${{ matrix.rocm }} + -DROCPROFSYS_USE_OMPT=${{ matrix.ompt }} + -DROCPROFSYS_USE_PAPI=${{ matrix.papi }} + -DROCPROFSYS_USE_PYTHON=${{ matrix.python }} + -DROCPROFSYS_USE_MPI_HEADERS=${{ matrix.mpi-headers }} + -DROCPROFSYS_BUILD_DYNINST=${{ matrix.build-dyninst }} + -DROCPROFSYS_BUILD_BOOST=${{ matrix.build-dyninst }} + -DROCPROFSYS_BUILD_TBB=${{ matrix.build-dyninst }} + -DROCPROFSYS_BUILD_ELFUTILS=${{ matrix.build-dyninst }} + -DROCPROFSYS_BUILD_LIBIBERTY=${{ matrix.build-dyninst }} + -DROCPROFSYS_BUILD_HIDDEN_VISIBILITY=${{ matrix.hidden }} + -DROCPROFSYS_PYTHON_PREFIX=/opt/conda/envs + -DROCPROFSYS_PYTHON_ENVS="py3.7;py3.8;py3.9;py3.10;py3.11" + -DROCPROFSYS_STRIP_LIBRARIES=${{ matrix.strip }} + -DROCPROFSYS_MAX_THREADS=64 + -DROCPROFSYS_DISABLE_EXAMPLES="transpose;rccl;openmp-target" + -DROCPROFSYS_BUILD_NUMBER=${{ github.run_attempt }} + -DUSE_CLANG_OMP=OFF + -- + -LE "transpose|rccl|videodecode|jpegdecode|network" + + - 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 /opt/rocprofiler-systems + ./rocprofiler-systems-*.sh --prefix=/opt/rocprofiler-systems --exclude-subdir --skip-license + + - name: Test Install with Modulefile + timeout-minutes: 15 + shell: bash + run: | + set -v + source /usr/share/modules/init/$(basename ${SHELL}) + module use /opt/rocprofiler-systems/share/modulefiles + module avail + module load rocprofiler-systems + ./scripts/test-install.sh --test-rocprof-sys-{instrument,avail,sample,python,rewrite,runtime}=1 + + - name: Test User API + timeout-minutes: 10 + run: | + set -v + ./scripts/test-find-package.sh --install-dir /opt/rocprofiler-systems + + - name: CTest Artifacts + if: failure() + continue-on-error: True + uses: actions/upload-artifact@v4 + with: + name: ctest-${{ github.job }}-${{ strategy.job-index }}-log + path: | + build/*.log + + - name: Data Artifacts + if: failure() + continue-on-error: True + uses: actions/upload-artifact@v4 + with: + name: data-${{ github.job }}-${{ strategy.job-index }}-files + path: | + build/rocprofsys-tests-config/*.cfg + build/rocprofsys-tests-output/**/*.txt + build/rocprofsys-tests-output/**/*-instr*.json + + ubuntu-jammy-external-rocm: + runs-on: ubuntu-latest + container: + image: dgaliffiamd/rocprofiler-systems:ci-base-ubuntu-22.04 + strategy: + fail-fast: false + matrix: + compiler: ['g++'] + rocm: ['ON'] + mpi: ['OFF'] + ompt: ['OFF'] + papi: ['OFF'] + python: ['ON'] + strip: ['OFF'] + hidden: ['ON'] + build-type: ['Release'] + mpi-headers: ['OFF'] + build-dyninst: ['ON'] + rocm-version: ['6.3', '6.4'] + + env: + OMPI_ALLOW_RUN_AS_ROOT: 1 + OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1 + ROCPROFSYS_CI: 'ON' + + steps: + - uses: actions/checkout@v4 + + - name: Install Packages + timeout-minutes: 25 + uses: nick-fields/retry@v3 + with: + retry_wait_seconds: 30 + timeout_minutes: 25 + max_attempts: 5 + command: | + apt-get update && + apt-get install -y software-properties-common && + apt-get upgrade -y && + apt-get install -y autoconf bison build-essential clang environment-modules \ + gettext libfabric-dev libiberty-dev libomp-dev libopenmpi-dev libtool m4 \ + openmpi-bin python3-pip texinfo ${{ matrix.compiler }} && + python3 -m pip install --upgrade pip && + python3 -m pip install --upgrade numpy perfetto dataclasses && + python3 -m pip install 'cmake==3.21' && + for i in 6 7 8 9 10 11; do /opt/conda/envs/py3.${i}/bin/python -m pip install --upgrade numpy perfetto dataclasses; done + + - name: Install ROCm Packages + timeout-minutes: 25 + uses: nick-fields/retry@v3 + with: + retry_wait_seconds: 30 + timeout_minutes: 25 + max_attempts: 5 + shell: bash + command: | + ROCM_VERSION=${{ matrix.rocm-version }} + ROCM_MAJOR=$(echo ${ROCM_VERSION} | sed 's/\./ /g' | awk '{print $1}') + ROCM_MINOR=$(echo ${ROCM_VERSION} | sed 's/\./ /g' | awk '{print $2}') + ROCM_VERSN=$(( (${ROCM_MAJOR}*10000)+(${ROCM_MINOR}*100) )) + echo "ROCM_MAJOR=${ROCM_MAJOR} ROCM_MINOR=${ROCM_MINOR} ROCM_VERSN=${ROCM_VERSN}" + wget -q https://repo.radeon.com/amdgpu-install/${{ matrix.rocm-version }}/ubuntu/jammy/amdgpu-install_${ROCM_MAJOR}.${ROCM_MINOR}.${ROCM_VERSN}-1_all.deb + apt-get install -y ./amdgpu-install_${ROCM_MAJOR}.${ROCM_MINOR}.${ROCM_VERSN}-1_all.deb + apt-get update + apt-get install -y rocm-dev rocdecode-dev libavformat-dev libavcodec-dev + echo "/opt/rocm/bin" >> $GITHUB_PATH + echo "ROCM_PATH=/opt/rocm" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=/opt/rocm/lib:${LD_LIBRARY_PATH}" >> $GITHUB_ENV + /opt/rocm/bin/hipcc -O3 -c ./examples/transpose/transpose.cpp -o /tmp/transpose.o + + - name: Test Environment Modules + timeout-minutes: 15 + shell: bash + run: | + set -v + source /usr/share/modules/init/$(basename ${SHELL}) + module avail + + - name: Configure Env + run: | + echo "CC=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g')" >> $GITHUB_ENV + echo "CXX=${{ matrix.compiler }}" >> $GITHUB_ENV + + - name: Configure, Build, and Test + timeout-minutes: 115 + shell: bash + run: + git config --global --add safe.directory ${PWD} && + cmake --version && + TAG="" && + append-tagname() { if [ "${1}" == "ON" ]; then TAG="${TAG}-${2}"; fi; } && + append-tagname ${{ matrix.rocm }} rocm-${{ matrix.rocm-version }} && + append-tagname ${{ matrix.mpi }} mpi && + append-tagname ${{ matrix.ompt }} ompt && + append-tagname ${{ matrix.papi }} papi && + append-tagname ${{ matrix.python }} python && + append-tagname ${{ matrix.mpi-headers }} mpip && + append-tagname ${{ matrix.build-dyninst }} internal-dyninst && + append-tagname ${{ matrix.strip }} strip && + append-tagname ${{ matrix.hidden }} hidden-viz && + python3 ./scripts/run-ci.py -B build + --name ${{ github.repository_owner }}-${{ github.ref_name }}-ubuntu-jammy-${{ matrix.compiler }}${TAG} + --build-jobs 2 + --site GitHub + -- + -DCMAKE_C_COMPILER=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g') + -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} + -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} + -DCMAKE_INSTALL_PREFIX=/opt/rocprofiler-systems-dev + -DROCPROFSYS_BUILD_TESTING=ON + -DROCPROFSYS_USE_MPI=${{ matrix.mpi }} + -DROCPROFSYS_USE_ROCM=${{ matrix.rocm }} + -DROCPROFSYS_USE_OMPT=${{ matrix.ompt }} + -DROCPROFSYS_USE_PAPI=${{ matrix.papi }} + -DROCPROFSYS_USE_PYTHON=${{ matrix.python }} + -DROCPROFSYS_USE_MPI_HEADERS=${{ matrix.mpi-headers }} + -DROCPROFSYS_BUILD_DYNINST=${{ matrix.build-dyninst }} + -DROCPROFSYS_BUILD_BOOST=${{ matrix.build-dyninst }} + -DROCPROFSYS_BUILD_TBB=${{ matrix.build-dyninst }} + -DROCPROFSYS_BUILD_ELFUTILS=${{ matrix.build-dyninst }} + -DROCPROFSYS_BUILD_LIBIBERTY=${{ matrix.build-dyninst }} + -DROCPROFSYS_BUILD_HIDDEN_VISIBILITY=${{ matrix.hidden }} + -DROCPROFSYS_PYTHON_PREFIX=/opt/conda/envs + -DROCPROFSYS_PYTHON_ENVS="py3.7;py3.8;py3.9;py3.10;py3.11" + -DROCPROFSYS_STRIP_LIBRARIES=${{ matrix.strip }} + -DROCPROFSYS_MAX_THREADS=64 + -DROCPROFSYS_DISABLE_EXAMPLES="transpose;rccl;openmp-target" + -DROCPROFSYS_BUILD_NUMBER=${{ github.run_attempt }} + -DUSE_CLANG_OMP=OFF + -- + -LE "transpose|rccl|videodecode|jpegdecode|network" + + - 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 /opt/rocprofiler-systems + ./rocprofiler-systems-*.sh --prefix=/opt/rocprofiler-systems --exclude-subdir --skip-license + + - name: Test Install with Modulefile + timeout-minutes: 15 + shell: bash + run: | + set -v + source /usr/share/modules/init/$(basename ${SHELL}) + module use /opt/rocprofiler-systems/share/modulefiles + module avail + module load rocprofiler-systems + ./scripts/test-install.sh --test-rocprof-sys-{instrument,avail,sample,python,rewrite,runtime}=1 + + - name: Test User API + timeout-minutes: 10 + run: | + set -v + ./scripts/test-find-package.sh --install-dir /opt/rocprofiler-systems + + - name: CTest Artifacts + if: failure() + continue-on-error: True + uses: actions/upload-artifact@v4 + with: + name: ctest-${{ github.job }}-${{ strategy.job-index }}-log + path: | + build/*.log + + - name: Data Artifacts + if: failure() + continue-on-error: True + uses: actions/upload-artifact@v4 + with: + name: data-${{ github.job }}-${{ strategy.job-index }}-files + path: | + build/rocprofsys-tests-config/*.cfg + build/rocprofsys-tests-output/**/*.txt + build/rocprofsys-tests-output/**/*-instr*.json \ No newline at end of file diff --git a/projects/rocprofiler-systems/.github/workflows/ubuntu-noble.yml b/projects/rocprofiler-systems/.github/workflows/ubuntu-noble.yml new file mode 100644 index 0000000000..3544b32b9d --- /dev/null +++ b/projects/rocprofiler-systems/.github/workflows/ubuntu-noble.yml @@ -0,0 +1,121 @@ +name: Ubuntu 24.04 (GCC, Python, ROCm) +run-name: ubuntu-noble + +on: + push: + branches: [ amd-mainline, amd-staging, release/** ] + paths-ignore: + - '*.md' + - 'docs/**' + - 'source/docs/**' + - 'source/python/gui/**' + - '.github/workflows/docs.yml' + - '.github/workflows/cpack.yml' + - '.github/workflows/containers.yml' + - '.github/workflows/formatting.yml' + - '.github/workflows/weekly-mainline-sync.yml' + - 'docker/**' + - .wordlist.txt + - CMakePresets.json + pull_request: + branches: [ amd-mainline, amd-staging, release/** ] + paths-ignore: + - '*.md' + - 'docs/**' + - 'source/docs/**' + - 'source/python/gui/**' + - '.github/workflows/docs.yml' + - '.github/workflows/cpack.yml' + - '.github/workflows/containers.yml' + - '.github/workflows/formatting.yml' + - '.github/workflows/weekly-mainline-sync.yml' + - 'docker/**' + - .wordlist.txt + - CMakePresets.json + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + ROCPROFSYS_CI: ON + ROCPROFSYS_TMPDIR: "%env{PWD}%/testing-tmp" + +jobs: + ubuntu-noble: + runs-on: ubuntu-latest + container: + image: dgaliffiamd/rocprofiler-systems:ci-base-ubuntu-24.04 + strategy: + fail-fast: false + matrix: + compiler: ['g++'] + build-type: ['Release', 'Debug'] + strip: ['OFF'] + build-dyninst: ['OFF'] + rocm-version: ['0.0','6.3','6.4'] + + env: + ROCPROFSYS_CI: 'ON' + + steps: + - uses: actions/checkout@v4 + + - name: Install Packages + timeout-minutes: 25 + uses: nick-fields/retry@v3 + with: + retry_wait_seconds: 30 + timeout_minutes: 25 + max_attempts: 5 + command: | + apt-get -y update && apt-get upgrade -y && + apt-get install -y \ + libiberty-dev clang libomp-dev libopenmpi-dev libfabric-dev \ + openmpi-bin ${{ matrix.compiler }} && + for i in 8 9 10 11 12; do /opt/conda/envs/py3.${i}/bin/python -m pip install numpy perfetto dataclasses; done + + - name: Install ROCm Packages + if: ${{ matrix.rocm-version > 0 }} + timeout-minutes: 30 + shell: bash + run: | + ROCM_VERSION=${{ matrix.rocm-version }} + ROCM_MAJOR=$(echo ${ROCM_VERSION} | sed 's/\./ /g' | awk '{print $1}') + ROCM_MINOR=$(echo ${ROCM_VERSION} | sed 's/\./ /g' | awk '{print $2}') + ROCM_VERSN=$(( (${ROCM_MAJOR}*10000)+(${ROCM_MINOR}*100) )) + echo "ROCM_MAJOR=${ROCM_MAJOR} ROCM_MINOR=${ROCM_MINOR} ROCM_VERSN=${ROCM_VERSN}" + wget -q https://repo.radeon.com/amdgpu-install/${{ matrix.rocm-version }}/ubuntu/noble/amdgpu-install_${ROCM_MAJOR}.${ROCM_MINOR}.${ROCM_VERSN}-1_all.deb + apt-get install -y ./amdgpu-install_${ROCM_MAJOR}.${ROCM_MINOR}.${ROCM_VERSN}-1_all.deb + apt-get update + apt-get install -y rocm-dev rocdecode-dev libavformat-dev libavcodec-dev + + - name: Configure + timeout-minutes: 30 + shell: bash + run: | + git config --global --add safe.directory ${PWD} && + cmake --version + USE_ROCM=OFF + if [ ${{ matrix.rocm-version }} != "0.0" ]; then USE_ROCM=ON; fi + cmake -B build \ + -DCMAKE_C_COMPILER=$(echo '${{ matrix.compiler }}' | sed 's/+/c/g') \ + -DCMAKE_CXX_COMPILER=${{ matrix.compiler }} \ + -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \ + -DCMAKE_INSTALL_PREFIX=/opt/rocprofiler-systems \ + -DROCPROFSYS_BUILD_TESTING=ON \ + -DROCPROFSYS_DISABLE_EXAMPLES="transpose;rccl;openmp-target" \ + -DROCPROFSYS_USE_ROCM=${USE_ROCM} \ + -DRCOPROFSYS_USE_PYTHON=ON \ + -DROCPROFSYS_BUILD_DYNINST=ON \ + -DROCPROFSYS_BUILD_BOOST=ON \ + -DROCPROFSYS_BUILD_TBB=ON \ + -DROCPROFSYS_BUILD_ELFUTILS=ON \ + -DROCPROFSYS_BUILD_LIBIBERTY=ON \ + -DROCPROFSYS_STRIP_LIBRARIES=${{ matrix.strip }} \ + -DROCPROFSYS_PYTHON_PREFIX=/opt/conda/envs \ + -DROCPROFSYS_PYTHON_ENVS="py3.8;py3.9;py3.10;py3.11;py3.12" + + - name: Build + timeout-minutes: 115 + run: cmake --build build --parallel 2 diff --git a/projects/rocprofiler-systems/.github/workflows/weekly-mainline-sync.yml b/projects/rocprofiler-systems/.github/workflows/weekly-mainline-sync.yml new file mode 100644 index 0000000000..1eaf4d0c50 --- /dev/null +++ b/projects/rocprofiler-systems/.github/workflows/weekly-mainline-sync.yml @@ -0,0 +1,25 @@ +name: Sync Mainline with Staging +on: + workflow_dispatch: + +jobs: + promote-stg-to-main: + if: github.repository == 'ROCm/rocprofiler-systems' + runs-on: ubuntu-latest + name: Promote Staging to Mainline + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: amd-mainline + fetch-depth: '0' + + - name: Merge - Fast Forward Only + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + git checkout amd-mainline + git checkout -b promote-staging-$(date +%F) + git merge --ff-only origin/amd-staging + git push -u origin HEAD + gh pr create --base amd-mainline --title "Promote \`amd-staging\` to \`amd-mainline\`" --fill --label "automerge" diff --git a/projects/rocprofiler-systems/.gitignore b/projects/rocprofiler-systems/.gitignore new file mode 100644 index 0000000000..ca63de3fcf --- /dev/null +++ b/projects/rocprofiler-systems/.gitignore @@ -0,0 +1,50 @@ +# Edit files +*~ + +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# Python cache files +*.pyc + +# Documentation artifacts +/_build +_toc.yml + +/build* +/.vscode +/.cache +/.clangd +/compile_commands.json +/rocprof-sys-install.py +/scripts/rocprof-sys-install.py diff --git a/projects/rocprofiler-systems/.gitmodules b/projects/rocprofiler-systems/.gitmodules new file mode 100644 index 0000000000..89b551a769 --- /dev/null +++ b/projects/rocprofiler-systems/.gitmodules @@ -0,0 +1,26 @@ +[submodule "external/timemory"] + path = external/timemory + url = https://github.com/ROCm/timemory.git + branch = rocprofiler-systems +[submodule "external/perfetto"] + path = external/perfetto + url = https://github.com/google/perfetto.git +[submodule "external/elfio"] + path = external/elfio + url = https://github.com/jrmadsen/ELFIO.git +[submodule "external/dyninst"] + path = external/dyninst + url = https://github.com/ROCm/dyninst.git + branch = dyninst_13 +[submodule "external/PTL"] + path = external/PTL + url = https://github.com/jrmadsen/PTL.git +[submodule "external/kokkos"] + path = examples/lulesh/external/kokkos + url = https://github.com/kokkos/kokkos.git +[submodule "external/papi"] + path = external/papi + url = https://github.com/icl-utk-edu/papi.git +[submodule "external/pybind11"] + path = external/pybind11 + url = https://github.com/jrmadsen/pybind11.git diff --git a/projects/rocprofiler-systems/.pre-commit-config.yaml b/projects/rocprofiler-systems/.pre-commit-config.yaml new file mode 100644 index 0000000000..9e0c2e1586 --- /dev/null +++ b/projects/rocprofiler-systems/.pre-commit-config.yaml @@ -0,0 +1,68 @@ +# MIT License +# +# Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# Pre-configuration file for pre-commit hooks +# This is optional. To run pre-commit, see CONTRIBUTING.md + +exclude: \.(svg)$|(^|/)\.gitignore$ # Exclude files with these extensions +default_stages: [pre-commit] +repos: + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: check-yaml # Check YAML files for syntax errors + - id: trailing-whitespace # Remove trailing whitespace + - id: end-of-file-fixer # Fix files to have a newline at the end + + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v18.1.8 # Version 18 as specified in contributor guide + hooks: + - id: clang-format + files: \.(c|cpp|h.*)$ + + - repo: https://github.com/BlankSpruce/gersemi + rev: 0.19.3 + hooks: + - id: gersemi + + - repo: local + hooks: + - id: check-copyright + name: copyright-detector + require_serial: true # Slightly slower, but prevents hook running script many times + entry: ./scripts/check-copyright.sh + language: script + files: \.(c|h|txt|cpp|hpp|py)$ + exclude: ^\.|^docs/|^examples/lulesh/|^examples/mpi/|^examples/openmp/|^external/|^cmake/ + + # - repo: local + # hooks: + # - id: check-copyright-date + # name: Check Copyright Date + # # Check copyright date in all files + # # Fails if something is out of date. + # # -u automatically updates copyright year + # entry: ./scripts/check-copyright.sh -u + # language: script + # files: \.(c|h|txt|cpp|hpp|py)$ + # exclude: ^\.|^docs/|^examples/lulesh/|^examples/mpi/|^examples/openmp/|^external/|^cmake/ diff --git a/projects/rocprofiler-systems/.readthedocs.yaml b/projects/rocprofiler-systems/.readthedocs.yaml new file mode 100644 index 0000000000..3c310707b7 --- /dev/null +++ b/projects/rocprofiler-systems/.readthedocs.yaml @@ -0,0 +1,18 @@ +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.10" + +python: + install: + - requirements: docs/sphinx/requirements.txt + +sphinx: + configuration: docs/conf.py + +formats: [] diff --git a/projects/rocprofiler-systems/.wordlist.txt b/projects/rocprofiler-systems/.wordlist.txt new file mode 100644 index 0000000000..19f383ce6e --- /dev/null +++ b/projects/rocprofiler-systems/.wordlist.txt @@ -0,0 +1,53 @@ +aarch +amd +bundler +Coz +CrayPAT +dl +durations +Dyninst +enp +Kokkos +KokkosP +librocprof +LibIberty +libunwind +Linkable +LIKWID +lvalue +metaprogramming +MPICH +mpirun +NVTX +OpenMPI +OpenSUSE +PAPI +perf +pid +polymorphism +POSIX +ppc +proc +proto +Pthreads +rocDecode +rocdecode +ROCprofiler +ROCPROFSYS +rocJPEG +rocjpeg +ROCTX +roctx +rpath +RPATH +RSS +rvalues +sdk +SELinux +STGZ +sudo +sys +TBB +Timemory +VCN +VTune diff --git a/projects/rocprofiler-systems/CHANGELOG.md b/projects/rocprofiler-systems/CHANGELOG.md new file mode 100644 index 0000000000..d849c5628e --- /dev/null +++ b/projects/rocprofiler-systems/CHANGELOG.md @@ -0,0 +1,110 @@ +# Changelog for ROCm Systems Profiler + +Full documentation for ROCm Systems Profiler is available at [https://rocm.docs.amd.com/projects/rocprofiler-systems/en/latest/](https://rocm.docs.amd.com/projects/rocprofiler-systems/en/latest/). + +## ROCm Systems Profiler 1.1.0 for ROCm 7.0 + +### Added + +- Profiling and metric collection capabilities for VCN engine activity, JPEG engine activity, and API tracing for rocDecode, rocJPEG, and VA-APIs. +- How-to document for VCN and JPEG activity sampling and tracing. +- Support for tracing Fortran applications. +- Support for tracing MPI API in Fortran. + +### Changed + +- Replaced ROCm SMI backend with AMD SMI backend for collecting GPU metrics. +- ROCprofiler-SDK is now used to trace RCCL API and collect communication counters. +- Updated the Dyninst submodule to v13.0. +- Set the default value of `ROCPROFSYS_SAMPLING_CPUS` to `none`. + +### Resolved issues + +- Fixed GPU metric collection settings with `ROCPROFSYS_AMD_SMI_METRICS`. +- Fixed a build issue with CMake 4. +- Fixed incorrect kernel names shown for kernel dispatch tracks in Perfetto. +- Fixed formatting of some output logs. +- Fixed an issue where ROC-TX ranges were displayed as two separate events instead of a single spanning event. + +## ROCm Systems Profiler 1.0.2 for ROCm 6.4.2 + +### Optimized + +- Improved readability of the OpenMP target offload traces by showing on a single Perfetto track. + +### Resolved issues + +- Fixed the file path to the script that merges Perfetto files from multi-process MPI runs. The script has also been renamed from `merge-multiprocess-output.sh` to `rocprof-sys-merge-output.sh`. + +## ROCm Systems Profiler 1.0.1 for ROCm 6.4.1 + +### Added + +- How-to document for [network performance profiling](https://rocm.docs.amd.com/projects/rocprofiler-systems/en/amd-staging/how-to/nic-profiling.html) for standard Network Interface Cards (NICs). + +### Resolved issues + +- Fixed a build issue with Dyninst on GCC 13. + +## ROCm Systems Profiler 1.0.0 for ROCm 6.4.0 + +### Added + +- Support for VA-API and rocDecode tracing. + +- Aggregation of MPI data collected across distributed nodes and ranks. The data is concatenated into a single proto file. + +### Changed + +- Backend refactored to use ROCprofiler-SDK rather than ROCProfiler and ROCTracer. + +### Resolved issues + +- Fixed hardware counter summary files not being generated after profiling. + +- Fixed an application crash when collecting performance counters with ROCProfiler. + +- Fixed interruption in config file generation. + +- Fixed segmentation fault while running `rocprof-sys-instrument`. + +- Fixed an issue where running `rocprof-sys-causal` or using the `-I all` option with `rocprof-sys-sample` caused the system to become non-responsive. + +- Fixed an issue where sampling multi-GPU Python workloads caused the system to stop responding. + +## ROCm Systems Profiler 0.1.1 for ROCm 6.3.2 + +### Resolved issues + +- Fixed an error when building from source on some SUSE and RHEL systems when using the `ROCPROFSYS_BUILD_DYNINST` option. + +## ROCm Systems Profiler 0.1.0 for ROCm 6.3.1 + +### Added + +- Improvements to support OMPT target offload. + +### Resolved issues + +- Fixed an issue with generated Perfetto files. + +- Fixed an issue with merging multiple `.proto` files. + +- Fixed an issue causing GPU resource data to be missing from traces of Instinct MI300A systems. + +- Fixed a minor issue for users upgrading to ROCm 6.3 from 6.2 post-rename from `omnitrace`. + +## ROCm Systems Profiler 0.1.0 for ROCm 6.3.0 + +### Changed + +- Renamed Omnitrace to ROCm Systems Profiler. + +## Omnitrace 1.11.2 for ROCm 6.2.1 + +### Known issues + +- Perfetto can no longer open Omnitrace proto files. Loading the Perfetto trace output `.proto` file in `ui.perfetto.dev` can + result in a dialog with the message, "Oops, something went wrong! Please file a bug." The information in the dialog will + refer to an "Unknown field type." The workaround is to open the files with the previous version of the Perfetto UI found + at https://ui.perfetto.dev/v46.0-35b3d9845/#!/. diff --git a/projects/rocprofiler-systems/CMakeLists.txt b/projects/rocprofiler-systems/CMakeLists.txt new file mode 100644 index 0000000000..04bb87d551 --- /dev/null +++ b/projects/rocprofiler-systems/CMakeLists.txt @@ -0,0 +1,488 @@ +cmake_minimum_required(VERSION 3.18.4 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 unintented, please remove 'CMakeCache.txt' and 'CMakeFiles'") + message(STATUS "and build from a separate directory") + message(AUTHOR_WARNING "In-source build") +endif() + +# find_package() uses upper-case _ROOT variables. +if(POLICY CMP0144) + cmake_policy(SET CMP0144 NEW) +endif() + +if(NOT UNIX OR APPLE) + message( + AUTHOR_WARNING + "rocprofiler-systems only supports Linux. Configure and/or build is likely to fail" + ) +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" + ROCPROFSYS_VERSION + "${FULL_VERSION_STRING}" +) + +project( + rocprofiler-systems + LANGUAGES C CXX + VERSION ${ROCPROFSYS_VERSION} + DESCRIPTION "CPU/GPU Application tracing with static/dynamic binary instrumentation" + HOMEPAGE_URL "https://github.com/ROCm/rocprofiler-systems" +) +set(PROJECT_NAME_UNDERSCORED "rocprofiler_systems") + +set(BINARY_NAME_PREFIX "rocprof-sys") + +find_package(Git) + +if(Git_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") + execute_process( + COMMAND ${GIT_EXECUTABLE} describe --tags + OUTPUT_VARIABLE ROCPROFSYS_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 ROCPROFSYS_GIT_DESCRIBE + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE _GIT_DESCRIBE_RESULT + ERROR_QUIET + ) + endif() + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + OUTPUT_VARIABLE ROCPROFSYS_GIT_REVISION + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) +else() + set(ROCPROFSYS_GIT_DESCRIBE "v${ROCPROFSYS_VERSION}") + set(ROCPROFSYS_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: ${ROCPROFSYS_GIT_REVISION}") +message(STATUS "[${PROJECT_NAME}] git describe: ${ROCPROFSYS_GIT_DESCRIBE}") +set(CMAKE_MODULE_PATH + ${PROJECT_SOURCE_DIR}/cmake + ${PROJECT_SOURCE_DIR}/cmake/Modules + ${PROJECT_SOURCE_DIR}/source/python/cmake + ${CMAKE_MODULE_PATH} +) +set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries") +set(BUILD_STATIC_LIBS OFF CACHE BOOL "Build static libraries") +set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "Build position independent code") + +if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24) + cmake_policy(SET CMP0135 NEW) +endif() + +if("${CMAKE_BUILD_TYPE}" STREQUAL "") + set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) +else() + set(VALID_BUILD_TYPES "Release" "RelWithDebInfo" "Debug" "MinSizeRel") + if(NOT "${CMAKE_BUILD_TYPE}" IN_LIST VALID_BUILD_TYPES) + string(REPLACE ";" ", " _VALID_BUILD_TYPES "${VALID_BUILD_TYPES}") + message( + FATAL_ERROR + "Invalid CMAKE_BUILD_TYPE :: ${CMAKE_BUILD_TYPE}. Valid build types are: ${_VALID_BUILD_TYPES}" + ) + endif() +endif() +set(_STRIP_LIBRARIES_DEFAULT OFF) +if("${CMAKE_BUILD_TYPE}" STREQUAL "Release") + set(_STRIP_LIBRARIES_DEFAULT ON) +endif() + +if(DEFINED CMAKE_INSTALL_LIBDIR AND NOT DEFINED CMAKE_DEFAULT_INSTALL_LIBDIR) + # always have a fresh install + unset(CMAKE_INSTALL_LIBDIR CACHE) + include(GNUInstallDirs) # install directories + # force this because dyninst always installs to lib + set(CMAKE_DEFAULT_INSTALL_LIBDIR + "${CMAKE_INSTALL_LIBDIR}" + CACHE STRING + "Object code libraries" + FORCE + ) +endif() + +if(NOT "$ENV{ROCPROFSYS_CI}" STREQUAL "") + set(CI_BUILD $ENV{ROCPROFSYS_CI}) +else() + set(CI_BUILD OFF) +endif() + +include(GNUInstallDirs) # install directories +include(MacroUtilities) # various functions and macros + +if(CI_BUILD) + rocprofiler_systems_add_option(ROCPROFSYS_BUILD_CI "Enable internal asserts, etc." ON + ADVANCED NO_FEATURE + ) + rocprofiler_systems_add_option(ROCPROFSYS_BUILD_TESTING + "Enable building the testing suite" ON ADVANCED + ) + rocprofiler_systems_add_option( + ROCPROFSYS_BUILD_DEBUG "Enable building with extensive debug symbols" OFF + ADVANCED + ) + rocprofiler_systems_add_option( + ROCPROFSYS_BUILD_HIDDEN_VISIBILITY + "Build with hidden visibility (disable for Debug builds)" OFF ADVANCED + ) + rocprofiler_systems_add_option(ROCPROFSYS_STRIP_LIBRARIES "Strip the libraries" OFF + ADVANCED + ) +else() + rocprofiler_systems_add_option(ROCPROFSYS_BUILD_CI "Enable internal asserts, etc." + OFF ADVANCED NO_FEATURE + ) + rocprofiler_systems_add_option(ROCPROFSYS_BUILD_EXAMPLES + "Enable building the examples" OFF ADVANCED + ) + rocprofiler_systems_add_option(ROCPROFSYS_BUILD_TESTING + "Enable building the testing suite" OFF ADVANCED + ) + rocprofiler_systems_add_option( + ROCPROFSYS_BUILD_DEBUG "Enable building with extensive debug symbols" OFF + ADVANCED + ) + rocprofiler_systems_add_option( + ROCPROFSYS_BUILD_HIDDEN_VISIBILITY + "Build with hidden visibility (disable for Debug builds)" ON ADVANCED + ) + rocprofiler_systems_add_option(ROCPROFSYS_STRIP_LIBRARIES "Strip the libraries" + ${_STRIP_LIBRARIES_DEFAULT} ADVANCED + ) +endif() + +include(Compilers) # compiler identification +include(BuildSettings) # compiler flags + +set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Object code libraries (lib)" FORCE) +set(CMAKE_CXX_STANDARD 17 CACHE STRING "CXX language standard") + +rocprofiler_systems_add_feature(CMAKE_BUILD_TYPE "Build optimization level") +rocprofiler_systems_add_feature(CMAKE_INSTALL_PREFIX "Installation prefix") +rocprofiler_systems_add_feature(CMAKE_CXX_COMPILER "C++ compiler") +rocprofiler_systems_add_feature(CMAKE_CXX_STANDARD "CXX language standard") +rocprofiler_systems_add_option(CMAKE_CXX_STANDARD_REQUIRED + "Require C++ language standard" ON +) +rocprofiler_systems_add_option(CMAKE_CXX_EXTENSIONS + "Compiler specific language extensions" OFF +) +rocprofiler_systems_add_option(CMAKE_INSTALL_RPATH_USE_LINK_PATH + "Enable rpath to linked libraries" ON +) +set(CMAKE_INSTALL_MESSAGE "LAZY" CACHE STRING "Installation message") +mark_as_advanced(CMAKE_INSTALL_MESSAGE) + +rocprofiler_systems_add_option(ROCPROFSYS_USE_CLANG_TIDY "Enable clang-tidy" OFF) +rocprofiler_systems_add_option(ROCPROFSYS_USE_BFD + "Enable BFD support (map call-stack samples to LOC)" ON +) +rocprofiler_systems_add_option(ROCPROFSYS_USE_MPI "Enable MPI support" OFF) +rocprofiler_systems_add_option(ROCPROFSYS_USE_ROCM "Enable ROCm support" ON) +rocprofiler_systems_add_option(ROCPROFSYS_USE_PAPI "Enable HW counter support via PAPI" + ON +) +rocprofiler_systems_add_option( + ROCPROFSYS_USE_MPI_HEADERS + "Enable wrapping MPI functions w/o enabling MPI dependency" ON +) +rocprofiler_systems_add_option(ROCPROFSYS_USE_OMPT "Enable OpenMP tools support" ON) +rocprofiler_systems_add_option(ROCPROFSYS_USE_PYTHON "Enable Python support" OFF) +rocprofiler_systems_add_option(ROCPROFSYS_BUILD_DYNINST "Build dyninst from submodule" + OFF +) +rocprofiler_systems_add_option(ROCPROFSYS_BUILD_LIBUNWIND + "Build libunwind from submodule" ON +) +rocprofiler_systems_add_option(ROCPROFSYS_BUILD_CODECOV "Build for code coverage" OFF) +rocprofiler_systems_add_option(ROCPROFSYS_INSTALL_PERFETTO_TOOLS + "Install perfetto tools (i.e. traced, perfetto, etc.)" OFF +) + +if(ROCPROFSYS_USE_PAPI) + rocprofiler_systems_add_option(ROCPROFSYS_BUILD_PAPI "Build PAPI from submodule" ON) +endif() + +if(ROCPROFSYS_USE_PYTHON) + rocprofiler_systems_add_option(ROCPROFSYS_BUILD_PYTHON + "Build python bindings with internal pybind11" ON + ) +elseif("$ENV{ROCPROFSYS_CI}") + # quiet warnings in dashboard + if(ROCPROFSYS_PYTHON_ENVS OR ROCPROFSYS_PYTHON_PREFIX) + rocprofiler_systems_message( + STATUS + "Ignoring values of ROCPROFSYS_PYTHON_ENVS and/or ROCPROFSYS_PYTHON_PREFIX" + ) + endif() +endif() + +if(ROCPROFSYS_BUILD_TESTING) + set(ROCPROFSYS_BUILD_EXAMPLES ON CACHE BOOL "Enable building the examples" FORCE) +endif() + +include(ProcessorCount) +ProcessorCount(ROCPROFSYS_PROCESSOR_COUNT) + +if(ROCPROFSYS_PROCESSOR_COUNT LESS 8) + set(ROCPROFSYS_THREAD_COUNT 128) +else() + math(EXPR ROCPROFSYS_THREAD_COUNT "16 * ${ROCPROFSYS_PROCESSOR_COUNT}") + compute_pow2_ceil(ROCPROFSYS_THREAD_COUNT "16 * ${ROCPROFSYS_PROCESSOR_COUNT}") + + # set the default to 2048 if it could not be calculated + if(ROCPROFSYS_THREAD_COUNT LESS 2) + set(ROCPROFSYS_THREAD_COUNT 2048) + endif() +endif() + +set(ROCPROFSYS_MAX_THREADS + "${ROCPROFSYS_THREAD_COUNT}" + CACHE STRING + "Maximum number of threads in the host application. Likely only needs to be increased if host app does not use thread-pool but creates many threads" +) +rocprofiler_systems_add_feature( + ROCPROFSYS_MAX_THREADS + "Maximum number of total threads supported in the host application (default: max of 128 or 16 * nproc)" +) + +compute_pow2_ceil(_MAX_THREADS "${ROCPROFSYS_MAX_THREADS}") + +if(_MAX_THREADS GREATER 0 AND NOT ROCPROFSYS_MAX_THREADS EQUAL _MAX_THREADS) + rocprofiler_systems_message( + FATAL_ERROR + "Error! ROCPROFSYS_MAX_THREADS must be a power of 2. Recommendation: ${_MAX_THREADS}" + ) +elseif(NOT ROCPROFSYS_MAX_THREADS EQUAL _MAX_THREADS) + rocprofiler_systems_message( + AUTHOR_WARNING + "ROCPROFSYS_MAX_THREADS (=${ROCPROFSYS_MAX_THREADS}) must be a power of 2. We were unable to verify it so we are emitting this warning instead. Estimate resulted in: ${_MAX_THREADS}" + ) +endif() + +set(ROCPROFSYS_MAX_UNWIND_DEPTH + "64" + CACHE STRING + "Maximum call-stack depth to search during call-stack unwinding. Decreasing this value will result in sampling consuming less memory" +) +rocprofiler_systems_add_feature( + ROCPROFSYS_MAX_UNWIND_DEPTH + "Maximum call-stack depth to search during call-stack unwinding. Decreasing this value will result in sampling consuming less memory" +) + +# default visibility settings +set(CMAKE_C_VISIBILITY_PRESET + "default" + CACHE STRING + "Visibility preset for non-inline C functions" +) +set(CMAKE_CXX_VISIBILITY_PRESET + "default" + CACHE STRING + "Visibility preset for non-inline C++ functions/objects" +) +set(CMAKE_VISIBILITY_INLINES_HIDDEN + OFF + CACHE BOOL + "Visibility preset for inline functions" +) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +include(Formatting) # format target +include(Packages) # finds third-party libraries + +rocprofiler_systems_activate_clang_tidy() + +# custom visibility settings +if(ROCPROFSYS_BUILD_HIDDEN_VISIBILITY) + set(CMAKE_C_VISIBILITY_PRESET "internal") + set(CMAKE_CXX_VISIBILITY_PRESET "internal") + set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) +endif() + +if(ROCPROFSYS_BUILD_TESTING OR "$ENV{ROCPROFSYS_CI}" MATCHES "[1-9]+|ON|on|y|yes") + enable_testing() + include(CTest) +endif() + +# ------------------------------------------------------------------------------# +# +# library and executables +# +# ------------------------------------------------------------------------------# + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME core) + +if(ROCPROFSYS_BUILD_CODECOV) + rocprofiler_systems_save_variables(CODECOV_FLAGS VARIABLES CMAKE_C_FLAGS + CMAKE_CXX_FLAGS + ) + foreach(_BUILD_TYPE DEBUG MINSIZEREL RELWITHDEBINFO RELEASE) + rocprofiler_systems_save_variables( + CODECOV_FLAGS VARIABLES CMAKE_C_FLAGS_${_BUILD_TYPE} + CMAKE_CXX_FLAGS_${_BUILD_TYPE} + ) + endforeach() + + foreach(_BUILD_TYPE DEBUG MINSIZEREL RELWITHDEBINFO RELEASE) + set(CMAKE_C_FLAGS_${_BUILD_TYPE} + "-Og -g3 -fno-omit-frame-pointer -fprofile-abs-path -fprofile-arcs -ftest-coverage" + ) + set(CMAKE_CXX_FLAGS_${_BUILD_TYPE} + "-Og -g3 -fno-omit-frame-pointer -fprofile-abs-path -fprofile-arcs -ftest-coverage" + ) + endforeach() + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") +endif() + +add_subdirectory(source) + +if(ROCPROFSYS_BUILD_CODECOV) + rocprofiler_systems_restore_variables(CODECOV_FLAGS VARIABLES CMAKE_C_FLAGS + CMAKE_CXX_FLAGS + ) + + foreach(_BUILD_TYPE DEBUG MINSIZEREL RELWITHDEBINFO RELEASE) + rocprofiler_systems_restore_variables( + CODECOV_FLAGS VARIABLES CMAKE_C_FLAGS_${_BUILD_TYPE} + CMAKE_CXX_FLAGS_${_BUILD_TYPE} + ) + endforeach() +endif() + +# ------------------------------------------------------------------------------# +# +# miscellaneous installs +# +# ------------------------------------------------------------------------------# + +configure_file( + ${PROJECT_SOURCE_DIR}/LICENSE + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}/LICENSE + COPYONLY +) + +configure_file( + ${PROJECT_SOURCE_DIR}/perfetto.cfg + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/perfetto.cfg + COPYONLY +) + +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}/${ROCPROFSYS_VERSION} + @ONLY +) + +configure_file( + ${PROJECT_SOURCE_DIR}/scripts/merge-multiprocess-output.sh + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}/rocprof-sys-merge-output.sh + COPYONLY +) + +install( + FILES + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/setup-env.sh + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/perfetto.cfg + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME} + COMPONENT setup +) + +install( + FILES + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/modulefiles/${PROJECT_NAME}/${ROCPROFSYS_VERSION} + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/modulefiles/${PROJECT_NAME} + COMPONENT setup +) + +install( + FILES ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME}/LICENSE + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/doc/${PROJECT_NAME} + COMPONENT setup +) + +install( + PROGRAMS + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME}/rocprof-sys-merge-output.sh + DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME} + COMPONENT setup +) + +# ------------------------------------------------------------------------------# +# +# install +# +# ------------------------------------------------------------------------------# + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME core) +include(ConfigInstall) + +# ------------------------------------------------------------------------------# +# +# examples +# +# ------------------------------------------------------------------------------# + +if(ROCPROFSYS_BUILD_EXAMPLES) + set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME examples) + add_subdirectory(examples) +endif() + +# ------------------------------------------------------------------------------# +# +# tests +# +# ------------------------------------------------------------------------------# + +if(ROCPROFSYS_BUILD_TESTING) + set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME testing) + add_subdirectory(tests) +endif() + +# ------------------------------------------------------------------------------# +# +# packaging +# +# ------------------------------------------------------------------------------# + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME core) +include(ConfigCPack) + +# ------------------------------------------------------------------------------# +# +# config info +# +# ------------------------------------------------------------------------------# + +rocprofiler_systems_print_features() diff --git a/projects/rocprofiler-systems/CMakePresets.json b/projects/rocprofiler-systems/CMakePresets.json new file mode 100644 index 0000000000..e1e86a0f75 --- /dev/null +++ b/projects/rocprofiler-systems/CMakePresets.json @@ -0,0 +1,94 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "ci", + "displayName": "official CI build", + "description": "Official CI build parameters", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/ci", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_INSTALL_PREFIX": "/opt/rocprofiler-systems", + "CMAKE_C_COMPILER": "gcc", + "CMAKE_CXX_COMPILER": "g++", + "ROCPROFSYS_USE_ROCM": "ON", + "ROCPROFSYS_USE_PYTHON": "ON", + "ROCPROFSYS_BUILD_DYNINST": "ON", + "ROCPROFSYS_BUILD_TBB": "ON", + "ROCPROFSYS_BUILD_BOOST": "ON", + "ROCPROFSYS_BUILD_ELFUTILS": "ON", + "ROCPROFSYS_BUILD_LIBIBERTY": "ON", + "ROCPROFSYS_BUILD_TESTING": "ON", + "ROCPROFSYS_STRIP_LIBRARIES": "OFF", + "ROCPROFSYS_MAX_THREADS": "64", + "ROCPROFSYS_BUILD_CI": "ON" + } + }, + { + "name": "debug", + "displayName": "official debug build", + "description": "Debug build parameters with tests", + "binaryDir": "${sourceDir}/build/debug", + "generator": "Ninja", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_INSTALL_PREFIX": "/opt/rocprofiler-systems", + "CMAKE_C_COMPILER": "gcc", + "CMAKE_CXX_COMPILER": "g++", + "ROCPROFSYS_USE_ROCM": "ON", + "ROCPROFSYS_USE_PYTHON": "ON", + "ROCPROFSYS_BUILD_DYNINST": "ON", + "ROCPROFSYS_BUILD_TBB": "ON", + "ROCPROFSYS_BUILD_BOOST": "ON", + "ROCPROFSYS_BUILD_ELFUTILS": "ON", + "ROCPROFSYS_BUILD_LIBIBERTY": "ON", + "ROCPROFSYS_BUILD_TESTING": "ON", + "ROCPROFSYS_STRIP_LIBRARIES": "OFF", + "ROCPROFSYS_BUILD_DEBUG": "ON" + } + }, + { + "name": "debug-optimized", + "displayName": "release build with debug info", + "description": "Release build with debug info with tests", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/debug-optimized", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo", + "CMAKE_INSTALL_PREFIX": "/opt/rocprofiler-systems", + "CMAKE_C_COMPILER": "gcc", + "CMAKE_CXX_COMPILER": "g++", + "ROCPROFSYS_USE_ROCM": "ON", + "ROCPROFSYS_USE_PYTHON": "ON", + "ROCPROFSYS_BUILD_DYNINST": "ON", + "ROCPROFSYS_BUILD_TBB": "ON", + "ROCPROFSYS_BUILD_BOOST": "ON", + "ROCPROFSYS_BUILD_ELFUTILS": "ON", + "ROCPROFSYS_BUILD_LIBIBERTY": "ON", + "ROCPROFSYS_BUILD_TESTING": "ON", + "ROCPROFSYS_STRIP_LIBRARIES": "OFF" + } + }, + { + "name": "release", + "displayName": "official release build", + "description": "Official release build", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_INSTALL_PREFIX": "/opt/rocprofiler-systems", + "CMAKE_C_COMPILER": "gcc", + "CMAKE_CXX_COMPILER": "g++", + "ROCPROFSYS_USE_ROCM": "ON", + "ROCPROFSYS_USE_PYTHON": "ON", + "ROCPROFSYS_BUILD_DYNINST": "ON", + "ROCPROFSYS_BUILD_TBB": "ON", + "ROCPROFSYS_BUILD_BOOST": "ON", + "ROCPROFSYS_BUILD_ELFUTILS": "ON", + "ROCPROFSYS_BUILD_LIBIBERTY": "ON" + } + } + ] +} diff --git a/projects/rocprofiler-systems/CONTRIBUTING.md b/projects/rocprofiler-systems/CONTRIBUTING.md new file mode 100644 index 0000000000..d295ca9cf6 --- /dev/null +++ b/projects/rocprofiler-systems/CONTRIBUTING.md @@ -0,0 +1,107 @@ + + + + + + +# Contributing to rocprofiler-systems # + +ROCm Systems Profiler (rocprofiler-systems), formerly Omnitrace, is a comprehensive profiling and tracing tool for parallel applications written in C, C++, Fortran, HIP, OpenCL, and Python which execute on the CPU or CPU+GPU. + +We welcome contributions to rocprofiler-systems. Please follow these details to help ensure your contributions will be successfully accepted. + +## Table of Contents ## + +1. [Issue Discussion](#issue-discussion) +2. [Acceptance Criteria](#acceptance-criteria) +3. [Pull Request Guidelines](#pull-request-guidelines) +4. [Coding Style](#coding-style) +5. [Code License](#code-license) +6. [References](#references) + +## Issue Discussion ## + +Please use the GitHub Issues tab to notify us of issues. + +* Use your best judgement for issue creation. Search [existing issues](https://github.com/ROCm/rocprofiler-systems/issues) to make sure your issue isn't already listed +* If your issue is already listed, upvote the issue and comment or post to provide additional details, such as how you reproduced this issue. +* If you're not sure if your issue is the same, err on the side of caution and file your issue. You can add a comment to include the issue number (and link) for the similar issue. If we evaluate your issue as being the same as the existing issue, we'll close the duplicate. +* If your issue doesn't exist, use the issue template to file a new issue. +* When filing an issue, be sure to provide as much information as possible, including script output so we can collect information about your configuration. This helps reduce the time required to reproduce your issue. +* Check your issue regularly, as we may require additional information to successfully reproduce the issue. +* You may also open an issue to ask questions to the maintainers about whether a proposed change meets the acceptance criteria, or to discuss an idea pertaining to the library. + +## Acceptance Criteria ## + +* Contributions should align with the project's goals and maintainability. +* Code should be well-documented and include tests where applicable. +* Ensure that your changes do not break existing functionality. +* Each commit is to be digitally signed. For more details see: [About commit signature verification - GitHub Docs](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification). + +### Exceptions ### + +* If you believe your contribution does not fit the guidelines but is still valuable, please discuss it with the maintainers before submitting. + +## Pull Request Guidelines ## + +By creating a pull request, you agree to the statements made in the [code license](#code-license) section. Your pull request should target the default branch. Our current default branch is the **amd-staging** branch, which serves as our integration branch. + +### Process ### + +* Fork the repository and create your branch from `amd-staging`. +* If you've added code that should be tested, add tests. +* Ensure the test suite passes. +* Make sure your code conforms to the format. Use clang-format-18 and/or gersemi. +* Use clear and descriptive commit messages. +* Submit your PR and work with the reviewer or maintainer to get your PR approved +* Once approved, the PR is brought onto internal CI systems and may be merged into the component during our release cycle, as coordinated by the maintainer. + +### Setting Up the Development Environment ### + +* It is recommended to [fork](https://github.com/ROCm/rocprofiler-systems/fork) the repository. +* Clone your forked repository: `git clone https://github.com/ROCm//rocprofiler-systems.git` +* Navigate to the project directory: `cd rocprofiler-systems` +* Set the original repository URL as the remote upstream using `git remote add upstream https://github.com/ROCm/rocprofiler-systems` (or `git remote set-url upstream https://github.com/ROCm/rocprofiler-systems`) +* Verify if origin and upstream points correctly with `git remote -v`. +* Start a new branch for your work: `git checkout -b topic-` +* Build the project as outlined in [ROCm documentation](https://github.com/ROCm/rocprofiler-systems/blob/a03770c0606c23fda5e2c83782f2d188eb8522f5/docs/install/install.rst#building-and-installing-rocm-systems-profiler). + +### Running Tests ### + +* To run the test suite, use the following command: `make test` +* Ensure all tests pass before submitting a pull request. +* If the project was built with option `-D ROCPROFSYS_BUILD_TESTING=ON`, then the tests are built with it. Individual tests groups can be run using command: `ctest -R -V --output-on-failure`. Command `ctest --print-labels` will list all the test names which can be passed to -R as test-name. + +## Coding Style ## + +* Adhere to the coding style used in the project. This includes naming conventions, indentation, and commenting practices. +* Follow the existing directory structure and organization of the codebase. +* Group related files together and maintain a logical hierarchy. +* Use `clang-format-18` and `gersemi` formatters to ensure consistency. + +### Using pre-commit hooks ### + +Our project supports optional [*pre-commit hooks*](https://pre-commit.com/#introduction) which developers can leverage to verify formatting before publishing their code. Once enabled, any commits you propose to the repository will be automatically checked for formatting. Initial setup is as follows: + +```shell +pip install pre-commit # or: apt-get install pre-commit +cd rocprofiler-systems +pre-commit install +``` + +**Note:** pre-commit version **3.0.0 or higher** is required. + +Now, when you commit code to the repository you should see something like this: + +![A screen capture showing terminal output from a pre-commit hook](docs/data/pre-commit-hook.png) + +Please see the [pre-commit documentation](https://pre-commit.com/#quick-start) for additional information. + +## Code License ## + +All code contributed to this project will be licensed under the license identified in the [License](LICENSE). Your contribution will be accepted under the same license. + +## References ## + +1. [ROCm Systems Profiler Documentation](https://rocm.docs.amd.com/projects/rocprofiler-systems/en/latest/index.html) +2. [ROCm Systems Profiler README](README.md) diff --git a/projects/rocprofiler-systems/LICENSE b/projects/rocprofiler-systems/LICENSE new file mode 100644 index 0000000000..2718c7a4e4 --- /dev/null +++ b/projects/rocprofiler-systems/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Advanced Micro Devices, Inc. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/projects/rocprofiler-systems/README.md b/projects/rocprofiler-systems/README.md new file mode 100755 index 0000000000..8e81fb6a2a --- /dev/null +++ b/projects/rocprofiler-systems/README.md @@ -0,0 +1,419 @@ +# ROCm Systems Profiler: Application profiling, tracing, and analysis + +[![Ubuntu 20.04 with GCC, ROCm, and MPI](https://github.com/ROCm/rocprofiler-systems/actions/workflows/ubuntu-focal.yml/badge.svg)](https://github.com/ROCm/rocprofiler-systems/actions/workflows/ubuntu-focal.yml) +[![Ubuntu 22.04 (GCC, Python, ROCm)](https://github.com/ROCm/rocprofiler-systems/actions/workflows/ubuntu-jammy.yml/badge.svg)](https://github.com/ROCm/rocprofiler-systems/actions/workflows/ubuntu-jammy.yml) +[![OpenSUSE 15.x with GCC](https://github.com/ROCm/rocprofiler-systems/actions/workflows/opensuse.yml/badge.svg)](https://github.com/ROCm/rocprofiler-systems/actions/workflows/opensuse.yml) +[![RedHat Linux (GCC, Python, ROCm)](https://github.com/ROCm/rocprofiler-systems/actions/workflows/redhat.yml/badge.svg)](https://github.com/ROCm/rocprofiler-systems/actions/workflows/redhat.yml) +[![Installer Packaging (CPack)](https://github.com/ROCm/rocprofiler-systems/actions/workflows/cpack.yml/badge.svg)](https://github.com/ROCm/rocprofiler-systems/actions/workflows/cpack.yml) +[![Documentation](https://github.com/ROCm/rocprofiler-systems/actions/workflows/docs.yml/badge.svg)](https://github.com/ROCm/rocprofiler-systems/actions/workflows/docs.yml) + +> [!NOTE] +> If you are using a version of ROCm prior to ROCm 6.3.1 and are experiencing problems viewing your trace in the latest version of [Perfetto](http://ui.perfetto.dev), then try using [Perfetto UI v46.0](https://ui.perfetto.dev/v46.0-35b3d9845/#!/). + +## Overview + +ROCm Systems Profiler (rocprofiler-systems), formerly Omnitrace, is a comprehensive profiling and tracing tool for parallel applications written in C, C++, Fortran, HIP, OpenCL, and Python which execute on the CPU or CPU+GPU. +It is capable of gathering the performance information of functions through any combination of binary instrumentation, call-stack sampling, user-defined regions, and Python interpreter hooks. +ROCm Systems Profiler supports interactive visualization of comprehensive traces in the web browser in addition to high-level summary profiles with mean/min/max/stddev statistics. +In addition to runtimes, ROCm Systems Profiler supports the collection of system-level metrics such as the CPU frequency, GPU temperature, and GPU utilization, process-level metrics +such as the memory usage, page-faults, and context-switches, and thread-level metrics such as memory usage, CPU time, and numerous hardware counters. + +> [!NOTE] +> Full documentation is available at [ROCm Systems Profiler documentation](https://rocm.docs.amd.com/projects/rocprofiler-systems/en/latest/index.html) in an organized, easy-to-read, searchable format. +The documentation source files reside in the [`/docs`](/docs) folder of this repository. For information on contributing to the documentation, see +[Contribute to ROCm documentation](https://rocm.docs.amd.com/en/latest/contribute/contributing.html) + +### Data collection modes + +- Dynamic instrumentation + - Runtime instrumentation + - Instrument executable and shared libraries at runtime + - Binary rewriting + - Generate a new executable and/or library with instrumentation built-in +- Statistical sampling + - Periodic software interrupts per-thread +- Process-level sampling + - Background thread records process-, system- and device-level metrics while the application executes +- Causal profiling + - Quantifies the potential impact of optimizations in parallel codes + +### Data analysis + +- High-level summary profiles with mean/min/max/stddev statistics + - Low overhead, memory efficient + - Ideal for running at scale +- Comprehensive traces + - Every individual event/measurement +- Application speedup predictions resulting from potential optimizations in functions and lines of code (causal profiling) + +### Parallelism API support + +- HIP +- HSA +- Pthreads +- MPI +- Kokkos-Tools (KokkosP) +- OpenMP-Tools (OMPT) + +### GPU metrics + +- GPU hardware counters +- HIP API tracing +- HIP kernel tracing +- HSA API tracing +- HSA operation tracing +- rocDecode API tracing +- rocJPEG API tracing +- System-level sampling (via AMD-SMI) + - Memory usage + - Power usage + - Temperature + - Utilization + - VCN Utilization + - JPEG Utilization + +> [!NOTE] +> The availability of VCN and JPEG engine utilization depends on device support for different ASICs. If unsupported, all values for VCN_ACTIVITY and JPEG_ACTIVITY will be reported as N/A in the output of `amd-smi metric --usage`. + +### CPU metrics + +- CPU hardware counters sampling and profiles +- CPU frequency sampling +- Various timing metrics + - Wall time + - CPU time (process and/or thread) + - CPU utilization (process and/or thread) + - User CPU time + - Kernel CPU time +- Various memory metrics + - High-water mark (sampling and profiles) + - Memory page allocation + - Virtual memory usage +- Network statistics +- I/O metrics +- ... many more + +## Quick start + +### Installation + +- Visit [Releases](https://github.com/ROCm/rocprofiler-systems/releases) page +- Select appropriate installer (recommendation: `.sh` scripts do not require super-user priviledges unlike the DEB/RPM installers) + - If targeting a ROCm application, find the installer script with the matching ROCm version + - If you are unsure about your Linux distro, check `/etc/os-release` or use the `rocprofiler-systems-install.py` script + +If the above recommendation is not desired, download the `rocprofiler-systems-install.py` and specify `--prefix ` when +executing it. This script will attempt to auto-detect a compatible OS distribution and version. +If ROCm support is desired, specify `--rocm X.Y` where `X` is the ROCm major version and `Y` +is the ROCm minor version, e.g. `--rocm 6.2`. + +```console +wget https://github.com/ROCm/rocprofiler-systems/releases/latest/download/rocprofiler-systems-install.py +python3 ./rocprofiler-systems-install.py --prefix /opt/rocprofiler-systems --rocm 6.2 +``` + +See the [ROCm Systems Profiler installation guide](https://rocm.docs.amd.com/projects/rocprofiler-systems/en/latest/install/install.html) for detailed information. + +### Setup + +> [!NOTE] +> Replace `/opt/rocprofiler-systems` below with installation prefix as necessary. + +- **Option 1**: Source `setup-env.sh` script + +```bash +source /opt/rocprofiler-systems/share/rocprofiler-systems/setup-env.sh +``` + +- **Option 2**: Load modulefile + +```bash +module use /opt/rocprofiler-systems/share/modulefiles +module load rocprofiler-systems +``` + +- **Option 3**: Manual + +```bash +export PATH=/opt/rocprofiler-systems/bin:${PATH} +export LD_LIBRARY_PATH=/opt/rocprofiler-systems/lib:${LD_LIBRARY_PATH} +``` + +### Testing environment + +The `build-docker` script can be used to create a testing environment. To see the available options, use the following commands: + +```shell +cd docker +./build-docker.sh --help +``` + +> [!NOTE] +> The `-m` argument can be used to show supported OS + ROCm combinations. + +**Example:** To set up an Ubuntu 24.04 + ROCm 6.4 + Python 3.12 environment for building and testing, run the following commands: + +```shell +cd docker +./build-docker.sh --distro ubuntu --versions 24.04 \ + --rocm-versions 6.4 --python-versions 12 --retry 1 +docker run -v "$(cd .. && pwd)":/home/development \ + -it -w /home/development \ + --device /dev/kfd --device /dev/dri \ + $(whoami)/rocprofiler-systems:release-base-ubuntu-24.04-rocm-6.4 +``` + +Inside the container, clean, build, and install the project with testing enabled using the following commands: + +```shell +rm -rf rocprof-sys-build +cmake -B rocprof-sys-build -S . \ + -D CMAKE_INSTALL_PREFIX=/opt/rocprofiler-systems \ + -D ROCPROFSYS_USE_PYTHON=ON -D ROCPROFSYS_BUILD_DYNINST=ON \ + -D ROCPROFSYS_BUILD_TBB=ON -D ROCPROFSYS_BUILD_BOOST=ON \ + -D ROCPROFSYS_BUILD_ELFUTILS=ON -D ROCPROFSYS_BUILD_LIBIBERTY=ON \ + -D ROCPROFSYS_BUILD_TESTING=ON +cmake --build rocprof-sys-build --target all --parallel 8 +cmake --build rocprof-sys-build --target install +source /opt/rocprofiler-systems/share/rocprofiler-systems/setup-env.sh +``` + +> [!NOTE] +> If you see "dubious ownership" Git errors when working in the container, run: +> +> ```shell +> git config --global --add safe.directory /home/development +> ``` +> +> and +> +> ```shell +> git config --global --add safe.directory /home/development/external/timemory +> ``` + +Then, use the following command to start automated testing: + +```shell +ctest --test-dir rocprof-sys-build --output-on-failure +``` + +To enable MPI testing inside the container, set the following environment variables: + +```shell +export OMPI_ALLOW_RUN_AS_ROOT=1 +export OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1 +``` + +For manual testing, you can find the executables in `rocprof-sys-build/bin`. + +### ROCm Systems Profiler settings + +Generate a rocprofiler-systems configuration file using `rocprof-sys-avail -G rocprof-sys.cfg`. Optionally, use `rocprof-sys-avail -G rocprof-sys.cfg --all` for +a verbose configuration file with descriptions, categories, etc. Modify the configuration file as desired, e.g. enable +[perfetto](https://perfetto.dev/), [timemory](https://github.com/ROCm/timemory), sampling, and process-level sampling by default +and tweak some sampling default values: + +```console +# ... +ROCPROFSYS_TRACE = true +ROCPROFSYS_PROFILE = true +ROCPROFSYS_USE_SAMPLING = true +ROCPROFSYS_USE_PROCESS_SAMPLING = true +# ... +ROCPROFSYS_SAMPLING_FREQ = 50 +ROCPROFSYS_SAMPLING_CPUS = all +ROCPROFSYS_SAMPLING_GPUS = $env:HIP_VISIBLE_DEVICES +``` + +Once the configuration file is adjusted to your preferences, either export the path to this file via `ROCPROFSYS_CONFIG_FILE=/path/to/rocprof-sys.cfg` +or place this file in `${HOME}/.rocprof-sys.cfg` to ensure these values are always read as the default. If you wish to change any of these settings, +you can override them via environment variables or by specifying an alternative `ROCPROFSYS_CONFIG_FILE`. + +### Call-Stack sampling + +The `rocprof-sys-sample` executable is used to execute call-stack sampling on a target application without binary instrumentation. +Use a double-hypen (`--`) to separate the command-line arguments for `rocprof-sys-sample` from the target application and it's arguments. + +```shell +rocprof-sys-sample --help +rocprof-sys-sample -- +rocprof-sys-sample -f 1000 -- ls -la +``` + +### Binary instrumentation + +The `rocprof-sys-instrument` executable is used to instrument an existing binary. Call-stack sampling can be enabled alongside +the execution an instrumented binary, to help "fill in the gaps" between the instrumentation via setting the `ROCPROFSYS_USE_SAMPLING` +configuration variable to `ON`. +Similar to `rocprof-sys-sample`, use a double-hypen (`--`) to separate the command-line arguments for `rocprof-sys-instrument` from the target application and it's arguments. + +```shell +rocprof-sys-instrument --help +rocprof-sys-instrument -- +``` + +#### Binary rewrite + +Rewrite the text section of an executable or library with instrumentation: + +```shell +rocprof-sys-instrument -o app.inst -- /path/to/app +``` + +In binary rewrite mode, if you also want instrumentation in the linked libraries, you must also rewrite those libraries. +Example of rewriting the functions starting with `"hip"` with instrumentation in the amdhip64 library: + +```shell +mkdir -p ./lib +rocprof-sys-instrument -R '^hip' -o ./lib/libamdhip64.so.4 -- /opt/rocm/lib/libamdhip64.so.4 +export LD_LIBRARY_PATH=${PWD}/lib:${LD_LIBRARY_PATH} +``` + +> [!NOTE] +> Verify via `ldd` that your executable will load the instrumented library. If you built your executable with an RPATH to the original library's directory, then prefixing `LD_LIBRARY_PATH` will have no effect. + +Once you have rewritten your executable and/or libraries with instrumentation, you can just run the (instrumented) executable +or exectuable which loads the instrumented libraries normally, e.g.: + +```shell +rocprof-sys-run -- ./app.inst +``` + +If you want to re-define certain settings to new default in a binary rewrite, use the `--env` option. This `rocprof-sys` option +will set the environment variable to the given value but will not override it. E.g. the default value of `ROCPROFSYS_PERFETTO_BUFFER_SIZE_KB` +is 1024000 KB (1 GiB): + +```shell +# buffer size defaults to 1024000 +rocprof-sys-instrument -o app.inst -- /path/to/app +rocprof-sys-run -- ./app.inst +``` + +Passing `--env ROCPROFSYS_PERFETTO_BUFFER_SIZE_KB=5120000` will change the default value in `app.inst` to 5120000 KiB (5 GiB): + +```shell +# defaults to 5 GiB buffer size +rocprof-sys-instrument -o app.inst --env ROCPROFSYS_PERFETTO_BUFFER_SIZE_KB=5120000 -- /path/to/app +rocprof-sys-run -- ./app.inst +``` + +```shell +# override default 5 GiB buffer size to 200 MB via command-line +rocprof-sys-run --trace-buffer-size=200000 -- ./app.inst +# override default 5 GiB buffer size to 200 MB via environment +export ROCPROFSYS_PERFETTO_BUFFER_SIZE_KB=200000 +rocprof-sys-run -- ./app.inst +``` + +#### Runtime instrumentation + +Runtime instrumentation will not only instrument the text section of the executable but also the text sections of the +linked libraries. Thus, it may be useful to exclude those libraries via the `-ME` (module exclude) regex option +or exclude specific functions with the `-E` regex option. + +```shell +rocprof-sys-instrument -- /path/to/app +rocprof-sys-instrument -ME '^(libhsa-runtime64|libz\\.so)' -- /path/to/app +rocprof-sys-instrument -E 'rocr::atomic|rocr::core|rocr::HSA' -- /path/to/app +``` + +### Python profiling and tracing + +Use the `rocprof-sys-python` script to profile/trace Python interpreter function calls. +Use a double-hypen (`--`) to separate the command-line arguments for `rocprof-sys-python` from the target script and it's arguments. + +```shell +rocprof-sys-python --help +rocprof-sys-python -- +rocprof-sys-python -- ./script.py +``` + +> [!NOTE] +> The first argument after the double-hyphen must be a Python script, e.g. `rocprof-sys-python -- ./script.py`. + +If you need to specify a specific python interpreter version, use `rocprof-sys-python-X.Y` where `X.Y` is the Python +major and minor version: + +```shell +rpcprof-sys-python-3.8 -- ./script.py +``` + +If you need to specify the full path to a Python interpreter, set the `PYTHON_EXECUTABLE` environment variable: + +```shell +PYTHON_EXECUTABLE=/opt/conda/bin/python rocprof-sys-python -- ./script.py +``` + +If you want to restrict the data collection to specific function(s) and its callees, pass the `-b` / `--builtin` option after decorating the +function(s) with `@profile`. Use the `@noprofile` decorator for excluding/ignoring function(s) and its callees: + +```python +def foo(): + pass + +@noprofile +def bar(): + foo() + +@profile +def spam(): + foo() + bar() +``` + +Each time `spam` is called during profiling, the profiling results will include 1 entry for `spam` and 1 entry +for `foo` via the direct call within `spam`. There will be no entries for `bar` or the `foo` invocation within it. + +### Trace visualization + +- Visit [ui.perfetto.dev](https://ui.perfetto.dev) in the web-browser +- Select "Open trace file" from panel on the left +- Locate the rocprofiler-systems perfetto output (extension: `.proto`) + +![rocprof-sys-perfetto](docs/data/rocprof-sys-perfetto.png) + +![rocprof-sys-rocm](docs/data/rocprof-sys-rocm.png) + +![rocprof-sys-rocm-flow](docs/data/rocprof-sys-rocm-flow.png) + +![rocprof-sys-user-api](docs/data/rocprof-sys-user-api.png) + +## Using Perfetto tracing with system backend + +Perfetto tracing with the system backend supports multiple processes writing to the same +output file. Thus, it is a useful technique if rocprofiler-systems is built with partial MPI support +because all the perfetto output will be coalesced into a single file. The +installation docs for perfetto can be found [here](https://perfetto.dev/docs/contributing/build-instructions). +If you are building rocprofiler-systems from source, you can configure CMake with `ROCPROFSYS_INSTALL_PERFETTO_TOOLS=ON` +and the `perfetto` and `traced` applications will be installed as part of the build process. However, +it should be noted that to prevent this option from accidentally overwriting an existing perfetto install, +all the perfetto executables installed by ROCm Systems Profiler are prefixed with `rocprof-sys-perfetto-`, except +for the `perfetto` executable, which is just renamed `rocprof-sys-perfetto`. + +Enable `traced` and `perfetto` in the background: + +```shell +pkill traced +traced --background +perfetto --out ./rocprof-sys-perfetto.proto --txt -c ${ROCPROFSYS_ROOT}/share/perfetto.cfg --background +``` + +> [!NOTE] +> If the perfetto tools were installed by rocprofiler-systems, replace `traced` with `rocprof-sys-perfetto-traced` and `perfetto` with `rocprof-sys-perfetto`. + +Configure rocprofiler-systems to use the perfetto system backend via the `--perfetto-backend` option of `rocprof-sys-run`: + +```shell +# enable sampling on the uninstrumented binary +rocprof-sys-run --sample --trace --perfetto-backend=system -- ./myapp + +# trace the instrument the binary +rocprof-sys-instrument -o ./myapp.inst -- ./myapp +rocprof-sys-run --trace --perfetto-backend=system -- ./myapp.inst +``` + +or via the `--env` option of `rocprof-sys-instrument` + runtime instrumentation: + +```shell +rocprof-sys-instrument --env ROCPROFSYS_PERFETTO_BACKEND=system -- ./myapp +``` diff --git a/projects/rocprofiler-systems/VERSION b/projects/rocprofiler-systems/VERSION new file mode 100644 index 0000000000..9084fa2f71 --- /dev/null +++ b/projects/rocprofiler-systems/VERSION @@ -0,0 +1 @@ +1.1.0 diff --git a/projects/rocprofiler-systems/cmake/BuildSettings.cmake b/projects/rocprofiler-systems/cmake/BuildSettings.cmake new file mode 100644 index 0000000000..9110d80d8f --- /dev/null +++ b/projects/rocprofiler-systems/cmake/BuildSettings.cmake @@ -0,0 +1,451 @@ +# include guard +include_guard(DIRECTORY) + +# ######################################################################################## +# +# Handles the build settings +# +# ######################################################################################## + +include(GNUInstallDirs) +include(Compilers) +include(FindPackageHandleStandardArgs) +include(MacroUtilities) + +rocprofiler_systems_add_option( + ROCPROFSYS_BUILD_DEVELOPER "Extra build flags for development like -Werror" + ${ROCPROFSYS_BUILD_CI} +) +rocprofiler_systems_add_option(ROCPROFSYS_BUILD_RELEASE + "Build with minimal debug line info" OFF +) +rocprofiler_systems_add_option(ROCPROFSYS_BUILD_EXTRA_OPTIMIZATIONS + "Extra optimization flags" OFF +) +rocprofiler_systems_add_option(ROCPROFSYS_BUILD_LTO "Build with link-time optimization" + OFF +) +rocprofiler_systems_add_option(ROCPROFSYS_USE_COMPILE_TIMING + "Build with timing metrics for compilation" OFF +) +rocprofiler_systems_add_option(ROCPROFSYS_USE_SANITIZER + "Build with -fsanitze=\${ROCPROFSYS_SANITIZER_TYPE}" OFF +) +rocprofiler_systems_add_option(ROCPROFSYS_BUILD_STATIC_LIBGCC + "Build with -static-libgcc if possible" OFF +) +rocprofiler_systems_add_option(ROCPROFSYS_BUILD_STATIC_LIBSTDCXX + "Build with -static-libstdc++ if possible" OFF +) +rocprofiler_systems_add_option(ROCPROFSYS_BUILD_STACK_PROTECTOR + "Build with -fstack-protector" ON +) +rocprofiler_systems_add_cache_option( + ROCPROFSYS_BUILD_LINKER + "If set to a non-empty value, pass -fuse-ld=\${ROCPROFSYS_BUILD_LINKER}" STRING "bfd" +) +rocprofiler_systems_add_cache_option(ROCPROFSYS_BUILD_NUMBER "Internal CI use" STRING "0" + ADVANCED NO_FEATURE +) + +rocprofiler_systems_add_interface_library(rocprofiler-systems-static-libgcc + "Link to static version of libgcc" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-static-libstdcxx + "Link to static version of libstdc++" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-static-libgcc-optional + "Link to static version of libgcc" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-static-libstdcxx-optional + "Link to static version of libstdc++" +) + +target_compile_definitions( + rocprofiler-systems-compile-options + INTERFACE $<$:DEBUG> +) + +set(ROCPROFSYS_SANITIZER_TYPE "leak" CACHE STRING "Sanitizer type") +if(ROCPROFSYS_USE_SANITIZER) + rocprofiler_systems_add_feature( + ROCPROFSYS_SANITIZER_TYPE + "Sanitizer type, e.g. leak, thread, address, memory, etc." + ) +endif() + +if(ROCPROFSYS_BUILD_CI) + rocprofiler_systems_target_compile_definitions(${LIBNAME}-compile-options + INTERFACE ROCPROFSYS_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 dw) + if(NOT ${_TYPE}_LIBRARY) + find_library(${_TYPE}_LIBRARY NAMES ${_TYPE}) + endif() +endforeach() + +find_package_handle_standard_args(dl-library REQUIRED_VARS dl_LIBRARY) +find_package_handle_standard_args(rt-library REQUIRED_VARS rt_LIBRARY) +# find_package_handle_standard_args(dw-library REQUIRED_VARS dw_LIBRARY) + +if(dl_LIBRARY) + target_link_libraries(rocprofiler-systems-compile-options INTERFACE ${dl_LIBRARY}) +endif() + +# ----------------------------------------------------------------------------------------# +# set the compiler flags +# +add_flag_if_avail( + "-W" "-Wall" "-Wno-unknown-pragmas" "-Wno-unused-function" "-Wno-ignored-attributes" + "-Wno-attributes" "-Wno-missing-field-initializers" "-Wno-interference-size" +) + +if(ROCPROFSYS_BUILD_DEBUG) + add_flag_if_avail("-g3" "-fno-omit-frame-pointer") +endif() + +if(WIN32) + # suggested by MSVC for spectre mitigation in rapidjson implementation + add_cxx_flag_if_avail("/Qspectre") +endif() + +if(CMAKE_CXX_COMPILER_IS_CLANG) + add_cxx_flag_if_avail("-Wno-mismatched-tags") +endif() + +# ----------------------------------------------------------------------------------------# +# extra flags for debug information in debug or optimized binaries +# +rocprofiler_systems_add_interface_library( + rocprofiler-systems-compile-debuginfo + "Attempts to set best flags for more expressive profiling information in debug or optimized binaries" +) + +add_target_flag_if_avail(rocprofiler-systems-compile-debuginfo "-g3" + "-fno-omit-frame-pointer" "-fno-optimize-sibling-calls" +) + +if(CMAKE_CUDA_COMPILER_IS_NVIDIA) + add_target_cuda_flag(rocprofiler-systems-compile-debuginfo "-lineinfo") +endif() + +target_compile_options( + rocprofiler-systems-compile-debuginfo + INTERFACE + $<$:$<$:-rdynamic>> + $<$:$<$:-rdynamic>> +) + +if(NOT APPLE) + target_link_options( + rocprofiler-systems-compile-debuginfo + INTERFACE $<$:-rdynamic> + ) +endif() + +if(CMAKE_CUDA_COMPILER_IS_NVIDIA) + target_compile_options( + rocprofiler-systems-compile-debuginfo + INTERFACE + $<$:$<$:-Xcompiler=-rdynamic>> + ) +endif() + +if(dl_LIBRARY) + target_link_libraries(rocprofiler-systems-compile-debuginfo INTERFACE ${dl_LIBRARY}) +endif() + +if(rt_LIBRARY) + target_link_libraries(rocprofiler-systems-compile-debuginfo INTERFACE ${rt_LIBRARY}) +endif() + +# ----------------------------------------------------------------------------------------# +# non-debug optimizations +# +rocprofiler_systems_add_interface_library(rocprofiler-systems-compile-extra + "Extra optimization flags" +) +if(NOT ROCPROFSYS_BUILD_CODECOV AND ROCPROFSYS_BUILD_EXTRA_OPTIMIZATIONS) + add_target_flag_if_avail( + rocprofiler-systems-compile-extra "-finline-functions" "-funroll-loops" + "-ftree-vectorize" "-ftree-loop-optimize" "-ftree-loop-vectorize" + ) +endif() + +if( + NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Debug" + AND ROCPROFSYS_BUILD_EXTRA_OPTIMIZATIONS + AND NOT ROCPROFSYS_BUILD_CODECOV +) + target_link_libraries( + rocprofiler-systems-compile-options + INTERFACE $ + ) + add_flag_if_avail( + "-fno-signaling-nans" "-fno-trapping-math" "-fno-signed-zeros" + "-ffinite-math-only" "-fno-math-errno" "-fpredictive-commoning" + "-fvariable-expansion-in-unroller" + ) + # add_flag_if_avail("-freciprocal-math" "-fno-signed-zeros" "-mfast-fp") +endif() + +# ----------------------------------------------------------------------------------------# +# debug-safe optimizations +# +add_cxx_flag_if_avail("-faligned-new") + +rocprofiler_systems_add_interface_library(rocprofiler-systems-lto + "Adds link-time-optimization flags" +) + +if(NOT ROCPROFSYS_BUILD_CODECOV) + rocprofiler_systems_save_variables(FLTO VARIABLES CMAKE_CXX_FLAGS) + set(_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "-flto=thin ${_CXX_FLAGS}") + + add_target_flag_if_avail(rocprofiler-systems-lto "-flto=thin") + if(NOT cxx_rocprofiler_systems_lto_flto_thin) + set(CMAKE_CXX_FLAGS "-flto ${_CXX_FLAGS}") + add_target_flag_if_avail(rocprofiler-systems-lto "-flto") + if(NOT cxx_rocprofiler_systems_lto_flto) + set(ROCPROFSYS_BUILD_LTO OFF) + else() + target_link_options(rocprofiler-systems-lto INTERFACE -flto) + endif() + add_target_flag_if_avail(rocprofiler-systems-lto "-fno-fat-lto-objects") + if(cxx_rocprofiler_systems_lto_fno_fat_lto_objects) + target_link_options(rocprofiler-systems-lto INTERFACE -fno-fat-lto-objects) + endif() + else() + target_link_options(rocprofiler-systems-lto INTERFACE -flto=thin) + endif() + + rocprofiler_systems_restore_variables(FLTO VARIABLES CMAKE_CXX_FLAGS) +endif() + +# ----------------------------------------------------------------------------------------# +# print compilation timing reports (Clang compiler) +# +rocprofiler_systems_add_interface_library( + rocprofiler-systems-compile-timing + "Adds compiler flags which report compilation timing metrics" +) +if(CMAKE_CXX_COMPILER_IS_CLANG) + add_target_flag_if_avail(rocprofiler-systems-compile-timing "-ftime-trace") + if(NOT cxx_rocprofiler_systems_compile_timing_ftime_trace) + add_target_flag_if_avail(rocprofiler-systems-compile-timing "-ftime-report") + endif() +else() + add_target_flag_if_avail(rocprofiler-systems-compile-timing "-ftime-report") +endif() + +if(ROCPROFSYS_USE_COMPILE_TIMING) + target_link_libraries( + rocprofiler-systems-compile-options + INTERFACE rocprofiler-systems-compile-timing + ) +endif() + +# ----------------------------------------------------------------------------------------# +# fstack-protector +# +rocprofiler_systems_add_interface_library(rocprofiler-systems-stack-protector + "Adds stack-protector compiler flags" +) +add_target_flag_if_avail(rocprofiler-systems-stack-protector "-fstack-protector-strong" + "-Wstack-protector" +) + +if(ROCPROFSYS_BUILD_STACK_PROTECTOR) + target_link_libraries( + rocprofiler-systems-compile-options + INTERFACE rocprofiler-systems-stack-protector + ) +endif() + +# ----------------------------------------------------------------------------------------# +# developer build flags +# +if(ROCPROFSYS_BUILD_DEVELOPER) + add_target_flag_if_avail( + rocprofiler-systems-compile-options "-Werror" "-Wdouble-promotion" "-Wshadow" + "-Wextra" "-Wpedantic" "-Wstack-usage=524288" # 512 KB + "/showIncludes" + ) + if(ROCPROFSYS_BUILD_NUMBER GREATER 2) + add_target_flag_if_avail(rocprofiler-systems-compile-options "-gsplit-dwarf") + endif() +endif() + +if(ROCPROFSYS_BUILD_LINKER) + target_link_options( + rocprofiler-systems-compile-options + INTERFACE + $<$:-fuse-ld=${ROCPROFSYS_BUILD_LINKER}> + $<$:-fuse-ld=${ROCPROFSYS_BUILD_LINKER}> + ) +endif() + +# ----------------------------------------------------------------------------------------# +# release build flags +# +if(ROCPROFSYS_BUILD_RELEASE AND NOT ROCPROFSYS_BUILD_DEBUG) + add_target_flag_if_avail( + rocprofiler-systems-compile-options "-g1" "-feliminate-unused-debug-symbols" + "-gno-column-info" "-gno-variable-location-views" "-gline-tables-only" + ) +endif() + +# ----------------------------------------------------------------------------------------# +# visibility build flags +# +rocprofiler_systems_add_interface_library(rocprofiler-systems-default-visibility + "Adds -fvisibility=default compiler flag" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-hidden-visibility + "Adds -fvisibility=hidden compiler flag" +) + +add_target_flag_if_avail(rocprofiler-systems-default-visibility "-fvisibility=default") +add_target_flag_if_avail(rocprofiler-systems-hidden-visibility "-fvisibility=hidden" + "-fvisibility-inlines-hidden" +) + +# ----------------------------------------------------------------------------------------# +# developer build flags +# +if(dl_LIBRARY) + # 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. + add_flag_if_avail("-rdynamic") +endif() + +# ----------------------------------------------------------------------------------------# +# sanitizer +# +set(ROCPROFSYS_SANITIZER_TYPES + address + memory + thread + leak + undefined + unreachable + null + bounds + alignment +) +set_property( + CACHE ROCPROFSYS_SANITIZER_TYPE + PROPERTY STRINGS "${ROCPROFSYS_SANITIZER_TYPES}" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-sanitizer-compile-options + "Adds compiler flags for sanitizers" +) +rocprofiler_systems_add_interface_library( + rocprofiler-systems-sanitizer + "Adds compiler flags to enable ${ROCPROFSYS_SANITIZER_TYPE} sanitizer (-fsanitizer=${ROCPROFSYS_SANITIZER_TYPE})" +) + +set(COMMON_SANITIZER_FLAGS + "-fno-optimize-sibling-calls" + "-fno-omit-frame-pointer" + "-fno-inline-functions" +) +add_target_flag(rocprofiler-systems-sanitizer-compile-options ${COMMON_SANITIZER_FLAGS}) + +foreach(_TYPE ${ROCPROFSYS_SANITIZER_TYPES}) + set(_FLAG "-fsanitize=${_TYPE}") + rocprofiler_systems_add_interface_library( + rocprofiler-systems-${_TYPE}-sanitizer + "Adds compiler flags to enable ${_TYPE} sanitizer (${_FLAG})" + ) + add_target_flag(rocprofiler-systems-${_TYPE}-sanitizer ${_FLAG}) + target_link_libraries( + rocprofiler-systems-${_TYPE}-sanitizer + INTERFACE rocprofiler-systems-sanitizer-compile-options + ) + set_property( + TARGET rocprofiler-systems-${_TYPE}-sanitizer + PROPERTY INTERFACE_LINK_OPTIONS ${_FLAG} ${COMMON_SANITIZER_FLAGS} + ) +endforeach() + +unset(_FLAG) +unset(COMMON_SANITIZER_FLAGS) + +if(ROCPROFSYS_USE_SANITIZER) + foreach(_TYPE ${ROCPROFSYS_SANITIZER_TYPE}) + if(TARGET rocprofiler-systems-${_TYPE}-sanitizer) + target_link_libraries( + rocprofiler-systems-sanitizer + INTERFACE rocprofiler-systems-${_TYPE}-sanitizer + ) + else() + message( + FATAL_ERROR + "Error! Target 'rocprofiler-systems-${_TYPE}-sanitizer' does not exist!" + ) + endif() + endforeach() +else() + set(ROCPROFSYS_USE_SANITIZER OFF) +endif() + +# ----------------------------------------------------------------------------------------# +# static lib flags +# +target_compile_options( + rocprofiler-systems-static-libgcc + INTERFACE + $<$:$<$:-static-libgcc>> + $<$:$<$:-static-libgcc>> +) +target_link_options( + rocprofiler-systems-static-libgcc + INTERFACE + $<$:$<$:-static-libgcc>> + $<$:$<$:-static-libgcc>> +) + +target_compile_options( + rocprofiler-systems-static-libstdcxx + INTERFACE $<$:$<$:-static-libstdc++>> +) +target_link_options( + rocprofiler-systems-static-libstdcxx + INTERFACE $<$:$<$:-static-libstdc++>> +) + +if(ROCPROFSYS_BUILD_STATIC_LIBGCC) + target_link_libraries( + rocprofiler-systems-static-libgcc-optional + INTERFACE rocprofiler-systems-static-libgcc + ) +endif() + +if(ROCPROFSYS_BUILD_STATIC_LIBSTDCXX) + target_link_libraries( + rocprofiler-systems-static-libstdcxx-optional + INTERFACE rocprofiler-systems-static-libstdcxx + ) +endif() + +# ----------------------------------------------------------------------------------------# +# user customization +# +get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + +if(NOT APPLE OR "$ENV{CONDA_PYTHON_EXE}" STREQUAL "") + add_user_flags(rocprofiler-systems-compile-options "CXX") +endif() diff --git a/projects/rocprofiler-systems/cmake/Compilers.cmake b/projects/rocprofiler-systems/cmake/Compilers.cmake new file mode 100644 index 0000000000..2c9d1a7c79 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Compilers.cmake @@ -0,0 +1,619 @@ +# include guard +# ######################################################################################## +# +# Compilers +# +# ######################################################################################## +# +# sets (cached): +# +# CMAKE_C_COMPILER_IS_ CMAKE_CXX_COMPILER_IS_ +# +# 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(MacroUtilities) + +if("${LIBNAME}" STREQUAL "") + string(TOLOWER "${PROJECT_NAME}" LIBNAME) +endif() + +if(NOT TARGET ${LIBNAME}-compile-options) + rocprofiler_systems_add_interface_library( + ${LIBNAME}-compile-options + "Adds the standard set of compiler flags used by timemory" + ) +endif() + +# ----------------------------------------------------------------------------------------# +# macro converting string to list +# ----------------------------------------------------------------------------------------# +macro(to_list _VAR _STR) + string(REPLACE " " " " ${_VAR} "${_STR}") + string(REPLACE " " ";" ${_VAR} "${_STR}") +endmacro(to_list _VAR _STR) + +# ----------------------------------------------------------------------------------------# +# macro converting string to list +# ----------------------------------------------------------------------------------------# +macro(to_string _VAR _STR) + string(REPLACE ";" " " ${_VAR} "${_STR}") +endmacro(to_string _VAR _STR) + +# ----------------------------------------------------------------------------------------# +# 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() + +# ----------------------------------------------------------------------------------------# +# macro to remove duplicates from string +# ----------------------------------------------------------------------------------------# +macro(set_no_duplicates _VAR) + if(NOT "${ARGN}" STREQUAL "") + set(${_VAR} "${ARGN}") + endif() + # remove the duplicates + if(NOT "${${_VAR}}" STREQUAL "") + # create list of flags + to_list(_VAR_LIST "${${_VAR}}") + list(REMOVE_DUPLICATES _VAR_LIST) + to_string(${_VAR} "${_VAR_LIST}") + endif(NOT "${${_VAR}}" STREQUAL "") +endmacro(set_no_duplicates _VAR) + +# ----------------------------------------------------------------------------------------# +# call before running check_{c,cxx}_compiler_flag +# ----------------------------------------------------------------------------------------# +macro(rocprofiler_systems_begin_flag_check) + if(ROCPROFSYS_QUIET_CONFIG) + if(NOT DEFINED CMAKE_REQUIRED_QUIET) + set(CMAKE_REQUIRED_QUIET OFF) + endif() + rocprofiler_systems_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_systems_end_flag_check) + if(ROCPROFSYS_QUIET_CONFIG) + rocprofiler_systems_restore_variables(FLAG_CHECK VARIABLES CMAKE_REQUIRED_QUIET) + endif() +endmacro() + +# ######################################################################################## +# +# C compiler flags +# +# ######################################################################################## + +# ----------------------------------------------------------------------------------------# +# add C flag to target +# ----------------------------------------------------------------------------------------# +macro(ADD_TARGET_C_FLAG _TARG) + get_target_property(_TARG_TYPE ${_TARG} TYPE) + if("${_TARG_TYPE}" MATCHES "INTERFACE_LIBRARY") + set(_SCOPE INTERFACE) + else() + set(_SCOPE PRIVATE) + endif() + + string(REPLACE "-" "_" _MAKE_TARG "${_TARG}") + list(APPEND ROCPROFSYS_MAKE_TARGETS ${_MAKE_TARG}) + + target_compile_options(${_TARG} ${_SCOPE} $<$:${ARGN}>) + list(APPEND ${_MAKE_TARG}_C_FLAGS ${ARGN}) +endmacro() + +# ----------------------------------------------------------------------------------------# +# add C flag w/o check +# ----------------------------------------------------------------------------------------# +macro(ADD_C_FLAG FLAG) + set(_TARG) + set(_LTARG) + if(NOT "${ARGN}" STREQUAL "") + set(_TARG ${ARGN}) + string(TOLOWER "_${ARGN}" _LTARG) + endif() + if(NOT "${FLAG}" STREQUAL "") + if("${_LTARG}" STREQUAL "") + list(APPEND ${PROJECT_NAME}_C_FLAGS "${FLAG}") + list(APPEND ${PROJECT_NAME}_C_COMPILE_OPTIONS "${FLAG}") + add_target_c_flag(${LIBNAME}-compile-options ${FLAG}) + else() + add_target_c_flag(${_TARG} ${FLAG}) + endif() + endif() + unset(_TARG) + unset(_LTARG) +endmacro() + +# ----------------------------------------------------------------------------------------# +# check C flag +# ----------------------------------------------------------------------------------------# +macro(ADD_C_FLAG_IF_AVAIL FLAG) + set(_ENABLE ON) + if(DEFINED ROCPROFSYS_BUILD_C AND NOT ROCPROFSYS_BUILD_C) + set(_ENABLE OFF) + endif() + set(_TARG) + set(_LTARG) + if(NOT "${ARGN}" STREQUAL "") + set(_TARG ${ARGN}) + string(TOLOWER "_${ARGN}" _LTARG) + endif() + if(NOT "${FLAG}" STREQUAL "") + string(REGEX REPLACE "^/" "c${_LTARG}_" FLAG_NAME "${FLAG}") + string(REGEX REPLACE "^-" "c${_LTARG}_" FLAG_NAME "${FLAG_NAME}") + string(REPLACE "-" "_" FLAG_NAME "${FLAG_NAME}") + string(REPLACE " " "_" FLAG_NAME "${FLAG_NAME}") + string(REPLACE "=" "_" FLAG_NAME "${FLAG_NAME}") + if(NOT ROCPROFSYS_BUILD_C) + set(${FLAG_NAME} ON) + else() + rocprofiler_systems_begin_flag_check() + check_c_compiler_flag("-Werror" c_werror) + if(c_werror) + check_c_compiler_flag("${FLAG} -Werror" ${FLAG_NAME}) + else() + check_c_compiler_flag("${FLAG}" ${FLAG_NAME}) + endif() + rocprofiler_systems_end_flag_check() + if(${FLAG_NAME}) + if("${_LTARG}" STREQUAL "") + list(APPEND ${PROJECT_NAME}_C_FLAGS "${FLAG}") + list(APPEND ${PROJECT_NAME}_C_COMPILE_OPTIONS "${FLAG}") + add_target_c_flag(${LIBNAME}-compile-options ${FLAG}) + else() + add_target_c_flag(${_TARG} ${FLAG}) + endif() + endif() + endif() + endif() + unset(_TARG) + unset(_LTARG) +endmacro() + +# ----------------------------------------------------------------------------------------# +# add C flag to target +# ----------------------------------------------------------------------------------------# +macro(ADD_TARGET_C_FLAG_IF_AVAIL _TARG) + foreach(_FLAG ${ARGN}) + add_c_flag_if_avail(${_FLAG} ${_TARG}) + endforeach() +endmacro() + +# ######################################################################################## +# +# CXX compiler flags +# +# ######################################################################################## + +# ----------------------------------------------------------------------------------------# +# add CXX flag to target +# ----------------------------------------------------------------------------------------# +macro(ADD_TARGET_CXX_FLAG _TARG) + get_target_property(_TARG_TYPE ${_TARG} TYPE) + if("${_TARG_TYPE}" MATCHES "INTERFACE_LIBRARY") + set(_SCOPE INTERFACE) + else() + set(_SCOPE PRIVATE) + endif() + + string(REPLACE "-" "_" _MAKE_TARG "${_TARG}") + list(APPEND ROCPROFSYS_MAKE_TARGETS ${_MAKE_TARG}) + + target_compile_options(${_TARG} ${_SCOPE} $<$:${ARGN}>) + list(APPEND ${_MAKE_TARG}_CXX_FLAGS ${ARGN}) + get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + if(CMAKE_CUDA_COMPILER_IS_NVIDIA) + target_compile_options( + ${_TARG} + ${_SCOPE} + $<$:-Xcompiler=${ARGN}> + ) + list(APPEND ${_MAKE_TARG}_CUDA_FLAGS -Xcompiler=${ARGN}) + elseif(CMAKE_CUDA_COMPILER_IS_CLANG) + target_compile_options(${_TARG} ${_SCOPE} $<$:${ARGN}>) + list(APPEND ${_MAKE_TARG}_CUDA_FLAGS ${ARGN}) + endif() +endmacro() + +# ----------------------------------------------------------------------------------------# +# add CXX flag w/o check +# ----------------------------------------------------------------------------------------# +macro(ADD_CXX_FLAG FLAG) + set(_TARG) + set(_LTARG) + if(NOT "${ARGN}" STREQUAL "") + set(_TARG ${ARGN}) + string(TOLOWER "_${ARGN}" _LTARG) + endif() + if(NOT "${FLAG}" STREQUAL "") + if("${_LTARG}" STREQUAL "") + list(APPEND ${PROJECT_NAME}_CXX_FLAGS "${FLAG}") + list(APPEND ${PROJECT_NAME}_CXX_COMPILE_OPTIONS "${FLAG}") + add_target_cxx_flag(${LIBNAME}-compile-options ${FLAG}) + else() + add_target_cxx_flag(${_TARG} ${FLAG}) + endif() + endif() + unset(_TARG) + unset(_LTARG) +endmacro() + +# ----------------------------------------------------------------------------------------# +# check CXX flag +# ----------------------------------------------------------------------------------------# +macro(ADD_CXX_FLAG_IF_AVAIL FLAG) + set(_TARG) + set(_LTARG) + if(NOT "${ARGN}" STREQUAL "") + set(_TARG ${ARGN}) + string(TOLOWER "_${ARGN}" _LTARG) + endif() + if(NOT "${FLAG}" STREQUAL "") + string(REGEX REPLACE "^/" "cxx${_LTARG}_" FLAG_NAME "${FLAG}") + string(REGEX REPLACE "^-" "cxx${_LTARG}_" FLAG_NAME "${FLAG_NAME}") + string(REPLACE "-" "_" FLAG_NAME "${FLAG_NAME}") + string(REPLACE " " "_" FLAG_NAME "${FLAG_NAME}") + string(REPLACE "=" "_" FLAG_NAME "${FLAG_NAME}") + string(REPLACE "/" "_" FLAG_NAME "${FLAG_NAME}") + rocprofiler_systems_begin_flag_check() + check_cxx_compiler_flag("-Werror" cxx_werror) + if(cxx_werror) + check_cxx_compiler_flag("${FLAG} -Werror" ${FLAG_NAME}) + else() + check_cxx_compiler_flag("${FLAG}" ${FLAG_NAME}) + endif() + rocprofiler_systems_end_flag_check() + if(${FLAG_NAME}) + if("${_LTARG}" STREQUAL "") + list(APPEND ${PROJECT_NAME}_CXX_FLAGS "${FLAG}") + list(APPEND ${PROJECT_NAME}_CXX_COMPILE_OPTIONS "${FLAG}") + add_target_cxx_flag(${LIBNAME}-compile-options ${FLAG}) + else() + add_target_cxx_flag(${_TARG} ${FLAG}) + endif() + endif() + endif() + unset(_TARG) + unset(_LTARG) +endmacro() + +# ----------------------------------------------------------------------------------------# +# add CXX flag to target +# ----------------------------------------------------------------------------------------# +macro(ADD_TARGET_CXX_FLAG_IF_AVAIL _TARG) + foreach(_FLAG ${ARGN}) + add_cxx_flag_if_avail(${_FLAG} ${_TARG}) + endforeach() +endmacro() + +# ######################################################################################## +# +# Common +# +# ######################################################################################## + +# ----------------------------------------------------------------------------------------# +# check C and CXX flag to compile-options w/o checking +# ----------------------------------------------------------------------------------------# +macro(ADD_FLAG) + foreach(_ARG ${ARGN}) + add_c_flag("${_ARG}") + add_cxx_flag("${_ARG}") + endforeach() +endmacro() + +# ----------------------------------------------------------------------------------------# +# add C and CXX flag w/o checking +# ----------------------------------------------------------------------------------------# +macro(ADD_TARGET_FLAG _TARG) + foreach(_ARG ${ARGN}) + add_target_c_flag(${_TARG} ${_ARG}) + add_target_cxx_flag(${_TARG} ${_ARG}) + endforeach() +endmacro() + +# ----------------------------------------------------------------------------------------# +# check C and CXX flag +# ----------------------------------------------------------------------------------------# +macro(ADD_FLAG_IF_AVAIL) + foreach(_ARG ${ARGN}) + add_c_flag_if_avail("${_ARG}") + add_cxx_flag_if_avail("${_ARG}") + endforeach() +endmacro() + +# ----------------------------------------------------------------------------------------# +# check C and CXX flag +# ----------------------------------------------------------------------------------------# +macro(ADD_TARGET_FLAG_IF_AVAIL _TARG) + foreach(_ARG ${ARGN}) + add_target_c_flag_if_avail(${_TARG} ${_ARG}) + add_target_cxx_flag_if_avail(${_TARG} ${_ARG}) + endforeach() +endmacro() + +# ----------------------------------------------------------------------------------------# +# check flag +# ----------------------------------------------------------------------------------------# +function(ROCPROFILER_SYSTEMS_TARGET_FLAG _TARG_TARGET) + cmake_parse_arguments(_TARG "IF_AVAIL" "MODE" "FLAGS;LANGUAGES" ${ARGN}) + + if(NOT _TARG_MODE) + set(_TARG_MODE INTERFACE) + endif() + + get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + + if(NOT _TARG_LANGUAGES) + get_property(_TARG_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + endif() + + string(TOLOWER "_${_TARG_TARGET}" _LTARG) + + foreach(_FLAG ${_TARG_FLAGS}) + foreach(_LANG ${_TARG_LANGUAGES}) + if(NOT _TARG_IF_AVAIL) + target_compile_options( + ${_TARG_TARGET} + ${_TARG_MODE} + $<$:${_FLAG}> + ) + continue() + endif() + + if("${_LANG}" STREQUAL "C") + string(REGEX REPLACE "^/" "c${_LTARG}_" FLAG_NAME "${_FLAG}") + string(REGEX REPLACE "^-" "c${_LTARG}_" FLAG_NAME "${FLAG_NAME}") + string(REPLACE "-" "_" FLAG_NAME "${FLAG_NAME}") + string(REPLACE " " "_" FLAG_NAME "${FLAG_NAME}") + string(REPLACE "=" "_" FLAG_NAME "${FLAG_NAME}") + rocprofiler_systems_begin_flag_check() + check_c_compiler_flag("-Werror" c_werror) + if(c_werror) + check_c_compiler_flag("${FLAG} -Werror" ${FLAG_NAME}) + else() + check_c_compiler_flag("${FLAG}" ${FLAG_NAME}) + endif() + rocprofiler_systems_end_flag_check() + if(${FLAG_NAME}) + target_compile_options( + ${_TARG_TARGET} + ${_TARG_MODE} + $<$:${_FLAG}> + ) + endif() + elseif("${_LANG}" STREQUAL "CXX") + string(REGEX REPLACE "^/" "cxx${_LTARG}_" FLAG_NAME "${_FLAG}") + string(REGEX REPLACE "^-" "cxx${_LTARG}_" FLAG_NAME "${FLAG_NAME}") + string(REPLACE "-" "_" FLAG_NAME "${FLAG_NAME}") + string(REPLACE " " "_" FLAG_NAME "${FLAG_NAME}") + string(REPLACE "=" "_" FLAG_NAME "${FLAG_NAME}") + rocprofiler_systems_begin_flag_check() + check_cxx_compiler_flag("-Werror" cxx_werror) + if(cxx_werror) + check_cxx_compiler_flag("${FLAG} -Werror" ${FLAG_NAME}) + else() + check_cxx_compiler_flag("${FLAG}" ${FLAG_NAME}) + endif() + rocprofiler_systems_end_flag_check() + if(${FLAG_NAME}) + target_compile_options( + ${_TARG_TARGET} + ${_TARG_MODE} + $<$:${_FLAG}> + ) + if(CMAKE_CUDA_COMPILER_IS_NVIDIA) + target_compile_options( + ${_TARG_TARGET} + ${_TARG_MODE} + $<$:-Xcompiler=${_FLAG}> + ) + elseif(CMAKE_CUDA_COMPILER_IS_CLANG) + target_compile_options( + ${_TARG_TARGET} + ${_TARG_MODE} + $<$:${_FLAG}> + ) + endif() + endif() + endif() + endforeach() + endforeach() +endfunction() + +# ----------------------------------------------------------------------------------------# +# add CUDA flag to target +# ----------------------------------------------------------------------------------------# +macro(ADD_TARGET_CUDA_FLAG _TARG) + string(REPLACE "-" "_" _MAKE_TARG "${_TARG}") + list(APPEND ROCPROFSYS_MAKE_TARGETS ${_MAKE_TARG}) + + target_compile_options(${_TARG} INTERFACE $<$:${ARGN}>) + list(APPEND ${_MAKE_TARG}_CUDA_FLAGS ${ARGN}) +endmacro() + +# ----------------------------------------------------------------------------------------# +# add to any language +# ----------------------------------------------------------------------------------------# +function(ADD_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 $<$:${_FLAGS}> + ) +endfunction() + +# ----------------------------------------------------------------------------------------# +# add compiler definition +# ----------------------------------------------------------------------------------------# +function(ROCPROFILER_SYSTEMS_TARGET_COMPILE_DEFINITIONS _TARG _VIS) + foreach(_DEF ${ARGN}) + if(NOT "${_DEF}" MATCHES "[A-Za-z_]+=.*" AND "${_DEF}" MATCHES "^ROCPROFSYS_") + set(_DEF "${_DEF}=1") + endif() + target_compile_definitions(${_TARG} ${_VIS} $<$:${_DEF}>) + if(CMAKE_CUDA_COMPILER_IS_NVIDIA) + target_compile_definitions( + ${_TARG} + ${_VIS} + $<$:${_DEF}> + ) + elseif(CMAKE_CUDA_COMPILER_IS_CLANG) + target_compile_definitions( + ${_TARG} + ${_VIS} + $<$:${_DEF}> + ) + endif() + endforeach() +endfunction() + +# ----------------------------------------------------------------------------------------# +# determine compiler types for each language +# ----------------------------------------------------------------------------------------# +get_property(ENABLED_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) +foreach(LANG C CXX 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() diff --git a/projects/rocprofiler-systems/cmake/ConfigCPack.cmake b/projects/rocprofiler-systems/cmake/ConfigCPack.cmake new file mode 100644 index 0000000000..35e68e5fed --- /dev/null +++ b/projects/rocprofiler-systems/cmake/ConfigCPack.cmake @@ -0,0 +1,347 @@ +# configure packaging + +function(rocprofiler_systems_parse_release) + if(EXISTS /etc/lsb-release AND NOT IS_DIRECTORY /etc/lsb-release) + file(READ /etc/lsb-release _LSB_RELEASE) + if(_LSB_RELEASE) + string( + REGEX REPLACE + "DISTRIB_ID=(.*)\nDISTRIB_RELEASE=(.*)\nDISTRIB_CODENAME=.*" + "\\1-\\2" + _SYSTEM_NAME + "${_LSB_RELEASE}" + ) + endif() + elseif(EXISTS /etc/os-release AND NOT IS_DIRECTORY /etc/os-release) + file(READ /etc/os-release _OS_RELEASE) + if(_OS_RELEASE) + string(REPLACE "\"" "" _OS_RELEASE "${_OS_RELEASE}") + string(REPLACE "-" " " _OS_RELEASE "${_OS_RELEASE}") + string( + REGEX REPLACE + "NAME=.*\nVERSION=([0-9\.]+).*\nID=([a-z]+).*" + "\\2-\\1" + _SYSTEM_NAME + "${_OS_RELEASE}" + ) + endif() + endif() + string(TOLOWER "${_SYSTEM_NAME}" _SYSTEM_NAME) + if(NOT _SYSTEM_NAME) + set(_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}") + endif() + set(_SYSTEM_NAME "${_SYSTEM_NAME}" PARENT_SCOPE) +endfunction() + +# parse either /etc/lsb-release or /etc/os-release +rocprofiler_systems_parse_release() + +if(NOT _SYSTEM_NAME) + set(_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}") +endif() + +# Add packaging directives +set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) +set(CPACK_PACKAGE_VENDOR "Advanced Micro Devices, Inc.") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY + "Runtime instrumentation and binary rewriting for Perfetto via Dyninst" +) +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 "https://github.com/ROCm/rocprofiler-systems") +set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE") +set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF) + +# For handling the project rebranding from "omnitrace" to "rocprofiler-systems" +set(OMNITRACE_PACKAGE_NAME "omnitrace") + +set(ROCPROFSYS_CPACK_SYSTEM_NAME + "${_SYSTEM_NAME}" + CACHE STRING + "System name, e.g. Linux or Ubuntu-20.04" +) +set(ROCPROFSYS_CPACK_PACKAGE_SUFFIX "") + +if(ROCPROFSYS_USE_ROCM) + set(ROCPROFSYS_CPACK_PACKAGE_SUFFIX + "${ROCPROFSYS_CPACK_PACKAGE_SUFFIX}-ROCm-${ROCmVersion_NUMERIC_VERSION}" + ) +endif() + +if(ROCPROFSYS_USE_PAPI) + set(ROCPROFSYS_CPACK_PACKAGE_SUFFIX "${ROCPROFSYS_CPACK_PACKAGE_SUFFIX}-PAPI") +endif() + +if(ROCPROFSYS_USE_OMPT) + set(ROCPROFSYS_CPACK_PACKAGE_SUFFIX "${ROCPROFSYS_CPACK_PACKAGE_SUFFIX}-OMPT") +endif() + +if(ROCPROFSYS_USE_MPI) + set(VALID_MPI_IMPLS "mpich" "openmpi") + if("${MPI_C_COMPILER_INCLUDE_DIRS};${MPI_C_HEADER_DIR}" MATCHES "openmpi") + set(ROCPROFSYS_MPI_IMPL "openmpi") + elseif("${MPI_C_COMPILER_INCLUDE_DIRS};${MPI_C_HEADER_DIR}" MATCHES "mpich") + set(ROCPROFSYS_MPI_IMPL "mpich") + else() + message( + WARNING + "MPI implementation could not be determined. Please set ROCPROFSYS_MPI_IMPL to one of the following for CPack: ${VALID_MPI_IMPLS}" + ) + endif() + if(ROCPROFSYS_MPI_IMPL AND NOT "${ROCPROFSYS_MPI_IMPL}" IN_LIST VALID_MPI_IMPLS) + message( + SEND_ERROR + "Invalid ROCPROFSYS_MPI_IMPL (${ROCPROFSYS_MPI_IMPL}). Should be one of: ${VALID_MPI_IMPLS}" + ) + else() + rocprofiler_systems_add_feature(ROCPROFSYS_MPI_IMPL + "MPI implementation for CPack DEBIAN depends" + ) + endif() + + if("${ROCPROFSYS_MPI_IMPL}" STREQUAL "openmpi") + set(ROCPROFSYS_MPI_IMPL_UPPER "OpenMPI") + elseif("${ROCPROFSYS_MPI_IMPL}" STREQUAL "mpich") + set(ROCPROFSYS_MPI_IMPL_UPPER "MPICH") + else() + set(ROCPROFSYS_MPI_IMPL_UPPER "MPI") + endif() + set(ROCPROFSYS_CPACK_PACKAGE_SUFFIX + "${ROCPROFSYS_CPACK_PACKAGE_SUFFIX}-${ROCPROFSYS_MPI_IMPL_UPPER}" + ) +endif() + +if(ROCPROFSYS_USE_PYTHON) + set(_ROCPROFSYS_PYTHON_NAME "Python3") + foreach(_VER ${ROCPROFSYS_PYTHON_VERSIONS}) + if("${_VER}" VERSION_LESS 3.0.0) + set(_ROCPROFSYS_PYTHON_NAME "Python") + endif() + endforeach() + set(ROCPROFSYS_CPACK_PACKAGE_SUFFIX "${ROCPROFSYS_CPACK_PACKAGE_SUFFIX}-Python3") +endif() + +set(CPACK_PACKAGE_FILE_NAME + "${CPACK_PACKAGE_NAME}-${ROCPROFSYS_VERSION}-${ROCPROFSYS_CPACK_SYSTEM_NAME}${ROCPROFSYS_CPACK_PACKAGE_SUFFIX}" +) +if(DEFINED ENV{CPACK_PACKAGE_FILE_NAME}) + set(CPACK_PACKAGE_FILE_NAME $ENV{CPACK_PACKAGE_FILE_NAME}) +endif() + +set(ROCPROFSYS_PACKAGE_FILE_NAME + ${CPACK_PACKAGE_NAME}-${ROCPROFSYS_VERSION}-${ROCPROFSYS_CPACK_SYSTEM_NAME}${ROCPROFSYS_CPACK_PACKAGE_SUFFIX} +) +rocprofiler_systems_add_feature(ROCPROFSYS_PACKAGE_FILE_NAME "CPack filename") + +if(ROCM_DEP_ROCMCORE OR ROCPROFILER_DEP_ROCMCORE) + set(_DEBIAN_PACKAGE_DEPENDS "rocm-core") + set(_RPM_PACKAGE_REQUIRES "rocm-core") +else() + set(_DEBIAN_PACKAGE_DEPENDS "") + set(_RPM_PACKAGE_REQUIRES "") +endif() + +# -------------------------------------------------------------------------------------- # +# +# Debian package specific variables +# +# -------------------------------------------------------------------------------------- # + +set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/ROCm/rocprofiler-systems") +set(CPACK_DEBIAN_PACKAGE_RELEASE + "${ROCPROFSYS_CPACK_SYSTEM_NAME}${ROCPROFSYS_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(ROCPROFSYS_USE_PAPI AND NOT ROCPROFSYS_BUILD_PAPI) + list(APPEND _DEBIAN_PACKAGE_DEPENDS libpapi-dev libpfm4) +endif() +if(NOT ROCPROFSYS_BUILD_DYNINST) + if(NOT ROCPROFSYS_BUILD_BOOST) + foreach( + _BOOST_COMPONENT + atomic + system + thread + date-time + filesystem + timer + ) + list( + APPEND + _DEBIAN_PACKAGE_DEPENDS + "libboost-${_BOOST_COMPONENT}-dev (>= 1.67.0)" + ) + endforeach() + endif() + if(NOT ROCPROFSYS_BUILD_TBB) + list(APPEND _DEBIAN_PACKAGE_DEPENDS "libtbb-dev (>= 2018.6)") + endif() + if(NOT ROCPROFSYS_BUILD_LIBIBERTY) + list(APPEND _DEBIAN_PACKAGE_DEPENDS "libiberty-dev (>= 20170913)") + endif() +endif() +if(ROCmVersion_FOUND) + set(_AMD_SMI_SUFFIX + " (>= ${ROCmVersion_MAJOR_VERSION}.0.0.${ROCmVersion_NUMERIC_VERSION})" + ) +endif() +if(ROCPROFSYS_USE_ROCM) + list(APPEND _DEBIAN_PACKAGE_DEPENDS "amd-smi-lib${_AMD_SMI_SUFFIX}") + list(APPEND _DEBIAN_PACKAGE_DEPENDS "rocprofiler-sdk (>= ${rocprofiler-sdk_VERSION})") +endif() +if(ROCPROFSYS_USE_MPI) + if("${ROCPROFSYS_MPI_IMPL}" STREQUAL "openmpi") + list(APPEND _DEBIAN_PACKAGE_DEPENDS "libopenmpi-dev") + elseif("${ROCPROFSYS_MPI_IMPL}" STREQUAL "mpich") + list(APPEND _DEBIAN_PACKAGE_DEPENDS "libmpich-dev") + endif() +endif() +if(ROCPROFSYS_BUILD_TESTING) + list(APPEND _DEBIAN_PACKAGE_DEPENDS "rocdecode-test") + list(APPEND _DEBIAN_PACKAGE_DEPENDS "rocjpeg-test") +endif() +string(REPLACE ";" ", " _DEBIAN_PACKAGE_DEPENDS "${_DEBIAN_PACKAGE_DEPENDS}") +set(CPACK_DEBIAN_PACKAGE_DEPENDS + "${_DEBIAN_PACKAGE_DEPENDS}" + CACHE STRING + "Debian package dependencies" + FORCE +) + +set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT") +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + +# Handle the project rebranding from "omnitrace" to "rocprofiler-systems" +set(CPACK_DEBIAN_PACKAGE_PROVIDES ${OMNITRACE_PACKAGE_NAME}) +set(CPACK_DEBIAN_PACKAGE_REPLACES ${OMNITRACE_PACKAGE_NAME}) +set(CPACK_DEBIAN_PACKAGE_BREAKS ${OMNITRACE_PACKAGE_NAME}) + +# -------------------------------------------------------------------------------------- # +# +# 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 + "${ROCPROFSYS_CPACK_SYSTEM_NAME}${ROCPROFSYS_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}") + +# Handle the project rebranding from "omnitrace" to "rocprofiler-systems" +set(CPACK_RPM_PACKAGE_OBSOLETES "${OMNITRACE_PACKAGE_NAME} <= 1.13.0") +set(CPACK_RPM_PACKAGE_CONFLICTS ${OMNITRACE_PACKAGE_NAME}) +set(_RPM_PACKAGE_PROVIDES ${OMNITRACE_PACKAGE_NAME}) + +if(ROCPROFSYS_BUILD_LIBUNWIND) + list(APPEND _RPM_PACKAGE_PROVIDES "libunwind.so.99()(64bit)") + list(APPEND _RPM_PACKAGE_PROVIDES "libunwind-x86_64.so.99()(64bit)") + list(APPEND _RPM_PACKAGE_PROVIDES "libunwind-setjmp.so.0()(64bit)") + list(APPEND _RPM_PACKAGE_PROVIDES "libunwind-ptrace.so.0()(64bit)") +endif() + +string(REPLACE ";" ", " CPACK_RPM_PACKAGE_PROVIDES "${_RPM_PACKAGE_PROVIDES}") +set(CPACK_RPM_PACKAGE_PROVIDES + "${CPACK_RPM_PACKAGE_PROVIDES}" + CACHE STRING + "RPM package provides" + FORCE +) + +if(ROCPROFSYS_USE_MPI) + if("${ROCPROFSYS_MPI_IMPL}" STREQUAL "openmpi") + list(APPEND _RPM_PACKAGE_REQUIRES "libopenmpi-devel") + elseif("${ROCPROFSYS_MPI_IMPL}" STREQUAL "mpich") + list(APPEND _RPM_PACKAGE_REQUIRES "libmpich-devel") + endif() +endif() + +if(ROCPROFSYS_USE_ROCM) + if(ROCPROFSYS_BUILD_TESTING) + list(APPEND _RPM_PACKAGE_REQUIRES "rocdecode-test") + list(APPEND _RPM_PACKAGE_REQUIRES "rocjpeg-test") + endif() +endif() + +string(REPLACE ";" ", " _RPM_PACKAGE_REQUIRES "${_RPM_PACKAGE_REQUIRES}") +set(CPACK_RPM_PACKAGE_REQUIRES + ${_RPM_PACKAGE_REQUIRES} + CACHE STRING + "RPM package requires" + FORCE +) +set(CPACK_RPM_SPEC_MORE_DEFINE "%undefine __brp_mangle_shebangs") +set(CPACK_RPM_PACKAGE_LICENSE "MIT") +set(CPACK_RPM_FILE_NAME "RPM-DEFAULT") +set(CPACK_RPM_PACKAGE_RELEASE_DIST ON) +set(CPACK_RPM_PACKAGE_AUTOPROV ON) +set(CPACK_RPM_PACKAGE_AUTOREQ ON) + +# -------------------------------------------------------------------------------------- # +# +# Prepare final CPACK parameters +# +# -------------------------------------------------------------------------------------- # + +set(CPACK_PACKAGE_VERSION + "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}" +) + +if(DEFINED ENV{ROCM_LIBPATCH_VERSION}) + set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}.$ENV{ROCM_LIBPATCH_VERSION}") +endif() + +if(DEFINED ENV{CPACK_DEBIAN_PACKAGE_RELEASE}) + set(CPACK_DEBIAN_PACKAGE_RELEASE $ENV{CPACK_DEBIAN_PACKAGE_RELEASE}) +endif() + +if(DEFINED ENV{CPACK_RPM_PACKAGE_RELEASE}) + set(CPACK_RPM_PACKAGE_RELEASE $ENV{CPACK_RPM_PACKAGE_RELEASE}) +endif() + +rocprofiler_systems_add_feature(CPACK_PACKAGE_NAME "Package name") +rocprofiler_systems_add_feature(CPACK_PACKAGE_VERSION "Package version") +rocprofiler_systems_add_feature(CPACK_PACKAGING_INSTALL_PREFIX + "Package installation prefix" +) + +rocprofiler_systems_add_feature(CPACK_DEBIAN_FILE_NAME "Debian file name") +rocprofiler_systems_add_feature(CPACK_DEBIAN_PACKAGE_RELEASE + "Debian package release version" +) +rocprofiler_systems_add_feature(CPACK_DEBIAN_PACKAGE_DEPENDS + "Debian package dependencies" +) +rocprofiler_systems_add_feature(CPACK_DEBIAN_PACKAGE_SHLIBDEPS + "Debian package shared library dependencies" +) + +rocprofiler_systems_add_feature(CPACK_RPM_FILE_NAME "RPM file name") +rocprofiler_systems_add_feature(CPACK_RPM_PACKAGE_RELEASE "RPM package release version") +rocprofiler_systems_add_feature(CPACK_RPM_PACKAGE_AUTOREQPROV + "RPM package auto generate requires and provides" +) +rocprofiler_systems_add_feature(CPACK_RPM_PACKAGE_REQUIRES "RPM package requires") +rocprofiler_systems_add_feature(CPACK_RPM_PACKAGE_PROVIDES "RPM package provides") + +include(CPack) diff --git a/projects/rocprofiler-systems/cmake/ConfigInstall.cmake b/projects/rocprofiler-systems/cmake/ConfigInstall.cmake new file mode 100644 index 0000000000..6274191fda --- /dev/null +++ b/projects/rocprofiler-systems/cmake/ConfigInstall.cmake @@ -0,0 +1,86 @@ +# include guard +include_guard(GLOBAL) + +include(CMakePackageConfigHelpers) + +set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME config) + +install( + EXPORT rocprofiler-systems-library-targets + FILE ${PROJECT_NAME}-library-targets.cmake + NAMESPACE rocprofiler-systems:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} +) + +# ------------------------------------------------------------------------------# +# install tree +# +set(PROJECT_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}) +set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}) +set(LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}) +set(PROJECT_BUILD_TARGETS user) + +configure_package_config_file( + ${PROJECT_SOURCE_DIR}/cmake/Templates/rocprof-sys-config.cmake.in + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} + INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} + PATH_VARS PROJECT_INSTALL_DIR INCLUDE_INSTALL_DIR LIB_INSTALL_DIR +) + +write_basic_package_version_file( + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-version.cmake + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMinorVersion +) + +install( + FILES + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-version.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} + OPTIONAL +) + +export(PACKAGE ${PROJECT_NAME}) + +# ------------------------------------------------------------------------------# +# install the validate-causal-json python script as a utility +# +configure_file( + ${PROJECT_SOURCE_DIR}/tests/validate-causal-json.py + ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/rocprof-sys-causal-print + COPYONLY +) + +install( + PROGRAMS ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}/rocprof-sys-causal-print + DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME} +) + +# ------------------------------------------------------------------------------# +# build tree +# +set(_BUILDTREE_EXPORT_DIR + "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" +) + +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}/${PROJECT_NAME}-library-targets.cmake") + file(TOUCH "${_BUILDTREE_EXPORT_DIR}/${PROJECT_NAME}-library-targets.cmake") +endif() + +export( + EXPORT ${PROJECT_NAME}-library-targets + NAMESPACE rocprofiler-systems:: + FILE "${_BUILDTREE_EXPORT_DIR}/${PROJECT_NAME}-library-targets.cmake" +) + +set(${PROJECT_NAME}_DIR "${_BUILDTREE_EXPORT_DIR}" CACHE PATH "${PROJECT_NAME}" FORCE) diff --git a/projects/rocprofiler-systems/cmake/DyninstBoost.cmake b/projects/rocprofiler-systems/cmake/DyninstBoost.cmake new file mode 100644 index 0000000000..fd3b4d2355 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/DyninstBoost.cmake @@ -0,0 +1,437 @@ +# ======================================================================================================== +# Boost.cmake +# +# Configure Boost for Dyninst +# +# ---------------------------------------- +# +# Accepts the following CMake variables +# +# Boost_ROOT_DIR - Hint directory that contains the Boost installation +# PATH_BOOST - Alias for Boost_ROOT_DIR Boost_MIN_VERSION - Minimum +# acceptable version of Boost Boost_USE_MULTITHREADED - Use the multithreaded version of +# Boost Boost_USE_STATIC_RUNTIME - Use libraries linked statically to the C++ runtime +# +# Options inherited from Modules/FindBoost.cmake that may be useful +# +# BOOST_INCLUDEDIR - Hint directory that contains the Boost headers files +# BOOST_LIBRARYDIR - Hint directory that contains the Boost library files +# +# Advanced options: +# +# Boost_DEBUG - Enable debug output from FindBoost Boost_NO_SYSTEM_PATHS - +# Disable searching in locations not specified by hint variables +# +# Exports the following CMake cache variables +# +# Boost_ROOT_DIR - Computed base directory the of Boost installation +# Boost_INCLUDE_DIRS - Boost include directories Boost_INCLUDE_DIR - Alias for +# Boost_INCLUDE_DIRS Boost_LIBRARY_DIRS - Link directories for Boost libraries +# Boost_DEFINES - Boost compiler definitions Boost_LIBRARIES - Boost +# library files Boost__LIBRARY_RELEASE - Release libraries to link for component +# ( is upper-case) Boost__LIBRARY_DEBUG - Debug libraries to link for component +# Boost_THREAD_LIBRARY - The filename of the Boost thread library +# Boost_USE_MULTITHREADED - Use the multithreaded version of Boost +# Boost_USE_STATIC_RUNTIME - Use libraries linked statically to the C++ runtime +# +# NOTE: The exported Boost_ROOT_DIR can be different from the value provided by the user +# in the case that it is determined to build Boost from source. In such a case, +# Boost_ROOT_DIR will contain the directory of the from-source installation. +# +# See Modules/FindBoost.cmake for additional input and exported variables +# +# ======================================================================================================== + +include_guard(GLOBAL) + +if(NOT BUILD_BOOST) + find_package(Boost) +endif() + +if(Boost_FOUND) + return() +endif() + +# Need at least Boost-1.67 because of deprecated headers +set(_boost_min_version 1.67.0) + +# Provide a default, if the user didn't specify +set(Boost_MIN_VERSION ${_boost_min_version} CACHE STRING "Minimum Boost version") + +# Enforce minimum version +if(${Boost_MIN_VERSION} VERSION_LESS ${_boost_min_version}) + rocprofiler_systems_message( + FATAL_ERROR + "Requested Boost-${Boost_MIN_VERSION} is less than minimum supported version (${_boost_min_version})" + ) +endif() + +# -------------- RUNTIME CONFIGURATION ---------------------------------------- + +# Use the multithreaded version of Boost NB: This _must_ be a cache variable as it +# controls the tagged layout of Boost library names +set(Boost_USE_MULTITHREADED ON CACHE BOOL "Enable multithreaded Boost libraries") + +# Don't use libraries linked statically to the C++ runtime NB: This _must_ be a cache +# variable as it controls the tagged layout of Boost library names +set(Boost_USE_STATIC_RUNTIME + OFF + CACHE BOOL + "Enable usage of libraries statically linked to C++ runtime" +) + +# If using multithreaded Boost, make sure Threads has been intialized +if(Boost_USE_MULTITHREADED AND NOT DEFINED CMAKE_THREAD_LIBS_INIT) + find_package(Threads) +endif() + +# Enable debug output from FindBoost +set(Boost_DEBUG OFF CACHE BOOL "Enable debug output from FindBoost") + +# -------------- PATHS -------------------------------------------------------- + +# By default, search system paths +set(Boost_NO_SYSTEM_PATHS + OFF + CACHE BOOL + "Disable searching in locations not specified by hint variables" +) + +# A sanity check This must be done _before_ the cache variables are set +if(PATH_BOOST AND Boost_ROOT_DIR) + rocprofiler_systems_message( + FATAL_ERROR + "PATH_BOOST AND Boost_ROOT_DIR both specified. Please provide only one" + ) +endif() + +# Provide a default root directory +if(NOT PATH_BOOST AND NOT Boost_ROOT_DIR) + set(PATH_BOOST "/usr") +endif() + +# Set the default location to look for Boost +set(Boost_ROOT_DIR ${PATH_BOOST} CACHE PATH "Base directory the of Boost installation") + +# In FindBoost, Boost_ROOT_DIR is spelled BOOST_ROOT +set(BOOST_ROOT ${Boost_ROOT_DIR}) + +# -------------- COMPILER DEFINES --------------------------------------------- + +set(_boost_defines) + +# Disable auto-linking +list(APPEND _boost_defines BOOST_ALL_NO_LIB=1) + +# Disable generating serialization code in boost::multi_index +list(APPEND _boost_defines BOOST_MULTI_INDEX_DISABLE_SERIALIZATION) + +# There are broken versions of MSVC that won't handle variadic templates correctly +# (despite the C++11 test case passing). +if(MSVC) + list(APPEND _boost_defines BOOST_NO_CXX11_VARIADIC_TEMPLATES) +endif() + +set(Boost_DEFINES ${_boost_defines} CACHE STRING "Boost compiler defines") +add_compile_definitions(${Boost_DEFINES}) + +# -------------- INTERNALS ---------------------------------------------------- + +# Disable Boost's own CMake as it's known to be buggy NB: This should not be a cache +# variable +set(Boost_NO_BOOST_CMAKE ON) + +# The required Boost library components NB: These are just the ones that require +# compilation/linking This should _not_ be a cache variable +set(_boost_components + atomic + chrono + date_time + filesystem + system + thread + timer +) + +if(NOT BUILD_BOOST) + find_package(Boost ${Boost_MIN_VERSION} QUIET COMPONENTS ${_boost_components}) +endif() + +# -------------- SOURCE BUILD ------------------------------------------------- + +if(Boost_FOUND AND NOT BUILD_BOOST) + # Force the cache entries to be updated Normally, these would not be exported. + # However, we need them in the Testsuite + set(Boost_INCLUDE_DIRS + ${Boost_INCLUDE_DIRS} + CACHE PATH + "Boost include directory" + FORCE + ) + set(Boost_LIBRARY_DIRS + ${Boost_LIBRARY_DIRS} + CACHE PATH + "Boost library directory" + FORCE + ) + set(Boost_INCLUDE_DIR ${Boost_INCLUDE_DIR} CACHE PATH "Boost include directory" FORCE) +elseif(NOT Boost_FOUND AND STERILE_BUILD) + rocprofiler_systems_message( + FATAL_ERROR "Boost not found and cannot be downloaded because build is sterile." + ) +elseif(NOT BUILD_BOOST) + rocprofiler_systems_message( + FATAL_ERROR + "Boost was not found. Either configure cmake to find Boost properly or set BUILD_BOOST=ON to download and build" + ) +else() + rocprofiler_systems_add_option(BOOST_LINK_STATIC "Link to boost libraries statically" + ON + ) + # If we didn't find a suitable version on the system, then download one from the web + rocprofiler_systems_add_cache_option( + ROCPROFSYS_BOOST_DOWNLOAD_VERSION "Version of boost to download and install" + STRING "1.79.0" + ) + + # If the user specifies a version other than ROCPROFSYS_BOOST_DOWNLOAD_VERSION, use + # that version. + if(${ROCPROFSYS_BOOST_DOWNLOAD_VERSION} VERSION_LESS ${Boost_MIN_VERSION}) + rocprofiler_systems_message( + FATAL_ERROR + "Boost download version is set to ${ROCPROFSYS_BOOST_DOWNLOAD_VERSION} but Boost minimum version is set to ${Boost_MIN_VERSION}" + ) + endif() + + rocprofiler_systems_message( + STATUS + "Attempting to build BOOST(${ROCPROFSYS_BOOST_DOWNLOAD_VERSION}) as external project" + ) + + if(Boost_USE_MULTITHREADED) + set(_boost_threading multi) + else() + set(_boost_threading single) + endif() + + if(Boost_USE_STATIC_RUNTIME) + set(_boost_runtime_link static) + else() + set(_boost_runtime_link shared) + endif() + + # Change the base directory + set(Boost_ROOT_DIR + ${TPL_STAGING_PREFIX}/boost + CACHE PATH + "Base directory the of Boost installation" + FORCE + ) + + # Update the exported variables + set(Boost_INCLUDE_DIRS + "$;$" + CACHE PATH + "Boost include directory" + FORCE + ) + set(Boost_LIBRARY_DIRS + "$;$" + CACHE PATH + "Boost library directory" + FORCE + ) + set(Boost_INCLUDE_DIR + ${Boost_INCLUDE_DIRS} + CACHE PATH + "Boost include directory" + FORCE + ) + + file(MAKE_DIRECTORY ${Boost_ROOT_DIR}/include) + file(MAKE_DIRECTORY ${Boost_ROOT_DIR}/lib) + + if(BOOST_LINK_STATIC) + set(_BOOST_LINK static) + else() + set(_BOOST_LINK shared) + endif() + + set(BOOST_ARGS + link=${_BOOST_LINK} + runtime-link=${_boost_runtime_link} + threading=${_boost_threading} + ) + if(WIN32) + # NB: We need to build both debug/release on windows as we don't use + # CMAKE_BUILD_TYPE + set(BOOST_BOOTSTRAP call bootstrap.bat) + set(BOOST_BUILD ".\\b2") + if(CMAKE_SIZEOF_VOID_P STREQUAL "8") + list(APPEND BOOST_ARGS address-model=64) + endif() + else() + set(BOOST_BOOTSTRAP "./bootstrap.sh") + set(BOOST_BUILD "./b2") + if(CMAKE_BUILD_TYPE MATCHES "^(Debug|DEBUG)$") + list(APPEND BOOST_ARGS variant=debug) + else() + list(APPEND BOOST_ARGS variant=release) + endif() + endif() + + # Join the component names together to pass to --with-libraries during bootstrap + set(_boost_lib_names "headers,") + foreach(c ${_boost_components}) + # list(JOIN ...) is in cmake 3.12 + string(CONCAT _boost_lib_names "${_boost_lib_names}${c},") + endforeach() + + if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang|Intel)") + list(APPEND BOOST_ARGS cflags=-fPIC cxxflags=-fPIC) + endif() + + string(REPLACE "." "_" _boost_download_filename ${ROCPROFSYS_BOOST_DOWNLOAD_VERSION}) + # zip is subject to locales on Unix + set(_boost_download_ext "zip") + if(UNIX) + set(_boost_download_ext "tar.gz") + endif() + + set(_LIB_SUFFIX "${CMAKE_SHARED_LIBRARY_SUFFIX}") + if(BOOST_LINK_STATIC) + set(_LIB_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}") + endif() + + if(WIN32) + # We need to specify different library names for debug vs release + set(Boost_LIBRARIES "") + foreach(c ${_boost_components}) + list(APPEND Boost_LIBRARIES "optimized libboost_${c} debug libboost_${c}-gd ") + list( + APPEND + _boost_build_byproducts + "{Boost_ROOT_DIR}/lib/libboost_${c}${_LIB_SUFFIX}" + ) + set(Boost_${c}_LIBRARY + $ + $ + ) + set(Boost_${c}_LIBRARY_DEBUG + $ + $ + ) + + # Also export cache variables for the file location of each library + string(TOUPPER ${c} _basename) + set(Boost_${_basename}_LIBRARY_RELEASE + "${Boost_${c}_LIBRARY}" + CACHE FILEPATH + "" + FORCE + ) + set(Boost_${_basename}_LIBRARY_DEBUG + "${Boost_${c}_LIBRARY_DEBUG}" + CACHE FILEPATH + "" + FORCE + ) + endforeach() + else() + # Transform the component names into the library filenames e.g., system -> + # boost_system + set(Boost_LIBRARIES "") + foreach(c ${_boost_components}) + set(Boost_${c}_LIBRARY + $ + $/${INSTALL_LIB_DIR}/${TPL_INSTALL_LIB_DIR}/libboost_${c}${_LIB_SUFFIX}> + ) + list( + APPEND + _boost_build_byproducts + "${Boost_ROOT_DIR}/lib/libboost_${c}${_LIB_SUFFIX}" + ) + list(APPEND Boost_LIBRARIES "${Boost_${c}_LIBRARY}") + + # Also export cache variables for the file location of each library + string(TOUPPER ${c} _basename) + set(Boost_${_basename}_LIBRARY_RELEASE + "${Boost_${c}_LIBRARY}" + CACHE FILEPATH + "" + FORCE + ) + set(Boost_${_basename}_LIBRARY_DEBUG + "${Boost_${c}_LIBRARY}" + CACHE FILEPATH + "" + FORCE + ) + endforeach() + endif() + + include(ExternalProject) + ExternalProject_Add( + rocprofiler-systems-boost-build + PREFIX ${Boost_ROOT_DIR} + GIT_REPOSITORY https://github.com/boostorg/boost.git + GIT_TAG boost-${ROCPROFSYS_BOOST_DOWNLOAD_VERSION} + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND + ${BOOST_BOOTSTRAP} --prefix=${Boost_ROOT_DIR} + --with-libraries=${_boost_lib_names} + BUILD_COMMAND + ${BOOST_BUILD} --ignore-site-config --prefix=${Boost_ROOT_DIR} -j2 + ${BOOST_ARGS} -d0 install + BUILD_BYPRODUCTS ${_boost_build_byproducts} + INSTALL_COMMAND "" + ) + + # target for re-executing the installation + add_custom_target( + rocprofiler-systems-boost-install + COMMAND ${BOOST_BUILD} ${BOOST_ARGS} -d0 install + WORKING_DIRECTORY ${Boost_ROOT_DIR}/src/Boost-External + COMMENT "Installing Boost..." + ) +endif() + +# -------------- EXPORT VARIABLES --------------------------------------------- + +# Export Boost_THREAD_LIBRARY +list(FIND _boost_components "thread" _building_threads) +if(Boost_USE_MULTITHREADED AND ${_building_threads}) + # On Windows, always use the debug version On Linux, we don't use tagged builds, so + # the debug/release filenames are the same + set(Boost_THREAD_LIBRARY + ${Boost_THREAD_LIBRARY_DEBUG} + CACHE FILEPATH + "Boost thread library" + ) +endif() + +# Add the system thread library +if(Boost_USE_MULTITHREADED) + list(APPEND Boost_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) +endif() + +# Export the complete set of libraries +set(Boost_LIBRARIES ${Boost_LIBRARIES} CACHE FILEPATH "Boost library files" FORCE) + +target_include_directories( + rocprofiler-systems-boost + SYSTEM + INTERFACE ${Boost_INCLUDE_DIRS} +) +target_compile_definitions(rocprofiler-systems-boost INTERFACE ${Boost_DEFINITIONS}) +target_link_directories(rocprofiler-systems-boost INTERFACE ${Boost_LIBRARY_DIRS}) +target_link_libraries(rocprofiler-systems-boost INTERFACE ${Boost_LIBRARIES}) + +rocprofiler_systems_message(STATUS "Boost includes: ${Boost_INCLUDE_DIRS}") +rocprofiler_systems_message(STATUS "Boost library dirs: ${Boost_LIBRARY_DIRS}") +rocprofiler_systems_message(STATUS "Boost thread library: ${Boost_THREAD_LIBRARY}") +rocprofiler_systems_message(STATUS "Boost libraries: ${Boost_LIBRARIES}") + +# Just the headers (effectively a simplified Boost::headers target) +add_library(Dyninst::Boost_headers INTERFACE IMPORTED) +target_include_directories(Dyninst::Boost_headers SYSTEM INTERFACE ${Boost_INCLUDE_DIRS}) diff --git a/projects/rocprofiler-systems/cmake/DyninstElfUtils.cmake b/projects/rocprofiler-systems/cmake/DyninstElfUtils.cmake new file mode 100644 index 0000000000..1ed36cb7f9 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/DyninstElfUtils.cmake @@ -0,0 +1,243 @@ +# ====================================================================================== +# elfutils.cmake +# +# Configure elfutils for Dyninst +# +# ---------------------------------------- +# +# Accepts the following CMake variables +# +# ElfUtils_ROOT_DIR - Base directory the of elfutils installation +# ElfUtils_INCLUDEDIR - Hint directory that contains the elfutils headers files +# ElfUtils_LIBRARYDIR - Hint directory that contains the elfutils library files +# ElfUtils_MIN_VERSION - Minimum acceptable version of elfutils +# +# Directly exports the following CMake variables +# +# ElfUtils_ROOT_DIR - Computed base directory the of elfutils installation +# ElfUtils_INCLUDE_DIRS - elfutils include directories ElfUtils_LIBRARY_DIRS - Link +# directories for elfutils libraries ElfUtils_LIBRARIES - elfutils library files +# +# NOTE: The exported ElfUtils_ROOT_DIR can be different from the value provided by the +# user in the case that it is determined to build elfutils from source. In such a case, +# ElfUtils_ROOT_DIR will contain the directory of the from-source installation. +# +# See Modules/FindLibElf.cmake and Modules/FindLibDwarf.cmake for details +# +# ====================================================================================== + +include_guard(GLOBAL) + +if(NOT BUILD_ELFUTILS) + find_package(Elfutils) +endif() + +if(LibElf_FOUND AND LibDwarf_FOUND AND NOT ENABLE_DEBUGINFOD) + return() +endif() + +if(NOT UNIX) + return() +endif() + +# Minimum acceptable version of elfutils NB: We need >=0.178 because libdw isn't +# thread-safe before then +set(_min_version 0.178) + +set(ElfUtils_MIN_VERSION + ${_min_version} + CACHE STRING + "Minimum acceptable elfutils version" +) +if(${ElfUtils_MIN_VERSION} VERSION_LESS ${_min_version}) + rocprofiler_systems_message( + FATAL_ERROR + "Requested version ${ElfUtils_MIN_VERSION} is less than minimum supported version (${_min_version})" + ) +endif() + +# -------------- PATHS -------------------------------------------------------- + +# Base directory the of elfutils installation +set(ElfUtils_ROOT_DIR "/usr" CACHE PATH "Base directory the of elfutils installation") + +# Hint directory that contains the elfutils headers files +set(ElfUtils_INCLUDEDIR + "${ElfUtils_ROOT_DIR}/include" + CACHE PATH + "Hint directory that contains the elfutils headers files" +) + +# Hint directory that contains the elfutils library files +set(ElfUtils_LIBRARYDIR + "${ElfUtils_ROOT_DIR}/lib" + CACHE PATH + "Hint directory that contains the elfutils library files" +) + +# libelf/dwarf-specific directory hints +foreach(l LibElf LibDwarf LibDebuginfod) + foreach(d ROOT_DIR INCLUDEDIR LIBRARYDIR) + set(${l}_${d} ${ElfUtils_${d}}) + endforeach() +endforeach() + +# -------------- PACKAGES------------------------------------------------------ + +if(NOT BUILD_ELFUTILS) + find_package(LibElf ${ElfUtils_MIN_VERSION}) + + # Don't search for libdw or libdebuginfod if we didn't find a suitable libelf + if(LibElf_FOUND) + find_package(LibDwarf ${ElfUtils_MIN_VERSION}) + if(ENABLE_DEBUGINFOD) + find_package(LibDebuginfod ${ElfUtils_MIN_VERSION} REQUIRED) + endif() + endif() +endif() + +# -------------- SOURCE BUILD ------------------------------------------------- + +if(LibElf_FOUND AND LibDwarf_FOUND AND (NOT ENABLE_DEBUGINFOD OR LibDebuginfod_FOUND)) + if(ENABLE_DEBUGINFOD AND LibDebuginfod_FOUND) + set(_eu_root ${ElfUtils_ROOT_DIR}) + set(_eu_inc_dirs + ${LibElf_INCLUDE_DIRS} + ${LibDwarf_INCLUDE_DIRS} + ${LibDebuginfod_INCLUDE_DIRS} + ) + set(_eu_lib_dirs + ${LibElf_LIBRARY_DIRS} + ${LibDwarf_LIBRARY_DIRS} + ${LibDebuginfod_LIBRARY_DIRS} + ) + set(_eu_libs ${LibElf_LIBRARIES} ${LibDwarf_LIBRARIES} ${LibDebuginfod_LIBRARIES}) + else() + set(_eu_root ${ElfUtils_ROOT_DIR}) + set(_eu_inc_dirs ${LibElf_INCLUDE_DIRS} ${LibDwarf_INCLUDE_DIRS}) + set(_eu_lib_dirs ${LibElf_LIBRARY_DIRS} ${LibDwarf_LIBRARY_DIRS}) + set(_eu_libs ${LibElf_LIBRARIES} ${LibDwarf_LIBRARIES}) + endif() +elseif(NOT (LibElf_FOUND AND LibDwarf_FOUND) AND STERILE_BUILD) + rocprofiler_systems_message( + FATAL_ERROR + "ElfUtils not found and cannot be downloaded because build is sterile." + ) +elseif(NOT BUILD_ELFUTILS) + rocprofiler_systems_message( + FATAL_ERROR + "ElfUtils was not found. Either configure cmake to find ElfUtils properly or set BUILD_ELFUTILS=ON to download and build" + ) +else() + # If we didn't find a suitable version on the system, then download one from the web + rocprofiler_systems_add_cache_option( + ELFUTILS_DOWNLOAD_VERSION "Version of elfutils to download and install" STRING + "0.188" + ) + set(ELFUTILS_DOWNLOAD_VERSION ${ElfUtils_DOWNLOAD_VERSION}) + + # make sure we are not downloading a version less than minimum + if(${ELFUTILS_DOWNLOAD_VERSION} VERSION_LESS ${ElfUtils_MIN_VERSION}) + rocprofiler_systems_message( + FATAL_ERROR + "elfutils download version is set to ${ELFUTILS_DOWNLOAD_VERSION} but elfutils minimum version is set to ${ElfUtils_MIN_VERSION}" + ) + endif() + + rocprofiler_systems_message(STATUS "${ElfUtils_ERROR_REASON}") + rocprofiler_systems_message( + STATUS + "Attempting to build elfutils(${ELFUTILS_DOWNLOAD_VERSION}) as external project" + ) + + if( + NOT (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") + OR NOT (${CMAKE_C_COMPILER_ID} STREQUAL "GNU") + ) + rocprofiler_systems_message(FATAL_ERROR + "ElfUtils will only build with the GNU compiler" + ) + endif() + + set(_eu_root ${TPL_STAGING_PREFIX}/elfutils) + set(_eu_inc_dirs $) + set(_eu_lib_dirs $) + set(_eu_libs + $ + $ + ) + set(_eu_build_byproducts + "${_eu_root}/lib/libdw${CMAKE_SHARED_LIBRARY_SUFFIX}" + "${_eu_root}/lib/libelf${CMAKE_SHARED_LIBRARY_SUFFIX}" + ) + + file(MAKE_DIRECTORY "${_eu_root}/lib") + file(MAKE_DIRECTORY "${_eu_root}/include") + + include(ExternalProject) + ExternalProject_Add( + rocprofiler-systems-elfutils-build + PREFIX ${_eu_root} + URL + ${ElfUtils_DOWNLOAD_URL} + "https://sourceware.org/elfutils/ftp/${ELFUTILS_DOWNLOAD_VERSION}/elfutils-${ELFUTILS_DOWNLOAD_VERSION}.tar.bz2" + "https://mirrors.kernel.org/sourceware/elfutils/${ELFUTILS_DOWNLOAD_VERSION}/elfutils-${ELFUTILS_DOWNLOAD_VERSION}.tar.bz2" + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND + ${CMAKE_COMMAND} -E env CC=${CMAKE_C_COMPILER} CFLAGS=-fPIC\ -O3 + CXX=${CMAKE_CXX_COMPILER} CXXFLAGS=-fPIC\ -O3 + [=[LDFLAGS=-Wl,-rpath='$$ORIGIN']=] /configure + --enable-install-elfh --prefix=${_eu_root} --disable-libdebuginfod + --disable-debuginfod --enable-thread-safety ${ElfUtils_CONFIG_OPTIONS} + --libdir=${_eu_root}/lib + BUILD_COMMAND make install + BUILD_BYPRODUCTS ${_eu_build_byproducts} + INSTALL_COMMAND "" + ) + + # target for re-executing the installation + add_custom_target( + rocprofiler-systems-elfutils-install + COMMAND make install + WORKING_DIRECTORY ${${_eu_root}}/src/ElfUtils-External + COMMENT "Installing ElfUtils..." + ) + + install( + DIRECTORY ${_eu_root}/lib/ + DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME} + FILES_MATCHING + PATTERN "*${CMAKE_SHARED_LIBRARY_SUFFIX}*" + ) +endif() + +# -------------- EXPORT VARIABLES --------------------------------------------- + +set(ElfUtils_ROOT_DIR + ${_eu_root} + CACHE PATH + "Base directory the of elfutils installation" + FORCE +) +set(ElfUtils_INCLUDE_DIRS ${_eu_inc_dirs} CACHE PATH "elfutils include directory" FORCE) +set(ElfUtils_LIBRARY_DIRS ${_eu_lib_dirs} CACHE PATH "elfutils library directory" FORCE) +set(ElfUtils_INCLUDE_DIR + ${ElfUtils_INCLUDE_DIRS} + CACHE PATH + "elfutils include directory" + FORCE +) +set(ElfUtils_LIBRARIES ${_eu_libs} CACHE FILEPATH "elfutils library files" FORCE) + +target_include_directories( + rocprofiler-systems-elfutils + SYSTEM + INTERFACE ${ElfUtils_INCLUDE_DIRS} +) +target_compile_definitions(rocprofiler-systems-elfutils INTERFACE ${ElfUtils_DEFINITIONS}) +target_link_directories(rocprofiler-systems-elfutils INTERFACE ${ElfUtils_LIBRARY_DIRS}) +target_link_libraries(rocprofiler-systems-elfutils INTERFACE ${ElfUtils_LIBRARIES}) + +rocprofiler_systems_message(STATUS "ElfUtils includes: ${ElfUtils_INCLUDE_DIRS}") +rocprofiler_systems_message(STATUS "ElfUtils library dirs: ${ElfUtils_LIBRARY_DIRS}") +rocprofiler_systems_message(STATUS "ElfUtils libraries: ${ElfUtils_LIBRARIES}") diff --git a/projects/rocprofiler-systems/cmake/DyninstExternals.cmake b/projects/rocprofiler-systems/cmake/DyninstExternals.cmake new file mode 100644 index 0000000000..92d6aa15bd --- /dev/null +++ b/projects/rocprofiler-systems/cmake/DyninstExternals.cmake @@ -0,0 +1,139 @@ +include(MacroUtilities) + +# Map deprecated DYNINST_BUILD_* variables to new ROCPROFSYS_BUILD_* variables +foreach(dep BOOST TBB ELFUTILS LIBIBERTY) + if(DYNINST_BUILD_${dep}) + message( + WARNING + "DYNINST_BUILD_${dep} is deprecated. Using ROCPROFSYS_BUILD_${dep} instead." + ) + set(ROCPROFSYS_BUILD_${dep} ON) + endif() +endforeach() + +# Set BUILD_* to ON if ROCPROFSYS_BUILD_* is ON +foreach(dep BOOST TBB ELFUTILS LIBIBERTY) + if(ROCPROFSYS_BUILD_${dep}) + if(dep STREQUAL "BOOST") + rocprofiler_systems_add_option(BUILD_BOOST "Enable building Boost internally" + ON + ) + elseif(dep STREQUAL "TBB") + rocprofiler_systems_add_option(BUILD_TBB "Enable building TBB internally" ON) + elseif(dep STREQUAL "ELFUTILS") + rocprofiler_systems_add_option(BUILD_ELFUTILS + "Enable building elfutils internally" ON + ) + elseif(dep STREQUAL "LIBIBERTY") + rocprofiler_systems_add_option(BUILD_LIBIBERTY + "Enable building libiberty internally" ON + ) + endif() + endif() +endforeach() + +set(TPL_STAGING_PREFIX + "${PROJECT_BINARY_DIR}/external" + CACHE PATH + "Third-party library build-tree install prefix" +) +file(MAKE_DIRECTORY "${TPL_STAGING_PREFIX}") +file(MAKE_DIRECTORY "${TPL_STAGING_PREFIX}/include") + +add_custom_target(external-prebuild) + +# Add external dependencies to be built +include(DyninstBoost) +if(TARGET rocprofiler-systems-boost-build) + # Make Boost build serially + set_target_properties( + rocprofiler-systems-boost + PROPERTIES JOB_POOL_COMPILE external_deps_pool JOB_POOL_LINK external_deps_pool + ) + # Create a prebuild target that depends on Boost + add_dependencies(external-prebuild rocprofiler-systems-boost-build) +endif() + +include(DyninstTBB) +if(TARGET rocprofiler-systems-tbb-build AND TARGET external-prebuild) + # Make TBB build serially and wait for Boost + set_target_properties( + rocprofiler-systems-tbb-build + PROPERTIES JOB_POOL_COMPILE external_deps_pool JOB_POOL_LINK external_deps_pool + ) + add_dependencies(external-prebuild rocprofiler-systems-tbb-build) +endif() + +include(DyninstElfUtils) +if(TARGET rocprofiler-systems-elfutils-build AND TARGET external-prebuild) + set_target_properties( + rocprofiler-systems-elfutils-build + PROPERTIES JOB_POOL_COMPILE external_deps_pool JOB_POOL_LINK external_deps_pool + ) + add_dependencies(external-prebuild rocprofiler-systems-elfutils-build) +endif() + +include(DyninstLibIberty) +if(TARGET rocprofiler-systems-libiberty-build AND TARGET external-prebuild) + set_target_properties( + rocprofiler-systems-libiberty-build + PROPERTIES JOB_POOL_COMPILE external_deps_pool JOB_POOL_LINK external_deps_pool + ) + add_dependencies(external-prebuild rocprofiler-systems-libiberty-build) +endif() + +# Final dependency check +if(NOT TARGET external-prebuild) + message(WARNING "Not all dyninst external dependencies found. Build may fail.") +endif() + +# Create a dummy target to ensure external dependencies are fully built +add_custom_target(external-deps-complete) +if(TARGET external-prebuild) + add_dependencies(external-deps-complete external-prebuild) +endif() + +if(NOT TARGET Dyninst::Boost AND TARGET rocprofiler-systems-boost) + add_library(Dyninst::Boost INTERFACE IMPORTED) + set_target_properties( + Dyninst::Boost + PROPERTIES INTERFACE_LINK_LIBRARIES rocprofiler-systems-boost + ) + message( + STATUS + "Created imported target Dyninst::Boost linked to rocprofiler-systems-boost" + ) +endif() + +if(NOT TARGET Dyninst::ElfUtils AND TARGET rocprofiler-systems-elfutils) + add_library(Dyninst::ElfUtils INTERFACE IMPORTED) + set_target_properties( + Dyninst::ElfUtils + PROPERTIES INTERFACE_LINK_LIBRARIES rocprofiler-systems-elfutils + ) + message(STATUS "Created imported target Dyninst::ElfUtils linked to ElfUtils") +endif() + +if(NOT TARGET Dyninst::TBB AND TARGET rocprofiler-systems-tbb) + add_library(Dyninst::TBB INTERFACE IMPORTED) + set_target_properties( + Dyninst::TBB + PROPERTIES INTERFACE_LINK_LIBRARIES rocprofiler-systems-tbb + ) + message( + STATUS + "Created imported target Dyninst::TBB linked to rocprofiler-systems-tbb" + ) +endif() + +if(NOT TARGET Dyninst::LibIberty AND TARGET rocprofiler-systems-libiberty) + add_library(Dyninst::LibIberty INTERFACE IMPORTED) + set_target_properties( + Dyninst::LibIberty + PROPERTIES INTERFACE_LINK_LIBRARIES rocprofiler-systems-libiberty + ) + message( + STATUS + "Created imported target Dyninst::LibIberty linked to rocprofiler-systems-libiberty" + ) +endif() diff --git a/projects/rocprofiler-systems/cmake/DyninstLibIberty.cmake b/projects/rocprofiler-systems/cmake/DyninstLibIberty.cmake new file mode 100644 index 0000000000..66b52b1bee --- /dev/null +++ b/projects/rocprofiler-systems/cmake/DyninstLibIberty.cmake @@ -0,0 +1,156 @@ +# ====================================================================================== +# LibIberty.cmake +# +# Configure LibIberty for Dyninst +# +# ---------------------------------------- +# +# Directly exports the following CMake variables +# +# LibIberty_ROOT_DIR - Computed base directory the of LibIberty installation +# LibIberty_LIBRARY_DIRS - Link directories for LibIberty libraries LibIberty_LIBRARIES +# - LibIberty library files LibIberty_INCLUDE - LibIberty include files +# +# NOTE: The exported LibIberty_ROOT_DIR can be different from the value provided by the +# user in the case that it is determined to build LibIberty from source. In such a case, +# LibIberty_ROOT_DIR will contain the directory of the from-source installation. +# +# See Modules/FindLibIberty.cmake for details +# +# ====================================================================================== + +include_guard(GLOBAL) + +if(NOT UNIX) + return() +endif() + +# -------------- PATHS -------------------------------------------------------- + +# Base directory the of LibIberty installation +set(LibIberty_ROOT_DIR "/usr" CACHE PATH "Base directory the of LibIberty installation") + +# Hint directory that contains the LibIberty library files +set(LibIberty_LIBRARYDIR + "${LibIberty_ROOT_DIR}/lib" + CACHE PATH + "Hint directory that contains the LibIberty library files" +) + +# -------------- PACKAGES ----------------------------------------------------- + +if(NOT BUILD_LIBIBERTY) + find_package(LibIberty) +endif() + +# -------------- SOURCE BUILD ------------------------------------------------- + +if(LibIberty_FOUND) + set(_li_root ${LibIberty_ROOT_DIR}) + set(_li_inc_dirs ${LibIberty_INCLUDE_DIRS}) + set(_li_lib_dirs ${LibIberty_LIBRARY_DIRS}) + set(_li_libs ${LibIberty_LIBRARIES}) +elseif(STERILE_BUILD) + rocprofiler_systems_message( + FATAL_ERROR + "LibIberty not found and cannot be downloaded because build is sterile." + ) +elseif(NOT BUILD_LIBIBERTY) + rocprofiler_systems_message( + FATAL_ERROR + "LibIberty was not found. Either configure cmake to find TBB properly or set BUILD_LIBIBERTY=ON to download and build" + ) +else() + rocprofiler_systems_message(STATUS "${LibIberty_ERROR_REASON}") + rocprofiler_systems_message(STATUS + "Attempting to build LibIberty as external project" + ) + + set(_li_root ${TPL_STAGING_PREFIX}/binutils) + set(_li_project_name rocprofiler-systems-libiberty-build) + set(_li_working_dir ${_li_root}/src/${_li_project_name}) + set(_li_inc_dirs $) + set(_li_lib_dirs $) + set(_li_libs + $ + ) + set(_li_build_byproducts "${_li_root}/lib/libiberty${CMAKE_STATIC_LIBRARY_SUFFIX}") + + file(MAKE_DIRECTORY "${_li_root}/lib") + file(MAKE_DIRECTORY "${_li_root}/include") + + include(ExternalProject) + ExternalProject_Add( + ${_li_project_name} + PREFIX ${_li_root} + URL + ${DYNINST_BINUTILS_DOWNLOAD_URL} + http://ftpmirror.gnu.org/gnu/binutils/binutils-2.42.tar.gz + http://mirrors.kernel.org/sourceware/binutils/releases/binutils-2.42.tar.gz + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND + ${CMAKE_COMMAND} -E env CC=${CMAKE_C_COMPILER} CFLAGS=-fPIC\ -O3 + CXX=${CMAKE_CXX_COMPILER} CXXFLAGS=-fPIC\ -O3 /configure + --prefix=${_li_root} + BUILD_COMMAND make + BUILD_BYPRODUCTS ${_li_build_byproducts} + INSTALL_COMMAND "" + ) + + add_custom_command( + TARGET ${_li_project_name} + POST_BUILD + COMMAND install + ARGS -C ${_li_working_dir}/libiberty/libiberty.a ${_li_root}/lib + COMMAND install + ARGS -C ${_li_working_dir}/include/*.h ${_li_root}/include + COMMENT "Installing LibIberty..." + ) + + # target for re-executing the installation + add_custom_target( + rocprofiler-systems-libiberty-install + COMMAND install -C ${_li_working_dir}/libiberty/libiberty.a ${_li_root}/lib + COMMAND install ARGS -C ${_li_working_dir}/include/*.h ${_li_root}/include + WORKING_DIRECTORY ${_li_working_dir} + COMMENT "Installing LibIberty..." + ) + + # For backward compatibility + set(IBERTY_FOUND TRUE) + set(IBERTY_BUILD TRUE) +endif() + +# -------------- EXPORT VARIABLES --------------------------------------------- + +foreach(_DIR_TYPE inc lib) + if(_li_${_DIR_TYPE}_dirs) + list(REMOVE_DUPLICATES _li_${_DIR_TYPE}_dirs) + endif() +endforeach() + +target_include_directories(rocprofiler-systems-libiberty INTERFACE ${_li_inc_dirs}) +target_link_directories(rocprofiler-systems-libiberty INTERFACE ${_lib_lib_dirs}) +target_link_libraries(rocprofiler-systems-libiberty INTERFACE ${_li_libs}) + +set(LibIberty_ROOT_DIR + ${_li_root} + CACHE PATH + "Base directory the of LibIberty installation" + FORCE +) +set(LibIberty_INCLUDE_DIRS + ${_li_inc_dirs} + CACHE PATH + "LibIberty include directories" + FORCE +) +set(LibIberty_LIBRARY_DIRS ${_li_lib_dirs} CACHE PATH "LibIberty library directory" FORCE) +set(LibIberty_LIBRARIES ${_li_libs} CACHE FILEPATH "LibIberty library files" FORCE) + +# For backward compatibility only +set(IBERTY_LIBRARIES ${LibIberty_LIBRARIES}) + +rocprofiler_systems_message(STATUS "LibIberty include dirs: ${LibIberty_INCLUDE_DIRS}") +rocprofiler_systems_message(STATUS "LibIberty library dirs: ${LibIberty_LIBRARY_DIRS}") +rocprofiler_systems_message(STATUS "LibIberty libraries: ${LibIberty_LIBRARIES}") diff --git a/projects/rocprofiler-systems/cmake/DyninstTBB.cmake b/projects/rocprofiler-systems/cmake/DyninstTBB.cmake new file mode 100644 index 0000000000..110d00f8e8 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/DyninstTBB.cmake @@ -0,0 +1,248 @@ +# ===================================================================================== +# ThreadingBuildingBlocks.cmake +# +# Configure Intel's Threading Building Blocks for Dyninst +# +# ---------------------------------------- +# +# Accepts the following CMake variables +# +# TBB_ROOT_DIR - Hint directory that contains the TBB installation TBB_INCLUDEDIR - +# Hint directory that contains the TBB headers files TBB_LIBRARYDIR - Hint directory +# that contains the TBB library files TBB_LIBRARY - Alias for TBB_LIBRARYDIR +# TBB_USE_DEBUG_BUILD - Use debug version of tbb libraries, if present TBB_MIN_VERSION - +# Minimum acceptable version of TBB +# +# Directly exports the following CMake variables +# +# TBB_ROOT_DIR - Computed base directory of TBB installation TBB_INCLUDE_DIRS - +# TBB include directory TBB_INCLUDE_DIR - Alias for TBB_INCLUDE_DIRS TBB_LIBRARY_DIRS +# - TBB library directory TBB_LIBRARY_DIR - Alias for TBB_LIBRARY_DIRS TBB_DEFINITIONS - +# TBB compiler definitions TBB_LIBRARIES - TBB library files +# +# TBB__LIBRARY_RELEASE - Path to the release version of component +# TBB__LIBRARY_DEBUG - Path to the debug version of component +# +# NOTE: The exported TBB_ROOT_DIR can be different from the value provided by the user in +# the case that it is determined to build TBB from source. In such a case, TBB_ROOT_DIR +# will contain the directory of the from-source installation. +# +# See Modules/FindTBB.cmake for additional input and exported variables +# +# ===================================================================================== + +include_guard(GLOBAL) + +if(TBB_FOUND) + return() +endif() + +# -------------- RUNTIME CONFIGURATION ---------------------------------------- + +# Use debug versions of TBB libraries +set(TBB_USE_DEBUG_BUILD OFF CACHE BOOL "Use debug versions of TBB libraries") + +# Minimum version of TBB (assumes a dotted-decimal format: YYYY.XX) +if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + set(_tbb_min_version 2019.7) +else() + set(_tbb_min_version 2018.6) +endif() + +set(TBB_MIN_VERSION + ${_tbb_min_version} + CACHE STRING + "Minimum version of TBB (assumes a dotted-decimal format: YYYY.XX)" +) + +if(${TBB_MIN_VERSION} VERSION_LESS ${_tbb_min_version}) + dyninst_message( + FATAL_ERROR + "Requested TBB version ${TBB_MIN_VERSION} is less than minimum supported version ${_tbb_min_version}" + ) +endif() + +# -------------- PATHS -------------------------------------------------------- + +# TBB root directory +set(TBB_ROOT_DIR "/usr" CACHE PATH "TBB root directory") + +# TBB include directory hint +set(TBB_INCLUDEDIR "${TBB_ROOT_DIR}/include" CACHE INTERNAL "TBB include directory") + +# TBB library directory hint +set(TBB_LIBRARYDIR "${TBB_ROOT_DIR}/lib" CACHE INTERNAL "TBB library directory") + +# Translate to FindTBB names +set(TBB_LIBRARY ${TBB_LIBRARYDIR}) +set(TBB_INCLUDE_DIR ${TBB_INCLUDEDIR}) + +# The specific TBB libraries we need NB: This should _NOT_ be a cache variable +set(_tbb_components tbb tbbmalloc_proxy tbbmalloc) + +if(NOT BUILD_TBB) + find_package(TBB ${TBB_MIN_VERSION} COMPONENTS ${_tbb_components}) +endif() + +# -------------- SOURCE BUILD ------------------------------------------------- +if(TBB_FOUND) + # Force the cache entries to be updated Normally, these would not be exported. + # However, we need them in the Testsuite + set(TBB_INCLUDE_DIRS ${TBB_INCLUDE_DIRS} CACHE PATH "TBB include directory" FORCE) + set(TBB_LIBRARY_DIRS ${TBB_LIBRARY_DIRS} CACHE PATH "TBB library directory" FORCE) + set(TBB_DEFINITIONS ${TBB_DEFINITIONS} CACHE STRING "TBB compiler definitions" FORCE) + set(TBB_LIBRARIES ${TBB_LIBRARIES} CACHE FILEPATH "TBB library files" FORCE) +elseif(STERILE_BUILD) + rocprofiler_systems_message( + FATAL_ERROR "TBB not found and cannot be downloaded because build is sterile." + ) +elseif(NOT BUILD_TBB) + rocprofiler_systems_message( + FATAL_ERROR + "TBB was not found. Either configure cmake to find TBB properly or set BUILD_TBB=ON to download and build" + ) +else() + # If we didn't find a suitable version on the system, then download one from the web + rocprofiler_systems_message(STATUS "${ThreadingBuildingBlocks_ERROR_REASON}") + rocprofiler_systems_message( + STATUS "Attempting to build TBB(${TBB_MIN_VERSION}) as external project" + ) + + if(NOT UNIX) + rocprofiler_systems_message( + FATAL_ERROR "Building TBB from source is not supported on this platform" + ) + endif() + + set(TBB_ROOT_DIR ${TPL_STAGING_PREFIX}/tbb CACHE PATH "TBB root directory" FORCE) + + set(_tbb_libraries) + set(_tbb_components_cfg) + set(_tbb_library_dirs + $ + $ + ) + set(_tbb_include_dirs + $ + $ + ) + + # Forcibly update the cache variables + set(TBB_INCLUDE_DIRS "${_tbb_include_dirs}" CACHE PATH "TBB include directory" FORCE) + set(TBB_LIBRARY_DIRS "${_tbb_library_dirs}" CACHE PATH "TBB library directory" FORCE) + set(TBB_DEFINITIONS "" CACHE STRING "TBB compiler definitions" FORCE) + + file(MAKE_DIRECTORY "${TBB_ROOT_DIR}/include") + file(MAKE_DIRECTORY "${TBB_ROOT_DIR}/lib") + + foreach(c ${_tbb_components}) + # Generate make target names + if(${c} STREQUAL tbbmalloc_proxy) + # tbbmalloc_proxy is spelled tbbproxy in their Makefiles + list(APPEND _tbb_components_cfg tbbproxy_release) + else() + list(APPEND _tbb_components_cfg ${c}_release) + endif() + + set(_tbb_${c}_lib + $ + $ + ) + + # Generate library filenames + list(APPEND _tbb_libraries ${_tbb_${c}_lib}) + list( + APPEND + _tbb_build_byproducts + "${TBB_ROOT_DIR}/lib/lib${c}${CMAKE_SHARED_LIBRARY_SUFFIX}" + ) + + foreach(t RELEASE DEBUG) + set(TBB_${c}_LIBRARY_${t} "${_tbb_${c}_lib}" CACHE FILEPATH "" FORCE) + endforeach() + endforeach() + + set(TBB_LIBRARIES "${_tbb_libraries}" CACHE FILEPATH "TBB library files" FORCE) + + # Split the dotted decimal version into major/minor parts + string(REGEX REPLACE "\\." ";" _tbb_download_name ${TBB_MIN_VERSION}) + list(GET _tbb_download_name 0 _tbb_ver_major) + list(GET _tbb_download_name 1 _tbb_ver_minor) + + # Set the compiler for TBB It assumes gcc and tests for Intel, so clang is the only + # one that needs special treatment. + if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang") + set(_tbb_compiler "compiler=clang") + endif() + + find_program(MAKE_EXECUTABLE NAMES make gmake PATH_SUFFIXES bin) + + if(NOT MAKE_EXECUTABLE AND CMAKE_GENERATOR MATCHES "Ninja") + dyninst_message( + FATAL_ERROR + "make/gmake executable not found. Please re-run with -DMAKE_EXECUTABLE=/path/to/make" + ) + elseif(NOT MAKE_EXECUTABLE AND CMAKE_GENERATOR MATCHES "Makefiles") + set(MAKE_EXECUTABLE "$(MAKE)") + endif() + + include(ExternalProject) + ExternalProject_Add( + rocprofiler-systems-tbb-build + PREFIX ${TBB_ROOT_DIR} + URL + https://github.com/ajanicijamd/oneTBB/archive/refs/tags/v${_tbb_ver_major}.${_tbb_ver_minor}.01.tar.gz + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "" + BUILD_COMMAND + ${CMAKE_COMMAND} -E env CC=${CMAKE_C_COMPILER} CXX=${CMAKE_CXX_COMPILER} + [=[LDFLAGS=-Wl,-rpath='$$ORIGIN']=] ${MAKE_EXECUTABLE} -C src + ${_tbb_components_cfg} tbb_build_dir=${TBB_ROOT_DIR}/src tbb_build_prefix=tbb + ${_tbb_compiler} + BUILD_BYPRODUCTS ${_tbb_build_byproducts} + INSTALL_COMMAND "" + ) + + # post-build target for installing build + add_custom_command( + TARGET rocprofiler-systems-tbb-build + POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS + -DLIBDIR=${TBB_LIBRARY_DIRS} -DINCDIR=${TBB_INCLUDE_DIRS} + -DPREFIX=${TBB_ROOT_DIR} -DCMAKE_STRIP=${CMAKE_STRIP} -P + ${CMAKE_CURRENT_LIST_DIR}/DyninstTBBInstall.cmake + COMMENT "Installing TBB..." + ) + + add_custom_target( + rocprofiler-systems-tbb-install + COMMAND + ${CMAKE_COMMAND} -DLIBDIR=${TBB_LIBRARY_DIRS} -DINCDIR=${TBB_INCLUDE_DIRS} + -DPREFIX=${TBB_ROOT_DIR} -P ${CMAKE_CURRENT_LIST_DIR}/DyninstTBBInstall.cmake + COMMENT "Installing TBB..." + ) + + install( + DIRECTORY ${TPL_STAGING_PREFIX}/tbb/lib/ + DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME} + FILES_MATCHING + PATTERN "*${CMAKE_SHARED_LIBRARY_SUFFIX}*" + ) +endif() + +foreach(_DIR_TYPE INCLUDE LIBRARY) + if(TBB_${_DIR_TYPE}_DIRS) + list(REMOVE_DUPLICATES TBB_${_DIR_TYPE}_DIRS) + endif() +endforeach() + +target_include_directories(rocprofiler-systems-tbb SYSTEM INTERFACE ${TBB_INCLUDE_DIRS}) +target_compile_definitions(rocprofiler-systems-tbb INTERFACE ${TBB_DEFINITIONS}) +target_link_directories(rocprofiler-systems-tbb INTERFACE ${TBB_LIBRARY_DIRS}) +target_link_libraries(rocprofiler-systems-tbb INTERFACE ${TBB_LIBRARIES}) + +rocprofiler_systems_message(STATUS "TBB include directory: ${TBB_INCLUDE_DIRS}") +rocprofiler_systems_message(STATUS "TBB library directory: ${TBB_LIBRARY_DIRS}") +rocprofiler_systems_message(STATUS "TBB libraries: ${TBB_LIBRARIES}") +rocprofiler_systems_message(STATUS "TBB definitions: ${TBB_DEFINITIONS}") diff --git a/projects/rocprofiler-systems/cmake/DyninstTBBInstall.cmake b/projects/rocprofiler-systems/cmake/DyninstTBBInstall.cmake new file mode 100644 index 0000000000..efebee6f11 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/DyninstTBBInstall.cmake @@ -0,0 +1,46 @@ +# ######################################################################################## +# ThreadingBuildingBlocks.cmake +# +# Install Intel's Threading Building Blocks for Dyninst +# +# The default TBB build does not have an 'install' target, so we have to do it manually. +# This file contains the necessary CMake commands to complete the installation assuming it +# has been built using ExternalProject_Add. +# +# ######################################################################################## + +cmake_minimum_required(VERSION 3.13.0) + +if(NOT CMAKE_STRIP) + find_program(CMAKE_STRIP NAMES strip) +endif() + +file(MAKE_DIRECTORY ${LIBDIR} ${INCDIR}) +file( + COPY ${PREFIX}/src/tbb_release/ + DESTINATION ${LIBDIR} + FILES_MATCHING + PATTERN "*.so.*" +) +file(COPY ${PREFIX}/src/rocprofiler-systems-tbb-build/include/tbb DESTINATION ${INCDIR}) +file(GLOB _tbb_libs ${LIBDIR}/libtbb*.so.*) + +foreach(_lib ${_tbb_libs}) + string(REGEX REPLACE "\\.2$" "" _lib_short ${_lib}) + get_filename_component(_lib "${_lib}" NAME) + execute_process( + COMMAND ${CMAKE_COMMAND} -E create_symlink ${_lib} ${_lib_short} + WORKING_DIRECTORY ${LIBDIR} + ) +endforeach() + +foreach(_lib ${_tbb_libs}) + get_filename_component(_lib_realpath "${_lib}" REALPATH) + if(NOT "${_lib_realpath}" IN_LIST _tbb_libs_realpath) + list(APPEND _tbb_libs_realpath ${_lib_realpath}) + endif() +endforeach() + +foreach(_lib ${_tbb_libs_realpath}) + execute_process(COMMAND ${CMAKE_STRIP} ${_lib}) +endforeach() diff --git a/projects/rocprofiler-systems/cmake/Formatting.cmake b/projects/rocprofiler-systems/cmake/Formatting.cmake new file mode 100644 index 0000000000..b1451ff91d --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Formatting.cmake @@ -0,0 +1,154 @@ +include_guard(DIRECTORY) + +# ----------------------------------------------------------------------------------------# +# +# Clang Tidy +# +# ----------------------------------------------------------------------------------------# + +# clang-tidy +macro(ROCPROFILER_SYSTEMS_ACTIVATE_CLANG_TIDY) + if(ROCPROFSYS_USE_CLANG_TIDY) + find_program(CLANG_TIDY_COMMAND NAMES clang-tidy) + rocprofiler_systems_add_feature(CLANG_TIDY_COMMAND "Path to clang-tidy command") + if(NOT CLANG_TIDY_COMMAND) + timemory_message( + WARNING "ROCPROFSYS_USE_CLANG_TIDY is ON but clang-tidy is not found!" + ) + set(ROCPROFSYS_USE_CLANG_TIDY OFF) + else() + set(CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY_COMMAND}) + + # 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 ${CMAKE_CURRENT_LIST_DIR}/.clang-tidy clang_tidy_sha1) + set(CLANG_TIDY_DEFINITIONS "CLANG_TIDY_SHA1=${clang_tidy_sha1}") + unset(clang_tidy_sha1) + endif() + endif() +endmacro() + +# ------------------------------------------------------------------------------# +# +# clang-format target +# +# ------------------------------------------------------------------------------# + +find_program(ROCPROFSYS_CLANG_FORMAT_EXE NAMES clang-format-18 clang-format) + +find_program(ROCPROFSYS_CMAKE_FORMAT_EXE NAMES gersemi) +find_program(ROCPROFSYS_BLACK_FORMAT_EXE NAMES black) + +add_custom_target(format-rocprofiler-systems) +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( + ROCPROFSYS_CLANG_FORMAT_EXE + OR ROCPROFSYS_BLACK_FORMAT_EXE + OR ROCPROFSYS_CMAKE_FORMAT_EXE +) + file( + GLOB_RECURSE sources + ${PROJECT_SOURCE_DIR}/source/*.cpp + ${PROJECT_SOURCE_DIR}/source/*.c + ) + file( + GLOB_RECURSE headers + ${PROJECT_SOURCE_DIR}/source/*.hpp + ${PROJECT_SOURCE_DIR}/source/*.hpp.in + ${PROJECT_SOURCE_DIR}/source/*.h + ${PROJECT_SOURCE_DIR}/source/*.h.in + ) + file( + GLOB_RECURSE examples + ${PROJECT_SOURCE_DIR}/examples/*.cpp + ${PROJECT_SOURCE_DIR}/examples/*.c + ${PROJECT_SOURCE_DIR}/examples/*.hpp + ${PROJECT_SOURCE_DIR}/examples/*.h + ) + file( + GLOB_RECURSE tests_source + ${PROJECT_SOURCE_DIR}/tests/source/*.cpp + ${PROJECT_SOURCE_DIR}/tests/source/*.hpp + ) + file(GLOB_RECURSE external ${PROJECT_SOURCE_DIR}/examples/lulesh/external/kokkos/*) + file( + GLOB_RECURSE cmake_files + ${PROJECT_SOURCE_DIR}/source/*CMakeLists.txt + ${PROJECT_SOURCE_DIR}/examples/*CMakeLists.txt + ${PROJECT_SOURCE_DIR}/tests/*CMakeLists.txt + ${PROJECT_SOURCE_DIR}/source/*.cmake + ${PROJECT_SOURCE_DIR}/examples/*.cmake + ${PROJECT_SOURCE_DIR}/tests/*.cmake + ${PROJECT_SOURCE_DIR}/cmake/*.cmake + ${PROJECT_SOURCE_DIR}/source/*.cmake + ) + list(APPEND cmake_files ${PROJECT_SOURCE_DIR}/CMakeLists.txt) + if(external) + list(REMOVE_ITEM examples ${external}) + list(REMOVE_ITEM cmake_files ${external}) + endif() + + if(ROCPROFSYS_CLANG_FORMAT_EXE) + add_custom_target( + format-rocprofiler-systems-source + ${ROCPROFSYS_CLANG_FORMAT_EXE} -i ${sources} ${headers} ${examples} + ${tests_source} + COMMENT + "[rocprofiler-systems] Running C++ formatter ${ROCPROFSYS_CLANG_FORMAT_EXE}..." + ) + endif() + + if(ROCPROFSYS_BLACK_FORMAT_EXE) + add_custom_target( + format-rocprofiler-systems-python + ${ROCPROFSYS_BLACK_FORMAT_EXE} -q ${PROJECT_SOURCE_DIR} + COMMENT + "[rocprofiler-systems] Running Python formatter ${ROCPROFSYS_BLACK_FORMAT_EXE}..." + ) + if(NOT TARGET format-python) + add_custom_target(format-python) + endif() + endif() + + if(ROCPROFSYS_CMAKE_FORMAT_EXE) + add_custom_target( + format-rocprofiler-systems-cmake + ${ROCPROFSYS_CMAKE_FORMAT_EXE} -i ${cmake_files} + COMMENT + "[rocprofiler-systems] Running CMake formatter ${ROCPROFSYS_CMAKE_FORMAT_EXE}..." + ) + if(NOT TARGET format-cmake) + add_custom_target(format-cmake) + endif() + endif() + + foreach(_TYPE source python cmake) + if(TARGET format-rocprofiler-systems-${_TYPE}) + add_dependencies( + format-rocprofiler-systems + format-rocprofiler-systems-${_TYPE} + ) + add_dependencies(format-${_TYPE} format-rocprofiler-systems-${_TYPE}) + endif() + endforeach() + + foreach(_TYPE source python) + if(TARGET format-rocprofiler-systems-${_TYPE}) + add_dependencies(format format-rocprofiler-systems-${_TYPE}) + endif() + endforeach() +else() + message(STATUS "clang-format could not be found. format build target not available.") +endif() diff --git a/projects/rocprofiler-systems/cmake/MacroUtilities.cmake b/projects/rocprofiler-systems/cmake/MacroUtilities.cmake new file mode 100644 index 0000000000..d7004bc3c4 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/MacroUtilities.cmake @@ -0,0 +1,1006 @@ +# include guard +include_guard(DIRECTORY) + +# 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 ROCPROFSYS_QUIET_CONFIG settings +# ----------------------------------------------------------------------- +# +function(ROCPROFILER_SYSTEMS_MESSAGE TYPE) + if(NOT ROCPROFSYS_QUIET_CONFIG) + message(${TYPE} "[rocprofiler-systems] ${ARGN}") + endif() +endfunction() + +# ----------------------------------------------------------------------- +# Save a set of variables with the given prefix +# ----------------------------------------------------------------------- +macro(ROCPROFILER_SYSTEMS_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_SYSTEMS_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_systems_capitalize - make a string capitalized (first letter is +# capital) usage: capitalize("SHARED" CShared) message(STATUS "-- CShared is +# \"${CShared}\"") $ -- CShared is "Shared" +function(ROCPROFILER_SYSTEMS_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_systems_strip_target( [FORCE] [EXPLICIT]) +# +# Creates a post-build command which strips a binary. FORCE flag will override +# +function(ROCPROFILER_SYSTEMS_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_systems_message( + FATAL_ERROR + "rocprofiler_systems_strip_target cannot deduce target from \"${ARGN}\"" + ) + endif() + + if(NOT TARGET "${_TARGET}") + rocprofiler_systems_message( + FATAL_ERROR + "rocprofiler_systems_strip_target not provided valid target: \"${_TARGET}\"" + ) + endif() + + if(CMAKE_STRIP AND (STRIP_FORCE OR ROCPROFSYS_STRIP_LIBRARIES)) + if(STRIP_EXPLICIT) + add_custom_command( + TARGET ${_TARGET} + POST_BUILD + COMMAND ${CMAKE_STRIP} ${STRIP_ARGS} $ + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Stripping ${_TARGET}..." + ) + else() + add_custom_command( + TARGET ${_TARGET} + POST_BUILD + COMMAND + ${CMAKE_STRIP} -w --keep-symbol="rocprofsys_init" + --keep-symbol="rocprofsys_finalize" + --keep-symbol="rocprofsys_push_trace" + --keep-symbol="rocprofsys_pop_trace" + --keep-symbol="rocprofsys_push_region" + --keep-symbol="rocprofsys_pop_region" + --keep-symbol="rocprofsys_set_env" --keep-symbol="rocprofsys_set_mpi" + --keep-symbol="rocprofsys_reset_preload" + --keep-symbol="rocprofsys_set_instrumented" + --keep-symbol="rocprofsys_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} $ + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Stripping ${_TARGET}..." + ) + endif() + endif() +endfunction() + +# ------------------------------------------------------------------------------# +# function add_rocprofiler_systems_test_target() +# +# Creates a target which runs ctest but depends on all the tests being built. +# +# function(ADD_ROCPROFSYS_TEST_TARGET) if(NOT TARGET rocprofiler-systems-test) +# add_custom_target( rocprofiler-systems-test COMMAND ${CMAKE_COMMAND} --build +# ${PROJECT_BINARY_DIR} --target test WORKING_DIRECTORY ${PROJECT_BINARY_DIR} COMMENT +# "Running tests...") endif() endfunction() + +# ----------------------------------------------------------------------------------------# +# macro rocprofiler_systems_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_SYSTEMS_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_systems_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_systems_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_SYSTEMS_TEST_FIND_PACKAGE PACKAGE_NAME OUTPUT_VAR) + cmake_parse_arguments(PACKAGE "" "" "UNSET" ${ARGN}) + find_package(${PROJECT_NAME} QUIET ${PACKAGE_UNPARSED_ARGUMENTS}) + if(NOT ${PROJECT_NAME}_FOUND) + set(${OUTPUT_VAR} OFF PARENT_SCOPE) + else() + set(${OUTPUT_VAR} ON PARENT_SCOPE) + endif() + foreach(_ARG ${PACKAGE_UNSET} FIND_PACKAGE_MESSAGE_DETAILS_${PROJECT_NAME}) + unset(${_ARG} CACHE) + endforeach() +endfunction() + +# ----------------------------------------------------------------------------------------# +# macro to add an interface lib +# +macro(ROCPROFILER_SYSTEMS_ADD_INTERFACE_LIBRARY _TARGET) + add_library(${_TARGET} INTERFACE) + add_library(${PROJECT_NAME}::${_TARGET} ALIAS ${_TARGET}) + install( + TARGETS ${_TARGET} + DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT core + EXPORT ${PROJECT_NAME}-interface-targets + OPTIONAL + ) + if(NOT "${ARGN}" STREQUAL "") + set_property( + GLOBAL + APPEND + PROPERTY + ${PROJECT_NAME}_CMAKE_INTERFACE_DOC + "${PROJECT_NAME}::${_TARGET}` | ${ARGN} |" + ) + endif() +endmacro() + +# ----------------------------------------------------------------------- +# function add_feature( ) Add a project feature, whose activation is +# specified by the existence of the variable , to the list of enabled/disabled +# features, plus a docstring describing the feature +# +function(ROCPROFILER_SYSTEMS_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(ROCPROFSYS_BUILD_DOCS) + set_property( + GLOBAL + APPEND + PROPERTY + ${PROJECT_NAME}_CMAKE_OPTIONS_DOC + "${_var}` | ${_description}${EXTRA_DESC} |" + ) + endif() + elseif("DOC" IN_LIST ARGN AND ROCPROFSYS_BUILD_DOCS) + set_property( + GLOBAL + APPEND + PROPERTY + ${PROJECT_NAME}_CMAKE_OPTIONS_DOC + "${_var}` | ${_description}${EXTRA_DESC} |" + ) + endif() +endfunction() + +# ----------------------------------------------------------------------------------------# +# function add_option( [NO_FEATURE]) Add an +# option and add as a feature if NO_FEATURE is not provided +# +function(ROCPROFILER_SYSTEMS_ADD_OPTION _NAME _MESSAGE _DEFAULT) + option(${_NAME} "${_MESSAGE}" ${_DEFAULT}) + if("NO_FEATURE" IN_LIST ARGN) + mark_as_advanced(${_NAME}) + else() + rocprofiler_systems_add_feature(${_NAME} "${_MESSAGE}") + if(ROCPROFSYS_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_systems_add_cache_option( +# [NO_FEATURE] [ADVANCED] [CMAKE_DEFINE]) +# +function(ROCPROFILER_SYSTEMS_ADD_CACHE_OPTION _NAME _MESSAGE _TYPE _DEFAULT) + 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_systems_add_feature(${_NAME} "${_MESSAGE}") + + if(ROCPROFSYS_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_systems_report_feature_changes() :: print changes in features +# +function(ROCPROFILER_SYSTEMS_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_systems_watch_for_change(${_feature}) + elseif("${_feature}" IN_LIST ARGN) + rocprofiler_systems_watch_for_change(${_feature}) + endif() + endforeach() +endfunction() + +# ----------------------------------------------------------------------------------------# +# function print_enabled_features() Print enabled features plus their docstrings. +# +function(ROCPROFILER_SYSTEMS_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_systems_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_SYSTEMS_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_SYSTEMS_PRINT_FEATURES) + rocprofiler_systems_report_feature_changes() + rocprofiler_systems_print_enabled_features() + rocprofiler_systems_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_systems_custom_compilation) + cmake_parse_arguments( + COMP + "GLOBAL;PROJECT" + "COMPILER" + "DIRECTORY;TARGET;SOURCE" + ${ARGN} + ) + + # find rocprof-sys-launch-compiler + find_program( + ROCPROFSYS_COMPILE_LAUNCHER + NAMES rocprof-sys-launch-compiler + HINTS ${PROJECT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} + PATHS ${PROJECT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} + PATH_SUFFIXES scripts bin + ) + + message(STATUS "rocprof_sys_compile_launcher: ${ROCPROFSYS_COMPILE_LAUNCHER}") + + if(NOT COMP_COMPILER) + message( + FATAL_ERROR + "rocprof_sys_custom_compilation not provided COMPILER argument" + ) + endif() + + if(NOT ROCPROFSYS_COMPILE_LAUNCHER) + message( + FATAL_ERROR + "rocprofiler-systems could not find 'rocprof-sys-launch-compiler'. Please set '-DROCPROFSYS_COMPILE_LAUNCHER=/path/to/launcher'" + ) + endif() + + if(COMP_GLOBAL) + # if global, don't bother setting others + set_property( + GLOBAL + PROPERTY + RULE_LAUNCH_COMPILE + "${ROCPROFSYS_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}" + ) + set_property( + GLOBAL + PROPERTY + RULE_LAUNCH_LINK + "${ROCPROFSYS_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}" + ) + else() + foreach(_TYPE PROJECT DIRECTORY TARGET SOURCE) + # make project/subproject scoping easy, e.g. + # rocprofiler_systems_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 + "${ROCPROFSYS_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}" + ) + set_property( + ${_TYPE} + ${_VAL} + PROPERTY + RULE_LAUNCH_LINK + "${ROCPROFSYS_COMPILE_LAUNCHER} ${COMP_COMPILER} ${CMAKE_CXX_COMPILER}" + ) + endforeach() + endif() + endforeach() + endif() +endfunction() + +function(ROCPROFILER_SYSTEMS_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_systems_watch_var_name ROCPROFSYS_WATCH_VALUE_${_var}) + if(DEFINED ${_rocprofiler_systems_watch_var_name}) + if("${${_var}}" STREQUAL "${${_rocprofiler_systems_watch_var_name}}") + return() + else() + rocprofiler_systems_message( + STATUS + "${_var} changed :: ${${_rocprofiler_systems_watch_var_name}} --> ${${_var}}" + ) + update_var(ON) + endif() + else() + if(NOT "${${_var}}" STREQUAL "") + rocprofiler_systems_message(STATUS "${_var} :: ${${_var}}") + update_var(ON) + endif() + endif() + + # store the value for the next run + set(${_rocprofiler_systems_watch_var_name} + "${${_var}}" + CACHE INTERNAL + "Last value of ${_var}" + FORCE + ) +endfunction() + +function(ROCPROFILER_SYSTEMS_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_systems_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_systems_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_systems_message(FATAL_ERROR "Directory '${_PATH}' does not exist") + elseif(NOT IS_DIRECTORY "${_PATH}" AND F_FAIL) + rocprofiler_systems_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_SYSTEMS_CHECK_PYTHON_DIRS_AND_VERSIONS) + cmake_parse_arguments(F "FAIL;UNSET" "RESULT_VARIABLE;OUTPUT_VARIABLE" "" ${ARGN}) + + list(LENGTH ROCPROFSYS_PYTHON_VERSIONS _NUM_PYTHON_VERSIONS) + list(LENGTH ROCPROFSYS_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_systems_message( + WARNING + "Error! Number of python versions : ${_NUM_PYTHON_VERSIONS}. VERSIONS :: ${ROCPROFSYS_PYTHON_VERSIONS}" + ) + rocprofiler_systems_message( + WARNING + "Error! Number of python root directories : ${_NUM_PYTHON_ROOT_DIRS}. ROOT DIRS :: ${ROCPROFSYS_PYTHON_ROOT_DIRS}" + ) + rocprofiler_systems_message( + FATAL_ERROR + "Error! Number of python versions != number of python root directories" + ) + elseif(F_UNSET) + unset(ROCPROFSYS_PYTHON_VERSIONS CACHE) + unset(ROCPROFSYS_PYTHON_ROOT_DIRS CACHE) + if(F_OUTPUT_VARIABLE) + set(${F_OUTPUT_VARIABLE} 0) + endif() + endif() + endif() +endfunction() + +# ---------------------------------------------------------------------------- +# Console scripts +# +function(ROCPROFILER_SYSTEMS_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(ROCPROFSYS_BUILD_TESTING OR ROCPROFSYS_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_SYSTEMS_FIND_STATIC_LIBRARY) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) + find_library(${ARGN}) +endfunction() + +function(ROCPROFILER_SYSTEMS_FIND_SHARED_LIBRARY) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) + find_library(${ARGN}) +endfunction() + +function(ROCPROFILER_SYSTEMS_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 $ + ${_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_SYSTEMS_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_systems_buildtree_tpl("${_TPL_TARGET}" "${_NEW_NAME}" + "${_BUILD_TREE_DIR}" ${ARGN} + ) + + install( + FILES $ + 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) diff --git a/projects/rocprofiler-systems/cmake/Modules/FindBoost.cmake b/projects/rocprofiler-systems/cmake/Modules/FindBoost.cmake new file mode 100644 index 0000000000..ec7e36005c --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Modules/FindBoost.cmake @@ -0,0 +1,3461 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying file +# Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +FindBoost +--------- + +Find Boost include dirs and libraries + +Use this module by invoking find_package with the form:: + + find_package(Boost + [version] [EXACT] # Minimum or EXACT version e.g. 1.67.0 + [REQUIRED] # Fail with error if Boost is not found + [COMPONENTS ...] # Boost libraries by their canonical name + # e.g. "date_time" for "libboost_date_time" + [OPTIONAL_COMPONENTS ...] + # Optional Boost libraries by their canonical name) + ) # e.g. "date_time" for "libboost_date_time" + +This module finds headers and requested component libraries OR a CMake +package configuration file provided by a "Boost CMake" build. For the +latter case skip to the "Boost CMake" section below. For the former +case results are reported in variables:: + + Boost_FOUND - True if headers and requested libraries were found + Boost_INCLUDE_DIRS - Boost include directories + Boost_LIBRARY_DIRS - Link directories for Boost libraries + Boost_LIBRARIES - Boost component libraries to be linked + Boost__FOUND - True if component was found ( is upper-case) + Boost__LIBRARY - Libraries to link for component (may include + target_link_libraries debug/optimized keywords) + Boost_VERSION_MACRO - BOOST_VERSION value from boost/version.hpp + Boost_VERSION_STRING - Boost version number in x.y.z format + Boost_VERSION - if CMP0093 NEW => same as Boost_VERSION_STRING + if CMP0093 OLD or unset => same as Boost_VERSION_MACRO + Boost_LIB_VERSION - Version string appended to library filenames + Boost_VERSION_MAJOR - Boost major version number (X in X.y.z) + alias: Boost_MAJOR_VERSION + Boost_VERSION_MINOR - Boost minor version number (Y in x.Y.z) + alias: Boost_MINOR_VERSION + Boost_VERSION_PATCH - Boost subminor version number (Z in x.y.Z) + alias: Boost_SUBMINOR_VERSION + Boost_VERSION_COUNT - Amount of version components (3) + Boost_LIB_DIAGNOSTIC_DEFINITIONS (Windows) + - Pass to add_definitions() to have diagnostic + information about Boost's automatic linking + displayed during compilation + +Note that Boost Python components require a Python version suffix +(Boost 1.67 and later), e.g. ``python36`` or ``python27`` for the +versions built against Python 3.6 and 2.7, respectively. This also +applies to additional components using Python including +``mpi_python`` and ``numpy``. Earlier Boost releases may use +distribution-specific suffixes such as ``2``, ``3`` or ``2.7``. +These may also be used as suffixes, but note that they are not +portable. + +This module reads hints about search locations from variables:: + + BOOST_ROOT - Preferred installation prefix + (or BOOSTROOT) + BOOST_INCLUDEDIR - Preferred include directory e.g. /include + BOOST_LIBRARYDIR - Preferred library directory e.g. /lib + Boost_NO_SYSTEM_PATHS - Set to ON to disable searching in locations not + specified by these hint variables. Default is OFF. + Boost_ADDITIONAL_VERSIONS + - List of Boost versions not known to this module + (Boost install locations may contain the version) + +and saves search results persistently in CMake cache entries:: + + Boost_INCLUDE_DIR - Directory containing Boost headers + Boost_LIBRARY_DIR_RELEASE - Directory containing release Boost libraries + Boost_LIBRARY_DIR_DEBUG - Directory containing debug Boost libraries + Boost__LIBRARY_DEBUG - Component library debug variant + Boost__LIBRARY_RELEASE - Component library release variant + +The following :prop_tgt:`IMPORTED` targets are also defined:: + + Boost::headers - Target for header-only dependencies + (Boost include directory) + alias: Boost::boost + Boost:: - Target for specific component dependency + (shared or static library); is lower- + case + Boost::diagnostic_definitions - interface target to enable diagnostic + information about Boost's automatic linking + during compilation (adds BOOST_LIB_DIAGNOSTIC) + Boost::disable_autolinking - interface target to disable automatic + linking with MSVC (adds BOOST_ALL_NO_LIB) + Boost::dynamic_linking - interface target to enable dynamic linking + linking with MSVC (adds BOOST_ALL_DYN_LINK) + +Implicit dependencies such as ``Boost::filesystem`` requiring +``Boost::system`` will be automatically detected and satisfied, even +if system is not specified when using :command:`find_package` and if +``Boost::system`` is not added to :command:`target_link_libraries`. If using +``Boost::thread``, then ``Threads::Threads`` will also be added automatically. + +It is important to note that the imported targets behave differently +than variables created by this module: multiple calls to +:command:`find_package(Boost)` in the same directory or sub-directories with +different options (e.g. static or shared) will not override the +values of the targets created by the first call. + +Users may set these hints or results as ``CACHE`` entries. Projects +should not read these entries directly but instead use the above +result variables. Note that some hint names start in upper-case +"BOOST". One may specify these as environment variables if they are +not specified as CMake variables or cache entries. + +This module first searches for the ``Boost`` header files using the above +hint variables (excluding ``BOOST_LIBRARYDIR``) and saves the result in +``Boost_INCLUDE_DIR``. Then it searches for requested component libraries +using the above hints (excluding ``BOOST_INCLUDEDIR`` and +``Boost_ADDITIONAL_VERSIONS``), "lib" directories near ``Boost_INCLUDE_DIR``, +and the library name configuration settings below. It saves the +library directories in ``Boost_LIBRARY_DIR_DEBUG`` and +``Boost_LIBRARY_DIR_RELEASE`` and individual library +locations in ``Boost__LIBRARY_DEBUG`` and ``Boost__LIBRARY_RELEASE``. +When one changes settings used by previous searches in the same build +tree (excluding environment variables) this module discards previous +search results affected by the changes and searches again. + +Boost libraries come in many variants encoded in their file name. +Users or projects may tell this module which variant to find by +setting variables:: + + Boost_USE_DEBUG_LIBS - Set to ON or OFF to specify whether to search + and use the debug libraries. Default is ON. + Boost_USE_RELEASE_LIBS - Set to ON or OFF to specify whether to search + and use the release libraries. Default is ON. + Boost_USE_MULTITHREADED - Set to OFF to use the non-multithreaded + libraries ('mt' tag). Default is ON. + Boost_USE_STATIC_LIBS - Set to ON to force the use of the static + libraries. Default is OFF. + Boost_USE_STATIC_RUNTIME - Set to ON or OFF to specify whether to use + libraries linked statically to the C++ runtime + ('s' tag). Default is platform dependent. + Boost_USE_DEBUG_RUNTIME - Set to ON or OFF to specify whether to use + libraries linked to the MS debug C++ runtime + ('g' tag). Default is ON. + Boost_USE_DEBUG_PYTHON - Set to ON to use libraries compiled with a + debug Python build ('y' tag). Default is OFF. + Boost_USE_STLPORT - Set to ON to use libraries compiled with + STLPort ('p' tag). Default is OFF. + Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS + - Set to ON to use libraries compiled with + STLPort deprecated "native iostreams" + ('n' tag). Default is OFF. + Boost_COMPILER - Set to the compiler-specific library suffix + (e.g. "-gcc43"). Default is auto-computed + for the C++ compiler in use. A list may be + used if multiple compatible suffixes should + be tested for, in decreasing order of + preference. + Boost_ARCHITECTURE - Set to the architecture-specific library suffix + (e.g. "-x64"). Default is auto-computed for the + C++ compiler in use. + Boost_THREADAPI - Suffix for "thread" component library name, + such as "pthread" or "win32". Names with + and without this suffix will both be tried. + Boost_NAMESPACE - Alternate namespace used to build boost with + e.g. if set to "myboost", will search for + myboost_thread instead of boost_thread. + +Other variables one may set to control this module are:: + + Boost_DEBUG - Set to ON to enable debug output from FindBoost. + Please enable this before filing any bug report. + Boost_REALPATH - Set to ON to resolve symlinks for discovered + libraries to assist with packaging. For example, + the "system" component library may be resolved to + "/usr/lib/libboost_system.so.1.67.0" instead of + "/usr/lib/libboost_system.so". This does not + affect linking and should not be enabled unless + the user needs this information. + Boost_LIBRARY_DIR - Default value for Boost_LIBRARY_DIR_RELEASE and + Boost_LIBRARY_DIR_DEBUG. + +On Visual Studio and Borland compilers Boost headers request automatic +linking to corresponding libraries. This requires matching libraries +to be linked explicitly or available in the link library search path. +In this case setting ``Boost_USE_STATIC_LIBS`` to ``OFF`` may not achieve +dynamic linking. Boost automatic linking typically requests static +libraries with a few exceptions (such as ``Boost.Python``). Use:: + + add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS}) + +to ask Boost to report information about automatic linking requests. + +Example to find Boost headers only:: + + find_package(Boost 1.36.0) + if(Boost_FOUND) + include_directories(${Boost_INCLUDE_DIRS}) + add_executable(foo foo.cc) + endif() + +Example to find Boost libraries and use imported targets:: + + find_package(Boost 1.56 REQUIRED COMPONENTS + date_time filesystem iostreams) + add_executable(foo foo.cc) + target_link_libraries(foo Boost::date_time Boost::filesystem + Boost::iostreams) + +Example to find Boost Python 3.6 libraries and use imported targets:: + + find_package(Boost 1.67 REQUIRED COMPONENTS + python36 numpy36) + add_executable(foo foo.cc) + target_link_libraries(foo Boost::python36 Boost::numpy36) + +Example to find Boost headers and some *static* (release only) libraries:: + + set(Boost_USE_STATIC_LIBS ON) # only find static libs + set(Boost_USE_DEBUG_LIBS OFF) # ignore debug libs and + set(Boost_USE_RELEASE_LIBS ON) # only find release libs + set(Boost_USE_MULTITHREADED ON) + set(Boost_USE_STATIC_RUNTIME OFF) + find_package(Boost 1.66.0 COMPONENTS date_time filesystem system ...) + if(Boost_FOUND) + include_directories(${Boost_INCLUDE_DIRS}) + add_executable(foo foo.cc) + target_link_libraries(foo ${Boost_LIBRARIES}) + endif() + +Boost CMake +^^^^^^^^^^^ + +If Boost was built using the boost-cmake project or from Boost 1.70.0 on +it provides a package configuration file for use with find_package's config mode. +This module looks for the package configuration file called +``BoostConfig.cmake`` or ``boost-config.cmake`` and stores the result in +``CACHE`` entry "Boost_DIR". If found, the package configuration file is loaded +and this module returns with no further action. See documentation of +the Boost CMake package configuration for details on what it provides. + +Set ``Boost_NO_BOOST_CMAKE`` to ``ON``, to disable the search for boost-cmake. +#]=======================================================================] + +# The FPHSA helper provides standard way of reporting final search results to the user +# including the version and component checks. +include(FindPackageHandleStandardArgs) + +# Save project's policies +cmake_policy(PUSH) +cmake_policy(SET CMP0057 NEW) # if IN_LIST +if(NOT CMAKE_VERSION VERSION_LESS 3.17) + cmake_policy(SET CMP0102 NEW) # if mark_as_advanced(non_cache_var) +endif() + +function(_boost_get_existing_target component target_var) + set(names "${component}") + if(component MATCHES "^([a-z_]*)(python|numpy)([1-9])\\.?([0-9])?$") + # handle pythonXY and numpyXY versioned components and also python X.Y, mpi_python + # etc. + list( + APPEND + names + "${CMAKE_MATCH_1}${CMAKE_MATCH_2}" # python + "${CMAKE_MATCH_1}${CMAKE_MATCH_2}${CMAKE_MATCH_3}" # pythonX + "${CMAKE_MATCH_1}${CMAKE_MATCH_2}${CMAKE_MATCH_3}${CMAKE_MATCH_4}" # pythonXY + ) + endif() + # https://github.com/boost-cmake/boost-cmake uses boost::file_system etc. So handle + # similar constructions of target names + string(TOLOWER "${component}" lower_component) + list(APPEND names "${lower_component}") + foreach(prefix Boost boost) + foreach(name IN LISTS names) + if(TARGET "${prefix}::${name}") + # The target may be an INTERFACE library that wraps around a single other + # target for compatibility. Unwrap this layer so we can extract real + # info. + if("${name}" MATCHES "^(python|numpy|mpi_python)([1-9])([0-9])$") + set(name_nv "${CMAKE_MATCH_1}") + if(TARGET "${prefix}::${name_nv}") + get_property(type TARGET "${prefix}::${name}" PROPERTY TYPE) + if(type STREQUAL "INTERFACE_LIBRARY") + get_property( + lib + TARGET "${prefix}::${name}" + PROPERTY INTERFACE_LINK_LIBRARIES + ) + if("${lib}" STREQUAL "${prefix}::${name_nv}") + set(${target_var} "${prefix}::${name_nv}" PARENT_SCOPE) + return() + endif() + endif() + endif() + endif() + set(${target_var} "${prefix}::${name}" PARENT_SCOPE) + return() + endif() + endforeach() + endforeach() + set(${target_var} "" PARENT_SCOPE) +endfunction() + +function(_boost_get_canonical_target_name component target_var) + string(TOLOWER "${component}" component) + if(component MATCHES "^([a-z_]*)(python|numpy)([1-9])\\.?([0-9])?$") + # handle pythonXY and numpyXY versioned components and also python X.Y, mpi_python + # etc. + set(${target_var} "Boost::${CMAKE_MATCH_1}${CMAKE_MATCH_2}" PARENT_SCOPE) + else() + set(${target_var} "Boost::${component}" PARENT_SCOPE) + endif() +endfunction() + +macro(_boost_set_in_parent_scope name value) + # Set a variable in parent scope and make it visibile in current scope + set(${name} "${value}" PARENT_SCOPE) + set(${name} "${value}") +endmacro() + +macro(_boost_set_if_unset name value) + if(NOT ${name}) + _boost_set_in_parent_scope(${name} "${value}") + endif() +endmacro() + +macro(_boost_set_cache_if_unset name value) + if(NOT ${name}) + set(${name} "${value}" CACHE STRING "" FORCE) + endif() +endmacro() + +macro(_boost_append_include_dir target) + get_target_property(inc "${target}" INTERFACE_INCLUDE_DIRECTORIES) + if(inc) + list(APPEND include_dirs "${inc}") + endif() +endmacro() + +function(_boost_set_legacy_variables_from_config) + # Set legacy variables for compatibility if not set + set(include_dirs "") + set(library_dirs "") + set(libraries "") + # Header targets Boost::headers or Boost::boost + foreach(comp headers boost) + _boost_get_existing_target(${comp} target) + if(TARGET) + _boost_append_include_dir("${target}") + endif() + endforeach() + # Library targets + foreach(comp IN LISTS Boost_FIND_COMPONENTS) + string(TOUPPER ${comp} uppercomp) + # Overwrite if set + _boost_set_in_parent_scope(Boost_${uppercomp}_FOUND "${Boost_${comp}_FOUND}") + if(Boost_${comp}_FOUND) + _boost_get_existing_target(${comp} target) + if(NOT TARGET) + if(Boost_DEBUG OR Boost_VERBOSE) + message( + WARNING + "Could not find imported target for required component '${comp}'. Legacy variables for this component might be missing. Refer to the documentation of your Boost installation for help on variables to use." + ) + endif() + continue() + endif() + _boost_append_include_dir("${target}") + _boost_set_if_unset(Boost_${uppercomp}_LIBRARY "${target}") + _boost_set_if_unset( + Boost_${uppercomp}_LIBRARIES "${target}" + ) # Very old legacy variable + list(APPEND libraries "${target}") + get_property(type TARGET "${target}" PROPERTY TYPE) + if(NOT type STREQUAL "INTERFACE_LIBRARY") + foreach(cfg RELEASE DEBUG) + get_target_property(lib ${target} IMPORTED_LOCATION_${cfg}) + if(lib) + get_filename_component(lib_dir "${lib}" DIRECTORY) + list(APPEND library_dirs ${lib_dir}) + _boost_set_cache_if_unset(Boost_${uppercomp}_LIBRARY_${cfg} + "${lib}" + ) + endif() + endforeach() + elseif(Boost_DEBUG OR Boost_VERBOSE) + # For projects using only the Boost::* targets this warning can be safely + # ignored. + if(NOT Boost_FIND_QUIETLY) + message( + WARNING + "Imported target '${target}' for required component '${comp}' has no artifact. Legacy variables for this component might be missing. Refer to the documentation of your Boost installation for help on variables to use." + ) + endif() + endif() + _boost_get_canonical_target_name("${comp}" canonical_target) + if(NOT TARGET "${canonical_target}") + add_library("${canonical_target}" INTERFACE IMPORTED) + target_link_libraries("${canonical_target}" INTERFACE "${target}") + endif() + endif() + endforeach() + list(REMOVE_DUPLICATES include_dirs) + list(REMOVE_DUPLICATES library_dirs) + _boost_set_if_unset(Boost_INCLUDE_DIRS "${include_dirs}") + _boost_set_if_unset(Boost_LIBRARY_DIRS "${library_dirs}") + _boost_set_if_unset(Boost_LIBRARIES "${libraries}") + _boost_set_if_unset( + Boost_VERSION_STRING + "${Boost_VERSION_MAJOR}.${Boost_VERSION_MINOR}.${Boost_VERSION_PATCH}" + ) + find_path( + Boost_INCLUDE_DIR + NAMES boost/version.hpp boost/config.hpp + HINTS ${Boost_INCLUDE_DIRS} + NO_DEFAULT_PATH + ) + if(NOT Boost_VERSION_MACRO OR NOT Boost_LIB_VERSION) + set(version_file ${Boost_INCLUDE_DIR}/boost/version.hpp) + if(EXISTS "${version_file}") + file(STRINGS "${version_file}" contents REGEX "#define BOOST_(LIB_)?VERSION ") + if(contents MATCHES "#define BOOST_VERSION ([0-9]+)") + _boost_set_if_unset(Boost_VERSION_MACRO "${CMAKE_MATCH_1}") + endif() + if(contents MATCHES "#define BOOST_LIB_VERSION \"([0-9_]+)\"") + _boost_set_if_unset(Boost_LIB_VERSION "${CMAKE_MATCH_1}") + endif() + endif() + endif() + _boost_set_if_unset(Boost_MAJOR_VERSION ${Boost_VERSION_MAJOR}) + _boost_set_if_unset(Boost_MINOR_VERSION ${Boost_VERSION_MINOR}) + _boost_set_if_unset(Boost_SUBMINOR_VERSION ${Boost_VERSION_PATCH}) + if(WIN32) + _boost_set_if_unset(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC") + endif() + if(NOT TARGET Boost::headers) + add_library(Boost::headers INTERFACE IMPORTED) + target_include_directories(Boost::headers INTERFACE ${Boost_INCLUDE_DIRS}) + endif() + # Legacy targets w/o functionality as all handled by defined targets + foreach(lib diagnostic_definitions disable_autolinking dynamic_linking) + if(NOT TARGET Boost::${lib}) + add_library(Boost::${lib} INTERFACE IMPORTED) + endif() + endforeach() + if(NOT TARGET Boost::boost) + add_library(Boost::boost INTERFACE IMPORTED) + target_link_libraries(Boost::boost INTERFACE Boost::headers) + endif() +endfunction() + +# ------------------------------------------------------------------------------- +# Before we go searching, check whether a boost cmake package is available, unless the +# user specifically asked NOT to search for one. +# +# If Boost_DIR is set, this behaves as any find_package call would. If not, it looks at +# BOOST_ROOT and BOOSTROOT to find Boost. +# +if(NOT Boost_NO_BOOST_CMAKE) + # If Boost_DIR is not set, look for BOOSTROOT and BOOST_ROOT as alternatives, since + # these are more conventional for Boost. + if("$ENV{Boost_DIR}" STREQUAL "") + if(NOT "$ENV{BOOST_ROOT}" STREQUAL "") + set(ENV{Boost_DIR} $ENV{BOOST_ROOT}) + elseif(NOT "$ENV{BOOSTROOT}" STREQUAL "") + set(ENV{Boost_DIR} $ENV{BOOSTROOT}) + endif() + endif() + + # Do the same find_package call but look specifically for the CMake version. Note that + # args are passed in the Boost_FIND_xxxxx variables, so there is no need to delegate + # them to this find_package call. + find_package(Boost QUIET NO_MODULE) + if(DEFINED Boost_DIR) + mark_as_advanced(Boost_DIR) + endif() + + # If we found a boost cmake package, then we're done. Print out what we found. + # Otherwise let the rest of the module try to find it. + if(Boost_FOUND) + # Convert component found variables to standard variables if required Necessary + # for legacy boost-cmake and 1.70 builtin BoostConfig + if(Boost_FIND_COMPONENTS) + # Ignore the meta-component "ALL", introduced by Boost 1.73 + list(REMOVE_ITEM Boost_FIND_COMPONENTS "ALL") + + foreach(_comp IN LISTS Boost_FIND_COMPONENTS) + if(DEFINED Boost_${_comp}_FOUND) + continue() + endif() + string(TOUPPER ${_comp} _uppercomp) + if(DEFINED Boost${_comp}_FOUND) # legacy boost-cmake project + set(Boost_${_comp}_FOUND ${Boost${_comp}_FOUND}) + elseif(DEFINED Boost_${_uppercomp}_FOUND) # Boost 1.70 + set(Boost_${_comp}_FOUND ${Boost_${_uppercomp}_FOUND}) + endif() + endforeach() + endif() + + find_package_handle_standard_args(Boost HANDLE_COMPONENTS CONFIG_MODE) + _boost_set_legacy_variables_from_config() + + # Restore project's policies + cmake_policy(POP) + return() + endif() +endif() + +# ------------------------------------------------------------------------------- +# FindBoost functions & macros +# + +# +# Print debug text if Boost_DEBUG is set. Call example: +# _Boost_DEBUG_PRINT("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" "debug +# message") +# +function(_Boost_DEBUG_PRINT file line text) + if(Boost_DEBUG) + message(STATUS "[ ${file}:${line} ] ${text}") + endif() +endfunction() + +# +# _Boost_DEBUG_PRINT_VAR(file line variable_name [ENVIRONMENT] [SOURCE "short explanation +# of origin of var value"]) +# +# ENVIRONMENT - look up environment variable instead of CMake variable +# +# Print variable name and its value if Boost_DEBUG is set. Call example: +# _Boost_DEBUG_PRINT_VAR("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" +# BOOST_ROOT) +# +function(_Boost_DEBUG_PRINT_VAR file line name) + if(Boost_DEBUG) + cmake_parse_arguments(_args "ENVIRONMENT" "SOURCE" "" ${ARGN}) + + unset(source) + if(_args_SOURCE) + set(source " (${_args_SOURCE})") + endif() + + if(_args_ENVIRONMENT) + if(DEFINED ENV{${name}}) + set(value "\"$ENV{${name}}\"") + else() + set(value "") + endif() + set(_name "ENV{${name}}") + else() + if(DEFINED "${name}") + set(value "\"${${name}}\"") + else() + set(value "") + endif() + set(_name "${name}") + endif() + + _boost_debug_print("${file}" "${line}" "${_name} = ${value}${source}") + endif() +endfunction() + +# ######################################################################################## +# +# Check the existence of the libraries. +# +# ######################################################################################## +# This macro was taken directly from the FindQt4.cmake file that is included with the +# CMake distribution. This is NOT my work. All work was done by the original authors of +# the FindQt4.cmake file. Only minor modifications were made to remove references to Qt +# and make this file more generally applicable And ELSE/ENDIF pairs were removed for +# readability. +# ######################################################################################## + +macro(_Boost_ADJUST_LIB_VARS basename) + if(Boost_INCLUDE_DIR) + if(Boost_${basename}_LIBRARY_DEBUG AND Boost_${basename}_LIBRARY_RELEASE) + # if the generator is multi-config or if CMAKE_BUILD_TYPE is set for + # single-config generators, set optimized and debug libraries + get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(_isMultiConfig OR CMAKE_BUILD_TYPE) + set(Boost_${basename}_LIBRARY + optimized + ${Boost_${basename}_LIBRARY_RELEASE} + debug + ${Boost_${basename}_LIBRARY_DEBUG} + ) + else() + # For single-config generators where CMAKE_BUILD_TYPE has no value, just + # use the release libraries + set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE}) + endif() + # FIXME: This probably should be set for both cases + set(Boost_${basename}_LIBRARIES + optimized + ${Boost_${basename}_LIBRARY_RELEASE} + debug + ${Boost_${basename}_LIBRARY_DEBUG} + ) + endif() + + # if only the release version was found, set the debug variable also to the + # release version + if(Boost_${basename}_LIBRARY_RELEASE AND NOT Boost_${basename}_LIBRARY_DEBUG) + set(Boost_${basename}_LIBRARY_DEBUG ${Boost_${basename}_LIBRARY_RELEASE}) + set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE}) + set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_RELEASE}) + endif() + + # if only the debug version was found, set the release variable also to the debug + # version + if(Boost_${basename}_LIBRARY_DEBUG AND NOT Boost_${basename}_LIBRARY_RELEASE) + set(Boost_${basename}_LIBRARY_RELEASE ${Boost_${basename}_LIBRARY_DEBUG}) + set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_DEBUG}) + set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_DEBUG}) + endif() + + # If the debug & release library ends up being the same, omit the keywords + if( + "${Boost_${basename}_LIBRARY_RELEASE}" + STREQUAL + "${Boost_${basename}_LIBRARY_DEBUG}" + ) + set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE}) + set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_RELEASE}) + endif() + + if(Boost_${basename}_LIBRARY AND Boost_${basename}_HEADER) + set(Boost_${basename}_FOUND ON) + if("x${basename}" STREQUAL "xTHREAD" AND NOT TARGET Threads::Threads) + string(APPEND Boost_ERROR_REASON_THREAD " (missing dependency: Threads)") + set(Boost_THREAD_FOUND OFF) + endif() + endif() + endif() + # Make variables changeable to the advanced user + mark_as_advanced(Boost_${basename}_LIBRARY_RELEASE Boost_${basename}_LIBRARY_DEBUG) +endmacro() + +# Detect changes in used variables. Compares the current variable value with the last one. +# In short form: v != v_LAST -> CHANGED = 1 v is defined, v_LAST not +# -> CHANGED = 1 v is not defined, but v_LAST is -> CHANGED = 1 otherwise -> CHANGED = 0 +# CHANGED is returned in variable named ${changed_var} +macro(_Boost_CHANGE_DETECT changed_var) + set(${changed_var} 0) + foreach(v ${ARGN}) + if(DEFINED _Boost_COMPONENTS_SEARCHED) + if(${v}) + if(_${v}_LAST) + string(COMPARE NOTEQUAL "${${v}}" "${_${v}_LAST}" _${v}_CHANGED) + else() + set(_${v}_CHANGED 1) + endif() + elseif(_${v}_LAST) + set(_${v}_CHANGED 1) + endif() + if(_${v}_CHANGED) + set(${changed_var} 1) + endif() + else() + set(_${v}_CHANGED 0) + endif() + endforeach() +endmacro() + +# +# Find the given library (var). Use 'build_type' to support different lib paths for +# RELEASE or DEBUG builds +# +macro(_Boost_FIND_LIBRARY var build_type) + find_library(${var} ${ARGN}) + + if(${var}) + # If this is the first library found then save Boost_LIBRARY_DIR_[RELEASE,DEBUG]. + if(NOT Boost_LIBRARY_DIR_${build_type}) + get_filename_component(_dir "${${var}}" PATH) + set(Boost_LIBRARY_DIR_${build_type} + "${_dir}" + CACHE PATH + "Boost library directory ${build_type}" + FORCE + ) + endif() + elseif(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT) + # Try component-specific hints but do not save Boost_LIBRARY_DIR_[RELEASE,DEBUG]. + find_library(${var} HINTS ${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT} ${ARGN}) + endif() + + # If Boost_LIBRARY_DIR_[RELEASE,DEBUG] is known then search only there. + if(Boost_LIBRARY_DIR_${build_type}) + set(_boost_LIBRARY_SEARCH_DIRS_${build_type} + ${Boost_LIBRARY_DIR_${build_type}} + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_LIBRARY_DIR_${build_type}" + ) + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "_boost_LIBRARY_SEARCH_DIRS_${build_type}" + ) + endif() +endmacro() + +# ------------------------------------------------------------------------------- + +# Convert CMAKE_CXX_COMPILER_VERSION to boost compiler suffix version. +function( + _Boost_COMPILER_DUMPVERSION + _OUTPUT_VERSION + _OUTPUT_VERSION_MAJOR + _OUTPUT_VERSION_MINOR +) + string( + REGEX REPLACE + "([0-9]+)\\.([0-9]+)(\\.[0-9]+)?" + "\\1" + _boost_COMPILER_VERSION_MAJOR + "${CMAKE_CXX_COMPILER_VERSION}" + ) + string( + REGEX REPLACE + "([0-9]+)\\.([0-9]+)(\\.[0-9]+)?" + "\\2" + _boost_COMPILER_VERSION_MINOR + "${CMAKE_CXX_COMPILER_VERSION}" + ) + + set(_boost_COMPILER_VERSION + "${_boost_COMPILER_VERSION_MAJOR}${_boost_COMPILER_VERSION_MINOR}" + ) + + set(${_OUTPUT_VERSION} ${_boost_COMPILER_VERSION} PARENT_SCOPE) + set(${_OUTPUT_VERSION_MAJOR} ${_boost_COMPILER_VERSION_MAJOR} PARENT_SCOPE) + set(${_OUTPUT_VERSION_MINOR} ${_boost_COMPILER_VERSION_MINOR} PARENT_SCOPE) +endfunction() + +# +# Take a list of libraries with "thread" in it and prepend duplicates with +# "thread_${Boost_THREADAPI}" at the front of the list +# +function(_Boost_PREPEND_LIST_WITH_THREADAPI _output) + set(_orig_libnames ${ARGN}) + string( + REPLACE + "thread" + "thread_${Boost_THREADAPI}" + _threadapi_libnames + "${_orig_libnames}" + ) + set(${_output} ${_threadapi_libnames} ${_orig_libnames} PARENT_SCOPE) +endfunction() + +# +# If a library is found, replace its cache entry with its REALPATH +# +function(_Boost_SWAP_WITH_REALPATH _library _docstring) + if(${_library}) + get_filename_component(_boost_filepathreal ${${_library}} REALPATH) + unset(${_library} CACHE) + set(${_library} ${_boost_filepathreal} CACHE FILEPATH "${_docstring}") + endif() +endfunction() + +function(_Boost_CHECK_SPELLING _var) + if(${_var}) + string(TOUPPER ${_var} _var_UC) + message( + FATAL_ERROR + "ERROR: ${_var} is not the correct spelling. The proper spelling is ${_var_UC}." + ) + endif() +endfunction() + +# Guesses Boost's compiler prefix used in built library names Returns the guess by setting +# the variable pointed to by _ret +function(_Boost_GUESS_COMPILER_PREFIX _ret) + if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntel") + if(WIN32) + set(_boost_COMPILER "-iw") + else() + set(_boost_COMPILER "-il") + endif() + elseif(GHSMULTI) + set(_boost_COMPILER "-ghs") + elseif( + "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" + OR "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC" + ) + if(MSVC_TOOLSET_VERSION GREATER_EQUAL 150) + # Not yet known. + set(_boost_COMPILER "") + elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 140) + # MSVC toolset 14.x versions are forward compatible. + set(_boost_COMPILER "") + foreach( + v + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0 + ) + if(MSVC_TOOLSET_VERSION GREATER_EQUAL 14${v}) + list(APPEND _boost_COMPILER "-vc14${v}") + endif() + endforeach() + elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80) + set(_boost_COMPILER "-vc${MSVC_TOOLSET_VERSION}") + elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.10) + set(_boost_COMPILER "-vc71") + elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13) # Good luck! + set(_boost_COMPILER "-vc7") # yes, this is correct + else() # VS 6.0 Good luck! + set(_boost_COMPILER "-vc6") # yes, this is correct + endif() + + if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang") + string(REPLACE "." ";" VERSION_LIST "${CMAKE_CXX_COMPILER_VERSION}") + list(GET VERSION_LIST 0 CLANG_VERSION_MAJOR) + set(_boost_COMPILER "-clangw${CLANG_VERSION_MAJOR};${_boost_COMPILER}") + endif() + elseif(BORLAND) + set(_boost_COMPILER "-bcb") + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") + set(_boost_COMPILER "-sw") + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "XL") + set(_boost_COMPILER "-xlc") + elseif(MINGW) + if(Boost_VERSION_STRING VERSION_LESS 1.34) + set(_boost_COMPILER "-mgw") # no GCC version encoding prior to 1.34 + else() + _boost_compiler_dumpversion( + _boost_COMPILER_VERSION _boost_COMPILER_VERSION_MAJOR + _boost_COMPILER_VERSION_MINOR + ) + set(_boost_COMPILER "-mgw${_boost_COMPILER_VERSION}") + endif() + elseif(UNIX) + _boost_compiler_dumpversion(_boost_COMPILER_VERSION _boost_COMPILER_VERSION_MAJOR + _boost_COMPILER_VERSION_MINOR + ) + if(NOT Boost_VERSION_STRING VERSION_LESS 1.69.0) + # From GCC 5 and clang 4, versioning changes and minor becomes patch. For + # those compilers, patch is exclude from compiler tag in Boost 1.69+ library + # naming. + if( + CMAKE_CXX_COMPILER_ID STREQUAL "GNU" + AND _boost_COMPILER_VERSION_MAJOR VERSION_GREATER 4 + ) + set(_boost_COMPILER_VERSION "${_boost_COMPILER_VERSION_MAJOR}") + elseif( + CMAKE_CXX_COMPILER_ID STREQUAL "Clang" + AND _boost_COMPILER_VERSION_MAJOR VERSION_GREATER 3 + ) + set(_boost_COMPILER_VERSION "${_boost_COMPILER_VERSION_MAJOR}") + endif() + endif() + + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if(Boost_VERSION_STRING VERSION_LESS 1.34) + set(_boost_COMPILER "-gcc") # no GCC version encoding prior to 1.34 + else() + # Determine which version of GCC we have. + if(APPLE) + if(Boost_VERSION_STRING VERSION_LESS 1.36.0) + # In Boost <= 1.35.0, there is no mangled compiler name for the + # macOS/Darwin version of GCC. + set(_boost_COMPILER "") + else() + # In Boost 1.36.0 and newer, the mangled compiler name used on + # macOS/Darwin is "xgcc". + set(_boost_COMPILER "-xgcc${_boost_COMPILER_VERSION}") + endif() + else() + set(_boost_COMPILER "-gcc${_boost_COMPILER_VERSION}") + endif() + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + # TODO: Find out any Boost version constraints vs clang support. + set(_boost_COMPILER "-clang${_boost_COMPILER_VERSION}") + endif() + else() + set(_boost_COMPILER "") + endif() + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "_boost_COMPILER" SOURCE "guessed" + ) + set(${_ret} ${_boost_COMPILER} PARENT_SCOPE) +endfunction() + +# +# Get component dependencies. Requires the dependencies to have been defined for the +# Boost release version. +# +# component - the component to check _ret - list of library dependencies +# +function(_Boost_COMPONENT_DEPENDENCIES component _ret) + # Note: to add a new Boost release, run + # + # % cmake -DBOOST_DIR=/path/to/boost/source -P Utilities/Scripts/BoostScanDeps.cmake + # + # The output may be added in a new block below. If it's the same as the previous + # release, simply update the version range of the block for the previous release. Also + # check if any new components have been added, and add any new components to + # _Boost_COMPONENT_HEADERS. + # + # This information was originally generated by running BoostScanDeps.cmake against + # every boost release to date supported by FindBoost: + # + # % for version in /path/to/boost/sources/* do cmake -DBOOST_DIR=$version -P + # Utilities/Scripts/BoostScanDeps.cmake done + # + # The output was then updated by search and replace with these regexes: + # + # * Strip message(STATUS) prefix dashes s;^-- ;; + # * Indent s;^set(; set(;; + # * Add conditionals s;Scanning /path/to/boost/sources/boost_\(.*\)_\(.*\)_\(.*); + # elseif(NOT Boost_VERSION_STRING VERSION_LESS \1\.\2\.\3 AND Boost_VERSION_STRING + # VERSION_LESS xxxx); + # + # This results in the logic seen below, but will require the xxxx replacing with the + # following Boost release version (or the next minor version to be released, e.g. 1.59 + # was the latest at the time of writing, making 1.60 the next. Identical consecutive + # releases were then merged together by updating the end range of the first block and + # removing the following redundant blocks. + # + # Running the script against all historical releases should be required only if the + # BoostScanDeps.cmake script logic is changed. The addition of a new release should + # only require it to be run against the new release. + + # Handle Python version suffixes + if(component MATCHES "^(python|mpi_python|numpy)([0-9][0-9]?|[0-9]\\.[0-9])\$") + set(component "${CMAKE_MATCH_1}") + set(component_python_version "${CMAKE_MATCH_2}") + endif() + + set(_Boost_IMPORTED_TARGETS TRUE) + if(Boost_VERSION_STRING) + if(Boost_VERSION_STRING VERSION_LESS 1.33.0) + if(NOT Boost_FIND_QUIETLY) + message( + WARNING + "Imported targets and dependency information not available for Boost version ${Boost_VERSION_STRING} (all versions older than 1.33)" + ) + endif() + set(_Boost_IMPORTED_TARGETS FALSE) + elseif(Boost_VERSION_STRING VERSION_LESS 1.35.0) + set(_Boost_IOSTREAMS_DEPENDENCIES regex thread) + set(_Boost_REGEX_DEPENDENCIES thread) + set(_Boost_WAVE_DEPENDENCIES filesystem thread) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.36.0) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_WAVE_DEPENDENCIES filesystem system thread) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.38.0) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_WAVE_DEPENDENCIES filesystem system thread) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.43.0) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_THREAD_DEPENDENCIES date_time) + set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.44.0) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + random + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_THREAD_DEPENDENCIES date_time) + set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.45.0) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + random + serialization + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_THREAD_DEPENDENCIES date_time) + set(_Boost_WAVE_DEPENDENCIES + serialization + filesystem + system + thread + date_time + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.47.0) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + random + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_THREAD_DEPENDENCIES date_time) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + date_time + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.48.0) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + random + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_THREAD_DEPENDENCIES date_time) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + date_time + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.50.0) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + random + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_THREAD_DEPENDENCIES date_time) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + date_time + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.53.0) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + regex + random + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + chrono + date_time + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.54.0) + set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + regex + random + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + chrono + date_time + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.55.0) + set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + log_setup + date_time + system + filesystem + thread + regex + chrono + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + regex + random + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.56.0) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + log_setup + date_time + system + filesystem + thread + regex + chrono + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + regex + random + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.59.0) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + log_setup + date_time + system + filesystem + thread + regex + chrono + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + atomic + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_RANDOM_DEPENDENCIES system) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.60.0) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + log_setup + date_time + system + filesystem + thread + regex + chrono + atomic + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + atomic + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_RANDOM_DEPENDENCIES system) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.61.0) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + date_time + log_setup + system + filesystem + thread + regex + chrono + atomic + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + atomic + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_RANDOM_DEPENDENCIES system) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.62.0) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + date_time + log_setup + system + filesystem + thread + regex + chrono + atomic + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + atomic + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_RANDOM_DEPENDENCIES system) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.63.0) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FIBER_DEPENDENCIES + context + thread + chrono + system + date_time + ) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + date_time + log_setup + system + filesystem + thread + regex + chrono + atomic + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + atomic + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_RANDOM_DEPENDENCIES system) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.65.0) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_COROUTINE2_DEPENDENCIES + context + fiber + thread + chrono + system + date_time + ) + set(_Boost_FIBER_DEPENDENCIES + context + thread + chrono + system + date_time + ) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + date_time + log_setup + system + filesystem + thread + regex + chrono + atomic + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + atomic + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_RANDOM_DEPENDENCIES system) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.67.0) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FIBER_DEPENDENCIES + context + thread + chrono + system + date_time + ) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + date_time + log_setup + system + filesystem + thread + regex + chrono + atomic + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + atomic + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) + set(_Boost_RANDOM_DEPENDENCIES system) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.68.0) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FIBER_DEPENDENCIES + context + thread + chrono + system + date_time + ) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + date_time + log_setup + system + filesystem + thread + regex + chrono + atomic + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + atomic + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) + set(_Boost_RANDOM_DEPENDENCIES system) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.69.0) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_CONTEXT_DEPENDENCIES thread chrono system date_time) + set(_Boost_CONTRACT_DEPENDENCIES thread chrono system date_time) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FIBER_DEPENDENCIES + context + thread + chrono + system + date_time + ) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + date_time + log_setup + system + filesystem + thread + regex + chrono + atomic + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + atomic + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) + set(_Boost_RANDOM_DEPENDENCIES system) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES + filesystem + system + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.70.0) + set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time) + set(_Boost_COROUTINE_DEPENDENCIES context) + set(_Boost_FIBER_DEPENDENCIES context) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + date_time + log_setup + filesystem + thread + regex + chrono + atomic + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + atomic + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) + set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES + filesystem + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.72.0) + set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time) + set(_Boost_COROUTINE_DEPENDENCIES context) + set(_Boost_FIBER_DEPENDENCIES context) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + date_time + log_setup + filesystem + thread + regex + chrono + atomic + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + atomic + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) + set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono) + set(_Boost_WAVE_DEPENDENCIES + filesystem + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(Boost_VERSION_STRING VERSION_LESS 1.73.0) + set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time) + set(_Boost_COROUTINE_DEPENDENCIES context) + set(_Boost_FIBER_DEPENDENCIES context) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + date_time + log_setup + filesystem + thread + regex + chrono + atomic + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + chrono + atomic + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) + set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono) + set(_Boost_WAVE_DEPENDENCIES + filesystem + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + else() + set(_Boost_CONTRACT_DEPENDENCIES thread chrono date_time) + set(_Boost_COROUTINE_DEPENDENCIES context) + set(_Boost_FIBER_DEPENDENCIES context) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES + date_time + log_setup + filesystem + thread + regex + chrono + atomic + ) + set(_Boost_MATH_DEPENDENCIES + math_c99 + math_c99f + math_c99l + math_tr1 + math_tr1f + math_tr1l + atomic + ) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES + python${component_python_version} + mpi + serialization + ) + set(_Boost_NUMPY_DEPENDENCIES python${component_python_version}) + set(_Boost_THREAD_DEPENDENCIES chrono date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono) + set(_Boost_WAVE_DEPENDENCIES + filesystem + serialization + thread + chrono + date_time + atomic + ) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.74.0) + if(NOT Boost_FIND_QUIETLY) + message( + WARNING + "New Boost version may have incorrect or missing dependencies and imported targets" + ) + endif() + endif() + endif() + endif() + + string(TOUPPER ${component} uppercomponent) + set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) + set(_Boost_IMPORTED_TARGETS ${_Boost_IMPORTED_TARGETS} PARENT_SCOPE) + + string( + REGEX REPLACE + ";" + " " + _boost_DEPS_STRING + "${_Boost_${uppercomponent}_DEPENDENCIES}" + ) + if(NOT _boost_DEPS_STRING) + set(_boost_DEPS_STRING "(none)") + endif() + # message(STATUS "Dependencies for Boost::${component}: ${_boost_DEPS_STRING}") +endfunction() + +# +# Get component headers. This is the primary header (or headers) for a given component, +# and is used to check that the headers are present as well as the library itself as an +# extra sanity check of the build environment. +# +# component - the component to check _hdrs +# +function(_Boost_COMPONENT_HEADERS component _hdrs) + # Handle Python version suffixes + if(component MATCHES "^(python|mpi_python|numpy)([0-9][0-9]?|[0-9]\\.[0-9])\$") + set(component "${CMAKE_MATCH_1}") + set(component_python_version "${CMAKE_MATCH_2}") + endif() + + # Note: new boost components will require adding here. The header must be present in + # all versions of Boost providing a library. + set(_Boost_ATOMIC_HEADERS "boost/atomic.hpp") + set(_Boost_CHRONO_HEADERS "boost/chrono.hpp") + set(_Boost_CONTAINER_HEADERS "boost/container/container_fwd.hpp") + set(_Boost_CONTRACT_HEADERS "boost/contract.hpp") + if(Boost_VERSION_STRING VERSION_LESS 1.61.0) + set(_Boost_CONTEXT_HEADERS "boost/context/all.hpp") + else() + set(_Boost_CONTEXT_HEADERS "boost/context/detail/fcontext.hpp") + endif() + set(_Boost_COROUTINE_HEADERS "boost/coroutine/all.hpp") + set(_Boost_DATE_TIME_HEADERS "boost/date_time/date.hpp") + set(_Boost_EXCEPTION_HEADERS "boost/exception/exception.hpp") + set(_Boost_FIBER_HEADERS "boost/fiber/all.hpp") + set(_Boost_FILESYSTEM_HEADERS "boost/filesystem/path.hpp") + set(_Boost_GRAPH_HEADERS "boost/graph/adjacency_list.hpp") + set(_Boost_GRAPH_PARALLEL_HEADERS "boost/graph/adjacency_list.hpp") + set(_Boost_IOSTREAMS_HEADERS "boost/iostreams/stream.hpp") + set(_Boost_LOCALE_HEADERS "boost/locale.hpp") + set(_Boost_LOG_HEADERS "boost/log/core.hpp") + set(_Boost_LOG_SETUP_HEADERS "boost/log/detail/setup_config.hpp") + set(_Boost_MATH_HEADERS "boost/math_fwd.hpp") + set(_Boost_MATH_C99_HEADERS "boost/math/tr1.hpp") + set(_Boost_MATH_C99F_HEADERS "boost/math/tr1.hpp") + set(_Boost_MATH_C99L_HEADERS "boost/math/tr1.hpp") + set(_Boost_MATH_TR1_HEADERS "boost/math/tr1.hpp") + set(_Boost_MATH_TR1F_HEADERS "boost/math/tr1.hpp") + set(_Boost_MATH_TR1L_HEADERS "boost/math/tr1.hpp") + set(_Boost_MPI_HEADERS "boost/mpi.hpp") + set(_Boost_MPI_PYTHON_HEADERS "boost/mpi/python/config.hpp") + set(_Boost_NUMPY_HEADERS "boost/python/numpy.hpp") + set(_Boost_NOWIDE_HEADERS "boost/nowide/cstdlib.hpp") + set(_Boost_PRG_EXEC_MONITOR_HEADERS "boost/test/prg_exec_monitor.hpp") + set(_Boost_PROGRAM_OPTIONS_HEADERS "boost/program_options.hpp") + set(_Boost_PYTHON_HEADERS "boost/python.hpp") + set(_Boost_RANDOM_HEADERS "boost/random.hpp") + set(_Boost_REGEX_HEADERS "boost/regex.hpp") + set(_Boost_SERIALIZATION_HEADERS "boost/serialization/serialization.hpp") + set(_Boost_SIGNALS_HEADERS "boost/signals.hpp") + set(_Boost_STACKTRACE_ADDR2LINE_HEADERS "boost/stacktrace.hpp") + set(_Boost_STACKTRACE_BACKTRACE_HEADERS "boost/stacktrace.hpp") + set(_Boost_STACKTRACE_BASIC_HEADERS "boost/stacktrace.hpp") + set(_Boost_STACKTRACE_NOOP_HEADERS "boost/stacktrace.hpp") + set(_Boost_STACKTRACE_WINDBG_CACHED_HEADERS "boost/stacktrace.hpp") + set(_Boost_STACKTRACE_WINDBG_HEADERS "boost/stacktrace.hpp") + set(_Boost_SYSTEM_HEADERS "boost/system/config.hpp") + set(_Boost_TEST_EXEC_MONITOR_HEADERS "boost/test/test_exec_monitor.hpp") + set(_Boost_THREAD_HEADERS "boost/thread.hpp") + set(_Boost_TIMER_HEADERS "boost/timer.hpp") + set(_Boost_TYPE_ERASURE_HEADERS "boost/type_erasure/config.hpp") + set(_Boost_UNIT_TEST_FRAMEWORK_HEADERS "boost/test/framework.hpp") + set(_Boost_WAVE_HEADERS "boost/wave.hpp") + set(_Boost_WSERIALIZATION_HEADERS "boost/archive/text_wiarchive.hpp") + if(WIN32) + set(_Boost_BZIP2_HEADERS "boost/iostreams/filter/bzip2.hpp") + set(_Boost_ZLIB_HEADERS "boost/iostreams/filter/zlib.hpp") + endif() + + string(TOUPPER ${component} uppercomponent) + set(${_hdrs} ${_Boost_${uppercomponent}_HEADERS} PARENT_SCOPE) + + string(REGEX REPLACE ";" " " _boost_HDRS_STRING "${_Boost_${uppercomponent}_HEADERS}") + if(NOT _boost_HDRS_STRING) + set(_boost_HDRS_STRING "(none)") + endif() + # message(STATUS "Headers for Boost::${component}: ${_boost_HDRS_STRING}") +endfunction() + +# +# Determine if any missing dependencies require adding to the component list. +# +# Sets _Boost_${COMPONENT}_DEPENDENCIES for each required component, plus +# _Boost_IMPORTED_TARGETS (TRUE if imported targets should be defined; FALSE if dependency +# information is unavailable). +# +# componentvar - the component list variable name extravar - the indirect dependency list +# variable name +# +function(_Boost_MISSING_DEPENDENCIES componentvar extravar) + # _boost_unprocessed_components - list of components requiring processing + # _boost_processed_components - components already processed (or currently being + # processed) _boost_new_components - new components discovered for future processing + # + list(APPEND _boost_unprocessed_components ${${componentvar}}) + + while(_boost_unprocessed_components) + list(APPEND _boost_processed_components ${_boost_unprocessed_components}) + foreach(component ${_boost_unprocessed_components}) + string(TOUPPER ${component} uppercomponent) + set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) + _boost_component_dependencies("${component}" + _Boost_${uppercomponent}_DEPENDENCIES + ) + set(_Boost_${uppercomponent}_DEPENDENCIES + ${_Boost_${uppercomponent}_DEPENDENCIES} + PARENT_SCOPE + ) + set(_Boost_IMPORTED_TARGETS ${_Boost_IMPORTED_TARGETS} PARENT_SCOPE) + foreach(componentdep ${_Boost_${uppercomponent}_DEPENDENCIES}) + if( + NOT ( + "${componentdep}" IN_LIST _boost_processed_components + OR "${componentdep}" IN_LIST _boost_new_components + ) + ) + list(APPEND _boost_new_components ${componentdep}) + endif() + endforeach() + endforeach() + set(_boost_unprocessed_components ${_boost_new_components}) + unset(_boost_new_components) + endwhile() + set(_boost_extra_components ${_boost_processed_components}) + if(_boost_extra_components AND ${componentvar}) + list(REMOVE_ITEM _boost_extra_components ${${componentvar}}) + endif() + set(${componentvar} ${_boost_processed_components} PARENT_SCOPE) + set(${extravar} ${_boost_extra_components} PARENT_SCOPE) +endfunction() + +# +# Some boost libraries may require particular set of compler features. The very first one +# was `boost::fiber` introduced in Boost 1.62. One can check required compiler features of +# it in - `${Boost_ROOT}/libs/fiber/build/Jamfile.v2`; - +# `${Boost_ROOT}/libs/context/build/Jamfile.v2`. +# +# TODO (Re)Check compiler features on (every?) release ??? One may use the following +# command to get the files to check: +# +# $ find . -name Jamfile.v2 | grep build | xargs grep -l cxx1 +# +function(_Boost_COMPILER_FEATURES component _ret) + # Boost >= 1.62 + if(NOT Boost_VERSION_STRING VERSION_LESS 1.62.0) + set(_Boost_FIBER_COMPILER_FEATURES + cxx_alias_templates + cxx_auto_type + cxx_constexpr + cxx_defaulted_functions + cxx_final + cxx_lambdas + cxx_noexcept + cxx_nullptr + cxx_rvalue_references + cxx_thread_local + cxx_variadic_templates + ) + # Compiler feature for `context` same as for `fiber`. + set(_Boost_CONTEXT_COMPILER_FEATURES ${_Boost_FIBER_COMPILER_FEATURES}) + endif() + + # Boost Contract library available in >= 1.67 + if(NOT Boost_VERSION_STRING VERSION_LESS 1.67.0) + # From `libs/contract/build/boost_contract_build.jam` + set(_Boost_CONTRACT_COMPILER_FEATURES cxx_lambdas cxx_variadic_templates) + endif() + + string(TOUPPER ${component} uppercomponent) + set(${_ret} ${_Boost_${uppercomponent}_COMPILER_FEATURES} PARENT_SCOPE) +endfunction() + +# +# Update library search directory hint variable with paths used by prebuilt boost +# binaries. +# +# Prebuilt windows binaries (https://sourceforge.net/projects/boost/files/boost-binaries/) +# have library directories named using MSVC compiler version and architecture. This +# function would append corresponding directories if MSVC is a current compiler, so having +# `BOOST_ROOT` would be enough to specify to find everything. +# +function( + _Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS + componentlibvar + basedir +) + if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_arch_suffix 64) + else() + set(_arch_suffix 32) + endif() + if(MSVC_TOOLSET_VERSION GREATER_EQUAL 150) + # Not yet known. + elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 140) + # MSVC toolset 14.x versions are forward compatible. + foreach( + v + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0 + ) + if(MSVC_TOOLSET_VERSION GREATER_EQUAL 14${v}) + list( + APPEND + ${componentlibvar} + ${basedir}/lib${_arch_suffix}-msvc-14.${v} + ) + endif() + endforeach() + elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80) + math(EXPR _toolset_major_version "${MSVC_TOOLSET_VERSION} / 10") + list( + APPEND + ${componentlibvar} + ${basedir}/lib${_arch_suffix}-msvc-${_toolset_major_version}.0 + ) + endif() + set(${componentlibvar} ${${componentlibvar}} PARENT_SCOPE) + endif() +endfunction() + +# +# End functions/macros +# +# ------------------------------------------------------------------------------- + +# ------------------------------------------------------------------------------- +# main. +# ------------------------------------------------------------------------------- + +# If the user sets Boost_LIBRARY_DIR, use it as the default for both configurations. +if(NOT Boost_LIBRARY_DIR_RELEASE AND Boost_LIBRARY_DIR) + set(Boost_LIBRARY_DIR_RELEASE "${Boost_LIBRARY_DIR}") +endif() +if(NOT Boost_LIBRARY_DIR_DEBUG AND Boost_LIBRARY_DIR) + set(Boost_LIBRARY_DIR_DEBUG "${Boost_LIBRARY_DIR}") +endif() + +if(NOT DEFINED Boost_USE_DEBUG_LIBS) + set(Boost_USE_DEBUG_LIBS TRUE) +endif() +if(NOT DEFINED Boost_USE_RELEASE_LIBS) + set(Boost_USE_RELEASE_LIBS TRUE) +endif() +if(NOT DEFINED Boost_USE_MULTITHREADED) + set(Boost_USE_MULTITHREADED TRUE) +endif() +if(NOT DEFINED Boost_USE_DEBUG_RUNTIME) + set(Boost_USE_DEBUG_RUNTIME TRUE) +endif() + +# Check the version of Boost against the requested version. +if(Boost_FIND_VERSION AND NOT Boost_FIND_VERSION_MINOR) + message( + SEND_ERROR + "When requesting a specific version of Boost, you must provide at least the major and minor version numbers, e.g., 1.34" + ) +endif() + +if(Boost_FIND_VERSION_EXACT) + # The version may appear in a directory with or without the patch level, even when the + # patch level is non-zero. + set(_boost_TEST_VERSIONS + "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}.${Boost_FIND_VERSION_PATCH}" + "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}" + ) +else() + # The user has not requested an exact version. Among known versions, find those that + # are acceptable to the user request. + # + # Note: When adding a new Boost release, also update the dependency information in + # _Boost_COMPONENT_DEPENDENCIES and _Boost_COMPONENT_HEADERS. See the instructions at + # the top of _Boost_COMPONENT_DEPENDENCIES. + set(_Boost_KNOWN_VERSIONS + ${Boost_ADDITIONAL_VERSIONS} + "1.72.0" + "1.72" + "1.71.0" + "1.71" + "1.70.0" + "1.70" + "1.69.0" + "1.69" + "1.68.0" + "1.68" + "1.67.0" + "1.67" + "1.66.0" + "1.66" + "1.65.1" + "1.65.0" + "1.65" + "1.64.0" + "1.64" + "1.63.0" + "1.63" + "1.62.0" + "1.62" + "1.61.0" + "1.61" + "1.60.0" + "1.60" + "1.59.0" + "1.59" + "1.58.0" + "1.58" + "1.57.0" + "1.57" + "1.56.0" + "1.56" + "1.55.0" + "1.55" + "1.54.0" + "1.54" + "1.53.0" + "1.53" + "1.52.0" + "1.52" + "1.51.0" + "1.51" + "1.50.0" + "1.50" + "1.49.0" + "1.49" + "1.48.0" + "1.48" + "1.47.0" + "1.47" + "1.46.1" + "1.46.0" + "1.46" + "1.45.0" + "1.45" + "1.44.0" + "1.44" + "1.43.0" + "1.43" + "1.42.0" + "1.42" + "1.41.0" + "1.41" + "1.40.0" + "1.40" + "1.39.0" + "1.39" + "1.38.0" + "1.38" + "1.37.0" + "1.37" + "1.36.1" + "1.36.0" + "1.36" + "1.35.1" + "1.35.0" + "1.35" + "1.34.1" + "1.34.0" + "1.34" + "1.33.1" + "1.33.0" + "1.33" + ) + + set(_boost_TEST_VERSIONS) + if(Boost_FIND_VERSION) + set(_Boost_FIND_VERSION_SHORT + "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}" + ) + # Select acceptable versions. + foreach(version ${_Boost_KNOWN_VERSIONS}) + if(NOT "${version}" VERSION_LESS "${Boost_FIND_VERSION}") + # This version is high enough. + list(APPEND _boost_TEST_VERSIONS "${version}") + elseif("${version}.99" VERSION_EQUAL "${_Boost_FIND_VERSION_SHORT}.99") + # This version is a short-form for the requested version with the patch + # level dropped. + list(APPEND _boost_TEST_VERSIONS "${version}") + endif() + endforeach() + else() + # Any version is acceptable. + set(_boost_TEST_VERSIONS "${_Boost_KNOWN_VERSIONS}") + endif() +endif() + +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "_boost_TEST_VERSIONS" +) +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_USE_MULTITHREADED" +) +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_USE_STATIC_LIBS" +) +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_USE_STATIC_RUNTIME" +) +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_ADDITIONAL_VERSIONS" +) +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_NO_SYSTEM_PATHS" +) + +cmake_policy(GET CMP0074 _Boost_CMP0074) +if(NOT "x${_Boost_CMP0074}x" STREQUAL "xNEWx") + _boost_check_spelling(Boost_ROOT) +endif() +unset(_Boost_CMP0074) +_boost_check_spelling(Boost_LIBRARYDIR) +_boost_check_spelling(Boost_INCLUDEDIR) + +# Collect environment variable inputs as hints. Do not consider changes. +foreach(v BOOSTROOT BOOST_ROOT BOOST_INCLUDEDIR BOOST_LIBRARYDIR) + set(_env $ENV{${v}}) + if(_env) + file(TO_CMAKE_PATH "${_env}" _ENV_${v}) + else() + set(_ENV_${v} "") + endif() +endforeach() +if(NOT _ENV_BOOST_ROOT AND _ENV_BOOSTROOT) + set(_ENV_BOOST_ROOT "${_ENV_BOOSTROOT}") +endif() + +# Collect inputs and cached results. Detect changes since the last run. +if(NOT BOOST_ROOT AND BOOSTROOT) + set(BOOST_ROOT "${BOOSTROOT}") +endif() +set(_Boost_VARS_DIR BOOST_ROOT Boost_NO_SYSTEM_PATHS) + +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "BOOST_ROOT" +) +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "BOOST_ROOT" ENVIRONMENT +) +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "BOOST_INCLUDEDIR" +) +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "BOOST_INCLUDEDIR" ENVIRONMENT +) +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "BOOST_LIBRARYDIR" +) +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "BOOST_LIBRARYDIR" ENVIRONMENT +) + +# ------------------------------------------------------------------------ +# Search for Boost include DIR +# ------------------------------------------------------------------------ + +set(_Boost_VARS_INC BOOST_INCLUDEDIR Boost_INCLUDE_DIR Boost_ADDITIONAL_VERSIONS) +_boost_change_detect(_Boost_CHANGE_INCDIR ${_Boost_VARS_DIR} ${_Boost_VARS_INC}) +# Clear Boost_INCLUDE_DIR if it did not change but other input affecting the location did. +# We will find a new one based on the new inputs. +if(_Boost_CHANGE_INCDIR AND NOT _Boost_INCLUDE_DIR_CHANGED) + unset(Boost_INCLUDE_DIR CACHE) +endif() + +if(NOT Boost_INCLUDE_DIR) + set(_boost_INCLUDE_SEARCH_DIRS "") + if(BOOST_INCLUDEDIR) + list(APPEND _boost_INCLUDE_SEARCH_DIRS ${BOOST_INCLUDEDIR}) + elseif(_ENV_BOOST_INCLUDEDIR) + list(APPEND _boost_INCLUDE_SEARCH_DIRS ${_ENV_BOOST_INCLUDEDIR}) + endif() + + if(BOOST_ROOT) + list(APPEND _boost_INCLUDE_SEARCH_DIRS ${BOOST_ROOT}/include ${BOOST_ROOT}) + elseif(_ENV_BOOST_ROOT) + list( + APPEND + _boost_INCLUDE_SEARCH_DIRS + ${_ENV_BOOST_ROOT}/include + ${_ENV_BOOST_ROOT} + ) + endif() + + if(Boost_NO_SYSTEM_PATHS) + list( + APPEND + _boost_INCLUDE_SEARCH_DIRS + NO_CMAKE_SYSTEM_PATH + NO_SYSTEM_ENVIRONMENT_PATH + ) + else() + if("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") + foreach(ver ${_boost_TEST_VERSIONS}) + string(REPLACE "." "_" ver "${ver}") + list(APPEND _boost_INCLUDE_SEARCH_DIRS PATHS "C:/local/boost_${ver}") + endforeach() + endif() + list( + APPEND + _boost_INCLUDE_SEARCH_DIRS + PATHS + C:/boost/include + C:/boost + /sw/local/include + ) + endif() + + # Try to find Boost by stepping backwards through the Boost versions we know about. + # Build a list of path suffixes for each version. + set(_boost_PATH_SUFFIXES) + foreach(_boost_VER ${_boost_TEST_VERSIONS}) + # Add in a path suffix, based on the required version, ideally we could read this + # from version.hpp, but for that to work we'd need to know the include dir already + set(_boost_BOOSTIFIED_VERSION) + + # Transform 1.35 => 1_35 and 1.36.0 => 1_36_0 + if(_boost_VER MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+)") + set(_boost_BOOSTIFIED_VERSION + "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}_${CMAKE_MATCH_3}" + ) + elseif(_boost_VER MATCHES "([0-9]+)\\.([0-9]+)") + set(_boost_BOOSTIFIED_VERSION "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}") + endif() + + list( + APPEND + _boost_PATH_SUFFIXES + "boost-${_boost_BOOSTIFIED_VERSION}" + "boost_${_boost_BOOSTIFIED_VERSION}" + "boost/boost-${_boost_BOOSTIFIED_VERSION}" + "boost/boost_${_boost_BOOSTIFIED_VERSION}" + ) + endforeach() + + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "_boost_INCLUDE_SEARCH_DIRS" + ) + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "_boost_PATH_SUFFIXES" + ) + + # Look for a standard boost header file. + find_path( + Boost_INCLUDE_DIR + NAMES boost/config.hpp + HINTS ${_boost_INCLUDE_SEARCH_DIRS} + PATH_SUFFIXES ${_boost_PATH_SUFFIXES} + ) +endif() + +# ------------------------------------------------------------------------ +# Extract version information from version.hpp +# ------------------------------------------------------------------------ + +if(Boost_INCLUDE_DIR) + _boost_debug_print("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "location of version.hpp: ${Boost_INCLUDE_DIR}/boost/version.hpp" + ) + + # Extract Boost_VERSION_MACRO and Boost_LIB_VERSION from version.hpp + set(Boost_VERSION_MACRO 0) + set(Boost_LIB_VERSION "") + file( + STRINGS + "${Boost_INCLUDE_DIR}/boost/version.hpp" + _boost_VERSION_HPP_CONTENTS + REGEX "#define BOOST_(LIB_)?VERSION " + ) + if("${_boost_VERSION_HPP_CONTENTS}" MATCHES "#define BOOST_VERSION ([0-9]+)") + set(Boost_VERSION_MACRO "${CMAKE_MATCH_1}") + endif() + if("${_boost_VERSION_HPP_CONTENTS}" MATCHES "#define BOOST_LIB_VERSION \"([0-9_]+)\"") + set(Boost_LIB_VERSION "${CMAKE_MATCH_1}") + endif() + unset(_boost_VERSION_HPP_CONTENTS) + + # Calculate version components + math(EXPR Boost_VERSION_MAJOR "${Boost_VERSION_MACRO} / 100000") + math(EXPR Boost_VERSION_MINOR "${Boost_VERSION_MACRO} / 100 % 1000") + math(EXPR Boost_VERSION_PATCH "${Boost_VERSION_MACRO} % 100") + set(Boost_VERSION_COUNT 3) + + # Define alias variables for backwards compat. + set(Boost_MAJOR_VERSION ${Boost_VERSION_MAJOR}) + set(Boost_MINOR_VERSION ${Boost_VERSION_MINOR}) + set(Boost_SUBMINOR_VERSION ${Boost_VERSION_PATCH}) + + # Define Boost version in x.y.z format + set(Boost_VERSION_STRING + "${Boost_VERSION_MAJOR}.${Boost_VERSION_MINOR}.${Boost_VERSION_PATCH}" + ) + + if(NOT CMAKE_VERSION VERSION_LESS 3.15) + # Define final Boost_VERSION + cmake_policy( + GET + CMP0093 + _Boost_CMP0093 + PARENT_SCOPE # undocumented, do not use outside of + # CMake + ) + if("x${_Boost_CMP0093}x" STREQUAL "xNEWx") + set(Boost_VERSION ${Boost_VERSION_STRING}) + else() + set(Boost_VERSION ${Boost_VERSION_MACRO}) + endif() + unset(_Boost_CMP0093) + endif() + + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_VERSION" + ) + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_VERSION_STRING" + ) + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_VERSION_MACRO" + ) + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_VERSION_MAJOR" + ) + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_VERSION_MINOR" + ) + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_VERSION_PATCH" + ) + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_VERSION_COUNT" + ) +endif() + +# ------------------------------------------------------------------------ +# Prefix initialization +# ------------------------------------------------------------------------ + +set(Boost_LIB_PREFIX "") +if( + (GHSMULTI AND Boost_USE_STATIC_LIBS) + OR (WIN32 AND Boost_USE_STATIC_LIBS AND NOT CYGWIN) +) + set(Boost_LIB_PREFIX "lib") +endif() + +if(NOT Boost_NAMESPACE) + set(Boost_NAMESPACE "boost") +endif() + +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_LIB_PREFIX" +) +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Boost_NAMESPACE" +) + +# ------------------------------------------------------------------------ +# Suffix initialization and compiler suffix detection. +# ------------------------------------------------------------------------ + +set(_Boost_VARS_NAME + Boost_NAMESPACE + Boost_COMPILER + Boost_THREADAPI + Boost_USE_DEBUG_PYTHON + Boost_USE_MULTITHREADED + Boost_USE_STATIC_LIBS + Boost_USE_STATIC_RUNTIME + Boost_USE_STLPORT + Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS +) +_boost_change_detect(_Boost_CHANGE_LIBNAME ${_Boost_VARS_NAME}) + +# Setting some more suffixes for the library +if(Boost_COMPILER) + set(_boost_COMPILER ${Boost_COMPILER}) + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "_boost_COMPILER" SOURCE "user-specified via Boost_COMPILER" + ) +else() + # Attempt to guess the compiler suffix NOTE: this is not perfect yet, if you + # experience any issues please report them and use the Boost_COMPILER variable to work + # around the problems. + _boost_guess_compiler_prefix(_boost_COMPILER) +endif() + +set(_boost_MULTITHREADED "-mt") +if(NOT Boost_USE_MULTITHREADED) + set(_boost_MULTITHREADED "") +endif() +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "_boost_MULTITHREADED" +) + +# ====================== +# Systematically build up the Boost ABI tag for the 'tagged' and 'versioned' layouts +# http://boost.org/doc/libs/1_66_0/more/getting_started/windows.html#library-naming +# http://boost.org/doc/libs/1_66_0/boost/config/auto_link.hpp +# http://boost.org/doc/libs/1_66_0/tools/build/src/tools/common.jam +# http://boost.org/doc/libs/1_66_0/boostcpp.jam +set(_boost_RELEASE_ABI_TAG "-") +set(_boost_DEBUG_ABI_TAG "-") +# Key Use this library when: s linking statically to the C++ standard library +# and compiler runtime support libraries. +if(Boost_USE_STATIC_RUNTIME) + set(_boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}s") + set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}s") +endif() +# g using debug versions of the standard and runtime support libraries +if(WIN32 AND Boost_USE_DEBUG_RUNTIME) + if( + "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" + OR "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang" + OR "x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xIntel" + ) + string(APPEND _boost_DEBUG_ABI_TAG "g") + endif() +endif() +# y using special debug build of python +if(Boost_USE_DEBUG_PYTHON) + string(APPEND _boost_DEBUG_ABI_TAG "y") +endif() +# d using a debug version of your code +string(APPEND _boost_DEBUG_ABI_TAG "d") +# p using the STLport standard library rather than the default one supplied with +# your compiler +if(Boost_USE_STLPORT) + string(APPEND _boost_RELEASE_ABI_TAG "p") + string(APPEND _boost_DEBUG_ABI_TAG "p") +endif() +# n using the STLport deprecated "native iostreams" feature removed from the +# documentation in 1.43.0 but still present in boost/config/auto_link.hpp +if(Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS) + string(APPEND _boost_RELEASE_ABI_TAG "n") + string(APPEND _boost_DEBUG_ABI_TAG "n") +endif() + +# -x86 Architecture and address model tag First character is the architecture, then +# word-size, either 32 or 64 Only used in 'versioned' layout, added in Boost 1.66.0 +if(DEFINED Boost_ARCHITECTURE) + set(_boost_ARCHITECTURE_TAG "${Boost_ARCHITECTURE}") + _boost_debug_print_var( + "${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "_boost_ARCHITECTURE_TAG" SOURCE "user-specified via Boost_ARCHITECTURE" + ) +else() + set(_boost_ARCHITECTURE_TAG "") + # {CMAKE_CXX_COMPILER_ARCHITECTURE_ID} is not currently set for all compilers + if( + NOT "x${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}" STREQUAL "x" + AND NOT Boost_VERSION_STRING VERSION_LESS 1.66.0 + ) + string(APPEND _boost_ARCHITECTURE_TAG "-") + # This needs to be kept in-sync with the section of CMakePlatformId.h.in inside + # 'defined(_WIN32) && defined(_MSC_VER)' + if(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "IA64") + string(APPEND _boost_ARCHITECTURE_TAG "i") + elseif( + CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "X86" + OR CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "x64" + ) + string(APPEND _boost_ARCHITECTURE_TAG "x") + elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID MATCHES "^ARM") + string(APPEND _boost_ARCHITECTURE_TAG "a") + elseif(CMAKE_CXX_COMPILER_ARCHITECTURE_ID STREQUAL "MIPS") + string(APPEND _boost_ARCHITECTURE_TAG "m") + endif() + + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + string(APPEND _boost_ARCHITECTURE_TAG "64") + else() + string(APPEND _boost_ARCHITECTURE_TAG "32") + endif() + endif() + _boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "_boost_ARCHITECTURE_TAG" SOURCE "detected" + ) +endif() + +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "_boost_RELEASE_ABI_TAG" +) +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "_boost_DEBUG_ABI_TAG" +) + +# ------------------------------------------------------------------------ +# Begin finding boost libraries +# ------------------------------------------------------------------------ + +set(_Boost_VARS_LIB "") +foreach(c DEBUG RELEASE) + set(_Boost_VARS_LIB_${c} BOOST_LIBRARYDIR Boost_LIBRARY_DIR_${c}) + list(APPEND _Boost_VARS_LIB ${_Boost_VARS_LIB_${c}}) + _boost_change_detect(_Boost_CHANGE_LIBDIR_${c} ${_Boost_VARS_DIR} + ${_Boost_VARS_LIB_${c}} Boost_INCLUDE_DIR + ) + # Clear Boost_LIBRARY_DIR_${c} if it did not change but other input affecting the + # location did. We will find a new one based on the new inputs. + if(_Boost_CHANGE_LIBDIR_${c} AND NOT _Boost_LIBRARY_DIR_${c}_CHANGED) + unset(Boost_LIBRARY_DIR_${c} CACHE) + endif() + + # If Boost_LIBRARY_DIR_[RELEASE,DEBUG] is set, prefer its value. + if(Boost_LIBRARY_DIR_${c}) + set(_boost_LIBRARY_SEARCH_DIRS_${c} + ${Boost_LIBRARY_DIR_${c}} + NO_DEFAULT_PATH + NO_CMAKE_FIND_ROOT_PATH + ) + else() + set(_boost_LIBRARY_SEARCH_DIRS_${c} "") + if(BOOST_LIBRARYDIR) + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${BOOST_LIBRARYDIR}) + elseif(_ENV_BOOST_LIBRARYDIR) + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${_ENV_BOOST_LIBRARYDIR}) + endif() + + if(BOOST_ROOT) + list( + APPEND + _boost_LIBRARY_SEARCH_DIRS_${c} + ${BOOST_ROOT}/lib + ${BOOST_ROOT}/stage/lib + ) + _boost_update_windows_library_search_dirs_with_prebuilt_paths( + _boost_LIBRARY_SEARCH_DIRS_${c} "${BOOST_ROOT}" + ) + elseif(_ENV_BOOST_ROOT) + list( + APPEND + _boost_LIBRARY_SEARCH_DIRS_${c} + ${_ENV_BOOST_ROOT}/lib + ${_ENV_BOOST_ROOT}/stage/lib + ) + _boost_update_windows_library_search_dirs_with_prebuilt_paths( + _boost_LIBRARY_SEARCH_DIRS_${c} "${_ENV_BOOST_ROOT}" + ) + endif() + + list( + APPEND + _boost_LIBRARY_SEARCH_DIRS_${c} + ${Boost_INCLUDE_DIR}/lib + ${Boost_INCLUDE_DIR}/../lib + ${Boost_INCLUDE_DIR}/stage/lib + ) + _boost_update_windows_library_search_dirs_with_prebuilt_paths( + _boost_LIBRARY_SEARCH_DIRS_${c} "${Boost_INCLUDE_DIR}/.." + ) + _boost_update_windows_library_search_dirs_with_prebuilt_paths( + _boost_LIBRARY_SEARCH_DIRS_${c} "${Boost_INCLUDE_DIR}" + ) + if(Boost_NO_SYSTEM_PATHS) + list( + APPEND + _boost_LIBRARY_SEARCH_DIRS_${c} + NO_CMAKE_SYSTEM_PATH + NO_SYSTEM_ENVIRONMENT_PATH + ) + else() + foreach(ver ${_boost_TEST_VERSIONS}) + string(REPLACE "." "_" ver "${ver}") + _boost_update_windows_library_search_dirs_with_prebuilt_paths( + _boost_LIBRARY_SEARCH_DIRS_${c} "C:/local/boost_${ver}" + ) + endforeach() + _boost_update_windows_library_search_dirs_with_prebuilt_paths( + _boost_LIBRARY_SEARCH_DIRS_${c} "C:/boost" + ) + list( + APPEND + _boost_LIBRARY_SEARCH_DIRS_${c} + PATHS + C:/boost/lib + C:/boost + /sw/local/lib + ) + endif() + endif() +endforeach() + +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "_boost_LIBRARY_SEARCH_DIRS_RELEASE" +) +_boost_debug_print_var("${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "_boost_LIBRARY_SEARCH_DIRS_DEBUG" +) + +# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES +if(Boost_USE_STATIC_LIBS) + set(_boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(WIN32) + list(INSERT CMAKE_FIND_LIBRARY_SUFFIXES 0 .lib .a) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a) + endif() +endif() + +# We want to use the tag inline below without risking double dashes +if(_boost_RELEASE_ABI_TAG) + if(${_boost_RELEASE_ABI_TAG} STREQUAL "-") + set(_boost_RELEASE_ABI_TAG "") + endif() +endif() +if(_boost_DEBUG_ABI_TAG) + if(${_boost_DEBUG_ABI_TAG} STREQUAL "-") + set(_boost_DEBUG_ABI_TAG "") + endif() +endif() + +# The previous behavior of FindBoost when Boost_USE_STATIC_LIBS was enabled on WIN32 was +# to: 1. Search for static libs compiled against a SHARED C++ standard runtime library +# (use if found) 2. Search for static libs compiled against a STATIC C++ standard runtime +# library (use if found) We maintain this behavior since changing it could break people's +# builds. To disable the ambiguous behavior, the user need only set +# Boost_USE_STATIC_RUNTIME either ON or OFF. +set(_boost_STATIC_RUNTIME_WORKAROUND false) +if(WIN32 AND Boost_USE_STATIC_LIBS) + if(NOT DEFINED Boost_USE_STATIC_RUNTIME) + set(_boost_STATIC_RUNTIME_WORKAROUND TRUE) + endif() +endif() + +# On versions < 1.35, remove the System library from the considered list since it wasn't +# added until 1.35. +if(Boost_VERSION_STRING AND Boost_FIND_COMPONENTS) + if(Boost_VERSION_STRING VERSION_LESS 1.35.0) + list(REMOVE_ITEM Boost_FIND_COMPONENTS system) + endif() +endif() + +# Additional components may be required via component dependencies. Add any missing +# components to the list. +_boost_missing_dependencies(Boost_FIND_COMPONENTS _Boost_EXTRA_FIND_COMPONENTS) + +# If thread is required, get the thread libs as a dependency +if("thread" IN_LIST Boost_FIND_COMPONENTS) + if(Boost_FIND_QUIETLY) + set(_Boost_find_quiet QUIET) + else() + set(_Boost_find_quiet "") + endif() + find_package(Threads ${_Boost_find_quiet}) + unset(_Boost_find_quiet) +endif() + +# If the user changed any of our control inputs flush previous results. +if(_Boost_CHANGE_LIBDIR_DEBUG OR _Boost_CHANGE_LIBDIR_RELEASE OR _Boost_CHANGE_LIBNAME) + foreach(COMPONENT ${_Boost_COMPONENTS_SEARCHED}) + string(TOUPPER ${COMPONENT} UPPERCOMPONENT) + foreach(c DEBUG RELEASE) + set(_var Boost_${UPPERCOMPONENT}_LIBRARY_${c}) + unset(${_var} CACHE) + set(${_var} "${_var}-NOTFOUND") + endforeach() + endforeach() + set(_Boost_COMPONENTS_SEARCHED "") +endif() + +foreach(COMPONENT ${Boost_FIND_COMPONENTS}) + string(TOUPPER ${COMPONENT} UPPERCOMPONENT) + + set(_boost_docstring_release "Boost ${COMPONENT} library (release)") + set(_boost_docstring_debug "Boost ${COMPONENT} library (debug)") + + # Compute component-specific hints. + set(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT "") + if( + ${COMPONENT} STREQUAL "mpi" + OR ${COMPONENT} STREQUAL "mpi_python" + OR ${COMPONENT} STREQUAL "graph_parallel" + ) + foreach(lib ${MPI_CXX_LIBRARIES} ${MPI_C_LIBRARIES}) + if(IS_ABSOLUTE "${lib}") + get_filename_component(libdir "${lib}" PATH) + string(REPLACE "\\" "/" libdir "${libdir}") + list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT ${libdir}) + endif() + endforeach() + endif() + + # Handle Python version suffixes + unset(COMPONENT_PYTHON_VERSION_MAJOR) + unset(COMPONENT_PYTHON_VERSION_MINOR) + if(${COMPONENT} MATCHES "^(python|mpi_python|numpy)([0-9])\$") + set(COMPONENT_UNVERSIONED "${CMAKE_MATCH_1}") + set(COMPONENT_PYTHON_VERSION_MAJOR "${CMAKE_MATCH_2}") + elseif(${COMPONENT} MATCHES "^(python|mpi_python|numpy)([0-9])\\.?([0-9])\$") + set(COMPONENT_UNVERSIONED "${CMAKE_MATCH_1}") + set(COMPONENT_PYTHON_VERSION_MAJOR "${CMAKE_MATCH_2}") + set(COMPONENT_PYTHON_VERSION_MINOR "${CMAKE_MATCH_3}") + endif() + + unset(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME) + if(COMPONENT_PYTHON_VERSION_MINOR) + # Boost >= 1.67 + list( + APPEND + _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME + "${COMPONENT_UNVERSIONED}${COMPONENT_PYTHON_VERSION_MAJOR}${COMPONENT_PYTHON_VERSION_MINOR}" + ) + # Debian/Ubuntu (Some versions omit the 2 and/or 3 from the suffix) + list( + APPEND + _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME + "${COMPONENT_UNVERSIONED}${COMPONENT_PYTHON_VERSION_MAJOR}-py${COMPONENT_PYTHON_VERSION_MAJOR}${COMPONENT_PYTHON_VERSION_MINOR}" + ) + list( + APPEND + _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME + "${COMPONENT_UNVERSIONED}-py${COMPONENT_PYTHON_VERSION_MAJOR}${COMPONENT_PYTHON_VERSION_MINOR}" + ) + # Gentoo + list( + APPEND + _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME + "${COMPONENT_UNVERSIONED}-${COMPONENT_PYTHON_VERSION_MAJOR}.${COMPONENT_PYTHON_VERSION_MINOR}" + ) + # RPMs + list( + APPEND + _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME + "${COMPONENT_UNVERSIONED}-${COMPONENT_PYTHON_VERSION_MAJOR}${COMPONENT_PYTHON_VERSION_MINOR}" + ) + endif() + if(COMPONENT_PYTHON_VERSION_MAJOR AND NOT COMPONENT_PYTHON_VERSION_MINOR) + # Boost < 1.67 + list( + APPEND + _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME + "${COMPONENT_UNVERSIONED}${COMPONENT_PYTHON_VERSION_MAJOR}" + ) + endif() + + # Consolidate and report component-specific hints. + if(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME) + list(REMOVE_DUPLICATES _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME) + _boost_debug_print( + "${CMAKE_CURRENT_LIST_FILE}" + "${CMAKE_CURRENT_LIST_LINE}" + "Component-specific library search names for ${COMPONENT_NAME}: ${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME}" + ) + endif() + if(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT) + list(REMOVE_DUPLICATES _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT) + _boost_debug_print( + "${CMAKE_CURRENT_LIST_FILE}" + "${CMAKE_CURRENT_LIST_LINE}" + "Component-specific library search paths for ${COMPONENT}: ${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT}" + ) + endif() + + # + # Find headers + # + _boost_component_headers("${COMPONENT}" Boost_${UPPERCOMPONENT}_HEADER_NAME) + # Look for a standard boost header file. + if(Boost_${UPPERCOMPONENT}_HEADER_NAME) + if(EXISTS "${Boost_INCLUDE_DIR}/${Boost_${UPPERCOMPONENT}_HEADER_NAME}") + set(Boost_${UPPERCOMPONENT}_HEADER ON) + else() + set(Boost_${UPPERCOMPONENT}_HEADER OFF) + endif() + else() + set(Boost_${UPPERCOMPONENT}_HEADER ON) + if(NOT Boost_FIND_QUIETLY) + message( + WARNING + "No header defined for ${COMPONENT}; skipping header check " + "(note: header-only libraries have no designated component)" + ) + endif() + endif() + + # + # Find RELEASE libraries + # + unset(_boost_RELEASE_NAMES) + foreach(component IN LISTS _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME COMPONENT) + foreach(compiler IN LISTS _boost_COMPILER) + list( + APPEND + _boost_RELEASE_NAMES + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} + ) + endforeach() + list( + APPEND + _boost_RELEASE_NAMES + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}${_boost_ARCHITECTURE_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component} + ) + if(_boost_STATIC_RUNTIME_WORKAROUND) + set(_boost_RELEASE_STATIC_ABI_TAG "-s${_boost_RELEASE_ABI_TAG}") + foreach(compiler IN LISTS _boost_COMPILER) + list( + APPEND + _boost_RELEASE_NAMES + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} + ) + endforeach() + list( + APPEND + _boost_RELEASE_NAMES + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} + ) + endif() + endforeach() + if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread") + _boost_prepend_list_with_threadapi(_boost_RELEASE_NAMES ${_boost_RELEASE_NAMES}) + endif() + _boost_debug_print( + "${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Searching for ${UPPERCOMPONENT}_LIBRARY_RELEASE: ${_boost_RELEASE_NAMES}" + ) + + # if Boost_LIBRARY_DIR_RELEASE is not defined, but Boost_LIBRARY_DIR_DEBUG is, look + # there first for RELEASE libs + if(NOT Boost_LIBRARY_DIR_RELEASE AND Boost_LIBRARY_DIR_DEBUG) + list(INSERT _boost_LIBRARY_SEARCH_DIRS_RELEASE 0 ${Boost_LIBRARY_DIR_DEBUG}) + endif() + + # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing. + string( + REPLACE + "\\" + "/" + _boost_LIBRARY_SEARCH_DIRS_tmp + "${_boost_LIBRARY_SEARCH_DIRS_RELEASE}" + ) + + if(Boost_USE_RELEASE_LIBS) + _boost_find_library( + Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE + RELEASE + NAMES + ${_boost_RELEASE_NAMES} + HINTS + ${_boost_LIBRARY_SEARCH_DIRS_tmp} + NAMES_PER_DIR + DOC + "${_boost_docstring_release}" + ) + endif() + + # + # Find DEBUG libraries + # + unset(_boost_DEBUG_NAMES) + foreach(component IN LISTS _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT_NAME COMPONENT) + foreach(compiler IN LISTS _boost_COMPILER) + list( + APPEND + _boost_DEBUG_NAMES + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} + ) + endforeach() + list( + APPEND + _boost_DEBUG_NAMES + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}${_boost_ARCHITECTURE_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component} + ) + if(_boost_STATIC_RUNTIME_WORKAROUND) + set(_boost_DEBUG_STATIC_ABI_TAG "-s${_boost_DEBUG_ABI_TAG}") + foreach(compiler IN LISTS _boost_COMPILER) + list( + APPEND + _boost_DEBUG_NAMES + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${compiler}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} + ) + endforeach() + list( + APPEND + _boost_DEBUG_NAMES + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}${_boost_ARCHITECTURE_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${component}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} + ) + endif() + endforeach() + if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread") + _boost_prepend_list_with_threadapi(_boost_DEBUG_NAMES ${_boost_DEBUG_NAMES}) + endif() + _boost_debug_print( + "${CMAKE_CURRENT_LIST_FILE}" "${CMAKE_CURRENT_LIST_LINE}" + "Searching for ${UPPERCOMPONENT}_LIBRARY_DEBUG: ${_boost_DEBUG_NAMES}" + ) + + # if Boost_LIBRARY_DIR_DEBUG is not defined, but Boost_LIBRARY_DIR_RELEASE is, look + # there first for DEBUG libs + if(NOT Boost_LIBRARY_DIR_DEBUG AND Boost_LIBRARY_DIR_RELEASE) + list(INSERT _boost_LIBRARY_SEARCH_DIRS_DEBUG 0 ${Boost_LIBRARY_DIR_RELEASE}) + endif() + + # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing. + string( + REPLACE + "\\" + "/" + _boost_LIBRARY_SEARCH_DIRS_tmp + "${_boost_LIBRARY_SEARCH_DIRS_DEBUG}" + ) + + if(Boost_USE_DEBUG_LIBS) + _boost_find_library( + Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG + DEBUG + NAMES + ${_boost_DEBUG_NAMES} + HINTS + ${_boost_LIBRARY_SEARCH_DIRS_tmp} + NAMES_PER_DIR + DOC + "${_boost_docstring_debug}" + ) + endif() + + if(Boost_REALPATH) + _boost_swap_with_realpath(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE + "${_boost_docstring_release}" + ) + _boost_swap_with_realpath(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG + "${_boost_docstring_debug}" + ) + endif() + + _boost_adjust_lib_vars(${UPPERCOMPONENT}) + + # Check if component requires some compiler features + _boost_compiler_features(${COMPONENT} _Boost_${UPPERCOMPONENT}_COMPILER_FEATURES) +endforeach() + +# Restore the original find library ordering +if(Boost_USE_STATIC_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${_boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +endif() + +# ------------------------------------------------------------------------ +# End finding boost libraries +# ------------------------------------------------------------------------ + +set(Boost_INCLUDE_DIRS ${Boost_INCLUDE_DIR}) +set(Boost_LIBRARY_DIRS) +if(Boost_LIBRARY_DIR_RELEASE) + list(APPEND Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR_RELEASE}) +endif() +if(Boost_LIBRARY_DIR_DEBUG) + list(APPEND Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR_DEBUG}) +endif() +if(Boost_LIBRARY_DIRS) + list(REMOVE_DUPLICATES Boost_LIBRARY_DIRS) +endif() + +# ------------------------------------------------------------------------ +# Call FPHSA helper, see +# https://cmake.org/cmake/help/latest/module/FindPackageHandleStandardArgs.html +# ------------------------------------------------------------------------ + +# Define aliases as needed by the component handler in the FPHSA helper below +foreach(_comp IN LISTS Boost_FIND_COMPONENTS) + string(TOUPPER ${_comp} _uppercomp) + if(DEFINED Boost_${_uppercomp}_FOUND) + set(Boost_${_comp}_FOUND ${Boost_${_uppercomp}_FOUND}) + endif() +endforeach() + +find_package_handle_standard_args( + Boost + REQUIRED_VARS Boost_INCLUDE_DIR + VERSION_VAR Boost_VERSION_STRING + HANDLE_COMPONENTS +) + +if(Boost_FOUND) + if(NOT Boost_LIBRARY_DIRS) + # Compatibility Code for backwards compatibility with CMake 2.4's FindBoost + # module. + + # Look for the boost library path. Note that the user may not have installed any + # libraries so it is quite possible the Boost_LIBRARY_DIRS may not exist. + set(_boost_LIB_DIR ${Boost_INCLUDE_DIR}) + + if("${_boost_LIB_DIR}" MATCHES "boost-[0-9]+") + get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH) + endif() + + if("${_boost_LIB_DIR}" MATCHES "/include$") + # Strip off the trailing "/include" in the path. + get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH) + endif() + + if(EXISTS "${_boost_LIB_DIR}/lib") + string(APPEND _boost_LIB_DIR /lib) + elseif(EXISTS "${_boost_LIB_DIR}/stage/lib") + string(APPEND _boost_LIB_DIR "/stage/lib") + else() + set(_boost_LIB_DIR "") + endif() + + if(_boost_LIB_DIR AND EXISTS "${_boost_LIB_DIR}") + set(Boost_LIBRARY_DIRS ${_boost_LIB_DIR}) + endif() + endif() +else() + # Boost headers were not found so no components were found. + foreach(COMPONENT ${Boost_FIND_COMPONENTS}) + string(TOUPPER ${COMPONENT} UPPERCOMPONENT) + set(Boost_${UPPERCOMPONENT}_FOUND 0) + endforeach() +endif() + +# ------------------------------------------------------------------------ +# Add imported targets +# ------------------------------------------------------------------------ + +if(Boost_FOUND) + # The builtin CMake package in Boost 1.70+ introduces a new name for the header-only + # lib, let's provide the same UI in module mode + if(NOT TARGET Boost::headers) + add_library(Boost::headers INTERFACE IMPORTED) + if(Boost_INCLUDE_DIRS) + set_target_properties( + Boost::headers + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}" + ) + endif() + endif() + + # Define the old target name for header-only libraries for backwards compat. + if(NOT TARGET Boost::boost) + add_library(Boost::boost INTERFACE IMPORTED) + set_target_properties( + Boost::boost + PROPERTIES INTERFACE_LINK_LIBRARIES Boost::headers + ) + endif() + + foreach(COMPONENT ${Boost_FIND_COMPONENTS}) + if(_Boost_IMPORTED_TARGETS AND NOT TARGET Boost::${COMPONENT}) + string(TOUPPER ${COMPONENT} UPPERCOMPONENT) + if(Boost_${UPPERCOMPONENT}_FOUND) + if(Boost_USE_STATIC_LIBS) + add_library(Boost::${COMPONENT} STATIC IMPORTED) + else() + # Even if Boost_USE_STATIC_LIBS is OFF, we might have static libraries + # as a result. + add_library(Boost::${COMPONENT} UNKNOWN IMPORTED) + endif() + if(Boost_INCLUDE_DIRS) + set_target_properties( + Boost::${COMPONENT} + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}" + ) + endif() + if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY}") + set_target_properties( + Boost::${COMPONENT} + PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION "${Boost_${UPPERCOMPONENT}_LIBRARY}" + ) + endif() + if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE}") + set_property( + TARGET Boost::${COMPONENT} + APPEND + PROPERTY IMPORTED_CONFIGURATIONS RELEASE + ) + set_target_properties( + Boost::${COMPONENT} + PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX" + IMPORTED_LOCATION_RELEASE + "${Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE}" + ) + endif() + if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG}") + set_property( + TARGET Boost::${COMPONENT} + APPEND + PROPERTY IMPORTED_CONFIGURATIONS DEBUG + ) + set_target_properties( + Boost::${COMPONENT} + PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX" + IMPORTED_LOCATION_DEBUG + "${Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG}" + ) + endif() + if(_Boost_${UPPERCOMPONENT}_DEPENDENCIES) + unset(_Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES) + foreach(dep ${_Boost_${UPPERCOMPONENT}_DEPENDENCIES}) + list( + APPEND + _Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES + Boost::${dep} + ) + endforeach() + if(COMPONENT STREQUAL "thread") + list( + APPEND + _Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES + Threads::Threads + ) + endif() + set_target_properties( + Boost::${COMPONENT} + PROPERTIES + INTERFACE_LINK_LIBRARIES + "${_Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES}" + ) + endif() + if(_Boost_${UPPERCOMPONENT}_COMPILER_FEATURES) + set_target_properties( + Boost::${COMPONENT} + PROPERTIES + INTERFACE_COMPILE_FEATURES + "${_Boost_${UPPERCOMPONENT}_COMPILER_FEATURES}" + ) + endif() + endif() + endif() + endforeach() + + # Supply Boost_LIB_DIAGNOSTIC_DEFINITIONS as a convenience target. It will only + # contain any interface definitions on WIN32, but is created on all platforms to keep + # end user code free from platform dependent code. Also provide convenience targets + # to disable autolinking and enable dynamic linking. + if(NOT TARGET Boost::diagnostic_definitions) + add_library(Boost::diagnostic_definitions INTERFACE IMPORTED) + add_library(Boost::disable_autolinking INTERFACE IMPORTED) + add_library(Boost::dynamic_linking INTERFACE IMPORTED) + set_target_properties( + Boost::dynamic_linking + PROPERTIES INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_DYN_LINK" + ) + endif() + if(WIN32) + # In windows, automatic linking is performed, so you do not have to specify the + # libraries. If you are linking to a dynamic runtime, then you can choose to link + # to either a static or a dynamic Boost library, the default is to do a static + # link. You can alter this for a specific library "whatever" by defining + # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be linked + # dynamically. Alternatively you can force all Boost libraries to dynamic link by + # defining BOOST_ALL_DYN_LINK. + + # This feature can be disabled for Boost library "whatever" by defining + # BOOST_WHATEVER_NO_LIB, or for all of Boost by defining BOOST_ALL_NO_LIB. + + # If you want to observe which libraries are being linked against then defining + # BOOST_LIB_DIAGNOSTIC will cause the auto-linking code to emit a #pragma message + # each time a library is selected for linking. + set(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC") + set_target_properties( + Boost::diagnostic_definitions + PROPERTIES INTERFACE_COMPILE_DEFINITIONS "BOOST_LIB_DIAGNOSTIC" + ) + set_target_properties( + Boost::disable_autolinking + PROPERTIES INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_NO_LIB" + ) + endif() +endif() + +# ------------------------------------------------------------------------ +# Finalize +# ------------------------------------------------------------------------ + +# Report Boost_LIBRARIES +set(Boost_LIBRARIES "") +foreach(_comp IN LISTS Boost_FIND_COMPONENTS) + string(TOUPPER ${_comp} _uppercomp) + if(Boost_${_uppercomp}_FOUND) + list(APPEND Boost_LIBRARIES ${Boost_${_uppercomp}_LIBRARY}) + if(_comp STREQUAL "thread") + list(APPEND Boost_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) + endif() + endif() +endforeach() + +# Configure display of cache entries in GUI. +foreach(v BOOSTROOT BOOST_ROOT ${_Boost_VARS_INC} ${_Boost_VARS_LIB}) + get_property(_type CACHE ${v} PROPERTY TYPE) + if(_type) + set_property(CACHE ${v} PROPERTY ADVANCED 1) + if("x${_type}" STREQUAL "xUNINITIALIZED") + if("x${v}" STREQUAL "xBoost_ADDITIONAL_VERSIONS") + set_property(CACHE ${v} PROPERTY TYPE STRING) + else() + set_property(CACHE ${v} PROPERTY TYPE PATH) + endif() + endif() + endif() +endforeach() + +# Record last used values of input variables so we can detect on the next run if the user +# changed them. +foreach(v ${_Boost_VARS_INC} ${_Boost_VARS_LIB} ${_Boost_VARS_DIR} ${_Boost_VARS_NAME}) + if(DEFINED ${v}) + set(_${v}_LAST "${${v}}" CACHE INTERNAL "Last used ${v} value.") + else() + unset(_${v}_LAST CACHE) + endif() +endforeach() + +# Maintain a persistent list of components requested anywhere since the last flush. +set(_Boost_COMPONENTS_SEARCHED "${_Boost_COMPONENTS_SEARCHED}") +list(APPEND _Boost_COMPONENTS_SEARCHED ${Boost_FIND_COMPONENTS}) +list(REMOVE_DUPLICATES _Boost_COMPONENTS_SEARCHED) +list(SORT _Boost_COMPONENTS_SEARCHED) +set(_Boost_COMPONENTS_SEARCHED + "${_Boost_COMPONENTS_SEARCHED}" + CACHE INTERNAL + "Components requested for this build tree." +) + +# Restore project's policies +cmake_policy(POP) diff --git a/projects/rocprofiler-systems/cmake/Modules/FindLibDW.cmake b/projects/rocprofiler-systems/cmake/Modules/FindLibDW.cmake new file mode 100644 index 0000000000..8030e78638 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Modules/FindLibDW.cmake @@ -0,0 +1,142 @@ +#[=======================================================================[.rst: +FindLibDW +--------- + +Find libdw, the elfutils library for DWARF data and ELF file or process inspection. + +Variables that affect this module + +``LibDW_NO_SYSTEM_PATHS`` + If `True`, no system paths are searched. + +Imported targets +^^^^^^^^^^^^^^^^ + +This module defines the following :prop_tgt:`IMPORTED` target: + +``LibDW::LibDW`` + The libdw library, if found. + +Result variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: + +``LibDW_INCLUDE_DIRS`` + where to find libdw.h, etc. +``LibDW_LIBRARIES`` + the libraries to link against to use libdw. +``LibDW_FOUND`` + If false, do not try to use libdw. +``LibDW_VERSION`` + the version of the libdw library found + +#]=======================================================================] +cmake_policy(SET CMP0074 NEW) # Use _ROOT + +if(LibDW_NO_SYSTEM_PATHS) + set(_find_path_args NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH) +endif() + +# There is no way to tell pkg-config to ignore directories, so disable it +if(NOT LibDW_NO_SYSTEM_PATHS) + find_package(PkgConfig QUIET) + if(PKG_CONFIG_FOUND) + if(NOT "x${LibDW_FIND_VERSION}" STREQUAL "x") + set(_version ">=${LibDW_FIND_VERSION}") + endif() + if(LibDW_FIND_QUIETLY) + set(_quiet "QUIET") + endif() + + pkg_check_modules(PC_LIBDW ${_quiet} "libdw${_version}") + unset(_version) + unset(_quiet) + endif() +endif() + +if(PC_LIBDW_FOUND) + # FindPkgConfig sometimes gets the include dir wrong + if("x${PC_LIBDW_INCLUDE_DIRS}" STREQUAL "x") + pkg_get_variable(PC_LIBDW_INCLUDE_DIRS libdw includedir) + endif() + + set(LibDW_INCLUDE_DIRS ${PC_LIBDW_INCLUDE_DIRS} CACHE PATH "") + set(LibDW_LIBRARIES ${PC_LIBDW_LINK_LIBRARIES} CACHE PATH "") + set(LibDW_VERSION ${PC_LIBDW_VERSION} CACHE STRING "") +else() + find_path(LibDW_INCLUDE_DIRS NAMES libdw.h PATH_SUFFIXES elfutils ${_find_path_args}) + + find_library(LibDW_LIBRARIES NAMES libdw dw PATH_SUFFIXES elfutils ${_find_path_args}) + + if(EXISTS "${LibDW_INCLUDE_DIRS}/version.h") + file( + STRINGS + "${LibDW_INCLUDE_DIRS}/version.h" + _version_line + REGEX "^#define _ELFUTILS_VERSION[ \t]+[0-9]+" + ) + string(REGEX MATCH "[0-9]+" _version "${_version_line}") + if(NOT "x${_version}" STREQUAL "x") + set(LibDW_VERSION "0.${_version}") + endif() + unset(_version_line) + unset(_version) + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + LibDW + FOUND_VAR LibDW_FOUND + REQUIRED_VARS LibDW_LIBRARIES LibDW_INCLUDE_DIRS + VERSION_VAR LibDW_VERSION +) + +if(LibDW_FOUND) + mark_as_advanced(LibDW_INCLUDE_DIRS) + mark_as_advanced(LibDW_LIBRARIES) + mark_as_advanced(LibDW_VERSION) + + # Some platforms explicitly list libelf as a dependency, so separate it out + list(LENGTH LibDW_LIBRARIES _cnt) + if(${_cnt} GREATER 1) + foreach(_l ${LibDW_LIBRARIES}) + if(${_l} MATCHES "libdw") + set(_libdw ${_l}) + else() + list(APPEND _link_libs ${_l}) + endif() + endforeach() + endif() + unset(_cnt) + + if(NOT TARGET LibDW::LibDW) + add_library(LibDW::LibDW UNKNOWN IMPORTED) + set_target_properties( + LibDW::LibDW + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LibDW_INCLUDE_DIRS}" + ) + + if(NOT "x${_link_libs}" STREQUAL "x") + set_target_properties( + LibDW::LibDW + PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LINK_DEPENDENT_LIBRARIES "${_link_libs}" + ) + set(LibDW_LIBRARIES ${_libdw}) + unset(_libdw) + unset(_link_libs) + endif() + + set_target_properties( + LibDW::LibDW + PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${LibDW_LIBRARIES}" + ) + endif() +endif() + +unset(_find_path_args) diff --git a/projects/rocprofiler-systems/cmake/Modules/FindLibDebuginfod.cmake b/projects/rocprofiler-systems/cmake/Modules/FindLibDebuginfod.cmake new file mode 100644 index 0000000000..695c815a6a --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Modules/FindLibDebuginfod.cmake @@ -0,0 +1,121 @@ +#[=======================================================================[.rst: +FindLibDebuginfod +----------------- + +Find libdebuginfod, the elfutils library to query debuginfo files from debuginfod servers. + +Variables that affect this module + +``LibDebuginfod_NO_SYSTEM_PATHS`` + If `True`, no system paths are searched. + +Imported targets +^^^^^^^^^^^^^^^^ + +This module defines the following :prop_tgt:`IMPORTED` target: + +``LibDebuginfod::LibDebuginfod`` + The libdebuginfod library, if found. + +Result variables +^^^^^^^^^^^^^^^^ + +This module will set the following variables in your project: + +``LibDebuginfod_INCLUDE_DIRS`` + where to find debuginfod.h, etc. +``LibDebuginfod_LIBRARIES`` + the libraries to link against to use libdebuginfod. +``LibDebuginfod_FOUND`` + If false, do not try to use libdebuginfod. +``LibDebuginfod_VERSION`` + the version of the libdebuginfod library found + +#]=======================================================================] +cmake_policy(SET CMP0074 NEW) # Use _ROOT + +if(LibDebuginfod_NO_SYSTEM_PATHS) + set(_find_path_args NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH) +endif() + +# There is no way to tell pkg-config to ignore directories, so disable it +if(NOT LibDebuginfod_NO_SYSTEM_PATHS) + find_package(PkgConfig QUIET) + if(PKG_CONFIG_FOUND) + if(NOT "x${LibDebuginfod_FIND_VERSION}" STREQUAL "x") + set(_version ">=${LibDebuginfod_FIND_VERSION}") + endif() + if(LibDebuginfod_FIND_QUIETLY) + set(_quiet "QUIET") + endif() + + pkg_check_modules(PC_LIBDEBUGINFOD ${_quiet} "libdebuginfod${_version}") + unset(_version) + unset(_quiet) + endif() +endif() + +if(PC_LIBDEBUGINFOD_FOUND) + # FindPkgConfig sometimes gets the include dir wrong + if("x${PC_LIBDEBUGINFOD_INCLUDE_DIRS}" STREQUAL "x") + pkg_get_variable(PC_LIBDEBUGINFOD_INCLUDE_DIRS libdebuginfod includedir) + endif() + + set(LibDebuginfod_INCLUDE_DIRS ${PC_LIBDEBUGINFOD_INCLUDE_DIRS} CACHE PATH "") + set(LibDebuginfod_LIBRARIES ${PC_LIBDEBUGINFOD_LINK_LIBRARIES} CACHE PATH "") + set(LibDebuginfod_VERSION ${PC_LIBDEBUGINFOD_VERSION} CACHE STRING "") +else() + find_path( + LibDebuginfod_INCLUDE_DIRS + NAMES debuginfod.h + PATH_SUFFIXES elfutils ${_find_path_args} + ) + + find_library( + LibDebuginfod_LIBRARIES + NAMES libdebuginfod debuginfod + PATH_SUFFIXES elfutils ${_find_path_args} + ) + + if(EXISTS "${LibDebuginfod_INCLUDE_DIRS}/version.h") + file( + STRINGS + "${LibDebuginfod_INCLUDE_DIRS}/version.h" + _version_line + REGEX "^#define _ELFUTILS_VERSION[ \t]+[0-9]+" + ) + string(REGEX MATCH "[0-9]+" _version "${_version_line}") + if(NOT "x${_version}" STREQUAL "x") + set(LibDebuginfod_VERSION "0.${_version}") + endif() + unset(_version_line) + unset(_version) + endif() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + LibDebuginfod + FOUND_VAR LibDebuginfod_FOUND + REQUIRED_VARS LibDebuginfod_LIBRARIES LibDebuginfod_INCLUDE_DIRS + VERSION_VAR LibDebuginfod_VERSION +) + +if(LibDebuginfod_FOUND) + mark_as_advanced(LibDebuginfod_INCLUDE_DIR) + mark_as_advanced(LibDebuginfod_LIBRARIES) + mark_as_advanced(LibDebuginfod_VERSION) + + if(NOT TARGET LibDebuginfod::LibDebuginfod) + add_library(LibDebuginfod::LibDebuginfod UNKNOWN IMPORTED) + set_target_properties( + LibDebuginfod::LibDebuginfod + PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${LibDebuginfod_INCLUDE_DIRS}" + IMPORTED_LINK_INTERFACE_LANGUAGES "C" + IMPORTED_LOCATION "${LibDebuginfod_LIBRARIES}" + ) + endif() +endif() + +unset(_find_path_args) diff --git a/projects/rocprofiler-systems/cmake/Modules/FindLibDwarf.cmake b/projects/rocprofiler-systems/cmake/Modules/FindLibDwarf.cmake new file mode 100644 index 0000000000..c9d4a956ef --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Modules/FindLibDwarf.cmake @@ -0,0 +1,89 @@ +# =================================================================================== +# FindLibDwarf.cmake +# +# Find libdw include dirs and libraries +# +# ---------------------------------------- +# +# Use this module by invoking find_package with the form:: +# +# find_package(LibDwarf [version] [EXACT] # Minimum or EXACT version e.g. 0.173 +# [REQUIRED] # Fail with error if libdw is not found ) +# +# This module reads hints about search locations from variables:: +# +# LibDwarf_ROOT_DIR - Base directory the of libdw installation +# LibDwarf_INCLUDEDIR - Hint directory that contains the libdw headers files +# LibDwarf_LIBRARYDIR - Hint directory that contains the libdw library files +# +# and saves search results persistently in CMake cache entries:: +# +# LibDwarf_FOUND - True if headers and requested libraries were found +# LibDwarf_INCLUDE_DIRS - libdw include directories LibDwarf_LIBRARY_DIRS - Link +# directories for libdw libraries LibDwarf_LIBRARIES - libdw library files +# +# =================================================================================== + +# Non-standard subdirectories to search +set(_path_suffixes libdw libdwarf elfutils) + +find_path( + LibDwarf_INCLUDE_DIR + NAMES libdw.h + HINTS ${LibDwarf_ROOT_DIR}/include ${LibDwarf_ROOT_DIR} ${LibDwarf_INCLUDEDIR} + PATHS ${DYNINST_SYSTEM_INCLUDE_PATHS} + PATH_SUFFIXES ${_path_suffixes} + DOC "libdw include directories" +) + +find_library( + LibDwarf_LIBRARIES + NAMES libdw.so.1 libdw.so + HINTS ${LibDwarf_ROOT_DIR}/lib ${LibDwarf_ROOT_DIR} ${LibDwarf_LIBRARYDIR} + PATHS ${DYNINST_SYSTEM_LIBRARY_PATHS} + PATH_SUFFIXES ${_path_suffixes} +) + +# Find the library with the highest version +set(_max_ver 0.0) +set(_max_ver_lib) +foreach(l ${LibDwarf_LIBRARIES}) + get_filename_component(_dw_realpath ${LibDwarf_LIBRARIES} REALPATH) + string(REGEX MATCH "libdw\\-(.+)\\.so\\.*$" res ${_dw_realpath}) + + # The library version number is stored in CMAKE_MATCH_1 + set(_cur_ver ${CMAKE_MATCH_1}) + + if(${_cur_ver} VERSION_GREATER ${_max_ver}) + set(_max_ver ${_cur_ver}) + set(_max_ver_lib ${l}) + endif() +endforeach() + +# Set the exported variables to the best match +set(LibDwarf_LIBRARIES ${_max_ver_lib}) +set(LibDwarf_VERSION ${_max_ver}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + LibDwarf + FOUND_VAR LibDwarf_FOUND + REQUIRED_VARS LibDwarf_LIBRARIES LibDwarf_INCLUDE_DIR + VERSION_VAR LibDwarf_VERSION +) + +# Export cache variables +if(LibDwarf_FOUND) + set(LibDwarf_INCLUDE_DIRS ${LibDwarf_INCLUDE_DIR}) + set(LibDwarf_LIBRARIES ${LibDwarf_LIBRARIES}) + + # Because we only report the library with the largest version, we are guaranteed there + # is only one file in LibDwarf_LIBRARIES + get_filename_component(_dw_dir ${LibDwarf_LIBRARIES} DIRECTORY) + set(LibDwarf_LIBRARY_DIRS ${_dw_dir}) + + add_library(LibDwarf::LibDwarf INTERFACE IMPORTED) + target_include_directories(LibDwarf::LibDwarf INTERFACE ${LibDwarf_INCLUDE_DIR}) + target_link_directories(LibDwarf::LibDwarf INTERFACE ${LibDwarf_LIBRARY_DIRS}) + target_link_libraries(LibDwarf::LibDwarf INTERFACE ${LibDwarf_LIBRARIES}) +endif() diff --git a/projects/rocprofiler-systems/cmake/Modules/FindLibElf.cmake b/projects/rocprofiler-systems/cmake/Modules/FindLibElf.cmake new file mode 100644 index 0000000000..782a688006 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Modules/FindLibElf.cmake @@ -0,0 +1,91 @@ +# ======================================================================================== +# FindLibElf.cmake +# +# Find libelf include dirs and libraries +# +# ---------------------------------------- +# +# Use this module by invoking find_package with the form:: +# +# find_package(LibElf [version] [EXACT] # Minimum or EXACT version e.g. 0.173 +# [REQUIRED] # Fail with error if libelf is not found ) +# +# This module reads hints about search locations from variables:: +# +# LibElf_ROOT_DIR - Base directory the of libelf installation LibElf_INCLUDEDIR - +# Hint directory that contains the libelf headers files LibElf_LIBRARYDIR - Hint +# directory that contains the libelf library files +# +# and saves search results persistently in CMake cache entries:: +# +# LibElf_FOUND - True if headers and requested libraries were found +# LibElf_INCLUDE_DIRS - libelf include directories LibElf_LIBRARY_DIRS - Link +# directories for libelf libraries LibElf_LIBRARIES - libelf library files +# +# Based on the version by Bernhard Walle Copyright (c) 2008 +# +# ======================================================================================== + +# Non-standard subdirectories to search +set(_path_suffixes libelf libelfls elfutils) + +find_path( + LibElf_INCLUDE_DIR + NAMES libelf.h + HINTS ${LibElf_ROOT_DIR}/include ${LibElf_ROOT_DIR} ${LibElf_INCLUDEDIR} + PATHS ${DYNINST_SYSTEM_INCLUDE_PATHS} + PATH_SUFFIXES ${_path_suffixes} + DOC "libelf include directories" +) + +find_library( + LibElf_LIBRARIES + NAMES libelf.so.1 libelf.so + HINTS ${LibElf_ROOT_DIR}/lib ${LibElf_ROOT_DIR} ${LibElf_LIBRARYDIR} + PATHS ${DYNINST_SYSTEM_LIBRARY_PATHS} + PATH_SUFFIXES ${_path_suffixes} +) + +# Find the library with the highest version +set(_max_ver 0.0) +set(_max_ver_lib) +foreach(l ${LibElf_LIBRARIES}) + get_filename_component(_elf_realpath ${LibElf_LIBRARIES} REALPATH) + string(REGEX MATCH "libelf\\-(.+)\\.so\\.*$" res ${_elf_realpath}) + + # The library version number is stored in CMAKE_MATCH_1 + set(_cur_ver ${CMAKE_MATCH_1}) + + if(${_cur_ver} VERSION_GREATER ${_max_ver}) + set(_max_ver ${_cur_ver}) + set(_max_ver_lib ${l}) + endif() +endforeach() + +# Set the exported variables to the best match +set(LibElf_LIBRARIES ${_max_ver_lib}) +set(LibElf_VERSION ${_max_ver}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + LibElf + FOUND_VAR LibElf_FOUND + REQUIRED_VARS LibElf_LIBRARIES LibElf_INCLUDE_DIR + VERSION_VAR LibElf_VERSION +) + +# Export cache variables +if(LibElf_FOUND) + set(LibElf_INCLUDE_DIRS ${LibElf_INCLUDE_DIR}) + set(LibElf_LIBRARIES ${LibElf_LIBRARIES}) + + # Because we only report the library with the largest version, we are guaranteed there + # is only one file in LibElf_LIBRARIES + get_filename_component(_elf_dir ${LibElf_LIBRARIES} DIRECTORY) + set(LibElf_LIBRARY_DIRS ${_elf_dir} "${_elf_dir}/elfutils") + + add_library(LibElf::LibElf INTERFACE IMPORTED) + target_include_directories(LibElf::LibElf INTERFACE ${LibElf_INCLUDE_DIR}) + target_link_directories(LibElf::LibElf INTERFACE ${LibElf_LIBRARY_DIRS}) + target_link_libraries(LibElf::LibElf INTERFACE ${LibElf_LIBRARIES}) +endif() diff --git a/projects/rocprofiler-systems/cmake/Modules/FindLibIberty.cmake b/projects/rocprofiler-systems/cmake/Modules/FindLibIberty.cmake new file mode 100644 index 0000000000..36d38db4ab --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Modules/FindLibIberty.cmake @@ -0,0 +1,83 @@ +# ======================================================================================== +# FindLibIberty.cmake +# +# Find LibIberty include dirs and libraries +# +# ---------------------------------------- +# +# Use this module by invoking find_package with the form:: +# +# find_package(LibIberty [REQUIRED] # Fail with error if LibIberty is not +# found ) +# +# This module reads hints about search locations from variables:: +# +# LibIberty_ROOT_DIR - Base directory the of LibIberty installation +# LibIberty_LIBRARYDIR - Hint directory that contains the LibIberty library files +# IBERTY_LIBRARIES - Alias for LibIberty_LIBRARIES (backwards compatibility only) +# LibIberty_INCLUDEDIR - Hint directory that contains the libiberty headers files +# +# and saves search results persistently in CMake cache entries:: +# +# LibIberty_FOUND - True if headers and requested libraries were found +# IBERTY_FOUND - Alias for LibIberty_FOUND (backwards compatibility only) +# LibIberty_INCLUDE_DIRS - libiberty include directories LibIberty_LIBRARY_DIRS - Link +# directories for LibIberty libraries LibIberty_LIBRARIES - LibIberty library files +# IBERTY_LIBRARIES - Alias for LibIberty_LIBRARIES (backwards compatibility only) +# +# ======================================================================================== + +cmake_minimum_required(VERSION 3.13.0 FATAL_ERROR) + +# Keep the semantics of IBERTY_LIBRARIES for backward compatibility NB: If both are +# specified, LibIberty_LIBRARIES is ignored +if(NOT "${IBERTY_LIBRARIES}" STREQUAL "") + set(LibIberty_LIBRARIES ${IBERTY_LIBRARIES}) +endif() + +# Non-standard subdirectories to search +set(_path_suffixes libiberty iberty) + +find_path( + LibIberty_INCLUDE_DIRS + NAMES libiberty.h + HINTS ${LibIberty_ROOT_DIR} ${LibIberty_ROOT_DIR}/include ${LibIberty_INCLUDEDIR} + PATHS ${DYNINST_SYSTEM_INCLUDE_PATHS} + PATH_SUFFIXES ${_path_suffixes} + DOC "LibIberty include directories" +) + +# iberty_pic is for Debian <= wheezy +find_library( + LibIberty_LIBRARIES + NAMES iberty_pic iberty + HINTS ${LibIberty_ROOT_DIR} ${LibIberty_LIBRARYDIR} ${IBERTY_LIBRARIES} + PATHS ${DYNINST_SYSTEM_LIBRARY_PATHS} + PATH_SUFFIXES ${_path_suffixes} +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + LibIberty + FOUND_VAR LibIberty_FOUND + REQUIRED_VARS LibIberty_INCLUDE_DIRS LibIberty_LIBRARIES +) + +# For backwards compatibility only +set(IBERTY_FOUND ${LibIberty_FOUND}) + +if(LibIberty_FOUND) + foreach(l ${LibIberty_LIBRARIES}) + get_filename_component(_dir ${l} DIRECTORY) + if(NOT "${_dir}" IN_LIST LibIberty_LIBRARY_DIRS) + list(APPEND LibIberty_LIBRARY_DIRS ${_dir}) + endif() + endforeach() + + add_library(LibIberty::LibIberty INTERFACE IMPORTED) + target_include_directories(LibIberty::LibIberty INTERFACE ${LibIberty_INCLUDE_DIRS}) + target_link_libraries(LibIberty::LibIberty INTERFACE ${LibIberty_LIBRARIES}) + + # For backwards compatibility only + set(IBERTY_LIBRARIES ${LibIberty_LIBRARIES}) +endif() diff --git a/projects/rocprofiler-systems/cmake/Modules/FindLibva-headers.cmake b/projects/rocprofiler-systems/cmake/Modules/FindLibva-headers.cmake new file mode 100644 index 0000000000..e4b463cc2e --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Modules/FindLibva-headers.cmake @@ -0,0 +1,56 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying file +# Copyright.txt or https://cmake.org/licensing for details. + +include(FindPackageHandleStandardArgs) + +# ----------------------------------------------------------------------------------------# + +set(LIBVA_HEADERS_INCLUDE_DIR_INTERNAL + "${PROJECT_SOURCE_DIR}/source/lib/rocprof-sys/library/tpls" + CACHE PATH + "Path to internal va headers" +) + +# ----------------------------------------------------------------------------------------# +find_path( + LIBVA_HEADERS_INCLUDE_DIR + NAMES va/va.h + PATHS /opt/amdgpu/include + NO_DEFAULT_PATH +) + +if(NOT EXISTS "${LIBVA_HEADERS_INCLUDE_DIR}") + rocprofiler_systems_message( + AUTHOR_WARNING + "VA API header does not exist! Setting LIBVA_HEADERS_INCLUDE_DIR to internal directory: ${LIBVA_HEADERS_INCLUDE_DIR}" + ) + set(LIBVA_HEADERS_INCLUDE_DIR + "${LIBVA_HEADERS_INCLUDE_DIR_INTERNAL}" + CACHE PATH + "Path to VA API headers" + FORCE + ) +else() + rocprofiler_systems_message(STATUS + "VA API header found: ${LIBVA_HEADERS_INCLUDE_DIR}" + ) +endif() + +mark_as_advanced(LIBVA_HEADERS_INCLUDE_DIR) + +# ----------------------------------------------------------------------------------------# + +find_package_handle_standard_args(Libva-headers DEFAULT_MSG LIBVA_HEADERS_INCLUDE_DIR) + +# ------------------------------------------------------------------------------# + +if(Libva-headers_FOUND) + add_library(roc::libva-headers INTERFACE IMPORTED) + target_include_directories( + roc::libva-headers + SYSTEM + INTERFACE ${LIBVA_HEADERS_INCLUDE_DIR} + ) +endif() + +# ------------------------------------------------------------------------------# diff --git a/projects/rocprofiler-systems/cmake/Modules/FindMPI-Headers.cmake b/projects/rocprofiler-systems/cmake/Modules/FindMPI-Headers.cmake new file mode 100644 index 0000000000..ae625c75de --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Modules/FindMPI-Headers.cmake @@ -0,0 +1,198 @@ +# ------------------------------------------------------------------------------# +# +# Finds headers for MPI +# +# ------------------------------------------------------------------------------# + +include(FindPackageHandleStandardArgs) + +set(MPI_HEADERS_VENDOR_INTERNAL + "OpenMPI" + CACHE STRING + "Distribution type of internal mpi.h" +) +set(MPI_HEADERS_INCLUDE_DIR_INTERNAL + "${PROJECT_SOURCE_DIR}/source/lib/rocprof-sys/library/tpls/mpi" + CACHE PATH + "Path to internal ${MPI_HEADERS_VENDOR_INTERNAL} mpi.h" +) +mark_as_advanced(MPI_HEADERS_VENDOR_INTERNAL) +mark_as_advanced(MPI_HEADERS_INCLUDE_DIR_INTERNAL) + +if( + DEFINED _MPI_HEADERS_LAST_MPI_HEADERS_INCLUDE_DIR + AND NOT _MPI_HEADERS_LAST_MPI_HEADERS_INCLUDE_DIR STREQUAL MPI_HEADERS_INCLUDE_DIR +) + unset(MPI_HEADERS_VENDOR CACHE) + # if skip mpicxx is on because of internal unset this value + if( + MPI_HEADERS_SKIP_MPICXX + AND "${_MPI_HEADERS_LAST_MPI_HEADERS_INCLUDE_DIR}" + STREQUAL + "${MPI_HEADERS_INCLUDE_DIR_INTERNAL}" + ) + unset(MPI_HEADERS_SKIP_MPICXX CACHE) + endif() +endif() + +# define the (OMPI|MPICH)_SKIP_MPICXX pp definition +option(MPI_HEADERS_SKIP_MPICXX "Skip MPI C++" ON) +mark_as_advanced(MPI_HEADERS_SKIP_MPICXX) + +# ------------------------------------------------------------------------------# +# +# Try to find an openmpi header +# +# ------------------------------------------------------------------------------# + +find_path( + MPI_HEADERS_INCLUDE_DIR + NAMES mpi.h + PATH_SUFFIXES include/openmpi openmpi include + HINTS ${MPI_ROOT_DIR} + PATHS ${MPI_ROOT_DIR} +) + +# ------------------------------------------------------------------------------# +# +# If direct find failed, try to find MPI and use MPI_C_INCLUDE_DIRS +# +# ------------------------------------------------------------------------------# + +if(NOT MPI_HEADERS_INCLUDE_DIR) + find_package(MPI QUIET) + if(MPI_C_INCLUDE_DIRS) + set(MPI_HEADERS_INCLUDE_DIR + ${MPI_C_INCLUDE_DIRS} + CACHE PATH + "Include directory for MPI" + FORCE + ) + elseif(MPI_CXX_INCLUDE_DIRS) + set(MPI_HEADERS_INCLUDE_DIR + ${MPI_CXX_INCLUDE_DIRS} + CACHE PATH + "Include directory for MPI" + FORCE + ) + endif() +endif() + +# ------------------------------------------------------------------------------# +# +# If found, try to determine the MPI vendor (i.e. distribution) +# +# ------------------------------------------------------------------------------# + +if(MPI_HEADERS_INCLUDE_DIR) + file(STRINGS ${MPI_HEADERS_INCLUDE_DIR}/mpi.h _MPI_H_LINES REGEX "#([ \t]+)define ") + foreach(_LINE ${_MPI_H_LINES}) + if("${_LINE}" MATCHES "define([ \t]+)OMPI_") + set(MPI_HEADERS_VENDOR + "OpenMPI" + CACHE STRING + "MPI headers are from OpenMPI distribution" + ) + break() + elseif("${_LINE}" MATCHES "define([ \t]+)MPICH_") + set(MPI_HEADERS_VENDOR + "MPICH" + CACHE STRING + "MPI headers are from MPICH distribution" + ) + break() + elseif("${_LINE}" MATCHES "define([ \t]+)MVAPICH_") + set(MPI_HEADERS_VENDOR + "MVAPICH" + CACHE STRING + "MPI headers are from MVAPICH distribution" + ) + break() + endif() + endforeach() +endif() + +# ------------------------------------------------------------------------------# +# +# If not found, use internal version or if vendor is MPICH set to internal +# +# ------------------------------------------------------------------------------# + +if(NOT MPI_HEADERS_INCLUDE_DIR) + set(MPI_HEADERS_INCLUDE_DIR "${MPI_HEADERS_INCLUDE_DIR_INTERNAL}" CACHE PATH "" FORCE) + set(MPI_HEADERS_VENDOR + "${MPI_HEADERS_VENDOR_INTERNAL}" + CACHE STRING + "MPI headers are from OpenMPI distribution" + FORCE + ) + set(MPI_HEADERS_SKIP_MPICXX ON CACHE BOOL "" FORCE) +elseif("${MPI_HEADERS_VENDOR}" STREQUAL "MPICH") + option( + MPI_HEADERS_ALLOW_MPICH + "Permit the use of MPI headers from MPICH instead of using internal OpenMPI header" + OFF + ) + mark_as_advanced(MPI_HEADERS_ALLOW_MPICH) + if(NOT MPI_HEADERS_ALLOW_MPICH) + set(_MESSAGE "\nFound MPI headers belonging to a MPICH distribution. ") + set(_MESSAGE + "${_MESSAGE}The data types for MPICH will cause segfaults when an application uses OpenMPI, " + ) + set(_MESSAGE + "${_MESSAGE}whereas the OpenMPI data types are compatible with both. " + ) + set(_MESSAGE + "${_MESSAGE}Forcing internal OpenMPI header... This can be disabled via MPI_HEADERS_ALLOW_MPICH=ON ...\n" + ) + message(AUTHOR_WARNING "${_MESSAGE}") + unset(_MESSAGE) + set(MPI_HEADERS_INCLUDE_DIR + "${MPI_HEADERS_INCLUDE_DIR_INTERNAL}" + CACHE PATH + "" + FORCE + ) + set(MPI_HEADERS_VENDOR + "${MPI_HEADERS_VENDOR_INTERNAL}" + CACHE STRING + "MPI headers are from OpenMPI distribution" + FORCE + ) + set(MPI_HEADERS_SKIP_MPICXX ON CACHE BOOL "" FORCE) + endif() +endif() + +# set local variable +if(MPI_HEADERS_INCLUDE_DIR) + set(MPI_HEADERS_INCLUDE_DIRS ${MPI_HEADERS_INCLUDE_DIR}) +endif() + +mark_as_advanced(MPI_HEADERS_INCLUDE_DIR) + +# store value to detect changes +set(_MPI_HEADERS_LAST_MPI_HEADERS_INCLUDE_DIR + "${MPI_HEADERS_INCLUDE_DIR}" + CACHE INTERNAL + "Last value of MPI_HEADERS_INCLUDE_DIR" +) + +# handle find_package +find_package_handle_standard_args(MPI-Headers REQUIRED_VARS MPI_HEADERS_INCLUDE_DIR) + +if(MPI-Headers_FOUND) + add_library(MPI::MPI_HEADERS IMPORTED INTERFACE) + if(MPI_HEADERS_SKIP_MPICXX) + if(MPI_HEADERS_VENDOR STREQUAL "MPICH") + target_compile_definitions(MPI::MPI_HEADERS INTERFACE MPICH_SKIP_MPICXX=1) + else() + target_compile_definitions(MPI::MPI_HEADERS INTERFACE OMPI_SKIP_MPICXX=1) + endif() + endif() + target_include_directories( + MPI::MPI_HEADERS + INTERFACE + $<$:${MPI_HEADERS_INCLUDE_DIR}> + $<$:${MPI_HEADERS_INCLUDE_DIR}> + ) +endif() diff --git a/projects/rocprofiler-systems/cmake/Modules/FindROCmVersion.cmake b/projects/rocprofiler-systems/cmake/Modules/FindROCmVersion.cmake new file mode 100644 index 0000000000..97fe56727d --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Modules/FindROCmVersion.cmake @@ -0,0 +1,372 @@ +#[=======================================================================[.rst: +FindROCmVersion +--------------- + +Search the /.info/version* files to determine the version of ROCm + +Use this module by invoking find_package with the form:: + + find_package(ROCmVersion + [version] [EXACT] + [REQUIRED]) + +This module finds the version info for ROCm. The cached variables are:: + + ROCmVersion_FOUND - Whether the ROCm versioning was found + ROCmVersion_FULL_VERSION - The exact string from `/.info/version` or similar + ROCmVersion_MAJOR_VERSION - Major version, e.g. 4 in 4.5.2.100-40502 + ROCmVersion_MINOR_VERSION - Minor version, e.g. 5 in 4.5.2.100-40502 + ROCmVersion_PATCH_VERSION - Patch version, e.g. 2 in 4.5.2.100-40502 + ROCmVersion_TWEAK_VERSION - Tweak version, e.g. 100 in 4.5.2.100-40502 + ROCmVersion_REVISION_VERSION - Revision version, e.g. 40502 in 4.5.2.100-40502. + ROCmVersion_EPOCH_VERSION - See deb-version for a description of epochs. Epochs are used when versioning system change + ROCmVersion_CANONICAL_VERSION - `[:]..[.][-]` + ROCmVersion_NUMERIC_VERSION - e.g. `10000* + 100* + `, e.g. 40502 for ROCm 4.5.2 + ROCmVersion_TRIPLE_VERSION - e.g. `..`, e.g. 4.5.2 for ROCm 4.5.2 + +These variables are relevant for the find procedure:: + + ROCmVersion_DEBUG - Print info about processing + ROCmVersion_VERSION_FILE - `` to read from in `/.info/`, e.g. `version`, `version-dev`, `version-hip-libraries`, etc. + It may also be a full path + ROCmVersion_DIR - Root location for +#]=======================================================================] + +set(ROCmVersion_VARIABLES + EPOCH + MAJOR + MINOR + PATCH + TWEAK + REVISION + TRIPLE + NUMERIC + CANONICAL + FULL +) + +function(ROCM_VERSION_MESSAGE _TYPE) + if(ROCmVersion_DEBUG) + message(${_TYPE} "[ROCmVersion] ${ARGN}") + endif() +endfunction() + +# read a .info/version* file and propagate the variables to the calling scope +function(ROCM_VERSION_COMPUTE FULL_VERSION_STRING _VAR_PREFIX) + # remove any line endings + string(REGEX REPLACE "(\n|\r)" "" FULL_VERSION_STRING "${FULL_VERSION_STRING}") + + # store the full version so it can be set later + set(FULL_VERSION "${FULL_VERSION_STRING}") + + # get number and remove from full version string + string(REGEX REPLACE "([0-9]+)\:(.*)" "\\1" EPOCH_VERSION "${FULL_VERSION_STRING}") + string( + REGEX REPLACE + "([0-9]+)\:(.*)" + "\\2" + FULL_VERSION_STRING + "${FULL_VERSION_STRING}" + ) + + if(EPOCH_VERSION STREQUAL FULL_VERSION) + set(EPOCH_VERSION) + endif() + + # get number and remove from full version string + string(REGEX REPLACE "([0-9]+)(.*)" "\\1" MAJOR_VERSION "${FULL_VERSION_STRING}") + string( + REGEX REPLACE + "([0-9]+)(.*)" + "\\2" + FULL_VERSION_STRING + "${FULL_VERSION_STRING}" + ) + + # get number and remove from full version string + string(REGEX REPLACE "\.([0-9]+)(.*)" "\\1" MINOR_VERSION "${FULL_VERSION_STRING}") + string( + REGEX REPLACE + "\.([0-9]+)(.*)" + "\\2" + FULL_VERSION_STRING + "${FULL_VERSION_STRING}" + ) + + # get number and remove from full version string + string(REGEX REPLACE "\.([0-9]+)(.*)" "\\1" PATCH_VERSION "${FULL_VERSION_STRING}") + string( + REGEX REPLACE + "\.([0-9]+)(.*)" + "\\2" + FULL_VERSION_STRING + "${FULL_VERSION_STRING}" + ) + + if(NOT PATCH_VERSION LESS 100) + set(PATCH_VERSION 0) + endif() + + # get number and remove from full version string + string(REGEX REPLACE "\.([0-9]+)(.*)" "\\1" TWEAK_VERSION "${FULL_VERSION_STRING}") + string( + REGEX REPLACE + "\.([0-9]+)(.*)" + "\\2" + FULL_VERSION_STRING + "${FULL_VERSION_STRING}" + ) + + # get number + string( + REGEX REPLACE + "-([0-9A-Za-z+~]+)" + "\\1" + REVISION_VERSION + "${FULL_VERSION_STRING}" + ) + + set(CANONICAL_VERSION) + set(_MAJOR_SEP ":") + set(_MINOR_SEP ".") + set(_PATCH_SEP ".") + set(_TWEAK_SEP ".") + set(_REVISION_SEP "-") + + foreach( + _V + EPOCH + MAJOR + MINOR + PATCH + TWEAK + REVISION + ) + if(${_V}_VERSION) + set(CANONICAL_VERSION "${CANONICAL_VERSION}${_${_V}_SEP}${${_V}_VERSION}") + else() + set(CANONICAL_VERSION "${CANONICAL_VERSION}${_${_V}_SEP}0") + endif() + endforeach() + + set(_MAJOR_SEP "") + + foreach(_V MAJOR MINOR PATCH) + if(${_V}_VERSION) + set(TRIPLE_VERSION "${TRIPLE_VERSION}${_${_V}_SEP}${${_V}_VERSION}") + else() + set(TRIPLE_VERSION "${TRIPLE_VERSION}${_${_V}_SEP}0") + endif() + endforeach() + + math( + EXPR + NUMERIC_VERSION + "(10000 * (${MAJOR_VERSION}+0)) + (100 * (${MINOR_VERSION}+0)) + (${PATCH_VERSION}+0)" + ) + + # propagate to parent scopes + foreach(_V ${ROCmVersion_VARIABLES}) + set(${_VAR_PREFIX}_${_V}_VERSION ${${_V}_VERSION} PARENT_SCOPE) + endforeach() +endfunction() + +# this macro watches for changes in the variables and unsets the remaining cache varaible +# when they change +function(ROCM_VERSION_WATCH_FOR_CHANGE _var) + set(_rocm_version_watch_var_name ROCmVersion_WATCH_VALUE_${_var}) + + if(DEFINED ${_rocm_version_watch_var_name}) + if("${${_var}}" STREQUAL "${${_rocm_version_watch_var_name}}") + if(NOT "${${_var}}" STREQUAL "") + rocm_version_message(STATUS "${_var} :: ${${_var}}") + endif() + + list(REMOVE_ITEM _REMAIN_VARIABLES ${_var}) + set(_REMAIN_VARIABLES "${_REMAIN_VARIABLES}" PARENT_SCOPE) + return() + else() + rocm_version_message( + STATUS + "${_var} changed :: ${${_rocm_version_watch_var_name}} --> ${${_var}}" + ) + + foreach(_V ${_REMAIN_VARIABLES}) + rocm_version_message( + STATUS "${_var} changed :: Unsetting cache variable ${_V}..." + ) + unset(${_V} CACHE) + endforeach() + endif() + else() + if(NOT "${${_var}}" STREQUAL "") + rocm_version_message(STATUS "${_var} :: ${${_var}}") + endif() + endif() + + # store the value for the next run + set(${_rocm_version_watch_var_name} + "${${_var}}" + CACHE INTERNAL + "Last value of ${_var}" + FORCE + ) +endfunction() + +# scope this to a function to avoid leaking local variables +function(ROCM_VERSION_PARSE_VERSION_FILES) + # the list of variables set by module. when one of these changes, we need to unset the + # cache variables after it + set(_ALL_VARIABLES) + + foreach(_V ${ROCmVersion_VARIABLES}) + list(APPEND _ALL_VARIABLES ROCmVersion_${_V}_VERSION) + endforeach() + set(_REMAIN_VARIABLES ${_ALL_VARIABLES}) + + # read a .info/version* file and propagate the variables to the calling scope + function(ROCM_VERSION_READ_FILE _FILE _VAR_PREFIX) + file(READ "${_FILE}" FULL_VERSION_STRING LIMIT_COUNT 1) + rocm_version_compute("${FULL_VERSION_STRING}" "${_VAR_PREFIX}") + + # propagate to parent scopes + foreach(_V ${ROCmVersion_VARIABLES}) + set(${_VAR_PREFIX}_${_V}_VERSION ${${_VAR_PREFIX}_${_V}_VERSION} PARENT_SCOPE) + endforeach() + endfunction() + + # search for HIP to set ROCM_PATH if(NOT hip_FOUND) find_package(hip) endif() + + function(COMPUTE_ROCM_VERSION_DIR) + if( + EXISTS "${ROCmVersion_VERSION_FILE}" + AND IS_ABSOLUTE "${ROCmVersion_VERSION_FILE}" + ) + get_filename_component(_VERSION_DIR "${ROCmVersion_VERSION_FILE}" PATH) + get_filename_component(_VERSION_DIR "${_VERSION_DIR}/.." REALPATH) + set(ROCmVersion_DIR + "${_VERSION_DIR}" + CACHE PATH + "Root path to ROCm's .info/${ROCmVersion_VERSION_FILE}" + ${ARGN} + ) + rocm_version_watch_for_change(ROCmVersion_DIR) + endif() + endfunction() + + if(ROCmVersion_VERSION_FILE) + get_filename_component(_VERSION_FILE "${ROCmVersion_VERSION_FILE}" NAME) + set(_VERSION_FILES ${_VERSION_FILE}) + compute_rocm_version_dir(FORCE) + else() + set(_VERSION_FILES + version + version-dev + version-hip-libraries + version-hiprt + version-hiprt-devel + version-hip-sdk + version-libs + version-utils + ) + rocm_version_message(STATUS "ROCmVersion version files: ${_VERSION_FILES}") + endif() + + # convert env to cache if not defined + foreach( + _PATH + ROCmVersion_DIR + ROCmVersion_ROOT + ROCmVersion_ROOT_DIR + ROCPROFSYS_DEFAULT_ROCM_PATH + ROCM_PATH + ) + if(NOT DEFINED ${_PATH} AND DEFINED ENV{${_PATH}}) + set(_VAL "$ENV{${_PATH}}") + get_filename_component(_VAL "${_VAL}" REALPATH) + set(${_PATH} + "${_VAL}" + CACHE PATH + "Search path for ROCm version for ROCmVersion" + ) + endif() + endforeach() + + if(ROCmVersion_DIR) + set(_PATHS ${ROCmVersion_DIR}) + else() + set(_PATHS) + foreach( + _DIR + ${ROCmVersion_DIR} + ${ROCmVersion_ROOT} + ${ROCmVersion_ROOT_DIR} + $ENV{CMAKE_PREFIX_PATH} + ${CMAKE_PREFIX_PATH} + ${ROCPROFSYS_DEFAULT_ROCM_PATH} + ${ROCM_PATH} + /opt/rocm + ) + if(EXISTS ${_DIR}) + get_filename_component(_ABS_DIR "${_DIR}" REALPATH) + list(APPEND _PATHS ${_ABS_DIR}) + endif() + endforeach() + rocm_version_message(STATUS "ROCmVersion search paths: ${_PATHS}") + endif() + + string(REPLACE ":" ";" _PATHS "${_PATHS}") + + foreach(_PATH ${_PATHS}) + foreach(_FILE ${_VERSION_FILES}) + set(_F ${_PATH}/.info/${_FILE}) + if(EXISTS ${_F}) + set(ROCmVersion_VERSION_FILE + "${_F}" + CACHE FILEPATH + "File with versioning info" + ) + rocm_version_watch_for_change(ROCmVersion_VERSION_FILE) + compute_rocm_version_dir() + else() + rocm_version_message(AUTHOR_WARNING "File does not exist: ${_F}") + endif() + endforeach() + endforeach() + + if(EXISTS "${ROCmVersion_VERSION_FILE}") + set(_F "${ROCmVersion_VERSION_FILE}") + rocm_version_message(STATUS "Reading ${_F}...") + get_filename_component(_B "${_F}" NAME) + string(REPLACE "." "_" _B "${_B}") + string(REPLACE "-" "_" _B "${_B}") + rocm_version_read_file(${_F} ${_B}) + + foreach(_V ${ROCmVersion_VARIABLES}) + set(_CACHE_VAR ROCmVersion_${_V}_VERSION) + set(_LOCAL_VAR ${_B}_${_V}_VERSION) + set(ROCmVersion_${_V}_VERSION + "${${_LOCAL_VAR}}" + CACHE STRING + "ROCm ${_V} version" + ) + rocm_version_watch_for_change(${_CACHE_VAR}) + endforeach() + endif() +endfunction() + +# execute +rocm_version_parse_version_files() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + ROCmVersion + VERSION_VAR ROCmVersion_FULL_VERSION + REQUIRED_VARS + ROCmVersion_FULL_VERSION + ROCmVersion_TRIPLE_VERSION + ROCmVersion_DIR + ROCmVersion_VERSION_FILE +) +# don't add major/minor/patch/etc. version variables to required vars because they might +# be zero, which will cause CMake to evaluate it as not set diff --git a/projects/rocprofiler-systems/cmake/Modules/FindTBB.cmake b/projects/rocprofiler-systems/cmake/Modules/FindTBB.cmake new file mode 100644 index 0000000000..982545f108 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Modules/FindTBB.cmake @@ -0,0 +1,297 @@ +# ====================================================================================================== +# FindTBB.cmake +# +# Find TBB include directories and libraries. +# +# ---------------------------------------- +# +# Use this module by invoking find_package with the form:: +# +# find_package(TBB [major[.minor]] [EXACT] [QUIET] # Minimum or EXACT version e.g. +# 2018.6 [REQUIRED] # Fail with error if TBB is not found +# [[COMPONENTS] [components...]] # Required components [OPTIONAL_COMPONENTS +# components...] # Optional components ) +# +# This module reads hints about search locations from variables:: +# +# TBB_ROOT_DIR - The base directory the of TBB installation. TBB_INCLUDE_DIR - +# The directory that contains the TBB headers files. TBB_LIBRARY - The directory +# that contains the TBB library files. TBB__LIBRARY - The path of the TBB the +# corresponding TBB library. These libraries override the corresponding library search +# results. TBB_USE_DEBUG_BUILD - Use the debug version of tbb libraries +# +# Environment variable aliases for TBB_ROOT_DIR: +# +# TBB_INSTALL_DIR TBBROOT LIBRARY_PATH +# +# This module will set the following variables: +# +# TBB_FOUND - If false, or undefined, TBB not found, or don’t want to +# use TBB. TBB__FOUND - If False, optional part of TBB +# sytem is not available. TBB_VERSION - The full version string TBB_VERSION_MAJOR - The +# major version TBB_VERSION_MINOR - The minor version TBB_INTERFACE_VERSION - The +# interface version number defined in tbb/tbb_stddef.h. TBB__LIBRARY_RELEASE - +# The path of the TBB release version of . TBB__LIBRARY_DEBUG - The +# path of the TBB debug version of . +# +# The following varibles should be used to build and link with TBB: +# +# TBB_INCLUDE_DIRS - The include directory for TBB. TBB_LIBRARY_DIRS - The library +# directory for TBB. TBB_LIBRARIES - The libraries to link against to use TBB. +# TBB_LIBRARIES_RELEASE - The release libraries to link against to use TBB. +# TBB_LIBRARIES_DEBUG - The debug libraries to link against to use TBB. +# TBB_DEFINITIONS - Definitions to use when compiling code that uses TBB. +# TBB_DEFINITIONS_RELEASE - Definitions to use when compiling release code that uses TBB. +# TBB_DEFINITIONS_DEBUG - Definitions to use when compiling debug code that uses TBB. +# +# This module will also create the "TBB" target that may be used when building executables +# and libraries. +# +# Based on the version by Justus Calvin - Copyright (c) 2015 +# +# ====================================================================================================== + +if(TBB_FOUND) + return() +endif() + +include(FindPackageHandleStandardArgs) + +# +# Check the build type +# +if(NOT DEFINED TBB_USE_DEBUG_BUILD) + if(CMAKE_BUILD_TYPE MATCHES "(Debug|DEBUG|debug)") + set(TBB_BUILD_TYPE DEBUG) + else() + set(TBB_BUILD_TYPE RELEASE) + endif() +elseif(TBB_USE_DEBUG_BUILD) + set(TBB_BUILD_TYPE DEBUG) +else() + set(TBB_BUILD_TYPE RELEASE) +endif() + +# +# Set the TBB search directories +# + +# Define search paths based on user input and environment variables +set(TBB_SEARCH_DIR ${TBB_ROOT_DIR} $ENV{TBB_INSTALL_DIR} $ENV{TBBROOT}) + +# Define the search directories based on the current platform +if(CMAKE_SYSTEM_NAME STREQUAL "Windows") + set(TBB_DEFAULT_SEARCH_DIR + "C:/Program Files/Intel/TBB" + "C:/Program Files (x86)/Intel/TBB" + ) + + # Set the target architecture + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(TBB_ARCHITECTURE "intel64") + else() + set(TBB_ARCHITECTURE "ia32") + endif() + + # Set the TBB search library path search suffix based on the version of VC + if(WINDOWS_STORE) + set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc11_ui") + elseif(MSVC14) + set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc14") + elseif(MSVC12) + set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc12") + elseif(MSVC11) + set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc11") + elseif(MSVC10) + set(TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc10") + endif() + + # Add the library path search suffix for the VC independent version of TBB + list(APPEND TBB_LIB_PATH_SUFFIX "lib/${TBB_ARCHITECTURE}/vc_mt") +elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + # OS X + set(TBB_DEFAULT_SEARCH_DIR "/opt/intel/tbb") + + # TODO: Check to see which C++ library is being used by the compiler. + if(NOT ${CMAKE_SYSTEM_VERSION} VERSION_LESS 13.0) + # The default C++ library on OS X 10.9 and later is libc++ + set(TBB_LIB_PATH_SUFFIX "lib/libc++" "lib") + else() + set(TBB_LIB_PATH_SUFFIX "lib") + endif() +elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") + # Linux + set(TBB_DEFAULT_SEARCH_DIR "/opt/intel/tbb") + + # TODO: Check compiler version to see the suffix should be /gcc4.1 or + # /gcc4.1. For now, assume that the compiler is more recent than gcc 4.4.x or + # later. + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") + set(TBB_LIB_PATH_SUFFIX "lib/intel64/gcc4.4") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^i.86$") + set(TBB_LIB_PATH_SUFFIX "lib/ia32/gcc4.4") + endif() +endif() + +# +# Find the TBB include dir +# +find_path( + TBB_INCLUDE_DIRS + tbb/tbb.h + HINTS ${TBB_INCLUDE_DIRS} ${TBB_SEARCH_DIR} + PATHS ${TBB_DEFAULT_SEARCH_DIR} + PATH_SUFFIXES include +) + +# +# Set version strings +# +if(TBB_INCLUDE_DIRS) + # Starting in 2020.1.1, tbb_stddef.h is replaced by version.h + set(_version_files + "${TBB_INCLUDE_DIRS}/tbb/tbb_stddef.h" + "${TBB_INCLUDE_DIRS}/tbb/version.h" + ) + foreach(f IN ITEMS ${_version_files}) + if(EXISTS ${f}) + set(_version_file ${f}) + endif() + endforeach() + unset(_version_files) + + file(READ ${_version_file} _tbb_version_file) + string( + REGEX REPLACE + ".*#define TBB_VERSION_MAJOR ([0-9]+).*" + "\\1" + TBB_VERSION_MAJOR + "${_tbb_version_file}" + ) + string( + REGEX REPLACE + ".*#define TBB_VERSION_MINOR ([0-9]+).*" + "\\1" + TBB_VERSION_MINOR + "${_tbb_version_file}" + ) + string( + REGEX REPLACE + ".*#define TBB_INTERFACE_VERSION ([0-9]+).*" + "\\1" + TBB_INTERFACE_VERSION + "${_tbb_version_file}" + ) + + # The TBB_VERSION_MINOR isn't necessarily changed for minor releases Hence, we need to + # read the engineering versioning in TBB_INTERFACE_VERSION to get the minor version + # correct + if("${TBB_VERSION_MINOR}" STREQUAL "0") + math(EXPR _tbb_iface_major_ver "${TBB_INTERFACE_VERSION} / 100") + math( + EXPR + TBB_VERSION_MINOR + "${TBB_INTERFACE_VERSION} - ${_tbb_iface_major_ver} * 100" + ) + endif() + set(TBB_VERSION "${TBB_VERSION_MAJOR}.${TBB_VERSION_MINOR}") +endif() + +# +# Find TBB components +# +if(TBB_VERSION VERSION_LESS 4.3) + set(TBB_SEARCH_COMPOMPONENTS tbb_preview tbbmalloc tbb) +else() + set(TBB_SEARCH_COMPOMPONENTS tbb_preview tbbmalloc_proxy tbbmalloc tbb) +endif() + +set(TBB_LIBRARY_DIRS) + +# Find each component +foreach(_comp ${TBB_SEARCH_COMPOMPONENTS}) + # message(STATUS "Searching for ${_comp}...") message(STATUS "Hints: ${TBB_LIBRARY} + # ${TBB_SEARCH_DIR}") + if(";${TBB_FIND_COMPONENTS};tbb;" MATCHES ";${_comp};") + # Search for the libraries + find_library( + TBB_${_comp}_LIBRARY_RELEASE + ${_comp} + HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR} + PATHS ${TBB_DEFAULT_SEARCH_DIR} + ENV LIBRARY_PATH + PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX} lib_release + ) + + find_library( + TBB_${_comp}_LIBRARY_DEBUG + ${_comp}_debug + HINTS ${TBB_LIBRARY} ${TBB_SEARCH_DIR} + PATHS ${TBB_DEFAULT_SEARCH_DIR} + ENV LIBRARY_PATH + PATH_SUFFIXES ${TBB_LIB_PATH_SUFFIX} lib_debug + ) + + if(TBB_${_comp}_LIBRARY_DEBUG) + list(APPEND TBB_LIBRARIES_DEBUG "${TBB_${_comp}_LIBRARY_DEBUG}") + # message(STATUS "Found ${TBB_${_comp}_LIBRARY_DEBUG}") + endif() + if(TBB_${_comp}_LIBRARY_RELEASE) + list(APPEND TBB_LIBRARIES_RELEASE "${TBB_${_comp}_LIBRARY_RELEASE}") + # message(STATUS "Found ${TBB_${_comp}_LIBRARY_RELEASE}") + endif() + if(TBB_${_comp}_LIBRARY_${TBB_BUILD_TYPE} AND NOT TBB_${_comp}_LIBRARY) + set(TBB_${_comp}_LIBRARY "${TBB_${_comp}_LIBRARY_${TBB_BUILD_TYPE}}") + endif() + + if(TBB_${_comp}_LIBRARY AND EXISTS "${TBB_${_comp}_LIBRARY}") + set(TBB_${_comp}_FOUND TRUE) + else() + set(TBB_${_comp}_FOUND FALSE) + endif() + + # Mark internal variables as advanced + mark_as_advanced(TBB_${_comp}_LIBRARY_RELEASE) + mark_as_advanced(TBB_${_comp}_LIBRARY_DEBUG) + mark_as_advanced(TBB_${_comp}_LIBRARY) + + # Save the directory names for each library component + if(TBB_USE_DEBUG_BUILD) + get_filename_component(_dir ${TBB_${_comp}_LIBRARY_DEBUG} DIRECTORY) + else() + get_filename_component(_dir ${TBB_${_comp}_LIBRARY_RELEASE} DIRECTORY) + endif() + list(APPEND TBB_LIBRARY_DIRS ${_dir}) + endif() +endforeach() + +# +# Set compile flags and libraries +# +set(TBB_DEFINITIONS_RELEASE "") +set(TBB_DEFINITIONS_DEBUG "-DTBB_USE_DEBUG=1") + +if(TBB_LIBRARIES_${TBB_BUILD_TYPE}) + set(TBB_DEFINITIONS "${TBB_DEFINITIONS_${TBB_BUILD_TYPE}}") + set(TBB_LIBRARIES "${TBB_LIBRARIES_${TBB_BUILD_TYPE}}") +elseif(TBB_LIBRARIES_RELEASE) + set(TBB_DEFINITIONS "${TBB_DEFINITIONS_RELEASE}") + set(TBB_LIBRARIES "${TBB_LIBRARIES_RELEASE}") +elseif(TBB_LIBRARIES_DEBUG) + set(TBB_DEFINITIONS "${TBB_DEFINITIONS_DEBUG}") + set(TBB_LIBRARIES "${TBB_LIBRARIES_DEBUG}") +endif() + +find_package_handle_standard_args( + TBB + REQUIRED_VARS TBB_INCLUDE_DIRS TBB_LIBRARIES + HANDLE_COMPONENTS + VERSION_VAR TBB_VERSION +) + +mark_as_advanced(TBB_INCLUDE_DIRS TBB_LIBRARIES TBB_LIBRARY_DIRS) + +unset(TBB_ARCHITECTURE) +unset(TBB_BUILD_TYPE) +unset(TBB_LIB_PATH_SUFFIX) +unset(TBB_DEFAULT_SEARCH_DIR) diff --git a/projects/rocprofiler-systems/cmake/Modules/Findamd-smi.cmake b/projects/rocprofiler-systems/cmake/Modules/Findamd-smi.cmake new file mode 100644 index 0000000000..46965ab4dd --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Modules/Findamd-smi.cmake @@ -0,0 +1,86 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying file +# Copyright.txt or https://cmake.org/licensing for details. + +include(FindPackageHandleStandardArgs) + +# ----------------------------------------------------------------------------------------# + +if(NOT ROCM_PATH AND NOT "$ENV{ROCM_PATH}" STREQUAL "") + set(ROCM_PATH "$ENV{ROCM_PATH}") +endif() + +foreach(_DIR ${ROCmVersion_DIR} ${ROCM_PATH} /opt/rocm /opt/rocm/amd_smi) + if(EXISTS ${_DIR}) + get_filename_component(_ABS_DIR "${_DIR}" REALPATH) + list(APPEND _AMD_SMI_PATHS ${_ABS_DIR}) + endif() +endforeach() + +# ----------------------------------------------------------------------------------------# + +find_path( + amd-smi_ROOT_DIR + NAMES include/amd_smi/amdsmi.h + HINTS ${_AMD_SMI_PATHS} + PATHS ${_AMD_SMI_PATHS} + PATH_SUFFIXES amd_smi +) + +mark_as_advanced(amd-smi_ROOT_DIR) + +# ----------------------------------------------------------------------------------------# + +find_path( + amd-smi_INCLUDE_DIR + NAMES amd_smi/amdsmi.h + HINTS ${amd-smi_ROOT_DIR} ${_AMD_SMI_PATHS} + PATHS ${amd-smi_ROOT_DIR} ${_AMD_SMI_PATHS} + PATH_SUFFIXES include amd_smi/include +) + +mark_as_advanced(amd-smi_INCLUDE_DIR) + +# ----------------------------------------------------------------------------------------# + +find_library( + amd-smi_LIBRARY + NAMES amd_smi + HINTS ${amd-smi_ROOT_DIR} ${_AMD_SMI_PATHS} + PATHS ${amd-smi_ROOT_DIR} ${_AMD_SMI_PATHS} + PATH_SUFFIXES amd-smi/lib lib +) + +if(amd-smi_LIBRARY) + get_filename_component(amd-smi_LIBRARY_DIR "${amd-smi_LIBRARY}" PATH CACHE) +endif() + +mark_as_advanced(amd-smi_LIBRARY) + +# ----------------------------------------------------------------------------------------# + +find_package_handle_standard_args( + amd-smi + DEFAULT_MSG + amd-smi_ROOT_DIR + amd-smi_INCLUDE_DIR + amd-smi_LIBRARY +) + +# ------------------------------------------------------------------------------# + +if(amd-smi_FOUND) + add_library(amd-smi::amd-smi INTERFACE IMPORTED) + add_library(amd-smi::roctx INTERFACE IMPORTED) + set(amd-smi_INCLUDE_DIRS ${amd-smi_INCLUDE_DIR}) + set(amd-smi_LIBRARIES ${amd-smi_LIBRARY}) + set(amd-smi_LIBRARY_DIRS ${amd-smi_LIBRARY_DIR}) + + target_include_directories(amd-smi::amd-smi INTERFACE ${amd-smi_INCLUDE_DIR}) + target_link_libraries(amd-smi::amd-smi INTERFACE ${amd-smi_LIBRARY}) +endif() + +# ------------------------------------------------------------------------------# + +unset(_AMD_SMI_PATHS) + +# ------------------------------------------------------------------------------# diff --git a/projects/rocprofiler-systems/cmake/PAPI.cmake b/projects/rocprofiler-systems/cmake/PAPI.cmake new file mode 100644 index 0000000000..0c793efd71 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/PAPI.cmake @@ -0,0 +1,388 @@ +# ====================================================================================== +# PAPI.cmake +# +# Configure papi for rocprofiler-systems +# +# ====================================================================================== + +include_guard(GLOBAL) + +rocprofiler_systems_checkout_git_submodule( + RELATIVE_PATH external/papi + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + REPO_URL https://bitbucket.org/icl/papi.git + REPO_BRANCH effd1ef4e0fd4b80e36546791277215a2d6b9eba + TEST_FILE src/configure +) + +set(PAPI_LIBPFM_SOVERSION "4.11.1" CACHE STRING "libpfm.so version") + +set(ROCPROFSYS_PAPI_SOURCE_DIR ${PROJECT_BINARY_DIR}/external/papi/source) +set(ROCPROFSYS_PAPI_INSTALL_DIR ${PROJECT_BINARY_DIR}/external/papi/install) + +if(NOT EXISTS "${ROCPROFSYS_PAPI_SOURCE_DIR}") + execute_process( + COMMAND + ${CMAKE_COMMAND} -E copy_directory ${PROJECT_SOURCE_DIR}/external/papi + ${ROCPROFSYS_PAPI_SOURCE_DIR} + ) +endif() + +if(NOT EXISTS "${ROCPROFSYS_PAPI_INSTALL_DIR}") + execute_process( + COMMAND ${CMAKE_COMMAND} -E make_directory ${ROCPROFSYS_PAPI_INSTALL_DIR} + ) + execute_process( + COMMAND ${CMAKE_COMMAND} -E make_directory ${ROCPROFSYS_PAPI_INSTALL_DIR}/include + ) + execute_process( + COMMAND ${CMAKE_COMMAND} -E make_directory ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib + ) + execute_process( + COMMAND + ${CMAKE_COMMAND} -E touch ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/libpapi.a + ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/libpfm.a + ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/libpfm.so + ) + set(_ROCPROFSYS_PAPI_BUILD_BYPRODUCTS + ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/libpapi.a + ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/libpfm.a + ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/libpfm.so + ) +endif() + +# Set ROCPROFSYS_PAPI_CONFIGURE_JOBS for commands that need to be run nonparallel +set(ROCPROFSYS_PAPI_CONFIGURE_JOBS 1) + +rocprofiler_systems_add_option(ROCPROFSYS_PAPI_AUTO_COMPONENTS + "Automatically enable components" OFF +) + +# -------------- PACKAGES ----------------------------------------------------- + +set(_ROCPROFSYS_VALID_PAPI_COMPONENTS + appio + bgpm + coretemp + coretemp_freebsd + cuda + emon + example + host_micpower + infiniband + intel_gpu + io + libmsr + lmsensors + lustre + micpower + mx + net + nvml + pcp + perfctr + perfctr_ppc + perf_event + perf_event_uncore + perfmon2 + perfmon_ia64 + perfnec + powercap + powercap_ppc + rapl + rocm + rocm_smi + sde + sensors_ppc + stealtime + sysdetect + vmware +) +set(ROCPROFSYS_VALID_PAPI_COMPONENTS + "${_ROCPROFSYS_VALID_PAPI_COMPONENTS}" + CACHE STRING + "Valid PAPI components" +) +mark_as_advanced(ROCPROFSYS_VALID_PAPI_COMPONENTS) + +# default components which do not require 3rd-party headers or libraries +set(_ROCPROFSYS_PAPI_COMPONENTS + appio + coretemp + io + infiniband + # lustre micpower mx + net + perf_event + perf_event_uncore + # rapl stealtime +) + +if(ROCPROFSYS_PAPI_AUTO_COMPONENTS) + # lmsensors + find_path( + ROCPROFSYS_PAPI_LMSENSORS_ROOT_DIR + NAMES include/sensors/sensors.h include/sensors.h + ) + + if(ROCPROFSYS_PAPI_LMSENSORS_ROOT_DIR) + list(APPEND _ROCPROFSYS_PAPI_COMPONENTS lmsensors) + endif() + + # pcp + find_path(ROCPROFSYS_PAPI_PCP_ROOT_DIR NAMES include/pcp/impl.h) + find_library(ROCPROFSYS_PAPI_PCP_LIBRARY NAMES pcp PATH_SUFFIXES lib lib64) + + if(ROCPROFSYS_PAPI_PCP_ROOT_DIR AND ROCPROFSYS_PAPI_PCP_LIBRARY) + list(APPEND _ROCPROFSYS_PAPI_COMPONENTS pcp) + endif() +endif() + +# set the ROCPROFSYS_PAPI_COMPONENTS cache variable +set(ROCPROFSYS_PAPI_COMPONENTS + "${_ROCPROFSYS_PAPI_COMPONENTS}" + CACHE STRING + "PAPI components" +) +rocprofiler_systems_add_feature(ROCPROFSYS_PAPI_COMPONENTS "PAPI components") +string(REPLACE ";" "\ " _ROCPROFSYS_PAPI_COMPONENTS "${ROCPROFSYS_PAPI_COMPONENTS}") +set(ROCPROFSYS_PAPI_EXTRA_ENV) + +foreach(_COMP ${ROCPROFSYS_PAPI_COMPONENTS}) + string( + REPLACE + ";" + ", " + _ROCPROFSYS_VALID_PAPI_COMPONENTS_MSG + "${ROCPROFSYS_VALID_PAPI_COMPONENTS}" + ) + if(NOT "${_COMP}" IN_LIST ROCPROFSYS_VALID_PAPI_COMPONENTS) + rocprofiler_systems_message( + AUTHOR_WARNING + "ROCPROFSYS_PAPI_COMPONENTS contains an unknown component '${_COMP}'. Known components: ${_ROCPROFSYS_VALID_PAPI_COMPONENTS_MSG}" + ) + endif() + unset(_ROCPROFSYS_VALID_PAPI_COMPONENTS_MSG) +endforeach() + +if("rocm" IN_LIST ROCPROFSYS_PAPI_COMPONENTS) + find_package(ROCmVersion REQUIRED) + list(APPEND ROCPROFSYS_PAPI_EXTRA_ENV PAPI_ROCM_ROOT=${ROCmVersion_DIR}) +endif() + +if("lmsensors" IN_LIST ROCPROFSYS_PAPI_COMPONENTS AND ROCPROFSYS_PAPI_LMSENSORS_ROOT_DIR) + list( + APPEND + ROCPROFSYS_PAPI_EXTRA_ENV + PAPI_LMSENSORS_ROOT=${ROCPROFSYS_PAPI_LMSENSORS_ROOT_DIR} + ) +endif() + +if("pcp" IN_LIST ROCPROFSYS_PAPI_COMPONENTS AND ROCPROFSYS_PAPI_PCP_ROOT_DIR) + list(APPEND ROCPROFSYS_PAPI_EXTRA_ENV PAPI_PCP_ROOT=${ROCPROFSYS_PAPI_PCP_ROOT_DIR}) +endif() + +if( + "perf_event_uncore" IN_LIST ROCPROFSYS_PAPI_COMPONENTS + AND NOT "perf_event" IN_LIST ROCPROFSYS_PAPI_COMPONENTS +) + rocprofiler_systems_message( + FATAL_ERROR + "ROCPROFSYS_PAPI_COMPONENTS :: 'perf_event_uncore' requires 'perf_event' component" + ) +endif() + +find_program(MAKE_EXECUTABLE NAMES make gmake PATH_SUFFIXES bin) + +if(NOT MAKE_EXECUTABLE) + rocprofiler_systems_message( + FATAL_ERROR + "make/gmake executable not found. Please re-run with -DMAKE_EXECUTABLE=/path/to/make" + ) +endif() + +set(_PAPI_C_COMPILER ${CMAKE_C_COMPILER}) +if(CMAKE_C_COMPILER_IS_CLANG) + find_program(ROCPROFSYS_GNU_C_COMPILER NAMES gcc) + if(ROCPROFSYS_GNU_C_COMPILER) + set(_PAPI_C_COMPILER ${ROCPROFSYS_GNU_C_COMPILER}) + endif() +endif() +set(PAPI_C_COMPILER ${_PAPI_C_COMPILER} CACHE FILEPATH "C compiler used to compile PAPI") + +include(ExternalProject) +ExternalProject_Add( + rocprofiler-systems-papi-build + PREFIX ${PROJECT_BINARY_DIR}/external/papi + SOURCE_DIR ${ROCPROFSYS_PAPI_SOURCE_DIR}/src + BUILD_IN_SOURCE 1 + PATCH_COMMAND + ${CMAKE_COMMAND} -E env CC=${PAPI_C_COMPILER} + CFLAGS=-fPIC\ -O3\ -Wno-stringop-truncation\ -Wno-use-after-free LIBS=-lrt + LDFLAGS=-lrt ${ROCPROFSYS_PAPI_EXTRA_ENV} /configure --quiet + --prefix=${ROCPROFSYS_PAPI_INSTALL_DIR} --with-static-lib=yes --with-shared-lib=no + --with-perf-events --with-tests=no + --with-components=${_ROCPROFSYS_PAPI_COMPONENTS} + --libdir=${ROCPROFSYS_PAPI_INSTALL_DIR}/lib + CONFIGURE_COMMAND + ${CMAKE_COMMAND} -E env + CFLAGS=-fPIC\ -O3\ -Wno-stringop-truncation\ -Wno-use-after-free + ${ROCPROFSYS_PAPI_EXTRA_ENV} ${MAKE_EXECUTABLE} static install -s -j + ${ROCPROFSYS_PAPI_CONFIGURE_JOBS} + BUILD_COMMAND + ${CMAKE_COMMAND} -E env + CFLAGS=-fPIC\ -O3\ -Wno-stringop-truncation\ -Wno-use-after-free + ${ROCPROFSYS_PAPI_EXTRA_ENV} ${MAKE_EXECUTABLE} utils install-utils -s + INSTALL_COMMAND "" + BUILD_BYPRODUCTS "${_ROCPROFSYS_PAPI_BUILD_BYPRODUCTS}" +) + +# target for re-executing the installation +add_custom_target( + rocprofiler-systems-papi-install + COMMAND + ${CMAKE_COMMAND} -E env + CFLAGS=-fPIC\ -O3\ -Wno-stringop-truncation\ -Wno-use-after-free + ${ROCPROFSYS_PAPI_EXTRA_ENV} ${MAKE_EXECUTABLE} static install -s + COMMAND + ${CMAKE_COMMAND} -E env + CFLAGS=-fPIC\ -O3\ -Wno-stringop-truncation\ -Wno-use-after-free + ${ROCPROFSYS_PAPI_EXTRA_ENV} ${MAKE_EXECUTABLE} utils install-utils -s + WORKING_DIRECTORY ${ROCPROFSYS_PAPI_SOURCE_DIR}/src + COMMENT "Installing PAPI..." +) + +add_custom_target( + rocprofiler-systems-papi-clean + COMMAND ${MAKE_EXECUTABLE} distclean + COMMAND ${CMAKE_COMMAND} -E rm -rf ${ROCPROFSYS_PAPI_INSTALL_DIR}/include/* + COMMAND ${CMAKE_COMMAND} -E rm -rf ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/* + COMMAND + ${CMAKE_COMMAND} -E touch ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/libpapi.a + ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/libpfm.a + ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/libpfm.so + WORKING_DIRECTORY ${ROCPROFSYS_PAPI_SOURCE_DIR}/src + COMMENT "Cleaning PAPI..." +) + +set(PAPI_ROOT_DIR + ${ROCPROFSYS_PAPI_INSTALL_DIR} + CACHE PATH + "Root PAPI installation" + FORCE +) +set(PAPI_INCLUDE_DIR + ${ROCPROFSYS_PAPI_INSTALL_DIR}/include + CACHE PATH + "PAPI include folder" + FORCE +) +set(PAPI_LIBRARY + ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/libpapi.a + CACHE FILEPATH + "PAPI library" + FORCE +) +set(PAPI_pfm_LIBRARY + ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/libpfm.so + CACHE FILEPATH + "PAPI library" + FORCE +) +set(PAPI_STATIC_LIBRARY + ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/libpapi.a + CACHE FILEPATH + "PAPI library" + FORCE +) +set(PAPI_pfm_STATIC_LIBRARY + ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/libpfm.a + CACHE FILEPATH + "PAPI library" + FORCE +) + +target_include_directories( + rocprofiler-systems-papi + SYSTEM + INTERFACE $ +) +target_link_libraries( + rocprofiler-systems-papi + INTERFACE $ $ +) +rocprofiler_systems_target_compile_definitions( + rocprofiler-systems-papi INTERFACE ROCPROFSYS_USE_PAPI + $ +) + +install( + DIRECTORY ${ROCPROFSYS_PAPI_INSTALL_DIR}/lib/ + DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME} + COMPONENT papi + FILES_MATCHING + PATTERN "*.so*" +) + +foreach( + _UTIL_EXE + papi_avail + papi_clockres + papi_command_line + papi_component_avail + papi_cost + papi_decode + papi_error_codes + papi_event_chooser + papi_hardware_avail + papi_hl_output_writer.py + papi_mem_info + papi_multiplex_cost + papi_native_avail + papi_version + papi_xml_event_info +) + string(REPLACE "_" "-" _UTIL_EXE_INSTALL_NAME "${BINARY_NAME_PREFIX}-${_UTIL_EXE}") + + # RPM installer on RedHat/RockyLinux throws error that #!/usr/bin/python should either + # be #!/usr/bin/python2 or #!/usr/bin/python3 + if(_UTIL_EXE STREQUAL "papi_hl_output_writer.py") + file( + READ + "${PROJECT_BINARY_DIR}/external/papi/source/src/high-level/scripts/${_UTIL_EXE}" + _HL_OUTPUT_WRITER + ) + string( + REPLACE + "#!/usr/bin/python\n" + "#!/usr/bin/python3\n" + _HL_OUTPUT_WRITER + "${_HL_OUTPUT_WRITER}" + ) + file(MAKE_DIRECTORY "${ROCPROFSYS_PAPI_INSTALL_DIR}/bin") + file( + WRITE + "${ROCPROFSYS_PAPI_INSTALL_DIR}/bin/${_UTIL_EXE}3" + "${_HL_OUTPUT_WRITER}" + ) + set(_UTIL_EXE "${_UTIL_EXE}3") + + # python script file install to libexec + install( + PROGRAMS ${ROCPROFSYS_PAPI_INSTALL_DIR}/bin/${_UTIL_EXE} + DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}/${PROJECT_NAME} + RENAME ${_UTIL_EXE_INSTALL_NAME} + COMPONENT papi + OPTIONAL + ) + else() + # Binary files moved to bin + install( + PROGRAMS ${ROCPROFSYS_PAPI_INSTALL_DIR}/bin/${_UTIL_EXE} + DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME} + RENAME ${_UTIL_EXE_INSTALL_NAME} + COMPONENT papi + OPTIONAL + ) + endif() +endforeach() diff --git a/projects/rocprofiler-systems/cmake/Packages.cmake b/projects/rocprofiler-systems/cmake/Packages.cmake new file mode 100644 index 0000000000..f24c2c653a --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Packages.cmake @@ -0,0 +1,1035 @@ +# include guard +include_guard(DIRECTORY) + +# ######################################################################################## +# +# External Packages are found here +# +# ######################################################################################## + +rocprofiler_systems_add_interface_library( + rocprofiler-systems-headers + "Provides minimal set of include flags to compile with rocprofiler-systems" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-threading + "Enables multithreading support" +) +rocprofiler_systems_add_interface_library( + rocprofiler-systems-dyninst + "Provides flags and libraries for Dyninst (dynamic instrumentation)" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-boost + "Boost interface library (for Dyninst)" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-elfutils + "ElfUtils interface library (for Dyninst)" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-libiberty + "LibIberty interface library (for Dyninst)" +) +rocprofiler_systems_add_interface_library( + rocprofiler-systems-tbb "Threading Building Blocks interface library (for Dyninst)" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-rocm + "Provides flags and libraries for ROCm" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-mpi + "Provides MPI or MPI headers" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-libva + "Provides VA-API headers" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-bfd + "Provides Binary File Descriptor (BFD)" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-ptl + "Enables PTL support (tasking)" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-papi "Enable PAPI support") +rocprofiler_systems_add_interface_library(rocprofiler-systems-ompt "Enable OMPT support") +rocprofiler_systems_add_interface_library(rocprofiler-systems-python + "Enables Python support" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-perfetto + "Enables Perfetto support" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-timemory + "Provides timemory libraries" +) +rocprofiler_systems_add_interface_library( + rocprofiler-systems-timemory-config + "CMake interface library applied to all timemory targets" +) +rocprofiler_systems_add_interface_library(rocprofiler-systems-compile-definitions + "Compile definitions" +) + +# libraries with relevant compile definitions +set(ROCPROFSYS_EXTENSION_LIBRARIES + rocprofiler-systems::rocprofiler-systems-rocm + rocprofiler-systems::rocprofiler-systems-bfd + rocprofiler-systems::rocprofiler-systems-mpi + rocprofiler-systems::rocprofiler-systems-ptl + rocprofiler-systems::rocprofiler-systems-ompt + rocprofiler-systems::rocprofiler-systems-papi + rocprofiler-systems::rocprofiler-systems-perfetto +) + +target_include_directories( + rocprofiler-systems-headers + INTERFACE + $ + $ + $ + $ + $ + $ +) + +# include threading because of rooflines +target_link_libraries( + rocprofiler-systems-headers + INTERFACE rocprofiler-systems::rocprofiler-systems-threading +) + +# ensure the env overrides the appending /opt/rocm later +string(REPLACE ":" ";" CMAKE_PREFIX_PATH "$ENV{CMAKE_PREFIX_PATH};${CMAKE_PREFIX_PATH}") + +set(ROCPROFSYS_DEFAULT_ROCM_PATH /opt/rocm CACHE PATH "Default search path for ROCM") +if(EXISTS ${ROCPROFSYS_DEFAULT_ROCM_PATH}) + get_filename_component( + _ROCPROFSYS_DEFAULT_ROCM_PATH + "${ROCPROFSYS_DEFAULT_ROCM_PATH}" + REALPATH + ) + + if(NOT "${_ROCPROFSYS_DEFAULT_ROCM_PATH}" STREQUAL "${ROCPROFSYS_DEFAULT_ROCM_PATH}") + set(ROCPROFSYS_DEFAULT_ROCM_PATH + "${_ROCPROFSYS_DEFAULT_ROCM_PATH}" + CACHE PATH + "Default search path for ROCM" + FORCE + ) + endif() +endif() + +# ----------------------------------------------------------------------------------------# +# +# Threading +# +# ----------------------------------------------------------------------------------------# + +set(CMAKE_THREAD_PREFER_PTHREAD ON) +set(THREADS_PREFER_PTHREAD_FLAG OFF) + +find_library(pthread_LIBRARY NAMES pthread pthreads) +find_package_handle_standard_args(pthread-library REQUIRED_VARS pthread_LIBRARY) + +find_library(pthread_LIBRARY NAMES pthread pthreads) +find_package_handle_standard_args(pthread-library REQUIRED_VARS pthread_LIBRARY) + +if(pthread_LIBRARY) + target_link_libraries(rocprofiler-systems-threading INTERFACE ${pthread_LIBRARY}) +else() + find_package( + Threads + ${rocprofiler_systems_FIND_QUIETLY} + ${rocprofiler_systems_FIND_REQUIREMENT} + ) + if(Threads_FOUND) + target_link_libraries(rocprofiler-systems-threading INTERFACE Threads::Threads) + endif() +endif() + +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-systems-threading INTERFACE ${${_LIB}_LIBRARY}) + endif() +endforeach() + +# ----------------------------------------------------------------------------------------# +# +# ROCm Version +# +# ----------------------------------------------------------------------------------------# + +if(ROCPROFSYS_USE_ROCM) + find_package(ROCmVersion) + + if(NOT ROCmVersion_FOUND) + find_package( + hip + ${rocprofiler_systems_FIND_QUIETLY} + REQUIRED + HINTS ${ROCPROFSYS_DEFAULT_ROCM_PATH} + PATHS ${ROCPROFSYS_DEFAULT_ROCM_PATH} + ) + if(SPACK_BUILD) + find_package(ROCmVersion HINTS ${ROCM_PATH} PATHS ${ROCM_PATH}) + else() + find_package(ROCmVersion REQUIRED HINTS ${ROCM_PATH} PATHS ${ROCM_PATH}) + endif() + endif() + + if(NOT ROCmVersion_FOUND) + rocm_version_compute("${hip_VERSION}" _local) + + foreach(_V ${ROCmVersion_VARIABLES}) + set(_CACHE_VAR ROCmVersion_${_V}_VERSION) + set(_LOCAL_VAR _local_${_V}_VERSION) + set(ROCmVersion_${_V}_VERSION + "${${_LOCAL_VAR}}" + CACHE STRING + "ROCm ${_V} version" + ) + rocm_version_watch_for_change(${_CACHE_VAR}) + endforeach() + else() + list(APPEND CMAKE_PREFIX_PATH ${ROCmVersion_DIR}) + endif() + + set(ROCPROFSYS_ROCM_VERSION ${ROCmVersion_FULL_VERSION}) + set(ROCPROFSYS_ROCM_VERSION_MAJOR ${ROCmVersion_MAJOR_VERSION}) + set(ROCPROFSYS_ROCM_VERSION_MINOR ${ROCmVersion_MINOR_VERSION}) + set(ROCPROFSYS_ROCM_VERSION_PATCH ${ROCmVersion_PATCH_VERSION}) + set(ROCPROFSYS_ROCM_VERSION ${ROCmVersion_TRIPLE_VERSION}) + + rocprofiler_systems_add_feature(ROCPROFSYS_ROCM_VERSION + "ROCm version used by rocprofiler-systems" + ) +else() + set(ROCPROFSYS_ROCM_VERSION "0.0.0") + set(ROCPROFSYS_ROCM_VERSION_MAJOR 0) + set(ROCPROFSYS_ROCM_VERSION_MINOR 0) + set(ROCPROFSYS_ROCM_VERSION_PATCH 0) +endif() + +# ----------------------------------------------------------------------------------------# +# +# ROCm +# +# ----------------------------------------------------------------------------------------# + +if(ROCPROFSYS_USE_ROCM) + find_package(rocprofiler-sdk ${rocprofiler_systems_FIND_QUIETLY} REQUIRED) + rocprofiler_systems_target_compile_definitions(rocprofiler-systems-rocm + INTERFACE ROCPROFSYS_USE_ROCM + ) + target_link_libraries( + rocprofiler-systems-rocm + INTERFACE rocprofiler-sdk::rocprofiler-sdk + ) + + find_package(amd-smi ${rocprofiler_systems_FIND_QUIETLY} REQUIRED) + target_link_libraries(rocprofiler-systems-rocm INTERFACE amd-smi::amd-smi) +endif() + +# ----------------------------------------------------------------------------------------# +# +# MPI +# +# ----------------------------------------------------------------------------------------# + +# suppress warning during CI that MPI_HEADERS_ALLOW_MPICH was unused +set(_ROCPROFSYS_MPI_HEADERS_ALLOW_MPICH ${MPI_HEADERS_ALLOW_MPICH}) + +if(ROCPROFSYS_USE_MPI) + find_package(MPI ${rocprofiler_systems_FIND_QUIETLY} REQUIRED) + target_link_libraries(rocprofiler-systems-mpi INTERFACE MPI::MPI_C MPI::MPI_CXX) + rocprofiler_systems_target_compile_definitions(rocprofiler-systems-mpi + INTERFACE ROCPROFSYS_USE_MPI + ) +elseif(ROCPROFSYS_USE_MPI_HEADERS) + find_package(MPI-Headers ${rocprofiler_systems_FIND_QUIETLY} REQUIRED) + rocprofiler_systems_target_compile_definitions(rocprofiler-systems-mpi + INTERFACE ROCPROFSYS_USE_MPI_HEADERS + ) + target_link_libraries(rocprofiler-systems-mpi INTERFACE MPI::MPI_HEADERS) +endif() + +# ----------------------------------------------------------------------------------------# +# +# OMPT +# +# ----------------------------------------------------------------------------------------# + +rocprofiler_systems_target_compile_definitions( + rocprofiler-systems-ompt INTERFACE ROCPROFSYS_USE_OMPT=$ +) + +# ----------------------------------------------------------------------------------------# +# +# Dyninst +# +# ----------------------------------------------------------------------------------------# +include(DyninstExternals) +if(ROCPROFSYS_BUILD_DYNINST) + rocprofiler_systems_checkout_git_submodule( + RELATIVE_PATH external/dyninst + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + REPO_URL https://github.com/ROCm/dyninst.git + REPO_BRANCH dyninst_13 + ) + + set(DYNINST_OPTION_PREFIX ON) + set(DYNINST_BUILD_DOCS OFF) + set(DYNINST_BUILD_RTLIB OFF) + set(DYNINST_QUIET_CONFIG ON CACHE BOOL "Suppress dyninst cmake messages") + set(DYNINST_BUILD_PARSE_THAT OFF CACHE BOOL "Build dyninst parseThat executable") + set(DYNINST_BUILD_SHARED_LIBS ON CACHE BOOL "Build shared dyninst libraries") + set(DYNINST_BUILD_STATIC_LIBS OFF CACHE BOOL "Build static dyninst libraries") + set(DYNINST_ENABLE_LTO OFF CACHE BOOL "Enable LTO for dyninst libraries") + + if(NOT DEFINED CMAKE_INSTALL_RPATH) + set(CMAKE_INSTALL_RPATH "") + endif() + + if(NOT DEFINED CMAKE_BUILD_RPATH) + set(CMAKE_BUILD_RPATH "") + endif() + + rocprofiler_systems_save_variables( + PIC VARIABLES CMAKE_POSITION_INDEPENDENT_CODE CMAKE_INSTALL_RPATH + CMAKE_BUILD_RPATH CMAKE_INSTALL_RPATH_USE_LINK_PATH + ) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH OFF) + + set(CMAKE_BUILD_RPATH "\$ORIGIN:\$ORIGIN/${PROJECT_NAME}") + set(CMAKE_INSTALL_RPATH "\$ORIGIN:\$ORIGIN/${PROJECT_NAME}") + set(DYNINST_TPL_INSTALL_PREFIX + "${PROJECT_NAME}" + CACHE PATH + "Third-party library install-tree install prefix" + FORCE + ) + set(DYNINST_TPL_INSTALL_LIB_DIR + "${PROJECT_NAME}" + CACHE PATH + "Third-party library install-tree install library prefix" + FORCE + ) + + add_subdirectory(external/dyninst EXCLUDE_FROM_ALL) + rocprofiler_systems_restore_variables( + PIC VARIABLES CMAKE_POSITION_INDEPENDENT_CODE CMAKE_INSTALL_RPATH + CMAKE_BUILD_RPATH CMAKE_INSTALL_RPATH_USE_LINK_PATH + ) + + add_library(Dyninst::Dyninst INTERFACE IMPORTED) + foreach( + _LIB + common + dyninstAPI + parseAPI + instructionAPI + symtabAPI + stackwalk + ) + target_link_libraries(Dyninst::Dyninst INTERFACE Dyninst::${_LIB}) + endforeach() + + foreach( + _LIB + common + dynDwarf + dynElf + dyninstAPI + instructionAPI + parseAPI + patchAPI + pcontrol + stackwalk + symtabAPI + ) + if(TARGET ${_LIB}) + install( + TARGETS ${_LIB} + DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME} + COMPONENT dyninst + PUBLIC_HEADER + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/dyninst + ) + endif() + endforeach() + + foreach( + _LIB + common + dynDwarf + dynElf + dyninstAPI + instructionAPI + parseAPI + patchAPI + pcontrol + stackwalk + symtabAPI + ) + if(TARGET ${_LIB}) + add_dependencies(${_LIB} external-prebuild) + if(NOT TARGET Dyninst::${_LIB}) + add_library(Dyninst::${_LIB} ALIAS ${_LIB}) + endif() + endif() + endforeach() + + target_link_libraries(rocprofiler-systems-dyninst INTERFACE Dyninst::Dyninst) +else() + # Find Boost before finding Dyninst + find_package(Boost) + if(NOT TARGET Dyninst::Boost_headers) + add_library(Dyninst::Boost_headers INTERFACE IMPORTED) + target_include_directories( + Dyninst::Boost_headers + SYSTEM + INTERFACE ${Boost_INCLUDE_DIRS} + ) + endif() + + find_package( + Dyninst + ${rocprofiler_systems_FIND_QUIETLY} + REQUIRED + COMPONENTS dyninstAPI parseAPI instructionAPI symtabAPI + ) + + if(TARGET Dyninst::Dyninst) # updated Dyninst CMake system was found + target_link_libraries(rocprofiler-systems-dyninst INTERFACE Dyninst::Dyninst) + else() # updated Dyninst CMake system was not found + set(_BOOST_COMPONENTS atomic system thread date_time) + set(rocprofiler_systems_BOOST_COMPONENTS + "${_BOOST_COMPONENTS}" + CACHE STRING + "Boost components used by Dyninst in rocprofiler-systems" + ) + set(Boost_NO_BOOST_CMAKE ON) + find_package( + Boost + QUIET + REQUIRED + COMPONENTS ${rocprofiler_systems_BOOST_COMPONENTS} + ) + + # some installs of dyninst don't set this properly + if(EXISTS "${DYNINST_INCLUDE_DIR}" AND NOT DYNINST_HEADER_DIR) + get_filename_component( + DYNINST_HEADER_DIR + "${DYNINST_INCLUDE_DIR}" + REALPATH + CACHE + ) + else() + find_path( + DYNINST_HEADER_DIR + NAMES BPatch.h dyninstAPI_RT.h + HINTS ${Dyninst_ROOT_DIR} ${Dyninst_DIR} ${Dyninst_DIR}/../../.. + PATHS ${Dyninst_ROOT_DIR} ${Dyninst_DIR} ${Dyninst_DIR}/../../.. + PATH_SUFFIXES include + ) + endif() + + # try to find TBB + find_package(TBB QUIET) + + # if fail try to use the Dyninst installed FindTBB.cmake + if(NOT TBB_FOUND) + list(APPEND CMAKE_MODULE_PATH ${Dyninst_DIR}/Modules) + find_package(TBB QUIET) + endif() + + if(NOT TBB_FOUND) + find_path(TBB_INCLUDE_DIR NAMES tbb/tbb.h PATH_SUFFIXES include) + endif() + + target_link_libraries( + rocprofiler-systems-dyninst + INTERFACE ${DYNINST_LIBRARIES} ${Boost_LIBRARIES} + ) + foreach( + _TARG + dyninst + dyninstAPI + instructionAPI + symtabAPI + parseAPI + headers + atomic + system + thread + date_time + TBB + ) + if(TARGET Dyninst::${_TARG}) + target_link_libraries( + rocprofiler-systems-dyninst + INTERFACE Dyninst::${_TARG} + ) + elseif(TARGET Boost::${_TARG}) + target_link_libraries( + rocprofiler-systems-dyninst + INTERFACE Boost::${_TARG} + ) + elseif(TARGET ${_TARG}) + target_link_libraries(rocprofiler-systems-dyninst INTERFACE ${_TARG}) + endif() + endforeach() + target_include_directories( + rocprofiler-systems-dyninst + SYSTEM + INTERFACE ${TBB_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${DYNINST_HEADER_DIR} + ) + rocprofiler_systems_target_compile_definitions(rocprofiler-systems-dyninst + INTERFACE ROCPROFSYS_USE_DYNINST + ) + endif() +endif() + +# ----------------------------------------------------------------------------------------# +# +# Modify CMAKE_C_FLAGS and CMAKE_CXX_FLAGS with -static-libgcc and -static-libstdc++ +# +# ----------------------------------------------------------------------------------------# + +if(ROCPROFSYS_BUILD_STATIC_LIBGCC) + if(CMAKE_C_COMPILER_ID MATCHES "GNU") + rocprofiler_systems_save_variables(STATIC_LIBGCC_C VARIABLES CMAKE_C_FLAGS) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc") + endif() + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + rocprofiler_systems_save_variables(STATIC_LIBGCC_CXX VARIABLES CMAKE_CXX_FLAGS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc") + else() + set(ROCPROFSYS_BUILD_STATIC_LIBGCC OFF) + endif() +endif() + +if(ROCPROFSYS_BUILD_STATIC_LIBSTDCXX) + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + rocprofiler_systems_save_variables(STATIC_LIBSTDCXX_CXX VARIABLES CMAKE_CXX_FLAGS) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++") + else() + set(ROCPROFSYS_BUILD_STATIC_LIBSTDCXX OFF) + endif() +endif() + +# ----------------------------------------------------------------------------------------# +# +# Perfetto +# +# ----------------------------------------------------------------------------------------# + +set(perfetto_DIR ${PROJECT_SOURCE_DIR}/external/perfetto) +rocprofiler_systems_checkout_git_submodule( + RELATIVE_PATH external/perfetto + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + REPO_URL https://github.com/google/perfetto.git + REPO_BRANCH v46.0 + TEST_FILE sdk/perfetto.cc +) + +include(Perfetto) + +# ----------------------------------------------------------------------------------------# +# +# ELFIO +# +# ----------------------------------------------------------------------------------------# + +if(ROCPROFSYS_BUILD_DEVICETRACE) + rocprofiler_systems_checkout_git_submodule( + RELATIVE_PATH external/elfio + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + REPO_URL https://github.com/jrmadsen/ELFIO.git + REPO_BRANCH set-offset-support + ) + + add_subdirectory(external/elfio) +endif() + +# ----------------------------------------------------------------------------------------# +# +# papi submodule +# +# ----------------------------------------------------------------------------------------# + +if(ROCPROFSYS_USE_PAPI AND ROCPROFSYS_BUILD_PAPI) + include(PAPI) +endif() + +# ----------------------------------------------------------------------------------------# +# +# timemory submodule +# +# ----------------------------------------------------------------------------------------# + +target_compile_definitions( + rocprofiler-systems-timemory-config + INTERFACE + TIMEMORY_PAPI_ARRAY_SIZE=12 + TIMEMORY_USE_ROOFLINE=0 + TIMEMORY_USE_ERT=0 + TIMEMORY_USE_CONTAINERS=0 + TIMEMORY_USE_ERT_EXTERN=0 + TIMEMORY_USE_CONTAINERS_EXTERN=0 +) + +if(ROCPROFSYS_BUILD_STACK_PROTECTOR) + add_target_flag_if_avail(rocprofiler-systems-timemory-config + "-fstack-protector-strong" "-Wstack-protector" + ) +endif() + +if(ROCPROFSYS_BUILD_DEBUG) + add_target_flag_if_avail(rocprofiler-systems-timemory-config + "-fno-omit-frame-pointer" "-g3" + ) +endif() + +set(TIMEMORY_EXTERNAL_INTERFACE_LIBRARY + rocprofiler-systems-timemory-config + CACHE STRING + "timemory configuration interface library" +) +set(TIMEMORY_INSTALL_HEADERS OFF CACHE BOOL "Disable timemory header install") +set(TIMEMORY_INSTALL_CONFIG OFF CACHE BOOL "Disable timemory cmake configuration install") +set(TIMEMORY_INSTALL_LIBRARIES + OFF + CACHE BOOL + "Disable timemory installation of libraries not needed at runtime" +) +set(TIMEMORY_INSTALL_ALL OFF CACHE BOOL "Disable install target depending on all target") +set(TIMEMORY_BUILD_C OFF CACHE BOOL "Disable timemory C library") +set(TIMEMORY_BUILD_FORTRAN OFF CACHE BOOL "Disable timemory Fortran library") +set(TIMEMORY_BUILD_TOOLS OFF CACHE BOOL "Ensure timem executable is built") +set(TIMEMORY_BUILD_EXCLUDE_FROM_ALL + ON + CACHE BOOL + "Set timemory to only build dependencies" +) +set(TIMEMORY_BUILD_HIDDEN_VISIBILITY + ON + CACHE BOOL + "Build timemory with hidden visibility" +) +set(TIMEMORY_QUIET_CONFIG ON CACHE BOOL "Make timemory configuration quieter") + +# timemory feature settings +set(TIMEMORY_USE_GOTCHA ON CACHE BOOL "Enable GOTCHA support in timemory") +set(TIMEMORY_USE_PERFETTO OFF CACHE BOOL "Disable perfetto support in timemory") +set(TIMEMORY_USE_OMPT + ${ROCPROFSYS_USE_OMPT} + CACHE BOOL + "Enable OMPT support in timemory" + FORCE +) +set(TIMEMORY_USE_PAPI + ${ROCPROFSYS_USE_PAPI} + CACHE BOOL + "Enable PAPI support in timemory" + FORCE +) +set(TIMEMORY_USE_BFD + ${ROCPROFSYS_USE_BFD} + CACHE BOOL + "Enable BFD support in timemory" + FORCE +) +set(TIMEMORY_USE_LIBUNWIND ON CACHE BOOL "Enable libunwind support in timemory") +set(TIMEMORY_USE_VISIBILITY OFF CACHE BOOL "Enable/disable using visibility decorations") +set(TIMEMORY_USE_SANITIZER + ${ROCPROFSYS_USE_SANITIZER} + CACHE BOOL + "Build with -fsanitze=\${ROCPROFSYS_SANITIZER_TYPE}" + FORCE +) +set(TIMEMORY_SANITIZER_TYPE + ${ROCPROFSYS_SANITIZER_TYPE} + CACHE STRING + "Sanitizer type, e.g. leak, thread, address, memory, etc." + FORCE +) + +if(DEFINED TIMEMORY_BUILD_GOTCHA AND NOT TIMEMORY_BUILD_GOTCHA) + rocprofiler_systems_message( + FATAL_ERROR + "Using an external gotcha is not allowed due to known bug that has not been accepted upstream" + ) +endif() + +# timemory feature build settings +set(TIMEMORY_BUILD_GOTCHA + ON + CACHE BOOL + "Enable building GOTCHA library from submodule" + FORCE +) +set(TIMEMORY_BUILD_LIBUNWIND + ${ROCPROFSYS_BUILD_LIBUNWIND} + CACHE BOOL + "Enable building libunwind library from submodule" + FORCE +) +set(TIMEMORY_BUILD_EXTRA_OPTIMIZATIONS + ${ROCPROFSYS_BUILD_EXTRA_OPTIMIZATIONS} + CACHE BOOL + "Enable building GOTCHA library from submodule" + FORCE +) +set(TIMEMORY_BUILD_ERT OFF CACHE BOOL "Disable building ERT support" FORCE) +set(TIMEMORY_BUILD_CONTAINERS + OFF + CACHE BOOL + "Disable building container extern templates (unused)" + FORCE +) + +# timemory build settings +set(TIMEMORY_TLS_MODEL "global-dynamic" CACHE STRING "Thread-local static model" FORCE) +set(TIMEMORY_MAX_THREADS + "${ROCPROFSYS_MAX_THREADS}" + CACHE STRING + "Max statically-allocated threads" + FORCE +) +set(TIMEMORY_SETTINGS_PREFIX + "ROCPROFSYS_" + CACHE STRING + "Prefix used for settings and environment variables" +) +set(TIMEMORY_PROJECT_NAME "rocprofiler-systems" CACHE STRING "Name for configuration") +set(TIMEMORY_CXX_LIBRARY_EXCLUDE + "kokkosp.cpp;pthread.cpp;timemory_c.cpp;trace.cpp;weak.cpp;library.cpp" + CACHE STRING + "Timemory C++ library implementation files to exclude from compiling" +) + +mark_as_advanced(TIMEMORY_SETTINGS_PREFIX) +mark_as_advanced(TIMEMORY_PROJECT_NAME) + +rocprofiler_systems_checkout_git_submodule( + RELATIVE_PATH external/timemory + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + REPO_URL https://github.com/ROCm/timemory.git + REPO_BRANCH omnitrace +) + +rocprofiler_systems_save_variables( + BUILD_CONFIG VARIABLES BUILD_SHARED_LIBS BUILD_STATIC_LIBS + CMAKE_POSITION_INDEPENDENT_CODE CMAKE_PREFIX_PATH +) + +# ensure timemory builds PIC static libs so that we don't have to install timemory shared +# lib +set(BUILD_SHARED_LIBS OFF) +set(BUILD_STATIC_LIBS ON) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +set(TIMEMORY_CTP_OPTIONS GLOBAL) + +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + # results in undefined symbols to component::base::load() + set(TIMEMORY_BUILD_HIDDEN_VISIBILITY OFF CACHE BOOL "" FORCE) +endif() + +add_subdirectory(external/timemory EXCLUDE_FROM_ALL) + +install( + TARGETS gotcha + DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME} + COMPONENT gotcha +) +if(ROCPROFSYS_BUILD_LIBUNWIND) + install( + DIRECTORY ${PROJECT_BINARY_DIR}/external/timemory/external/libunwind/install/lib/ + DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME} + COMPONENT libunwind + FILES_MATCHING + PATTERN "*${CMAKE_SHARED_LIBRARY_SUFFIX}*" + ) +endif() + +rocprofiler_systems_restore_variables( + BUILD_CONFIG VARIABLES BUILD_SHARED_LIBS BUILD_STATIC_LIBS + CMAKE_POSITION_INDEPENDENT_CODE CMAKE_PREFIX_PATH +) + +if(TARGET rocprofiler-systems-papi-build) + foreach( + _TARGET + PAPI::papi + timemory-core + timemory-common + timemory-papi-component + timemory-cxx + ) + if(TARGET "${_TARGET}") + add_dependencies(${_TARGET} rocprofiler-systems-papi-build) + endif() + foreach(_LINK shared static) + if(TARGET "${_TARGET}-${_LINK}") + add_dependencies(${_TARGET}-${_LINK} rocprofiler-systems-papi-build) + endif() + endforeach() + endforeach() +endif() + +target_link_libraries( + rocprofiler-systems-timemory + INTERFACE + $ + $ + $ +) + +target_link_libraries( + rocprofiler-systems-bfd + INTERFACE $ +) + +if(ROCPROFSYS_USE_BFD) + rocprofiler_systems_target_compile_definitions(rocprofiler-systems-bfd + INTERFACE ROCPROFSYS_USE_BFD + ) +endif() + +find_package(Libva-headers ${rocprofiler_systems_FIND_QUIETLY} REQUIRED) +target_include_directories( + rocprofiler-systems-libva + INTERFACE ${LIBVA_HEADERS_INCLUDE_DIR} +) + +# ----------------------------------------------------------------------------------------# +# +# PTL (Parallel Tasking Library) submodule +# +# ----------------------------------------------------------------------------------------# + +# timemory might provide PTL::ptl-shared +if(NOT TARGET PTL::ptl-shared) + rocprofiler_systems_checkout_git_submodule( + RELATIVE_PATH external/PTL + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + REPO_URL https://github.com/jrmadsen/PTL.git + REPO_BRANCH omnitrace + ) + + set(PTL_BUILD_EXAMPLES OFF) + set(PTL_USE_TBB OFF) + set(PTL_USE_GPU OFF) + set(PTL_DEVELOPER_INSTALL OFF) + + if(NOT DEFINED BUILD_OBJECT_LIBS) + set(BUILD_OBJECT_LIBS OFF) + endif() + rocprofiler_systems_save_variables( + BUILD_CONFIG + VARIABLES BUILD_SHARED_LIBS BUILD_STATIC_LIBS BUILD_OBJECT_LIBS + CMAKE_POSITION_INDEPENDENT_CODE CMAKE_CXX_VISIBILITY_PRESET + CMAKE_VISIBILITY_INLINES_HIDDEN + ) + + set(BUILD_SHARED_LIBS OFF) + set(BUILD_STATIC_LIBS OFF) + set(BUILD_OBJECT_LIBS ON) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + set(CMAKE_CXX_VISIBILITY_PRESET "hidden") + set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) + + add_subdirectory(external/PTL EXCLUDE_FROM_ALL) + + rocprofiler_systems_restore_variables( + BUILD_CONFIG + VARIABLES BUILD_SHARED_LIBS BUILD_STATIC_LIBS BUILD_OBJECT_LIBS + CMAKE_POSITION_INDEPENDENT_CODE CMAKE_CXX_VISIBILITY_PRESET + CMAKE_VISIBILITY_INLINES_HIDDEN + ) +endif() + +target_sources( + rocprofiler-systems-ptl + INTERFACE $> +) +target_include_directories( + rocprofiler-systems-ptl + INTERFACE + $ + $ +) + +# ----------------------------------------------------------------------------------------# +# +# Restore the CMAKE_C_FLAGS and CMAKE_CXX_FLAGS in the inverse order +# +# ----------------------------------------------------------------------------------------# + +# override compiler macros +include(Compilers) + +if(ROCPROFSYS_BUILD_STATIC_LIBSTDCXX) + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + rocprofiler_systems_restore_variables(STATIC_LIBSTDCXX_CXX + VARIABLES CMAKE_CXX_FLAGS + ) + endif() +endif() + +if(ROCPROFSYS_BUILD_STATIC_LIBGCC) + if(CMAKE_C_COMPILER_ID MATCHES "GNU") + rocprofiler_systems_restore_variables(STATIC_LIBGCC_C VARIABLES CMAKE_C_FLAGS) + endif() + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + rocprofiler_systems_restore_variables(STATIC_LIBGCC_CXX VARIABLES CMAKE_CXX_FLAGS) + endif() +endif() + +rocprofiler_systems_add_feature(CMAKE_C_FLAGS "C compiler flags") +rocprofiler_systems_add_feature(CMAKE_CXX_FLAGS "C++ compiler flags") + +# ----------------------------------------------------------------------------------------# +# +# Python +# +# ----------------------------------------------------------------------------------------# + +if(ROCPROFSYS_USE_PYTHON) + if(ROCPROFSYS_USE_PYTHON AND NOT ROCPROFSYS_BUILD_PYTHON) + find_package(pybind11 REQUIRED) + endif() + + include(ConfigPython) + include(PyBind11Tools) + + rocprofiler_systems_watch_for_change(ROCPROFSYS_PYTHON_ROOT_DIRS _PYTHON_DIRS_CHANGED) + + if(_PYTHON_DIRS_CHANGED) + unset(ROCPROFSYS_PYTHON_VERSION CACHE) + unset(ROCPROFSYS_PYTHON_VERSIONS CACHE) + unset(ROCPROFSYS_INSTALL_PYTHONDIR CACHE) + else() + foreach(_VAR PREFIX ENVS) + rocprofiler_systems_watch_for_change(ROCPROFSYS_PYTHON_${_VAR} _CHANGED) + + if(_CHANGED) + unset(ROCPROFSYS_PYTHON_ROOT_DIRS CACHE) + unset(ROCPROFSYS_PYTHON_VERSIONS CACHE) + unset(ROCPROFSYS_INSTALL_PYTHONDIR CACHE) + break() + endif() + endforeach() + endif() + + if(ROCPROFSYS_PYTHON_PREFIX AND ROCPROFSYS_PYTHON_ENVS) + rocprofiler_systems_directory( + FAIL + PREFIX ${ROCPROFSYS_PYTHON_PREFIX} + PATHS ${ROCPROFSYS_PYTHON_ENVS} + OUTPUT_VARIABLE _PYTHON_ROOT_DIRS + ) + set(ROCPROFSYS_PYTHON_ROOT_DIRS + "${_PYTHON_ROOT_DIRS}" + CACHE INTERNAL + "Root directories for python" + ) + endif() + + if(NOT ROCPROFSYS_PYTHON_VERSIONS AND ROCPROFSYS_PYTHON_VERSION) + set(ROCPROFSYS_PYTHON_VERSIONS "${ROCPROFSYS_PYTHON_VERSION}") + + if(NOT ROCPROFSYS_PYTHON_ROOT_DIRS) + rocprofiler_systems_find_python(_PY VERSION ${ROCPROFSYS_PYTHON_VERSION}) + set(ROCPROFSYS_PYTHON_ROOT_DIRS "${_PY_ROOT_DIR}" CACHE INTERNAL "" FORCE) + endif() + + unset(ROCPROFSYS_PYTHON_VERSION CACHE) + unset(ROCPROFSYS_INSTALL_PYTHONDIR CACHE) + elseif( + NOT ROCPROFSYS_PYTHON_VERSIONS + AND NOT ROCPROFSYS_PYTHON_VERSION + AND ROCPROFSYS_PYTHON_ROOT_DIRS + ) + set(_PY_VERSIONS) + + foreach(_DIR ${ROCPROFSYS_PYTHON_ROOT_DIRS}) + rocprofiler_systems_find_python(_PY ROOT_DIR ${_DIR}) + + if(NOT _PY_FOUND) + continue() + endif() + + if(NOT "${_PY_VERSION}" IN_LIST _PY_VERSIONS) + list(APPEND _PY_VERSIONS "${_PY_VERSION}") + endif() + endforeach() + + set(ROCPROFSYS_PYTHON_VERSIONS "${_PY_VERSIONS}" CACHE INTERNAL "" FORCE) + elseif( + NOT ROCPROFSYS_PYTHON_VERSIONS + AND NOT ROCPROFSYS_PYTHON_VERSION + AND NOT ROCPROFSYS_PYTHON_ROOT_DIRS + ) + rocprofiler_systems_find_python(_PY REQUIRED) + set(ROCPROFSYS_PYTHON_ROOT_DIRS "${_PY_ROOT_DIR}" CACHE INTERNAL "" FORCE) + set(ROCPROFSYS_PYTHON_VERSIONS "${_PY_VERSION}" CACHE INTERNAL "" FORCE) + endif() + + rocprofiler_systems_watch_for_change(ROCPROFSYS_PYTHON_ROOT_DIRS) + rocprofiler_systems_watch_for_change(ROCPROFSYS_PYTHON_VERSIONS) + + rocprofiler_systems_check_python_dirs_and_versions(FAIL) + + list(LENGTH ROCPROFSYS_PYTHON_VERSIONS _NUM_PYTHON_VERSIONS) + + if(_NUM_PYTHON_VERSIONS GREATER 1) + set(ROCPROFSYS_INSTALL_PYTHONDIR + "${CMAKE_INSTALL_LIBDIR}/python/site-packages" + CACHE STRING + "Installation prefix for python" + ) + else() + set(ROCPROFSYS_INSTALL_PYTHONDIR + "${CMAKE_INSTALL_LIBDIR}/python${ROCPROFSYS_PYTHON_VERSIONS}/site-packages" + CACHE STRING + "Installation prefix for python" + ) + endif() +else() + set(ROCPROFSYS_INSTALL_PYTHONDIR + "${CMAKE_INSTALL_LIBDIR}/python/site-packages" + CACHE STRING + "Installation prefix for python" + ) +endif() + +rocprofiler_systems_watch_for_change(ROCPROFSYS_INSTALL_PYTHONDIR) +set(CMAKE_INSTALL_PYTHONDIR ${ROCPROFSYS_INSTALL_PYTHONDIR}) + +# ----------------------------------------------------------------------------------------# +# +# Compile definitions +# +# ----------------------------------------------------------------------------------------# + +if("${CMAKE_BUILD_TYPE}" MATCHES "Release" AND NOT ROCPROFSYS_BUILD_DEBUG) + add_target_flag_if_avail(rocprofiler-systems-compile-options "-g1") +endif() + +target_compile_definitions( + rocprofiler-systems-compile-definitions + INTERFACE ROCPROFSYS_MAX_THREADS=${ROCPROFSYS_MAX_THREADS} +) + +foreach(_LIB ${ROCPROFSYS_EXTENSION_LIBRARIES}) + get_target_property(_COMPILE_DEFS ${_LIB} INTERFACE_COMPILE_DEFINITIONS) + if(_COMPILE_DEFS) + foreach(_DEF ${_COMPILE_DEFS}) + if("${_DEF}" MATCHES "ROCPROFSYS_") + target_compile_definitions( + rocprofiler-systems-compile-definitions + INTERFACE ${_DEF} + ) + endif() + endforeach() + endif() +endforeach() diff --git a/projects/rocprofiler-systems/cmake/Perfetto.cmake b/projects/rocprofiler-systems/cmake/Perfetto.cmake new file mode 100644 index 0000000000..bc73687425 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Perfetto.cmake @@ -0,0 +1,302 @@ +# ====================================================================================== +# Perfetto.cmake +# +# Configure perfetto for rocprofiler-systems +# +# ====================================================================================== + +include_guard(GLOBAL) + +include(ExternalProject) +include(ProcessorCount) + +# ---------------------------------------------------------------------------------------# +# +# executables and libraries +# +# ---------------------------------------------------------------------------------------# + +find_program(ROCPROFSYS_COPY_EXECUTABLE NAMES cp PATH_SUFFIXES bin) + +find_program(ROCPROFSYS_NINJA_EXECUTABLE NAMES ninja PATH_SUFFIXES bin) + +mark_as_advanced(ROCPROFSYS_COPY_EXECUTABLE) +mark_as_advanced(ROCPROFSYS_NINJA_EXECUTABLE) + +# ---------------------------------------------------------------------------------------# +# +# variables +# +# ---------------------------------------------------------------------------------------# + +ProcessorCount(NUM_PROCS_REAL) +math(EXPR _NUM_THREADS "${NUM_PROCS_REAL} - (${NUM_PROCS_REAL} / 2)") +if(_NUM_THREADS GREATER 8) + set(_NUM_THREADS 8) +elseif(_NUM_THREADS LESS 1) + set(_NUM_THREADS 1) +endif() + +set(ROCPROFSYS_PERFETTO_SOURCE_DIR ${PROJECT_BINARY_DIR}/external/perfetto/source) +set(ROCPROFSYS_PERFETTO_TOOLS_DIR ${PROJECT_BINARY_DIR}/external/perfetto/source/tools) +set(ROCPROFSYS_PERFETTO_BINARY_DIR + ${PROJECT_BINARY_DIR}/external/perfetto/source/out/linux +) +set(ROCPROFSYS_PERFETTO_INSTALL_DIR + ${PROJECT_BINARY_DIR}/external/perfetto/source/out/linux/stripped +) +set(ROCPROFSYS_PERFETTO_LINK_FLAGS + "-static-libgcc" + CACHE STRING + "Link flags for perfetto" +) +set(ROCPROFSYS_PERFETTO_BUILD_THREADS + ${_NUM_THREADS} + CACHE STRING + "Number of threads to use when building perfetto tools" +) + +if(CMAKE_CXX_COMPILER_IS_CLANG) + set(PERFETTO_IS_CLANG true) + set(ROCPROFSYS_PERFETTO_C_FLAGS "" CACHE STRING "Perfetto C flags") + set(ROCPROFSYS_PERFETTO_CXX_FLAGS "" CACHE STRING "Perfetto C++ flags") +else() + set(PERFETTO_IS_CLANG false) + set(ROCPROFSYS_PERFETTO_C_FLAGS + "-static-libgcc -Wno-maybe-uninitialized -Wno-stringop-overflow" + CACHE STRING + "Perfetto C flags" + ) + set(ROCPROFSYS_PERFETTO_CXX_FLAGS + "-static-libgcc -Wno-maybe-uninitialized -Wno-stringop-overflow -Wno-mismatched-new-delete" + CACHE STRING + "Perfetto C++ flags" + ) +endif() + +mark_as_advanced(ROCPROFSYS_PERFETTO_C_FLAGS) +mark_as_advanced(ROCPROFSYS_PERFETTO_CXX_FLAGS) +mark_as_advanced(ROCPROFSYS_PERFETTO_LINK_FLAGS) + +if(NOT ROCPROFSYS_NINJA_EXECUTABLE) + set(ROCPROFSYS_NINJA_EXECUTABLE + ${ROCPROFSYS_PERFETTO_TOOLS_DIR}/ninja + CACHE FILEPATH + "Ninja" + FORCE + ) +endif() + +# ---------------------------------------------------------------------------------------# +# +# source tree +# +# ---------------------------------------------------------------------------------------# + +if(NOT EXISTS "${ROCPROFSYS_PERFETTO_SOURCE_DIR}") + execute_process( + COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/external/perfetto + ) + # cmake -E copy_directory fails for some reason + execute_process( + COMMAND + ${ROCPROFSYS_COPY_EXECUTABLE} -r ${PROJECT_SOURCE_DIR}/external/perfetto/ + ${ROCPROFSYS_PERFETTO_SOURCE_DIR} + ) +endif() + +file(READ ${PROJECT_SOURCE_DIR}/external/perfetto/sdk/perfetto.h _PERFETTO_HEADER) + +string( + REGEX REPLACE + " perfetto::internal::ValidateEventNameType" + " ::perfetto::internal::ValidateEventNameType" + _PERFETTO_HEADER + "${_PERFETTO_HEADER}" +) + +if(ROCPROFSYS_USE_SANITIZER AND ROCPROFSYS_SANITIZER_TYPE MATCHES "address") + string( + REPLACE + "__asan_poison_memory_region((a), (s))" + "" + _PERFETTO_HEADER + "${_PERFETTO_HEADER}" + ) + string( + REPLACE + "__asan_unpoison_memory_region((a), (s))" + "" + _PERFETTO_HEADER + "${_PERFETTO_HEADER}" + ) +endif() + +file(WRITE ${ROCPROFSYS_PERFETTO_SOURCE_DIR}/sdk/perfetto.h.tmp "${_PERFETTO_HEADER}") + +configure_file( + ${ROCPROFSYS_PERFETTO_SOURCE_DIR}/sdk/perfetto.h.tmp + ${ROCPROFSYS_PERFETTO_SOURCE_DIR}/sdk/perfetto.h + COPYONLY +) +configure_file( + ${PROJECT_SOURCE_DIR}/external/perfetto/sdk/perfetto.cc + ${ROCPROFSYS_PERFETTO_SOURCE_DIR}/sdk/perfetto.cc + COPYONLY +) +configure_file( + ${PROJECT_SOURCE_DIR}/cmake/Templates/args.gn.in + ${ROCPROFSYS_PERFETTO_BINARY_DIR}/args.gn + @ONLY +) + +# ---------------------------------------------------------------------------------------# +# +# build tools +# +# ---------------------------------------------------------------------------------------# + +if(ROCPROFSYS_INSTALL_PERFETTO_TOOLS) + find_program(ROCPROFSYS_CURL_EXECUTABLE NAMES curl PATH_SUFFIXES bin) + + if(NOT ROCPROFSYS_CURL_EXECUTABLE) + rocprofiler_systems_message( + SEND_ERROR + "curl executable cannot be found. install-build-deps script for perfetto will fail" + ) + endif() + + ExternalProject_Add( + rocprofiler-systems-perfetto-build + PREFIX ${PROJECT_BINARY_DIR}/external/perfetto + SOURCE_DIR ${ROCPROFSYS_PERFETTO_SOURCE_DIR} + BUILD_IN_SOURCE 1 + PATCH_COMMAND ${ROCPROFSYS_PERFETTO_TOOLS_DIR}/install-build-deps + CONFIGURE_COMMAND + ${ROCPROFSYS_PERFETTO_TOOLS_DIR}/gn gen ${ROCPROFSYS_PERFETTO_BINARY_DIR} + BUILD_COMMAND + ${ROCPROFSYS_NINJA_EXECUTABLE} -C ${ROCPROFSYS_PERFETTO_BINARY_DIR} -j + ${ROCPROFSYS_PERFETTO_BUILD_THREADS} + INSTALL_COMMAND "" + BUILD_BYPRODUCTS ${ROCPROFSYS_PERFETTO_BINARY_DIR}/args.gn + ) + + add_custom_target( + rocprofiler-systems-perfetto-clean + COMMAND ${ROCPROFSYS_NINJA_EXECUTABLE} -t clean + COMMAND + ${CMAKE_COMMAND} -E rm -rf + ${PROJECT_BINARY_DIR}/external/perfetto/src/rocprof-sys-perfetto-build-stamp + WORKING_DIRECTORY ${ROCPROFSYS_PERFETTO_BINARY_DIR} + COMMENT "Cleaning Perfetto..." + ) + + install( + DIRECTORY ${ROCPROFSYS_PERFETTO_INSTALL_DIR}/ + DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_NAME} + COMPONENT perfetto + FILES_MATCHING + PATTERN "*libperfetto.so*" + ) + + foreach( + _FILE + perfetto + traced + tracebox + traced_probes + traced_perf + trigger_perfetto + ) + if("${_FILE}" STREQUAL "perfetto") + string(REPLACE "_" "-" _INSTALL_FILE "rocprof-sys-${_FILE}") + else() + string(REPLACE "_" "-" _INSTALL_FILE "rocprof-sys-perfetto-${_FILE}") + endif() + install( + PROGRAMS ${ROCPROFSYS_PERFETTO_INSTALL_DIR}/${_FILE} + DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT perfetto + RENAME ${_INSTALL_FILE} + OPTIONAL + ) + endforeach() +endif() + +# ---------------------------------------------------------------------------------------# +# +# perfetto static library +# +# ---------------------------------------------------------------------------------------# + +add_library(rocprofiler-systems-perfetto-library STATIC) +add_library( + rocprofiler-systems::rocprofiler-systems-perfetto-library + ALIAS rocprofiler-systems-perfetto-library +) +target_sources( + rocprofiler-systems-perfetto-library + PRIVATE + ${ROCPROFSYS_PERFETTO_SOURCE_DIR}/sdk/perfetto.cc + ${ROCPROFSYS_PERFETTO_SOURCE_DIR}/sdk/perfetto.h +) +target_link_libraries( + rocprofiler-systems-perfetto-library + PRIVATE + rocprofiler-systems::rocprofiler-systems-threading + rocprofiler-systems::rocprofiler-systems-static-libgcc + rocprofiler-systems::rocprofiler-systems-static-libstdcxx +) +set_target_properties( + rocprofiler-systems-perfetto-library + PROPERTIES + OUTPUT_NAME perfetto + ARCHIVE_OUTPUT_DIRECTORY ${ROCPROFSYS_PERFETTO_BINARY_DIR} + POSITION_INDEPENDENT_CODE ON + CXX_VISIBILITY_PRESET "internal" +) + +set(perfetto_DIR ${ROCPROFSYS_PERFETTO_SOURCE_DIR}) +set(PERFETTO_ROOT_DIR + ${ROCPROFSYS_PERFETTO_SOURCE_DIR} + CACHE PATH + "Root Perfetto installation" + FORCE +) +set(PERFETTO_INCLUDE_DIR + ${ROCPROFSYS_PERFETTO_SOURCE_DIR}/sdk + CACHE PATH + "Perfetto include folder" + FORCE +) +set(PERFETTO_LIBRARY + ${ROCPROFSYS_PERFETTO_BINARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}perfetto${CMAKE_STATIC_LIBRARY_SUFFIX} + CACHE FILEPATH + "Perfetto library" + FORCE +) + +mark_as_advanced(PERFETTO_ROOT_DIR) +mark_as_advanced(PERFETTO_INCLUDE_DIR) +mark_as_advanced(PERFETTO_LIBRARY) + +# ---------------------------------------------------------------------------------------# +# +# perfetto interface library +# +# ---------------------------------------------------------------------------------------# + +rocprofiler_systems_target_compile_definitions(rocprofiler-systems-perfetto + INTERFACE ROCPROFSYS_USE_PERFETTO +) +target_include_directories( + rocprofiler-systems-perfetto + SYSTEM + INTERFACE $ +) +target_link_libraries( + rocprofiler-systems-perfetto + INTERFACE + $ + $ +) diff --git a/projects/rocprofiler-systems/cmake/Templates/args.gn.in b/projects/rocprofiler-systems/cmake/Templates/args.gn.in new file mode 100644 index 0000000000..21c844b696 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Templates/args.gn.in @@ -0,0 +1,28 @@ +# Set build arguments here. See `gn help buildargs`. + +cc = "@CMAKE_C_COMPILER@" +cxx = "@CMAKE_CXX_COMPILER@" + +is_debug = false +is_clang = @PERFETTO_IS_CLANG@ +is_hermetic_clang = false + +enable_perfetto_benchmarks = false +enable_perfetto_integration_tests = true +enable_perfetto_unittests = false +enable_perfetto_fuzzers = false + +# enable_perfetto_stderr_crash_dump = false +enable_perfetto_heapprofd = false +enable_perfetto_tools = false +enable_perfetto_trace_processor = true +enable_perfetto_trace_processor_httpd = true +enable_perfetto_trace_processor_json = false +enable_perfetto_trace_processor_linenoise = false +enable_perfetto_trace_processor_percentile = false +enable_perfetto_trace_processor_sqlite = true +enable_perfetto_ui = false + +extra_cflags = "@ROCPROFSYS_PERFETTO_C_FLAGS@" +extra_cxxflags = "@ROCPROFSYS_PERFETTO_CXX_FLAGS@" +extra_ldflags = "@ROCPROFSYS_PERFETTO_LINK_FLAGS@ -Wl,-rpath=\\\$ORIGIN:\\\$ORIGIN/../lib:\\\$ORIGIN/../lib/rocprof-sys" diff --git a/projects/rocprofiler-systems/cmake/Templates/console-script.in b/projects/rocprofiler-systems/cmake/Templates/console-script.in new file mode 100755 index 0000000000..76a5fafbd8 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Templates/console-script.in @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +export PYTHONPATH=$(cd $(dirname ${BASH_SOURCE[0]})/../@CMAKE_INSTALL_PYTHONDIR@ && pwd):${PYTHONPATH} + +: ${PYTHON_EXECUTABLE:=@PYTHON_EXECUTABLE@} + +if [ ! -f ${PYTHON_EXECUTABLE} ]; then PYTHON_EXECUTABLE=$(basename ${PYTHON_EXECUTABLE}); fi + +set -e + +run-script() +{ + echo -e "\n##### ${PROJECT_NAME} :: executing '${@}'... #####\n" + eval $@ +} + +run-script ${PYTHON_EXECUTABLE} -m @SCRIPT_SUBMODULE@ "$(printf ' %q' "$@")" diff --git a/projects/rocprofiler-systems/cmake/Templates/modulefile.in b/projects/rocprofiler-systems/cmake/Templates/modulefile.in new file mode 100644 index 0000000000..c485f5973e --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Templates/modulefile.in @@ -0,0 +1,17 @@ +#%Module1.0 + +module-whatis "@PROJECT_NAME@ (version @PROJECT_VERSION@)" + +proc ModulesHelp { } { +puts stderr "Loads @PROJECT_NAME@ v@PROJECT_VERSION@" +} + +set ROOT [file normalize [file dirname [file normalize ${ModulesCurrentModulefile}]]/../../..] + +setenv @PROJECT_NAME_UNDERSCORED@_ROOT "${ROOT}" +prepend-path CMAKE_PREFIX_PATH "${ROOT}" +prepend-path PATH "${ROOT}/bin" +prepend-path PATH "${ROOT}/@CMAKE_INSTALL_LIBEXECDIR@/@PROJECT_NAME@" +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@" diff --git a/projects/rocprofiler-systems/cmake/Templates/rocprof-sys-config.cmake.in b/projects/rocprofiler-systems/cmake/Templates/rocprof-sys-config.cmake.in new file mode 100644 index 0000000000..2f46cbc8fb --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Templates/rocprof-sys-config.cmake.in @@ -0,0 +1,56 @@ +# - Config file for @PROJECT_NAME@ and its component libraries +# It defines the following variables: +# +# @PROJECT_NAME@_INCLUDE_DIRS +# @PROJECT_NAME@_LIBRARIES +# @PROJECT_NAME@_INTERNAL_DEFINES - used by the test suite + +# compute paths +get_filename_component(@PROJECT_NAME@_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) + +# version +include(${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-version.cmake) + +@PACKAGE_INIT@ + +set_and_check(@PROJECT_NAME@_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") +set_and_check(@PROJECT_NAME@_LIB_DIR "@PACKAGE_LIB_INSTALL_DIR@") +get_filename_component(@PROJECT_NAME@_ROOT_DIR ${@PROJECT_NAME@_INCLUDE_DIR} PATH) + +set(@PROJECT_NAME@_LIBRARIES) + +add_library(@PROJECT_NAME@::@PROJECT_NAME@ INTERFACE IMPORTED) + +include("${@PROJECT_NAME@_CMAKE_DIR}/@PROJECT_NAME@-library-targets.cmake") + +# Library dependencies +foreach(TARG @PROJECT_BUILD_TARGETS@) + set(TARG @PROJECT_NAME@-${TARG}-library) + if(NOT @PROJECT_NAME@_FIND_COMPONENTS) + list(APPEND @PROJECT_NAME@_LIBRARIES @PROJECT_NAME@::${TARG}) + target_link_libraries(@PROJECT_NAME@::@PROJECT_NAME@ + INTERFACE @PROJECT_NAME@::${TARG}) + endif() +endforeach() + +if(@PROJECT_NAME@_FIND_COMPONENTS) + foreach(COMP ${@PROJECT_NAME@_FIND_COMPONENTS}) + set(TARG @PROJECT_NAME@::@PROJECT_NAME@-${COMP}-library) + if(TARGET ${TARG}) + set(@PROJECT_NAME@_${COMP}_FOUND 1) + list(APPEND @PROJECT_NAME@_LIBRARIES ${TARG}) + target_link_libraries(@PROJECT_NAME@::@PROJECT_NAME@ + INTERFACE ${TARG}) + else() + set(@PROJECT_NAME@_${COMP}_FOUND 0) + endif() + endforeach() +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + @PROJECT_NAME@ + FOUND_VAR @PROJECT_NAME@_FOUND + REQUIRED_VARS @PROJECT_NAME@_ROOT_DIR @PROJECT_NAME@_INCLUDE_DIR @PROJECT_NAME@_LIBRARIES + VERSION_VAR @PROJECT_NAME@_VERSION + HANDLE_COMPONENTS) diff --git a/projects/rocprofiler-systems/cmake/Templates/rocprof-sys-install.py.in b/projects/rocprofiler-systems/cmake/Templates/rocprof-sys-install.py.in new file mode 100755 index 0000000000..364d2612ff --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Templates/rocprof-sys-install.py.in @@ -0,0 +1,294 @@ +#!/usr/bin/env python3 + +import os +import re +import sys +import stat +import argparse +import tempfile +import subprocess as sp +from urllib import request +from urllib.error import HTTPError + +rocprofsys_version = "@ROCPROFSYS_VERSION@" +rocprofsys_git_tag = "@ROCPROFSYS_GIT_TAG@" +_rocm_path = os.environ.get("ROCM_PATH", "/opt/rocm") +_rocm_version = None + + +def get_rocm_version(rocm_hint): + global _rocm_path + global _rocm_version + + if rocm_hint is not None and rocm_hint is not True: + if rocm_hint.replace(".", "0").isnumeric(): + _rocm_version = rocm_hint + else: + _rocm_path = rocm_hint + + def _parse_version(_v): + return re.split(r"[\\.-]", _v) if _v is not None else None + + _version = _parse_version(_rocm_version) + for fname in [ + "version", + "version-dev", + "version-hip-libraries", + "version-hiprt", + "version-hiprt-devel", + "version-hip-sdk", + "version-libs", + "version-utils", + ]: + if _version is not None and len(_version) > 0: + break + _fname = os.path.join(_rocm_path, ".info", fname) + if os.path.exists(_fname): + with open(_fname, "r") as f: + _version = _parse_version(f.readlines()[0].strip("\n")) + + if _version is not None and len(_version) > 0: + _major = int(_version[0]) + _minor = int(_version[1]) if len(_version) >= 2 else 0 + _rocm_version = f"{_major}.{_minor}" + return "-ROCm-{}".format((10000 * _major) + (100 * _minor)) + return None + + +def get_os_info(os_distrib, os_version): + _os_info = {} + with open("/etc/os-release", "r") as f: + for line in [_v.strip() for _v in f.readlines()]: + if "=" not in line: + continue + _key, _data = line.split("=", 1) + _os_info[_key] = _data.strip('"') + + def _parse_version(_v): + _version = re.split(r"[\\.-]", _v) + return ( + "{}.{}".format(_version[0], _version[1]) + if len(_version) > 1 + else "{}".format(_version[0]) + ) + + if os_distrib is None or os_distrib == "auto": + if "ubuntu" in _os_info["ID"]: + os_distrib = "ubuntu" + elif "opensuse" in _os_info["ID"]: + os_distrib = "opensuse" + elif "rhel" in _os_info["ID"]: + os_distrib = "rhel" + elif "centos" in _os_info["ID"]: + os_distrib = "rhel" + elif "rockylinux" in _os_info["ID"]: + os_distrib = "rhel" + elif "debian" in _os_info["ID"]: + os_distrib = "ubuntu" + if "debian" in _os_info["ID"] and os_version is None: + _debian_version = float(_parse_version(_os_info["VERSION_ID"])) + if _debian_version >= 11.0: + os_version = "20.04" + else: + os_version = "18.04" + elif "fedora" in _os_info["ID"]: + os_distrib = "rhel" + # fedora has different versioning system so fallback to 8.7 + if os_version is None: + os_version = "8.7" + else: + # if we don't have an exact match, check ID_LIKE + if "ID_LIKE" not in _os_info.keys(): + _os_info["ID_LIKE"] = _os_info["ID"] + + if "debian" in _os_info["ID_LIKE"]: + os_distrib = "ubuntu" + if os_version is None: + # fallback on 20.04 if ID is not ubuntu but debian-like + os_version = "20.04" + elif "suse" in _os_info["ID_LIKE"]: + os_distrib = "opensuse" + # fallback on 15.3 if ID is not opensuse but suse-like + if os_version is None: + os_version = "15.3" + elif "rhel" in _os_info["ID_LIKE"] or "centos" in _os_info["ID_LIKE"]: + os_distrib = "rhel" + if os_version is None: + os_version = "8.7" + else: + raise RuntimeError( + "Unknown ID_LIKE value in /etc/os-release: {}".format( + _os_info["ID_LIKE"] + ) + ) + elif os_distrib == "centos": + os_distrib = "rhel" + # uses same versioning system + elif os_distrib == "fedora": + os_distrib = "rhel" + if os_version is None: + # fedora has different versioning system so fallback to 8.7 + os_version = "8.7" + + if os_version is None: + os_version = _parse_version(_os_info["VERSION_ID"]) + + return (os_distrib, os_version) + + +def print_log(*args, **kwargs): + sys.stdout.flush() + sys.stderr.flush() + sys.stderr.write("### ") + sys.stderr.write(*args, **kwargs) + sys.stderr.write("\n") + sys.stderr.flush() + + +def run(*args, **kwargs): + print_log("Executing: {}\n".format(" ".join(*args))) + sp.run(*args, **kwargs, check=True) + sys.stderr.write("\n") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + + parser.add_argument( + "--version", + help="Print ROCm Systems Profiler version which will be installed", + action="store_true", + ) + parser.add_argument( + "-p", "--prefix", help="Installation prefix", type=str, default="/opt/rocprofiler-systems" + ) + parser.add_argument( + "-i", + "--interactive", + help="Prompt to accept the license and include/exclude subdirectory", + action="store_true", + ) + parser.add_argument( + "-D", + "--download-path", + help="Download directory (default: temporary directory)", + type=str, + default=None, + ) + parser.add_argument( + "-d", + "--os-distrib", + help="Target OS distribution", + type=str, + default=None, + choices=("auto", "ubuntu", "opensuse", "rhel", "centos", "fedora"), + ) + parser.add_argument( + "-v", "--os-version", help="Target OS version", type=str, default=None + ) + parser.add_argument( + "-k", + "--keep-download", + help="Do not delete downloaded file as installation", + action="store_true", + ) + parser.add_argument( + "--rocm", + help="Install ROCm Systems Profiler with ROCm support. Accepts either a ROCm version (e.g. '6.2') or the root path to the ROCm install containing .info/version* file(s) (e.g. /opt/rocm if /opt/rocm/.info/version exists). If no argument is provided, the ROCm version will attempted to be deduced from $ENV{ROCM_PATH}/.info/version", + nargs="?", + default=None, + const=True, + metavar="VERSION or ROCM_PATH with .info/version file(s)", + ) + # right now, only valid set of extensions are: papi + ompt + python3 + # in the future, this might change, e.g. MPI variants + parser.add_argument( + "-e", + "--extensions", + help="ROCm Systems Profiler extensions, e.g. PAPI, OMPT, and Python3", + nargs="*", + default=("papi", "ompt", "python3"), + choices=("papi", "ompt", "python3"), + ) + + args = parser.parse_args() + + if args.version: + print(f"ROCm Systems Profiler {rocprofsys_version}") + sys.exit(0) + + os_distrib, os_version = get_os_info(args.os_distrib, args.os_version) + rocm_version = get_rocm_version(args.rocm) if args.rocm is not None else "" + extensions = "" + if "papi" in args.extensions: + extensions += "-PAPI" + if "ompt" in args.extensions: + extensions += "-OMPT" + if "python3" in args.extensions: + extensions += "-Python3" + + if rocm_version is None: + raise RuntimeError( + f"Error! ROCm version could not be determined from {_rocm_path}/.info/version*. Please provide a ROCm version or the root path to the ROCm install containing the .info directory, e.g. '--rocm 5.4' or '--rocm /path/to/rocm/install'" + ) + + script = f"rocprofiler-systems-{rocprofsys_version}-{os_distrib}-{os_version}{rocm_version}{extensions}.sh" + url = f"https://github.com/ROCm/rocprofiler-systems/releases/download/{rocprofsys_git_tag}/{script}" + download_dir = ( + tempfile.mkdtemp(prefix="rocprof-sys-install-") + if args.download_path is None + else args.download_path + ) + install_script = os.path.join(download_dir, script) + + try: + if not os.path.exists(download_dir): + print_log(f"Creating download directory: {download_dir} ...") + os.makedirs(download_dir) + + print_log(f"Downloading {url} ...") + + try: + response = request.urlretrieve(url, install_script) + except HTTPError as e: + print_log(f"") + print_log(f"Error: {e}") + print_log(f"") + print_log(f"Error: Installer script download from {url} failed!") + if args.rocm is not None: + print_log( + f"There may not be a pre-built installer for ROCm version {_rocm_version}" + ) + sys.exit(-1) + + if os.path.exists(install_script): + print_log(f"Download completed: {install_script}") + else: + raise RuntimeError(f"Download completed but {install_script} does not exist") + + os.chmod(install_script, stat.S_IRWXU) + + if not os.path.exists(args.prefix): + print_log(f"Creating directory: {args.prefix} ...") + os.makedirs(args.prefix) + + install_args = ( + ["--exclude-subdir", "--skip-license"] if not args.interactive else [] + ) + + print_log(f"Installing ROCm Systems Profiler to {args.prefix} ...") + + run([install_script, f"--prefix={args.prefix}"] + install_args) + + print_log( + f"ROCm Systems Profiler v{rocprofsys_version} installation to {args.prefix} succeeded!" + ) + + finally: + if not args.keep_download: + print_log(f"Removing install script {install_script} ...") + os.remove(install_script) + # remove the directory if it is a temporary directory + if args.download_path is None: + print_log(f"Removing temporary directory {download_dir} ...") + os.rmdir(download_dir) diff --git a/projects/rocprofiler-systems/cmake/Templates/setup-env.sh.in b/projects/rocprofiler-systems/cmake/Templates/setup-env.sh.in new file mode 100644 index 0000000000..423203e741 --- /dev/null +++ b/projects/rocprofiler-systems/cmake/Templates/setup-env.sh.in @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +if [ -z "$BASH_SOURCE" ]; then + # If not running bash, try to obtain directory with $0 + BASEDIR="$( cd "$(dirname "$0")"; pwd -P )" +else + BASEDIR=$(dirname ${BASH_SOURCE[0]}) +fi +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} +PATH=${BASEDIR}/@CMAKE_INSTALL_LIBEXECDIR@/@PROJECT_NAME@:${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@ + +export @PROJECT_NAME_UNDERSCORED@_ROOT +export PATH +export LD_LIBRARY_PATH +export PYTHONPATH +export CMAKE_PREFIX_PATH +export @PROJECT_NAME_UNDERSCORED@_DIR diff --git a/projects/rocprofiler-systems/docker/.gitignore b/projects/rocprofiler-systems/docker/.gitignore new file mode 100644 index 0000000000..5f0a74bff3 --- /dev/null +++ b/projects/rocprofiler-systems/docker/.gitignore @@ -0,0 +1 @@ +/dyninst-source diff --git a/projects/rocprofiler-systems/docker/Dockerfile.opensuse b/projects/rocprofiler-systems/docker/Dockerfile.opensuse new file mode 100644 index 0000000000..8aca6bd599 --- /dev/null +++ b/projects/rocprofiler-systems/docker/Dockerfile.opensuse @@ -0,0 +1,65 @@ +ARG DISTRO=opensuse/leap +ARG VERSION=15.5 +FROM ${DISTRO}:${VERSION} + +ENV HOME /root +ENV SHELL /bin/bash +ENV BASH_ENV /etc/bash.bashrc +ENV DEBIAN_FRONTEND noninteractive + +WORKDIR /tmp +SHELL [ "/bin/bash", "-c" ] + +ENV PATH /usr/local/bin:${PATH} +ENV LIBRARY_PATH ${LIBRARY_PATH}:/opt/amdgpu/lib64 + +RUN set +e; \ + zypper --non-interactive -i --gpg-auto-import-keys refresh; \ + zypper --non-interactive -i patch; \ + zypper --non-interactive -i patch; \ + zypper --non-interactive -i --gpg-auto-import-keys refresh; \ + exit 0 + +RUN zypper --non-interactive update -y && \ + zypper --non-interactive dist-upgrade -y && \ + zypper --non-interactive install -y -t pattern devel_basis && \ + zypper --non-interactive install -y binutils-gold chrpath cmake curl dpkg-devel \ + gcc-c++ git iproute2 libdrm-devel libnuma-devel openmpi3-devel python3-pip rpm-build \ + sqlite3-devel wget && \ + python3 -m pip install 'cmake==3.21' + +ARG ROCM_VERSION=0.0 + +RUN ROCM_MAJOR=$(echo "${ROCM_VERSION}" | sed 's/\./ /g' | awk '{print $1}') && \ + ROCM_MINOR=$(echo "${ROCM_VERSION}" | sed 's/\./ /g' | awk '{print $2}') && \ + if [ "${ROCM_MAJOR}" != "0" ] || [ "${ROCM_MINOR}" != "0" ]; then \ + OS_VERSION=$(grep '^VERSION_ID=' /etc/os-release | cut -d'=' -f2 | tr -d '"') && \ + OS_VERSION_MAJOR=$(echo "$OS_VERSION" | cut -d'.' -f1) && \ + OS_VERSION_MINOR=$(echo "$OS_VERSION" | cut -d'.' -f2) && \ + ROCM_PATCH=$(echo "${ROCM_VERSION}" | sed 's/\./ /g' | awk '{print $3}') && \ + if [ -z "${ROCM_PATCH}" ] || [ "${ROCM_PATCH}" = "0" ]; then \ + ROCM_PATCH=0 && \ + ROCM_VERSION=$(echo "${ROCM_VERSION}" | sed 's/\.0$//') \ + ; fi && \ + ROCM_VERSN=$(( ("${ROCM_MAJOR}"*10000)+("${ROCM_MINOR}"*100) + ("${ROCM_PATCH}"))) && \ + zypper --non-interactive addrepo https://download.opensuse.org/repositories/devel:languages:perl/15.6/devel:languages:perl.repo && \ + zypper --non-interactive --no-gpg-checks install -y https://repo.radeon.com/amdgpu-install/${ROCM_VERSION}/sle/${OS_VERSION}/amdgpu-install-${ROCM_MAJOR}.${ROCM_MINOR}.${ROCM_VERSN}-1.noarch.rpm && \ + zypper --non-interactive --gpg-auto-import-keys refresh && \ + zypper --non-interactive install -y rocm-dev rccl-devel libpciaccess0 && \ + zypper --non-interactive clean --all; \ + fi + +ARG PYTHON_VERSIONS="6 7 8 9 10 11 12 13" + +RUN wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh -O miniforge.sh && \ + bash miniforge.sh -b -p /opt/conda && \ + export PATH="/opt/conda/bin:${PATH}" && \ + conda config --set always_yes yes --set changeps1 no && \ + conda update -c conda-forge -n base conda && \ + for i in ${PYTHON_VERSIONS}; do conda create -n py3.${i} -c conda-forge python=3.${i} pip; done && \ + for i in ${PYTHON_VERSIONS}; do /opt/conda/envs/py3.${i}/bin/python -m pip install numpy perfetto dataclasses; done && \ + conda clean -a -y && \ + conda init + +WORKDIR /home +SHELL [ "/bin/bash", "--login", "-c" ] diff --git a/projects/rocprofiler-systems/docker/Dockerfile.opensuse.ci b/projects/rocprofiler-systems/docker/Dockerfile.opensuse.ci new file mode 100644 index 0000000000..915759dbea --- /dev/null +++ b/projects/rocprofiler-systems/docker/Dockerfile.opensuse.ci @@ -0,0 +1,51 @@ +ARG DISTRO=opensuse/leap +ARG VERSION=15.5 +FROM ${DISTRO}:${VERSION} + +ENV HOME /root +ENV SHELL /bin/bash +ENV BASH_ENV /etc/bash.bashrc +ENV DEBIAN_FRONTEND noninteractive + +WORKDIR /tmp +SHELL [ "/bin/bash", "-c" ] + +ENV PATH /usr/local/bin:${PATH} + +ARG EXTRA_PACKAGES="" +ARG ELFUTILS_DOWNLOAD_VERSION="0.188" +ARG BOOST_DOWNLOAD_VERSION="1.79.0" +ARG NJOBS="8" + +RUN set +e; \ + zypper --non-interactive -i --gpg-auto-import-keys refresh; \ + zypper --non-interactive -i patch; \ + zypper --non-interactive -i patch; \ + zypper --non-interactive -i --gpg-auto-import-keys refresh; \ + exit 0 + +RUN zypper --non-interactive update -y && \ + zypper --non-interactive dist-upgrade -y && \ + zypper --non-interactive install -y -t pattern devel_basis && \ + zypper --non-interactive install -y binutils-gold chrpath cmake curl dpkg-devel \ + gcc-c++ git iproute2 libnuma-devel openmpi3-devel papi-devel python3-pip \ + rpm-build sqlite3-devel vim wget && \ + zypper --non-interactive clean --all && \ + python3 -m pip install 'cmake==3.21' perfetto + +ARG PYTHON_VERSIONS="6 7 8 9 10 11 12 13" + +RUN wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh -O miniforge.sh && \ + bash miniforge.sh -b -p /opt/conda && \ + export PATH="/opt/conda/bin:${PATH}" && \ + conda config --set always_yes yes --set changeps1 no && \ + conda update -c conda-forge -n base conda && \ + for i in ${PYTHON_VERSIONS}; do conda create -n py3.${i} -c conda-forge python=3.${i} pip numpy; done && \ + for i in ${PYTHON_VERSIONS}; do /opt/conda/envs/py3.${i}/bin/python -m pip install numpy perfetto dataclasses; done && \ + conda clean -a -y && \ + cd /tmp && \ + shopt -s dotglob extglob && \ + rm -rf * + +WORKDIR /home +SHELL [ "/bin/bash", "--login", "-c" ] diff --git a/projects/rocprofiler-systems/docker/Dockerfile.rhel b/projects/rocprofiler-systems/docker/Dockerfile.rhel new file mode 100644 index 0000000000..5d73d1bd90 --- /dev/null +++ b/projects/rocprofiler-systems/docker/Dockerfile.rhel @@ -0,0 +1,64 @@ +ARG DISTRO=rockylinux/rockylinux +ARG VERSION=8 +FROM ${DISTRO}:${VERSION} + +ENV HOME /root +ENV SHELL /bin/bash +ENV BASH_ENV /etc/bash.bashrc +ENV DEBIAN_FRONTEND noninteractive + +WORKDIR /tmp +SHELL [ "/bin/bash", "-c" ] + +ENV PATH /usr/lib64/openmpi/bin:/usr/local/bin:${PATH} +ENV LIBRARY_PATH ${LIBRARY_PATH}:/opt/amdgpu/lib64 + +RUN yum groupinstall -y "Development Tools" && \ + yum install -y epel-release && crb enable && \ + yum install -y --allowerasing chrpath cmake curl dpkg-devel iproute libdrm-devel \ + numactl-devel openmpi-devel papi-devel python3-pip sqlite-devel texinfo \ + wget which zlib-devel && \ + yum clean all && \ + python3 -m pip install 'cmake==3.21' && \ + python3 -m pip install 'perfetto' + +ARG ROCM_VERSION=0.0 + +RUN ROCM_MAJOR=$(echo "${ROCM_VERSION}" | sed 's/\./ /g' | awk '{print $1}') && \ + ROCM_MINOR=$(echo "${ROCM_VERSION}" | sed 's/\./ /g' | awk '{print $2}') && \ + if [ "${ROCM_MAJOR}" != "0" ] || [ "${ROCM_MINOR}" != "0" ]; then \ + OS_VERSION=$(grep '^VERSION_ID=' /etc/os-release | cut -d'=' -f2 | tr -d '"') && \ + OS_VERSION_MAJOR=$(echo "$OS_VERSION" | cut -d'.' -f1) && \ + RPM_TAG=".el${OS_VERSION_MAJOR}" && \ + ROCM_PATCH=$(echo "${ROCM_VERSION}" | sed 's/\./ /g' | awk '{print $3}') && \ + if [ -z "${ROCM_PATCH}" ] || [ "${ROCM_PATCH}" = "0" ]; then \ + ROCM_PATCH=0 && \ + ROCM_VERSION=$(echo "${ROCM_VERSION}" | sed 's/\.0$//') \ + ; fi && \ + ROCM_VERSN=$(( ("${ROCM_MAJOR}"*10000)+("${ROCM_MINOR}"*100) + ("${ROCM_PATCH}"))) && \ + if [ "${OS_VERSION_MAJOR}" -eq 8 ]; then PERL_REPO=powertools; else PERL_REPO=crb; fi && \ + dnf -y --enablerepo=${PERL_REPO} install perl-File-BaseDir && \ + yum install -y https://repo.radeon.com/amdgpu-install/${ROCM_VERSION}/rhel/${OS_VERSION}/amdgpu-install-${ROCM_MAJOR}.${ROCM_MINOR}.${ROCM_VERSN}-1${RPM_TAG}.noarch.rpm && \ + yum install -y rocm-dev && \ + yum clean all; \ + fi + +ARG PYTHON_VERSIONS="6 7 8 9 10 11 12 13" + +RUN wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh -O miniforge.sh && \ + bash miniforge.sh -b -p /opt/conda && \ + export PATH="/opt/conda/bin:${PATH}" && \ + conda config --set always_yes yes --set changeps1 no && \ + conda update -c conda-forge -n base conda && \ + for i in ${PYTHON_VERSIONS}; do conda create -n py3.${i} -c conda-forge python=3.${i} pip; done && \ + for i in ${PYTHON_VERSIONS}; do /opt/conda/envs/py3.${i}/bin/python -m pip install numpy perfetto dataclasses; done && \ + conda clean -a -y && \ + conda init + +RUN if [ "${ROCM_VERSION}" != "0.0" ]; then ln -sf /opt/rocm-${ROCM_VERSION}* /opt/rocm; fi + +WORKDIR /home +ENV LC_ALL C.UTF-8 +SHELL [ "/bin/bash", "--login", "-c" ] +COPY ./entrypoint-rhel.sh /docker-entrypoint.sh +ENTRYPOINT [ "/docker-entrypoint.sh" ] diff --git a/projects/rocprofiler-systems/docker/Dockerfile.rhel.ci b/projects/rocprofiler-systems/docker/Dockerfile.rhel.ci new file mode 100644 index 0000000000..67f0dd079f --- /dev/null +++ b/projects/rocprofiler-systems/docker/Dockerfile.rhel.ci @@ -0,0 +1,42 @@ +ARG DISTRO=rockylinux/rockylinux +ARG VERSION=8 +FROM ${DISTRO}:${VERSION} + +ENV HOME /root +ENV SHELL /bin/bash +ENV BASH_ENV /etc/bash.bashrc +ENV DEBIAN_FRONTEND noninteractive + +WORKDIR /tmp +SHELL [ "/bin/bash", "-c" ] + +ENV PATH /usr/lib64/openmpi/bin:/usr/local/bin:${PATH} + +ARG EXTRA_PACKAGES="" +ARG ELFUTILS_DOWNLOAD_VERSION="0.188" +ARG BOOST_DOWNLOAD_VERSION="1.79.0" +ARG NJOBS="8" + +RUN yum groupinstall -y "Development Tools" && \ + yum install -y epel-release && crb enable && \ + yum install -y --allowerasing chrpath cmake curl dpkg-devel iproute numactl-devel \ + openmpi-devel papi-devel python3-pip sqlite-devel texinfo wget which vim zlib-devel && \ + yum clean all && \ + python3 -m pip install 'cmake==3.21' perfetto + +ARG PYTHON_VERSIONS="6 7 8 9 10 11 12 13" + +RUN wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh -O miniforge.sh && \ + bash miniforge.sh -b -p /opt/conda && \ + export PATH="/opt/conda/bin:${PATH}" && \ + conda config --set always_yes yes --set changeps1 no && \ + conda update -c conda-forge -n base conda && \ + for i in ${PYTHON_VERSIONS}; do conda create -n py3.${i} -c conda-forge python=3.${i} pip numpy; done && \ + for i in ${PYTHON_VERSIONS}; do /opt/conda/envs/py3.${i}/bin/python -m pip install numpy perfetto dataclasses; done && \ + conda clean -a -y && \ + cd /tmp && \ + shopt -s dotglob extglob && \ + rm -rf * + +WORKDIR /home +SHELL [ "/bin/bash", "--login", "-c" ] diff --git a/projects/rocprofiler-systems/docker/Dockerfile.ubuntu b/projects/rocprofiler-systems/docker/Dockerfile.ubuntu new file mode 100644 index 0000000000..5ffb31c275 --- /dev/null +++ b/projects/rocprofiler-systems/docker/Dockerfile.ubuntu @@ -0,0 +1,67 @@ + +ARG DISTRO +ARG VERSION +FROM ${DISTRO}:${VERSION} + +ENV HOME /root +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US +ENV LC_ALL C +ENV SHELL /bin/bash +ENV BASH_ENV /etc/bash.bashrc +ENV DEBIAN_FRONTEND noninteractive + +WORKDIR /tmp +SHELL [ "/bin/bash", "-c" ] + +ARG EXTRA_PACKAGES="" +ARG ROCM_VERSION="0.0" +ENV PATH ${HOME}/.local/bin:${PATH} + +RUN apt-get update && \ + apt-get dist-upgrade -y && \ + apt-get install -y apt-utils autoconf autotools-dev bash-completion bison \ + build-essential chrpath cmake curl flex gettext git-core gnupg2 iproute2 \ + libnuma1 libopenmpi-dev libpapi-dev libpfm4-dev librpm-dev libsqlite3-dev \ + libtool libudev1 lsb-release m4 python3-pip rpm texinfo wget && \ + OS_VERSION=$(cat /etc/os-release | grep VERSION_ID | sed 's/=/ /'1 | awk '{print $NF}' | sed 's/"//g') && \ + if [ "${OS_VERSION}" == "24.04" ]; then \ + python3 -m pip install --break-system-packages 'cmake==3.21'; \ + else \ + python3 -m pip install 'cmake==3.21'; \ + fi + +RUN ROCM_MAJOR=$(echo "${ROCM_VERSION}" | sed 's/\./ /g' | awk '{print $1}') && \ + ROCM_MINOR=$(echo "${ROCM_VERSION}" | sed 's/\./ /g' | awk '{print $2}') && \ + if [ "${ROCM_MAJOR}" != "0" ] || [ "${ROCM_MINOR}" != "0" ]; then \ + OS_VERSION=$(grep '^VERSION_ID=' /etc/os-release | cut -d'=' -f2 | tr -d '"') && \ + OS_CODENAME=$(grep '^VERSION_CODENAME=' /etc/os-release | cut -d'=' -f2) && \ + ROCM_PATCH=$(echo "${ROCM_VERSION}" | sed 's/\./ /g' | awk '{print $3}') && \ + if [ -z "${ROCM_PATCH}" ] || [ "${ROCM_PATCH}" = "0" ]; then \ + ROCM_PATCH=0 && \ + ROCM_VERSION=$(echo "${ROCM_VERSION}" | sed 's/\.0$//') \ + ; fi && \ + ROCM_VERSN=$(( ("${ROCM_MAJOR}"*10000)+("${ROCM_MINOR}"*100) + ("${ROCM_PATCH}"))) && \ + AMDGPU_DEB="amdgpu-install_${ROCM_MAJOR}.${ROCM_MINOR}.${ROCM_VERSN}-1_all.deb" && \ + wget https://repo.radeon.com/amdgpu-install/${ROCM_VERSION}/ubuntu/${OS_CODENAME}/${AMDGPU_DEB} && \ + apt-get install -y ./${AMDGPU_DEB} && \ + apt-get update && \ + apt-get install -y rocm-dev rccl-dev libpciaccess0 ${EXTRA_PACKAGES} && \ + apt-get autoclean; \ + fi + +ARG PYTHON_VERSIONS="6 7 8 9 10 11 12 13" + +RUN wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh -O miniforge.sh && \ + bash miniforge.sh -b -p /opt/conda && \ + export PATH="/opt/conda/bin:${PATH}" && \ + conda config --set always_yes yes --set changeps1 no && \ + conda update -c conda-forge -n base conda && \ + for i in ${PYTHON_VERSIONS}; do conda create -n py3.${i} -c conda-forge python=3.${i} pip; done && \ + for i in ${PYTHON_VERSIONS}; do /opt/conda/envs/py3.${i}/bin/python -m pip install numpy perfetto dataclasses; done && \ + conda clean -a -y && \ + conda init + +ENV LC_ALL C.UTF-8 +WORKDIR /home +SHELL [ "/bin/bash", "--login", "-c" ] diff --git a/projects/rocprofiler-systems/docker/Dockerfile.ubuntu.ci b/projects/rocprofiler-systems/docker/Dockerfile.ubuntu.ci new file mode 100644 index 0000000000..4e8df50917 --- /dev/null +++ b/projects/rocprofiler-systems/docker/Dockerfile.ubuntu.ci @@ -0,0 +1,56 @@ + +ARG DISTRO +ARG VERSION +FROM ${DISTRO}:${VERSION} + +ENV HOME /root +ENV LANG C.UTF-8 +ENV SHELL /bin/bash +ENV BASH_ENV /etc/bash.bashrc +ENV DEBIAN_FRONTEND noninteractive + +WORKDIR /tmp +SHELL [ "/bin/bash", "-c" ] + +ARG EXTRA_PACKAGES="" +ARG ELFUTILS_DOWNLOAD_VERSION="0.188" +ARG BOOST_DOWNLOAD_VERSION="1.79.0" +ARG NJOBS="8" + + +ENV PATH /usr/local/bin:${PATH} +ENV LIBRARY_PATH /usr/local/lib:/usr/local/lib64:${LIBRARY_PATH} +ENV LD_LIBRARY_PATH /usr/local/lib:/usr/local/lib64:${LD_LIBRARY_PATH} +ENV CMAKE_PREFIX_PATH /usr/local:${CMAKE_PREFIX_PATH} + +RUN apt-get update && \ + apt-get dist-upgrade -y && \ + apt-get install -y autoconf autotools-dev bash-completion bison build-essential \ + bzip2 chrpath cmake curl environment-modules flex gettext git-core gnupg2 \ + gzip iproute2 libiberty-dev libpapi-dev libpfm4-dev libsqlite3-dev libtool \ + locales lsb-release m4 python3-pip texinfo unzip wget vim zip zlib1g-dev && \ + apt-get autoclean && \ + if [ "${OS_VERSION}" == "24.04" ]; then \ + python3 -m pip install --break-system-packages 'cmake==3.21' perfetto \ + else \ + python3 -m pip install 'cmake==3.21' perfetto; \ + fi + +ARG PYTHON_VERSIONS="6 7 8 9 10 11 12 13" + +RUN wget https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh -O miniforge.sh && \ + bash miniforge.sh -b -p /opt/conda && \ + export PATH="/opt/conda/bin:${PATH}" && \ + conda config --set always_yes yes --set changeps1 no && \ + conda update -c conda-forge -n base conda && \ + for i in ${PYTHON_VERSIONS}; do conda create -n py3.${i} -c conda-forge python=3.${i} pip numpy; done && \ + for i in ${PYTHON_VERSIONS}; do /opt/conda/envs/py3.${i}/bin/python -m pip install numpy perfetto dataclasses; done && \ + conda clean -a -y && \ + cd /tmp && \ + shopt -s dotglob extglob && \ + rm -rf * + + +ENV LC_ALL C.UTF-8 +WORKDIR /home +SHELL [ "/bin/bash", "--login", "-c" ] diff --git a/projects/rocprofiler-systems/docker/build-docker-ci.sh b/projects/rocprofiler-systems/docker/build-docker-ci.sh new file mode 100755 index 0000000000..e6694351b8 --- /dev/null +++ b/projects/rocprofiler-systems/docker/build-docker-ci.sh @@ -0,0 +1,171 @@ +#!/usr/bin/env bash + +set -e + +: ${USER:=$(whoami)} +: ${DISTRO:=ubuntu} +: ${VERSIONS:=20.04} +: ${NJOBS=$(nproc)} +: ${ELFUTILS_VERSION:=0.186} +: ${BOOST_VERSION:=1.79.0} +: ${PYTHON_VERSIONS:="6 7 8 9 10 11 12 13"} +: ${PUSH:=0} +: ${PULL:=--pull} + +verbose-run() +{ + echo -e "\n### Executing \"${@}\"... ###\n" + eval $@ +} + +tolower() +{ + echo "$@" | awk -F '\\|~\\|' '{print tolower($1)}'; +} + +toupper() +{ + echo "$@" | awk -F '\\|~\\|' '{print toupper($1)}'; +} + +usage() +{ + print_option() { printf " --%-20s %-24s %s\n" "${1}" "${2}" "${3}"; } + echo "Options:" + print_option "help -h" "" "This message" + print_option "push" "" "Push the container to DockerHub when completed" + print_option "no-pull" "" "Do not pull down most recent base container" + + echo "" + print_default_option() { printf " --%-20s %-24s %s (default: %s)\n" "${1}" "${2}" "${3}" "$(tolower ${4})"; } + print_default_option distro "[ubuntu|opensuse|rhel]" "OS distribution" "${DISTRO}" + print_default_option versions "[VERSION] [VERSION...]" "Ubuntu, OpenSUSE, or RHEL release" "${VERSIONS}" + print_default_option python-versions "[VERSION] [VERSION...]" "Python 3 minor releases" "${PYTHON_VERSIONS}" + print_default_option "jobs -j" "[N]" "parallel build jobs" "${NJOBS}" + print_default_option elfutils-version "[0.183..0.188]" "ElfUtils version" "${ELFUTILS_VERSION}" + print_default_option boost-version "[1.67.0..1.79.0]" "Boost version" "${BOOST_VERSION}" + print_default_option user "[USERNAME]" "DockerHub username" "${USER}" +} + +send-error() +{ + usage + echo -e "\nError: ${@}" + exit 1 +} + +reset-last() +{ + last() { send-error "Unsupported argument :: ${1}"; } +} + +reset-last + +n=0 +while [[ $# -gt 0 ]] +do + case "${1}" in + -h|--help) + usage + exit 0 + ;; + "--distro") + shift + DISTRO=${1} + last() { DISTRO="${DISTRO} ${1}"; } + ;; + "--versions") + shift + VERSIONS=${1} + last() { VERSIONS="${VERSIONS} ${1}"; } + ;; + "--python-versions") + shift + PYTHON_VERSIONS=${1} + last() { PYTHON_VERSIONS="${PYTHON_VERSIONS} ${1}"; } + ;; + --jobs|-j) + shift + NJOBS=${1} + reset-last + ;; + "--elfutils-version") + shift + ELFUTILS_VERSION=${1} + reset-last + ;; + "--boost-version") + shift + BOOST_VERSION=${1} + reset-last + ;; + --user|-u) + shift + USER=${1} + reset-last + ;; + "--push") + PUSH=1 + reset-last + ;; + "--no-pull") + PULL="" + reset-last + ;; + --*) + reset-last + last ${1} + ;; + *) + last ${1} + ;; + esac + n=$((${n} + 1)) + shift +done + +DOCKER_FILE=Dockerfile.${DISTRO}.ci + +if [ ! -f ${DOCKER_FILE} ]; then cd docker; fi + +if [ ! -f ${DOCKER_FILE} ]; then + echo "Error! Execute script from source directory" + exit 1 +fi + +verbose-run rm -rf ./dyninst-source +verbose-run cp -r ../external/dyninst ./dyninst-source +verbose-run rm -rf ./dyninst-source/{build,install}* + +set -e + +if [ "${DISTRO}" = "opensuse" ]; then + DISTRO_IMAGE="opensuse/leap" +elif [ "${DISTRO}" = "rhel" ]; then + DISTRO_IMAGE="rockylinux/rockylinux" +else + DISTRO_IMAGE=${DISTRO} +fi + +for VERSION in ${VERSIONS} +do + verbose-run docker build . \ + ${PULL} \ + -f ${DOCKER_FILE} \ + --tag ${USER}/rocprofiler-systems:ci-base-${DISTRO}-${VERSION} \ + --build-arg DISTRO=${DISTRO_IMAGE} \ + --build-arg VERSION=${VERSION} \ + --build-arg NJOBS=${NJOBS} \ + --build-arg PYTHON_VERSIONS=\"${PYTHON_VERSIONS}\" \ + --build-arg ELFUTILS_DOWNLOAD_VERSION=${ELFUTILS_VERSION} \ + --build-arg BOOST_DOWNLOAD_VERSION=${BOOST_VERSION} +done + +if [ "${PUSH}" -gt 0 ]; then + for VERSION in ${VERSIONS} + do + verbose-run docker push ${USER}/rocprofiler-systems:ci-base-${DISTRO}-${VERSION} + done +fi + +verbose-run rm -rf ./dyninst-source diff --git a/projects/rocprofiler-systems/docker/build-docker-release.sh b/projects/rocprofiler-systems/docker/build-docker-release.sh new file mode 100755 index 0000000000..30d1ca700d --- /dev/null +++ b/projects/rocprofiler-systems/docker/build-docker-release.sh @@ -0,0 +1,175 @@ +#!/bin/bash -e + +if [ ! -f CMakeLists.txt ]; then + if [ ! -f ../CMakeLists.txt ]; then + echo "Error! Execute script from source directory" + exit 1 + else + cd .. + fi +fi + +set -e + +tolower() +{ + echo "$@" | awk -F '\\|~\\|' '{print tolower($1)}'; +} + +toupper() +{ + echo "$@" | awk -F '\\|~\\|' '{print toupper($1)}'; +} + +usage() +{ + print_option() { printf " --%-20s %-24s %s\n" "${1}" "${2}" "${3}"; } + echo "Options:" + print_option "help -h" "" "This message" + + echo "" + print_default_option() { printf " --%-20s %-24s %s (default: %s)\n" "${1}" "${2}" "${3}" "$(tolower ${4})"; } + print_default_option distro "[ubuntu|opensuse|rhel]" "OS distribution" "${DISTRO}" + print_default_option versions "[VERSION] [VERSION...]" "Ubuntu or OpenSUSE release" "${VERSIONS}" + print_default_option rocm-versions "[VERSION] [VERSION...]" "ROCm versions" "${ROCM_VERSIONS}" + print_default_option python-versions "[VERSION] [VERSION...]" "Python 3 minor releases" "${PYTHON_VERSIONS}" + print_default_option "user -u" "[USERNAME]" "DockerHub username" "${USER}" + print_default_option "retry -r" "[N]" "Number of attempts to build (to account for network errors)" "${RETRY}" + + echo "" + echo "Usage: ${BASH_SOURCE[0]} -- " + echo " e.g:" + echo " ${BASH_SOURCE[0]} --distro ubuntu --versions 20.04 --rocm-versions 5.0 5.1 -- --core +nopython --rocm-mpi +nopython" + echo " ${BASH_SOURCE[0]} --distro ubuntu --versions 20.04 --python-version 6 7 8 9 10 -- --rocm +python --rocm-mpi +nopython" +} + +send-error() +{ + usage + echo -e "\nError: ${@}" + exit 1 +} + +verbose-run() +{ + echo -e "\n### Executing \"${@}\" a maximum of ${RETRY} times... ###\n" + for i in $(seq 1 1 ${RETRY}) + do + set +e + eval "${@}" + local RETC=$? + set -e + if [ "${RETC}" -eq 0 ]; then + break + else + echo -en "\n### Command failed with error code ${RETC}... " + if [ "${i}" -ne "${RETRY}" ]; then + echo -e "Retrying... ###\n" + sleep 3 + else + echo -e "Exiting... ###\n" + exit ${RETC} + fi + fi + done +} + +build-release() +{ + CONTAINER=$1 + OS=$2 + ROCM_VERSION=$3 + CODE_VERSION=$4 + shift + shift + shift + shift + local DOCKER_ARGS="" + tty -s && DOCKER_ARGS="-it" || DOCKER_ARGS="" + verbose-run docker run ${DOCKER_ARGS} --rm -v ${PWD}:/home/rocprofiler-systems --stop-signal "SIGINT" --env DISTRO=${OS} --env ROCM_VERSION=${ROCM_VERSION} --env VERSION=${CODE_VERSION} --env PYTHON_VERSIONS=\"${PYTHON_VERSIONS}\" --env IS_DOCKER=1 ${CONTAINER} /home/rocprofiler-systems/scripts/build-release.sh ${@} +} + +reset-last() +{ + last() { send-error "Unsupported argument :: ${1}"; } +} + +reset-last + +: ${USER:=$(whoami)} +: ${DISTRO:=ubuntu} +: ${VERSIONS:=22.04 20.04} +: ${ROCM_VERSIONS:=5.0 4.5 4.3} +: ${MPI:=0} +: ${PYTHON_VERSIONS:="6 7 8 9 10 11 12 13"} +: ${RETRY:=3} + +n=0 +while [[ $# -gt 0 ]] +do + case "${1}" in + -h|--help) + usage + exit 0 + ;; + "--distro") + shift + DISTRO=${1} + last() { DISTRO="${DISTRO} ${1}"; } + ;; + "--versions") + shift + VERSIONS=${1} + last() { VERSIONS="${VERSIONS} ${1}"; } + ;; + "--rocm-versions") + shift + ROCM_VERSIONS=${1} + last() { ROCM_VERSIONS="${ROCM_VERSIONS} ${1}"; } + ;; + "--python-versions") + shift + PYTHON_VERSIONS=${1} + last() { PYTHON_VERSIONS="${PYTHON_VERSIONS} ${1}"; } + ;; + --user|-u) + shift + USER=${1} + reset-last + ;; + --retry|-r) + shift + RETRY=${1} + reset-last + ;; + "--") + shift + SCRIPT_ARGS=${@} + break + ;; + *) + last ${1} + ;; + esac + n=$((${n} + 1)) + shift +done + +CODE_VERSION=$(cat VERSION) + +if [ "${RETRY}" -lt 1 ]; then + RETRY=1 +fi + +if [ "${DISTRO}" = "rhel" ]; then + SCRIPT_ARGS="${SCRIPT_ARGS} --static-libstdcxx off" +fi + +for VERSION in ${VERSIONS} +do + TAG=${DISTRO}-${VERSION} + for ROCM_VERSION in ${ROCM_VERSIONS} + do + build-release ${USER}/rocprofiler-systems:release-base-${TAG}-rocm-${ROCM_VERSION} ${DISTRO}-${VERSION} ${ROCM_VERSION} ${CODE_VERSION} ${SCRIPT_ARGS} + done +done diff --git a/projects/rocprofiler-systems/docker/build-docker.sh b/projects/rocprofiler-systems/docker/build-docker.sh new file mode 100755 index 0000000000..c0b172118b --- /dev/null +++ b/projects/rocprofiler-systems/docker/build-docker.sh @@ -0,0 +1,363 @@ +#!/usr/bin/env bash + +set-user-defaults() +{ + : ${USER:=$(whoami)} + : ${ROCM_VERSIONS:="6.3"} + : ${DISTRO:=ubuntu} + : ${VERSIONS:=20.04} + : ${PYTHON_VERSIONS:="6 7 8 9 10 11 12 13"} + : ${BUILD_CI:=""} + : ${PUSH:=0} + : ${PULL:=--pull} + : ${RETRY:=3} + : ${SCRIPT_DIR=$(dirname "$(readlink -f "${BASH_SOURCE[0]:-$0}")")} +} + +set-user-defaults + +set -e + +cd $(dirname ${SCRIPT_DIR}) + +declare -a MATRIX_DISTROS=() +declare -a MATRIX_VERSIONS=() +declare -a MATRIX_ROCM_VERSIONS=() + +load-matrix() +{ + local workflow_file=".github/workflows/containers.yml" + if [ ! -f "${workflow_file}" ]; then + echo -e "\n Error: Cannot find ${workflow_file}" + exit 1 + fi + + # In form os-distro;os-version;rocm-version + local matrix_data=$(awk ' + /rocprofiler-systems-release:/, /steps:/ { + if (/- os-distro:/) { + gsub(/[[:space:]]*- os-distro:[[:space:]]*"/, "") + gsub(/"/, "") + distro = $0 + } + if (/os-version:/) { + gsub(/[[:space:]]*os-version:[[:space:]]*"/, "") + gsub(/"/, "") + version = $0 + } + if (/rocm-version:/) { + gsub(/[[:space:]]*rocm-version:[[:space:]]*"/, "") + gsub(/"/, "") + rocm = $0 + printf "%s;%s;%s\n", distro, version, rocm + } + } + ' "${workflow_file}") + + while IFS=';' read -r os_distro os_version rocm_version; do + MATRIX_DISTROS+=("$os_distro") + MATRIX_VERSIONS+=("$os_version") + MATRIX_ROCM_VERSIONS+=("$rocm_version") + done <<< "$matrix_data" +} + +validate-distro() +{ + local distro="${1}" + + if [ -n "${distro}" ]; then + distro=$(tolower "${distro}") + case "${distro}" in + ubuntu|opensuse|rhel) + ;; + *) + send-error "Unsupported distribution '${distro}'" "Supported distributions: ubuntu, opensuse, rhel" + ;; + esac + fi +} + +show-matrix() +{ + local filter_distro="${1:-}" + + if [ -n "${filter_distro}" ]; then + validate-distro "${filter_distro}" + filter_distro=$(tolower "${filter_distro}") + fi + + echo "" + if [ -n "${filter_distro}" ]; then + echo " Supported ${filter_distro} + ROCm Combinations " + echo " ==============================================" + else + echo " Supported OS + ROCm Combinations " + echo " ==========================================" + fi + echo "" + echo " OS Distribution Version ROCm Version" + echo " ---------------- ------- ------------" + + for i in "${!MATRIX_DISTROS[@]}"; do + if [[ -z "${filter_distro}" || "${MATRIX_DISTROS[i]}" == "${filter_distro}" ]]; then + printf " %-16s %-9s %s\n" "${MATRIX_DISTROS[i]}" "${MATRIX_VERSIONS[i]}" "${MATRIX_ROCM_VERSIONS[i]}" + fi + done + + echo "" + echo "ROCm '0.0' means no ROCm installation (CPU-only build)" + echo "" + echo "Note: Patch versions are also supported (See: https://repo.radeon.com/amdgpu-install/)" + echo "" +} + +# Cross checks arguments against compatibility matrix (ignores ROCm patch version) +validate-combinations() +{ + # Check OS version combinations + for VERSION in ${VERSIONS}; do + VERSION_MAJOR=$(echo ${VERSION} | sed 's/\./ /g' | awk '{print $1}') + VERSION_MINOR=$(echo ${VERSION} | sed 's/\./ /g' | awk '{print $2}') + + local os_version_valid=0 + for i in "${!MATRIX_DISTROS[@]}"; do + if [[ "${MATRIX_DISTROS[i]}" == "${DISTRO}" && \ + "${MATRIX_VERSIONS[i]}" == "${VERSION}" ]]; then + os_version_valid=1 + break + fi + done + + if [ ${os_version_valid} -eq 0 ]; then + send-error "Unsupported OS version :: ${VERSION}. See compatibility matrix for supported versions." + fi + done + + # Check ROCm version combinations + for VERSION in ${VERSIONS}; do + for ROCM_VERSION in ${ROCM_VERSIONS}; do + local valid=0 + ROCM_MAJOR=$(echo ${ROCM_VERSION} | sed 's/\./ /g' | awk '{print $1}') + ROCM_MINOR=$(echo ${ROCM_VERSION} | sed 's/\./ /g' | awk '{print $2}') + ROCM_MAJOR_MINOR="${ROCM_MAJOR}.${ROCM_MINOR}" + if ! ([ "${ROCM_MAJOR_MINOR}" == "0.0" ] && [ "${ROCM_VERSION}" != "0.0" ]); then + for i in "${!MATRIX_DISTROS[@]}"; do + if [[ "${MATRIX_DISTROS[i]}" == "${DISTRO}" && \ + "${MATRIX_VERSIONS[i]}" == "${VERSION}" && \ + "${MATRIX_ROCM_VERSIONS[i]}" == "${ROCM_MAJOR_MINOR}" ]]; then + valid=1 + break + fi + done + fi + + if [ ${valid} -eq 0 ]; then + send-error "Unsupported combination :: ${DISTRO}-${VERSION} + ROCm ${ROCM_VERSION}. See compatibility matrix for supported versions." + fi + done + done +} + +tolower() +{ + echo "$@" | awk -F '\\|~\\|' '{print tolower($1)}'; +} + +toupper() +{ + echo "$@" | awk -F '\\|~\\|' '{print toupper($1)}'; +} + +usage() +{ + set-user-defaults + print_option() { printf " --%-20s %-24s %s\n" "${1}" "${2}" "${3}"; } + echo "Options:" + print_option "help -h" "" "This message" + print_option "no-pull" "" "Do not pull down most recent base container" + print_option "matrix -m" "[ubuntu|opensuse|rhel]" "Shows compatibility matrix" + + echo "" + print_default_option() { printf " --%-20s %-24s %s (default: %s)\n" "${1}" "${2}" "${3}" "$(tolower ${4})"; } + print_default_option distro "[ubuntu|opensuse|rhel]" "OS distribution" "${DISTRO}" + print_default_option versions "[VERSION] [VERSION...]" "Ubuntu, OpenSUSE, or RHEL release" "${VERSIONS}" + print_default_option rocm-versions "[VERSION] [VERSION...]" "ROCm versions (format: Major.Minor.Patch, patch defaults to 0 if not specified)" "${ROCM_VERSIONS}" + print_default_option python-versions "[VERSION] [VERSION...]" "Python 3 minor releases" "${PYTHON_VERSIONS}" + print_default_option "user -u" "[USERNAME]" "DockerHub username" "${USER}" + print_default_option "retry -r" "[N]" "Number of attempts to build (to account for network errors)" "${RETRY}" + print_default_option push "" "Push the image to Dockerhub" "" + #print_default_option lto "[on|off]" "Enable LTO" "${LTO}" +} + +send-error() +{ + usage + echo -e "\nError: ${@}" + exit 1 +} + +verbose-run() +{ + echo -e "\n### Executing \"${@}\"... ###\n" + eval "${@}" +} + +verbose-build() +{ + echo -e "\n### Executing \"${@}\" a maximum of ${RETRY} times... ###\n" + for i in $(seq 1 1 ${RETRY}) + do + set +e + eval "${@}" + local RETC=$? + set -e + if [ "${RETC}" -eq 0 ]; then + break + else + echo -en "\n### Command failed with error code ${RETC}... " + if [ "${i}" -ne "${RETRY}" ]; then + echo -e "Retrying... ###\n" + sleep 3 + else + echo -e "Exiting... ###\n" + exit ${RETC} + fi + fi + done +} + +reset-last() +{ + last() { send-error "Unsupported argument :: ${1}"; } +} + +reset-last +load-matrix +n=0 +while [[ $# -gt 0 ]] +do + case "${1}" in + -h|--help) + usage + exit 0 + ;; + -m|--matrix) + shift + if [[ $# -gt 0 && ! "${1}" =~ ^-- ]]; then + show-matrix "${1}" + else + show-matrix + fi + exit 0 + ;; + "--distro") + shift + DISTRO=$(tolower ${1}) + last() { DISTRO="${DISTRO} $(tolower${1})"; } + ;; + "--versions") + shift + VERSIONS=${1} + last() { VERSIONS="${VERSIONS} ${1}"; } + ;; + "--rocm-versions") + shift + ROCM_VERSIONS=${1} + last() { ROCM_VERSIONS="${ROCM_VERSIONS} ${1}"; } + ;; + "--python-versions") + shift + PYTHON_VERSIONS=${1} + last() { PYTHON_VERSIONS="${PYTHON_VERSIONS} ${1}"; } + ;; + --user|-u) + shift + USER=${1} + reset-last + ;; + --push) + PUSH=1 + reset-last + ;; + --no-pull) + PULL="" + reset-last + ;; + --retry|-r) + shift + RETRY=${1} + reset-last + ;; + "--*") + send-error "Unsupported argument at position $((${n} + 1)) :: ${1}" + ;; + *) + last ${1} + ;; + esac + n=$((${n} + 1)) + shift +done + +# Validate input parameters for os-distros and rocm-versions +validate-distro +validate-combinations + +DOCKER_FILE="Dockerfile.${DISTRO}" + +if [ "${RETRY}" -lt 1 ]; then + RETRY=1 +fi + +if [ -n "${BUILD_CI}" ]; then DOCKER_FILE="${DOCKER_FILE}.ci"; fi +cd docker # Forced since PWD is parent dir +if [ ! -f ${DOCKER_FILE} ]; then send-error "File \"${DOCKER_FILE}\" not found"; fi + +for VERSION in ${VERSIONS} +do + VERSION_MAJOR=$(echo ${VERSION} | sed 's/\./ /g' | awk '{print $1}') + VERSION_MINOR=$(echo ${VERSION} | sed 's/\./ /g' | awk '{print $2}') + VERSION_PATCH=$(echo ${VERSION} | sed 's/\./ /g' | awk '{print $3}') + for ROCM_VERSION in ${ROCM_VERSIONS} + do + ROCM_MAJOR=$(echo ${ROCM_VERSION} | sed 's/\./ /g' | awk '{print $1}') + ROCM_MINOR=$(echo ${ROCM_VERSION} | sed 's/\./ /g' | awk '{print $2}') + ROCM_PATCH=$(echo ${ROCM_VERSION} | sed 's/\./ /g' | awk '{print $3}') + if [ "${ROCM_PATCH}" = "0" ] || [ -z "${ROCM_PATCH}" ]; then + CONTAINER=${USER}/rocprofiler-systems:release-base-${DISTRO}-${VERSION}-rocm-${ROCM_MAJOR}.${ROCM_MINOR} + else + CONTAINER=${USER}/rocprofiler-systems:release-base-${DISTRO}-${VERSION}-rocm-${ROCM_VERSION} + fi + if [ "${DISTRO}" = "ubuntu" ]; then + case "${VERSION}" in + 24.04) + ROCM_REPO_DIST="noble" + ;; + 22.04) + ROCM_REPO_DIST="jammy" + ;; + 20.04) + ROCM_REPO_DIST="focal" + ;; + *) + ;; + esac + verbose-build docker build . ${PULL} --progress plain -f ${DOCKER_FILE} --tag ${CONTAINER} --build-arg DISTRO=${DISTRO} --build-arg VERSION=${VERSION} --build-arg ROCM_VERSION=${ROCM_VERSION} --build-arg PYTHON_VERSIONS=\"${PYTHON_VERSIONS}\" + elif [ "${DISTRO}" = "rhel" ]; then + # use Rocky Linux as a base image for RHEL builds + DISTRO_BASE_IMAGE=rockylinux/rockylinux + verbose-build docker build . ${PULL} --progress plain -f ${DOCKER_FILE} --tag ${CONTAINER} --build-arg DISTRO=${DISTRO_BASE_IMAGE} --build-arg VERSION=${VERSION} --build-arg ROCM_VERSION=${ROCM_VERSION} --build-arg PYTHON_VERSIONS=\"${PYTHON_VERSIONS}\" + elif [ "${DISTRO}" = "opensuse" ]; then + DISTRO_IMAGE="opensuse/leap" + if [[ "${VERSION_MAJOR}" -le 15 && "${VERSION_MINOR}" -le 5 ]]; then + PERL_REPO="15.6" + else + PERL_REPO="${VERSION_MAJOR}.${VERSION_MINOR}" + fi + verbose-build docker build . ${PULL} --progress plain -f ${DOCKER_FILE} --tag ${CONTAINER} --build-arg DISTRO=${DISTRO_IMAGE} --build-arg VERSION=${VERSION} --build-arg ROCM_VERSION=${ROCM_VERSION} --build-arg PERL_REPO=${PERL_REPO} --build-arg PYTHON_VERSIONS=\"${PYTHON_VERSIONS}\" + fi + if [ "${PUSH}" -ne 0 ]; then + docker push ${CONTAINER} + fi + done +done diff --git a/projects/rocprofiler-systems/docker/entrypoint-rhel.sh b/projects/rocprofiler-systems/docker/entrypoint-rhel.sh new file mode 100755 index 0000000000..06bac7124d --- /dev/null +++ b/projects/rocprofiler-systems/docker/entrypoint-rhel.sh @@ -0,0 +1,14 @@ +#!/bin/bash -l + +if [ -f /etc/profile.d/modules.sh ]; then + source /etc/profile.d/modules.sh + module load mpi &> /dev/null +fi + +if [ -z "${1}" ]; then + : ${SHELL:=/bin/bash} + exec ${SHELL} +else + set -e + eval $@ +fi diff --git a/projects/rocprofiler-systems/docker/test-docker-release.sh b/projects/rocprofiler-systems/docker/test-docker-release.sh new file mode 100755 index 0000000000..ac1b7c3fa8 --- /dev/null +++ b/projects/rocprofiler-systems/docker/test-docker-release.sh @@ -0,0 +1,126 @@ +#!/usr/bin/env bash + +if [ ! -f CMakeLists.txt ]; then + if [ ! -f ../CMakeLists.txt ]; then + echo "Error! Execute script from source directory" + exit 1 + else + cd .. + fi +fi + +set -e + +tolower() +{ + echo "$@" | awk -F '\\|~\\|' '{print tolower($1)}'; +} + +toupper() +{ + echo "$@" | awk -F '\\|~\\|' '{print toupper($1)}'; +} + +usage() +{ + print_option() { printf " --%-20s %-24s %s\n" "${1}" "${2}" "${3}"; } + echo "Options:" + print_option "help -h" "" "This message" + + echo "" + print_default_option() { printf " --%-20s %-24s %s (default: %s)\n" "${1}" "${2}" "${3}" "$(tolower ${4})"; } + print_default_option distro "[ubuntu|opensuse]" "OS distribution" "${DISTRO}" + print_default_option versions "[VERSION] [VERSION...]" "Ubuntu or OpenSUSE release" "${VERSIONS}" + print_default_option rocm-versions "[VERSION] [VERSION...]" "ROCm versions" "${ROCM_VERSIONS}" + print_default_option user "[USERNAME]" "DockerHub username" "${USER}" + + echo "" + echo "Usage: ${BASH_SOURCE[0]} -- " + echo " e.g:" + echo " ${BASH_SOURCE[0]} --distro ubuntu --versions 20.04 --rocm-versions 5.0 5.1 -- --stgz /path/to/stgz/installer" +} + +send-error() +{ + echo -e "\nError: ${@}" + exit 1 +} + +verbose-run() +{ + echo -e "\n### Executing \"${@}\"... ###\n" + exec "${@}" +} + +test-release() +{ + CONTAINER=${1} + shift + local DOCKER_ARGS="" + tty -s && DOCKER_ARGS="-it" || DOCKER_ARGS="" + verbose-run docker run ${DOCKER_ARGS} --rm -v ${PWD}:/home/rocprofiler-systems ${CONTAINER} /home/rocprofiler-systems/scripts/test-release.sh ${@} +} + +reset-last() +{ + last() { send-error "Unsupported argument :: ${1}"; } +} + +reset-last + +: ${USER:=$(whoami)} +: ${DISTRO:=ubuntu} +: ${VERSIONS:=22.04 20.04} +: ${ROCM_VERSIONS:=6.2} + +n=0 +while [[ $# -gt 0 ]] +do + case "${1}" in + -h|--help) + usage + exit 0 + ;; + "--distro") + shift + DISTRO=${1} + last() { DISTRO="${DISTRO} ${1}"; } + ;; + "--versions") + shift + VERSIONS=${1} + last() { VERSIONS="${VERSIONS} ${1}"; } + ;; + "--rocm-versions") + shift + ROCM_VERSIONS=${1} + last() { ROCM_VERSIONS="${ROCM_VERSIONS} ${1}"; } + ;; + --user|-u) + shift + USER=${1} + reset-last + ;; + "--") + shift + SCRIPT_ARGS=${@} + break + ;; + *) + last ${1} + ;; + esac + n=$((${n} + 1)) + shift +done + +CODE_VERSION=$(cat VERSION) + +for VERSION in ${VERSIONS} +do + TAG=${DISTRO}-${VERSION} + for ROCM_VERSION in ${ROCM_VERSIONS} + do + test-release ${USER}/rocprofiler-systems:release-base-${TAG}-rocm-${ROCM_VERSION} ${SCRIPT_ARGS} + done +done diff --git a/projects/rocprofiler-systems/docs/.gitignore b/projects/rocprofiler-systems/docs/.gitignore new file mode 100644 index 0000000000..8fca1b7979 --- /dev/null +++ b/projects/rocprofiler-systems/docs/.gitignore @@ -0,0 +1,2 @@ +_build/ +_doxygen/ \ No newline at end of file diff --git a/projects/rocprofiler-systems/docs/conceptual/data-collection-modes.rst b/projects/rocprofiler-systems/docs/conceptual/data-collection-modes.rst new file mode 100644 index 0000000000..42ef5c8365 --- /dev/null +++ b/projects/rocprofiler-systems/docs/conceptual/data-collection-modes.rst @@ -0,0 +1,147 @@ +.. meta:: + :description: ROCm Systems Profiler data collection modes documentation + :keywords: rocprof-sys, rocprofiler-systems, Omnitrace, ROCm, profiler, data collection, tracking, visualization, tool, Instinct, accelerator, AMD + +********************** +Data collection modes +********************** + +ROCm Systems Profiler supports several modes of recording trace and profiling data for your application. + +.. note:: + + For an explanation of the terms used in this topic, see + the :doc:`ROCm Systems Profiler glossary <../reference/rocprof-sys-glossary>`. + ++-----------------------------+---------------------------------------------------------+ +| Mode | Description | ++=============================+=========================================================+ +| Binary Instrumentation | Locates functions (and loops, if desired) in the binary | +| | and inserts snippets at the entry and exit | ++-----------------------------+---------------------------------------------------------+ +| Statistical Sampling | Periodically pauses application at specified intervals | +| | and records various metrics for the given call stack | ++-----------------------------+---------------------------------------------------------+ +| Callback APIs | Parallelism frameworks such as ROCm, OpenMP, and Kokkos | +| | make callbacks into ROCm Systems Profiler to provide | +| | information about the work the API is performing | ++-----------------------------+---------------------------------------------------------+ +| Dynamic Symbol Interception | Wrap function symbols defined in a position independent | +| | dynamic library/executable, like ``pthread_mutex_lock`` | +| | in ``libpthread.so`` or ``MPI_Init`` in the MPI library | ++-----------------------------+---------------------------------------------------------+ +| User API | User-defined regions and controls for ROCm Systems | +| | Profiler | ++-----------------------------+---------------------------------------------------------+ + +The two most generic and important modes are binary instrumentation and statistical sampling. +It is important to understand their advantages and disadvantages. +Binary instrumentation and statistical sampling can be performed with the ``rocprof-sys-instrument`` +executable. For statistical sampling, it's highly recommended to use the +``rocprof-sys-sample`` executable instead if binary instrumentation isn't required or needed. +Callback APIs and dynamic symbol interception can be utilized with either tool. + +Binary instrumentation +----------------------------------- + +Binary instrumentation lets you record deterministic measurements for +every single invocation of a given function. +Binary instrumentation effectively adds instructions to the target application to +collect the required information. It therefore has the potential to cause performance +changes which might, in some cases, lead to inaccurate results. The effect depends on +the information being collected and which features are activated in ROCm Systems Profiler. +For example, collecting only the wall-clock timing data +has less of an effect than collecting the wall-clock timing, CPU-clock timing, +memory usage, cache-misses, and number of instructions that were run. Similarly, +collecting a flat profile has less overhead than a hierarchical profile +and collecting a trace OR a profile has less overhead than collecting a +trace AND a profile. + +In ROCm Systems Profiler, the primary heuristic for controlling the overhead with binary +instrumentation is the minimum number of instructions for selecting functions +for instrumentation. + +Statistical sampling +----------------------------------- + +Statistical call-stack sampling periodically interrupts the application at +regular intervals using operating system interrupts. +Sampling is typically less numerically accurate and specific, but the +target program runs at nearly full speed. +In contrast to the data derived from binary instrumentation, the resulting +data is not exact but is instead a statistical approximation. +However, sampling often provides a more accurate picture of the application +execution because it is less intrusive to the target application and has fewer +side effects on memory caches or instruction decoding pipelines. Furthermore, +because sampling does not affect the execution speed as much, is it +relatively immune to over-evaluating the cost of small, frequently called +functions or "tight" loops. + +In ROCm Systems Profiler, the overhead for statistical sampling depends on the +sampling rate and whether the samples are taken with respect to the CPU time +and/or real time. + +Binary instrumentation vs. statistical sampling example +------------------------------------------------------- + +Consider the following code: + +.. code-block:: c++ + + long fib(long n) + { + if(n < 2) return n; + return fib(n - 1) + fib(n - 2); + } + + void run(long n) + { + long result = fib(n); + printf("[%li] fibonacci(%li) = %li\n", i, n, result); + } + + int main(int argc, char** argv) + { + long nfib = 30; + long nitr = 10; + if(argc > 1) nfib = atol(argv[1]); + if(argc > 2) nitr = atol(argv[2]); + + for(long i = 0; i < nitr; ++i) + run(nfib); + + return 0; + } + +Binary instrumentation of the ``fib`` function will record **every single invocation** +of the function. For a very small function +such as ``fib``, this results in **significant** overhead since this simple function +takes about 20 instructions, whereas the entry and +exit snippets are ~1024 instructions. Therefore, you generally want to avoid +instrumenting functions where the instrumented function has significantly fewer +instructions than entry and exit instrumentation. (Note that many of the +instructions in entry and exit functions are either logging functions or +depend on the runtime settings and thus might never run). However, +due to the number of potential instructions in the entry and exit snippets, +the default behavior of ``rocprof-sys-instrument`` is to only instrument functions +which contain at least 1024 instructions. + +However, recording every single invocation of the function can be extremely +useful for detecting anomalies, such as profiles that show minimum or maximum values much smaller or larger +than the average or a high standard deviation. In this case, the traces help you +identify exactly when and where those instances deviated from the norm. +Compare the level of detail in the following traces. In the top image, +every instance of the ``fib`` function is instrumented, while in the bottom image, +the ``fib`` call-stack is derived via sampling. + +Binary instrumentation of the Fibonacci function +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. image:: ../data/fibonacci-instrumented.png + :alt: Visualization of the output of a binary instrumentation of the Fibonacci function + +Statistical sampling of the Fibonacci function +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. image:: ../data/fibonacci-sampling.png + :alt: Visualization of the output of a statistical sample of the Fibonacci function diff --git a/projects/rocprofiler-systems/docs/conceptual/rocprof-sys-feature-set.rst b/projects/rocprofiler-systems/docs/conceptual/rocprof-sys-feature-set.rst new file mode 100644 index 0000000000..8aac222869 --- /dev/null +++ b/projects/rocprofiler-systems/docs/conceptual/rocprof-sys-feature-set.rst @@ -0,0 +1,137 @@ +.. meta:: + :description: ROCm Systems Profiler feature set documentation and reference + :keywords: rocprof-sys, rocprofiler-systems, Omnitrace, ROCm, profiler, feature set, use cases, tracking, visualization, tool, Instinct, accelerator, AMD + +******************************************** +ROCm Systems Profiler features and use cases +******************************************** + +`ROCm Systems Profiler `_ is designed to be highly extensible. +Internally, it leverages the `Timemory performance analysis toolkit `_ +to manage extensions, resources, data, and other items. It supports the following features, +modes, metrics, and APIs. + +Data collection modes +======================================== + +* Dynamic instrumentation + + * Runtime instrumentation: Instrument executables and shared libraries at runtime + * Binary rewriting: Generate a new executable and/or library with instrumentation built-in + +* Statistical sampling: Periodic software interrupts per-thread +* Process-level sampling: A background thread records process-, system- and device-level metrics while the application runs +* Causal profiling: Quantifies the potential impact of optimizations in parallel code + +Data analysis +======================================== + +* High-level summary profiles with mean, min, max, and standard deviation statistics + + * Low overhead and memory efficient + * Ideal for running at scale + +* Comprehensive traces for every individual event and measurement +* Application speed-up predictions resulting from potential optimizations in functions and lines of code based on causal profiling + +Parallelism API support +======================================== + +* HIP +* HSA +* Pthreads +* MPI +* Kokkos-Tools (KokkosP) +* OpenMP-Tools (OMPT) + +GPU metrics +======================================== + +* GPU hardware counters +* HIP API tracing +* HIP kernel tracing +* HSA API tracing +* HSA operation tracing +* rocDecode API tracing +* rocJPEG API tracing +* System-level sampling (via AMD-SMI) + + * Memory usage + * Power usage + * Temperature + * Utilization + * VCN activity + * JPEG activity + Note: The availability of VCN and JPEG engine activity depends on device support for different ASICs. If unsupported, all values for VCN_ACTIVITY and JPEG_ACTIVITY will be reported as N/A in the output of amd-smi metric--usage. + +CPU metrics +======================================== + +* CPU hardware counters sampling and profiles +* CPU frequency sampling +* Various timing metrics + + * Wall time + * CPU time (process and thread) + * CPU utilization (process and thread) + * User CPU time + * Kernel CPU time + +* Various memory metrics + + * High-water mark (sampling and profiles) + * Memory page allocation + * Virtual memory usage + +* Network statistics +* I/O metrics +* Many others + +Third-party API support +======================================== + +* TAU +* LIKWID +* Caliper +* CrayPAT +* VTune +* NVTX +* ROCTX + +ROCm Systems Profiler use cases +======================================== + +When analyzing the performance of an application, do NOT +assume you know where the performance bottlenecks are +and why they are happening. ROCm Systems Profiler is a tool for analyzing the entire +application and its performance. It is +ideal for characterizing where optimization would have the greatest impact +on an end-to-end run of the application and for +viewing what else is happening on the system during a performance bottleneck. + +When GPUs are involved, there is a tendency to assume that +the quickest path to performance improvement is minimizing +the runtime of the GPU kernels. This is a highly flawed assumption. +If you optimize the runtime of a kernel from one millisecond +to 1 microsecond (1000x speed-up) but the original application never +spent time waiting for kernels to complete, +there would be no statistically significant reduction in the end-to-end +runtime of your application. In other words, it does not matter +how fast or slow the code on GPU is if the application has a +bottleneck on waiting on the GPU. + +Use ROCm Systems Profiler to obtain a high-level view of the entire application. Use it +to determine where the performance bottlenecks are and +obtain clues to why these bottlenecks are happening. Rather than worrying about kernel +performance, start your investigation with ROCm Systems Profiler, which characterizes the +broad picture. + +.. note:: + + For insight into the execution of individual kernels on the GPU, + use `ROCm Compute Profiler `_. + +In terms of CPU analysis, ROCm Systems Profiler does not target any specific vendor. +It works just as well on AMD and non-AMD CPUs. +With regard to the GPU, ROCm Systems Profiler is currently restricted to HIP and HSA APIs +and kernels running on AMD GPUs. diff --git a/projects/rocprofiler-systems/docs/conf.py b/projects/rocprofiler-systems/docs/conf.py new file mode 100644 index 0000000000..2ea3c2ce70 --- /dev/null +++ b/projects/rocprofiler-systems/docs/conf.py @@ -0,0 +1,56 @@ +# MIT License + +# Copyright (c) 2023 - 2025 Advanced Micro Devices, Inc. All rights reserved. + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +import re + +from rocm_docs import ROCmDocs + +with open("../VERSION", encoding="utf-8") as f: + match = re.search(r"([0-9.]+)[^0-9.]+", f.read()) + if not match: + raise ValueError("VERSION not found!") + version_number = match[1] + +external_projects_current_project = "rocprofiler-systems" + +project = "rocprofiler-systems" +author = "Advanced Micro Devices, Inc." +copyright = "Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved." +version = version_number +release = version_number +html_title = f"ROCm Systems Profiler {version} documentation" + +external_toc_path = "./sphinx/_toc.yml" + +docs_core = ROCmDocs(html_title) +docs_core.setup() +docs_core.run_doxygen(doxygen_root="doxygen", doxygen_path="doxygen/xml") +docs_core.enable_api_reference() + +for sphinx_var in ROCmDocs.SPHINX_VARS: + globals()[sphinx_var] = getattr(docs_core, sphinx_var) diff --git a/projects/rocprofiler-systems/docs/data/causal-foobar.png b/projects/rocprofiler-systems/docs/data/causal-foobar.png new file mode 100644 index 0000000000..a887b126ae Binary files /dev/null and b/projects/rocprofiler-systems/docs/data/causal-foobar.png differ diff --git a/projects/rocprofiler-systems/docs/data/fibonacci-instrumented.png b/projects/rocprofiler-systems/docs/data/fibonacci-instrumented.png new file mode 100644 index 0000000000..95502062be Binary files /dev/null and b/projects/rocprofiler-systems/docs/data/fibonacci-instrumented.png differ diff --git a/projects/rocprofiler-systems/docs/data/fibonacci-sampling.png b/projects/rocprofiler-systems/docs/data/fibonacci-sampling.png new file mode 100644 index 0000000000..d6da81138c Binary files /dev/null and b/projects/rocprofiler-systems/docs/data/fibonacci-sampling.png differ diff --git a/projects/rocprofiler-systems/docs/data/pre-commit-hook.png b/projects/rocprofiler-systems/docs/data/pre-commit-hook.png new file mode 100644 index 0000000000..c362611d5c Binary files /dev/null and b/projects/rocprofiler-systems/docs/data/pre-commit-hook.png differ diff --git a/projects/rocprofiler-systems/docs/data/rocprof-sys-gpu-metrics.png b/projects/rocprofiler-systems/docs/data/rocprof-sys-gpu-metrics.png new file mode 100644 index 0000000000..366d35858c Binary files /dev/null and b/projects/rocprofiler-systems/docs/data/rocprof-sys-gpu-metrics.png differ diff --git a/projects/rocprofiler-systems/docs/data/rocprof-sys-jpeg-activity.png b/projects/rocprofiler-systems/docs/data/rocprof-sys-jpeg-activity.png new file mode 100644 index 0000000000..823cd847f7 Binary files /dev/null and b/projects/rocprofiler-systems/docs/data/rocprof-sys-jpeg-activity.png differ diff --git a/projects/rocprofiler-systems/docs/data/rocprof-sys-perfetto-nic-trace.png b/projects/rocprofiler-systems/docs/data/rocprof-sys-perfetto-nic-trace.png new file mode 100644 index 0000000000..1e252d5ee9 Binary files /dev/null and b/projects/rocprofiler-systems/docs/data/rocprof-sys-perfetto-nic-trace.png differ diff --git a/projects/rocprofiler-systems/docs/data/rocprof-sys-perfetto.png b/projects/rocprofiler-systems/docs/data/rocprof-sys-perfetto.png new file mode 100644 index 0000000000..21f1325cac Binary files /dev/null and b/projects/rocprofiler-systems/docs/data/rocprof-sys-perfetto.png differ diff --git a/projects/rocprofiler-systems/docs/data/rocprof-sys-rocdecode.png b/projects/rocprofiler-systems/docs/data/rocprof-sys-rocdecode.png new file mode 100644 index 0000000000..5948be502a Binary files /dev/null and b/projects/rocprofiler-systems/docs/data/rocprof-sys-rocdecode.png differ diff --git a/projects/rocprofiler-systems/docs/data/rocprof-sys-rocm-flow.png b/projects/rocprofiler-systems/docs/data/rocprof-sys-rocm-flow.png new file mode 100644 index 0000000000..ee188b455a Binary files /dev/null and b/projects/rocprofiler-systems/docs/data/rocprof-sys-rocm-flow.png differ diff --git a/projects/rocprofiler-systems/docs/data/rocprof-sys-rocm.png b/projects/rocprofiler-systems/docs/data/rocprof-sys-rocm.png new file mode 100644 index 0000000000..8f80ae6a8a Binary files /dev/null and b/projects/rocprofiler-systems/docs/data/rocprof-sys-rocm.png differ diff --git a/projects/rocprofiler-systems/docs/data/rocprof-sys-user-api.png b/projects/rocprofiler-systems/docs/data/rocprof-sys-user-api.png new file mode 100644 index 0000000000..e1d748a5fd Binary files /dev/null and b/projects/rocprofiler-systems/docs/data/rocprof-sys-user-api.png differ diff --git a/projects/rocprofiler-systems/docs/data/rocprof-sys-vcn-activity.png b/projects/rocprofiler-systems/docs/data/rocprof-sys-vcn-activity.png new file mode 100644 index 0000000000..92efad77b0 Binary files /dev/null and b/projects/rocprofiler-systems/docs/data/rocprof-sys-vcn-activity.png differ diff --git a/projects/rocprofiler-systems/docs/doxygen/.gitignore b/projects/rocprofiler-systems/docs/doxygen/.gitignore new file mode 100644 index 0000000000..0719ebc385 --- /dev/null +++ b/projects/rocprofiler-systems/docs/doxygen/.gitignore @@ -0,0 +1,3 @@ +html/ +latex/ +xml/ \ No newline at end of file diff --git a/projects/rocprofiler-systems/docs/doxygen/Doxyfile b/projects/rocprofiler-systems/docs/doxygen/Doxyfile new file mode 100644 index 0000000000..10e383354d --- /dev/null +++ b/projects/rocprofiler-systems/docs/doxygen/Doxyfile @@ -0,0 +1,373 @@ +# Doxyfile 1.8.20 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = rocprofiler-systems +PROJECT_NUMBER = 1.11.3 +PROJECT_BRIEF = "High-level and comprehensive application tracing and profiling on both the CPU and GPU" +PROJECT_LOGO = +OUTPUT_DIRECTORY = . +CREATE_SUBDIRS = NO +ALLOW_UNICODE_NAMES = YES +OUTPUT_LANGUAGE = English +OUTPUT_TEXT_DIRECTION = None +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = YES +INLINE_INHERITED_MEMB = YES +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = /home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-rocprofiler-systems/checkouts/ +STRIP_FROM_INC_PATH = /home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-rocprofiler-systems/checkouts/ +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +JAVADOC_BANNER = NO +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = YES +PYTHON_DOCSTRING = YES +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 4 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +OPTIMIZE_OUTPUT_SLICE = NO +EXTENSION_MAPPING = hpp=C++ \ + cpp=C++ \ + hh=C++ \ + cc=C++ \ + h=C \ + c=C \ + py=Python +MARKDOWN_SUPPORT = YES +TOC_INCLUDE_HEADINGS = 2 +AUTOLINK_SUPPORT = YES +BUILTIN_STL_SUPPORT = YES +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +GROUP_NESTED_COMPOUNDS = YES +SUBGROUPING = YES +INLINE_GROUPED_CLASSES = NO +INLINE_SIMPLE_STRUCTS = YES +TYPEDEF_HIDES_STRUCT = NO +LOOKUP_CACHE_SIZE = 5 +NUM_PROC_THREADS = 0 +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_PRIV_VIRTUAL = NO +EXTRACT_PACKAGE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = NO +HIDE_SCOPE_NAMES = NO +HIDE_COMPOUND_REFERENCE= NO +SHOW_INCLUDE_FILES = YES +SHOW_GROUPED_MEMB_INC = NO +FORCE_LOCAL_INCLUDES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_MEMBERS_CTORS_1ST = YES +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +STRICT_PROTO_MATCHING = NO +GENERATE_TODOLIST = NO +GENERATE_TESTLIST = NO +GENERATE_BUGLIST = NO +GENERATE_DEPRECATEDLIST= NO +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +LAYOUT_FILE = +CITE_BIB_FILES = +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = YES +WARN_AS_ERROR = YES +WARN_FORMAT = "---> WARNING! $file:$line: $text" +WARN_LOGFILE = doc/warnings.log +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = ../../README.md \ + ../../source/lib/rocprof-sys-user/rocprofiler-systems/types.h \ + ../../source/lib/rocprof-sys-user/rocprofiler-systems/categories.h \ + ../../source/lib/rocprof-sys-user/rocprofiler-systems/user.h \ + ../../source/lib/rocprof-sys-user/rocprofiler-systems/causal.h +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.h \ + *.hh \ + *.hpp \ + *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.icc \ + *.tcc \ + *.py +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = YES +EXCLUDE_PATTERNS = */.git/* \ + ../../external/* \ + ../../examples/* \ + ../../tests/* +EXCLUDE_SYMBOLS = "std::*" \ + "ROCPROFSYS_ATTRIBUTE" \ + "ROCPROFSYS_VISIBILITY" \ + "ROCPROFSYS_PUBLIC_API" \ + "ROCPROFSYS_HIDDEN_API" \ + "SpaceHandle" \ + "KokkosPDevice*" +EXAMPLE_PATH = ../../examples +EXAMPLE_PATTERNS = *.h \ + *.hh \ + *.hpp \ + *.c \ + *.cc \ + *.cpp \ + *.py \ + *.txt +EXAMPLE_RECURSIVE = YES +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +FILTER_SOURCE_PATTERNS = +USE_MDFILE_AS_MAINPAGE = ../../README.md +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = YES +STRIP_CODE_COMMENTS = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = YES +SOURCE_TOOLTIPS = YES +USE_HTAGS = NO +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = ../_doxygen/header.html +HTML_FOOTER = ../_doxygen/footer.html +HTML_STYLESHEET = ../_doxygen/stylesheet.css +HTML_EXTRA_STYLESHEET = ../_doxygen/extra_stylesheet.css +HTML_EXTRA_FILES = +HTML_COLORSTYLE_HUE = 220 +HTML_COLORSTYLE_SAT = 100 +HTML_COLORSTYLE_GAMMA = 80 +HTML_TIMESTAMP = YES +HTML_DYNAMIC_MENUS = YES +HTML_DYNAMIC_SECTIONS = YES +HTML_INDEX_NUM_ENTRIES = 1000 +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.rocprofiler-systems +DOCSET_PUBLISHER_ID = org.doxygen.amd +DOCSET_PUBLISHER_NAME = "Advanced Micro Devices, Inc." +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = YES +GENERATE_QHP = NO +QCH_FILE = +QHP_NAMESPACE = +QHP_VIRTUAL_FOLDER = doc +QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = +QHG_LOCATION = +GENERATE_ECLIPSEHELP = NO +ECLIPSE_DOC_ID = org.doxygen.rocprofiler-systems +DISABLE_INDEX = NO +GENERATE_TREEVIEW = NO +ENUM_VALUES_PER_LINE = 1 +TREEVIEW_WIDTH = 300 +EXT_LINKS_IN_WINDOW = YES +HTML_FORMULA_FORMAT = png +FORMULA_FONTSIZE = 12 +FORMULA_TRANSPARENT = YES +FORMULA_MACROFILE = +USE_MATHJAX = NO +MATHJAX_FORMAT = HTML-CSS +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest +MATHJAX_EXTENSIONS = +MATHJAX_CODEFILE = +SEARCHENGINE = NO +SERVER_BASED_SEARCH = NO +EXTERNAL_SEARCH = NO +SEARCHENGINE_URL = +SEARCHDATA_FILE = searchdata.xml +EXTERNAL_SEARCH_ID = +EXTRA_SEARCH_MAPPINGS = +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +LATEX_MAKEINDEX_CMD = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = float +LATEX_HEADER = +LATEX_FOOTER = +LATEX_EXTRA_STYLESHEET = +LATEX_EXTRA_FILES = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = YES +LATEX_HIDE_INDICES = NO +LATEX_SOURCE_CODE = YES +LATEX_BIB_STYLE = plain +LATEX_TIMESTAMP = NO +LATEX_EMOJI_DIRECTORY = +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +RTF_SOURCE_CODE = NO +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_SUBDIR = +MAN_LINKS = YES +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = YES +XML_OUTPUT = xml +XML_PROGRAMLISTING = YES +XML_NS_MEMB_FILE_SCOPE = YES +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- +GENERATE_DOCBOOK = NO +DOCBOOK_OUTPUT = docbook +DOCBOOK_PROGRAMLISTING = NO +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = ../../source/lib/rocprof-sys-user +INCLUDE_FILE_PATTERNS = *.h \ + *.hpp +PREDEFINED = ROCPROFSYS_PUBLIC_API= \ + ROCPROFSYS_HIDDEN_API= \ + "ROCPROFSYS_ATTRIBUTE(...)=" \ + "ROCPROFSYS_VISIBILITY(...)=" \ + "__attribute__(x)=" \ + "__declspec(x)=" \ + "size_t=unsigned long" \ + "uintptr_t=unsigned long" \ + DOXYGEN_SHOULD_SKIP_THIS +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = NO +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = html/tagfile.xml +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +EXTERNAL_PAGES = YES +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +DIA_PATH = +HIDE_UNDOC_RELATIONS = NO +HAVE_DOT = NO +DOT_NUM_THREADS = 0 +DOT_FONTNAME = Helvetica +DOT_FONTSIZE = 12 +DOT_FONTPATH = +CLASS_GRAPH = NO +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = YES +UML_LIMIT_NUM_FIELDS = 10 +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = svg +INTERACTIVE_SVG = YES +DOT_PATH = /usr/bin/dot +DOTFILE_DIRS = +MSCFILE_DIRS = +DIAFILE_DIRS = +PLANTUML_JAR_PATH = +PLANTUML_CFG_FILE = +PLANTUML_INCLUDE_PATH = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = YES +GENERATE_LEGEND = YES +DOT_CLEANUP = YES diff --git a/projects/rocprofiler-systems/docs/how-to/configuring-runtime-options.rst b/projects/rocprofiler-systems/docs/how-to/configuring-runtime-options.rst new file mode 100644 index 0000000000..59c1b9099e --- /dev/null +++ b/projects/rocprofiler-systems/docs/how-to/configuring-runtime-options.rst @@ -0,0 +1,1411 @@ +.. meta:: + :description: ROCm Systems Profiler runtime options documentation and reference + :keywords: rocprof-sys, rocprofiler-systems, Omnitrace, ROCm, runtime options, profiler, tracking, visualization, tool, Instinct, accelerator, AMD + +**************************************************** +Configuring runtime options +**************************************************** + +The ``rocprof-sys.cfg`` file maintains a list of the +`ROCm Systems Profiler `_ runtime +options. To create this configuration +file and view the current runtime options, use the ``rocprof-sys-avail`` executable. + +The rocprof-sys-avail executable +======================================== + +The ``rocprof-sys-avail`` executable provides information about the runtime settings, +data collection capabilities, and, when built with PAPI support, the +available hardware counters. The executable is effectively +self-updating. As new capabilities and settings are added to the ROCm Systems Profiler source code, they are +propagated to ``rocprof-sys-avail``. ``rocprof-sys-avail`` should be viewed as the ultimate authority +in the event of any conflicts with this documentation. + +It is recommended that you create a default configuration file in +``${HOME}/.rocprof-sys.cfg``. This can be done by +running the command ``rocprof-sys-avail -G ~/.rocprof-sys.cfg``. Alternatively, +use the ``rocprof-sys-avail -G ~/.rocprof-sys.cfg --all`` option +for a verbose configuration file with descriptions, categories, and additional information. + +Modify ``${HOME}/.rocprof-sys.cfg`` as required. For example, enable `Perfetto `_, +`Timemory `_, sampling, and process-level sampling by default +and tweak the default sampling values. + +.. code-block:: shell + + # ... + ROCPROFSYS_TRACE = true + ROCPROFSYS_PROFILE = true + ROCPROFSYS_USE_SAMPLING = true + ROCPROFSYS_USE_PROCESS_SAMPLING = true + # ... + ROCPROFSYS_SAMPLING_FREQ = 50 + ROCPROFSYS_SAMPLING_CPUS = all + ROCPROFSYS_SAMPLING_GPUS = $env:HIP_VISIBLE_DEVICES + +Use the configuration file +----------------------------------- + +Tell rocprof-systems to use the modified settings by creating the environment variable ``ROCPROFSYS_CONFIG_FILE`` + +.. code-block:: shell + + export ROCPROFSYS_CONFIG_FILE=~/.rocprof-sys.cfg + +See :ref:`creating a configuration file` for more details. + +Exploring runtime settings +----------------------------------- + +Use the following command to view the list of the available runtime settings, their current values, and descriptions +for each setting: + +.. code-block:: shell + + rocprof-sys-avail --description + +.. note:: + + Use ``--brief`` to suppress printing the current value and/or ``-c 0`` to suppress truncation of the descriptions. + +Any Boolean setting (``rocprof-sys-avail --settings --value --brief --filter bool``) +accepts a case insensitive match for nearly all common Boolean logic expressions: +``ON``, ``OFF``, ``YES``, ``NO``, ``TRUE``, ``FALSE``, ``0``, ``1``, etc. + +Exploring components +----------------------------------- + +ROCm Systems Profiler uses `Timemory `_ extensively to provide +various capabilities and manage +data and resources. By default, with ``ROCPROFSYS_PROFILE=ON``, ROCm Systems Profiler only collects wall-clock +timing values. However, by modifying the ``ROCPROFSYS_TIMEMORY_COMPONENTS`` setting, +ROCm Systems Profiler can be configured to +collect hardware counters, CPU-clock timers, memory usage, context switches, page faults, network statistics, +and much more. ROCm Systems Profiler can even be used as a dynamic instrumentation vehicle +for other third-party profiling +APIs such as `Caliper `_ and `LIKWID `_. +To leverage this capability, build ROCm Systems Profiler from source with the CMake +options ``TIMEMORY_USE_CALIPER=ON`` or ``TIMEMORY_USE_LIKWID=ON`` and then add +``caliper_marker``, ``likwid_marker``, or both to ``ROCPROFSYS_TIMEMORY_COMPONENTS``. + +To view all possible components and their descriptions: + +.. code-block:: shell + + rocprof-sys-avail --components --description + +To restrict the output to available components and view the string identifiers for ``ROCPROFSYS_TIMEMORY_COMPONENTS``: + +.. code-block:: shell + + rocprof-sys-avail --components --available --string --brief + +Exploring hardware counters +----------------------------------- + +ROCm Systems Profiler supports hardware counter collection via PAPI and ROCm. +Generally, PAPI is used to collect CPU-based hardware counters and ROCm is used to collect GPU-based hardware +counters. Although it is possible to install PAPI with ROCm support and use it to +collect GPU-based hardware counters, this is not recommended because PAPI +cannot simultaneously collect CPU and GPU hardware counters. + +To view all possible hardware counters and their descriptions, use the following command: + +.. code-block:: shell + + rocprof-sys-avail --hw-counters --description + +Appending the ``-c CPU`` option restricts the list of hardware counters to +those available through PAPI, while ``-c GPU`` limits the list to those available from ROCm. + +Enabling hardware counters +----------------------------------- + +PAPI Hardware counters are configured with the ``ROCPROFSYS_PAPI_EVENTS`` configuration variable. +ROCm Hardware counters are configured with the ``ROCPROFSYS_ROCM_EVENTS`` configuration variable. +ROCm hardware counters also require the ``ROCPROFSYS_USE_ROCPROFILER`` configuration +variable to be enabled using ``ROCPROFSYS_USE_ROCPROFILER=ON``. + +Here is a sample configuration for hardware counters: + +.. code-block:: shell + + # using papi identifiers + ROCPROFSYS_PAPI_EVENTS = PAPI_TOT_CYC PAPI_TOT_INS + + # using perf identifiers + ROCPROFSYS_PAPI_EVENTS = perf::INSTRUCTIONS perf::CACHE-REFERENCES perf::CACHE-MISSES + +.. _rocprof-sys_papi_events: + +ROCPROFSYS_PAPI_EVENTS +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In order to collect the majority of hardware counters via PAPI, ensure the ``/proc/sys/kernel/perf_event_paranoid`` +has a value <= 2. If you have ``sudo`` access, use the following command to modify the value: + +.. code-block:: shell + + echo 0 | sudo tee /proc/sys/kernel/perf_event_paranoid + +However this value is not retained upon reboot. +Use the following command to preserve this setting after a reboot: + +.. code-block:: shell + + echo 'kernel.perf_event_paranoid=0' | sudo tee -a /etc/sysctl.conf + +PAPI events use a concept similar to a namespace. All specified hardware +counters must be from the same namespace. +For hardware counters starting with the ``PAPI_`` prefix, these are high-level +aggregates of multiple hardware counters. +Otherwise, most events use two or three colons (``::`` or ``:::``) between the +component name and the counter name, for example, +``amd64_rapl::RAPL_ENERGY_PKG`` and ``perf::PERF_COUNT_HW_CPU_CYCLES``. + +For example, the following is a valid configuration: + +.. code-block:: shell + + ROCPROFSYS_PAPI_EVENTS = perf::INSTRUCTIONS perf::CACHE-REFERENCES perf::CACHE-MISSES + +However, the following specification of a roughly equivalent set of hardware counters is an incorrect configuration because it mixes +PAPI components from different namespaces: + +.. code-block:: shell + + ROCPROFSYS_PAPI_EVENTS = PAPI_TOT_INS perf::CACHE-REFERENCES perf::CACHE-MISSES + +.. note:: + + If ROCm Systems Profiler was configured with the default ``ROCPROFSYS_BUILD_PAPI=ON`` setting, + standard PAPI command-line tools such as + ``papi_avail`` and ``papi_event_chooser`` are not able to provide information + about the PAPI library used by ROCm Systems Profiler + (because ROCm Systems Profiler statically links to ``libpapi``). However, all of these tools are + installed with the prefix ``rocprof-sys-`` with + underscores replaced with hyphens, for example ``papi_avail`` becomes ``rocprof-sys-papi-avail``. + +ROCPROFSYS_ROCM_EVENTS +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +ROCm Systems Profiler reads the ROCm events from the ``${ROCM_PATH}/lib/rocprofiler/metrics.xml`` +file. Use the ``ROCP_METRICS`` environment +variable to point ROCm Systems Profiler to a different XML metrics file, for example, +``export ROCP_METRICS=${PWD}/custom_metrics.xml``. +``rocprof-sys-avail -H -c GPU`` shows event names with a suffix of ``:device=N`` +where ``N`` is the device number. +For example, if you have two devices, the output is: + +.. code-block:: shell + + | Wavefronts:device=0 | Derived counter: SQ_WAVES | + ... + | Wavefronts:device=1 | Derived counter: SQ_WAVES | + +To collect the event on all devices, specify the event, +such as ``Wavefronts``, without the ``:device=`` suffix. +To collect the event only on specific devices, use the ``:device=`` suffix. + +The following example: + +* Records the percentage of time the GPU was busy on all devices +* Counts the number of waves sent to SQs on device 0 +* Counts the number of VALU instructions issued on device 1 + +.. code-block:: shell + + ROCPROFSYS_ROCM_EVENTS = GPUBusy SQ_WAVES:device=0 SQ_INSTS_VALU:device=1 + +Exploring GPU Metrics +--------------------- + +ROCm Systems Profiler supports GPU metrics collection, sampling, and API tracing via `ROCprofiler-SDK `_ and `AMD-SMI `_. +ROCprofiler-SDK supports application tracing to provide a big picture of the GPU application execution and kernel profiling to provide low-level hardware details from the performance counters. +The AMD-SMI library offers a unified tool for managing, monitoring, and retrieving information about the system's drivers and GPUs. + +Sampling GPU metrics like utilization, temperature, power consumption, memory usage, etc., can be configured with ``ROCPROFSYS_AMD_SMI_METRICS``. +The ``ROCPROFSYS_USE_AMD_SMI`` setting should be enabled for GPU metric collection. + +For example, the following is a valid configuration: + +.. code-block:: shell + + ROCPROFSYS_AMD_SMI_METRICS=busy,temp,power,vcn_activity,mem_usage + +Supported values for ``ROCPROFSYS_AMD_SMI_METRICS`` are: ``busy``, ``temp``, ``power``, ``vcn_activity``, ``mem_usage``, ``jpeg_activity``. + +API tracing is configured with the ``ROCPROFSYS_ROCM_DOMAINS`` setting. The domains are used to filter the events that are captured during profiling. +Supported values for this setting are those supported by ROCprofiler-SDK, which are returned by the API ``get_callback_tracing_names()`` and ``get_buffer_tracing_names()``. See the `ROCprofiler-SDK developer API documentation `_ to learn more about ROCprofiler-SDK APIs. +Use the following command to view the available domains: + +.. code-block:: shell + + rocprof-sys-avail -bd -r ROCM_DOMAINS + +.. note:: + +Some settings can enable tracing for multiple domains, such as ``hip_api`` which will enable both ``hip_runtime_api`` and ``hip_compiler_api``. +And ``hsa_api`` which will enable all hsa domains, ``hsa_core_api``, ``hsa_amd_ext_api``, ``hsa_image_exit_api``, ``hsa_finalize_ext_api``. +The setting ``marker_api`` or ``roctx`` can be used to enable the roctx marker API tracing. + +For example, the following is a valid configuration: + +.. code-block:: shell + + ROCPROFSYS_ROCM_DOMAINS=hip_runtime_api,kernel_dispatch,memory_copy,rocdecode_api,rocjpeg_api + +rocprof-sys-avail examples +----------------------------------- + +The following examples demonstrate how to use ``rocprof-sys-avail`` to perform several common +configuration tasks. + +Generating a default configuration file +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: shell + + $ rocprof-sys-avail -G ~/.rocprof-sys.cfg + [rocprof-sys-avail] Outputting text configuration file '/home/user/.rocprof-sys.cfg'... + $ cat ~/.rocprof-sys.cfg + # auto-generated by rocprof-sys-avail (version 1.2.0) on 2022-06-27 @ 19:15 + + ROCPROFSYS_CONFIG_FILE = + ROCPROFSYS_MODE = trace + ROCPROFSYS_TRACE = true + ROCPROFSYS_PROFILE = false + ROCPROFSYS_USE_SAMPLING = false + ROCPROFSYS_USE_PROCESS_SAMPLING = true + ROCPROFSYS_USE_ROCM = true + ROCPROFSYS_USE_AMD_SMI = true + ROCPROFSYS_USE_KOKKOSP = false + ROCPROFSYS_USE_CODE_COVERAGE = false + ROCPROFSYS_USE_PID = true + ROCPROFSYS_OUTPUT_PATH = rocprof-sys-%tag%-output + ROCPROFSYS_OUTPUT_PREFIX = + ROCPROFSYS_CI = false + ROCPROFSYS_THREAD_POOL_SIZE = 8 + ROCPROFSYS_DEBUG = false + ROCPROFSYS_DL_VERBOSE = 0 + ROCPROFSYS_INSTRUMENTATION_INTERVAL = 1 + ROCPROFSYS_KOKKOSP_KERNEL_LOGGER = false + ROCPROFSYS_PAPI_EVENTS = PAPI_TOT_CYC + ROCPROFSYS_PERFETTO_BACKEND = inprocess + ROCPROFSYS_PERFETTO_BUFFER_SIZE_KB = 1024000 + ROCPROFSYS_PERFETTO_COMBINE_TRACES = false + ROCPROFSYS_PERFETTO_FILE = perfetto-trace.proto + ROCPROFSYS_PERFETTO_FILL_POLICY = discard + ROCPROFSYS_PERFETTO_SHMEM_SIZE_HINT_KB = 4096 + ROCPROFSYS_SAMPLING_CPUS = + ROCPROFSYS_SAMPLING_DELAY = 0.5 + ROCPROFSYS_SAMPLING_FREQ = 10 + ROCPROFSYS_SAMPLING_GPUS = all + ROCPROFSYS_TIME_OUTPUT = true + ROCPROFSYS_TIMEMORY_COMPONENTS = wall_clock + ROCPROFSYS_TRACE_THREAD_LOCKS = false + ROCPROFSYS_VERBOSE = 0 + ROCPROFSYS_COLLAPSE_PROCESSES = false + ROCPROFSYS_COLLAPSE_THREADS = false + ROCPROFSYS_COUT_OUTPUT = false + ROCPROFSYS_CPU_AFFINITY = false + ROCPROFSYS_DIFF_OUTPUT = false + ROCPROFSYS_ENABLE_SIGNAL_HANDLER = true + ROCPROFSYS_ENABLED = true + ROCPROFSYS_FILE_OUTPUT = true + ROCPROFSYS_FLAT_PROFILE = false + ROCPROFSYS_INPUT_EXTENSIONS = json,xml + ROCPROFSYS_INPUT_PATH = + ROCPROFSYS_INPUT_PREFIX = + ROCPROFSYS_JSON_OUTPUT = true + ROCPROFSYS_MAX_DEPTH = 65535 + ROCPROFSYS_MAX_WIDTH = 120 + ROCPROFSYS_MEMORY_PRECISION = -1 + ROCPROFSYS_MEMORY_SCIENTIFIC = false + ROCPROFSYS_MEMORY_UNITS = MB + ROCPROFSYS_MEMORY_WIDTH = -1 + ROCPROFSYS_NETWORK_INTERFACE = + ROCPROFSYS_NODE_COUNT = 0 + ROCPROFSYS_PAPI_FAIL_ON_ERROR = false + ROCPROFSYS_PAPI_MULTIPLEXING = false + ROCPROFSYS_PAPI_OVERFLOW = 0 + ROCPROFSYS_PAPI_QUIET = false + ROCPROFSYS_PAPI_THREADING = true + ROCPROFSYS_PRECISION = -1 + ROCPROFSYS_SCIENTIFIC = false + ROCPROFSYS_STRICT_CONFIG = true + ROCPROFSYS_SUPPRESS_CONFIG = true + ROCPROFSYS_SUPPRESS_PARSING = true + ROCPROFSYS_TEXT_OUTPUT = true + ROCPROFSYS_TIME_FORMAT = %F_%H.%M + ROCPROFSYS_TIMELINE_PROFILE = false + ROCPROFSYS_TIMING_PRECISION = 6 + ROCPROFSYS_TIMING_SCIENTIFIC = false + ROCPROFSYS_TIMING_UNITS = sec + ROCPROFSYS_TIMING_WIDTH = -1 + ROCPROFSYS_TREE_OUTPUT = true + ROCPROFSYS_WIDTH = -1 + +When creating a new configuration file, the following recommendations apply: + +* Use the ``--all`` option to view all descriptions, choices, and other information in the configuration file. +* To create a new configuration without inheriting from an existing ``${HOME}/.rocprof-sys.cfg`` file, + set ``ROCPROFSYS_SUPPRESS_CONFIG=ON`` in the environment beforehand. +* To create a new configuration that makes minor changes to an existing configuration, + set ``ROCPROFSYS_CONFIG_FILE=/path/to/existing/file`` and define the changes as environment + variables before generating it. + +Viewing the setting descriptions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: shell + + $ rocprof-sys-avail -S -bd + |-----------------------------------------|-----------------------------------------| + | ENVIRONMENT VARIABLE | DESCRIPTION | + |-----------------------------------------|-----------------------------------------| + | ROCPROFSYS_CI | Enable some runtime validation check... | + | ROCPROFSYS_ADD_SECONDARY | Enable/disable components adding sec... | + | ROCPROFSYS_COLLAPSE_PROCESSES | Enable/disable combining process-spe... | + | ROCPROFSYS_COLLAPSE_THREADS | Enable/disable combining thread-spec... | + | ROCPROFSYS_CONFIG_FILE | Configuration file for rocprof-sys | + | ROCPROFSYS_COUT_OUTPUT | Write output to stdout | + | ROCPROFSYS_CPU_AFFINITY | Enable pinning threads to CPUs (Linu... | + | ROCPROFSYS_THREAD_POOL_SIZE | Number of threads to use when genera... | + | ROCPROFSYS_DEBUG | Enable debug output | + | ROCPROFSYS_DIFF_OUTPUT | Generate a difference output vs. a p... | + | ROCPROFSYS_DL_VERBOSE | Verbosity within the rocprof-sys-dl ... | + | ROCPROFSYS_ENABLED | Activation state of timemory | + | ROCPROFSYS_ENABLE_SIGNAL_HANDLER | Enable signals in timemory_init | + | ROCPROFSYS_FILE_OUTPUT | Write output to files | + | ROCPROFSYS_FLAT_PROFILE | Set the label hierarchy mode to defa... | + | ROCPROFSYS_INPUT_EXTENSIONS | File extensions used when searching ... | + | ROCPROFSYS_INPUT_PATH | Explicitly specify the input folder ... | + | ROCPROFSYS_INPUT_PREFIX | Explicitly specify the prefix for in... | + | ROCPROFSYS_INSTRUMENTATION_INTERVAL | Instrumentation only takes measureme... | + | ROCPROFSYS_JSON_OUTPUT | Write json output files | + | ROCPROFSYS_KOKKOSP_KERNEL_LOGGER | Enables kernel logging | + | ROCPROFSYS_MAX_DEPTH | Set the maximum depth of label hiera... | + | ROCPROFSYS_MAX_THREAD_BOOKMARKS | Maximum number of times a worker thr... | + | ROCPROFSYS_MAX_WIDTH | Set the maximum width for component ... | + | ROCPROFSYS_MEMORY_PRECISION | Set the precision for components wit... | + | ROCPROFSYS_MEMORY_SCIENTIFIC | Set the numerical reporting format f... | + | ROCPROFSYS_MEMORY_UNITS | Set the units for components with u... | + | ROCPROFSYS_MEMORY_WIDTH | Set the output width for components ... | + | ROCPROFSYS_NETWORK_INTERFACE | Default network interface | + | ROCPROFSYS_NODE_COUNT | Total number of nodes used in applic... | + | ROCPROFSYS_OUTPUT_FILE | Perfetto filename | + | ROCPROFSYS_OUTPUT_PATH | Explicitly specify the output folder... | + | ROCPROFSYS_OUTPUT_PREFIX | Explicitly specify a prefix for all ... | + | ROCPROFSYS_PAPI_EVENTS | PAPI presets and events to collect (... | + | ROCPROFSYS_PAPI_FAIL_ON_ERROR | Configure PAPI errors to trigger a r... | + | ROCPROFSYS_PAPI_MULTIPLEXING | Enable multiplexing when using PAPI | + | ROCPROFSYS_PAPI_OVERFLOW | Value at which PAPI hw counters trig... | + | ROCPROFSYS_PAPI_QUIET | Configure suppression of reporting P... | + | ROCPROFSYS_PAPI_THREADING | Enable multithreading support when u... | + | ROCPROFSYS_PERFETTO_BACKEND | Specify the perfetto backend to acti... | + | ROCPROFSYS_PERFETTO_BUFFER_SIZE_KB | Size of perfetto buffer (in KB) | + | ROCPROFSYS_PERFETTO_COMBINE_TRACES | Combine Perfetto traces. If not expl... | + | ROCPROFSYS_PERFETTO_FILL_POLICY | Behavior when perfetto buffer is ful... | + | ROCPROFSYS_PERFETTO_SHMEM_SIZE_HINT_KB | Hint for shared-memory buffer size i... | + | ROCPROFSYS_PRECISION | Set the global output precision for ... | + | ROCPROFSYS_SAMPLING_CPUS | CPUs to collect frequency informatio... | + | ROCPROFSYS_SAMPLING_DELAY | Number of seconds to wait before the... | + | ROCPROFSYS_SAMPLING_FREQ | Number of software interrupts per se... | + | ROCPROFSYS_SAMPLING_GPUS | Devices to query when ROCPROFSYS_USE... | + | ROCPROFSYS_SCIENTIFIC | Set the global numerical reporting t... | + | ROCPROFSYS_STRICT_CONFIG | Throw errors for unknown setting nam... | + | ROCPROFSYS_SUPPRESS_CONFIG | Disable processing of setting config... | + | ROCPROFSYS_SUPPRESS_PARSING | Disable parsing environment | + | ROCPROFSYS_TEXT_OUTPUT | Write text output files | + | ROCPROFSYS_TIMELINE_PROFILE | Set the label hierarchy mode to defa... | + | ROCPROFSYS_TIMEMORY_COMPONENTS | List of components to collect via ti... | + | ROCPROFSYS_TIME_FORMAT | Customize the folder generation when... | + | ROCPROFSYS_TIME_OUTPUT | Output data to subfolder w/ a timest... | + | ROCPROFSYS_TIMING_PRECISION | Set the precision for components wit... | + | ROCPROFSYS_TIMING_SCIENTIFIC | Set the numerical reporting format f... | + | ROCPROFSYS_TIMING_UNITS | Set the units for components with u... | + | ROCPROFSYS_TIMING_WIDTH | Set the output width for components ... | + | ROCPROFSYS_TRACE_THREAD_LOCKS | Enable tracking calls to pthread_mut... | + | ROCPROFSYS_TREE_OUTPUT | Write hierarchical json output files | + | ROCPROFSYS_USE_CODE_COVERAGE | Enable support for code coverage | + | ROCPROFSYS_USE_KOKKOSP | Enable support for Kokkos Tools | + | ROCPROFSYS_USE_OMPT | Enable support for OpenMP-Tools | + | ROCPROFSYS_TRACE | Enable perfetto backend | + | ROCPROFSYS_USE_PID | Enable tagging filenames with proces... | + | ROCPROFSYS_USE_AMD_SMI | Enable sampling GPU power, temp, uti... | + | ROCPROFSYS_USE_ROCM | Enable ROCM tracing | + | ROCPROFSYS_USE_SAMPLING | Enable statistical sampling of call-... | + | ROCPROFSYS_USE_PROCESS_SAMPLING | Enable a background thread which sam... | + | ROCPROFSYS_PROFILE | Enable timemory backend | + | ROCPROFSYS_VERBOSE | Verbosity level | + | ROCPROFSYS_WIDTH | Set the global output width for comp... | + |------------------------------------------|-----------------------------------------| + +Viewing components +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: shell + + $ rocprof-sys-avail -C -bd + |-----------------------------------|----------------------------------------------| + | COMPONENT | DESCRIPTION | + |-----------------------------------|----------------------------------------------| + | allinea_map | Controls the AllineaMAP sampler. | + | caliper_marker | Generic forwarding of markers to Caliper ... | + | caliper_config | Caliper configuration manager. | + | caliper_loop_marker | Variant of caliper_marker with support fo... | + | cpu_clock | Total CPU time spent in both user- and ke... | + | cpu_util | Percentage of CPU-clock time divided by w... | + | craypat_counters | Names and value of any counter events tha... | + | craypat_flush_buffer | Writes all the recorded contents in the d... | + | craypat_heap_stats | Undocumented by 'pat_api.h'. | + | craypat_record | Toggles CrayPAT recording on calling thread. | + | craypat_region | Adds region labels to CrayPAT output. | + | current_peak_rss | Absolute value of high-water mark of memo... | + | gperftools_cpu_profiler | Control switch for gperftools CPU profiler. | + | gperftools_heap_profiler | Control switch for the gperftools heap pr... | + | hip_event | Records the time interval between two poi... | + | kernel_mode_time | CPU time spent executing in kernel mode (... | + | likwid_marker | LIKWID perfmon (CPU) marker forwarding. | + | likwid_nvmarker | LIKWID nvmon (GPU) marker forwarding. | + | malloc_gotcha | GOTCHA wrapper for memory allocation func... | + | memory_allocations | Number of bytes allocated/freed instead o... | + | monotonic_clock | Wall-clock timer which will continue to i... | + | monotonic_raw_clock | Wall-clock timer unaffected by frequency ... | + | network_stats | Reports network bytes, packets, errors, d... | + | num_io_in | Number of times the filesystem had to per... | + | num_io_out | Number of times the filesystem had to per... | + | num_major_page_faults | Number of page faults serviced that requi... | + | num_minor_page_faults | Number of page faults serviced without an... | + | page_rss | Amount of memory allocated in pages of me... | + | papi_array<8ul> | Fixed-size array of PAPI HW counters. | + | papi_vector | Dynamically allocated array of PAPI HW co... | + | peak_rss | Measures changes in the high-water mark f... | + | perfetto_trace | Provides Perfetto Tracing SDK: system pro... | + | priority_context_switch | Number of context switch due to higher pr... | + | process_cpu_clock | CPU-clock timer for the calling process (... | + | process_cpu_util | Percentage of CPU-clock time divided by w... | + | read_bytes | Number of bytes which this process really... | + | read_char | Number of bytes which this task has cause... | + | roctx_marker | Generates high-level region markers for H... | + | system_clock | CPU time spent in kernel-mode. | + | tau_marker | Forwards markers to TAU instrumentation (... | + | thread_cpu_clock | CPU-clock timer for the calling thread. | + | thread_cpu_util | Percentage of CPU-clock time divided by w... | + | timestamp | Provides a timestamp for every sample and... | + | trip_count | Counts number of invocations. | + | user_clock | CPU time spent in user-mode. | + | user_mode_time | CPU time spent executing in user mode (vi... | + | virtual_memory | Records the change in virtual memory. | + | voluntary_context_switch | Number of context switches due to a proce... | + | vtune_event | Creates events for Intel profiler running... | + | vtune_frame | Creates frames for Intel profiler running... | + | vtune_profiler | Control switch for Intel profiler running... | + | wall_clock | Real-clock timer (i.e. wall-clock timer). | + | written_bytes | Number of bytes sent to the storage layer. | + | written_char | Number of bytes which this task has cause... | + | rocprof-sys | Invokes instrumentation functions rocprof... | + | sampling_wall_clock | Wall-clock timing. Derived from statistic... | + | sampling_cpu_clock | CPU-clock timing. Derived from statistica... | + | sampling_percent | Fraction of wall-clock time spent in func... | + | sampling_gpu_power | GPU Power Usage via AMD-SMI. Derived from... | + | sampling_gpu_temp | GPU Temperature via AMD-SMI. Derived from... | + | sampling_gpu_busy | GPU Utilization (% busy) via AMD-SMI. Der... | + | sampling_gpu_vcn | GPU VCN Utilization (% activity) via AMD ... | + | sampling_gpu_jpeg | GPU JPEG Utilization (% activity) via AMD... | + | sampling_gpu_memory_usage | GPU Memory Usage via AMD-SMI. Derived fro... | + |-----------------------------------|----------------------------------------------| + +Viewing hardware counters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: shell + + $ rocprof-sys-avail -H -bd + |---------------------------------------|---------------------------------------| + | HARDWARE COUNTER | DESCRIPTION | + |---------------------------------------|---------------------------------------| + | CPU | | + |---------------------------------------|---------------------------------------| + | PAPI_L1_DCM | Level 1 data cache misses | + | PAPI_L1_ICM | Level 1 instruction cache misses | + | PAPI_L2_DCM | Level 2 data cache misses | + | PAPI_L2_ICM | Level 2 instruction cache misses | + | PAPI_L3_DCM | Level 3 data cache misses | + | PAPI_L3_ICM | Level 3 instruction cache misses | + | PAPI_L1_TCM | Level 1 cache misses | + | PAPI_L2_TCM | Level 2 cache misses | + | PAPI_L3_TCM | Level 3 cache misses | + | PAPI_CA_SNP | Requests for a snoop | + | PAPI_CA_SHR | Requests for exclusive access to s... | + | PAPI_CA_CLN | Requests for exclusive access to c... | + | PAPI_CA_INV | Requests for cache line invalidation | + | PAPI_CA_ITV | Requests for cache line intervention | + | PAPI_L3_LDM | Level 3 load misses | + | PAPI_L3_STM | Level 3 store misses | + | PAPI_BRU_IDL | Cycles branch units are idle | + | PAPI_FXU_IDL | Cycles integer units are idle | + | PAPI_FPU_IDL | Cycles floating point units are idle | + | PAPI_LSU_IDL | Cycles load/store units are idle | + | PAPI_TLB_DM | Data translation lookaside buffer ... | + | PAPI_TLB_IM | Instruction translation lookaside ... | + | PAPI_TLB_TL | Total translation lookaside buffer... | + | PAPI_L1_LDM | Level 1 load misses | + | PAPI_L1_STM | Level 1 store misses | + | PAPI_L2_LDM | Level 2 load misses | + | PAPI_L2_STM | Level 2 store misses | + | PAPI_BTAC_M | Branch target address cache misses | + | PAPI_PRF_DM | Data prefetch cache misses | + | PAPI_L3_DCH | Level 3 data cache hits | + | PAPI_TLB_SD | Translation lookaside buffer shoot... | + | PAPI_CSR_FAL | Failed store conditional instructions | + | PAPI_CSR_SUC | Successful store conditional instr... | + | PAPI_CSR_TOT | Total store conditional instructions | + | PAPI_MEM_SCY | Cycles Stalled Waiting for memory ... | + | PAPI_MEM_RCY | Cycles Stalled Waiting for memory ... | + | PAPI_MEM_WCY | Cycles Stalled Waiting for memory ... | + | PAPI_STL_ICY | Cycles with no instruction issue | + | PAPI_FUL_ICY | Cycles with maximum instruction issue | + | PAPI_STL_CCY | Cycles with no instructions completed | + | PAPI_FUL_CCY | Cycles with maximum instructions c... | + | PAPI_HW_INT | Hardware interrupts | + | PAPI_BR_UCN | Unconditional branch instructions | + | PAPI_BR_CN | Conditional branch instructions | + | PAPI_BR_TKN | Conditional branch instructions taken | + | PAPI_BR_NTK | Conditional branch instructions no... | + | PAPI_BR_MSP | Conditional branch instructions mi... | + | PAPI_BR_PRC | Conditional branch instructions co... | + | PAPI_FMA_INS | FMA instructions completed | + | PAPI_TOT_IIS | Instructions issued | + | PAPI_TOT_INS | Instructions completed | + | PAPI_INT_INS | Integer instructions | + | PAPI_FP_INS | Floating point instructions | + | PAPI_LD_INS | Load instructions | + | PAPI_SR_INS | Store instructions | + | PAPI_BR_INS | Branch instructions | + | PAPI_VEC_INS | Vector/SIMD instructions (could in... | + | PAPI_RES_STL | Cycles stalled on any resource | + | PAPI_FP_STAL | Cycles the FP unit(s) are stalled | + | PAPI_TOT_CYC | Total cycles | + | PAPI_LST_INS | Load/store instructions completed | + | PAPI_SYC_INS | Synchronization instructions compl... | + | PAPI_L1_DCH | Level 1 data cache hits | + | PAPI_L2_DCH | Level 2 data cache hits | + | PAPI_L1_DCA | Level 1 data cache accesses | + | PAPI_L2_DCA | Level 2 data cache accesses | + | PAPI_L3_DCA | Level 3 data cache accesses | + | PAPI_L1_DCR | Level 1 data cache reads | + | PAPI_L2_DCR | Level 2 data cache reads | + | PAPI_L3_DCR | Level 3 data cache reads | + | PAPI_L1_DCW | Level 1 data cache writes | + | PAPI_L2_DCW | Level 2 data cache writes | + | PAPI_L3_DCW | Level 3 data cache writes | + | PAPI_L1_ICH | Level 1 instruction cache hits | + | PAPI_L2_ICH | Level 2 instruction cache hits | + | PAPI_L3_ICH | Level 3 instruction cache hits | + | PAPI_L1_ICA | Level 1 instruction cache accesses | + | PAPI_L2_ICA | Level 2 instruction cache accesses | + | PAPI_L3_ICA | Level 3 instruction cache accesses | + | PAPI_L1_ICR | Level 1 instruction cache reads | + | PAPI_L2_ICR | Level 2 instruction cache reads | + | PAPI_L3_ICR | Level 3 instruction cache reads | + | PAPI_L1_ICW | Level 1 instruction cache writes | + | PAPI_L2_ICW | Level 2 instruction cache writes | + | PAPI_L3_ICW | Level 3 instruction cache writes | + | PAPI_L1_TCH | Level 1 total cache hits | + | PAPI_L2_TCH | Level 2 total cache hits | + | PAPI_L3_TCH | Level 3 total cache hits | + | PAPI_L1_TCA | Level 1 total cache accesses | + | PAPI_L2_TCA | Level 2 total cache accesses | + | PAPI_L3_TCA | Level 3 total cache accesses | + | PAPI_L1_TCR | Level 1 total cache reads | + | PAPI_L2_TCR | Level 2 total cache reads | + | PAPI_L3_TCR | Level 3 total cache reads | + | PAPI_L1_TCW | Level 1 total cache writes | + | PAPI_L2_TCW | Level 2 total cache writes | + | PAPI_L3_TCW | Level 3 total cache writes | + | PAPI_FML_INS | Floating point multiply instructions | + | PAPI_FAD_INS | Floating point add instructions | + | PAPI_FDV_INS | Floating point divide instructions | + | PAPI_FSQ_INS | Floating point square root instruc... | + | PAPI_FNV_INS | Floating point inverse instructions | + | PAPI_FP_OPS | Floating point operations | + | PAPI_SP_OPS | Floating point operations; optimiz... | + | PAPI_DP_OPS | Floating point operations; optimiz... | + | PAPI_VEC_SP | Single precision vector/SIMD instr... | + | PAPI_VEC_DP | Double precision vector/SIMD instr... | + | PAPI_REF_CYC | Reference clock cycles | + | perf::PERF_COUNT_HW_CPU_CYCLES | PERF_COUNT_HW_CPU_CYCLES | + | perf::PERF_COUNT_HW_CPU_CYCLES:u=0 | perf::PERF_COUNT_HW_CPU_CYCLES + m... | + | perf::PERF_COUNT_HW_CPU_CYCLES:k=0 | perf::PERF_COUNT_HW_CPU_CYCLES + m... | + | perf::PERF_COUNT_HW_CPU_CYCLES:h=0 | perf::PERF_COUNT_HW_CPU_CYCLES + m... | + | perf::PERF_COUNT_HW_CPU_CYCLES:per... | perf::PERF_COUNT_HW_CPU_CYCLES + s... | + | perf::PERF_COUNT_HW_CPU_CYCLES:freq=0 | perf::PERF_COUNT_HW_CPU_CYCLES + s... | + | perf::PERF_COUNT_HW_CPU_CYCLES:pre... | perf::PERF_COUNT_HW_CPU_CYCLES + p... | + | perf::PERF_COUNT_HW_CPU_CYCLES:excl=0 | perf::PERF_COUNT_HW_CPU_CYCLES + e... | + | perf::PERF_COUNT_HW_CPU_CYCLES:mg=0 | perf::PERF_COUNT_HW_CPU_CYCLES + m... | + | perf::PERF_COUNT_HW_CPU_CYCLES:mh=0 | perf::PERF_COUNT_HW_CPU_CYCLES + m... | + | perf::PERF_COUNT_HW_CPU_CYCLES:cpu=0 | perf::PERF_COUNT_HW_CPU_CYCLES + C... | + | perf::PERF_COUNT_HW_CPU_CYCLES:pin... | perf::PERF_COUNT_HW_CPU_CYCLES + p... | + | perf::CYCLES | PERF_COUNT_HW_CPU_CYCLES | + | perf::CYCLES:u=0 | perf::CYCLES + monitor at user level | + | perf::CYCLES:k=0 | perf::CYCLES + monitor at kernel l... | + | perf::CYCLES:h=0 | perf::CYCLES + monitor at hypervis... | + | perf::CYCLES:period=0 | perf::CYCLES + sampling period | + | perf::CYCLES:freq=0 | perf::CYCLES + sampling frequency ... | + | perf::CYCLES:precise=0 | perf::CYCLES + precise event sampling | + | perf::CYCLES:excl=0 | perf::CYCLES + exclusive access | + | perf::CYCLES:mg=0 | perf::CYCLES + monitor guest execu... | + | perf::CYCLES:mh=0 | perf::CYCLES + monitor host execution | + | perf::CYCLES:cpu=0 | perf::CYCLES + CPU to program | + | perf::CYCLES:pinned=0 | perf::CYCLES + pin event to counters | + | perf::CPU-CYCLES | PERF_COUNT_HW_CPU_CYCLES | + | perf::CPU-CYCLES:u=0 | perf::CPU-CYCLES + monitor at user... | + | perf::CPU-CYCLES:k=0 | perf::CPU-CYCLES + monitor at kern... | + | perf::CPU-CYCLES:h=0 | perf::CPU-CYCLES + monitor at hype... | + | perf::CPU-CYCLES:period=0 | perf::CPU-CYCLES + sampling period | + | perf::CPU-CYCLES:freq=0 | perf::CPU-CYCLES + sampling freque... | + | perf::CPU-CYCLES:precise=0 | perf::CPU-CYCLES + precise event s... | + | perf::CPU-CYCLES:excl=0 | perf::CPU-CYCLES + exclusive access | + | perf::CPU-CYCLES:mg=0 | perf::CPU-CYCLES + monitor guest e... | + | perf::CPU-CYCLES:mh=0 | perf::CPU-CYCLES + monitor host ex... | + | perf::CPU-CYCLES:cpu=0 | perf::CPU-CYCLES + CPU to program | + | perf::CPU-CYCLES:pinned=0 | perf::CPU-CYCLES + pin event to co... | + | perf::PERF_COUNT_HW_INSTRUCTIONS | PERF_COUNT_HW_INSTRUCTIONS | + | perf::PERF_COUNT_HW_INSTRUCTIONS:u=0 | perf::PERF_COUNT_HW_INSTRUCTIONS +... | + | perf::PERF_COUNT_HW_INSTRUCTIONS:k=0 | perf::PERF_COUNT_HW_INSTRUCTIONS +... | + | perf::PERF_COUNT_HW_INSTRUCTIONS:h=0 | perf::PERF_COUNT_HW_INSTRUCTIONS +... | + | perf::PERF_COUNT_HW_INSTRUCTIONS:p... | perf::PERF_COUNT_HW_INSTRUCTIONS +... | + | perf::PERF_COUNT_HW_INSTRUCTIONS:f... | perf::PERF_COUNT_HW_INSTRUCTIONS +... | + | perf::PERF_COUNT_HW_INSTRUCTIONS:p... | perf::PERF_COUNT_HW_INSTRUCTIONS +... | + | perf::PERF_COUNT_HW_INSTRUCTIONS:e... | perf::PERF_COUNT_HW_INSTRUCTIONS +... | + | perf::PERF_COUNT_HW_INSTRUCTIONS:mg=0 | perf::PERF_COUNT_HW_INSTRUCTIONS +... | + | perf::PERF_COUNT_HW_INSTRUCTIONS:mh=0 | perf::PERF_COUNT_HW_INSTRUCTIONS +... | + | perf::PERF_COUNT_HW_INSTRUCTIONS:c... | perf::PERF_COUNT_HW_INSTRUCTIONS +... | + | perf::PERF_COUNT_HW_INSTRUCTIONS:p... | perf::PERF_COUNT_HW_INSTRUCTIONS +... | + | ... etc. ... | | + | perf_raw::r0000 | perf_events raw event syntax: r[0-... | + | perf_raw::r0000:u=0 | perf_raw::r0000 + monitor at user ... | + | perf_raw::r0000:k=0 | perf_raw::r0000 + monitor at kerne... | + | perf_raw::r0000:h=0 | perf_raw::r0000 + monitor at hyper... | + | perf_raw::r0000:period=0 | perf_raw::r0000 + sampling period | + | perf_raw::r0000:freq=0 | perf_raw::r0000 + sampling frequen... | + | perf_raw::r0000:precise=0 | perf_raw::r0000 + precise event sa... | + | perf_raw::r0000:excl=0 | perf_raw::r0000 + exclusive access | + | perf_raw::r0000:mg=0 | perf_raw::r0000 + monitor guest ex... | + | perf_raw::r0000:mh=0 | perf_raw::r0000 + monitor host exe... | + | perf_raw::r0000:cpu=0 | perf_raw::r0000 + CPU to program | + | perf_raw::r0000:pinned=0 | perf_raw::r0000 + pin event to cou... | + | perf_raw::r0000:hw_smpl=0 | perf_raw::r0000 + enable hardware ... | + | L1_ITLB_MISS_L2_ITLB_HIT | Number of instruction fetches that... | + | L1_ITLB_MISS_L2_ITLB_HIT:e=0 | L1_ITLB_MISS_L2_ITLB_HIT + edge level | + | L1_ITLB_MISS_L2_ITLB_HIT:i=0 | L1_ITLB_MISS_L2_ITLB_HIT + invert | + | L1_ITLB_MISS_L2_ITLB_HIT:c=0 | L1_ITLB_MISS_L2_ITLB_HIT + counter... | + | L1_ITLB_MISS_L2_ITLB_HIT:g=0 | L1_ITLB_MISS_L2_ITLB_HIT + measure... | + | L1_ITLB_MISS_L2_ITLB_HIT:u=0 | L1_ITLB_MISS_L2_ITLB_HIT + monitor... | + | L1_ITLB_MISS_L2_ITLB_HIT:k=0 | L1_ITLB_MISS_L2_ITLB_HIT + monitor... | + | L1_ITLB_MISS_L2_ITLB_HIT:period=0 | L1_ITLB_MISS_L2_ITLB_HIT + samplin... | + | L1_ITLB_MISS_L2_ITLB_HIT:freq=0 | L1_ITLB_MISS_L2_ITLB_HIT + samplin... | + | L1_ITLB_MISS_L2_ITLB_HIT:excl=0 | L1_ITLB_MISS_L2_ITLB_HIT + exclusi... | + | L1_ITLB_MISS_L2_ITLB_HIT:mg=0 | L1_ITLB_MISS_L2_ITLB_HIT + monitor... | + | L1_ITLB_MISS_L2_ITLB_HIT:mh=0 | L1_ITLB_MISS_L2_ITLB_HIT + monitor... | + | L1_ITLB_MISS_L2_ITLB_HIT:cpu=0 | L1_ITLB_MISS_L2_ITLB_HIT + CPU to ... | + | L1_ITLB_MISS_L2_ITLB_HIT:pinned=0 | L1_ITLB_MISS_L2_ITLB_HIT + pin eve... | + | L1_ITLB_MISS_L2_ITLB_MISS | Number of instruction fetches that... | + | L1_ITLB_MISS_L2_ITLB_MISS:IF1G | L1_ITLB_MISS_L2_ITLB_MISS + Number... | + | L1_ITLB_MISS_L2_ITLB_MISS:IF2M | L1_ITLB_MISS_L2_ITLB_MISS + Number... | + | L1_ITLB_MISS_L2_ITLB_MISS:IF4K | L1_ITLB_MISS_L2_ITLB_MISS + Number... | + | L1_ITLB_MISS_L2_ITLB_MISS:e=0 | L1_ITLB_MISS_L2_ITLB_MISS + edge l... | + | L1_ITLB_MISS_L2_ITLB_MISS:i=0 | L1_ITLB_MISS_L2_ITLB_MISS + invert | + | L1_ITLB_MISS_L2_ITLB_MISS:c=0 | L1_ITLB_MISS_L2_ITLB_MISS + counte... | + | L1_ITLB_MISS_L2_ITLB_MISS:g=0 | L1_ITLB_MISS_L2_ITLB_MISS + measur... | + | L1_ITLB_MISS_L2_ITLB_MISS:u=0 | L1_ITLB_MISS_L2_ITLB_MISS + monito... | + | L1_ITLB_MISS_L2_ITLB_MISS:k=0 | L1_ITLB_MISS_L2_ITLB_MISS + monito... | + | L1_ITLB_MISS_L2_ITLB_MISS:period=0 | L1_ITLB_MISS_L2_ITLB_MISS + sampli... | + | L1_ITLB_MISS_L2_ITLB_MISS:freq=0 | L1_ITLB_MISS_L2_ITLB_MISS + sampli... | + | L1_ITLB_MISS_L2_ITLB_MISS:excl=0 | L1_ITLB_MISS_L2_ITLB_MISS + exclus... | + | L1_ITLB_MISS_L2_ITLB_MISS:mg=0 | L1_ITLB_MISS_L2_ITLB_MISS + monito... | + | L1_ITLB_MISS_L2_ITLB_MISS:mh=0 | L1_ITLB_MISS_L2_ITLB_MISS + monito... | + | L1_ITLB_MISS_L2_ITLB_MISS:cpu=0 | L1_ITLB_MISS_L2_ITLB_MISS + CPU to... | + | L1_ITLB_MISS_L2_ITLB_MISS:pinned=0 | L1_ITLB_MISS_L2_ITLB_MISS + pin ev... | + | RETIRED_SSE_AVX_FLOPS | This is a retire-based event. The ... | + | RETIRED_SSE_AVX_FLOPS:ADD_SUB_FLOPS | RETIRED_SSE_AVX_FLOPS + Addition/s... | + | RETIRED_SSE_AVX_FLOPS:MULT_FLOPS | RETIRED_SSE_AVX_FLOPS + Multiplica... | + | RETIRED_SSE_AVX_FLOPS:DIV_FLOPS | RETIRED_SSE_AVX_FLOPS + Division F... | + | RETIRED_SSE_AVX_FLOPS:MAC_FLOPS | RETIRED_SSE_AVX_FLOPS + Double pre... | + | RETIRED_SSE_AVX_FLOPS:ANY | RETIRED_SSE_AVX_FLOPS + Double pre... | + | RETIRED_SSE_AVX_FLOPS:e=0 | RETIRED_SSE_AVX_FLOPS + edge level | + | RETIRED_SSE_AVX_FLOPS:i=0 | RETIRED_SSE_AVX_FLOPS + invert | + | RETIRED_SSE_AVX_FLOPS:c=0 | RETIRED_SSE_AVX_FLOPS + counter-ma... | + | RETIRED_SSE_AVX_FLOPS:g=0 | RETIRED_SSE_AVX_FLOPS + measure in... | + | RETIRED_SSE_AVX_FLOPS:u=0 | RETIRED_SSE_AVX_FLOPS + monitor at... | + | RETIRED_SSE_AVX_FLOPS:k=0 | RETIRED_SSE_AVX_FLOPS + monitor at... | + | RETIRED_SSE_AVX_FLOPS:period=0 | RETIRED_SSE_AVX_FLOPS + sampling p... | + | RETIRED_SSE_AVX_FLOPS:freq=0 | RETIRED_SSE_AVX_FLOPS + sampling f... | + | RETIRED_SSE_AVX_FLOPS:excl=0 | RETIRED_SSE_AVX_FLOPS + exclusive ... | + | RETIRED_SSE_AVX_FLOPS:mg=0 | RETIRED_SSE_AVX_FLOPS + monitor gu... | + | RETIRED_SSE_AVX_FLOPS:mh=0 | RETIRED_SSE_AVX_FLOPS + monitor ho... | + | RETIRED_SSE_AVX_FLOPS:cpu=0 | RETIRED_SSE_AVX_FLOPS + CPU to pro... | + | RETIRED_SSE_AVX_FLOPS:pinned=0 | RETIRED_SSE_AVX_FLOPS + pin event ... | + | DIV_CYCLES_BUSY_COUNT | Number of cycles when the divider ... | + | DIV_CYCLES_BUSY_COUNT:e=0 | DIV_CYCLES_BUSY_COUNT + edge level | + | DIV_CYCLES_BUSY_COUNT:i=0 | DIV_CYCLES_BUSY_COUNT + invert | + | DIV_CYCLES_BUSY_COUNT:c=0 | DIV_CYCLES_BUSY_COUNT + counter-ma... | + | DIV_CYCLES_BUSY_COUNT:g=0 | DIV_CYCLES_BUSY_COUNT + measure in... | + | DIV_CYCLES_BUSY_COUNT:u=0 | DIV_CYCLES_BUSY_COUNT + monitor at... | + | DIV_CYCLES_BUSY_COUNT:k=0 | DIV_CYCLES_BUSY_COUNT + monitor at... | + | DIV_CYCLES_BUSY_COUNT:period=0 | DIV_CYCLES_BUSY_COUNT + sampling p... | + | DIV_CYCLES_BUSY_COUNT:freq=0 | DIV_CYCLES_BUSY_COUNT + sampling f... | + | DIV_CYCLES_BUSY_COUNT:excl=0 | DIV_CYCLES_BUSY_COUNT + exclusive ... | + | DIV_CYCLES_BUSY_COUNT:mg=0 | DIV_CYCLES_BUSY_COUNT + monitor gu... | + | DIV_CYCLES_BUSY_COUNT:mh=0 | DIV_CYCLES_BUSY_COUNT + monitor ho... | + | DIV_CYCLES_BUSY_COUNT:cpu=0 | DIV_CYCLES_BUSY_COUNT + CPU to pro... | + | DIV_CYCLES_BUSY_COUNT:pinned=0 | DIV_CYCLES_BUSY_COUNT + pin event ... | + | DIV_OP_COUNT | Number of divide uops. | + | DIV_OP_COUNT:e=0 | DIV_OP_COUNT + edge level | + | DIV_OP_COUNT:i=0 | DIV_OP_COUNT + invert | + | DIV_OP_COUNT:c=0 | DIV_OP_COUNT + counter-mask in ran... | + | DIV_OP_COUNT:g=0 | DIV_OP_COUNT + measure in guest | + | DIV_OP_COUNT:u=0 | DIV_OP_COUNT + monitor at user level | + | DIV_OP_COUNT:k=0 | DIV_OP_COUNT + monitor at kernel l... | + | DIV_OP_COUNT:period=0 | DIV_OP_COUNT + sampling period | + | DIV_OP_COUNT:freq=0 | DIV_OP_COUNT + sampling frequency ... | + | DIV_OP_COUNT:excl=0 | DIV_OP_COUNT + exclusive access | + | DIV_OP_COUNT:mg=0 | DIV_OP_COUNT + monitor guest execu... | + | DIV_OP_COUNT:mh=0 | DIV_OP_COUNT + monitor host execution | + | DIV_OP_COUNT:cpu=0 | DIV_OP_COUNT + CPU to program | + | DIV_OP_COUNT:pinned=0 | DIV_OP_COUNT + pin event to counters | + | ... etc. ... | | + | amd64_rapl::RAPL_ENERGY_PKG | Number of Joules consumed by all c... | + | amd64_rapl::RAPL_ENERGY_PKG:u=0 | amd64_rapl::RAPL_ENERGY_PKG + moni... | + | amd64_rapl::RAPL_ENERGY_PKG:k=0 | amd64_rapl::RAPL_ENERGY_PKG + moni... | + | amd64_rapl::RAPL_ENERGY_PKG:period=0 | amd64_rapl::RAPL_ENERGY_PKG + samp... | + | amd64_rapl::RAPL_ENERGY_PKG:freq=0 | amd64_rapl::RAPL_ENERGY_PKG + samp... | + | amd64_rapl::RAPL_ENERGY_PKG:excl=0 | amd64_rapl::RAPL_ENERGY_PKG + excl... | + | amd64_rapl::RAPL_ENERGY_PKG:mg=0 | amd64_rapl::RAPL_ENERGY_PKG + moni... | + | amd64_rapl::RAPL_ENERGY_PKG:mh=0 | amd64_rapl::RAPL_ENERGY_PKG + moni... | + | amd64_rapl::RAPL_ENERGY_PKG:cpu=0 | amd64_rapl::RAPL_ENERGY_PKG + CPU ... | + | amd64_rapl::RAPL_ENERGY_PKG:pinned=0 | amd64_rapl::RAPL_ENERGY_PKG + pin ... | + | appio:::READ_BYTES | Bytes read | + | appio:::READ_CALLS | Number of read calls | + | appio:::READ_ERR | Number of read calls that resulted... | + | appio:::READ_INTERRUPTED | Number of read calls that timed ou... | + | appio:::READ_WOULD_BLOCK | Number of read calls that would ha... | + | appio:::READ_SHORT | Number of read calls that returned... | + | appio:::READ_EOF | Number of read calls that returned... | + | appio:::READ_BLOCK_SIZE | Average block size of reads | + | appio:::READ_USEC | Real microseconds spent in reads | + | appio:::WRITE_BYTES | Bytes written | + | appio:::WRITE_CALLS | Number of write calls | + | appio:::WRITE_ERR | Number of write calls that resulte... | + | appio:::WRITE_SHORT | Number of write calls that wrote l... | + | appio:::WRITE_INTERRUPTED | Number of write calls that timed o... | + | appio:::WRITE_WOULD_BLOCK | Number of write calls that would h... | + | appio:::WRITE_BLOCK_SIZE | Mean block size of writes | + | appio:::WRITE_USEC | Real microseconds spent in writes | + | appio:::OPEN_CALLS | Number of open calls | + | appio:::OPEN_ERR | Number of open calls that resulted... | + | appio:::OPEN_FDS | Number of currently open descriptors | + | appio:::SELECT_USEC | Real microseconds spent in select ... | + | appio:::RECV_BYTES | Bytes read in recv/recvmsg/recvfrom | + | appio:::RECV_CALLS | Number of recv/recvmsg/recvfrom calls | + | appio:::RECV_ERR | Number of recv/recvmsg/recvfrom ca... | + | appio:::RECV_INTERRUPTED | Number of recv/recvmsg/recvfrom ca... | + | appio:::RECV_WOULD_BLOCK | Number of recv/recvmsg/recvfrom ca... | + | appio:::RECV_SHORT | Number of recv/recvmsg/recvfrom ca... | + | appio:::RECV_EOF | Number of recv/recvmsg/recvfrom ca... | + | appio:::RECV_BLOCK_SIZE | Average block size of recv/recvmsg... | + | appio:::RECV_USEC | Real microseconds spent in recv/re... | + | appio:::SOCK_READ_BYTES | Bytes read from socket | + | appio:::SOCK_READ_CALLS | Number of read calls on socket | + | appio:::SOCK_READ_ERR | Number of read calls on socket tha... | + | appio:::SOCK_READ_SHORT | Number of read calls on socket tha... | + | appio:::SOCK_READ_WOULD_BLOCK | Number of read calls on socket tha... | + | appio:::SOCK_READ_USEC | Real microseconds spent in read(s)... | + | appio:::SOCK_WRITE_BYTES | Bytes written to socket | + | appio:::SOCK_WRITE_CALLS | Number of write calls to socket | + | appio:::SOCK_WRITE_ERR | Number of write calls to socket th... | + | appio:::SOCK_WRITE_SHORT | Number of write calls to socket th... | + | appio:::SOCK_WRITE_WOULD_BLOCK | Number of write calls to socket th... | + | appio:::SOCK_WRITE_USEC | Real microseconds spent in write(s... | + | appio:::SEEK_CALLS | Number of seek calls | + | appio:::SEEK_ABS_STRIDE_SIZE | Average absolute stride size of seeks | + | appio:::SEEK_USEC | Real microseconds spent in seek calls | + | coretemp:::hwmon2:in0_input | V, amdgpu module, label vddgfx | + | coretemp:::hwmon2:temp1_input | degrees C, amdgpu module, label edge | + | coretemp:::hwmon2:temp2_input | degrees C, amdgpu module, label ju... | + | coretemp:::hwmon2:temp3_input | degrees C, amdgpu module, label mem | + | coretemp:::hwmon2:fan1_input | RPM, amdgpu module, label ? | + | coretemp:::hwmon0:temp1_input | degrees C, nvme module, label Comp... | + | coretemp:::hwmon0:temp2_input | degrees C, nvme module, label Sens... | + | coretemp:::hwmon0:temp3_input | degrees C, nvme module, label Sens... | + | coretemp:::hwmon3:temp1_input | degrees C, k10temp module, label Tctl | + | coretemp:::hwmon3:temp2_input | degrees C, k10temp module, label Tdie | + | coretemp:::hwmon3:temp5_input | degrees C, k10temp module, label T... | + | coretemp:::hwmon3:temp7_input | degrees C, k10temp module, label T... | + | coretemp:::hwmon1:temp1_input | degrees C, enp1s0 module, label PH... | + | coretemp:::hwmon1:temp2_input | degrees C, enp1s0 module, label MA... | + | io:::rchar | Characters read. | + | io:::wchar | Characters written. | + | io:::syscr | Characters read by system calls. | + | io:::syscw | Characters written by system calls. | + | io:::read_bytes | Binary bytes read. | + | io:::write_bytes | Binary bytes written. | + | io:::cancelled_write_bytes | Binary write bytes cancelled. | + | net:::lo:rx:bytes | lo receive bytes | + | net:::lo:rx:packets | lo receive packets | + | net:::lo:rx:errors | lo receive errors | + | net:::lo:rx:dropped | lo receive dropped | + | net:::lo:rx:fifo | lo receive fifo | + | net:::lo:rx:frame | lo receive frame | + | net:::lo:rx:compressed | lo receive compressed | + | net:::lo:rx:multicast | lo receive multicast | + | net:::lo:tx:bytes | lo transmit bytes | + | net:::lo:tx:packets | lo transmit packets | + | net:::lo:tx:errors | lo transmit errors | + | net:::lo:tx:dropped | lo transmit dropped | + | net:::lo:tx:fifo | lo transmit fifo | + | net:::lo:tx:colls | lo transmit colls | + | net:::lo:tx:carrier | lo transmit carrier | + | net:::lo:tx:compressed | lo transmit compressed | + | net:::enp1s0:rx:bytes | enp1s0 receive bytes | + | net:::enp1s0:rx:packets | enp1s0 receive packets | + | net:::enp1s0:rx:errors | enp1s0 receive errors | + | net:::enp1s0:rx:dropped | enp1s0 receive dropped | + | net:::enp1s0:rx:fifo | enp1s0 receive fifo | + | net:::enp1s0:rx:frame | enp1s0 receive frame | + | net:::enp1s0:rx:compressed | enp1s0 receive compressed | + | net:::enp1s0:rx:multicast | enp1s0 receive multicast | + | net:::enp1s0:tx:bytes | enp1s0 transmit bytes | + | net:::enp1s0:tx:packets | enp1s0 transmit packets | + | net:::enp1s0:tx:errors | enp1s0 transmit errors | + | net:::enp1s0:tx:dropped | enp1s0 transmit dropped | + | net:::enp1s0:tx:fifo | enp1s0 transmit fifo | + | net:::enp1s0:tx:colls | enp1s0 transmit colls | + | net:::enp1s0:tx:carrier | enp1s0 transmit carrier | + | net:::enp1s0:tx:compressed | enp1s0 transmit compressed | + | net:::vxlan.calico:rx:bytes | vxlan.calico receive bytes | + | net:::vxlan.calico:rx:packets | vxlan.calico receive packets | + | net:::vxlan.calico:rx:errors | vxlan.calico receive errors | + | net:::vxlan.calico:rx:dropped | vxlan.calico receive dropped | + | net:::vxlan.calico:rx:fifo | vxlan.calico receive fifo | + | net:::vxlan.calico:rx:frame | vxlan.calico receive frame | + | net:::vxlan.calico:rx:compressed | vxlan.calico receive compressed | + | net:::vxlan.calico:rx:multicast | vxlan.calico receive multicast | + | net:::vxlan.calico:tx:bytes | vxlan.calico transmit bytes | + | net:::vxlan.calico:tx:packets | vxlan.calico transmit packets | + | net:::vxlan.calico:tx:errors | vxlan.calico transmit errors | + | net:::vxlan.calico:tx:dropped | vxlan.calico transmit dropped | + | net:::vxlan.calico:tx:fifo | vxlan.calico transmit fifo | + | net:::vxlan.calico:tx:colls | vxlan.calico transmit colls | + | net:::vxlan.calico:tx:carrier | vxlan.calico transmit carrier | + | net:::vxlan.calico:tx:compressed | vxlan.calico transmit compressed | + | net:::cali59d6fabc2aa:rx:bytes | cali59d6fabc2aa receive bytes | + | net:::cali59d6fabc2aa:rx:packets | cali59d6fabc2aa receive packets | + | net:::cali59d6fabc2aa:rx:errors | cali59d6fabc2aa receive errors | + | net:::cali59d6fabc2aa:rx:dropped | cali59d6fabc2aa receive dropped | + | net:::cali59d6fabc2aa:rx:fifo | cali59d6fabc2aa receive fifo | + | net:::cali59d6fabc2aa:rx:frame | cali59d6fabc2aa receive frame | + | net:::cali59d6fabc2aa:rx:compressed | cali59d6fabc2aa receive compressed | + | net:::cali59d6fabc2aa:rx:multicast | cali59d6fabc2aa receive multicast | + | net:::cali59d6fabc2aa:tx:bytes | cali59d6fabc2aa transmit bytes | + | net:::cali59d6fabc2aa:tx:packets | cali59d6fabc2aa transmit packets | + | net:::cali59d6fabc2aa:tx:errors | cali59d6fabc2aa transmit errors | + | net:::cali59d6fabc2aa:tx:dropped | cali59d6fabc2aa transmit dropped | + | net:::cali59d6fabc2aa:tx:fifo | cali59d6fabc2aa transmit fifo | + | net:::cali59d6fabc2aa:tx:colls | cali59d6fabc2aa transmit colls | + | net:::cali59d6fabc2aa:tx:carrier | cali59d6fabc2aa transmit carrier | + | net:::cali59d6fabc2aa:tx:compressed | cali59d6fabc2aa transmit compressed | + |---------------------------------------|---------------------------------------| + | GPU | | + |---------------------------------------|---------------------------------------| + | TCC_EA1_WRREQ[0]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[1]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[2]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[3]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[4]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[5]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[6]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[7]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[8]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[9]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[10]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[11]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[12]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[13]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[14]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ[15]:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ_64B[0]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[1]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[2]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[3]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[4]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[5]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[6]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[7]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[8]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[9]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[10]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[11]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[12]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[13]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[14]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_64B[15]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA1_WRREQ_STALL[0]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[1]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[2]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[3]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[4]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[5]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[6]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[7]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[8]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[9]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[10]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[11]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[12]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[13]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[14]:device=0 | Number of cycles a write request w... | + | TCC_EA1_WRREQ_STALL[15]:device=0 | Number of cycles a write request w... | + | TCC_EA1_RDREQ[0]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[1]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[2]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[3]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[4]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[5]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[6]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[7]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[8]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[9]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[10]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[11]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[12]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[13]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[14]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ[15]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_RDREQ_32B[0]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[1]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[2]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[3]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[4]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[5]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[6]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[7]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[8]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[9]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[10]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[11]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[12]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[13]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[14]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_32B[15]:device=0 | Number of 32-byte TCC/EA read requ... | + | GRBM_COUNT:device=0 | Tie High - Count Number of Clocks | + | GRBM_GUI_ACTIVE:device=0 | The GUI is Active | + | SQ_WAVES:device=0 | Count number of waves sent to SQs.... | + | SQ_INSTS_VALU:device=0 | Number of VALU instructions issued... | + | SQ_INSTS_VMEM_WR:device=0 | Number of VMEM write instructions ... | + | SQ_INSTS_VMEM_RD:device=0 | Number of VMEM read instructions i... | + | SQ_INSTS_SALU:device=0 | Number of SALU instructions issued... | + | SQ_INSTS_SMEM:device=0 | Number of SMEM instructions issued... | + | SQ_INSTS_FLAT:device=0 | Number of FLAT instructions issued... | + | SQ_INSTS_FLAT_LDS_ONLY:device=0 | Number of FLAT instructions issued... | + | SQ_INSTS_LDS:device=0 | Number of LDS instructions issued ... | + | SQ_INSTS_GDS:device=0 | Number of GDS instructions issued.... | + | SQ_WAIT_INST_LDS:device=0 | Number of wave-cycles spent waitin... | + | SQ_ACTIVE_INST_VALU:device=0 | regspec 71? Number of cycles the S... | + | SQ_INST_CYCLES_SALU:device=0 | Number of cycles needed to execute... | + | SQ_THREAD_CYCLES_VALU:device=0 | Number of thread-cycles used to ex... | + | SQ_LDS_BANK_CONFLICT:device=0 | Number of cycles LDS is stalled by... | + | TA_TA_BUSY[0]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[1]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[2]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[3]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[4]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[5]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[6]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[7]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[8]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[9]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[10]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[11]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[12]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[13]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[14]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_TA_BUSY[15]:device=0 | TA block is busy. Perf_Windowing n... | + | TA_FLAT_READ_WAVEFRONTS[0]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[1]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[2]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[3]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[4]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[5]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[6]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[7]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[8]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[9]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[10]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[11]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[12]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[13]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[14]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_READ_WAVEFRONTS[15]:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_WRITE_WAVEFRONTS[0]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[1]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[2]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[3]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[4]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[5]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[6]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[7]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[8]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[9]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[10]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[11]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[12]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[13]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[14]:device=0 | Number of flat opcode writes proce... | + | TA_FLAT_WRITE_WAVEFRONTS[15]:device=0 | Number of flat opcode writes proce... | + | TCC_HIT[0]:device=0 | Number of cache hits. | + | TCC_HIT[1]:device=0 | Number of cache hits. | + | TCC_HIT[2]:device=0 | Number of cache hits. | + | TCC_HIT[3]:device=0 | Number of cache hits. | + | TCC_HIT[4]:device=0 | Number of cache hits. | + | TCC_HIT[5]:device=0 | Number of cache hits. | + | TCC_HIT[6]:device=0 | Number of cache hits. | + | TCC_HIT[7]:device=0 | Number of cache hits. | + | TCC_HIT[8]:device=0 | Number of cache hits. | + | TCC_HIT[9]:device=0 | Number of cache hits. | + | TCC_HIT[10]:device=0 | Number of cache hits. | + | TCC_HIT[11]:device=0 | Number of cache hits. | + | TCC_HIT[12]:device=0 | Number of cache hits. | + | TCC_HIT[13]:device=0 | Number of cache hits. | + | TCC_HIT[14]:device=0 | Number of cache hits. | + | TCC_HIT[15]:device=0 | Number of cache hits. | + | TCC_MISS[0]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[1]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[2]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[3]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[4]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[5]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[6]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[7]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[8]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[9]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[10]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[11]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[12]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[13]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[14]:device=0 | Number of cache misses. UC reads c... | + | TCC_MISS[15]:device=0 | Number of cache misses. UC reads c... | + | TCC_EA_WRREQ[0]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[1]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[2]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[3]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[4]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[5]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[6]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[7]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[8]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[9]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[10]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[11]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[12]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[13]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[14]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ[15]:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ_64B[0]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[1]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[2]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[3]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[4]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[5]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[6]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[7]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[8]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[9]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[10]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[11]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[12]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[13]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[14]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_64B[15]:device=0 | Number of 64-byte transactions goi... | + | TCC_EA_WRREQ_STALL[0]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[1]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[2]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[3]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[4]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[5]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[6]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[7]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[8]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[9]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[10]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[11]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[12]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[13]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[14]:device=0 | Number of cycles a write request w... | + | TCC_EA_WRREQ_STALL[15]:device=0 | Number of cycles a write request w... | + | TCC_EA_RDREQ[0]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[1]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[2]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[3]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[4]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[5]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[6]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[7]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[8]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[9]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[10]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[11]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[12]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[13]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[14]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ[15]:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_RDREQ_32B[0]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[1]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[2]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[3]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[4]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[5]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[6]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[7]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[8]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[9]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[10]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[11]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[12]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[13]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[14]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_32B[15]:device=0 | Number of 32-byte TCC/EA read requ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[0]:de... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[1]:de... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[2]:de... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[3]:de... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[4]:de... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[5]:de... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[6]:de... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[7]:de... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[8]:de... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[9]:de... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[10]:d... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[11]:d... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[12]:d... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[13]:d... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[14]:d... | TCP stalls TA data interface. Now ... | + | TCP_TCP_TA_DATA_STALL_CYCLES[15]:d... | TCP stalls TA data interface. Now ... | + | TCC_EA1_RDREQ_32B_sum:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA1_RDREQ_sum:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA1_WRREQ_sum:device=0 | Number of transactions (either 32-... | + | TCC_EA1_WRREQ_64B_sum:device=0 | Number of 64-byte transactions goi... | + | TCC_WRREQ1_STALL_max:device=0 | Number of cycles a write request w... | + | RDATA1_SIZE:device=0 | The total kilobytes fetched from t... | + | WDATA1_SIZE:device=0 | The total kilobytes written to the... | + | FETCH_SIZE:device=0 | The total kilobytes fetched from t... | + | WRITE_SIZE:device=0 | The total kilobytes written to the... | + | WRITE_REQ_32B:device=0 | The total number of 32-byte effect... | + | TA_BUSY_avr:device=0 | TA block is busy. Average over TA ... | + | TA_BUSY_max:device=0 | TA block is busy. Max over TA inst... | + | TA_BUSY_min:device=0 | TA block is busy. Min over TA inst... | + | TA_FLAT_READ_WAVEFRONTS_sum:device=0 | Number of flat opcode reads proces... | + | TA_FLAT_WRITE_WAVEFRONTS_sum:device=0 | Number of flat opcode writes proce... | + | TCC_HIT_sum:device=0 | Number of cache hits. Sum over TCC... | + | TCC_MISS_sum:device=0 | Number of cache misses. Sum over T... | + | TCC_EA_RDREQ_32B_sum:device=0 | Number of 32-byte TCC/EA read requ... | + | TCC_EA_RDREQ_sum:device=0 | Number of TCC/EA read requests (ei... | + | TCC_EA_WRREQ_sum:device=0 | Number of transactions (either 32-... | + | TCC_EA_WRREQ_64B_sum:device=0 | Number of 64-byte transactions goi... | + | TCC_WRREQ_STALL_max:device=0 | Number of cycles a write request w... | + | GPUBusy:device=0 | The percentage of time GPU was busy. | + | Wavefronts:device=0 | Total wavefronts. | + | VALUInsts:device=0 | The average number of vector ALU i... | + | SALUInsts:device=0 | The average number of scalar ALU i... | + | VFetchInsts:device=0 | The average number of vector fetch... | + | SFetchInsts:device=0 | The average number of scalar fetch... | + | VWriteInsts:device=0 | The average number of vector write... | + | FlatVMemInsts:device=0 | The average number of FLAT instruc... | + | LDSInsts:device=0 | The average number of LDS read or ... | + | FlatLDSInsts:device=0 | The average number of FLAT instruc... | + | GDSInsts:device=0 | The average number of GDS read or ... | + | VALUUtilization:device=0 | The percentage of active vector AL... | + | VALUBusy:device=0 | The percentage of GPUTime vector A... | + | SALUBusy:device=0 | The percentage of GPUTime scalar A... | + | FetchSize:device=0 | The total kilobytes fetched from t... | + | WriteSize:device=0 | The total kilobytes written to the... | + | MemWrites32B:device=0 | The total number of effective 32B ... | + | L2CacheHit:device=0 | The percentage of fetch, write, at... | + | MemUnitBusy:device=0 | The percentage of GPUTime the memo... | + | MemUnitStalled:device=0 | The percentage of GPUTime the memo... | + | WriteUnitStalled:device=0 | The percentage of GPUTime the Writ... | + | ALUStalledByLDS:device=0 | The percentage of GPUTime ALU unit... | + | LDSBankConflict:device=0 | The percentage of GPUTime LDS is s... | + |---------------------------------------|---------------------------------------| + +.. _creating-a-configuration-file: + +Creating a configuration file +======================================== + +ROCm Systems Profiler supports three configuration file formats: JSON, XML, and plain text. +Use ``rocprof-sys-avail -G -F txt json xml`` to generate default +configuration files in each format. Optionally +include the ``--all`` flag to include full descriptions and other information. +Configuration files are specified by the ``ROCPROFSYS_CONFIG_FILE`` environment variable +which by default looks for ``${HOME}/.rocprof-sys.cfg`` and ``${HOME}/.rocprof-sys.json``. +Multiple configuration files can be concatenated using the ``:`` symbol, for example: + +.. code-block:: shell + + export ROCPROFSYS_CONFIG_FILE=~/.config/rocprof-sys.cfg:~/.config/rocprof-sys.json + +If a configuration variable is specified in both a configuration file and in the environment, +the environment variable takes precedence. + +Sample text configuration file +----------------------------------- + +Text files support very basic variables and are case insensitive. +Variables are created when an lvalue starts with a ``$`` and are +de-referenced when they appear as rvalues. + +Entries in the text configuration file which do not match a known setting +in ``rocprof-sys-avail`` but are prefixed with ``ROCPROFSYS_`` are interpreted as +environment variables. They are exported via ``setenv`` +but do not override an existing value for the environment variable. + +.. code-block:: shell + + # lvals starting with $ are variables + $ENABLE = ON + $SAMPLE = OFF + + # use fields + ROCPROFSYS_TRACE = $ENABLE + ROCPROFSYS_PROFILE = $ENABLE + ROCPROFSYS_USE_SAMPLING = $SAMPLE + ROCPROFSYS_USE_PROCESS_SAMPLING = $SAMPLE + + # debug + ROCPROFSYS_DEBUG = OFF + ROCPROFSYS_VERBOSE = 1 + + # output fields + ROCPROFSYS_OUTPUT_PATH = rocprof-sys-output + ROCPROFSYS_OUTPUT_PREFIX = %tag%/ + ROCPROFSYS_TIME_OUTPUT = OFF + ROCPROFSYS_USE_PID = OFF + + # timemory fields + ROCPROFSYS_PAPI_EVENTS = PAPI_TOT_INS PAPI_FP_INS + ROCPROFSYS_TIMEMORY_COMPONENTS = wall_clock peak_rss trip_count + ROCPROFSYS_MEMORY_UNITS = MB + ROCPROFSYS_TIMING_UNITS = sec + + # sampling fields + ROCPROFSYS_SAMPLING_FREQ = 50 + ROCPROFSYS_SAMPLING_DELAY = 0.1 + ROCPROFSYS_SAMPLING_CPUS = 0-3 + ROCPROFSYS_SAMPLING_GPUS = $env:HIP_VISIBLE_DEVICES + + # misc env variables (see metadata JSON file after run) + $env:ROCPROFSYS_SAMPLING_KEEP_DYNINST_SUFFIX = OFF + +Sample JSON configuration file +----------------------------------- + +The full JSON specification for a configuration value contains a lot of information: + +.. code-block:: json + + { + "rocprof-sys": { + "settings": { + "ROCPROFSYS_ADD_SECONDARY": { + "count": -1, + "name": "add_secondary", + "data_type": "bool", + "initial": true, + "value": true, + "max_count": 1, + "cmdline": [ + "--rocprof-sys-add-secondary" + ], + "environ": "ROCPROFSYS_ADD_SECONDARY", + "cereal_class_version": 1, + "categories": [ + "component", + "data", + "native" + ], + "description": "Enable/disable components adding secondary (child) entries when available. E.g. suppress individual CUDA kernels, etc. when using Cupti components" + } + } + } + } + +However when writing an JSON configuration file, the following example is minimally acceptable +for ``ROCPROFSYS_ADD_SECONDARY``: + +.. code-block:: json + + { + "rocprof-sys": { + "settings": { + "ROCPROFSYS_ADD_SECONDARY": { + "value": true + } + } + } + } + +Sample XML configuration file +----------------------------------- + +The full XML specification for a configuration value contains the same information as the JSON specification: + +.. code-block:: xml + + + + + + 2 + + + 1 + add_secondary + ROCPROFSYS_ADD_SECONDARY + ... + -1 + 1 + + --rocprof-sys-add-secondary + + + component + data + native + + bool + true + true + + + + + + +However, when writing an XML configuration file, it is minimally acceptable +to set ``ROCPROFSYS_ADD_SECONDARY=false``: + +.. code-block:: xml + + + + + + + false + + + + diff --git a/projects/rocprofiler-systems/docs/how-to/configuring-validating-environment.rst b/projects/rocprofiler-systems/docs/how-to/configuring-validating-environment.rst new file mode 100644 index 0000000000..99e33192f9 --- /dev/null +++ b/projects/rocprofiler-systems/docs/how-to/configuring-validating-environment.rst @@ -0,0 +1,71 @@ +.. meta:: + :description: ROCm Systems Profiler environment validation documentation and reference + :keywords: rocprof-sys, rocprofiler-systems, Omnitrace, ROCm, profiler, environment, tracking, visualization, tool, Instinct, accelerator, AMD + +**************************************************** +Configuring and validating the environment +**************************************************** + +After installing `ROCm Systems Profiler `_, additional steps are required to set up +and validate the environment. + +.. note:: + + The following instructions use the installation path ``/opt/rocprofiler-systems``. If + ROCm Systems Profiler is installed elsewhere, substitute the actual installation path. + +Configuring the environment +======================================== + +After ROCm Systems Profiler is installed, source the ``setup-env.sh`` script to prefix the +``PATH``, ``LD_LIBRARY_PATH``, and other environment variables: + +.. code-block:: shell + + source /opt/rocprofiler-systems/share/rocprofiler-systems/setup-env.sh + +Alternatively, if environment modules are supported, add the ``/share/modulefiles`` directory +to ``MODULEPATH``: + +.. code-block:: shell + + module use /opt/rocprofiler-systems/share/modulefiles + +.. note:: + + As an alternative, the above line can be added to the ``${HOME}/.modulerc`` file. + +After ROCm Systems Profiler has been added to the ``MODULEPATH``, it can be loaded +using ``module load rocprofiler-systems/`` and unloaded using ``module unload rocprofiler-systems/``. + +.. code-block:: shell + + module load rocprofiler-systems/1.0.0 + module unload rocprofiler-systems/1.0.0 + +.. note:: + + You might also need to add the path to the ROCm libraries to ``LD_LIBRARY_PATH``, + for example, ``export LD_LIBRARY_PATH=/opt/rocm/lib:${LD_LIBRARY_PATH}`` + +Validating the environment configuration +======================================== + +If the following commands all run successfully with the expected output, +then you are ready to use ROCm Systems Profiler: + +.. code-block:: shell + + which rocprof-sys + which rocprof-sys-avail + which rocprof-sys-sample + rocprof-sys-instrument --help + rocprof-sys-avail --all + rocprof-sys-sample --help + +If ROCm Systems Profiler was built with Python support, validate these additional commands: + +.. code-block:: shell + + which rocprof-sys-python + rocprof-sys-python --help diff --git a/projects/rocprofiler-systems/docs/how-to/general-tips-using-rocprof-sys.rst b/projects/rocprofiler-systems/docs/how-to/general-tips-using-rocprof-sys.rst new file mode 100644 index 0000000000..bf0aee9d10 --- /dev/null +++ b/projects/rocprofiler-systems/docs/how-to/general-tips-using-rocprof-sys.rst @@ -0,0 +1,60 @@ +.. meta:: + :description: ROCm Systems Profiler general tips and usage documentation and reference + :keywords: rocprof-sys, rocprofiler-systems, Omnitrace, ROCm, tips, how to, profiler, tracking, visualization, tool, Instinct, accelerator, AMD + +******************************************** +General tips for using ROCm Systems Profiler +******************************************** + +Follow these general guidelines when using ROCm Systems Profiler. For an explanation of the terms used in this topic, see +the :doc:`ROCm Systems Profiler glossary <../reference/rocprof-sys-glossary>`. + +* Use ``rocprof-sys-avail`` to look up configuration settings, hardware counters, and data collection components + + * Use the ``-d`` flag for descriptions + +* Generate a default configuration with ``rocprof-sys-avail -G ${HOME}/.rocprof-sys.cfg`` and adjust it + to the desired default behavior +* **Decide whether binary instrumentation, statistical sampling, or both** provides the desired performance data (for non-Python applications) +* Compile code with optimization enabled (``-O2`` or higher), disable asserts (i.e. ``-DNDEBUG``), and include debug info (for instance, ``-g1`` at a minimum) + + * Compiling with debug info does not slow down the code, it only increases compile time and the size of the binary + * In CMake, this is generally done with the settings ``CMAKE_BUILD_TYPE=RelWithDebInfo`` or ``CMAKE_BUILD_TYPE=Release`` and ``CMAKE__FLAGS=-g1`` + +* **Use binary instrumentation for characterizing the performance of every invocation of specific functions** +* **Use statistical sampling to characterize the performance of the entire application while minimizing overhead** +* Enable statistical sampling after binary instrumentation to help "fill in the gaps" between instrumented regions +* Use the user API to create custom regions and enable/disable ROCm Systems Profiler for specific processes, threads, and regions +* Dynamic symbol interception, callback APIs, and the user API are always available with binary instrumentation and sampling + + * Dynamic symbol interception and callback APIs are (generally) controlled through ``ROCPROFSYS_USE_`` + options, for example, ``ROCPROFSYS_USE_KOKKOSP`` and ``ROCPROFSYS_USE_OMPT`` enable Kokkos-Tools and OpenMP-Tools + callbacks, respectively + +* When generically seeking regions for performance improvement: + + * **Start off by collecting a flat profile** + * Look for functions with high call counts, large cumulative runtimes/values, or large standard deviations + + * When call counts are high, improving the performance of this function or "inlining" the function can result in quick and easy performance improvements + * When the standard deviation is high, collect a hierarchical profile and see if the high variation can be attributable to the calling context. + In this scenario, consider creating a specialized version of the function for the longer-running contexts + + * **Collect a hierarchical profile** and verify the functions that are part of the "critical path" of your + application, as indicated in the flat profile + + * For example, functions with high call counts but which are part of a "setup" or "post-processing" + phase that does not consume much time relative to the overall time are generally a lower priority for optimization + +* **Use the information from the profiles when analyzing detailed traces** +* When using binary instrumentation in "trace" mode, **binary rewrites are preferable to runtime instrumentation**. + + * Binary rewrites only instrument the functions defined in the target binary, whereas runtime instrumentation might instrument functions defined in the shared libraries which are linked into the target binary + +* When using binary instrumentation with MPI, avoid runtime instrumentation + + * Runtime instrumentation requires a fork and a ``ptrace``, which is generally incompatible with how MPI applications spawn processes + * Perform a binary rewrite of the executable (and optionally, libraries used by the executable) using MPI and run + the generated instrumented executable using ``rocprof-sys-run`` instead of the original. + For example, instead of ``mpirun -n 2 ./myexe``, use ``mpirun -n 2 rocprof-sys-run -- ./myexe.inst``, where + ``myexe.inst`` is the instrumented ``myexe`` executable that was generated. diff --git a/projects/rocprofiler-systems/docs/how-to/instrumenting-rewriting-binary-application.rst b/projects/rocprofiler-systems/docs/how-to/instrumenting-rewriting-binary-application.rst new file mode 100644 index 0000000000..52b740b106 --- /dev/null +++ b/projects/rocprofiler-systems/docs/how-to/instrumenting-rewriting-binary-application.rst @@ -0,0 +1,939 @@ +.. meta:: + :description: ROCm Systems Profiler binary instrumentation and rewrite documentation and reference + :keywords: rocprof-sys, rocprofiler-systems, Omnitrace, ROCm, binary instrumentation, binary rewrite, profiler, tracking, visualization, tool, Instinct, accelerator, AMD + +**************************************************** +Instrumenting and rewriting a binary application +**************************************************** + +There are three ways to perform instrumentation with the ``rocprof-sys-instrument`` executable: + +* Runtime instrumentation +* Attaching to an already running process +* Binary rewrite + +Here is a comparison of the three modes: + +* Runtime instrumentation of the application using the ``rocprof-sys-instrument`` executable + (analogous to ``gdb --args ``) + + * This mode is the default if neither the ``-p`` nor ``-o`` command-line options are used + * Runtime instrumentation supports instrumenting not only the target executable but also + the shared libraries loaded by the target executable. Consequently, this mode consumes more memory, + takes longer to perform the instrumentation, and tends to add more significant overhead to the + runtime of the application. + * This mode is recommended if you want to analyze not only the performance of your executable and/or + libraries but also the performance of the library dependencies + +* Attaching to a process that is currently running (analogous to ``gdb -p ``) + + * This mode is activated using ``-p `` + * The same caveats from the first example apply with respect to memory and overhead + + .. note:: + + Attaching to a running process is an alpha feature and detaching from the target process + without ending the target process is not currently supported. + +* Binary rewrite to generate a new executable or library with the instrumentation built-in + + * This mode is activated through the ``-o `` option + * Binary rewriting is limited to the text section of the target executable or library. It does not instrument + the dynamically-linked libraries. Consequently, this mode performs the + instrumentation significantly faster + and has a much lower overhead when running the instrumented executable and libraries. + * Binary rewriting is the recommended mode when the target executable uses + process-level parallelism (for example, MPI) + * If the target executable has a minimal ``main`` routine and the bulk of your + application is in one specific dynamic library, + see :ref:`binary-rewriting-library-label` for help + +The rocprof-sys-instrument executable +======================================== + +Instrumentation is performed with the ``rocprof-sys-instrument`` executable. For more details, use the ``-h`` or ``--help`` option to +view the help menu. + +.. code-block:: shell + + $ rocprof-sys-instrument --help + [rocprof-sys-instrument] Usage: rocprof-sys-instrument [ --help (count: 0, dtype: bool) + --version (count: 0, dtype: bool) + --verbose (max: 1, dtype: bool) + --error (max: 1, dtype: boolean) + --debug (max: 1, dtype: bool) + --log (count: 1) + --log-file (count: 1) + --simulate (max: 1, dtype: boolean) + --print-format (min: 1, dtype: string) + --print-dir (count: 1, dtype: string) + --print-available (count: 1) + --print-instrumented (count: 1) + --print-coverage (count: 1) + --print-excluded (count: 1) + --print-overlapping (count: 1) + --print-instructions (max: 1, dtype: bool) + --output (min: 0, dtype: string) + --pid (count: 1, dtype: int) + --mode (count: 1) + --force (max: 1, dtype: bool) + --command (count: 1) + --prefer (count: 1) + --library (count: unlimited) + --main-function (count: 1) + --load (count: unlimited, dtype: string) + --load-instr (count: unlimited, dtype: filepath) + --init-functions (count: unlimited, dtype: string) + --fini-functions (count: unlimited, dtype: string) + --all-functions (max: 1, dtype: boolean) + --function-include (count: unlimited) + --function-exclude (count: unlimited) + --function-restrict (count: unlimited) + --caller-include (count: unlimited) + --module-include (count: unlimited) + --module-exclude (count: unlimited) + --module-restrict (count: unlimited) + --internal-function-include (count: unlimited) + --internal-module-include (count: unlimited) + --instruction-exclude (count: unlimited) + --internal-library-deps (min: 0, dtype: boolean) + --internal-library-append (count: unlimited) + --internal-library-remove (count: unlimited) + --linkage (min: 1) + --visibility (min: 1) + --label (count: unlimited, dtype: string) + --config (min: 1, dtype: string) + --default-components (count: unlimited, dtype: string) + --env (count: unlimited) + --mpi (max: 1, dtype: bool) + --instrument-loops (max: 1, dtype: boolean) + --min-instructions (count: 1, dtype: int) + --min-address-range (count: 1, dtype: int) + --min-instructions-loop (count: 1, dtype: int) + --min-address-range-loop (count: 1, dtype: int) + --coverage (max: 1, dtype: bool) + --dynamic-callsites (max: 1, dtype: boolean) + --traps (max: 1, dtype: boolean) + --loop-traps (max: 1, dtype: boolean) + --allow-overlapping (max: 1, dtype: bool) + --parse-all-modules (max: 1, dtype: bool) + --batch-size (count: 1, dtype: int) + --dyninst-rt (min: 1, dtype: filepath) + --dyninst-options (count: unlimited) + ] -- + + Options: + -h, -?, --help Shows this page + --version Prints the version and exit + + [DEBUG OPTIONS] + + -v, --verbose Verbose output + -e, --error All warnings produce runtime errors + --debug Debug output + --log Number of log entries to display after an error. Any value < 0 will emit the entire log + --log-file Write the log out the specified file during the run + --simulate Exit after outputting diagnostic {available,instrumented,excluded,overlapping} module + function lists, e.g. available.txt + --print-format [ json | txt | xml ] + Output format for diagnostic {available,instrumented,excluded,overlapping} module + function lists, e.g. {print-dir}/available.txt + --print-dir Output directory for diagnostic {available,instrumented,excluded,overlapping} module + function lists, e.g. {print-dir}/available.txt + --print-available [ functions | functions+ | modules | pair | pair+ ] + Print the available entities for instrumentation (functions, modules, or module-function + pair) to stdout after applying regular expressions + --print-instrumented [ functions | functions+ | modules | pair | pair+ ] + Print the instrumented entities (functions, modules, or module-function pair) to stdout + after applying regular expressions + --print-coverage [ functions | functions+ | modules | pair | pair+ ] + Print the instrumented coverage entities (functions, modules, or module-function pair) to + stdout after applying regular expressions + --print-excluded [ functions | functions+ | modules | pair | pair+ ] + Print the entities for instrumentation (functions, modules, or module-function pair) + which are excluded from the instrumentation to stdout after applying regular expressions + --print-overlapping [ functions | functions+ | modules | pair | pair+ ] + Print the entities for instrumentation (functions, modules, or module-function pair) + which overlap other function calls or have multiple entry points to stdout after applying + regular expressions + --print-instructions Print the instructions for each basic-block in the JSON/XML outputs + + [MODE OPTIONS] + + -o, --output Enable generation of a new executable (binary-rewrite). If a filename is not provided, + rocprof-sys will use the basename and output to the cwd, unless the target binary is in the + cwd. In the latter case, rocprof-sys will either use ${PWD}/.inst (non-libraries) + or ${PWD}/instrumented/ (libraries) + -p, --pid Connect to running process + -M, --mode [ coverage | sampling | trace ] + Instrumentation mode. \'trace\' mode instruments the selected functions, \'sampling\' mode + only instruments the main function to start and stop the sampler. + -f, --force Force the command-line argument configuration, i.e. don't get cute. Useful for forcing + runtime instrumentation of an executable that [A] Dyninst thinks is a library after + reading ELF and [B] whose name makes it look like a library (e.g. starts with 'lib' + and/or ends in \'.so\', \'.so.*\', or \'.a\') + -c, --command Input executable and arguments (if \'-- \' not provided) + + [LIBRARY OPTIONS] + + --prefer [ shared | static ] Prefer this library types when available + -L, --library Libraries with instrumentation routines (default: "librocprof-sys-dl") + -m, --main-function The primary function to instrument around, e.g. \'main\' + --load Supplemental instrumentation library names w/o extension (e.g. \'libinstr\' for + \'libinstr.so\' or \'libinstr.a\') + --load-instr Load {available,instrumented,excluded,overlapping}-instr JSON or XML file(s) and override + what is read from the binary + --init-functions Initialization function(s) for supplemental instrumentation libraries (see \'--load\' + option) + --fini-functions Finalization function(s) for supplemental instrumentation libraries (see \'--load\' option) + --all-functions When finding functions, include the functions which are not instrumentable. This is + purely diagnostic for the available/excluded functions output + + [SYMBOL SELECTION OPTIONS] + + -I, --function-include Regex(es) for including functions (despite heuristics) + -E, --function-exclude Regex(es) for excluding functions (always applied) + -R, --function-restrict Regex(es) for restricting functions only to those that match the provided + regular-expressions + --caller-include Regex(es) for including functions that call the listed functions (despite heuristics) + -MI, --module-include Regex(es) for selecting modules/files/libraries (despite heuristics) + -ME, --module-exclude Regex(es) for excluding modules/files/libraries (always applied) + -MR, --module-restrict Regex(es) for restricting modules/files/libraries only to those that match the provided + regular-expressions + --internal-function-include Regex(es) for including functions which are (likely) utilized by rocprof-sys itself. Use + this option with care. + --internal-module-include Regex(es) for including modules/libraries which are (likely) utilized by rocprof-sys + itself. Use this option with care. + --instruction-exclude Regex(es) for excluding functions containing certain instructions + --internal-library-deps Treat the libraries linked to the internal libraries as internal libraries. This increase + the internal library processing time and consume more memory (so use with care) but may + be useful when the application uses Boost libraries and Dyninst is dynamically linked + against the same boost libraries + --internal-library-append Append to the list of libraries which rocprof-sys treats as being used internally, e.g. + ROCm Systems Profiler will find all the symbols in this library and prevent them from being + instrumented. + --internal-library-remove [ ld-linux-x86-64.so.2 + libBrokenLocale.so.1 + libanl.so.1 + libbfd.so + libbz2.so + libc.so.6 + libcaliper.so + libcommon.so + libcrypt.so.1 + libdl.so.2 + libdw.so + libdwarf.so + libdyninstAPI_RT.so + libelf.so + libgcc_s.so.1 + libgotcha.so + liblikwid.so + liblzma.so + libnsl.so.1 + libnss_compat.so.2 + libnss_db.so.2 + libnss_dns.so.2 + libnss_files.so.2 + libnss_hesiod.so.2 + libnss_ldap.so.2 + libnss_nis.so.2 + libnss_nisplus.so.2 + libnss_test1.so.2 + libnss_test2.so.2 + libpapi.so + libpfm.so + libprofiler.so + libpthread.so.0 + libresolv.so.2 + libamd_smi64.so + librocprofiler-sdk.so + librt.so.1 + libstdc++.so.6 + libtbb.so + libtbbmalloc.so + libtbbmalloc_proxy.so + libtcmalloc.so + libtcmalloc_and_profiler.so + libtcmalloc_debug.so + libtcmalloc_minimal.so + libtcmalloc_minimal_debug.so + libthread_db.so.1 + libunwind-coredump.so + libunwind-generic.so + libunwind-ptrace.so + libunwind-setjmp.so + libunwind-x86_64.so + libunwind.so + libutil.so.1 + libz.so + libzstd.so ] + Remove the specified libraries from being treated as being used internally, e.g. + ROCm System Profiler will permit all the symbols in these libraries to be eligible for + instrumentation. + --linkage [ global | local | unique | unknown | weak ] + Only instrument functions with specified linkage (default: global, local, unique) + --visibility [ default | hidden | internal | protected | unknown ] + Only instrument functions with specified visibility (default: default, internal, hidden, + protected) + + [RUNTIME OPTIONS] + + --label [ args | file | line | return ] + Labeling info for functions. By default, just the function name is recorded. Use these + options to gain more information about the function signature or location of the + functions + -C, --config Read in a configuration file and encode these values as the defaults in the executable + -d, --default-components Default components to instrument (only useful when timemory is enabled in rocprof-sys + library) + --env Environment variables to add to the runtime in form VARIABLE=VALUE. E.g. use \'--env + ROCPROFSYS_PROFILE=ON\' to default to using timemory instead of perfetto + --mpi Enable MPI support (requires rocprof-sys built w/ full or partial MPI support). NOTE: this + will automatically be activated if MPI_Init, MPI_Init_thread, MPI_Finalize, + MPI_Comm_rank, or MPI_Comm_size are found in the symbol table of target + + [GRANULARITY OPTIONS] + + -l, --instrument-loops Instrument at the loop level + -i, --min-instructions If the number of instructions in a function is less than this value, exclude it from + instrumentation + -r, --min-address-range If the address range of a function is less than this value, exclude it from + instrumentation + --min-instructions-loop If the number of instructions in a function containing a loop is less than this value, + exclude it from instrumentation + --min-address-range-loop If the address range of a function containing a loop is less than this value, exclude it + from instrumentation + --coverage [ basic_block | function | none ] + Enable recording the code coverage. If instrumenting in coverage mode (\'-M converage\'), + this simply specifies the granularity. If instrumenting in trace or sampling mode, this + enables recording code-coverage in addition to the instrumentation of that mode (if any). + --dynamic-callsites Force instrumentation if a function has dynamic callsites (e.g. function pointers) + --traps Instrument points which require using a trap. On the x86 architecture, because + instructions are of variable size, the instruction at a point may be too small for + Dyninst to replace it with the normal code sequence used to call instrumentation. Also, + when instrumentation is placed at points other than subroutine entry, exit, or call + points, traps may be used to ensure the instrumentation fits. In this case, Dyninst + replaces the instruction with a single-byte instruction that generates a trap. + --loop-traps Instrument points within a loop which require using a trap (only relevant when + --instrument-loops is enabled). + --allow-overlapping Allow dyninst to instrument either multiple functions which overlap (share part of same + function body) or single functions with multiple entry points. For more info, see Section + 2 of the DyninstAPI documentation. + --parse-all-modules By default, rocprof-sys simply requests Dyninst to provide all the procedures in the + application image. If this option is enabled, rocprof-sys will iterate over all the modules + and extract the functions. Theoretically, it should be the same but the data is slightly + different, possibly due to weak binding scopes. In general, enabling option will probably + have no visible effect + + [DYNINST OPTIONS] + + -b, --batch-size Dyninst supports batch insertion of multiple points during runtime instrumentation. If + one large batch insertion fails, this value will be used to create smaller batches. + Larger batches generally decrease the instrumentation time + --dyninst-rt Path(s) to the dyninstAPI_RT library + --dyninst-options [ BaseTrampDeletion + DebugParsing + DelayedParsing + InstrStackFrames + MergeTramp + SaveFPR + TrampRecursive + TypeChecking ] + Advanced dyninst options: BPatch::set