Files
TheRock/rocm-systems/projects/rocprofiler-systems/examples/cmake/standalone-helpers.cmake
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

485 lines
15 KiB
CMake

# Copyright (c) Advanced Micro Devices, Inc.
# SPDX-License-Identifier: MIT
#
# Standalone build helpers for rocprofiler-systems examples
#
# This file provides the CMake functions needed to build examples standalone
# (outside of the full rocprofiler-systems project build).
#
# Usage in example CMakeLists.txt:
# if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
# include(${CMAKE_CURRENT_LIST_DIR}/../cmake/standalone-helpers.cmake)
# endif()
include_guard(DIRECTORY)
# Set ROCPROFSYS_EXAMPLE_ROOT_DIR if not already set
if(NOT DEFINED ROCPROFSYS_EXAMPLE_ROOT_DIR)
get_filename_component(
ROCPROFSYS_EXAMPLE_ROOT_DIR
"${CMAKE_CURRENT_LIST_DIR}/.."
ABSOLUTE
)
endif()
# Include causal-helpers.cmake for causal profiling examples
include(${ROCPROFSYS_EXAMPLE_ROOT_DIR}/causal-helpers.cmake OPTIONAL)
# ----------------------------------------------------------------------------
# rocprofiler_systems_message()
# Wrapper around message() with project prefix
#
macro(ROCPROFILER_SYSTEMS_MESSAGE _TYPE)
message(${_TYPE} "[rocprofiler-systems] " ${ARGN})
endmacro()
# ----------------------------------------------------------------------------
# check_rocminfo()
# Searches for a given regex in the output of rocminfo
#
# ARGS:
# _REGEX: The regex to search for
# _RESULT_VARIABLE: The variable to store the result
# GET_OUTPUT: If present, return the matching output instead of boolean
#
function(CHECK_ROCMINFO _REGEX _RESULT_VARIABLE)
cmake_parse_arguments(ARG "GET_OUTPUT" "" "" ${ARGN})
find_program(
rocminfo_EXECUTABLE
NAMES rocminfo
HINTS ${ROCM_PATH} $ENV{ROCM_PATH} /opt/rocm
PATH_SUFFIXES bin
)
if(NOT DEFINED ARG_GET_OUTPUT AND _REGEX STREQUAL "")
message(FATAL_ERROR "Regex is empty, but GET_OUTPUT is not defined")
endif()
set(_result FALSE)
set(_failure FALSE)
if(rocminfo_EXECUTABLE)
execute_process(
COMMAND ${rocminfo_EXECUTABLE}
RESULT_VARIABLE rocminfo_RET
OUTPUT_VARIABLE rocminfo_OUTPUT
ERROR_VARIABLE rocminfo_ERROR
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_STRIP_TRAILING_WHITESPACE
)
if(rocminfo_RET EQUAL 0)
if(NOT _REGEX STREQUAL "")
string(REGEX MATCHALL "${_REGEX}" rocminfo_OUTPUT "${rocminfo_OUTPUT}")
if(rocminfo_OUTPUT)
set(_result TRUE)
endif()
endif()
else()
message(AUTHOR_WARNING "rocminfo failed: ${rocminfo_ERROR}")
set(_failure TRUE)
endif()
else()
message(AUTHOR_WARNING "rocminfo not found")
set(_failure TRUE)
endif()
if(ARG_GET_OUTPUT)
if(NOT _failure)
set(${_RESULT_VARIABLE} "${rocminfo_OUTPUT}" PARENT_SCOPE)
else()
set(${_RESULT_VARIABLE} "" PARENT_SCOPE)
endif()
return()
endif()
set(${_RESULT_VARIABLE} ${_result} PARENT_SCOPE)
endfunction()
# ----------------------------------------------------------------------------
# rocprofiler_systems_get_gfx_archs()
# Auto-detects GPU architectures from the system using rocminfo
#
# ARGS:
# _VAR: Output variable to store detected architectures (semicolon-separated)
#
function(ROCPROFILER_SYSTEMS_GET_GFX_ARCHS _VAR)
cmake_parse_arguments(ARG "ECHO" "PREFIX;DELIM;GFX_MATCH" "" ${ARGN})
if(NOT DEFINED ARG_DELIM)
set(ARG_DELIM ", ")
endif()
if(NOT DEFINED ARG_PREFIX)
set(ARG_PREFIX "[${PROJECT_NAME}] ")
endif()
check_rocminfo("Name:[ \t]+gfx[0-9A-Fa-f][0-9A-Fa-f]+" _RAW_GFXINFO GET_OUTPUT)
if(NOT _RAW_GFXINFO)
message(AUTHOR_WARNING "Could not detect GPU architectures")
set(${_VAR} "" PARENT_SCOPE)
return()
endif()
set(_GFXINFO "")
foreach(_match IN LISTS _RAW_GFXINFO)
string(REGEX MATCH "gfx[0-9A-Fa-f]+" _arch "${_match}")
if(_arch)
list(APPEND _GFXINFO "${_arch}")
endif()
endforeach()
list(REMOVE_ITEM _GFXINFO "gfx000")
list(REMOVE_DUPLICATES _GFXINFO)
if(DEFINED ARG_GFX_MATCH)
set(_FILTERED_GFXINFO "")
foreach(_arch IN LISTS _GFXINFO)
if(_arch MATCHES "${ARG_GFX_MATCH}")
list(APPEND _FILTERED_GFXINFO "${_arch}")
endif()
endforeach()
set(_GFXINFO "${_FILTERED_GFXINFO}")
endif()
if(ARG_ECHO)
string(REPLACE ";" "${ARG_DELIM}" _GFXINFO_ECHO "${_GFXINFO}")
message(STATUS "${ARG_PREFIX}System architectures: ${_GFXINFO_ECHO}")
endif()
set(${_VAR} "${_GFXINFO}" PARENT_SCOPE)
endfunction()
# ----------------------------------------------------------------------------
# rocprofiler_systems_lookup_gfx()
# Classifies AMD GPU architectures into categories (instinct, radeon, apu)
#
# ARGS:
# _TARGET: The gfx ID to classify (e.g., "gfx90a")
# _OUTPUT_LIST: Output variable for category list
#
function(ROCPROFILER_SYSTEMS_LOOKUP_GFX _TARGET _OUTPUT_LIST)
set(INSTINCT_LIST
"gfx900"
"gfx906"
"gfx908"
"gfx90a"
"gfx942"
"gfx950"
)
set(RADEON_LIST
"gfx1012"
"gfx1011"
"gfx1010"
"gfx1032"
"gfx1031"
"gfx1030"
"gfx1102"
"gfx1101"
"gfx1100"
"gfx1200"
"gfx1201"
"gfx1202"
)
set(APU_LIST
"gfx1035"
"gfx1036"
"gfx1103"
"gfx1151"
"gfx1152"
"gfx1153"
)
set(_CATEGORIES "")
if(_TARGET IN_LIST INSTINCT_LIST)
list(APPEND _CATEGORIES "instinct")
check_rocminfo("APU" _is_apu)
if(_is_apu)
list(APPEND _CATEGORIES "apu")
endif()
endif()
if(_TARGET IN_LIST RADEON_LIST)
list(APPEND _CATEGORIES "radeon")
endif()
if(_TARGET IN_LIST APU_LIST)
list(APPEND _CATEGORIES "apu")
endif()
if(_CATEGORIES STREQUAL "")
message(AUTHOR_WARNING "Unknown GFX target: ${_TARGET}. Defaulting to instinct")
list(APPEND _CATEGORIES "instinct")
endif()
set(${_OUTPUT_LIST} "${_CATEGORIES}" PARENT_SCOPE)
endfunction()
# ----------------------------------------------------------------------------
# rocprofiler_systems_custom_compilation()
# Sets up custom compiler for a target using the launch-compiler wrapper
#
# Uses the rocprof-sys-launch-compiler script to redirect compilation
# to the specified compiler (e.g., hipcc) while keeping CMAKE_CXX_COMPILER
# as the nominal compiler. This avoids enable_language(HIP) which can fail
# on build systems like TheRock that wrap compilers (e.g., resource_info.py).
#
# The launch-compiler script is found relative to the examples directory
# (at ../../scripts/rocprof-sys-launch-compiler) or via PATH/ROCM_PATH.
#
# ARGS:
# COMPILER: Path to the compiler to use (e.g., hipcc)
# TARGET: Target to apply custom compilation to
#
function(ROCPROFILER_SYSTEMS_CUSTOM_COMPILATION)
cmake_parse_arguments(ARG "" "COMPILER;TARGET" "" ${ARGN})
if(NOT ARG_COMPILER OR NOT ARG_TARGET)
return()
endif()
if(NOT TARGET ${ARG_TARGET})
return()
endif()
if(NOT DEFINED ROCPROFSYS_COMPILE_LAUNCHER)
find_program(
ROCPROFSYS_COMPILE_LAUNCHER
NAMES rocprof-sys-launch-compiler
HINTS
${ROCPROFSYS_EXAMPLE_ROOT_DIR}/../scripts
${ROCPROFSYS_EXAMPLE_ROOT_DIR}/../../scripts
${ROCM_PATH}
$ENV{ROCM_PATH}
/opt/rocm
PATH_SUFFIXES bin scripts
)
endif()
if(NOT ROCPROFSYS_COMPILE_LAUNCHER)
message(
AUTHOR_WARNING
"rocprof-sys-launch-compiler not found. "
"Cannot set up custom compilation for ${ARG_TARGET}."
)
return()
endif()
set(_LAUNCH_CMD
"${ROCPROFSYS_COMPILE_LAUNCHER} ${ARG_COMPILER} ${CMAKE_CXX_COMPILER}"
)
set_property(TARGET ${ARG_TARGET} PROPERTY RULE_LAUNCH_COMPILE "${_LAUNCH_CMD}")
set_property(TARGET ${ARG_TARGET} PROPERTY RULE_LAUNCH_LINK "${_LAUNCH_CMD}")
endfunction()
# ----------------------------------------------------------------------------
# rocprofiler_systems_checkout_git_submodule()
# Checks out a git submodule or clones a repo if not already present
#
# Mirrors the function from cmake/MacroUtilities.cmake for standalone builds.
#
# ARGS:
# RELATIVE_PATH: Path relative to WORKING_DIRECTORY
# WORKING_DIRECTORY: Base directory (default: PROJECT_SOURCE_DIR)
# TEST_FILE: File to check for existence (default: CMakeLists.txt)
# REPO_URL: URL to clone if submodule checkout fails
# REPO_BRANCH: Branch to checkout (default: master)
# RECURSIVE: Also init recursive submodules
#
function(ROCPROFILER_SYSTEMS_CHECKOUT_GIT_SUBMODULE)
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()
if(NOT CHECKOUT_REPO_BRANCH)
set(CHECKOUT_REPO_BRANCH "master")
endif()
find_package(Git)
set(_DIR "${CHECKOUT_WORKING_DIRECTORY}/${CHECKOUT_RELATIVE_PATH}")
if(NOT EXISTS "${_DIR}")
if(NOT CHECKOUT_REPO_URL)
message(FATAL_ERROR "submodule directory does not exist")
endif()
endif()
set(_TEST_FILE "${_DIR}/${CHECKOUT_TEST_FILE}")
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)
# .gitmodules lives at the monorepo root, not under PROJECT_SOURCE_DIR, because
# rocprofiler-systems was moved into the rocm-systems monorepo. Use git rev-parse
# to locate the root (result cached in CMakeCache.txt after first configure run).
if(NOT DEFINED CACHE{ROCPROFILER_SYSTEMS_GIT_TOPLEVEL})
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse --show-toplevel
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
OUTPUT_VARIABLE _GIT_TOPLEVEL
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE _GIT_TOPLEVEL_RET
)
if(NOT _GIT_TOPLEVEL_RET EQUAL 0)
message(
FATAL_ERROR
"Failed to determine git top-level directory. "
"Ensure this project is inside a git repository."
)
endif()
set(ROCPROFILER_SYSTEMS_GIT_TOPLEVEL
"${_GIT_TOPLEVEL}"
CACHE INTERNAL
"Git top-level directory"
)
endif()
set(_SUBMODULE "${ROCPROFILER_SYSTEMS_GIT_TOPLEVEL}/.gitmodules")
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()
set(_RECURSE "")
if(CHECKOUT_RECURSIVE)
set(_RECURSE "--recursive")
endif()
if(NOT _TEST_FILE_EXISTS AND _SUBMODULE_EXISTS)
execute_process(
COMMAND
${GIT_EXECUTABLE} submodule update --init ${_RECURSE}
${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_RELATIVE_PATH}
WORKING_DIRECTORY ${CHECKOUT_WORKING_DIRECTORY}
RESULT_VARIABLE RET
)
if(RET GREATER 0)
message(STATUS "function(rocprofiler_systems_checkout_git_submodule) failed.")
message(
FATAL_ERROR
"Command: \"${GIT_EXECUTABLE} submodule update --init ${_RECURSE} ${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_RELATIVE_PATH}\""
)
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}'..."
)
if(EXISTS "${_DIR}")
execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${_DIR})
endif()
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
)
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()
if(RET GREATER 0)
message(STATUS "function(rocprofiler_systems_checkout_git_submodule) failed.")
message(
FATAL_ERROR
"Command: \"${GIT_EXECUTABLE} clone -b ${CHECKOUT_REPO_BRANCH} ${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_REPO_URL} ${CHECKOUT_RELATIVE_PATH}\""
)
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()
# ----------------------------------------------------------------------------
# Setup GPU architecture detection for standalone builds
#
if(NOT DEFINED ROCPROFSYS_GFX_TARGETS OR ROCPROFSYS_GFX_TARGETS STREQUAL "")
rocprofiler_systems_get_gfx_archs(ROCPROFSYS_GFX_TARGETS)
endif()
set(ROCPROFSYS_GFX_TARGETS
"${ROCPROFSYS_GFX_TARGETS}"
CACHE STRING
"GPU architectures to compile for (semicolon-separated)"
)
if(ROCPROFSYS_GFX_TARGETS)
message(STATUS "[standalone] Detected GPU targets: ${ROCPROFSYS_GFX_TARGETS}")
else()
message(STATUS "[standalone] No GPU targets detected")
endif()
# ----------------------------------------------------------------------------
# Setup HIP compilation for standalone GPU example builds
#
# We avoid enable_language(HIP) because it can fail on build systems like
# TheRock that wrap compilers (e.g., resource_info.py). Instead, we find
# hipcc and use it via rocprofiler_systems_custom_compilation() which sets
# RULE_LAUNCH_COMPILE/RULE_LAUNCH_LINK on individual targets.
#
# This mirrors the approach used by the full project build (PR #3519).
#
if(ROCPROFSYS_GFX_TARGETS)
find_program(
HIPCC_EXECUTABLE
NAMES hipcc
HINTS ${ROCM_PATH} $ENV{ROCM_PATH} /opt/rocm
PATH_SUFFIXES bin NO_CACHE
)
mark_as_advanced(HIPCC_EXECUTABLE)
if(HIPCC_EXECUTABLE)
set(ROCPROFSYS_STANDALONE_HIP_AVAILABLE TRUE CACHE INTERNAL "")
message(STATUS "[standalone] HIP compilation via hipcc: ${HIPCC_EXECUTABLE}")
else()
set(ROCPROFSYS_STANDALONE_HIP_AVAILABLE FALSE CACHE INTERNAL "")
message(STATUS "[standalone] hipcc not found - GPU examples will be skipped")
endif()
endif()