Skip to content

Instantly share code, notes, and snippets.

@lnshi
Created March 26, 2022 04:59
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lnshi/eb3dea05d99daba5c932bbc786cc3701 to your computer and use it in GitHub Desktop.
Save lnshi/eb3dea05d99daba5c932bbc786cc3701 to your computer and use it in GitHub Desktop.
Build TensorFlow C library on Apple M1 (darwin_arm64) and use it with TensorFlow rust bindings

Background

Currently if you try to use the TensorFlow rust bindings crate: tensorflow = "0.17.0", this crate's sub-crate: tensorflow-sys will try to build the underlying TensorFlow C library from the source as Google hasn't provided an official release for Apple M1, but unfortunately the building will fail.

This gist provides a full working instructions for you to build the TensorFlow C library on Apple M1 (darwin_arm64), and eventually use it with the TensorFlow rust bindings crate: tensorflow = "0.17.0".

This gist was tested on TensorFlow v2.8.0, the other versions should work in the same way.

Steps

  1. Install bazel:

    > bazel --version
    > bazel 4.2.1
  2. Create python3.9 venv and install numpy (Python 3.9.9 + numpy 1.22.3);

  3. git clone the TensorFlow source code, and switch to v2.8.0 branch;

  4. Go to the cloned tensorflow/ project, do the compiling, and install it to your system:

    # Provide the python interpreter path in the venv you just created which has numpy installed,
    # for me: /private/tmp/venv/bin/python
    ./configure
    
    bazel build --jobs=10 --compilation_mode=opt --copt=-march=native //tensorflow/tools/lib_package:libtensorflow
    • After the compiling completed you should be able to find the bazel-bin/tensorflow/tools/lib_package/libtensorflow.tar.gz;
    • Install the tarball to /usr/local/lib:
      sudo mkdir -p /usr/local/lib/libtensorflow-cpu-darwin-arm64-2.8.0
      
      sudo tar -C /usr/local/lib/libtensorflow-cpu-darwin-arm64-2.8.0 -xzf bazel-bin/tensorflow/tools/lib_package/libtensorflow.tar.gz
  5. Configure the installed TensorFlow dylibs to pkg-config (if u haven't installed do: brew install pkg-config):

    • Generate the tensorflow.pc, u could utilize the $TENSORFLOW_SRC/tensorflow/c/generate-pc.sh script, but i was not able to run it, anyway the contents of the tensorflow.pc is very straightforward like below (make sure all the paths are correct):
      prefix=/usr/local/lib/libtensorflow-cpu-darwin-arm64-2.8.0
      exec_prefix=${prefix}
      libdir=${exec_prefix}/lib
      includedir=${prefix}/include/tensorflow
      
      Name: TensorFlow
      Version: 2.8.0
      Description: Library for computation using data flow graphs for scalable machine learning
      Requires:
      Libs: -L${libdir} -ltensorflow -ltensorflow_framework
      Cflags: -I${includedir}
      
    • Put the above tensorflow.pc into your system PKG_CONFIG_PATH, for me i use ~/.pkg_configs;
    • Then run the command PKG_CONFIG_PATH=~/.pkg_configs/ pkg-config --list-all | grep tensorflow u should be able to see:
      tensorflow        TensorFlow - Library for computation using data flow graphs for scalable machine learning
      
  6. Till here ur systemwide setup is all ok, but unfortunately due to this bug of rust-lang/pkg-config-rs, u need to perform the below steps to make ur rust TensorFlow project work:

    • Switch ur project's tensorflow-rust bindings dependencies to local source code: tensorflow = { path = "/Users/leonard/projects/rust" };
    • Then upgrade tensorflow-rust's dependant create pkg-config = "0.3.19" to pkg-config = "0.3.24";
  7. Finally all will work:

    cargo clean
    
    # Note u have to use the absolute path or $(pwd)
    PKG_CONFIG_PATH=~/.pkg_configs/ cargo build

🎉🎉🎉

@kcking
Copy link

kcking commented May 2, 2022

Thank you for the build instructions! Just FYI I had to omit --copt=-march=native from step 4 to get it working.

@wangjia184
Copy link

wangjia184 commented Aug 16, 2022

Using -march=native enables all instruction subsets supported by the local machine

Only Clang >= v15 supports this flag on Mac M1.

I am using --copt=-mcpu=apple-m1 instead

@wangjia184
Copy link

wangjia184 commented Aug 17, 2022

@cemlyn007
Copy link

I used a different version of NumPy but found for my installation to work, I needed to pip install like this:

pip install --no-binary numpy numpy

@juancresc
Copy link

adding the error im getting

INFO: Found 1 target...
ERROR: /private/var/tmp/_bazel_juan.crescente/0f82212909c9d84424a02f2dbee8d5eb/external/boringssl/BUILD:133:11: Compiling src/crypto/cpu_aarch64_apple.c failed: (Exit 1): wrapped_clang failed: error executing command (from target @boringssl//:crypto) external/local_config_cc/wrapped_clang '-D_FORTIFY_SOURCE=1' -fstack-protector -fcolor-diagnostics -Wall -Wthread-safety -Wself-assign -fno-omit-frame-pointer -g0 -O2 -DNDEBUG '-DNS_BLOCK_ASSERTIONS=1' ... (remaining 48 arguments skipped)
external/boringssl/src/crypto/cpu_aarch64_apple.c:56:2: error: "NEON and crypto extensions should be statically available."
#error "NEON and crypto extensions should be statically available."
 ^
1 error generated.
Error in child process '/usr/bin/xcrun'. 1
Target //tensorflow/tools/lib_package:libtensorflow failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 67.755s, Critical Path: 23.06s
INFO: 1096 processes: 50 internal, 1046 local.
FAILED: Build did NOT complete successfully

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment