# Copyright (c) Advanced Micro Devices, Inc. All rights reserved. # # SPDX-License-Identifier: MIT # Top-level CMake file for AIS # CMake version according to latest ROCm platform requirements cmake_minimum_required(VERSION 3.21) # Set the default CMake build type # # NOTE: This has to be done BEFORE the project is declared! if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Build type") endif() # Set the library version in a variable so we can use # it in *.in files and avoid version mismatch. set(AIS_LIBRARY_MAJOR 0) set(AIS_LIBRARY_MINOR 4) set(AIS_LIBRARY_PATCH 0) set(AIS_LIBRARY_VERSION "${AIS_LIBRARY_MAJOR}.${AIS_LIBRARY_MINOR}.${AIS_LIBRARY_PATCH}") # Set the SOVERSION to the major library version (this is the default # but we set it explicitly to convey intent). # # Changes to minor and patch releases must NEVER break the ABI. This # includes things like reordering struct fields that don't break the API. set(AIS_LIBRARY_SOVERSION "${AIS_LIBRARY_MAJOR}") project("hipfile" VERSION ${AIS_LIBRARY_VERSION} DESCRIPTION "Direct-to-GPU IO for AMD's ROCm platform" LANGUAGES C CXX HIP ) # Switch between building static and shared libraries option(BUILD_SHARED_LIBS "Build using shared libraries" ON) # Set the path to the include directories for later use # Do this early so we can use these later, in functions, etc. set(HIPFILE_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}") set(HIPFILE_INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/include") set(HIPFILE_AMD_SOURCE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/amd_detail") set(HIPFILE_NVIDIA_SOURCE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/nvidia_detail") set(HIPFILE_SRC_COMMON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/common") set(HIPFILE_TEST_COMMON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/test/common") set(HIPFILE_AMD_TEST_PATH "${CMAKE_CURRENT_SOURCE_DIR}/test/amd_detail") set(HIPFILE_THIRD_PARTY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/third-party") set(AIS_CXX_STANDARD "20" CACHE STRING "C++ standard to build with") set_property(CACHE AIS_CXX_STANDARD PROPERTY STRINGS "20" "23" "26") # Set the list of build types for ccmake/CMake GUI # # This turns the build type box into a multi-select so you don't have to # enter the names manually # # "None" sets nothing, so it's easier to override -O flags, etc. set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo" "MinSizeRel" "None") # Enable CTest (the include line automatically calls enable_testing()) include(CTest) # Enable options with dependencies include(CMakeDependentOption) # Ensure compile_commands.json has implicit header paths if(CMAKE_EXPORT_COMPILE_COMMANDS) set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) endif() #----------------------------------------------------------------------------- # Get the HIP platform #----------------------------------------------------------------------------- # The default is "amd" if CMAKE_HIP_PLATFORM hasn't been set if(NOT CMAKE_HIP_PLATFORM) set(CMAKE_HIP_PLATFORM "amd" CACHE STRING "HIP platform to build with") endif() set_property(CACHE CMAKE_HIP_PLATFORM PROPERTY STRINGS "amd" "nvidia") # Set the HIP_PLATFORM environment variable so that HIP headers are # parsed correctly set(ENV{HIP_PLATFORM} ${CMAKE_HIP_PLATFORM}) # Make sure the HIP platform is valid if(NOT CMAKE_HIP_PLATFORM STREQUAL "amd" AND NOT CMAKE_HIP_PLATFORM STREQUAL "nvidia") message(FATAL_ERROR "Invalid CMAKE_HIP_PLATFORM: '${CMAKE_HIP_PLATFORM}'. Allowed values are 'amd' or 'nvidia'.") endif() # Set the platform variables (internal only) if(CMAKE_HIP_PLATFORM STREQUAL "nvidia") set(AIS_BUILD_AMD_DETAIL OFF) set(AIS_BUILD_NVIDIA_DETAIL ON) else() set(AIS_BUILD_AMD_DETAIL ON) set(AIS_BUILD_NVIDIA_DETAIL OFF) endif() #----------------------------------------------------------------------------- # Include our custom CMake code in the module path #----------------------------------------------------------------------------- set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) #----------------------------------------------------------------------------- # Set ROCm Version and Install Path # # Values are set with the following prioritization in case of redundant declarations: # 1) CMake Argument # 2) Environment Variables # 3) Default Values # # Note: project(... LANGUAGES HIP) only looks at $ENV{ROCM_PATH} and will ignore # ROCM_PATH set as a CMake Argument. #----------------------------------------------------------------------------- # If ROCM_VERSION was set in the environment, seed it with that if(NOT DEFINED ROCM_VERSION AND DEFINED ENV{ROCM_VERSION}) set(ROCM_VERSION "$ENV{ROCM_VERSION}") endif() # If ROCM_PATH was set in the environment, seed it with that if(DEFINED ENV{ROCM_PATH}) set(ROCM_INITIAL_PATH "$ENV{ROCM_PATH}") elseif(DEFINED ROCM_VERSION) # ROCm 7.11+ installs to /opt/rocm/core-MAJOR.MINOR (new repo.amd.com layout); # earlier releases install to /opt/rocm-MAJOR.MINOR.PATCH. string(REGEX MATCH "^([0-9]+)\\.([0-9]+)" _rocm_mm "${ROCM_VERSION}") if(NOT _rocm_mm) message(FATAL_ERROR "ROCM_VERSION='${ROCM_VERSION}' does not match the expected " "MAJOR.MINOR[.PATCH] form (e.g., 7.13.0).") endif() set(_rocm_major "${CMAKE_MATCH_1}") set(_rocm_minor "${CMAKE_MATCH_2}") if(_rocm_major GREATER 7 OR (_rocm_major EQUAL 7 AND _rocm_minor GREATER_EQUAL 11)) set(ROCM_INITIAL_PATH "/opt/rocm/core-${_rocm_major}.${_rocm_minor}") else() set(ROCM_INITIAL_PATH "/opt/rocm-${ROCM_VERSION}") endif() else() # Default install location symlink set(ROCM_INITIAL_PATH "/opt/rocm") endif() set(ROCM_PATH "${ROCM_INITIAL_PATH}" CACHE PATH "The path to the ROCm installation") # Fallback if ROCM_VERSION not specified. Get from version file in ROCM_PATH if(NOT DEFINED ROCM_VERSION) file(READ "${ROCM_PATH}/.info/version" _rocm_version_file) string(REGEX MATCH "^([0-9]+\\.[0-9]+\\.[0-9]+)" _matched_rocm_version "${_rocm_version_file}") set(ROCM_VERSION "${_matched_rocm_version}") endif() set(ROCM_VERSION "${ROCM_VERSION}" CACHE STRING "The version of ROCm to build with") message(STATUS "Using ROCM_VERSION: ${ROCM_VERSION}") message(STATUS "ROCM_PATH set to: ${ROCM_PATH}") # Add ROCm search paths list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/llvm ${ROCM_PATH} ${ROCM_PATH}/hip /opt/rocm/llvm /opt/rocm /opt/rocm/hip ) # Set hipFile Install Path to the ROCm directory # Note: CMAKE_INSTALL_PREFIX is set to a default by project(). if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${ROCM_PATH}" CACHE PATH "The path where hipFile should be installed" FORCE) endif() # Fix library install directory to "lib" to be inline with the rest of ROCm # Note: If testing is enabled, installing GTest calls GNUInstallDirs which will # set this before ROCMInstallTargets can set it. set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Directory name for installed ROCm libraries") #----------------------------------------------------------------------------- # Import useful things for later #----------------------------------------------------------------------------- include(AISAddLibraries) #----------------------------------------------------------------------------- # Options #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Code coverage (via llvm-cov) # # To use with the hipFile library: # - Build with AIS_USE_CODE_COVERAGE set to ON # - Run `ctest .` # # This should create a default.profraw file in each test directory # # In each test directory: # - Run `llvm-profdata merge -output=.profdata default.profraw` # # The show command gives line-by-line coverage, report gives a summary # - Run `llvm-cov -instr-profile=.profdata` # # You can export the data to lcov or json # - Run `llvm-cov export -instr-profile=ais.profdata -format= > coverage.` #----------------------------------------------------------------------------- option(AIS_USE_CODE_COVERAGE "Build with code coverage flags (llvm C++ only)" OFF) #---------------------------------------------- # Clang "safe buffer" warnings and suggestions #---------------------------------------------- include(AISClangSafeBuffers) #---------------- # Run clang-tidy #---------------- include(AISClangTidy) #--------------------------------- # Run include-what-you-use (IWYU) #--------------------------------- include(AISIWYU) #------------------- # Sanitizer options #------------------- include(AISSanitizers) #------------------ # Example programs #------------------ option(AIS_INSTALL_EXAMPLES "Install example programs" ON) #------------------ # Tool programs #------------------ option(AIS_INSTALL_TOOLS "Install tool programs" ON) #------------------ # rocprofiler-register integration #------------------ option(HIPFILE_ROCPROFILER_REGISTER "Enable rocprofiler-register API table registration" ON) #------------------ # Test programs #------------------ # Whether to install the relocatable unit-test assets (binaries + ctest files) # so the suite can run from an installed/packaged tree. Default OFF, separate # from the build of the tests, matching the convention used by sibling projects # (e.g. rocprofiler-systems' ROCPROFSYS_INSTALL_TESTING). Installing the tests # requires building them, so enabling this forces BUILD_TESTING on. option(AIS_INSTALL_TESTS "Install unit-test programs" OFF) if(AIS_INSTALL_TESTS) set(BUILD_TESTING ON CACHE BOOL "Build testing (forced on by AIS_INSTALL_TESTS)" FORCE) endif() #------ # docs #------ include(AISDocumentation) #----------------------------------------------------------------------------- # Find important packages for building the software #----------------------------------------------------------------------------- find_package(hsa-runtime64 CONFIG REQUIRED) if(${hsa-runtime64_FOUND}) message(STATUS "hsa-runtime64 found @ ${hsa-runtime64_DIR} ") else() message(NOTICE "find_package did NOT find hsa-runtime64") endif() find_package(hip CONFIG REQUIRED) if(${hip_FOUND}) message(STATUS "hip found @ ${hip_DIR} ") else() message(NOTICE "find_package did NOT find hip") endif() if(HIPFILE_ROCPROFILER_REGISTER AND AIS_BUILD_AMD_DETAIL) find_package( rocprofiler-register REQUIRED HINTS $ENV{rocprofiler_register_ROOT} $ENV{ROCPROFILER_REGISTER_ROOT} ${CMAKE_INSTALL_PREFIX} PATHS ${ROCM_PATH}) endif() # Find the cuFile library and headers on NVIDIA if(AIS_BUILD_NVIDIA_DETAIL) find_package(CUDAToolkit REQUIRED) if(CMAKE_VERSION VERSION_LESS "3.28") enable_language(CUDA) # Set a default architecture if not provided. if(NOT CMAKE_CUDA_ARCHITECTURES) set(CMAKE_CUDA_ARCHITECTURES 80) endif() endif() find_library(CUFILE_LIBRARY cufile PATHS ${CUDAToolkit_LIBRARY_DIR}) if(NOT CUFILE_LIBRARY) message(FATAL_ERROR "cuFile library not found") endif() endif() if(NOT AIS_CAPABLE_DIR) set(AIS_CAPABLE_DIR "/tmp" CACHE STRING "Directory to use for e2e tests.") endif() option(HIPFILE_ALLOW_SKIP_FASTPATH_TESTS "Skip (instead of fail) fastpath-only tests when fastpath is unavailable" OFF) #----------------------------------------------------------------------------- # Configure hipFile #----------------------------------------------------------------------------- # Add the src directory depending on the HIP platform if(AIS_BUILD_NVIDIA_DETAIL) add_subdirectory(src/nvidia_detail) else() add_subdirectory(src/amd_detail) endif() # Add the testing directories if(BUILD_TESTING) include(AISUseGTest) add_subdirectory(test) endif() if(BUILD_TESTING AND AIS_BUILD_AMD_DETAIL) add_subdirectory(test/amd_detail) endif() # Add the example directory if(AIS_INSTALL_EXAMPLES) add_subdirectory(examples/aiscp) add_subdirectory(examples/api) add_subdirectory(examples/common) add_subdirectory(examples/basics) add_subdirectory(examples/async) endif() # Add tools directory if(AIS_INSTALL_TOOLS AND AIS_BUILD_AMD_DETAIL) add_subdirectory(tools/ais-stats) endif() #----------------------------------------------------------------------------- # Set up installs (must come AFTER target creation) #----------------------------------------------------------------------------- include(AISUseROCmCMake) # Install the relocatable unit-test assets (binaries + a self-locating # CTestTestfile.cmake) so the suite can run from an installed/packaged tree. # Gated on AIS_INSTALL_TESTS (which forces BUILD_TESTING on above, so the test # targets exist). Must come after the test targets are created # (add_subdirectory(test) above). if(AIS_INSTALL_TESTS) include(AISInstallTests) endif() include(AISInstall)