diff --git a/Dockerfile.aarch64 b/Dockerfile.aarch64 new file mode 100644 index 0000000..f6dc3f1 --- /dev/null +++ b/Dockerfile.aarch64 @@ -0,0 +1,48 @@ +FROM arm64v8/ubuntu:20.04 as base +ENV DEBIAN_FRONTEND=noninteractive +# See http://bugs.python.org/issue19846 +ENV LANG C.UTF-8 +# https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/dockerfiles/dockerfiles + +ARG DEBIAN_FRONTEND=noninteractive + +# Install apt dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3 \ + python3-pip \ + python3-dev \ + build-essential \ + protobuf-compiler \ + wget \ + curl \ + git \ + gpg-agent \ + gnupg \ + libgl1 \ + libglib2.0-0 \ + unzip \ + libstdc++6 && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* && \ + ln -s $(which python3) /usr/local/bin/python + +# Update pip/setuptools +RUN python3 -m pip --no-cache-dir install --upgrade \ + pip \ + setuptools + +# Install dependancies for Tensorflow +ADD tensorflow_io_gcs_filesystem-0.23.1-cp38-cp38-linux_aarch64.whl /tmp/tensorflow_io_gcs_filesystem-0.23.1-cp38-cp38-linux_aarch64.whl +RUN python3 -m pip install --no-cache-dir /tmp/tensorflow_io_gcs_filesystem-0.23.1-cp38-cp38-linux_aarch64.whl && rm /tmp/tensorflow_io_gcs_filesystem-0.23.1-cp38-cp38-linux_aarch64.whl +ADD tensorflow_io-0.23.1-cp38-cp38-linux_aarch64.whl /tmp/tensorflow_io-0.23.1-cp38-cp38-linux_aarch64.whl +RUN python3 -m pip install --no-cache-dir /tmp/tensorflow_io-0.23.1-cp38-cp38-linux_aarch64.whl && rm /tmp/tensorflow_io-0.23.1-cp38-cp38-linux_aarch64.whl + +# Install Tensorflow +ADD tensorflow-2.7.0-cp38-none-linux_aarch64.whl /tmp/tensorflow-2.7.0-cp38-none-linux_aarch64.whl +RUN python3 -m pip install --no-cache-dir /tmp/tensorflow-2.7.0-cp38-none-linux_aarch64.whl && rm /tmp/tensorflow-2.7.0-cp38-none-linux_aarch64.whl + +# Some TF tools expect a "python" binary +RUN ln -s $(which python3) /usr/local/bin/python + +ADD https://raw.githubusercontent.com/tensorflow/tensorflow/master/tensorflow/tools/dockerfiles/bashrc /etc/bash.bashrc +RUN chmod a+rwx /etc/bash.bashrc diff --git a/Dockerfile.armv7l b/Dockerfile.armv7l new file mode 100644 index 0000000..991cfbf --- /dev/null +++ b/Dockerfile.armv7l @@ -0,0 +1,58 @@ +FROM arm32v7/ubuntu:20.04 as base +ENV DEBIAN_FRONTEND=noninteractive +# See http://bugs.python.org/issue19846 +ENV LANG C.UTF-8 +# https://github.com/tensorflow/tensorflow/tree/master/tensorflow/tools/dockerfiles/dockerfiles + +ARG DEBIAN_FRONTEND=noninteractive + +# Install apt dependencies +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3 \ + python3-pip \ + python3-dev \ + build-essential \ + protobuf-compiler \ + wget \ + curl \ + git \ + gpg-agent \ + gnupg \ + libgl1 \ + libglib2.0-0 \ + unzip \ + libstdc++6 && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* && \ + ln -s $(which python3) /usr/local/bin/python + +# Update pip/setuptools +RUN python3 -m pip --no-cache-dir install --upgrade \ + pip \ + setuptools + +# Install tensorflow python dependencies for which there are good packages. +RUN apt-get update && apt-get install -y --no-install-recommends \ + python3-h5py && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +# No good libclang wheel is available for armv7l which is required for tensorflow +ADD libclang-12.0.0-py2.py3-none-linux_armv7l.whl /tmp/libclang-12.0.0-py2.py3-none-linux_armv7l.whl +RUN python3 -m pip install --no-cache-dir /tmp/libclang-12.0.0-py2.py3-none-linux_armv7l.whl && rm /tmp/libclang-12.0.0-py2.py3-none-linux_armv7l.whl + +# Install dependancies for Tensorflow +ADD tensorflow_io_gcs_filesystem-0.23.1-cp38-cp38-linux_armv7l.whl /tmp/tensorflow_io_gcs_filesystem-0.23.1-cp38-cp38-linux_armv7l.whl +RUN python3 -m pip install --no-cache-dir /tmp/tensorflow_io_gcs_filesystem-0.23.1-cp38-cp38-linux_armv7l.whl && rm /tmp/tensorflow_io_gcs_filesystem-0.23.1-cp38-cp38-linux_armv7l.whl +ADD tensorflow_io-0.23.1-cp38-cp38-linux_armv7l.whl /tmp/tensorflow_io-0.23.1-cp38-cp38-linux_armv7l.whl +RUN python3 -m pip install --no-cache-dir /tmp/tensorflow_io-0.23.1-cp38-cp38-linux_armv7l.whl && rm /tmp/tensorflow_io-0.23.1-cp38-cp38-linux_armv7l.whl + +# Install Tensorflow +ADD tensorflow-2.7.0-cp38-none-linux_armv7l.whl /tmp/tensorflow-2.7.0-cp38-none-linux_armv7l.whl +RUN python3 -m pip install --no-cache-dir /tmp/tensorflow-2.7.0-cp38-none-linux_armv7l.whl && rm /tmp/tensorflow-2.7.0-cp38-none-linux_armv7l.whl + +# Some TF tools expect a "python" binary +RUN ln -s $(which python3) /usr/local/bin/python + +ADD https://raw.githubusercontent.com/tensorflow/tensorflow/master/tensorflow/tools/dockerfiles/bashrc /etc/bash.bashrc +RUN chmod a+rwx /etc/bash.bashrc diff --git a/README.md b/README.md new file mode 100644 index 0000000..5b3fa26 --- /dev/null +++ b/README.md @@ -0,0 +1,65 @@ +# TENSORFLOW-ON-ARM + +This is my attempt to build a recent Tensorflow wheel and Docker image compatible with ARM32 and ARM64 devices. + +- Tensorflow v2.7.0 + +## Compiling Tensorflow Wheel +I checked out the Tensorflow source at version 2.7.0 and I had to edit the file `tensorflow/tools/ci_build/pi/build_raspberry_pi.sh` and insert on line 99 to add an ARMHF target. +``` +elif [[ $1 == "ARMHF" ]]; then + PI_COPTS="--config=elinux_armhf + --copt=-std=gnu11 + --copt=-O3" + WHEEL_ARCH=linux_armv7l +``` +I also removed the `--config=monolithic` option from the bazel build command around line 126. +After that I was able to cross compile the `aarch64` and `armv7l` wheels with the commands: + +``` +$ tensorflow/tools/ci_build/ci_build.sh PI-PYTHON38 \ + tensorflow/tools/ci_build/pi/build_raspberry_pi.sh AARCH64 +$ tensorflow/tools/ci_build/ci_build.sh PI-PYTHON38 \ + tensorflow/tools/ci_build/pi/build_raspberry_pi.sh ARMHF +``` +After running the command there was working python whl and library in the `output-artifacts` directory. + +I renamed the armhf output wheel from `tensorflow-2.7.0-cp38-none-linux_armhf.whl` to `tensorflow-2.7.0-cp38-none-linux_armv7l.whl` to ensure it matched the hardware architecture and would be installed by python. + +# Tensorflow IO +Tensorflow IO is required in order to install the Tensorflow wheel. There seems to be a chicken-egg problem +with creating a Tensorflow IO wheel. The Tensorflow Wheel won't install without TensorflowIO but TensorflowIO +won't compile without Tensorflow installed. + +I was able to work around this by installing just the python portion of Tensorflow IO. I had to actually +run this on ARM devices to get Tensorflow IO to compile. (QEMU segfaulted) + +``` +$ git clone https://github.com/tensorflow/io.git +$ cd io +$ git checkout v0.23.1 +$ python3 setup.py install # Install just the python code +$ python3 -m pip install tensorflow-2.7.0-cp38-none-linux_.whl # Install tensorflow wheel +``` + +From there I compiled Tensorflow IO with +``` +$ export SETUPTOOLS_USE_DISTUTILS=stdlib # Needed to overcome some strange error with python deps +# ./configure +$ bazel build -s --verbose_failures --local_ram_resources=HOST_RAM*.4 --local_cpu_resources=2 //tensorflow_io/... //tensorflow_io_gcs_filesystem/... +$ python3 setup.py bdist_wheel --data bazel-bin +$ python3 setup.py --project tensorflow_io_gcs_filesystem bdist_wheel --data bazel-bin +``` + +These wheels are included in this repo as well. + +## Docker Image +The Dockerfiles for `aarch64` and `armv7l` are slightly different as each had packages the other architecture didn't. + +I build them with docker buildx + +``` +docker run --rm --privileged multiarch/qemu-user-static --reset -p yes +docker buildx build --push --platform linux/arm/v7 -f Dockerfile.armv7l docker.io/snowzach/tensorflow:2.7.0-armv7l . +docker buildx build --push --platform linux/arm64/v8 --tag docker.io/snowzach/tensorflow:2.7.0-aarch64 -f Dockerfile.aarch64 . +```