Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cmake] add support for cuda 12 #210

Merged
merged 7 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ on:
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
container: [ "alicevision/cctag-deps:cuda11.8.0-ubuntu20.04", "alicevision/cctag-deps:cuda12.1.0-ubuntu22.04" ]
build_type: [ "Release", "Debug" ]

container:
image: alicevision/cctag-deps:cuda11.8.0-ubuntu20.04
image: ${{ matrix.container }}

env:
DEPS_INSTALL_DIR: /opt/
BUILD_TYPE: Release
BUILD_TYPE: ${{ matrix.build_type }}
CTEST_OUTPUT_ON_FAILURE: 1
steps:
- uses: actions/checkout@v2
Expand Down
33 changes: 19 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ if(BUILD_SHARED_LIBS)
endif()

if(CCTAG_WITH_CUDA)
set(CCTAG_MIN_CUDA_VERSION 9.0)
message( STATUS "Try finding CUDA" )
if(BUILD_SHARED_LIBS)
message(STATUS "BUILD_SHARED_LIBS ON")
Expand All @@ -149,7 +150,7 @@ if(CCTAG_WITH_CUDA)
set(CUDA_USE_STATIC_CUDA_RUNTIME ON)
endif()

find_package(CUDA 9.0 REQUIRED)
find_package(CUDA ${CCTAG_MIN_CUDA_VERSION} REQUIRED)

include(CheckNvccCompilerFlag)

Expand All @@ -165,22 +166,26 @@ if(CCTAG_WITH_CUDA)
message(STATUS "Building in release mode")
endif()

set(CCTAG_CUDA_CC_LIST_INIT0 3.5 3.7 5.0 5.2)
if( CUDA_VERSION VERSION_GREATER_EQUAL "9.0" )
list(APPEND CCTAG_CUDA_CC_LIST_INIT0 6.0 6.1 7.0)
endif()
if( CUDA_VERSION VERSION_GREATER_EQUAL "10.0" )
list(APPEND CCTAG_CUDA_CC_LIST_INIT0 7.5)
endif()
set(CCTAG_CUDA_CC_LIST_INIT ${CCTAG_CUDA_CC_LIST_INIT0} CACHE STRING "CUDA CCs as compile targets")

# if CCTAG_CUDA_CC_CURRENT_ONLY is specified only build for the current hardware architecture
if(CCTAG_CUDA_CC_CURRENT_ONLY)
set(CCTAG_CUDA_CC_LIST_BASIC Auto)
CUDA_SELECT_NVCC_ARCH_FLAGS(CCTAG_CUDA_GENCODE_FLAGS ${CCTAG_CUDA_CC_LIST_BASIC})
else()
set(CCTAG_CUDA_CC_LIST_BASIC ${CCTAG_CUDA_CC_LIST_INIT})
# otherwise build for all the architectures that are compatible with the current version of CUDA
# or those that are provided by the user setting CCTAG_CUDA_CC_LIST
include(ChooseCudaCC)
if(NOT DEFINED CCTAG_CUDA_CC_LIST)
chooseCudaCC(CCTAG_CUDA_CC_LIST_BASIC
CCTAG_CUDA_GENCODE_FLAGS
MIN_CC 30
MIN_CUDA_VERSION ${CCTAG_MIN_CUDA_VERSION})
set(CCTAG_CUDA_CC_LIST ${CCTAG_CUDA_CC_LIST_BASIC} CACHE STRING "CUDA CC versions to compile")
else()
getFlagsForCudaCCList(CCTAG_CUDA_CC_LIST CCTAG_CUDA_GENCODE_FLAGS)
endif()
endif()
CUDA_SELECT_NVCC_ARCH_FLAGS(ARCH_FLAGS ${CCTAG_CUDA_CC_LIST_BASIC})
LIST(APPEND CUDA_NVCC_FLAGS ${ARCH_FLAGS})

list(APPEND CUDA_NVCC_FLAGS "${CCTAG_CUDA_GENCODE_FLAGS}")

if(NOT MSVC)
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};-std=c++${CCTAG_CXX_STANDARD}")
Expand Down Expand Up @@ -273,7 +278,7 @@ message(STATUS "Build tests: " ${CCTAG_BUILD_TESTS})
message(STATUS "Build documentation: " ${CCTAG_BUILD_DOC})
message(STATUS "Cuda support: " ${CCTAG_WITH_CUDA})
if(CCTAG_WITH_CUDA)
message(STATUS "Compiling for CUDA CCs: ${ARCH_FLAGS}")
message(STATUS "Compiling for CUDA CCs: ${CCTAG_CUDA_GENCODE_FLAGS}")
endif()
message(STATUS "Enable Eigen alignment: " ${CCTAG_EIGEN_MEMORY_ALIGNMENT})
message(STATUS "Enable AVX2 optimizations: " ${CCTAG_ENABLE_SIMD_AVX2})
Expand Down
8 changes: 4 additions & 4 deletions Dockerfile_deps
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ RUN wget https://cmake.org/files/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION_FULL}.t
rm -rf cmake


ENV BOOST_VERSION="1.76.0"
ENV BOOST_VERSION_FILENAME="1_76_0"
ENV BOOST_VERSION="1.80.0"
ENV BOOST_VERSION_FILENAME="1_80_0"
WORKDIR /tmp/boost
RUN wget https://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION}/boost_${BOOST_VERSION_FILENAME}.tar.gz && \
tar -xzf boost_${BOOST_VERSION_FILENAME}.tar.gz && \
Expand All @@ -74,7 +74,7 @@ RUN wget https://gitlab.com/libeigen/eigen/-/archive/${EIGEN_VERSION}/${EIGEN_VE
rm -rf /tmp/eigen

# install opencv
ENV OPENCV_VERSION="4.5.3"
ENV OPENCV_VERSION="4.7.0"
WORKDIR /tmp/opencv
RUN wget https://github.com/opencv/opencv/archive/"${OPENCV_VERSION}".zip && \
unzip ${OPENCV_VERSION}.zip && \
Expand Down Expand Up @@ -102,7 +102,7 @@ RUN wget https://github.com/opencv/opencv/archive/"${OPENCV_VERSION}".zip && \
rm -r /tmp/opencv

# install tbb
ENV TBB_VERSION="2021.5.0"
ENV TBB_VERSION="2021.9.0"
WORKDIR /tmp/tbb
RUN wget https://github.com/oneapi-src/oneTBB/archive/refs/tags/v"${TBB_VERSION}".zip && \
unzip v${TBB_VERSION}.zip && \
Expand Down
184 changes: 184 additions & 0 deletions cmake/ChooseCudaCC.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#
# This file contains two functions:
# chooseCudaCC
# getFlagsForCudaCCList
#
# Motivation:
# CUDA hardware and SDKs are developing over time, different SDK support different
# hardware, and supported hardware differs depending on platform even for the same
# SDK version. This file attempts to provide a function that returns a valid selection
# of hardware for the current SDK and platform. It will require updates as CUDA develops,
# and it is currently not complete in terms of existing platforms that support CUDA.
#

#
# Return the minimal set of supported Cuda CC
#
# Usage:
# chooseCudaCC(SUPPORTED_CC SUPPORTED_GENCODE_FLAGS
# [MIN_CUDA_VERSION X.Y]
# [MIN_CC XX ])
#
# SUPPORTED_CC out variable. Stores the list of supported CC.
# SUPPORTED_GENCODE_FLAGS out variable. List of gencode flags to append to, e.g., CUDA_NVCC_FLAGS
# MIN_CUDA_VERSION the minimal supported version of cuda (e.g. 7.5, default 7.0).
# MIN_CC minimal supported Cuda CC by the project (e.g. 35, default 20)
#
# This function does not edit cache entries or variables in the parent scope
# except for the variables whose names are supplied for SUPPORTED_CC and
# SUPPORTED_GENCODE_FLAGS
#
# You may want to cache SUPPORTED_CC and append SUPPORTED_GENCODE_FLAGS to
# CUDA_NVCC_FLAGS.
# Like this:
# set(MYCC ${MYCC} CACHE STRING "CUDA CC versions to compile")
# end
# set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS};${MY_GENCODE_FLAGS}")
#
function(chooseCudaCC SUPPORTED_CC SUPPORTED_GENCODE_FLAGS)
set(options "")
set(oneValueArgs MIN_CUDA_VERSION MIN_CC)
set(multipleValueArgs "")
cmake_parse_arguments(CHOOSE_CUDA "${options}" "${oneValueArgs}" "${multipleValueArgs}" ${ARGN})

if(NOT DEFINED CHOOSE_CUDA_MIN_CC)
set(CHOOSE_CUDA_MIN_CC 20)
endif()
if(NOT DEFINED CHOOSE_CUDA_MIN_CUDA_VERSION)
set(CHOOSE_CUDA_MIN_CUDA_VERSION 7.0)
endif()

find_package(CUDA ${CHOOSE_CUDA_MIN_CUDA_VERSION} REQUIRED)

if(NOT CUDA_FOUND)
message(FATAL_ERROR "Could not find CUDA >= ${CHOOSE_CUDA_MIN_CUDA_VERSION}")
endif()

#
# Create a list of possible CCs for each host processor.
# This may require tuning: CUDA cards exist in AIX machines with POWER CPUs,
# it is possible that non-Tegra ARM systems exist as well.
# For now, this is my best guess.
#
set(TEGRA_SUPPORTED_PROCESSORS "armv71;arm;aarch64")
set(OTHER_SUPPORTED_PROCESSORS "i686;x86_64;AMD64")

set(CC_LIST_BY_SYSTEM_PROCESSOR "")
if(CMAKE_SYSTEM_PROCESSOR IN_LIST OTHER_SUPPORTED_PROCESSORS)
list(APPEND CC_LIST_BY_SYSTEM_PROCESSOR "20;21;30;35;50;52;60;61;70;75;80;86;89;90")
endif()
if(CMAKE_SYSTEM_PROCESSOR IN_LIST TEGRA_SUPPORTED_PROCESSORS)
list(APPEND CC_LIST_BY_SYSTEM_PROCESSOR "32;53;62;72")
endif()
if(NOT CC_LIST_BY_SYSTEM_PROCESSOR)
message(FATAL_ERROR "Unknown how to build for ${CMAKE_SYSTEM_PROCESSOR}")
endif()

#
# Default setting of the CUDA CC versions to compile.
# Shortening the lists saves a lot of compile time.
#

# The current version last time this list was updated was CUDA 12.1.
if(CUDA_VERSION VERSION_GREATER_EQUAL 12)
set(CUDA_MIN_CC 50)
set(CUDA_MAX_CC 90)
elseif(CUDA_VERSION VERSION_GREATER_EQUAL 11.8)
set(CUDA_MIN_CC 35)
set(CUDA_MAX_CC 90)
elseif(CUDA_VERSION VERSION_GREATER_EQUAL 11.1)
set(CUDA_MIN_CC 35)
set(CUDA_MAX_CC 86)
elseif(CUDA_VERSION_MAJOR GREATER_EQUAL 11)
set(CUDA_MIN_CC 35)
set(CUDA_MAX_CC 80)
elseif(CUDA_VERSION_MAJOR GREATER_EQUAL 10)
set(CUDA_MIN_CC 30)
set(CUDA_MAX_CC 75)
elseif(CUDA_VERSION_MAJOR GREATER_EQUAL 9)
set(CUDA_MIN_CC 30)
set(CUDA_MAX_CC 72)
elseif(CUDA_VERSION_MAJOR GREATER_EQUAL 8)
set(CUDA_MIN_CC 20)
set(CUDA_MAX_CC 62)
elseif(CUDA_VERSION_MAJOR GREATER_EQUAL 7)
set(CUDA_MIN_CC 20)
set(CUDA_MAX_CC 53)
else()
message(FATAL_ERROR "We do not support a CUDA SDK below version 7.0")
endif()
if(${CHOOSE_CUDA_MIN_CC} GREATER ${CUDA_MIN_CC})
set(CUDA_MIN_CC ${CHOOSE_CUDA_MIN_CC})
endif()

set(CC_LIST "")
foreach(CC ${CC_LIST_BY_SYSTEM_PROCESSOR})
if( (${CC} GREATER_EQUAL ${CUDA_MIN_CC}) AND
(${CC} LESS_EQUAL ${CUDA_MAX_CC}) )
list(APPEND CC_LIST ${CC})
endif()
endforeach()

#
# Add all requested CUDA CCs to the command line for offline compilation
#
set(GENCODE_FLAGS "")
list(SORT CC_LIST)
foreach(CC_VERSION ${CC_LIST})
list(APPEND GENCODE_FLAGS "-gencode;arch=compute_${CC_VERSION},code=sm_${CC_VERSION}")
endforeach()

#
# Use the highest request CUDA CC for CUDA JIT compilation
#
list(LENGTH CC_LIST CC_LIST_LEN)
MATH(EXPR CC_LIST_LEN "${CC_LIST_LEN}-1")
list(GET CC_LIST ${CC_LIST_LEN} CC_LIST_LAST)
list(APPEND GENCODE_FLAGS "-gencode;arch=compute_${CC_LIST_LAST},code=compute_${CC_LIST_LAST}")

#
# Two variables are exported to the parent scope. One is passed through the
# environment (CUDA_NVCC_FLAGS), the other is passed by name (SUPPORTED_CC)
#
set(${SUPPORTED_GENCODE_FLAGS} "${GENCODE_FLAGS}" PARENT_SCOPE)
set(${SUPPORTED_CC} "${CC_LIST}" PARENT_SCOPE)
endfunction()

#
# Return the gencode parameters for a given list of CCs.
#
# Usage:
# getFlagsForCudaCCList(INPUT_CC_LIST SUPPORTED_GENCODE_FLAGS)
#
# INPUT_CC_LIST in variable. Contains a list of supported CCs.
# SUPPORTED_GENCODE_FLAGS out variable. List of gencode flags to append to, e.g., CUDA_NVCC_FLAGS
#
function(getFlagsForCudaCCList INPUT_CC_LIST SUPPORTED_GENCODE_FLAGS)
set(CC_LIST "${${INPUT_CC_LIST}}")

#
# Add all requested CUDA CCs to the command line for offline compilation
#
set(GENCODE_FLAGS "")
list(SORT CC_LIST)
foreach(CC_VERSION ${CC_LIST})
list(APPEND GENCODE_FLAGS "-gencode;arch=compute_${CC_VERSION},code=sm_${CC_VERSION}")
endforeach()

#
# Use the highest request CUDA CC for CUDA JIT compilation
#
list(LENGTH CC_LIST CC_LIST_LEN)
MATH(EXPR CC_LIST_LEN "${CC_LIST_LEN}-1")
list(GET CC_LIST ${CC_LIST_LEN} CC_LIST_LAST)
list(APPEND GENCODE_FLAGS "-gencode;arch=compute_${CC_LIST_LAST},code=compute_${CC_LIST_LAST}")

message(STATUS "Setting gencode flags: ${GENCODE_FLAGS}")

#
# Two variables are exported to the parent scope. One is passed through the
# environment (CUDA_NVCC_FLAGS), the other is passed by name (SUPPORTED_CC)
#
set(${SUPPORTED_GENCODE_FLAGS} "${GENCODE_FLAGS}" PARENT_SCOPE)
endfunction()

Loading