Skip to content

Commit ec90bea

Browse files
vam-googletensorflower-gardener
authored andcommitted
Migrate TensorFlow on newest Hermetic Python set of rules
This makes Tensorflow consistent with JAX and XLA PiperOrigin-RevId: 647832813
1 parent e851bbf commit ec90bea

File tree

12 files changed

+83
-428
lines changed

12 files changed

+83
-428
lines changed

.bazelignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,3 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
# ==============================================================================
15-
16-
# The requirements updater has its own WORKSPACE file
17-
ci/official/requirements_updater

BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
exports_files([
1+
exports_files(glob(["requirements*"]) + [
22
"configure",
33
"configure.py",
44
"ACKNOWLEDGEMENTS",

WORKSPACE

Lines changed: 27 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -7,88 +7,51 @@ workspace(name = "org_tensorflow")
77
# We must initialize hermetic python first.
88
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
99

10-
http_archive(
11-
name = "bazel_skylib",
12-
sha256 = "74d544d96f4a5bb630d465ca8bbcfe231e3594e5aae57e1edbf17a6eb3ca2506",
13-
urls = [
14-
"https://storage.googleapis.com/mirror.tensorflow.org/github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
15-
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.3.0/bazel-skylib-1.3.0.tar.gz",
16-
],
17-
)
18-
1910
http_archive(
2011
name = "rules_java",
2112
sha256 = "c73336802d0b4882e40770666ad055212df4ea62cfa6edf9cb0f9d29828a0934",
2213
url = "https://github.com/bazelbuild/rules_java/releases/download/5.3.5/rules_java-5.3.5.tar.gz",
2314
)
2415

25-
http_archive(
26-
name = "rules_python",
27-
sha256 = "9d04041ac92a0985e344235f5d946f71ac543f1b1565f2cdbc9a2aaee8adf55b",
28-
strip_prefix = "rules_python-0.26.0",
29-
url = "https://github.com/bazelbuild/rules_python/releases/download/0.26.0/rules_python-0.26.0.tar.gz",
30-
)
31-
32-
# buildifier: disable=same-origin-load
33-
load("@rules_python//python:repositories.bzl", "py_repositories")
16+
# Initialize the TensorFlow repository and all dependencies.
17+
#
18+
# The cascade of load() statements and tf_workspace?() calls works around the
19+
# restriction that load() statements need to be at the top of .bzl files.
20+
# E.g. we can not retrieve a new repository with http_archive and then load()
21+
# a macro from that repository in the same file.
22+
load("@//tensorflow:workspace3.bzl", "tf_workspace3")
3423

35-
py_repositories()
24+
tf_workspace3()
3625

37-
load("@rules_python//python:repositories.bzl", "python_register_toolchains") # buildifier: disable=same-origin-load
38-
load(
39-
"//tensorflow/tools/toolchains/python:python_repo.bzl",
40-
"python_repository",
41-
)
26+
# Initialize hermetic Python
27+
load("@local_xla//third_party/py:python_init_rules.bzl", "python_init_rules")
4228

43-
python_repository(name = "python_version_repo")
29+
python_init_rules()
4430

45-
load("@python_version_repo//:py_version.bzl", "TF_PYTHON_VERSION")
31+
load("@local_xla//third_party/py:python_init_repositories.bzl", "python_init_repositories")
4632

47-
python_register_toolchains(
48-
name = "python",
49-
ignore_root_user_error = True,
50-
python_version = TF_PYTHON_VERSION,
33+
python_init_repositories(
34+
default_python_version = "system",
35+
requirements = {
36+
"3.9": "//:requirements_lock_3_9.txt",
37+
"3.10": "//:requirements_lock_3_10.txt",
38+
"3.11": "//:requirements_lock_3_11.txt",
39+
"3.12": "//:requirements_lock_3_12.txt",
40+
},
5141
)
5242

53-
load("@python//:defs.bzl", "interpreter")
54-
load("@rules_python//python:pip.bzl", "package_annotation", "pip_parse")
43+
load("@local_xla//third_party/py:python_init_toolchains.bzl", "python_init_toolchains")
5544

56-
NUMPY_ANNOTATIONS = {
57-
"numpy": package_annotation(
58-
additive_build_content = """\
59-
filegroup(
60-
name = "includes",
61-
srcs = glob(["site-packages/numpy/core/include/**/*.h"]),
62-
)
63-
cc_library(
64-
name = "numpy_headers",
65-
hdrs = [":includes"],
66-
strip_include_prefix="site-packages/numpy/core/include/",
67-
)
68-
""",
69-
),
70-
}
71-
72-
pip_parse(
73-
name = "pypi",
74-
annotations = NUMPY_ANNOTATIONS,
75-
python_interpreter_target = interpreter,
76-
requirements = "//:requirements_lock_" + TF_PYTHON_VERSION.replace(".", "_") + ".txt",
77-
)
45+
python_init_toolchains()
7846

79-
load("@pypi//:requirements.bzl", "install_deps")
47+
load("@local_xla//third_party/py:python_init_pip.bzl", "python_init_pip")
8048

81-
install_deps()
49+
python_init_pip()
8250

83-
# Initialize the TensorFlow repository and all dependencies.
84-
#
85-
# The cascade of load() statements and tf_workspace?() calls works around the
86-
# restriction that load() statements need to be at the top of .bzl files.
87-
# E.g. we can not retrieve a new repository with http_archive and then load()
88-
# a macro from that repository in the same file.
89-
load("@//tensorflow:workspace3.bzl", "tf_workspace3")
51+
load("@pypi//:requirements.bzl", "install_deps")
9052

91-
tf_workspace3()
53+
install_deps()
54+
# End hermetic Python initialization
9255

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

ci/official/requirements_updater/.bazelversion

Lines changed: 0 additions & 1 deletion
This file was deleted.

ci/official/requirements_updater/BUILD.bazel

Lines changed: 8 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -13,80 +13,17 @@
1313
# limitations under the License.
1414
# ==============================================================================
1515

16-
load("@python//3.10:defs.bzl", compile_pip_requirements_3_10 = "compile_pip_requirements")
17-
load("@python//3.11:defs.bzl", compile_pip_requirements_3_11 = "compile_pip_requirements")
18-
load("@python//3.12:defs.bzl", compile_pip_requirements_3_12 = "compile_pip_requirements")
19-
load("@python//3.9:defs.bzl", compile_pip_requirements_3_9 = "compile_pip_requirements")
20-
load("@updater_config_repository//:updater_config_repository.bzl", "REQUIREMENTS_FILE_NAME")
16+
load("@python//:defs.bzl", "compile_pip_requirements")
17+
load("@python_version_repo//:py_version.bzl", "REQUIREMENTS")
2118

22-
compile_pip_requirements_3_9(
23-
name = "requirements_3_9",
24-
extra_args = ["--allow-unsafe"],
25-
requirements_in = REQUIREMENTS_FILE_NAME,
26-
requirements_txt = "requirements_lock_3_9.txt",
27-
)
28-
29-
compile_pip_requirements_3_10(
30-
name = "requirements_3_10",
31-
extra_args = ["--allow-unsafe"],
32-
requirements_in = REQUIREMENTS_FILE_NAME,
33-
requirements_txt = "requirements_lock_3_10.txt",
34-
)
35-
36-
compile_pip_requirements_3_11(
37-
name = "requirements_3_11",
38-
extra_args = ["--allow-unsafe"],
39-
requirements_in = REQUIREMENTS_FILE_NAME,
40-
requirements_txt = "requirements_lock_3_11.txt",
41-
)
42-
43-
compile_pip_requirements_3_12(
44-
name = "requirements_3_12",
45-
extra_args = ["--allow-unsafe"],
46-
requirements_in = REQUIREMENTS_FILE_NAME,
47-
requirements_txt = "requirements_lock_3_12.txt",
48-
)
49-
50-
compile_pip_requirements_3_9(
51-
name = "requirements_3_9_release",
52-
extra_args = [
53-
"--allow-unsafe",
54-
"-P keras-nightly",
55-
"-P tb-nightly",
56-
],
57-
requirements_in = "requirements.in",
58-
requirements_txt = "requirements_lock_3_9.txt",
59-
)
60-
61-
compile_pip_requirements_3_10(
62-
name = "requirements_3_10_release",
63-
extra_args = [
64-
"--allow-unsafe",
65-
"-P keras-nightly",
66-
"-P tb-nightly",
67-
],
68-
requirements_in = "requirements.in",
69-
requirements_txt = "requirements_lock_3_10.txt",
70-
)
71-
72-
compile_pip_requirements_3_11(
73-
name = "requirements_3_11_release",
74-
extra_args = [
75-
"--allow-unsafe",
76-
"-P keras-nightly",
77-
"-P tb-nightly",
78-
],
79-
requirements_in = "requirements.in",
80-
requirements_txt = "requirements_lock_3_11.txt",
81-
)
82-
83-
compile_pip_requirements_3_12(
84-
name = "requirements_3_12_release",
19+
compile_pip_requirements(
20+
name = "requirements",
8521
extra_args = [
8622
"--allow-unsafe",
87-
"-P keras-nightly",
88-
"-P tb-nightly",
23+
"--build-isolation",
24+
"--rebuild",
8925
],
26+
generate_hashes = True,
9027
requirements_in = "requirements.in",
91-
requirements_txt = "requirements_lock_3_12.txt",
28+
requirements_txt = REQUIREMENTS,
9229
)
Lines changed: 47 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,71 @@
1-
# Hermetic Python
1+
## Managing hermetic Python
22

3-
Hermetic Python allows not to rely on system-installed Python, and
4-
system-installed Python packages. \
5-
Instead, an independent Python toolchain is registered, ensuring the right
6-
dependencies are always used. \
7-
See https://github.com/bazelbuild/rules_python/ for more details.
3+
To make sure that TensorFlow's build is reproducible, behaves uniformly across
4+
supported platforms (Linux, Windows, MacOS) and is properly isolated from
5+
specifics of a local system, we rely on hermetic Python (see
6+
[rules_python](https://github.com/bazelbuild/rules_python)) for all build
7+
and test commands executed via Bazel. This means that your system Python
8+
installation will be ignored during the build and Python interpreter itself
9+
as well as all the Python dependencies will be managed by bazel directly.
810

9-
### Specifying the Python version
11+
### Specifying Python version
1012

11-
Note: Only a number of minor Python versions are supported at any given time.
13+
The hermetic Python version is controlled by `HERMETIC_PYTHON_VERSION`
14+
environment variable, which could be setin one of the following ways:
1215

13-
By default, the lowest supported version is used.
14-
15-
To set a different version, use the `TF_PYTHON_VERSION` environment variable,
16-
e.g.
17-
18-
```
19-
export TF_PYTHON_VERSION=3.11
2016
```
17+
# Either add an entry to your `.bazelrc` file
18+
build --repo_env=HERMETIC_PYTHON_VERSION=3.12
2119
22-
To specify the version via a Bazel command argument, use the following:
20+
# OR pass it directly to your specific build command
21+
bazel build <target> --repo_env=HERMETIC_PYTHON_VERSION=3.12
2322
23+
# OR set the environment variable globally in your shell:
24+
export HERMETIC_PYTHON_VERSION=3.12
2425
```
25-
--repo_env=TF_PYTHON_VERSION=3.11
26-
```
27-
28-
## Requirements updater
2926

30-
Requirements updater is a standalone tool, intended to simplify process of
31-
updating requirements for multiple minor versions of Python.
27+
You may run builds and tests against different versions of Python sequentially
28+
on the same machine by simply switching the value of `HERMETIC_PYTHON_VERSION`
29+
between the runs. All the python-agnostic parts of the build cache from the
30+
previous build will be preserved and reused for the subsequent builds.
3231

33-
It takes in a file with a set of dependencies, and produces a more detailed
34-
requirements file for each version, with hashes specified for each
35-
dependency required, as well as their sub-dependencies.
32+
### Specifying Python dependencies
3633

37-
### How to update/add requirements
34+
During bazel build all TensorFlow's Python dependencies are pinned to their
35+
specific versions. This is necessary to ensure reproducibility of the build.
36+
The pinned versions of the full transitive closure of TensorFlow's dependencies
37+
together with their corresponding hashes are specified in
38+
`requirements_lock_<python version>.txt` files (e.g.
39+
`requirements_lock_3_12.txt` for `Python 3.12`).
3840

39-
By default, the name of the base requirements file is `requirements.in`, but it
40-
can be set using the `REQUIREMENTS_FILE_NAME` variable. \
41-
For example:
41+
To update the lock files, make sure
42+
`ci/official/requirements_updater/requirements.in` contains the desired direct
43+
dependencies list and then execute the following command (which will call
44+
[pip-compile](https://pypi.org/project/pip-tools/) under the hood):
4245

4346
```
44-
export REQUIREMENTS_FILE_NAME=my_requirements.in
47+
bazel run //ci/official/requirements_updater:requirements.update --repo_env=HERMETIC_PYTHON_VERSION=3.12
4548
```
4649

47-
To specify the file via a Bazel command argument, use the following:
50+
where `3.12` is the `Python` version you wish to update.
51+
52+
Note, since it is still `pip` and `pip-compile` tools used under the hood, so
53+
most of the command line arguments and features supported by those tools will be
54+
acknowledged by the Bazel requirements updater command as well. For example, if
55+
you wish the updater to consider pre-release versions simply pass `--pre`
56+
argument to the bazel command:
4857

4958
```
50-
--repo_env=REQUIREMENTS_FILE_NAME=my_requirements.in
59+
bazel run //ci/official/requirements_updater:requirements.update --repo_env=HERMETIC_PYTHON_VERSION=3.12 -- --pre
5160
```
5261

53-
### How to run the updater
62+
If you need to upgrade all of the packages in requirements lock file, just pass
63+
the `--upgrade` parameter:
5464

5565
```
56-
bash updater.sh
66+
bazel run //ci/official/requirements_updater:requirements.update --repo_env=HERMETIC_PYTHON_VERSION=3.12 -- --upgrade
5767
```
5868

59-
## How to add a new Python version
60-
61-
Note: Updating the
62-
[rules-python](https://github.com/bazelbuild/rules_python/releases) version may
63-
be required before going through the steps below. This is due to the new Python
64-
versions becoming available through `rules-python`. \
65-
See
66-
[here](https://github.com/tensorflow/tensorflow/commit/f91457f258fdd78f693044a57efa63a38335d1de),
67-
and
68-
[here](https://github.com/tensorflow/tensorflow/commit/052445e04ce20fd747657e0198a1bcec2b6dff5b),
69-
for an example.
70-
71-
See
72-
[this commit](https://github.com/tensorflow/tensorflow/commit/5f7f05a80aac9b01325a78ec3fcff0dbedb1cc23)
73-
as a rough example of the steps below.
74-
75-
All the files referenced below are located in the same directory as this README,
76-
unless indicated otherwise.
77-
78-
1) Add the new version to the `VERSIONS` variable inside
79-
`tensorflow/tools/toolchains/python/python_repo.bzl`. \
80-
While this isn't necessary for running the updater, it is required for
81-
actually using the new version with Tensorflow.
82-
83-
2) In the `WORKSPACE` file, add the new version to the `python_versions`
84-
parameter of the `python_register_multi_toolchains` function.
85-
86-
3) In the `BUILD.bazel` file, add a load statement for the new version, e.g.
87-
88-
```
89-
load("@python//3.11:defs.bzl",
90-
compile_pip_requirements_3_11 = "compile_pip_requirements")
91-
```
92-
93-
Add a new entry for the loaded `compile_pip_requirements`, e.g.
94-
95-
```
96-
compile_pip_requirements_3_11(
97-
name = "requirements_3_11",
98-
extra_args = ["--allow-unsafe"],
99-
requirements_in = "requirements.in",
100-
requirements_txt = "requirements_lock_3_11.txt",
101-
)
102-
```
103-
104-
```
105-
compile_pip_requirements_3_11(
106-
name = "requirements_3_11_release",
107-
extra_args = [
108-
"--allow-unsafe",
109-
"-P keras-nightly",
110-
"-P tb-nightly",
111-
],
112-
requirements_in = "requirements.in",
113-
requirements_txt = "requirements_lock_3_11.txt",
114-
)
115-
```
116-
117-
4) Add the version to `SUPPORTED_VERSIONS` in `updater.sh`, and
118-
`release_updater.sh`
119-
120-
5) Run the `updater.sh` shell script. \
121-
If the base requirements file hasn't yet been updated to account for the new
122-
Python version, which will require different versions for at least some
123-
dependencies, it will need to be updated now, for the script to run
124-
successfully.
125-
126-
6) A new `requirements_lock_3_11.txt` file should appear under the root of the
127-
`tensorflow` directory.
69+
For the full set of supported parameters please check
70+
[pip-compile](https://pip-tools.readthedocs.io/en/latest/cli/pip-compile/)
71+
documentation

0 commit comments

Comments
 (0)