1 #!/usr/bin/env bash 2 # Copyright 2017 The TensorFlow Authors. All Rights Reserved. 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # 8 # http://www.apache.org/licenses/LICENSE-2.0 9 # 10 # Unless required by applicable law or agreed to in writing, software 11 # distributed under the License is distributed on an "AS IS" BASIS, 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 # ============================================================================== 16 set -e 17 18 # By default this builds packages for the Pi Two and Three only, since the NEON support 19 # this allows makes calculations many times faster. To support the Pi One or Zero, pass 20 # PI_ONE as the first argument to the script, for example: 21 # tensorflow/tools/ci_build/pi/build_raspberry_pi.sh PI_ONE 22 # 23 # To install the cross-compilation support for Python this script needs on Ubuntu Trusty, run 24 # something like these steps, after backing up your original /etc/apt/sources.list file: 25 # 26 # dpkg --add-architecture armhf 27 # echo 'deb [arch=armhf] http://ports.ubuntu.com/ trusty main restricted universe multiverse' >> /etc/apt/sources.list.d/armhf.list 28 # echo 'deb [arch=armhf] http://ports.ubuntu.com/ trusty-updates main restricted universe multiverse' >> /etc/apt/sources.list.d/armhf.list 29 # echo 'deb [arch=armhf] http://ports.ubuntu.com/ trusty-security main restricted universe multiverse' >> /etc/apt/sources.list.d/armhf.list 30 # echo 'deb [arch=armhf] http://ports.ubuntu.com/ trusty-backports main restricted universe multiverse' >> /etc/apt/sources.list.d/armhf.list 31 # sed -i 's#deb http://archive.ubuntu.com/ubuntu/#deb [arch=amd64] http://archive.ubuntu.com/ubuntu/#g' /etc/apt/sources.list 32 # apt-get update 33 # apt-get install -y libpython-all-dev:armhf 34 # 35 # Make sure you have an up to date version of the Bazel build tool installed too. 36 37 yes '' | ./configure 38 39 # Fix for curl build problem in 32-bit, see https://stackoverflow.com/questions/35181744/size-of-array-curl-rule-01-is-negative 40 sudo sed -i 's/define CURL_SIZEOF_LONG 8/define CURL_SIZEOF_LONG 4/g' /usr/include/curl/curlbuild.h 41 sudo sed -i 's/define CURL_SIZEOF_CURL_OFF_T 8/define CURL_SIZEOF_CURL_OFF_T 4/g' /usr/include/curl/curlbuild.h 42 43 # The system-installed OpenSSL headers get pulled in by the latest BoringSSL 44 # release on this configuration, so move them before we build: 45 if [ -d /usr/include/openssl ]; then 46 sudo mv /usr/include/openssl /usr/include/openssl.original 47 fi 48 49 WORKSPACE_PATH=`pwd` 50 51 # Build the OpenBLAS library, which is faster than Eigen on the Pi Zero/One. 52 # TODO(petewarden) - It would be nicer to move this into the main Bazel build 53 # process if we can maintain a build file for this. 54 TOOLCHAIN_INSTALL_PATH=/tmp/toolchain_install/ 55 sudo rm -rf ${TOOLCHAIN_INSTALL_PATH} 56 mkdir ${TOOLCHAIN_INSTALL_PATH} 57 cd ${TOOLCHAIN_INSTALL_PATH} 58 curl -L https://github.com/raspberrypi/tools/archive/0e906ebc527eab1cdbf7adabff5b474da9562e9f.tar.gz -o toolchain.tar.gz 59 tar xzf toolchain.tar.gz 60 mv tools-0e906ebc527eab1cdbf7adabff5b474da9562e9f/ tools 61 62 CROSSTOOL_CC=${TOOLCHAIN_INSTALL_PATH}/tools/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc 63 64 OPENBLAS_SRC_PATH=/tmp/openblas_src/ 65 sudo rm -rf ${OPENBLAS_SRC_PATH} 66 git clone https://github.com/xianyi/OpenBLAS ${OPENBLAS_SRC_PATH} 67 cd ${OPENBLAS_SRC_PATH} 68 # If this path is changed, you'll also need to update 69 # cxx_builtin_include_directory in third_party/toolchains/cpus/arm/CROSSTOOL.tpl 70 OPENBLAS_INSTALL_PATH=/tmp/openblas_install/ 71 make CC=${CROSSTOOL_CC} FC=${CROSSTOOL_CC} HOSTCC=gcc TARGET=ARMV6 72 make PREFIX=${OPENBLAS_INSTALL_PATH} install 73 74 if [[ $1 == "PI_ONE" ]]; then 75 PI_COPTS="--copt=-march=armv6 --copt=-mfpu=vfp 76 --copt=-DUSE_GEMM_FOR_CONV --copt=-DUSE_OPENBLAS 77 --copt=-isystem --copt=${OPENBLAS_INSTALL_PATH}/include/ 78 --copt=-std=gnu11 --copt=-DS_IREAD=S_IRUSR --copt=-DS_IWRITE=S_IWUSR 79 --linkopt=-L${OPENBLAS_INSTALL_PATH}/lib/ 80 --linkopt=-l:libopenblas.a" 81 echo "Building for the Pi One/Zero, with no NEON support" 82 else 83 PI_COPTS='--copt=-march=armv7-a --copt=-mfpu=neon-vfpv4 84 --copt=-std=gnu11 --copt=-DS_IREAD=S_IRUSR --copt=-DS_IWRITE=S_IWUSR 85 --copt=-O3 86 --copt=-U__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 87 --copt=-U__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 88 --copt=-U__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8' 89 echo "Building for the Pi Two/Three, with NEON acceleration" 90 fi 91 92 # We need to pass down the environment variable with a possible alternate Python 93 # include path for Python 3.x builds to work. 94 export CROSSTOOL_PYTHON_INCLUDE_PATH 95 96 cd ${WORKSPACE_PATH} 97 bazel build -c opt ${PI_COPTS} \ 98 --config=monolithic \ 99 --copt=-funsafe-math-optimizations --copt=-ftree-vectorize \ 100 --copt=-fomit-frame-pointer --cpu=armeabi \ 101 --crosstool_top=@local_config_arm_compiler//:toolchain \ 102 --verbose_failures \ 103 //tensorflow/tools/benchmark:benchmark_model \ 104 //tensorflow/tools/pip_package:build_pip_package 105 106 OUTDIR=output-artifacts 107 mkdir -p "${OUTDIR}" 108 echo "Final outputs will go to ${OUTDIR}" 109 110 # Build a universal wheel. 111 BDIST_OPTS="--universal" \ 112 bazel-bin/tensorflow/tools/pip_package/build_pip_package "${OUTDIR}" 113 114 OLD_FN=$(ls "${OUTDIR}" | grep -m 1 \.whl) 115 SUB='s/tensorflow-([^-]+)-([^-]+)-.*/tensorflow-\1-\2-none-any.whl/; print' 116 NEW_FN=$(echo "${OLD_FN}" | perl -ne "${SUB}") 117 mv "${OUTDIR}/${OLD_FN}" "${OUTDIR}/${NEW_FN}" 118 cp bazel-bin/tensorflow/tools/benchmark/benchmark_model "${OUTDIR}" 119 120 echo "Output can be found here:" 121 find "${OUTDIR}" 122