Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 13 additions & 22 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -37,34 +37,25 @@ http_archive(
urls = ["https://github.com/quantumlib/qsim/archive/refs/tags/v0.13.3.zip"],
)

local_repository(
name = "python",
path = "third_party/python_legacy",
)

http_archive(
name = "org_tensorflow",
patches = [
"//third_party/tf:tf.patch",
],
sha256 = "f771db8d96ca13c72f73c85c9cfb6f5358e2de3dd62a97a9ae4b672fe4c6d094",
strip_prefix = "tensorflow-2.15.0",
urls = [
"https://github.com/tensorflow/tensorflow/archive/refs/tags/v2.15.0.zip",
],
patches = ["//third_party/tf:tf.patch"],
sha256 = "c8c8936e7b6156e669e08b3c388452bb973c1f41538149fce7ed4a4849c7a012",
strip_prefix = "tensorflow-2.16.2",
urls = ["https://github.com/tensorflow/tensorflow/archive/refs/tags/v2.16.2.zip"],
)


load("@org_tensorflow//tensorflow:workspace3.bzl", "tf_workspace3")

tf_workspace3()

load("@org_tensorflow//tensorflow:workspace2.bzl", "tf_workspace2")

tf_workspace2()

load("@org_tensorflow//tensorflow:workspace1.bzl", "tf_workspace1")

tf_workspace1()

load("@org_tensorflow//tensorflow:workspace0.bzl", "tf_workspace0")
load("@org_tensorflow//tensorflow:workspace3.bzl", "tf_workspace3"); tf_workspace3()
load("@org_tensorflow//tensorflow:workspace2.bzl", "tf_workspace2"); tf_workspace2()
load("@org_tensorflow//tensorflow:workspace1.bzl", "tf_workspace1"); tf_workspace1()
load("@org_tensorflow//tensorflow:workspace0.bzl", "tf_workspace0"); tf_workspace0()
Comment on lines +54 to +57
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's best to limit each PR to a specific purpose and avoid unrelated formatting changes. Also, although the TFQ contributor guidelines don't document this, we should follow the Bazel style generated by buildifier. That style uses the format of separate lines that was present in the original WORKSPACE file.

So, could you please undo the unrelated formatting changes?


tf_workspace0()

load("//third_party/tf:tf_configure.bzl", "tf_configure")

Expand Down
303 changes: 172 additions & 131 deletions configure.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,167 +13,208 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
set -euo pipefail

PLATFORM="$(uname -s | tr 'A-Z' 'a-z')"

function write_to_bazelrc() {
echo "$1" >> .bazelrc
}

function write_action_env_to_bazelrc() {
write_to_bazelrc "build --action_env $1=\"$2\""
}
# --- helpers ---------------------------------------------------------------
write_bazelrc() { echo "$1" >> .bazelrc; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although I personally don't mind short functions as one-liners, we had better follow the Google style guide and change these back to multiline function definitions.

write_tf_rc() { echo "$1" >> .tf_configure.bazelrc; }
die() { echo "ERROR: $*" >&2; exit 1; }

function write_linkopt_dir_to_bazelrc() {
write_to_bazelrc "build --linkopt -Wl,-rpath,$1" >> .bazelrc
}
is_macos() { [[ "${PLATFORM}" == "darwin" ]]; }
is_windows() { [[ "${PLATFORM}" =~ msys_nt*|mingw*|cygwin*|uwin* ]]; }

write_legacy_python_repo() {
mkdir -p third_party/python_legacy

function is_linux() {
[[ "${PLATFORM}" == "linux" ]]
}
# empty WORKSPACE
cat > third_party/python_legacy/WORKSPACE <<'EOF'
# intentionally empty
EOF

function is_macos() {
[[ "${PLATFORM}" == "darwin" ]]
}
# simple BUILD that exports defs.bzl
cat > third_party/python_legacy/BUILD <<'EOF'
package(default_visibility = ["//visibility:public"])
exports_files(["defs.bzl"])
EOF

function is_windows() {
# On windows, the shell script is actually running in msys
[[ "${PLATFORM}" =~ msys_nt*|mingw*|cygwin*|uwin* ]]
}
# defs.bzl MUST define 'interpreter' as a string, not a function.
# We also export py_runtime to satisfy older loads.
cat > third_party/python_legacy/defs.bzl <<EOF
# AUTOGENERATED by configure.sh
load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair")
# Absolute path to the python interpreter Bazel/TF should use:
interpreter = "${PYTHON_BIN_PATH}"
py_runtime = native.py_runtime
EOF

function is_ppc64le() {
[[ "$(uname -m)" == "ppc64le" ]]
echo "Wrote third_party/python_legacy with interpreter=${PYTHON_BIN_PATH}"
}

# --- start fresh -----------------------------------------------------------
rm -f .bazelrc .tf_configure.bazelrc

# Remove .bazelrc if it already exist
[ -e .bazelrc ] && rm .bazelrc

# Check if we are building GPU or CPU ops, default CPU
while [[ "$TF_NEED_CUDA" == "" ]]; do
read -p "Do you want to build ops again TensorFlow CPU pip package?"\
" Y or enter for CPU (tensorflow-cpu), N for GPU (tensorflow). [Y/n] " INPUT
case $INPUT in
[Yy]* ) echo "Build with CPU pip package."; TF_NEED_CUDA=0;;
[Nn]* ) echo "Build with GPU pip package."; TF_NEED_CUDA=1;;
"" ) echo "Build with CPU pip package."; TF_NEED_CUDA=0;;
* ) echo "Invalid selection: " $INPUT;;
# --- parse args ------------------------------------------------------------
USER_PY=""
for arg in "$@"; do
case "$arg" in
--python=*) USER_PY="${arg#--python=}" ;;
*) echo "Unknown arg: $arg" ;;
esac
done

while [[ "$TF_CUDA_VERSION" == "" ]]; do
read -p "Are you building against TensorFlow 2.1(including RCs) or newer?[Y/n] " INPUT
case $INPUT in
[Yy]* ) echo "Build against TensorFlow 2.1 or newer."; TF_CUDA_VERSION=11;;
[Nn]* ) echo "Build against TensorFlow <2.1."; TF_CUDA_VERSION=10.0;;
"" ) echo "Build against TensorFlow 2.1 or newer."; TF_CUDA_VERSION=11;;
* ) echo "Invalid selection: " $INPUT;;
# --- choose interpreter (venv/conda/system) --------------------------------
if [[ -n "${USER_PY}" ]]; then
PY="$USER_PY"
elif [[ -n "${PYTHON_BIN_PATH:-}" ]]; then
PY="$PYTHON_BIN_PATH"
elif [[ -n "${CONDA_PREFIX:-}" && -x "${CONDA_PREFIX}/bin/python" ]]; then
PY="${CONDA_PREFIX}/bin/python"
elif command -v python3.11 >/dev/null 2>&1; then
PY="$(command -v python3.11)"
elif command -v python3 >/dev/null 2>&1; then
PY="$(command -v python3)"
Comment on lines +73 to +78
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should mirror the logic discussed for the build script above. In other words, use the user-provided value, else try the conda path, else use python3 (checking the minimum).

else
die "No suitable Python found. Pass --python=/path/to/python or set PYTHON_BIN_PATH."
fi

# Normalize to an absolute path (readlink -f is GNU; fall back to python)
if command -v readlink >/dev/null 2>&1; then
PY_ABS="$(readlink -f "$PY" 2>/dev/null || true)"
fi
if [[ -z "${PY_ABS:-}" ]]; then
PY_ABS="$("$PY" - <<'PY'
import os,sys
print(os.path.abspath(sys.executable))
PY
Comment on lines +88 to +91
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This kind of thing does not need a heredoc. It can be done with the -c option to Python:

PY_ABS="$("$PY" -c 'import os, sys; print(os.path.abspath(sys.executable))')"

)"
fi
PYTHON_BIN_PATH="$PY_ABS"

# --- choose CPU/GPU like upstream script (default CPU) ---------------------
TF_NEED_CUDA=""
while [[ -z "${TF_NEED_CUDA}" ]]; do
read -p "Build against TensorFlow CPU pip package? [Y/n] " INPUT || true
case "${INPUT:-Y}" in
[Yy]* ) echo "CPU build selected."; TF_NEED_CUDA=0;;
[Nn]* ) echo "GPU build selected."; TF_NEED_CUDA=1;;
* ) echo "Please answer Y or n.";;
esac
done

# For TF >= 2.1 this value isn’t actually consulted by TFQ,
# but we keep a compatible prompt/flag.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry to be dense, but I don't actually understand what this is about. A compatible prompt/flag for what, exactly?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept this from the previous code, I keep this because I am not sure if it might be needed for any other package or dependency.

TF_CUDA_VERSION="11"

# Check if it's installed
# if [[ $(pip show tensorflow) == *tensorflow* ]] || [[ $(pip show tf-nightly) == *tf-nightly* ]]; then
# echo 'Using installed tensorflow'
# else
# # Uninstall CPU version if it is installed.
# if [[ $(pip show tensorflow-cpu) == *tensorflow-cpu* ]]; then
# echo 'Already have tensorflow non-gpu installed. Uninstalling......\n'
# pip uninstall tensorflow
# elif [[ $(pip show tf-nightly-cpu) == *tf-nightly-cpu* ]]; then
# echo 'Already have tensorflow non-gpu installed. Uninstalling......\n'
# pip uninstall tf-nightly
# fi
# # Install GPU version
# echo 'Installing tensorflow .....\n'
# pip install tensorflow
# fi



TF_CFLAGS=( $(python -c 'import tensorflow as tf; print(" ".join(tf.sysconfig.get_compile_flags()))') )
TF_LFLAGS="$(python -c 'import tensorflow as tf; print(" ".join(tf.sysconfig.get_link_flags()))')"


write_to_bazelrc "build --experimental_repo_remote_exec"
write_to_bazelrc "build --spawn_strategy=standalone"
write_to_bazelrc "build --strategy=Genrule=standalone"
write_to_bazelrc "build -c opt"
write_to_bazelrc "build --cxxopt=\"-D_GLIBCXX_USE_CXX11_ABI=1\""
write_to_bazelrc "build --cxxopt=\"-std=c++17\""

# The transitive inclusion of build rules from TensorFlow ends up including
# and building two copies of zlib (one from bazel_rules, one from the TF code
# baase itself). The version of zlib you get (at least in TF 2.15.0) ends up
# producing many compiler warnings that "a function declaration without a
# prototype is deprecated". It's difficult to patch the particular build rules
# involved, so the approach taken here is to silence those warnings for stuff
# in external/. TODO: figure out how to patch the BUILD files and put it there.
write_to_bazelrc "build --per_file_copt=external/.*@-Wno-deprecated-non-prototype"
write_to_bazelrc "build --host_per_file_copt=external/.*@-Wno-deprecated-non-prototype"

# Similarly, these are other harmless warnings about unused functions coming
# from things pulled in by the TF bazel config rules.
write_to_bazelrc "build --per_file_copt=external/com_google_protobuf/.*@-Wno-unused-function"
write_to_bazelrc "build --host_per_file_copt=external/com_google_protobuf/.*@-Wno-unused-function"
# --- sanity: python is importable and has TF -------------------------------
if [[ ! -x "$PYTHON_BIN_PATH" ]]; then
die "$PYTHON_BIN_PATH not found/executable."
fi

# Ensure TF is importable from system python (user should have installed it).
"$PYTHON_BIN_PATH" - <<'PY' || { echo "ERROR: tensorflow not importable by chosen Python."; exit 1; }
import tensorflow as tf
import tensorflow.sysconfig as sc
print("TF:", tf.__version__)
print("include:", sc.get_include())
print("lib:", sc.get_lib())
PY

# --- discover TF include/lib robustly --------------------------------------
HDR="$("$PYTHON_BIN_PATH" - <<'PY'
import tensorflow.sysconfig as sc
print(sc.get_include())
PY
)"

LIBDIR="$("$PYTHON_BIN_PATH" - <<'PY'
import os, tensorflow.sysconfig as sc
p = sc.get_lib()
print(p if os.path.isdir(p) else os.path.dirname(p))
PY
)"

LIBNAME="$("$PYTHON_BIN_PATH" - <<'PY'
import os, glob, tensorflow.sysconfig as sc
p = sc.get_lib()
d = p if os.path.isdir(p) else os.path.dirname(p)
cands = glob.glob(os.path.join(d,'libtensorflow_framework.so*')) \
or glob.glob(os.path.join(d,'libtensorflow.so*')) \
or glob.glob(os.path.join(d,'_pywrap_tensorflow_internal.*'))
print(os.path.basename(cands[0]) if cands else 'libtensorflow_framework.so.2')
PY
)"

echo "Detected:"
echo " PYTHON_BIN_PATH=$PYTHON_BIN_PATH"
echo " TF_HEADER_DIR=$HDR"
echo " TF_SHARED_LIBRARY_DIR=$LIBDIR"
echo " TF_SHARED_LIBRARY_NAME=$LIBNAME"

# --- write .tf_configure.bazelrc (repo_env for repository rules) -----------
write_tf_rc "build --repo_env=PYTHON_BIN_PATH=$PYTHON_BIN_PATH"
write_tf_rc "build --repo_env=TF_HEADER_DIR=$HDR"
write_tf_rc "build --repo_env=TF_SHARED_LIBRARY_DIR=$LIBDIR"
write_tf_rc "build --repo_env=TF_SHARED_LIBRARY_NAME=$LIBNAME"
write_tf_rc "build --repo_env=TF_NEED_CUDA=$TF_NEED_CUDA"
write_tf_rc "build --repo_env=TF_CUDA_VERSION=$TF_CUDA_VERSION"

# Make sure repo rules and sub-config see legacy Keras (keras 2 instead of Keras 3)
write_tf_rc "build --repo_env=TF_USE_LEGACY_KERAS=1"

# --- write third_party/python_legacy/ with interpreter --------------------
write_legacy_python_repo

# --- write .bazelrc (imports TF config usual flags) -----------------
write_bazelrc "try-import %workspace%/.tf_configure.bazelrc"
write_bazelrc "build --experimental_repo_remote_exec"
write_bazelrc "build --spawn_strategy=standalone"
write_bazelrc "build --strategy=Genrule=standalone"
write_bazelrc "build -c opt"
write_bazelrc "build --cxxopt=\"-D_GLIBCXX_USE_CXX11_ABI=1\""
write_bazelrc "build --cxxopt=\"-std=c++17\""
write_bazelrc "build --action_env=PYTHON_BIN_PATH=$PYTHON_BIN_PATH"
write_bazelrc "build --action_env=TF_USE_LEGACY_KERAS=1"
write_bazelrc "test --action_env=TF_USE_LEGACY_KERAS=1"


# zlib / protobuf warning suppressions
write_bazelrc "build --per_file_copt=external/.*@-Wno-deprecated-non-prototype"
write_bazelrc "build --host_per_file_copt=external/.*@-Wno-deprecated-non-prototype"
write_bazelrc "build --per_file_copt=external/com_google_protobuf/.*@-Wno-unused-function"
write_bazelrc "build --host_per_file_copt=external/com_google_protobuf/.*@-Wno-unused-function"

# qsim warnings
# The following supress warnings coming from qsim.
# TODO: fix the code in qsim & update TFQ to use the updated version.
write_to_bazelrc "build --per_file_copt=tensorflow_quantum/core/ops/noise/tfq_.*@-Wno-unused-but-set-variable"
write_to_bazelrc "build --host_per_file_copt=tensorflow_quantum/core/ops/noise/tfq_.*@-Wno-unused-but-set-variable"
write_to_bazelrc "build --per_file_copt=tensorflow_quantum/core/ops/math_ops/tfq_.*@-Wno-deprecated-declarations"
write_to_bazelrc "build --host_per_file_copt=tensorflow_quantum/core/ops/math_ops/tfq_.*@-Wno-deprecated-declarations"
write_bazelrc "build --per_file_copt=tensorflow_quantum/core/ops/noise/tfq_.*@-Wno-unused-but-set-variable"
write_bazelrc "build --host_per_file_copt=tensorflow_quantum/core/ops/noise/tfq_.*@-Wno-unused-but-set-variable"
write_bazelrc "build --per_file_copt=tensorflow_quantum/core/ops/math_ops/tfq_.*@-Wno-deprecated-declarations"
write_bazelrc "build --host_per_file_copt=tensorflow_quantum/core/ops/math_ops/tfq_.*@-Wno-deprecated-declarations"


if is_windows; then
# Use pywrap_tensorflow instead of tensorflow_framework on Windows
SHARED_LIBRARY_DIR=${TF_CFLAGS:2:-7}"python"
else
SHARED_LIBRARY_DIR=${TF_LFLAGS:2}
fi
SHARED_LIBRARY_NAME=$(echo $TF_LFLAGS | rev | cut -d":" -f1 | rev)
if ! [[ $TF_LFLAGS =~ .*:.* ]]; then
if is_macos; then
SHARED_LIBRARY_NAME="libtensorflow_framework.dylib"
elif is_windows; then
# Use pywrap_tensorflow's import library on Windows. It is in the same dir as the dll/pyd.
SHARED_LIBRARY_NAME="_pywrap_tensorflow_internal.lib"
else
SHARED_LIBRARY_NAME="libtensorflow_framework.so"
fi
fi

HEADER_DIR=${TF_CFLAGS:2}
if is_windows; then
SHARED_LIBRARY_DIR=${SHARED_LIBRARY_DIR//\\//}
SHARED_LIBRARY_NAME=${SHARED_LIBRARY_NAME//\\//}
HEADER_DIR=${HEADER_DIR//\\//}
fi
write_action_env_to_bazelrc "TF_HEADER_DIR" ${HEADER_DIR}
write_action_env_to_bazelrc "TF_SHARED_LIBRARY_DIR" ${SHARED_LIBRARY_DIR}
write_action_env_to_bazelrc "TF_SHARED_LIBRARY_NAME" ${SHARED_LIBRARY_NAME}
write_action_env_to_bazelrc "TF_NEED_CUDA" ${TF_NEED_CUDA}

# rpath so the dynamic linker finds TF’s shared lib
if ! is_windows; then
write_linkopt_dir_to_bazelrc ${SHARED_LIBRARY_DIR}
write_bazelrc "build --linkopt=-Wl,-rpath,${LIBDIR}"
fi

# TODO(yifeif): do not hardcode path
# CUDA toggle
if [[ "$TF_NEED_CUDA" == "1" ]]; then
write_to_bazelrc "build:cuda --define=using_cuda=true --define=using_cuda_nvcc=true"
write_to_bazelrc "build:cuda --@local_config_cuda//:enable_cuda"
write_to_bazelrc "build:cuda --crosstool_top=@local_config_cuda//crosstool:toolchain"

write_action_env_to_bazelrc "TF_CUDA_VERSION" ${TF_CUDA_VERSION}
write_action_env_to_bazelrc "TF_CUDNN_VERSION" "8"
write_bazelrc "build:cuda --define=using_cuda=true --define=using_cuda_nvcc=true"
write_bazelrc "build:cuda --@local_config_cuda//:enable_cuda"
write_bazelrc "build:cuda --crosstool_top=@local_config_cuda//crosstool:toolchain"
if is_windows; then
write_action_env_to_bazelrc "CUDNN_INSTALL_PATH" "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v${TF_CUDA_VERSION}"
write_action_env_to_bazelrc "CUDA_TOOLKIT_PATH" "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v${TF_CUDA_VERSION}"
write_tf_rc "build --repo_env=CUDNN_INSTALL_PATH=C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v${TF_CUDA_VERSION}"
write_tf_rc "build --repo_env=CUDA_TOOLKIT_PATH=C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v${TF_CUDA_VERSION}"
else
write_action_env_to_bazelrc "CUDNN_INSTALL_PATH" "/usr/lib/x86_64-linux-gnu"
write_action_env_to_bazelrc "CUDA_TOOLKIT_PATH" "/usr/local/cuda"
write_tf_rc "build --repo_env=CUDNN_INSTALL_PATH=/usr/lib/x86_64-linux-gnu"
write_tf_rc "build --repo_env=CUDA_TOOLKIT_PATH=/usr/local/cuda"
fi
write_to_bazelrc "build --config=cuda"
write_to_bazelrc "test --config=cuda"
write_bazelrc "build --config=cuda"
write_bazelrc "test --config=cuda"
fi

echo
echo "Wrote .tf_configure.bazelrc and .bazelrc successfully."
Loading
Loading