Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at 20.03 430 lines 14 kB view raw
1{ stdenv, pkgs, bazel_0_29, buildBazelPackage, lib, fetchFromGitHub, fetchpatch, symlinkJoin 2, addOpenGLRunpath 3# Python deps 4, buildPythonPackage, isPy3k, isPy27, pythonOlder, pythonAtLeast, python 5# Python libraries 6, numpy, tensorflow-tensorboard_2, backports_weakref, mock, enum34, absl-py 7, future, setuptools, wheel, keras-preprocessing, keras-applications, google-pasta 8, functools32 9, opt-einsum 10, termcolor, grpcio, six, wrapt, protobuf, tensorflow-estimator_2 11# Common deps 12, git, swig, which, binutils, glibcLocales, cython 13# Common libraries 14, jemalloc, openmpi, astor, gast, grpc, sqlite, openssl, jsoncpp, re2 15, curl, snappy, flatbuffers, icu, double-conversion, libpng, libjpeg, giflib 16# Upsteam by default includes cuda support since tensorflow 1.15. We could do 17# that in nix as well. It would make some things easier and less confusing, but 18# it would also make the default tensorflow package unfree. See 19# https://groups.google.com/a/tensorflow.org/forum/#!topic/developers/iRCt5m4qUz0 20, cudaSupport ? false, nvidia_x11 ? null, cudatoolkit ? null, cudnn ? null, nccl ? null 21, mklSupport ? false, mkl ? null 22# XLA without CUDA is broken 23, xlaSupport ? cudaSupport 24# Default from ./configure script 25, cudaCapabilities ? [ "3.5" "5.2" ] 26, sse42Support ? builtins.elem (stdenv.hostPlatform.platform.gcc.arch or "default") ["westmere" "sandybridge" "ivybridge" "haswell" "broadwell" "skylake" "skylake-avx512"] 27, avx2Support ? builtins.elem (stdenv.hostPlatform.platform.gcc.arch or "default") [ "haswell" "broadwell" "skylake" "skylake-avx512"] 28, fmaSupport ? builtins.elem (stdenv.hostPlatform.platform.gcc.arch or "default") [ "haswell" "broadwell" "skylake" "skylake-avx512"] 29# Darwin deps 30, Foundation, Security 31}: 32 33assert cudaSupport -> nvidia_x11 != null 34 && cudatoolkit != null 35 && cudnn != null; 36 37# unsupported combination 38assert ! (stdenv.isDarwin && cudaSupport); 39 40assert mklSupport -> mkl != null; 41 42let 43 withTensorboard = pythonOlder "3.6"; 44 45 cudatoolkit_joined = symlinkJoin { 46 name = "${cudatoolkit.name}-merged"; 47 paths = [ 48 cudatoolkit.lib 49 cudatoolkit.out 50 # for some reason some of the required libs are in the targets/x86_64-linux 51 # directory; not sure why but this works around it 52 "${cudatoolkit}/targets/${stdenv.system}" 53 ]; 54 }; 55 56 cudatoolkit_cc_joined = symlinkJoin { 57 name = "${cudatoolkit.cc.name}-merged"; 58 paths = [ 59 cudatoolkit.cc 60 binutils.bintools # for ar, dwp, nm, objcopy, objdump, strip 61 ]; 62 }; 63 64 # Needed for _some_ system libraries, grep INCLUDEDIR. 65 includes_joined = symlinkJoin { 66 name = "tensorflow-deps-merged"; 67 paths = [ 68 pkgs.protobuf 69 jsoncpp 70 ]; 71 }; 72 73 tfFeature = x: if x then "1" else "0"; 74 75 version = "2.1.0"; 76 variant = if cudaSupport then "-gpu" else ""; 77 pname = "tensorflow${variant}"; 78 79 pythonEnv = python.withPackages (_: 80 [ # python deps needed during wheel build time (not runtime, see the buildPythonPackage part for that) 81 numpy 82 keras-preprocessing 83 protobuf 84 wrapt 85 gast 86 astor 87 absl-py 88 termcolor 89 keras-applications 90 setuptools 91 wheel 92 ] ++ lib.optionals (!isPy3k) 93 [ future 94 functools32 95 mock 96 ]); 97 98 bazel-build = buildBazelPackage { 99 name = "${pname}-${version}"; 100 bazel = bazel_0_29; 101 102 src = fetchFromGitHub { 103 owner = "tensorflow"; 104 repo = "tensorflow"; 105 rev = "v${version}"; 106 sha256 = "1g79xi8yl4sjia8ysk9b7xfzrz83zy28v5dlb2wzmcf0k5pmz60p"; 107 }; 108 109 patches = [ 110 # Work around https://github.com/tensorflow/tensorflow/issues/24752 111 ../no-saved-proto.patch 112 # Fixes for NixOS jsoncpp 113 ../system-jsoncpp.patch 114 115 (fetchpatch { 116 name = "backport-pr-18950.patch"; 117 url = "https://github.com/tensorflow/tensorflow/commit/73640aaec2ab0234d9fff138e3c9833695570c0a.patch"; 118 sha256 = "1n9ypbrx36fc1kc9cz5b3p9qhg15xxhq4nz6ap3hwqba535nakfz"; 119 }) 120 121 (fetchpatch { 122 # Don't try to fetch things that don't exist 123 name = "prune-missing-deps.patch"; 124 url = "https://github.com/tensorflow/tensorflow/commit/b39b1ed24b4814db27d2f748dc85c10730ae851d.patch"; 125 sha256 = "1skysz53nancvw1slij6s7flar2kv3gngnsq60ff4lap88kx5s6c"; 126 excludes = [ "tensorflow/cc/saved_model/BUILD" ]; 127 }) 128 129 ./lift-gast-restriction.patch 130 131 # cuda 10.2 does not have "-bin2c-path" option anymore 132 # https://github.com/tensorflow/tensorflow/issues/34429 133 ../cuda-10.2-no-bin2c-path.patch 134 ]; 135 136 # On update, it can be useful to steal the changes from gentoo 137 # https://gitweb.gentoo.org/repo/gentoo.git/tree/sci-libs/tensorflow 138 139 nativeBuildInputs = [ 140 swig which pythonEnv 141 ] ++ lib.optional cudaSupport addOpenGLRunpath; 142 143 buildInputs = [ 144 jemalloc 145 openmpi 146 glibcLocales 147 git 148 149 # libs taken from system through the TF_SYS_LIBS mechanism 150 # grpc 151 sqlite 152 openssl 153 jsoncpp 154 pkgs.protobuf 155 curl 156 snappy 157 flatbuffers 158 icu 159 double-conversion 160 libpng 161 libjpeg 162 giflib 163 re2 164 pkgs.lmdb 165 ] ++ lib.optionals cudaSupport [ 166 cudatoolkit 167 cudnn 168 nvidia_x11 169 ] ++ lib.optionals mklSupport [ 170 mkl 171 ] ++ lib.optionals stdenv.isDarwin [ 172 Foundation 173 Security 174 ]; 175 176 # arbitrarily set to the current latest bazel version, overly careful 177 TF_IGNORE_MAX_BAZEL_VERSION = true; 178 179 # Take as many libraries from the system as possible. Keep in sync with 180 # list of valid syslibs in 181 # https://github.com/tensorflow/tensorflow/blob/master/third_party/systemlibs/syslibs_configure.bzl 182 TF_SYSTEM_LIBS = lib.concatStringsSep "," [ 183 "absl_py" 184 "astor_archive" 185 "boringssl" 186 # Not packaged in nixpkgs 187 # "com_github_googleapis_googleapis" 188 # "com_github_googlecloudplatform_google_cloud_cpp" 189 "com_google_protobuf" 190 "com_googlesource_code_re2" 191 "curl" 192 "cython" 193 "double_conversion" 194 "flatbuffers" 195 "gast_archive" 196 # Lots of errors, requires an older version 197 # "grpc" 198 "hwloc" 199 "icu" 200 "jpeg" 201 "jsoncpp_git" 202 "keras_applications_archive" 203 "lmdb" 204 "nasm" 205 # "nsync" # not packaged in nixpkgs 206 "opt_einsum_archive" 207 "org_sqlite" 208 "pasta" 209 "pcre" 210 "six_archive" 211 "snappy" 212 "swig" 213 "termcolor_archive" 214 "wrapt" 215 "zlib_archive" 216 ]; 217 218 INCLUDEDIR = "${includes_joined}/include"; 219 220 PYTHON_BIN_PATH = pythonEnv.interpreter; 221 222 TF_NEED_GCP = true; 223 TF_NEED_HDFS = true; 224 TF_ENABLE_XLA = tfFeature xlaSupport; 225 226 CC_OPT_FLAGS = " "; 227 228 # https://github.com/tensorflow/tensorflow/issues/14454 229 TF_NEED_MPI = tfFeature cudaSupport; 230 231 TF_NEED_CUDA = tfFeature cudaSupport; 232 TF_CUDA_PATHS = lib.optionalString cudaSupport "${cudatoolkit_joined},${cudnn},${nccl}"; 233 GCC_HOST_COMPILER_PREFIX = lib.optionalString cudaSupport "${cudatoolkit_cc_joined}/bin"; 234 GCC_HOST_COMPILER_PATH = lib.optionalString cudaSupport "${cudatoolkit_cc_joined}/bin/gcc"; 235 TF_CUDA_COMPUTE_CAPABILITIES = lib.concatStringsSep "," cudaCapabilities; 236 237 postPatch = '' 238 # https://github.com/tensorflow/tensorflow/issues/20919 239 sed -i '/androidndk/d' tensorflow/lite/kernels/internal/BUILD 240 241 # Tensorboard pulls in a bunch of dependencies, some of which may 242 # include security vulnerabilities. So we make it optional. 243 # https://github.com/tensorflow/tensorflow/issues/20280#issuecomment-400230560 244 sed -i '/tensorboard >=/d' tensorflow/tools/pip_package/setup.py 245 ''; 246 247 preConfigure = let 248 opt_flags = [] 249 ++ lib.optionals sse42Support ["-msse4.2"] 250 ++ lib.optionals avx2Support ["-mavx2"] 251 ++ lib.optionals fmaSupport ["-mfma"]; 252 in '' 253 patchShebangs configure 254 255 # dummy ldconfig 256 mkdir dummy-ldconfig 257 echo "#!${stdenv.shell}" > dummy-ldconfig/ldconfig 258 chmod +x dummy-ldconfig/ldconfig 259 export PATH="$PWD/dummy-ldconfig:$PATH" 260 261 export PYTHON_LIB_PATH="$NIX_BUILD_TOP/site-packages" 262 export CC_OPT_FLAGS="${lib.concatStringsSep " " opt_flags}" 263 mkdir -p "$PYTHON_LIB_PATH" 264 265 # To avoid mixing Python 2 and Python 3 266 unset PYTHONPATH 267 ''; 268 269 configurePhase = '' 270 runHook preConfigure 271 ./configure 272 runHook postConfigure 273 ''; 274 275 # FIXME: Tensorflow uses dlopen() for CUDA libraries. 276 NIX_LDFLAGS = lib.optionalString cudaSupport "-lcudart -lcublas -lcufft -lcurand -lcusolver -lcusparse -lcudnn"; 277 278 hardeningDisable = [ "format" ]; 279 280 bazelFlags = [ 281 # temporary fixes to make the build work with bazel 0.27 282 "--incompatible_no_support_tools_in_action_inputs=false" 283 ]; 284 bazelBuildFlags = [ 285 "--config=opt" # optimize using the flags set in the configure phase 286 ] 287 ++ lib.optionals (mklSupport) [ "--config=mkl" ]; 288 289 bazelTarget = "//tensorflow/tools/pip_package:build_pip_package //tensorflow/tools/lib_package:libtensorflow"; 290 291 fetchAttrs = { 292 # So that checksums don't depend on these. 293 TF_SYSTEM_LIBS = null; 294 295 # cudaSupport causes fetch of ncclArchive, resulting in different hashes 296 sha256 = if cudaSupport then 297 "0hg3ysy644950a34j28hrb317cz8gcbb9n84d36wdailvnlshghb" 298 else 299 "1gy4pz9kn30wb9c4a9584fibb88c3h38y3dqa99yw1lbsbyyi28c"; 300 }; 301 302 buildAttrs = { 303 outputs = [ "out" "python" ]; 304 305 preBuild = '' 306 patchShebangs . 307 ''; 308 309 installPhase = '' 310 mkdir -p "$out" 311 tar -xf bazel-bin/tensorflow/tools/lib_package/libtensorflow.tar.gz -C "$out" 312 # Write pkgconfig file. 313 mkdir "$out/lib/pkgconfig" 314 cat > "$out/lib/pkgconfig/tensorflow.pc" << EOF 315 Name: TensorFlow 316 Version: ${version} 317 Description: Library for computation using data flow graphs for scalable machine learning 318 Requires: 319 Libs: -L$out/lib -ltensorflow 320 Cflags: -I$out/include/tensorflow 321 EOF 322 323 # build the source code, then copy it to $python (build_pip_package 324 # actually builds a symlink farm so we must dereference them). 325 bazel-bin/tensorflow/tools/pip_package/build_pip_package --src "$PWD/dist" 326 cp -Lr "$PWD/dist" "$python" 327 ''; 328 329 postFixup = lib.optionalString cudaSupport '' 330 find $out -type f \( -name '*.so' -or -name '*.so.*' \) | while read lib; do 331 addOpenGLRunpath "$lib" 332 done 333 ''; 334 }; 335 336 meta = with stdenv.lib; { 337 description = "Computation using data flow graphs for scalable machine learning"; 338 homepage = http://tensorflow.org; 339 license = licenses.asl20; 340 maintainers = with maintainers; [ jyp abbradar ]; 341 platforms = with platforms; linux ++ darwin; 342 # It is complaining about not having protobuf 3.8, which is weird because 343 # it doesn't have that on master either. 344 broken = true; 345 ## The py2 build fails due to some issue importing protobuf. Possibly related to the fix in 346 ## https://github.com/akesandgren/easybuild-easyblocks/commit/1f2e517ddfd1b00a342c6abb55aef3fd93671a2b 347 #broken = !(xlaSupport -> cudaSupport) || !isPy3k; 348 }; 349 }; 350 351in buildPythonPackage { 352 inherit version pname; 353 disabled = isPy27 || (pythonAtLeast "3.8"); 354 355 src = bazel-build.python; 356 357 # Upstream has a pip hack that results in bin/tensorboard being in both tensorflow 358 # and the propagated input tensorflow-tensorboard, which causes environment collisions. 359 # Another possibility would be to have tensorboard only in the buildInputs 360 # https://github.com/tensorflow/tensorflow/blob/v1.7.1/tensorflow/tools/pip_package/setup.py#L79 361 postInstall = '' 362 rm $out/bin/tensorboard 363 ''; 364 365 setupPyGlobalFlags = [ "--project_name ${pname}" ]; 366 367 # tensorflow/tools/pip_package/setup.py 368 propagatedBuildInputs = [ 369 absl-py 370 astor 371 gast 372 google-pasta 373 keras-applications 374 keras-preprocessing 375 numpy 376 six 377 protobuf 378 tensorflow-estimator_2 379 termcolor 380 wrapt 381 grpcio 382 opt-einsum 383 ] ++ lib.optionals (!isPy3k) [ 384 mock 385 future 386 functools32 387 ] ++ lib.optionals (pythonOlder "3.4") [ 388 backports_weakref enum34 389 ] ++ lib.optionals withTensorboard [ 390 tensorflow-tensorboard_2 391 ]; 392 393 nativeBuildInputs = lib.optional cudaSupport addOpenGLRunpath; 394 395 postFixup = lib.optionalString cudaSupport '' 396 find $out -type f \( -name '*.so' -or -name '*.so.*' \) | while read lib; do 397 addOpenGLRunpath "$lib" 398 done 399 ''; 400 401 # Actual tests are slow and impure. 402 # TODO try to run them anyway 403 # TODO better test (files in tensorflow/tools/ci_build/builds/*test) 404 checkPhase = '' 405 ${python.interpreter} <<EOF 406 # A simple "Hello world" 407 import tensorflow as tf 408 hello = tf.constant("Hello, world!") 409 tf.print(hello) 410 411 # Fit a simple model to random data 412 import numpy as np 413 np.random.seed(0) 414 tf.random.set_seed(0) 415 model = tf.keras.models.Sequential([ 416 tf.keras.layers.Dense(1, activation="linear") 417 ]) 418 model.compile(optimizer="sgd", loss="mse") 419 420 x = np.random.uniform(size=(1,1)) 421 y = np.random.uniform(size=(1,)) 422 model.fit(x, y, epochs=1) 423 EOF 424 ''; 425 # Regression test for #77626 removed because not more `tensorflow.contrib`. 426 427 passthru.libtensorflow = bazel-build.out; 428 429 inherit (bazel-build) meta; 430}