Files
TheRock/rocm-systems/projects/rccl/bindings/ir/CMakeLists.txt
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

222 lines
8.4 KiB
CMake

# Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved.
# Adapted from NVIDIA NCCL ir/CMakeLists.txt (v2.29.2-1).
#
# See LICENSE.txt for license information
#
# LLVM IR / bitcode generation for RCCL device APIs (HIP / AMDGPU).
#
# This file is meant to be pulled in from the top-level RCCL CMakeLists.txt
# via:
# option(EMIT_LLVM_IR "Generate LLVM IR/bitcode for device APIs" OFF)
# if(EMIT_LLVM_IR)
# add_subdirectory(bindings/ir)
# add_dependencies(llvm_ir copy_nccl_device_headers)
# add_custom_target(rccl_with_ir ALL DEPENDS rccl llvm_ir)
# endif()
#
# The output mirrors the standalone bindings/ir/Makefile:
# ${CMAKE_BINARY_DIR}/lib/librccl_device.bc (final clean bitcode)
# ${CMAKE_BINARY_DIR}/obj/llvm_ir/*.bc.{un,}optimized
# ${CMAKE_BINARY_DIR}/obj/llvm_ir/librccl_device.ll (textual IR)
# ${CMAKE_BINARY_DIR}/include/nccl_device_wrapper.h (public C wrapper)
##### Source and output paths #####
set(LLVM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/nccl_device_wrapper__impl.h)
set(OBJDIR ${CMAKE_BINARY_DIR}/obj/llvm_ir)
set(LIBDIR ${CMAKE_BINARY_DIR}/lib)
set(INCLUDEDIR ${CMAKE_BINARY_DIR}/include)
set(UNOPTIMIZED_BC ${OBJDIR}/librccl_device.bc.unoptimized)
set(OPTIMIZED_BC ${OBJDIR}/librccl_device.bc.optimized)
set(LLVM_IR_FILE ${OBJDIR}/librccl_device.ll)
set(FINAL_BC ${LIBDIR}/librccl_device.bc)
set(WRAPPER_HEADER ${INCLUDEDIR}/nccl_device_wrapper.h)
##### Build configuration #####
# Default GPU architecture for the bitcode artifact. Override via:
# cmake -DEMIT_LLVM_IR=ON -DBITCODE_LIB_ARCH=gfx942 ...
set(BITCODE_LIB_ARCH "gfx950" CACHE STRING
"AMDGPU architecture for the LLVM bitcode (e.g. gfx942, gfx950)")
set(BITCODE_CXX_STD "c++17" CACHE STRING
"C++ standard for the LLVM bitcode build")
# ROCM_PATH is normally set by the top-level CMakeLists.txt; provide a
# safe default so this file is also usable standalone (cmake -P style).
if(NOT DEFINED ROCM_PATH OR ROCM_PATH STREQUAL "")
set(ROCM_PATH "/opt/rocm")
endif()
set(ROCM_LLVM_BIN "${ROCM_PATH}/llvm/bin")
##### Locate ROCm LLVM toolchain #####
# RCCL's cmake_minimum_required is 3.16, which predates
# `find_program(... REQUIRED)`, so check each one explicitly.
find_program(CLANG_EXECUTABLE NAMES amdclang++ clang++ HINTS ${ROCM_LLVM_BIN})
find_program(OPT_EXECUTABLE NAMES opt HINTS ${ROCM_LLVM_BIN})
find_program(LLVM_DIS_EXECUTABLE NAMES llvm-dis HINTS ${ROCM_LLVM_BIN})
find_program(LLVM_AS_EXECUTABLE NAMES llvm-as HINTS ${ROCM_LLVM_BIN})
foreach(_tool CLANG_EXECUTABLE OPT_EXECUTABLE LLVM_DIS_EXECUTABLE LLVM_AS_EXECUTABLE)
if(NOT ${_tool})
message(FATAL_ERROR
"RCCL IR (EMIT_LLVM_IR=ON): could not locate ${_tool} under "
"${ROCM_LLVM_BIN}. Install the ROCm LLVM toolchain or override "
"${_tool} on the command line.")
endif()
endforeach()
message(STATUS "RCCL IR: clang = ${CLANG_EXECUTABLE}")
message(STATUS "RCCL IR: opt = ${OPT_EXECUTABLE}")
message(STATUS "RCCL IR: llvm-dis = ${LLVM_DIS_EXECUTABLE}")
message(STATUS "RCCL IR: llvm-as = ${LLVM_AS_EXECUTABLE}")
message(STATUS "RCCL IR: target = ${BITCODE_LIB_ARCH} (${BITCODE_CXX_STD})")
##### Include paths #####
# Point at the hipify staging directory so this build sees exactly the
# same headers librccl.so is compiled from. HIPIFY_DIR is defined in
# src/CMakeLists.txt without CACHE/PARENT_SCOPE so it isn't visible from
# this sibling subdirectory; we re-derive the same well-known path.
# The dependency on the hipify pass having actually run must be wired
# up by the parent (`add_dependencies(llvm_ir copy_nccl_device_headers)`).
set(IR_HIPIFY_DIR "${PROJECT_BINARY_DIR}/hipify")
set(RCCL_INCLUDES
-I${CMAKE_BINARY_DIR}/include # generated rccl.h / nccl.h
-I${IR_HIPIFY_DIR}/src/include
-I${IR_HIPIFY_DIR}/src/include/nccl_device
-I${IR_HIPIFY_DIR}/src/device
)
set(ROCM_INCLUDES
-I${ROCM_PATH}/include
)
##### Compiler flags #####
# HIP device-only compilation. --offload-device-only is the modern,
# target-agnostic spelling of NCCL's --cuda-device-only.
set(COMMON_CLANG_FLAGS
-std=${BITCODE_CXX_STD}
-x hip
--rocm-path=${ROCM_PATH}
--offload-device-only
--offload-arch=${BITCODE_LIB_ARCH}
${RCCL_INCLUDES}
${ROCM_INCLUDES}
-D__clang_llvm_bitcode_lib__
-D__HIP_PLATFORM_AMD__=1
)
set(CLANG_FLAGS
-c -emit-llvm -O1
${COMMON_CLANG_FLAGS}
)
##### Stage the public wrapper header into build/include #####
add_custom_command(
OUTPUT ${WRAPPER_HEADER}
COMMAND ${CMAKE_COMMAND} -E make_directory ${INCLUDEDIR}
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/nccl_device_wrapper.h ${WRAPPER_HEADER}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/nccl_device_wrapper.h
COMMENT "Staging nccl_device_wrapper.h -> ${WRAPPER_HEADER}"
VERBATIM
)
##### Step 1: clang -> unoptimized bitcode #####
add_custom_command(
OUTPUT ${UNOPTIMIZED_BC}
COMMAND ${CMAKE_COMMAND} -E make_directory ${OBJDIR}
COMMAND ${CLANG_EXECUTABLE} ${CLANG_FLAGS} ${LLVM_SRC} -o ${UNOPTIMIZED_BC}
# Track both the impl TU (clang's direct input) and the staged wrapper
# header it transitively includes. Without the WRAPPER_HEADER dep,
# editing nccl_device_wrapper.h would not retrigger this command.
DEPENDS ${LLVM_SRC} ${WRAPPER_HEADER}
COMMENT "Generating unoptimized LLVM bitcode for ${BITCODE_LIB_ARCH}..."
VERBATIM
)
##### Step 2: opt -> optimized bitcode #####
# Internalize everything outside the public surface, then inline and drop
# dead globals. NCCL's recipe uses "-internalize-public-api-list=nccl*",
# but opt's `internalize` pass takes EXACT symbol names, not globs -- the
# literal token "nccl*" matches no symbol, so every wrapper thunk gets
# internalized and dropped to internal linkage. We list the public surface
# explicitly instead; keep this set in sync with the NCCL_IR_EXTERN_C
# entries in nccl_device_wrapper.h.
set(RCCL_DEVICE_BC_PUBLIC_API
# [A] Always-on
ncclGetPeerPointerTeam
# [B] ncclCoopAny + LSA barrier session
ncclCoopAnyInitThread
ncclCoopAnyInitWarp
ncclCoopAnyInitLanes
ncclCoopAnyInitWarpSpan
ncclCoopAnyInitCta
ncclCoopThreadRank
ncclCoopSize
ncclCoopNumThreads
ncclCoopSync
ncclLsaBarrierSessionInit
ncclLsaBarrierSessionArrive
ncclLsaBarrierSessionWait
ncclLsaBarrierSessionSync
# [C] GIN + composite barrier session
ncclGinBarrierSessionInit
ncclGinBarrierSessionSync
ncclBarrierSessionInit
ncclBarrierSessionSync
)
string(REPLACE ";" "," RCCL_DEVICE_BC_PUBLIC_API_CSV "${RCCL_DEVICE_BC_PUBLIC_API}")
add_custom_command(
OUTPUT ${OPTIMIZED_BC}
COMMAND ${OPT_EXECUTABLE}
--passes=internalize,inline,globaldce
-internalize-public-api-list=${RCCL_DEVICE_BC_PUBLIC_API_CSV}
${UNOPTIMIZED_BC} -o ${OPTIMIZED_BC}
DEPENDS ${UNOPTIMIZED_BC}
COMMENT "Optimizing LLVM bitcode (internalize/inline/globaldce)..."
VERBATIM
)
##### Step 3: llvm-dis -> textual IR (kept for inspection) #####
# AMDGPU has no equivalent of NCCL's "nvvm-reflect-ftz" metadata, so
# the awk/sed scrubbing pass that NCCL applies between dis and as is
# intentionally omitted.
add_custom_command(
OUTPUT ${LLVM_IR_FILE}
COMMAND ${LLVM_DIS_EXECUTABLE} ${OPTIMIZED_BC} -o ${LLVM_IR_FILE}
DEPENDS ${OPTIMIZED_BC}
COMMENT "Disassembling bitcode -> textual LLVM IR..."
VERBATIM
)
##### Step 4: llvm-as -> final bitcode artifact in build/lib #####
add_custom_command(
OUTPUT ${FINAL_BC}
COMMAND ${CMAKE_COMMAND} -E make_directory ${LIBDIR}
COMMAND ${LLVM_AS_EXECUTABLE} ${LLVM_IR_FILE} -o ${FINAL_BC}
DEPENDS ${LLVM_IR_FILE}
COMMENT "Assembling final bitcode -> librccl_device.bc..."
VERBATIM
)
##### Public target #####
add_custom_target(llvm_ir
DEPENDS ${FINAL_BC} ${OPTIMIZED_BC} ${WRAPPER_HEADER}
COMMENT "RCCL LLVM IR / bitcode generation"
)
##### Post-build summary #####
add_custom_command(TARGET llvm_ir POST_BUILD
COMMAND ${CMAKE_COMMAND} -E echo "RCCL LLVM IR and bitcode generated successfully:"
COMMAND ${CMAKE_COMMAND} -E echo " C++ Standard: ${BITCODE_CXX_STD}"
COMMAND ${CMAKE_COMMAND} -E echo " GPU Architecture: ${BITCODE_LIB_ARCH}"
COMMAND ${CMAKE_COMMAND} -E echo " Unoptimized BC: ${UNOPTIMIZED_BC}"
COMMAND ${CMAKE_COMMAND} -E echo " Optimized BC: ${OPTIMIZED_BC}"
COMMAND ${CMAKE_COMMAND} -E echo " LLVM IR (textual): ${LLVM_IR_FILE}"
COMMAND ${CMAKE_COMMAND} -E echo " Final BC: ${FINAL_BC}"
COMMAND ${CMAKE_COMMAND} -E echo " Wrapper Header: ${WRAPPER_HEADER}"
VERBATIM
)