From 289a292608c09ceba3aea40a009f80028361ee63 Mon Sep 17 00:00:00 2001 From: Andreas Rammhold Date: Tue, 5 Nov 2019 10:52:49 +0100 Subject: [PATCH 1/2] cuda: make cudatoolkit & cudnn packages overrideable --- pkgs/top-level/all-packages.nix | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index b127412c5bb5..dfba3bc849f0 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -2571,7 +2571,8 @@ in cron = callPackage ../tools/system/cron { }; - inherit (callPackages ../development/compilers/cudatoolkit { }) + cudaPackages = callPackages ../development/compilers/cudatoolkit { }; + inherit (cudaPackages) cudatoolkit_6 cudatoolkit_6_5 cudatoolkit_7 @@ -2587,7 +2588,8 @@ in cudatoolkit = cudatoolkit_10; - inherit (callPackages ../development/libraries/science/math/cudnn { }) + cudnnPackages = callPackages ../development/libraries/science/math/cudnn { }; + inherit (cudnnPackages) cudnn_cudatoolkit_7 cudnn_cudatoolkit_7_5 cudnn6_cudatoolkit_8 From ceafd896f5b801b4722f81b869c27ea2ed3870dd Mon Sep 17 00:00:00 2001 From: Andreas Rammhold Date: Tue, 26 Nov 2019 12:24:46 +0100 Subject: [PATCH 2/2] cudatoolkit: move the dependencies into a common expression This has the benefit of being able to override all the inputs to the build where you were previously only able to override the entire package set (if at all). --- .../compilers/cudatoolkit/common.nix | 206 +++++++++++++++++ .../compilers/cudatoolkit/default.nix | 213 +----------------- pkgs/top-level/all-packages.nix | 2 +- 3 files changed, 216 insertions(+), 205 deletions(-) create mode 100644 pkgs/development/compilers/cudatoolkit/common.nix diff --git a/pkgs/development/compilers/cudatoolkit/common.nix b/pkgs/development/compilers/cudatoolkit/common.nix new file mode 100644 index 000000000000..c5a1513b6480 --- /dev/null +++ b/pkgs/development/compilers/cudatoolkit/common.nix @@ -0,0 +1,206 @@ +args@ +{ version +, sha256 +, url ? "" +, name ? "" +, developerProgram ? false +, runPatches ? [] +, addOpenGLRunpath +, alsaLib +, expat +, fetchurl +, fontconfig +, freetype +, gcc +, gdk-pixbuf +, glib +, glibc +, gtk2 +, lib +, makeWrapper +, ncurses5 +, perl +, python27 +, requireFile +, stdenv +, unixODBC +, xorg +, zlib +}: + +stdenv.mkDerivation rec { + pname = "cudatoolkit"; + inherit version runPatches; + + dontPatchELF = true; + dontStrip = true; + + src = + if developerProgram then + requireFile { + message = '' + This nix expression requires that ${args.name} is already part of the store. + Register yourself to NVIDIA Accelerated Computing Developer Program, retrieve the CUDA toolkit + at https://developer.nvidia.com/cuda-toolkit, and run the following command in the download directory: + nix-prefetch-url file://\$PWD/${args.name} + ''; + inherit (args) name sha256; + } + else + fetchurl { + inherit (args) url sha256; + }; + + outputs = [ "out" "lib" "doc" ]; + + nativeBuildInputs = [ perl makeWrapper addOpenGLRunpath ]; + buildInputs = [ gdk-pixbuf ]; # To get $GDK_PIXBUF_MODULE_FILE via setup-hook + runtimeDependencies = [ + ncurses5 expat python27 zlib glibc + xorg.libX11 xorg.libXext xorg.libXrender xorg.libXt xorg.libXtst xorg.libXi xorg.libXext + gtk2 glib fontconfig freetype unixODBC alsaLib + ]; + + rpath = "${stdenv.lib.makeLibraryPath runtimeDependencies}:${stdenv.cc.cc.lib}/lib64"; + + unpackPhase = '' + sh $src --keep --noexec + + cd pkg/run_files + sh cuda-linux*.run --keep --noexec + sh cuda-samples*.run --keep --noexec + mv pkg ../../$(basename $src) + cd ../.. + rm -rf pkg + + for patch in $runPatches; do + sh $patch --keep --noexec + mv pkg $(basename $patch) + done + ''; + + installPhase = '' + runHook preInstall + mkdir $out + cd $(basename $src) + export PERL5LIB=. + perl ./install-linux.pl --prefix="$out" + cd .. + for patch in $runPatches; do + cd $(basename $patch) + perl ./install_patch.pl --silent --accept-eula --installdir="$out" + cd .. + done + + rm $out/tools/CUDA_Occupancy_Calculator.xls # FIXME: why? + + # let's remove the 32-bit libraries, they confuse the lib64->lib mover + rm -rf $out/lib + + # Remove some cruft. + ${lib.optionalString (lib.versionAtLeast version "7.0") "rm $out/bin/uninstall*"} + + # Fixup path to samples (needed for cuda 6.5 or else nsight will not find them) + if [ -d "$out"/cuda-samples ]; then + mv "$out"/cuda-samples "$out"/samples + fi + + # Change the #error on GCC > 4.9 to a #warning. + sed -i $out/include/host_config.h -e 's/#error\(.*unsupported GNU version\)/#warning\1/' + + # Fix builds with newer glibc version + sed -i "1 i#define _BITS_FLOATN_H" "$out/include/host_defines.h" + + # Ensure that cmake can find CUDA. + mkdir -p $out/nix-support + echo "cmakeFlags+=' -DCUDA_TOOLKIT_ROOT_DIR=$out'" >> $out/nix-support/setup-hook + + # Move some libraries to the lib output so that programs that + # depend on them don't pull in this entire monstrosity. + mkdir -p $lib/lib + mv -v $out/lib64/libcudart* $lib/lib/ + + # Remove OpenCL libraries as they are provided by ocl-icd and driver. + rm -f $out/lib64/libOpenCL* + + # Set compiler for NVCC. + wrapProgram $out/bin/nvcc \ + --prefix PATH : ${gcc}/bin + + # nvprof do not find any program to profile if LD_LIBRARY_PATH is not set + wrapProgram $out/bin/nvprof \ + --prefix LD_LIBRARY_PATH : $out/lib + '' + lib.optionalString (lib.versionOlder version "8.0") '' + # Hack to fix building against recent Glibc/GCC. + echo "NIX_CFLAGS_COMPILE+=' -D_FORCE_INLINES'" >> $out/nix-support/setup-hook + '' + '' + runHook postInstall + ''; + + postInstall = '' + for b in nvvp nsight; do + wrapProgram "$out/bin/$b" \ + --set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE" + done + ''; + + preFixup = '' + while IFS= read -r -d ''$'\0' i; do + if ! isELF "$i"; then continue; fi + echo "patching $i..." + if [[ ! $i =~ \.so ]]; then + patchelf \ + --set-interpreter "''$(cat $NIX_CC/nix-support/dynamic-linker)" $i + fi + if [[ $i =~ libcudart ]]; then + rpath2= + else + rpath2=$rpath:$lib/lib:$out/jre/lib/amd64/jli:$out/lib:$out/lib64:$out/nvvm/lib:$out/nvvm/lib64 + fi + patchelf --set-rpath "$rpath2" --force-rpath $i + done < <(find $out $lib $doc -type f -print0) + ''; + + # Set RPATH so that libcuda and other libraries in + # /run/opengl-driver(-32)/lib can be found. See the explanation in + # addOpenGLRunpath. Don't try to figure out which libraries really need + # it, just patch all (but not the stubs libraries). Note that + # --force-rpath prevents changing RPATH (set above) to RUNPATH. + postFixup = '' + addOpenGLRunpath --force-rpath {$out,$lib}/lib/lib*.so + ''; + + # cuda-gdb doesn't run correctly when not using sandboxing, so + # temporarily disabling the install check. This should be set to true + # when we figure out how to get `cuda-gdb --version` to run correctly + # when not using sandboxing. + doInstallCheck = false; + postInstallCheck = let + in '' + # Smoke test binaries + pushd $out/bin + for f in *; do + case $f in + crt) continue;; + nvcc.profile) continue;; + nsight_ee_plugins_manage.sh) continue;; + uninstall_cuda_toolkit_6.5.pl) continue;; + computeprof|nvvp|nsight) continue;; # GUIs don't feature "--version" + *) echo "Executing '$f --version':"; ./$f --version;; + esac + done + popd + ''; + passthru = { + cc = gcc; + majorVersion = lib.versions.majorMinor version; + }; + + meta = with stdenv.lib; { + description = "A compiler for NVIDIA GPUs, math libraries, and tools"; + homepage = "https://developer.nvidia.com/cuda-toolkit"; + platforms = [ "x86_64-linux" ]; + license = licenses.unfree; + }; +} + diff --git a/pkgs/development/compilers/cudatoolkit/default.nix b/pkgs/development/compilers/cudatoolkit/default.nix index 98c0381216a7..9c983a38e4e1 100644 --- a/pkgs/development/compilers/cudatoolkit/default.nix +++ b/pkgs/development/compilers/cudatoolkit/default.nix @@ -1,210 +1,15 @@ -{ lib, stdenv, makeWrapper, fetchurl, requireFile, perl, ncurses5, expat, python27, zlib -, gcc48, gcc49, gcc5, gcc6, gcc7 -, xorg, gtk2, gdk-pixbuf, glib, fontconfig, freetype, unixODBC, alsaLib, glibc -, addOpenGLRunpath +{ lib +, callPackage +, fetchurl +, gcc48 +, gcc49 +, gcc5 +, gcc6 +, gcc7 }: let - - common = - args@{ gcc, version, sha256 - , url ? "" - , name ? "" - , developerProgram ? false - , python ? python27 - , runPatches ? [] - }: - - stdenv.mkDerivation rec { - pname = "cudatoolkit"; - inherit version runPatches; - - dontPatchELF = true; - dontStrip = true; - - src = - if developerProgram then - requireFile { - message = '' - This nix expression requires that ${args.name} is already part of the store. - Register yourself to NVIDIA Accelerated Computing Developer Program, retrieve the CUDA toolkit - at https://developer.nvidia.com/cuda-toolkit, and run the following command in the download directory: - nix-prefetch-url file://\$PWD/${args.name} - ''; - inherit (args) name sha256; - } - else - fetchurl { - inherit (args) url sha256; - }; - - outputs = [ "out" "lib" "doc" ]; - - nativeBuildInputs = [ perl makeWrapper addOpenGLRunpath ]; - buildInputs = [ gdk-pixbuf ]; # To get $GDK_PIXBUF_MODULE_FILE via setup-hook - runtimeDependencies = [ - ncurses5 expat python zlib glibc - xorg.libX11 xorg.libXext xorg.libXrender xorg.libXt xorg.libXtst xorg.libXi xorg.libXext - gtk2 glib fontconfig freetype unixODBC alsaLib - ]; - - rpath = "${stdenv.lib.makeLibraryPath runtimeDependencies}:${stdenv.cc.cc.lib}/lib64"; - - unpackPhase = '' - sh $src --keep --noexec - - ${lib.optionalString (lib.versionOlder version "10.1") '' - cd pkg/run_files - sh cuda-linux*.run --keep --noexec - sh cuda-samples*.run --keep --noexec - mv pkg ../../$(basename $src) - cd ../.. - rm -rf pkg - - for patch in $runPatches; do - sh $patch --keep --noexec - mv pkg $(basename $patch) - done - ''} - ''; - - installPhase = '' - runHook preInstall - mkdir $out - ${lib.optionalString (lib.versionOlder version "10.1") '' - cd $(basename $src) - export PERL5LIB=. - perl ./install-linux.pl --prefix="$out" - cd .. - for patch in $runPatches; do - cd $(basename $patch) - perl ./install_patch.pl --silent --accept-eula --installdir="$out" - cd .. - done - ''} - ${lib.optionalString (lib.versionAtLeast version "10.1") '' - cd pkg/builds/cuda-toolkit - mv * $out/ - ''} - - rm $out/tools/CUDA_Occupancy_Calculator.xls # FIXME: why? - - ${lib.optionalString (lib.versionOlder version "10.1") '' - # let's remove the 32-bit libraries, they confuse the lib64->lib mover - rm -rf $out/lib - ''} - - # Remove some cruft. - ${lib.optionalString ((lib.versionAtLeast version "7.0") && (lib.versionOlder version "10.1")) - "rm $out/bin/uninstall*"} - - # Fixup path to samples (needed for cuda 6.5 or else nsight will not find them) - if [ -d "$out"/cuda-samples ]; then - mv "$out"/cuda-samples "$out"/samples - fi - - # Change the #error on GCC > 4.9 to a #warning. - sed -i $out/include/host_config.h -e 's/#error\(.*unsupported GNU version\)/#warning\1/' - - # Fix builds with newer glibc version - sed -i "1 i#define _BITS_FLOATN_H" "$out/include/host_defines.h" - - # Ensure that cmake can find CUDA. - mkdir -p $out/nix-support - echo "cmakeFlags+=' -DCUDA_TOOLKIT_ROOT_DIR=$out'" >> $out/nix-support/setup-hook - - # Move some libraries to the lib output so that programs that - # depend on them don't pull in this entire monstrosity. - mkdir -p $lib/lib - mv -v $out/lib64/libcudart* $lib/lib/ - - # Remove OpenCL libraries as they are provided by ocl-icd and driver. - rm -f $out/lib64/libOpenCL* - ${lib.optionalString (lib.versionAtLeast version "10.1") '' - mv $out/lib64 $out/lib - ''} - - # Set compiler for NVCC. - wrapProgram $out/bin/nvcc \ - --prefix PATH : ${gcc}/bin - - # nvprof do not find any program to profile if LD_LIBRARY_PATH is not set - wrapProgram $out/bin/nvprof \ - --prefix LD_LIBRARY_PATH : $out/lib - '' + lib.optionalString (lib.versionOlder version "8.0") '' - # Hack to fix building against recent Glibc/GCC. - echo "NIX_CFLAGS_COMPILE+=' -D_FORCE_INLINES'" >> $out/nix-support/setup-hook - '' + '' - runHook postInstall - ''; - - postInstall = '' - for b in nvvp nsight; do - wrapProgram "$out/bin/$b" \ - --set GDK_PIXBUF_MODULE_FILE "$GDK_PIXBUF_MODULE_FILE" - done - ''; - - preFixup = '' - while IFS= read -r -d ''$'\0' i; do - if ! isELF "$i"; then continue; fi - echo "patching $i..." - if [[ ! $i =~ \.so ]]; then - patchelf \ - --set-interpreter "''$(cat $NIX_CC/nix-support/dynamic-linker)" $i - fi - if [[ $i =~ libcudart ]]; then - rpath2= - else - rpath2=$rpath:$lib/lib:$out/jre/lib/amd64/jli:$out/lib:$out/lib64:$out/nvvm/lib:$out/nvvm/lib64 - fi - patchelf --set-rpath "$rpath2" --force-rpath $i - done < <(find $out $lib $doc -type f -print0) - ''; - - # Set RPATH so that libcuda and other libraries in - # /run/opengl-driver(-32)/lib can be found. See the explanation in - # addOpenGLRunpath. Don't try to figure out which libraries really need - # it, just patch all (but not the stubs libraries). Note that - # --force-rpath prevents changing RPATH (set above) to RUNPATH. - postFixup = '' - addOpenGLRunpath --force-rpath {$out,$lib}/lib/lib*.so - ''; - - # cuda-gdb doesn't run correctly when not using sandboxing, so - # temporarily disabling the install check. This should be set to true - # when we figure out how to get `cuda-gdb --version` to run correctly - # when not using sandboxing. - doInstallCheck = false; - postInstallCheck = let - in '' - # Smoke test binaries - pushd $out/bin - for f in *; do - case $f in - crt) continue;; - nvcc.profile) continue;; - nsight_ee_plugins_manage.sh) continue;; - uninstall_cuda_toolkit_6.5.pl) continue;; - computeprof|nvvp|nsight) continue;; # GUIs don't feature "--version" - *) echo "Executing '$f --version':"; ./$f --version;; - esac - done - popd - ''; - passthru = { - cc = gcc; - majorVersion = lib.versions.majorMinor version; - }; - - meta = with stdenv.lib; { - description = "A compiler for NVIDIA GPUs, math libraries, and tools"; - homepage = "https://developer.nvidia.com/cuda-toolkit"; - platforms = [ "x86_64-linux" ]; - license = licenses.unfree; - }; - }; - + common = callPackage ./common.nix; in rec { cudatoolkit_6 = common { version = "6.0.37"; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index dfba3bc849f0..24a86b333b36 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -2571,7 +2571,7 @@ in cron = callPackage ../tools/system/cron { }; - cudaPackages = callPackages ../development/compilers/cudatoolkit { }; + cudaPackages = recurseIntoAttrs (callPackage ../development/compilers/cudatoolkit {}); inherit (cudaPackages) cudatoolkit_6 cudatoolkit_6_5