1{ stdenv 2, lib 3, fetchurl 4, buildPythonPackage 5, isPy3k, pythonOlder, pythonAtLeast, astor 6, gast 7, google-pasta 8, wrapt 9, numpy 10, six 11, termcolor 12, protobuf 13, absl-py 14, grpcio 15, mock 16, scipy 17, wheel 18, opt-einsum 19, backports_weakref 20, tensorflow-estimator_2 21, tensorflow-tensorboard_2 22, cudaSupport ? false 23, cudatoolkit 24, cudnn 25, zlib 26, python 27, keras-applications 28, keras-preprocessing 29, addOpenGLRunpath 30, astunparse 31, flatbuffers 32, h5py 33, typing-extensions 34}: 35 36# We keep this binary build for two reasons: 37# - the source build doesn't work on Darwin. 38# - the source build is currently brittle and not easy to maintain 39 40# unsupported combination 41assert ! (stdenv.isDarwin && cudaSupport); 42 43let 44 packages = import ./binary-hashes.nix; 45 metadataPatch = ./relax-dependencies-metadata.patch; 46 patch = ./relax-dependencies.patch; 47in buildPythonPackage { 48 pname = "tensorflow" + lib.optionalString cudaSupport "-gpu"; 49 inherit (packages) version; 50 format = "wheel"; 51 52 disabled = pythonAtLeast "3.9"; 53 54 src = let 55 pyVerNoDot = lib.strings.stringAsChars (x: if x == "." then "" else x) python.pythonVersion; 56 platform = if stdenv.isDarwin then "mac" else "linux"; 57 unit = if cudaSupport then "gpu" else "cpu"; 58 key = "${platform}_py_${pyVerNoDot}_${unit}"; 59 in fetchurl packages.${key}; 60 61 propagatedBuildInputs = [ 62 astunparse 63 flatbuffers 64 typing-extensions 65 protobuf 66 numpy 67 scipy 68 termcolor 69 grpcio 70 six 71 astor 72 absl-py 73 gast 74 opt-einsum 75 google-pasta 76 wrapt 77 tensorflow-estimator_2 78 tensorflow-tensorboard_2 79 keras-applications 80 keras-preprocessing 81 h5py 82 ] ++ lib.optional (!isPy3k) mock 83 ++ lib.optionals (pythonOlder "3.4") [ backports_weakref ]; 84 85 nativeBuildInputs = [ wheel ] ++ lib.optional cudaSupport addOpenGLRunpath; 86 87 preConfigure = '' 88 unset SOURCE_DATE_EPOCH 89 90 # Make sure that dist and the wheel file are writable. 91 chmod u+rwx -R ./dist 92 93 pushd dist 94 95 wheel unpack --dest unpacked ./*.whl 96 ( 97 cd unpacked/tensorflow* 98 # relax too strict versions in setup.py 99 patch -p 1 < ${patch} 100 cd *.dist-info 101 # relax too strict versions in *.dist-info/METADATA 102 patch -p 3 < ${metadataPatch} 103 ) 104 wheel pack ./unpacked/tensorflow* 105 106 popd 107 ''; 108 109 # Note that we need to run *after* the fixup phase because the 110 # libraries are loaded at runtime. If we run in preFixup then 111 # patchelf --shrink-rpath will remove the cuda libraries. 112 postFixup = 113 let 114 # rpaths we only need to add if CUDA is enabled. 115 cudapaths = lib.optionals cudaSupport [ 116 cudatoolkit.out 117 cudatoolkit.lib 118 cudnn 119 ]; 120 121 libpaths = [ 122 stdenv.cc.cc.lib 123 zlib 124 ]; 125 126 rpath = lib.makeLibraryPath (libpaths ++ cudapaths); 127 in 128 lib.optionalString stdenv.isLinux '' 129 # This is an array containing all the directories in the tensorflow2 130 # package that contain .so files. 131 # 132 # TODO: Create this list programmatically, and remove paths that aren't 133 # actually needed. 134 rrPathArr=( 135 "$out/${python.sitePackages}/tensorflow/" 136 "$out/${python.sitePackages}/tensorflow/core/kernels" 137 "$out/${python.sitePackages}/tensorflow/compiler/tf2tensorrt/" 138 "$out/${python.sitePackages}/tensorflow/compiler/tf2xla/ops/" 139 "$out/${python.sitePackages}/tensorflow/lite/experimental/microfrontend/python/ops/" 140 "$out/${python.sitePackages}/tensorflow/lite/python/interpreter_wrapper/" 141 "$out/${python.sitePackages}/tensorflow/lite/python/optimize/" 142 "$out/${python.sitePackages}/tensorflow/python/" 143 "$out/${python.sitePackages}/tensorflow/python/framework/" 144 "$out/${python.sitePackages}/tensorflow/python/autograph/impl/testing" 145 "$out/${python.sitePackages}/tensorflow/python/data/experimental/service" 146 "$out/${python.sitePackages}/tensorflow/python/framework" 147 "$out/${python.sitePackages}/tensorflow/python/profiler/internal" 148 "${rpath}" 149 ) 150 151 # The the bash array into a colon-separated list of RPATHs. 152 rrPath=$(IFS=$':'; echo "''${rrPathArr[*]}") 153 echo "about to run patchelf with the following rpath: $rrPath" 154 155 find $out -type f \( -name '*.so' -or -name '*.so.*' \) | while read lib; do 156 echo "about to patchelf $lib..." 157 chmod a+rx "$lib" 158 patchelf --set-rpath "$rrPath" "$lib" 159 ${lib.optionalString cudaSupport '' 160 addOpenGLRunpath "$lib" 161 ''} 162 done 163 ''; 164 165 # Upstream has a pip hack that results in bin/tensorboard being in both tensorflow 166 # and the propagated input tensorflow-tensorboard, which causes environment collisions. 167 # Another possibility would be to have tensorboard only in the buildInputs 168 # See https://github.com/NixOS/nixpkgs/pull/44381 for more information. 169 postInstall = '' 170 rm $out/bin/tensorboard 171 ''; 172 173 pythonImportsCheck = [ 174 "tensorflow" 175 "tensorflow.keras" 176 "tensorflow.python" 177 "tensorflow.python.framework" 178 ]; 179 180 meta = with lib; { 181 description = "Computation using data flow graphs for scalable machine learning"; 182 homepage = "http://tensorflow.org"; 183 license = licenses.asl20; 184 maintainers = with maintainers; [ jyp abbradar cdepillabout ]; 185 platforms = [ "x86_64-linux" "x86_64-darwin" ]; 186 }; 187}