Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock X-Debbugs-Cc: nvidia-cu...@packages.debian.org Control: affects -1 + src:nvidia-cudnn
Please unblock package nvidia-cudnn. Not yet uploaded to unstable, just asking for a pre-approval. [ Reason ] Our current package version in testing is 8.5.0.96~cuda11.7, but the nvidia-cuda-toolkit version in testing is 11.8.89~11.8.0-2. So there is a little minor version mismatch in the cuda version (one 11.7, and the other 11.8). This package is a downloader script that downloads the Nvidia binary blob releases of the cuDNN library, and installs the library to the system directories for building reverse dependencies. So, generally updating the package is simply to update the binary tarball URL in the script, along with the exact version number, which is very trivial. But unfortunately, during the cuda11.7 to cuda11.8 update, I also introduced many changes to the package to the maintainer scripts to let the package correctly support the pytorch-cuda build. I'm the upstream of this package, and this looks like a low risk update to me. But I'm not sure how the release team will think. So asking for uploading permission in advance. [ Impact ] (What is the impact for the user if the unblock isn't granted?) Nearly no impact. This package is new and does not exist in the previous stable releases. To the best of my knowledge, there is only one tentative reverse dependency pytorch-cuda, which is not present in testing. [ Tests ] (What automated or manual tests cover the affected code?) The updated package is now able to correctly support the build of pytorch-cuda. I tested the built package with both Nvidia MX250 (laptop) and RTX 2060 (laptop) GPUs. It works correctly. [ Risks ] There is a small risk. The additional code is very simple. It does not have reverse dependency in testing. There is no alternative to this package. I'm the upstream author of the script, and I can provide stable updates on my own even if something goes wrong. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing [ Other info ] (Anything else the release team should know.) The debdiff contains necessary changes to make the package correctly support the pytorch-cuda build (with sbuild). Specifically: 1. A fake library is compiled (from a nearly empty C file cudnn-fake.c) with the soname of the library to be downloaded. This seems to be the only way to make apt/dpkg believe that the libcudnn.so.* is really provided by this binary package. This solves the libcudnn_* cannot be found in any system package error from dh_shlibdeps. 2. Added curl as an alternative binary blob downloader. 3. Updated the postinst and prerm script for handling installed files. In the current testing version, when we want to remove this package, we use some manually written glob patterns to remove the downloaded cudnn library. This implementation is not very safe when the user manually install another instance of cudnn to the system. The glob pattern will also include them to make them removed during postrm. In the proposed version (see debdiff), I record a list of files that are installed from the tarball to the system. And the postrm process will use the exact recorded installation paths for removal. I think this is a safer implementation than removal by glob pattern match. 4. debconf template default choice is changed to "I Agree". This package is in non-free section. Only by setting the debconf default choice to "I Agree", can we correctly build pytorch-cuda in sbuild without the cuDNN libraries not downloaded but the bin:nvidia-cudnn package installed. 5. More code comments (maintainence notes) in the script, and the upgraded binary blob URL. unblock nvidia-cudnn/8.7.0.84~cuda11.8+1 Thank you for using reportbug
diff -Nru nvidia-cudnn-8.5.0.96~cuda11.7/cudnn-fake.c nvidia-cudnn-8.7.0.84~cuda11.8/cudnn-fake.c --- nvidia-cudnn-8.5.0.96~cuda11.7/cudnn-fake.c 1969-12-31 19:00:00.000000000 -0500 +++ nvidia-cudnn-8.7.0.84~cuda11.8/cudnn-fake.c 2023-03-21 18:49:17.000000000 -0400 @@ -0,0 +1,8 @@ +/* This is a fake library. We want dpkg-shlibdeps to believe that the + * shared object libcudnn.so.8 is provided in this package. + */ +int +__cudnn_fake_library__() +{ + return 0; +} diff -Nru nvidia-cudnn-8.5.0.96~cuda11.7/debian/changelog nvidia-cudnn-8.7.0.84~cuda11.8/debian/changelog --- nvidia-cudnn-8.5.0.96~cuda11.7/debian/changelog 2023-02-17 23:24:39.000000000 -0500 +++ nvidia-cudnn-8.7.0.84~cuda11.8/debian/changelog 2023-03-21 18:49:17.000000000 -0400 @@ -1,3 +1,33 @@ +nvidia-cudnn (8.7.0.84~cuda11.8) experimental; urgency=medium + + * Upgrade to cuDNN v8.7.0.84 + * Set the debconf template default choice to "I Agree". + Only in this way can we use the binary package nvidia-cudnn as a real + libcudnn.so provider to build its reverse dependencies with sbuild. + * For nvidia-cudnn reverse depenendies: + * Build a fake library libcudnn.so.8 which provies nothing at all. + This can fix the dh_shlibdeps resolving for reverse dependencies. + This fake library will be overridden by the downloaded libcudnn.so.8 + * Add shlibs control file for reverse dependencies. + * Dynamically generate the d/shlibs from template shlibs.in. + * Updates to update-nvidia-cudnn downloader script: + * Fix the example commands in update-. + * Automatically detect and use curl/wget. + * Support recording the list of installed files. + * Support purge using the file list. + * Add instruction on how to maintain this script. + * Updates to the binary package dependency system (d/control): + * Depends on curl | wget instead. + * Depends on ca-certificates to avoid SSL error. + * Suggest nvidia-cuda-toolkit-gcc. + * Let the binary package Provides: libcudnn.so.8 as well. + * Updates to maintainer scripts: + * postinst/prerm: write filelist at /var/lib/nvidia-cudnn/filelist.txt + * prerm: Remove the leftover empty directory as well. + * Update lintian overrides and add d/clean. + + -- Mo Zhou <lu...@debian.org> Tue, 21 Mar 2023 18:49:17 -0400 + nvidia-cudnn (8.5.0.96~cuda11.7) unstable; urgency=medium [ Mo Zhou ] diff -Nru nvidia-cudnn-8.5.0.96~cuda11.7/debian/clean nvidia-cudnn-8.7.0.84~cuda11.8/debian/clean --- nvidia-cudnn-8.5.0.96~cuda11.7/debian/clean 1969-12-31 19:00:00.000000000 -0500 +++ nvidia-cudnn-8.7.0.84~cuda11.8/debian/clean 2023-03-21 18:42:20.000000000 -0400 @@ -0,0 +1,2 @@ +debian/shlibs +libcudnn.so.* diff -Nru nvidia-cudnn-8.5.0.96~cuda11.7/debian/control nvidia-cudnn-8.7.0.84~cuda11.8/debian/control --- nvidia-cudnn-8.5.0.96~cuda11.7/debian/control 2023-02-17 23:24:39.000000000 -0500 +++ nvidia-cudnn-8.7.0.84~cuda11.8/debian/control 2023-03-20 11:07:36.000000000 -0400 @@ -13,8 +13,9 @@ Package: nvidia-cudnn Architecture: amd64 arm64 ppc64el Depends: ${misc:Depends}, -Pre-Depends: nvidia-cuda-toolkit, dpkg-dev, wget -Provides: libcudnn.so +Pre-Depends: nvidia-cuda-toolkit, dpkg-dev, curl | wget, ca-certificates +Suggests: nvidia-cuda-toolkit-gcc, +Provides: libcudnn.so, libcudnn.so.8 Description: NVIDIA CUDA Deep Neural Network library (install script) The NVIDIA CUDA Deep Neural Network library (cuDNN) is a GPU-accelerated library of primitives for deep neural networks. cuDNN provides highly diff -Nru nvidia-cudnn-8.5.0.96~cuda11.7/debian/lintian-overrides nvidia-cudnn-8.7.0.84~cuda11.8/debian/lintian-overrides --- nvidia-cudnn-8.5.0.96~cuda11.7/debian/lintian-overrides 1969-12-31 19:00:00.000000000 -0500 +++ nvidia-cudnn-8.7.0.84~cuda11.8/debian/lintian-overrides 2023-03-21 18:43:44.000000000 -0400 @@ -0,0 +1,4 @@ +no-manual-page [usr/sbin/update-nvidia-cudnn] +package-name-doesnt-match-sonames libcudnn8 +shared-library-lacks-prerequisites [usr/lib/*/libcudnn.so.8] +too-long-extended-description-in-templates nvidia-cudnn/license [templates:22] diff -Nru nvidia-cudnn-8.5.0.96~cuda11.7/debian/postinst nvidia-cudnn-8.7.0.84~cuda11.8/debian/postinst --- nvidia-cudnn-8.5.0.96~cuda11.7/debian/postinst 2023-02-17 23:24:39.000000000 -0500 +++ nvidia-cudnn-8.7.0.84~cuda11.8/debian/postinst 2023-02-24 13:41:12.000000000 -0500 @@ -18,10 +18,11 @@ case "$1" in configure) - db_get nvidia-cudnn/question - if test "I Agree" = "${RET}"; then - update-nvidia-cudnn -u - fi + db_get nvidia-cudnn/question + if test "I Agree" = "${RET}"; then + update-nvidia-cudnn --update \ + --filelist /var/lib/nvidia-cudnn/filelist.txt + fi ;; abort-upgrade|abort-remove|abort-deconfigure) diff -Nru nvidia-cudnn-8.5.0.96~cuda11.7/debian/prerm nvidia-cudnn-8.7.0.84~cuda11.8/debian/prerm --- nvidia-cudnn-8.5.0.96~cuda11.7/debian/prerm 2023-02-17 23:24:39.000000000 -0500 +++ nvidia-cudnn-8.7.0.84~cuda11.8/debian/prerm 2023-03-15 14:38:10.000000000 -0400 @@ -17,11 +17,13 @@ case "$1" in remove|upgrade|deconfigure) - # no need to purge anything if it was not agreed - db_get nvidia-cudnn/question - if test "I Agree" = "${RET}"; then - update-nvidia-cudnn -p - fi + # no need to purge anything if it was not agreed + db_get nvidia-cudnn/question + if test "I Agree" = "${RET}"; then + update-nvidia-cudnn --purge \ + --filelist /var/lib/nvidia-cudnn/filelist.txt + rmdir -v /var/lib/nvidia-cudnn || true + fi ;; failed-upgrade) diff -Nru nvidia-cudnn-8.5.0.96~cuda11.7/debian/rules nvidia-cudnn-8.7.0.84~cuda11.8/debian/rules --- nvidia-cudnn-8.5.0.96~cuda11.7/debian/rules 2023-02-17 23:24:39.000000000 -0500 +++ nvidia-cudnn-8.7.0.84~cuda11.8/debian/rules 2023-03-21 18:15:15.000000000 -0400 @@ -1,7 +1,26 @@ #!/usr/bin/make -f +include /usr/share/dpkg/architecture.mk +CUDNN_VER="$(shell grep -oP 'CUDNN_VER="\K[^"]+' update-nvidia-cudnn)" %: dh $@ +execute_before_dh_auto_configure: + sed -e "s@CUDNN_VER@$(CUDNN_VER)@g" \ + < debian/shlibs.in \ + > debian/shlibs + +override_dh_auto_build: + $(CC) cudnn-fake.c -shared -fPIC -Wl,-soname=libcudnn.so.8 \ + -o libcudnn.so.8 \ + $(shell dpkg-buildflags --get CFLAGS) \ + $(shell dpkg-buildflags --get CPPFLAGS) \ + $(shell dpkg-buildflags --get LDFLAGS) + +override_dh_auto_install: + dh_auto_install + mkdir -p debian/nvidia-cudnn/usr/lib/$(DEB_HOST_MULTIARCH)/ + install -v -t debian/nvidia-cudnn/usr/lib/$(DEB_HOST_MULTIARCH)/ libcudnn.so.8 + override_dh_auto_configure: debconf-updatepo diff -Nru nvidia-cudnn-8.5.0.96~cuda11.7/debian/shlibs.in nvidia-cudnn-8.7.0.84~cuda11.8/debian/shlibs.in --- nvidia-cudnn-8.5.0.96~cuda11.7/debian/shlibs.in 1969-12-31 19:00:00.000000000 -0500 +++ nvidia-cudnn-8.7.0.84~cuda11.8/debian/shlibs.in 2023-03-21 18:11:40.000000000 -0400 @@ -0,0 +1 @@ +libcudnn 8 nvidia-cudnn (>= CUDNN_VER~) diff -Nru nvidia-cudnn-8.5.0.96~cuda11.7/debian/source/lintian-overrides nvidia-cudnn-8.7.0.84~cuda11.8/debian/source/lintian-overrides --- nvidia-cudnn-8.5.0.96~cuda11.7/debian/source/lintian-overrides 2023-02-17 23:24:39.000000000 -0500 +++ nvidia-cudnn-8.7.0.84~cuda11.8/debian/source/lintian-overrides 2023-03-21 18:40:28.000000000 -0400 @@ -1,2 +1,2 @@ -untranslatable-debconf-templates [debian/templates.in:9] -untranslatable-debconf-templates [debian/templates:9] +untranslatable-debconf-templates [debian/templates.in:10] +untranslatable-debconf-templates [debian/templates:10] diff -Nru nvidia-cudnn-8.5.0.96~cuda11.7/debian/templates nvidia-cudnn-8.7.0.84~cuda11.8/debian/templates --- nvidia-cudnn-8.5.0.96~cuda11.7/debian/templates 2023-02-17 23:24:39.000000000 -0500 +++ nvidia-cudnn-8.7.0.84~cuda11.8/debian/templates 2023-02-24 12:56:28.000000000 -0500 @@ -1,6 +1,7 @@ Template: nvidia-cudnn/question Type: select Choices: I Decline, I Agree +Default: I Agree _Description: Do you agree to all terms of the Nvidia cuDNN License Agreement? Nvidia cuDNN License Agreement diff -Nru nvidia-cudnn-8.5.0.96~cuda11.7/debian/templates.in nvidia-cudnn-8.7.0.84~cuda11.8/debian/templates.in --- nvidia-cudnn-8.5.0.96~cuda11.7/debian/templates.in 2023-02-17 23:24:39.000000000 -0500 +++ nvidia-cudnn-8.7.0.84~cuda11.8/debian/templates.in 2023-02-24 12:56:28.000000000 -0500 @@ -1,6 +1,7 @@ Template: nvidia-cudnn/question Type: select Choices: I Decline, I Agree +Default: I Agree _Description: Do you agree to all terms of the Nvidia cuDNN License Agreement? Nvidia cuDNN License Agreement diff -Nru nvidia-cudnn-8.5.0.96~cuda11.7/update-nvidia-cudnn nvidia-cudnn-8.7.0.84~cuda11.8/update-nvidia-cudnn --- nvidia-cudnn-8.5.0.96~cuda11.7/update-nvidia-cudnn 2023-02-17 23:24:39.000000000 -0500 +++ nvidia-cudnn-8.7.0.84~cuda11.8/update-nvidia-cudnn 2023-03-21 18:49:17.000000000 -0400 @@ -1,15 +1,32 @@ #!/bin/bash set -e -# Copyright (C) 2022 Mo Zhou <lu...@debian.org> +# Copyright (C) 2022-2023 Mo Zhou <lu...@debian.org> # MIT/Expat License. # # Nvidia CUDA Deep Neural Network Library installer script (Debian Specific) -# Borrowed bits from Archlinux: +# Borrowed some bits from Archlinux: # https://github.com/archlinux/svntogit-community/blob/packages/cudnn/trunk/PKGBUILD -# Useful References: -# https://developer.nvidia.com/cuDNN -# https://developer.nvidia.com/rdp/cudnn-archive -# https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ +# +# XXX: you can browse the following directory for updating the +# URL_{amd64,ppc64el,arm64} shell variables below: +# +# https://developer.download.nvidia.com/compute/redist/cudnn/ +# +# XXX: [maintainer/user notes] +# +# In case you want to upgrade to a newer version of cuDNN, you can just +# browse the link above, and find the binary tarballs you want. +# Then copy the urls and update the corresponding URL_* variables +# below. The rest of the shell code can remain unchanged as long +# as the upstream does not alter the file paths in tarball. +# +# To test whether the updated links work or not, you can just copy +# and paste the commands at the end part of the usage() function. +# You don't have to test all the three actions {-d, -u, -p}. +# As long as the update (-u) action works without issue, the download +# is good as well (-d). +# +# For a more thorough testing of install/purge, use piuparts instead. ## configs #################################################################### TMPDIR="$(mktemp -d)" @@ -17,13 +34,12 @@ ARCH="$(dpkg-architecture -qDEB_HOST_ARCH)" MULTIARCH="$(dpkg-architecture -qDEB_HOST_MULTIARCH)" PREFIX="/usr" -# XXX: browse this to update URLs: https://developer.download.nvidia.com/compute/redist/cudnn/ -CUDA_VER="11.7" -_CUDNN_VER="8.5.0" -CUDNN_VER="8.5.0.96" -URL_amd64="https://developer.download.nvidia.com/compute/redist/cudnn/v8.5.0/local_installers/11.7/cudnn-linux-x86_64-8.5.0.96_cuda11-archive.tar.xz" -URL_ppc64el="https://developer.download.nvidia.com/compute/redist/cudnn/v8.5.0/local_installers/11.7/cudnn-linux-ppc64le-8.5.0.96_cuda11-archive.tar.xz" -URL_arm64="https://developer.download.nvidia.com/compute/redist/cudnn/v8.5.0/local_installers/11.7/cudnn-linux-sbsa-8.5.0.96_cuda11-archive.tar.xz" +FILELIST="" +CUDA_VER="11.8" +CUDNN_VER="8.7.0.84" +URL_amd64="https://developer.download.nvidia.com/compute/redist/cudnn/v8.7.0/local_installers/11.8/cudnn-linux-x86_64-8.7.0.84_cuda11-archive.tar.xz" +URL_ppc64el="https://developer.download.nvidia.com/compute/redist/cudnn/v8.7.0/local_installers/11.8/cudnn-linux-ppc64le-8.7.0.84_cuda11-archive.tar.xz" +URL_arm64="https://developer.download.nvidia.com/compute/redist/cudnn/v8.7.0/local_installers/11.8/cudnn-linux-sbsa-8.7.0.84_cuda11-archive.tar.xz" ## usage ###################################################################### usage () { @@ -38,10 +54,11 @@ --multiarch <multiarch> override multiarch triplet (default: $(dpkg-architecture -qDEB_HOST_MULTIARCH)) --prefix <path> override install prefix (default: /usr) --tmpdir <dir> override temporary directory (default: ${TMPDIR}) + --filelist <path> write installed file list (default: ${FILELIST}) Testing this script cross-architecture: - $ update-nvidia-cudnn --arch amd64 --multiarch x86_64-linux-gnu --tmpdir . --prefix fake {-d,-u,-p} - $ update-nvidia-cudnn --arch ppc64el --multiarch powerpc64le-linux-gnu --tmpdir . --prefix fake {-d,-u,-p} - $ update-nvidia-cudnn --arch arm64 --multiarch aarch64-linux-gnu --tmpdir . --prefix fake {-d,-u,-p} + $ ./update-nvidia-cudnn --arch amd64 --multiarch x86_64-linux-gnu --tmpdir . --prefix fake {-d,-u,-p} + $ ./update-nvidia-cudnn --arch ppc64el --multiarch powerpc64le-linux-gnu --tmpdir . --prefix fake {-d,-u,-p} + $ ./update-nvidia-cudnn --arch arm64 --multiarch aarch64-linux-gnu --tmpdir . --prefix fake {-d,-u,-p} Version: cuDNN ${CUDNN_VER} for CUDA ${CUDA_VER} EOF } @@ -79,6 +96,11 @@ TMPDIR_IS_OVERRIDEN=1 fi shift; shift;; + --filelist) + if test -n "$2"; then + FILELIST=$2 + fi + shift; shift;; -h|--help) usage; exit 0;; -*|--*) @@ -107,7 +129,14 @@ local url="${1}" test -d ${TMPDIR} || mkdir ${TMPDIR} local dest="${TMPDIR}/$(basename ${url})" - local cmd="wget --verbose --show-progress=on --progress=bar --hsts-file=/tmp/wget-hsts -c ${URL} -O ${dest}" + if (command -v curl > /dev/null); then + local cmd="curl --continue-at - ${URL} --output ${dest}" + elif (command -v wget > /dev/null); then + local cmd="wget --continue --verbose --show-progress=off --hsts-file=/tmp/wget-hsts -c ${URL} -O ${dest}" + else + echo Error: no downloader available. + exit 255 + fi if ! test -f ${dest}; then echo ${cmd} 1>/dev/stderr bash -c "${cmd}" || bash -c "${cmd} --no-check-certificate" 1>/dev/stderr @@ -124,6 +153,7 @@ # Install extracted cudnn from src to dst local src=${1} # e.g. /tmp/nvidia-cudnn/ local dst=${2} # e.g. /usr/local/ + local installed=() FILES=( $(find ${src} -type f,l) ) for F in ${FILES[@]}; do (echo ${F} | grep -qo "cudnn.txz") && continue @@ -135,24 +165,71 @@ else install -vDm0644 -t ${dst}/lib/${MULTIARCH} ${F} fi + installed=( ${installed[@]} ${dst}/lib/${MULTIARCH}/$(basename ${F}) ) elif $(echo ${F} | grep -qo ".*/libcudnn.*\.a"); then # static library file install -vDm0644 -t ${dst}/lib/${MULTIARCH} ${F} + installed=( ${installed[@]} ${dst}/lib/${MULTIARCH}/$(basename ${F}) ) elif $(echo ${F} | grep -qo ".*/cudnn.*\.h"); then # header file install -vDm0644 -t ${dst}/include/${MULTIARCH} ${F} + installed=( ${installed[@]} ${dst}/include/${MULTIARCH}/$(basename ${F}) ) elif $(echo ${F} | grep -qo "NVIDIA_SLA_cuDNN_Support.txt"); then # copyright file install -vDm0644 -t ${dst}/share/doc/nvidia-cudnn/ ${F} + installed=( ${installed[@]} ${dst}/share/doc/nvidia-cudnn/$(basename ${F}) ) else echo Skipped ${F} fi done + echo Number of installed files: ${#installed[@]} + if test -n "${FILELIST}"; then + if ! test -d $(dirname "${FILELIST}"); then + mkdir -p $(dirname "${FILELIST}") + fi + for i in ${installed[@]}; do + echo "${i}" >> "${FILELIST}" + done + echo The list of installed files is recorded at "${FILELIST}" + fi } +# this is a dispatcher. When a ${FILELIST} is given, we use it to safely +# delete the recorded installed files. If not, we fallback to the manual +# deletion based on manually written matching rules. As long as the user +# does not modify /usr/lib/ (irrelevant to /usr/local) on their own, both +# methods will lead to the same results. purge_cudnn () { - test -n "${1}" || (echo "install_cudnn(): invalid argument"; exit 1) - # Purge cudnn from the given path + local prefix="${1}" + if test -n "${FILELIST}"; then + purge_cudnn_filelist "${FILELIST}" + else + purge_cudnn_fallback "${prefix}" + fi +} + +purge_cudnn_filelist () { + test -e "${1}" || (echo "purge_cudnn_filelist(): invalid argument"; exit 1) + # purge cudnn from the given file list + local filelist="${1}" + # first, validate the given file list + local FL=( $(cat "${filelist}") ) + for i in ${FL[@]}; do + if ! test -e "${i}"; then + echo Error: the given file list ${filelist} is invalid: file ${i} does not exist + exit 2 + fi + done + # then, remove the listed files + for i in ${FL[@]}; do + rm -v ${i} + done + rm -v "${filelist}" +} + +purge_cudnn_fallback () { + test -n "${1}" || (echo "purge_cudnn_fallback(): invalid argument"; exit 1) + # Purge cudnn from the given path (prefix) local dst="${1}" FILES=( $(find ${dst}/lib/${MULTIARCH} -type f,l -name "libcudnn*.so*") ) FILES+=( $(find ${dst}/include/${MULTIARCH} -type f -name "cudnn*.h") ) @@ -180,7 +257,9 @@ elif test "${DO_UPDATE}" -ne 0; then path=$(download_cudnn ${URL}) tmpdir2=$(mktemp -d) + echo Extracting files from the downloaded tarball... tar xvf ${path} -C ${tmpdir2}/ + echo Installing the files to system directories... install_cudnn ${tmpdir2} ${PREFIX} rm -rf ${tmpdir2} # cleanup @@ -192,4 +271,3 @@ echo Purging cuDNN installation from ${PREFIX} purge_cudnn ${PREFIX} || true fi -