Skip to content

Commit

Permalink
feat: adding release v0.13.0 of CV-CUDA (#219)
Browse files Browse the repository at this point in the history
  • Loading branch information
milesp-nvidia authored Dec 5, 2024
1 parent 07d5e44 commit 2a73733
Show file tree
Hide file tree
Showing 30 changed files with 2,350 additions and 147 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ endif()

project(cvcuda
LANGUAGES C CXX
VERSION 0.12.0
VERSION 0.13.0
DESCRIPTION "CUDA-accelerated Computer Vision algorithms"
)

Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

[![License](https://img.shields.io/badge/License-Apache_2.0-yellogreen.svg)](https://opensource.org/licenses/Apache-2.0)

![Version](https://img.shields.io/badge/Version-v0.12.0--beta-blue)
![Version](https://img.shields.io/badge/Version-v0.13.0--beta-blue)

![Platform](https://img.shields.io/badge/Platform-linux--64_%7C_win--64_wsl2%7C_aarch64-gray)

Expand Down Expand Up @@ -239,12 +239,13 @@ cpack . -G [DEB|TXZ]

Python Wheels

By default during the `release` build, Python bindings and wheels are created for the available CUDA version and the specified Python version(s). The wheels are stored in `build-rel/pythonX.Y/wheel` folder, where `build-rel` is the build directory used to build the release build and `X` and `Y` are Python major and minor versions.
By default, during the `release` build, Python bindings and wheels are created for the available CUDA version and the specified Python version(s). The wheels are now output to the `build-rel/python3/repaired_wheels` folder (after being processed by the `auditwheel repair` command in the case of ManyLinux). The single generated python wheel is compatible with all versions of python specified during the cmake build step. Here, `build-rel` is the build directory used to build the release build.

The built wheels can be installed using pip.
For example, to install the Python wheel built for CUDA 12.x, Python 3.10 on Linux x86_64 systems:
The new Python wheels for PyPI compliance must be built within the ManyLinux 2014 Docker environment. The Docker images can be generated using the `docker/manylinux/docker_buildx.sh` script. These images ensure the wheels meet ManyLinux 2014 and PyPI standards.

The built wheels can still be installed using `pip`. For example, to install the Python wheel built for CUDA 12.x, Python 3.10 and 3.11 on Linux x86_64 systems:
```shell
pip install cvcuda_cu12-<x.x.x>-cp310-cp310-linux_x86_64.whl
pip install cvcuda_cu12-<x.x.x>-cp310.cp311-cp310.cp311-linux_x86_64.whl
```

## Contributing
Expand Down
46 changes: 38 additions & 8 deletions cmake/BuildPython.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ list(APPEND PYPROJ_COMMON_ARGS
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
)

# It need to overwrite the PYTHON_MODULE_EXTENSION to generate
# It needs to overwrite the PYTHON_MODULE_EXTENSION to generate
# python module name with correct name when cross compiling
# example: set(PYTHON_MODULE_EXTENSION .cpython-py38-aarch64-linux-gnu.so)
if (CMAKE_CROSSCOMPILING)
list(APPEND PYPROJ_COMMON_ARGS
-DCUDAToolkit_ROOT=${CUDAToolkit_ROOT}
-DPYTHON_MODULE_EXTENSION=${PYTHON_MODULE_EXTENSION}
)
list(APPEND PYPROJ_COMMON_ARGS
-DCUDAToolkit_ROOT=${CUDAToolkit_ROOT}
-DPYTHON_MODULE_EXTENSION=${PYTHON_MODULE_EXTENSION}
)
endif()

foreach(VER ${PYTHON_VERSIONS})
Expand All @@ -61,7 +61,7 @@ foreach(VER ${PYTHON_VERSIONS})
ExternalProject_Add(cvcuda_python${VER}
PREFIX ${BASEDIR}
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/python
CMAKE_ARGS ${PYPROJ_COMMON_ARGS} -DPYTHON_VERSION=${VER} -DBUILD_ROOT=${CMAKE_BINARY_DIR} -DPYTHON_VERSION_SHORT=${VER}
CMAKE_ARGS ${PYPROJ_COMMON_ARGS} -DPYTHON_VERSION=${VER}
BINARY_DIR ${BASEDIR}/build
TMP_DIR ${BASEDIR}/tmp
STAMP_DIR ${BASEDIR}/stamp
Expand All @@ -72,7 +72,37 @@ foreach(VER ${PYTHON_VERSIONS})
endforeach()

if(CMAKE_BUILD_TYPE STREQUAL "Release")
foreach(PYTHON_VERSION ${PYTHON_VERSIONS})
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/python/setup.py.in" "${CMAKE_BINARY_DIR}/python${PYTHON_VERSION}/setup.py")
set(PACKAGE_LIB_DIR ${CMAKE_BINARY_DIR}/python3/lib)

file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python3)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python3/lib)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python3/cvcuda)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python3/cvcuda/_bindings)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python3/nvcv)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python3/nvcv/_bindings)

configure_file("${CMAKE_CURRENT_SOURCE_DIR}/python/setup.py.in" "${CMAKE_BINARY_DIR}/python3/setup.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/python/__init__.py.in" "${CMAKE_BINARY_DIR}/python3/cvcuda/__init__.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/python/__init__.py.in" "${CMAKE_BINARY_DIR}/python3/nvcv/__init__.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/python/_load_binding.py.in" "${CMAKE_BINARY_DIR}/python3/cvcuda/_load_binding.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/python/_load_binding.py.in" "${CMAKE_BINARY_DIR}/python3/nvcv/_load_binding.py")

add_custom_target(wheel ALL)

foreach(VER ${PYTHON_VERSIONS})
add_dependencies(wheel cvcuda_python${VER})
endforeach()

add_custom_command(
TARGET wheel
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:cvcuda> ${CMAKE_BINARY_DIR}/python3/lib
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:nvcv_types> ${CMAKE_BINARY_DIR}/python3/lib
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/lib/python/cvcuda*.so ${CMAKE_BINARY_DIR}/python3/cvcuda/_bindings
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/lib/python/nvcv*.so ${CMAKE_BINARY_DIR}/python3/nvcv/_bindings
)

add_custom_command(
TARGET wheel
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/python/build_wheels.sh" "${CMAKE_BINARY_DIR}/python3"
)
endif()
13 changes: 10 additions & 3 deletions cmake/ConfigCompiler.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,11 @@ if(BUILD_TESTS)
set(candidate_compilers ${PUBLIC_API_COMPILERS})
else()
# If not, by default, we'll try these.
set(candidate_compilers gcc-11 gcc-9 clang-11 clang-14)
set(candidate_compilers gcc-11 gcc-10 gcc-9 clang-11 clang-14)
endif()

unset(valid_compilers)
set(at_least_one_compiler_found OFF)

foreach(comp ${candidate_compilers})
string(MAKE_C_IDENTIFIER "${comp}" comp_str)
Expand All @@ -93,14 +94,20 @@ if(BUILD_TESTS)
find_program(COMPILER_EXEC_${COMP_STR} ${comp})
if(COMPILER_EXEC_${COMP_STR})
list(APPEND valid_compilers ${comp})
set(at_least_one_compiler_found ON)
else()
if(PUBLIC_API_COMPILERS)
message(FATAL_ERROR "Compiler '${comp}' not found")
else()
message(WARNING "Compiler '${comp}' not found, skipping public API checks for it")
endif()
endif()
endforeach()

if(NOT at_least_one_compiler_found)
foreach(comp ${candidate_compilers})
message(WARNING "Compiler '${comp}' not found, skipping public API checks for it")
endforeach()
endif()

set(PUBLIC_API_COMPILERS "${valid_compilers}")
endif()

Expand Down
27 changes: 27 additions & 0 deletions cmake/ConfigPython.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,33 @@ file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cmake/cvcuda_$<LOWER_CASE:$<CON
# Python versions to build already set?
if(PYTHON_VERSIONS)
set(USE_DEFAULT_PYTHON false)

set(AVAILABLE_PYTHON_VERSIONS "")
foreach(VER ${PYTHON_VERSIONS})
find_program(PYTHON_EXECUTABLE python${VER} PATHS /usr/bin /usr/local/bin NO_DEFAULT_PATH)
if (PYTHON_EXECUTABLE)
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')"
OUTPUT_VARIABLE PYTHON_VERSION_OUTPUT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if (PYTHON_VERSION_OUTPUT STREQUAL ${VER})
list(APPEND AVAILABLE_PYTHON_VERSIONS ${VER})
else()
message(WARNING "Python executable ${PYTHON_EXECUTABLE} does not match version ${VER} (${PYTHON_VERSION_OUTPUT}). Skipping.")
endif()
else()
message(WARNING "Python version ${VER} not found. Skipping.")
endif()
unset(PYTHON_EXECUTABLE CACHE)
endforeach()

if(NOT AVAILABLE_PYTHON_VERSIONS)
message(FATAL_ERROR "No available Python versions found. Exiting.")
endif()

set(PYTHON_VERSIONS ${AVAILABLE_PYTHON_VERSIONS})
unset(AVAILABLE_PYTHON_VERSIONS)
# If not, gets the default version from FindPython
else()
find_package(Python COMPONENTS Interpreter REQUIRED)
Expand Down
117 changes: 117 additions & 0 deletions docker/manylinux/Dockerfile.build.manylinux2014.deps
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Build arguments and version numbers
ARG FROM_IMAGE_NAME=quay.io/pypa/manylinux2014_x86_64
ARG BUILDER_EXTRA_DEPS=scratch

# Base image
FROM ${BUILDER_EXTRA_DEPS} AS extra_deps
FROM ${FROM_IMAGE_NAME}

ARG ARCH=x86_64
ARG CC=gcc
ARG CXX=g++
ARG PATCHELF_VERSION=0.17.2
ARG CMAKE_VERSION=3.20.1
ARG PYVER=3.8
ARG PYV=38
ARG CLANG_VERSION=14.0
ARG SPHINX_VERSION=4.5.0

# Set build arguments as environment variables
ENV ARCH=${ARCH}
ENV CC=${CC}
ENV CXX=${CXX}
ENV PATCHELF_VERSION=${PATCHELF_VERSION}
ENV CMAKE_VERSION=${CMAKE_VERSION}
ENV PYVER=${PYVER}
ENV PYV=${PYV}
ENV CLANG_VERSION=${CLANG_VERSION}
ENV LIBCLANG_VERSION=${CLANG_VERSION}
ENV SPHINX_VERSION=${SPHINX_VERSION}

# Install additional dependencies
RUN yum install -y ninja-build ccache ShellCheck curl

# Configure ccache
RUN mkdir -p /cache
COPY ccache.conf /etc/ccache.conf
ENV CCACHE_CONFIGPATH=/etc/ccache.conf
ENV PRE_COMMIT_HOME=/cache/pre-commit

# Install patchelf (needed to patch rpath of dependencies in bundle-wheel.sh)
RUN wget -q https://github.com/NixOS/patchelf/releases/download/${PATCHELF_VERSION}/patchelf-${PATCHELF_VERSION}-${ARCH}.tar.gz -O /tmp/patchelf.tar.gz && \
tar -xzf /tmp/patchelf.tar.gz -C /tmp && \
mv /tmp/bin/patchelf /usr/local/bin/ && \
rm -rf /tmp/patchelf*

# Install CMake
RUN cmake --version
RUN wget -q https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-${ARCH}.sh -O /tmp/cmake-install.sh && \
chmod +x /tmp/cmake-install.sh && \
mkdir /opt/cmake-${CMAKE_VERSION} && \
/tmp/cmake-install.sh --skip-license --prefix=/opt/cmake-${CMAKE_VERSION} \
&& rm -f /usr/local/bin/*cmake* \
&& rm -f /usr/local/bin/cpack \
&& rm -f /usr/local/bin/ctest && \
ln -s /opt/cmake-${CMAKE_VERSION}/bin/* /usr/local/bin/ && \
rm -rf /tmp/cmake-install.sh

# Set up Python environment variables
ENV PYTHONPATH=/opt/python/v
ENV PYBIN=${PYTHONPATH}/bin
ENV PYLIB=${PYTHONPATH}/lib

# Create symlink to the desired Python version
RUN ln -s /opt/python/cp${PYV}* ${PYTHONPATH}

# Update PATH and library paths
ENV PATH=${PYTHONPATH}/bin:/opt/python/*/bin:${PATH}
ENV LD_LIBRARY_PATH=/usr/local/lib:/opt/python/*/lib:${PYLIB}:${LD_LIBRARY_PATH}
ENV LIBRARY_PATH=/usr/local/lib:/opt/python/*/lib:${PYLIB}:${LIBRARY_PATH}

# Propagate the environment variable to profile.d
RUN echo "export PYTHONPATH=${PYTHONPATH}" >> /etc/profile.d/python.sh && \
echo "export PYBIN=${PYBIN}" >> /etc/profile.d/python.sh && \
echo "export PYLIB=${PYLIB}" >> /etc/profile.d/python.sh && \
echo "export PATH=\${PYTHONPATH}/bin:/opt/python/*/bin:\${PATH}" >> /etc/profile.d/python.sh && \
echo "export LD_LIBRARY_PATH=/usr/local/lib:/opt/python/*/lib:\${PYLIB}:\${LD_LIBRARY_PATH}" >> /etc/profile.d/python.sh && \
echo "export LIBRARY_PATH=/usr/local/lib:/opt/python/*/lib:\${PYLIB}:\${LIBRARY_PATH}" >> /etc/profile.d/python.sh && \
chmod +x /etc/profile.d/python.sh

# Install Python packages
RUN python3 -m pip install --no-cache-dir \
breathe \
cibuildwheel \
clang==${CLANG_VERSION} \
exhale \
flake8 \
future \
graphviz \
numpy \
pre-commit \
recommonmark \
setuptools \
sphinx_rtd_theme \
sphinx==${SPHINX_VERSION} \
twine \
wheel

# Update the dynamic linker run-time bindings
RUN ldconfig

# extra deps
COPY --from=extra_deps / /
61 changes: 61 additions & 0 deletions docker/manylinux/Dockerfile.builder.deps
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

ARG FROM_IMAGE_NAME=quay.io/pypa/manylinux2014_x86_64
ARG CUDA_IMAGE
ARG BUILDER_CUDA_EXTRA_DEPS=scratch

FROM ${BUILDER_CUDA_EXTRA_DEPS} AS cuda_extra_deps
FROM ${CUDA_IMAGE} AS cuda

# Find and copy libcuda.so* to /cuda_libs
RUN mkdir /cuda_libs && \
find /usr -name 'libcuda.so*' -exec cp {} /cuda_libs/ \;

FROM ${FROM_IMAGE_NAME}

ENV PATH=/usr/local/cuda/bin:${PATH}
ENV LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64:${LD_LIBRARY_PATH}

ENV NVIDIA_DRIVER_CAPABILITIES=video,compute,utility,compat32

# Propagating the environment variable to profile.d
RUN echo "export NVIDIA_DRIVER_CAPABILITIES=video,compute,utility,compat32" >> /etc/profile.d/nvidia.sh && \
echo "export PATH=/usr/local/cuda/bin:\${PATH}" >> /etc/profile.d/nvidia.sh && \
echo "export LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64:\${LD_LIBRARY_PATH}" >> /etc/profile.d/nvidia.sh && \
chmod +x /etc/profile.d/nvidia.sh

# CUDA
COPY --from=cuda /usr/local/cuda /usr/local/cuda

# Copy libcuda.so* files
COPY --from=cuda /cuda_libs/* /usr/lib64/

# Test CUDA compiler
RUN nvcc --version

# Ensure tmp is writable by all users recursively
RUN chmod -R a+rw /tmp

RUN git clone https://github.com/google/googletest.git -b release-1.10.0 && \
pushd googletest && \
mkdir build && \
pushd build && \
cmake .. && \
make -j$(nproc) && make install && \
popd && popd && rm -rf googletest

# Extra deps
COPY --from=cuda_extra_deps / /
19 changes: 19 additions & 0 deletions docker/manylinux/Dockerfile.cuda.centos7.deps
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

ARG FROM_IMAGE_NAME=nvidia/cuda:11.4.3-devel-centos7
FROM ${FROM_IMAGE_NAME} AS cuda

RUN ln -sf /usr/share/zoneinfo/US/Pacific /etc/localtime
Loading

0 comments on commit 2a73733

Please sign in to comment.