# Copyright Advanced Micro Devices, Inc., or its affiliates. # SPDX-License-Identifier: MIT cmake_minimum_required(VERSION 3.25.2 FATAL_ERROR) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(hipsparse_shim) option(CMAKE_EXPORT_COMPILE_COMMANDS "Export compile_commands.json for clang tooling support" ON) project(hipsparse VERSION 4.7.0 LANGUAGES CXX C) if(POLICY CMP0066) cmake_policy(SET CMP0066 NEW) # Honor per-config flags in try_compile() endif() if(POLICY CMP0077) cmake_policy(SET CMP0077 NEW) # option() honors normal variables endif() # Set cpack license file here to avoid rocm-cmake warning set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md") include(fetch_rocm_cmake) include(GNUInstallDirs) rocm_setup_version(VERSION ${PROJECT_VERSION}) set(hipsparse_SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}") if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) if(WIN32) set(CMAKE_INSTALL_PREFIX "${PROJECT_BINARY_DIR}/package" CACHE PATH "Install path prefix." FORCE) else() set(CMAKE_INSTALL_PREFIX "/opt/rocm" CACHE PATH "Install path prefix." FORCE) endif() endif() # Configure Windows version resource file if(WIN32) string(TIMESTAMP HIPSPARSE_COPYRIGHT_YEAR "%Y") if(hipsparse_VERSION_TWEAK) set(HIPSPARSE_PRODUCT_VERSION_DISPLAY "${hipsparse_VERSION_MAJOR}.${hipsparse_VERSION_MINOR} (${hipsparse_VERSION_TWEAK})") else() set(HIPSPARSE_PRODUCT_VERSION_DISPLAY "${hipsparse_VERSION_MAJOR}.${hipsparse_VERSION_MINOR}") endif() configure_file("${CMAKE_CURRENT_SOURCE_DIR}/library/src/version.rc.in" "${PROJECT_BINARY_DIR}/version.rc" @ONLY) endif() # --- Build options and validation --- option(HIPSPARSE_ENABLE_CUDA "Build hipSPARSE with CUDA backend." OFF) option(HIPSPARSE_ENABLE_HIP "Build hipSPARSE with HIP backend." ON) option(HIPSPARSE_BUILD_SHARED_LIBS "Build hipSPARSE as a shared library." ON) set(BUILD_SHARED_LIBS ${HIPSPARSE_BUILD_SHARED_LIBS}) option(HIPSPARSE_ENABLE_HOST "Build hipSPARSE library." ON) option(HIPSPARSE_ENABLE_CLIENT "Build hipSPARSE clients." OFF) if(HIPSPARSE_ENABLE_CLIENT) option(HIPSPARSE_ENABLE_BENCHMARKS "Build benchmark client." ON) option(HIPSPARSE_ENABLE_SAMPLES "Build sample programs." ON) if(WIN32) option(HIPSPARSE_ENABLE_FORTRAN "Enable Fortran client support." OFF) else() option(HIPSPARSE_ENABLE_FORTRAN "Enable Fortran client support." ON) endif() option(HIPSPARSE_ENABLE_OPENMP "Enable OpenMP support in clients for parallel execution." ON) endif() option(HIPSPARSE_BUILD_TESTING "Build test client." OFF) option(HIPSPARSE_ENABLE_SPMV_BSR "Build hipSPARSE with BSR format support in hipsparseSpMV." ON) option(BUILD_WITH_CSC_TRSV "Build hipSPARSE clients with CSC format support tests for hipsparseSpSV (requires a rocSPARSE built with BUILD_WITH_CSC_TRSV)." ON) option(BUILD_WITH_CSC_TRSM "Build hipSPARSE clients with CSC format support tests for hipsparseSpSM (requires a rocSPARSE built with BUILD_WITH_CSC_TRSM)." ON) option(HIPSPARSE_ENABLE_COVERAGE "Build with code coverage enabled." OFF) option(HIPSPARSE_ENABLE_ASAN "Build with address sanitizer enabled." OFF) option(HIPSPARSE_BUILD_DOCS "Build documentation." OFF) # Validate incompatible option combinations include(hipsparse_compatibility) # Set default build type if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to 'Release' as none was specified.") set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "" "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() if(HIPSPARSE_ENABLE_FORTRAN) enable_language(Fortran) endif() # --- Dependency Setup --- find_package(Python3 3.9 COMPONENTS Interpreter REQUIRED) if(HIPSPARSE_ENABLE_CUDA) find_package(HIP REQUIRED CONFIG) find_package(CUDAToolkit REQUIRED) elseif(HIPSPARSE_ENABLE_HIP) find_package(hip REQUIRED CONFIG) find_package(rocsparse REQUIRED) get_target_property(ROCSPARSE_LOCATION roc::rocsparse LOCATION) message(STATUS "Found rocsparse shared library: ${ROCSPARSE_LOCATION}") endif() if(HIPSPARSE_ENABLE_CLIENT OR HIPSPARSE_BUILD_TESTING OR BUILD_TESTING) if(HIPSPARSE_ENABLE_OPENMP) find_package(OpenMP REQUIRED) endif() endif() # --- Library target --- if(HIPSPARSE_ENABLE_HOST) add_subdirectory(library) endif() # Must be set before add_subdirectory(clients): clients/tests needs it for CTest categories # (shared/ctest/TestCategories.cmake and test_categories.yaml). if(NOT DEFINED ROCM_LIBRARIES_ROOT) set(ROCM_LIBRARIES_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../..") endif() # --- Client targets --- if(HIPSPARSE_ENABLE_CLIENT OR HIPSPARSE_BUILD_TESTING OR BUILD_TESTING) # Required at project root so ${CMAKE_BINARY_DIR}/CTestTestfile.cmake exists. # Otherwise ctest run from the build root finds no tests (they only lived under clients/). enable_testing() include(rocm_client_prerequisites) add_subdirectory(clients) endif() # --- Packaging and installation --- if(HIPSPARSE_ENABLE_HOST) rocm_package_setup_component(runtime) endif() if(HIPSPARSE_ENABLE_CLIENT OR HIPSPARSE_BUILD_TESTING OR BUILD_TESTING) rocm_package_setup_component(clients) rocm_package_setup_client_component(clients-common) endif() if(HIPSPARSE_BUILD_TESTING OR BUILD_TESTING) rocm_package_setup_client_component( tests DEPENDS COMPONENT clients-common DEB "${GFORTRAN_DEB}" RPM "${GFORTRAN_RPM}" ) rocm_package_setup_client_component( tests DEPENDS COMPONENT clients-common DEB "${OPENMP_DEB}" RPM "${OPENMP_RPM}" ) endif() if(HIPSPARSE_ENABLE_BENCHMARKS) rocm_package_setup_client_component( benchmarks DEPENDS COMPONENT clients-common DEB "${OPENMP_DEB}" RPM "${OPENMP_RPM}" ) endif() if(HIPSPARSE_BUILD_TESTING OR BUILD_TESTING) if(NOT WIN32) rocm_package_add_rpm_dependencies(COMPONENT tests DEPENDS "${GFORTRAN_RPM}") rocm_package_add_deb_dependencies(COMPONENT tests DEPENDS "${GFORTRAN_DEB}") if(HIPSPARSE_ENABLE_OPENMP) rocm_package_add_rpm_dependencies(COMPONENT tests DEPENDS "${OPENMP_RPM}") rocm_package_add_deb_dependencies(COMPONENT tests DEPENDS "${OPENMP_DEB}") endif() endif() endif() if(HIPSPARSE_ENABLE_BENCHMARKS) if(NOT WIN32) rocm_package_add_rpm_dependencies(COMPONENT benchmarks DEPENDS "${GFORTRAN_RPM}") rocm_package_add_deb_dependencies(COMPONENT benchmarks DEPENDS "${GFORTRAN_DEB}") if(HIPSPARSE_ENABLE_OPENMP) rocm_package_add_rpm_dependencies(COMPONENT benchmarks DEPENDS "${OPENMP_RPM}") rocm_package_add_deb_dependencies(COMPONENT benchmarks DEPENDS "${OPENMP_DEB}") endif() endif() endif() if(HIPSPARSE_ENABLE_HIP) set(ROCSPARSE_MINIMUM "4.0.1") rocm_package_add_dependencies(SHARED_DEPENDS "rocsparse >= ${ROCSPARSE_MINIMUM}") rocm_package_add_deb_dependencies(STATIC_DEPENDS "rocsparse-static-dev >= ${ROCSPARSE_MINIMUM}") rocm_package_add_rpm_dependencies(STATIC_DEPENDS "rocsparse-static-devel >= ${ROCSPARSE_MINIMUM}") endif() set(CPACK_RPM_PACKAGE_LICENSE "MIT") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") if(WIN32) set(CPACK_SOURCE_GENERATOR "ZIP") set(CPACK_GENERATOR "ZIP") set(CPACK_SET_DESTDIR OFF) set(CPACK_PACKAGE_INSTALL_DIRECTORY "C:/hipSDK") set(CPACK_PACKAGING_INSTALL_PREFIX "") set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF) else() if(NOT CPACK_PACKAGING_INSTALL_PREFIX) set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") endif() endif() set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "\${CPACK_PACKAGING_INSTALL_PREFIX}") if(HIPSPARSE_ENABLE_HIP) set(package_name hipsparse) elseif(HIPSPARSE_ENABLE_CUDA) set(package_name hipsparse-alt) endif() set(HIPSPARSE_CONFIG_DIR "\${CPACK_PACKAGING_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" CACHE PATH "Path placed into ldconfig file") rocm_create_package( NAME ${package_name} DESCRIPTION "ROCm SPARSE library" MAINTAINER "hipSPARSE Maintainer " LDCONFIG LDCONFIG_DIR ${HIPSPARSE_CONFIG_DIR} ) # --- Documentation --- if(HIPSPARSE_BUILD_DOCS) add_subdirectory(docs) endif() # --- Code coverage targets --- if(HIPSPARSE_ENABLE_COVERAGE) set(hipsparse_coverage_dir "${CMAKE_BINARY_DIR}/lcoverage") # Apply coverage to main library target_compile_options(hipsparse PRIVATE -fprofile-arcs -ftest-coverage) target_link_options(hipsparse PRIVATE --coverage) # Apply coverage to client common libraries if(HIPSPARSE_ENABLE_CLIENT) target_compile_options(hipsparse-clients-common PUBLIC -fprofile-arcs -ftest-coverage) target_link_options(hipsparse-clients-common PUBLIC --coverage) target_compile_options(hipsparse-samples-common PUBLIC -fprofile-arcs -ftest-coverage) target_link_options(hipsparse-samples-common PUBLIC --coverage) endif() add_custom_target(coverage_cleanup COMMAND find ${CMAKE_BINARY_DIR} -name *.gcda -delete WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Cleaning up coverage data files" ) add_custom_target(coverage_analysis COMMAND echo Coverage GTEST_FILTER=\${GTEST_FILTER} COMMAND $ --gtest_filter=\"\${GTEST_FILTER}\" WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Running tests for coverage analysis" ) add_dependencies(coverage_analysis hipsparse-test) add_custom_target(coverage_output DEPENDS coverage_analysis COMMAND mkdir -p lcoverage COMMAND lcov --directory . --base-directory . --capture -o "${hipsparse_coverage_dir}/raw_main_coverage.info" COMMAND lcov --remove "${hipsparse_coverage_dir}/raw_main_coverage.info" "'/opt/*'" "'/usr/*'" -o "${hipsparse_coverage_dir}/main_coverage.info" COMMAND genhtml "${hipsparse_coverage_dir}/main_coverage.info" --output-directory "${hipsparse_coverage_dir}" COMMENT "Generating coverage report" ) add_custom_target(coverage DEPENDS coverage_output) endif() # --- Address Sanitizer targets --- if(HIPSPARSE_ENABLE_ASAN) # Apply ASAN to main library target_compile_options(hipsparse PRIVATE -fsanitize=address -shared-libasan) target_link_options(hipsparse PRIVATE -fsanitize=address -shared-libasan -fuse-ld=lld) # Apply ASAN to client common libraries if(HIPSPARSE_ENABLE_CLIENT OR HIPSPARSE_BUILD_TESTING OR BUILD_TESTING) target_compile_options(hipsparse-clients-common PUBLIC -fsanitize=address -shared-libasan) target_link_options(hipsparse-clients-common PUBLIC -fsanitize=address -shared-libasan -fuse-ld=lld) target_compile_options(hipsparse-samples-common PUBLIC -fsanitize=address -shared-libasan) target_link_options(hipsparse-samples-common PUBLIC -fsanitize=address -shared-libasan -fuse-ld=lld) endif() endif()