Skip to content

Commit 4633e9f

Browse files
authored
Pin the Linux clang12 image to a torchci-capable source
Summary: Use the published November 2 torch, torchvision and torchaudio source commits for the existing clang12 Linux image. This supplies the upstream schema-1.0 reporter without a PyTorch backport PR or changes to the macOS/shared source pin. The matched domain sources avoid the old torchvision release reinstalling an incompatible torch version. Other images retain their current sources. After domain installation, fail the image build if the installed torch differs from its source pin or cannot capture a schema-1.0 report environment. The pins live in the existing Docker context and change its global content hash; other Linux images can consequently need rebuilding. No test-report opt-in is enabled by this diff. Authored with AI assistance. Reviewed By: shoumikhin Differential Revision: D129953668 Pull Request resolved: #24876
1 parent 0015c76 commit 4633e9f

8 files changed

Lines changed: 155 additions & 2 deletions

File tree

‎.ci/docker/README.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,12 @@ It also uses the same directory structure as PyTorch.
2323
# Set CLANG version (see build.sh) and build image
2424
CLANG_VERSION=11 ./build.sh executorch-ubuntu-22.04-clang11 -t myimage:latest
2525
```
26+
27+
The clang12 Linux image uses the published November 2 torch, torchvision and
28+
torchaudio source commits in `ci_commit_pins/*-linux-clang12.txt`. The shared
29+
macOS pin and other images' sources are unchanged. The build checks the installed
30+
torch identity and schema-1.0 reporter after installing the domain libraries.
31+
32+
These pins participate in the existing global Linux image hash. A pin change
33+
can require other Linux images to rebuild, even though only clang12 reads it.
34+
Validate the rebuilt image before enabling test-report uploads.

‎.ci/docker/build.sh‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,20 @@ case "${IMAGE_NAME}" in
107107
esac
108108

109109
TORCH_VERSION=$(cat ci_commit_pins/pytorch.txt)
110+
TORCHVISION_VERSION=""
111+
TORCHAUDIO_VERSION=""
112+
TORCHCI_REPORTS=""
113+
if [[ "${IMAGE_NAME}" == "executorch-ubuntu-22.04-clang12" ]]; then
114+
for pin in TORCH_VERSION:pytorch TORCHVISION_VERSION:torchvision TORCHAUDIO_VERSION:torchaudio; do
115+
override=$(cat "ci_commit_pins/${pin#*:}-linux-clang12.txt")
116+
if [[ ! "${override}" =~ ^[0-9a-f]{40}$ ]]; then
117+
echo "Expected a 40-character source commit in ${pin#*:}-linux-clang12.txt" >&2
118+
exit 1
119+
fi
120+
printf -v "${pin%:*}" '%s' "${override}"
121+
done
122+
TORCHCI_REPORTS=1
123+
fi
110124
BUILD_DOCS=1
111125

112126
if [[ -n "${GCC_VERSION:-}" && -z "${SKIP_PYTORCH:-}" ]]; then
@@ -138,6 +152,9 @@ fi
138152
--build-arg "PYTHON_VERSION=${PYTHON_VERSION}" \
139153
--build-arg "MINICONDA_VERSION=${MINICONDA_VERSION}" \
140154
--build-arg "TORCH_VERSION=${TORCH_VERSION}" \
155+
--build-arg "TORCHVISION_VERSION=${TORCHVISION_VERSION}" \
156+
--build-arg "TORCHAUDIO_VERSION=${TORCHAUDIO_VERSION}" \
157+
--build-arg "TORCHCI_REPORTS=${TORCHCI_REPORTS}" \
141158
--build-arg "PYTORCH_BUILD_MAX_JOBS=${PYTORCH_BUILD_MAX_JOBS:-}" \
142159
--build-arg "BUCK2_VERSION=${BUCK2_VERSION}" \
143160
--build-arg "LINTRUNNER=${LINTRUNNER:-}" \
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
45a70b7c0d318efced057e4c1adb33b936c52523
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
075002d7807674ad76126950bc63622df21a1220
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
d54492675a23a630ab16c5fe20bfdf10de5b5807

‎.ci/docker/common/install_pytorch.sh‎

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,27 @@ torch.linalg.qr(torch.randn(4, 4))
9898
")
9999

100100
# Grab the pinned audio and vision commits from PyTorch
101-
TORCHAUDIO_VERSION=release/2.11
101+
TORCHAUDIO_VERSION=${TORCHAUDIO_VERSION:-release/2.11}
102102
export TORCHAUDIO_VERSION
103-
TORCHVISION_VERSION=release/0.29
103+
TORCHVISION_VERSION=${TORCHVISION_VERSION:-release/0.29}
104104
export TORCHVISION_VERSION
105105

106106
install_domains
107107

108+
if [[ "${TORCHCI_REPORTS:-}" == "1" ]]; then
109+
(cd / && conda_run python -c '
110+
import os
111+
import torch
112+
from torch.testing._internal.torchci import environment, plugin, report
113+
114+
if torch.version.git_version != os.environ["TORCH_VERSION"]:
115+
raise RuntimeError("Installed torch differs from the image source pin")
116+
if report.SCHEMA_VERSION != "1.0":
117+
raise RuntimeError("The image requires torchci report schema 1.0")
118+
environment.capture()
119+
')
120+
fi
121+
108122
popd || true
109123
# Clean up the cloned PyTorch repo to reduce the Docker image size
110124
rm -rf pytorch

‎.ci/docker/ubuntu/Dockerfile‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ ENV AWS_REGION us-east-1
6666
ENV AWS_DEFAULT_REGION us-east-1
6767

6868
ARG TORCH_VERSION
69+
ARG TORCHVISION_VERSION
70+
ARG TORCHAUDIO_VERSION
71+
ARG TORCHCI_REPORTS
6972
ARG SKIP_PYTORCH
7073
ARG PYTORCH_BUILD_MAX_JOBS
7174
COPY ./common/install_pytorch.sh install_pytorch.sh
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
import os
8+
import shutil
9+
import subprocess
10+
import tempfile
11+
import unittest
12+
from pathlib import Path
13+
14+
15+
ROOT = Path(__file__).resolve().parents[3]
16+
IMAGE = "executorch-ubuntu-22.04-clang12"
17+
PACKAGES = {
18+
"pytorch": "TORCH_VERSION",
19+
"torchvision": "TORCHVISION_VERSION",
20+
"torchaudio": "TORCHAUDIO_VERSION",
21+
}
22+
23+
24+
class TorchciImageOverrideTest(unittest.TestCase):
25+
def run_build(self, image=IMAGE, invalid=None):
26+
with tempfile.TemporaryDirectory() as tmp:
27+
fixture = Path(tmp)
28+
docker = fixture / ".ci/docker"
29+
pins = docker / "ci_commit_pins"
30+
pins.mkdir(parents=True)
31+
(pins / "pytorch.txt").write_text("shared-pin\n")
32+
(pins / "buck2.txt").write_text("buck-pin\n")
33+
for package in PACKAGES:
34+
source = (
35+
ROOT / ".ci/docker/ci_commit_pins" / f"{package}-linux-clang12.txt"
36+
)
37+
value = invalid if invalid is not None else source.read_text()
38+
(pins / source.name).write_text(value)
39+
(fixture / "requirements-lintrunner.txt").write_text("")
40+
arm = fixture / "backends/arm/scripts"
41+
arm.mkdir(parents=True)
42+
for name in ("utils", "fvp_utils", "toolchain_utils"):
43+
(arm / f"{name}.sh").write_text("")
44+
shutil.copyfile(ROOT / ".ci/docker/build.sh", docker / "build.sh")
45+
binary = fixture / "bin"
46+
binary.mkdir()
47+
mock = binary / "docker"
48+
mock.write_text('#!/bin/sh\nprintf "%s\\n" "$@"\n')
49+
mock.chmod(0o755)
50+
return subprocess.run(
51+
["bash", "build.sh", image],
52+
cwd=docker,
53+
env={
54+
**os.environ,
55+
"PATH": f"{binary}:{os.environ['PATH']}",
56+
"REMOTE_BUILDKIT": "",
57+
},
58+
text=True,
59+
capture_output=True,
60+
)
61+
62+
def test_clang_image_uses_all_published_pins(self):
63+
result = self.run_build()
64+
self.assertEqual(result.returncode, 0, result.stderr)
65+
for package, variable in PACKAGES.items():
66+
pin = (
67+
(ROOT / ".ci/docker/ci_commit_pins" / f"{package}-linux-clang12.txt")
68+
.read_text()
69+
.strip()
70+
)
71+
self.assertRegex(pin, r"^[0-9a-f]{40}$")
72+
self.assertIn(f"{variable}={pin}", result.stdout.splitlines())
73+
self.assertIn("TORCHCI_REPORTS=1", result.stdout.splitlines())
74+
75+
def test_other_images_keep_the_shared_pin(self):
76+
result = self.run_build("executorch-ubuntu-22.04-gcc11", invalid="invalid")
77+
self.assertEqual(result.returncode, 0, result.stderr)
78+
for value in (
79+
"TORCH_VERSION=shared-pin",
80+
"TORCHVISION_VERSION=",
81+
"TORCHAUDIO_VERSION=",
82+
"TORCHCI_REPORTS=",
83+
):
84+
self.assertIn(value, result.stdout.splitlines())
85+
86+
def test_missing_or_mutable_pin_stops_before_docker(self):
87+
for pin in ("", "main", "a" * 39, "A" * 40):
88+
with self.subTest(pin=pin):
89+
result = self.run_build(invalid=pin)
90+
self.assertNotEqual(result.returncode, 0)
91+
self.assertNotIn("--no-cache", result.stdout.splitlines())
92+
93+
def test_docker_forwards_the_domain_pins_and_checks_installed_torch(self):
94+
dockerfile = (ROOT / ".ci/docker/ubuntu/Dockerfile").read_text()
95+
script = (ROOT / ".ci/docker/common/install_pytorch.sh").read_text()
96+
for variable in (*PACKAGES.values(), "TORCHCI_REPORTS"):
97+
self.assertIn(f"ARG {variable}\n", dockerfile)
98+
self.assertIn("TORCHAUDIO_VERSION=${TORCHAUDIO_VERSION:-release/2.11}", script)
99+
self.assertIn(
100+
"TORCHVISION_VERSION=${TORCHVISION_VERSION:-release/0.29}", script
101+
)
102+
self.assertLess(
103+
script.index(" install_domains\n"),
104+
script.index("if torch.version.git_version"),
105+
)
106+
self.assertIn('report.SCHEMA_VERSION != "1.0"', script)
107+
self.assertIn("environment.capture()", script)

0 commit comments

Comments
 (0)