I have installed the Tensorflow bindings with python successfully. But when I try to import Tensorflow, I get the follwoing error.
ImportError: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.17' not found (required by /usr/local/lib/python2.7/dist-packages/tensorflow/python/_pywrap_tensorflow.so)
I have tried to update GLIBC_2.15 to 2.17, but no luck.
I've just managed to install tensorflow 0.12rc0 on CentOS 6.5 with glibc 2.12, without having root privileges. Simply installing tensorflow binary via pip was giving me an error, related to GLIBC version as well.
Basically, you have 4 options how to deal with this (each with some advantages and disadvantages):
This is, probably, the best option, if your system supports this, you have root privileges, and you are confident that this upgrade won't break anything for some weird reason. Ultimately, this goes up to upgrading the whole Linux distribution. Here's a nice short list of default GLIBC versions on popular distributions.
Compile or download binary. The most simple&straightforward option. Especially if you only need to run few simple scripts.
.bashrc
. This may work for TF 0.6.0, but you would probably have to start again from scratch, when each new tensorflow version is released. E.g. here's a fix for 0.9.0.
If you re-compile it from source and link against your existing GLIBC, newer GLIBC would be no longer needed. Somehow, this option was not mentioned in any answer here yet. Imho, this is the best option, both "in general", and "specifically for tensorflow".
A quick summary of "building tensorflow on outdated system":
Although the official guide provides a "installing from sources" section, there are few tricks you need to do to build it on an outdated system. Here I assume, that you do not have root privileges (if you do - you probably would be able to install the same pre-requestities with a package manager, rather them manually building them from source).
I found two well-documented success stories: #1, #2 and a number of useful posts on the official github (mostly about a set of libraries to link inside the binary): #1, #2, #3, #4. I had to combine tricks, described there to successfully compile TF in my case.
First of all, check your gcc --version
, and verify that it supports c++11. Mine was 4.4.7, so it won't work. I've downloaded gcc-4.9.4 source code, and compiled it. This step is pretty straightforward, but the compilation itself may take few hours. As a workaround for an issue in bazel, I've compiled gcc with hardcoded paths to as
,ld
and nm
. However, you may try another workarounds: (1, 2).
#!/bin/sh
unset LIBRARY_PATH CPATH C_INCLUDE_PATH
unset PKG_CONFIG_PATH CPLUS_INCLUDE_PATH INCLUDE LD_LIBRARY_PATH
cd gcc-4.9.4
./contrib/download_prerequisites
mkdir objdir
cd objdir
# I've added --disable-multilib to fix the following error:
# /usr/bin/ld: crt1.o: No such file: No such file or directory
# collect2: ld returned 1 exit status
# configure: error: I suspect your system does not have 32-bit
# developement libraries (libc and headers). If you have them,
# rerun configure with --enable-multilib. If you do not have them,
# and want to build a 64-bit-only compiler, rerun configure
# with --disable-multilib.
../configure --prefix=$HOME/opt/gcc-4.9.4 \
--disable-multilib \
--disable-nls \
--enable-languages=c,c++ \
--with-ld=/usr/bin/ld \
--with-nm=/usr/bin/nm \
--with-as=/usr/bin/as
make
make install
Check your java --version
. Bazel requires JDK 8, install it if necessary. (They still provide some jdk7 related downloads, for bazel-0.4.1 but it looks like they consider it deprecated)
I've created a separate use_gcc_4.9.4.sh
file, with necessary environment variables. I use source ./use_gcc_4.9.4.sh
when I need to so something related to this newer compiler.
#!/bin/sh
this=$HOME/opt/gcc-4.9.4
export PATH=$this/bin:$PATH
export CPATH=$this/include:$CPATH
export LIBRARY_PATH=$this/lib:$LIBRARY_PATH
export LIBRARY_PATH=$this/lib64:$LIBRARY_PATH
export LD_LIBRARY_PATH=$this/lib:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$this/lib64:$LD_LIBRARY_PATH
The current bazel binary (0.4.1) requires GLIBC 2.14, so we have to compile bazel from source as well (with our new gcc). Works OK, unless you are only allowed to run a very limited number of threads on the target machine. (This post describes some additional workarounds, but in my case they were not needed, maybe due to recent updates in bazel code.)
Obtain tensorflow source code git clone https://github.com/tensorflow/tensorflow
, and install prerequisites you need (CUDA,cuDNN,python, etc). See official guide.
If you're not using default system gcc (e.g. if you had to compile newer gcc, like discussed above), add the following linker flags to tensorflow/third_party/gpus/crosstool/CROSSTOOL.tpl
, line 59:
linker_flag: "-L/home/username/localinst/opt/gcc-4.9.4/lib64"
linker_flag: "-Wl,-rpath,/home/username/localinst/opt/gcc-4.9.4/lib64"
Without this step, you would likely run into error messages like this:
# ERROR: /home/username/localdistr/src/tensorflow/tensorflow/tensorflow/core/debug/BUILD:33:1: null failed: protoc failed: error executing command bazel-out/host/bin/external/protobuf/protoc '--cpp_out=bazel-out/local_linux-py3-opt/genfiles/' '--plugin=protoc-gen-grpc=bazel-out/host/bin/external/grpc/grpc_cpp_plugin' ... (remaining 8 argument(s) skipped): com.google.devtools.build.lib.shell.BadExitStatusException: Process exited with status 1.
# bazel-out/host/bin/external/protobuf/protoc: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by bazel-out/host/bin/external/protobuf/protoc)
# bazel-out/host/bin/external/protobuf/protoc: /usr/lib64/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by bazel-out/host/bin/external/protobuf/protoc)
# bazel-out/host/bin/external/protobuf/protoc: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.18' not found (required by bazel-out/host/bin/external/protobuf/protoc)
Finally, to avoid GLIBC dependencies, we have to statically link some libraries, by adding the -lrt
linker flag (maybe -lm
as well). I found multiple posts, suggesting to add this in a different manner:
via "third_party/gpus/crosstool/CROSSTOOL.tpl" (the same file we've just edited in the previous step, just below the lines we've already added).
linker_flag: "-lrt"
linker_flag: "-lm"
via "tensorflow/tensorflow.bzl" (works for me, but less convenient just because you have to edit one more file. I'm not sure it's 100% equivalent to the previous point)
Without -lrt
I ran into GLIBC-version-specific error again, trying to import tensorflow
:
# ImportError: /lib64/libc.so.6: version `GLIBC_2.14' not found (required by /home/username/anaconda3/envs/myenvname/lib/python3.5/site-packages/tensorflow/python/_pywrap_tensorflow.so)
Without -lm
you may run into this (for me, it turned out to be not necessary).
Run the build process.
source ./use_gcc_4.9.4.sh
./configure
bazel build -c opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
pip install --upgrade /tmp/tensorflow_pkg/tensorflow-0.12.0rc0-cp35-cp35m-linux_x86_64.whl
Try to run the following simple python script to test if the most basic stuff is functioning:
import tensorflow as tf
hello = tf.constant('Hello, TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
a = tf.constant(10)
b = tf.constant(32)
print(sess.run(a + b))