Skip to content

Commit b1e9dfc

Browse files
0.22 Cherry-picks (#8983)
Co-authored-by: Zain Rizvi <ZainRizvi@users.noreply.github.com>
1 parent 8dcfb1c commit b1e9dfc

File tree

13 files changed

+187
-54
lines changed

13 files changed

+187
-54
lines changed

.github/scripts/setup-env.sh

+7-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,13 @@ echo '::endgroup::'
100100

101101
echo '::group::Install torchvision-extra-decoders'
102102
# This can be done after torchvision was built
103-
pip install torchvision-extra-decoders
103+
if [[ "$(uname)" == "Linux" && "$(uname -m)" != "aarch64" ]]; then
104+
extra_decoders_channel="--pre --index-url https://download.pytorch.org/whl/nightly/cpu"
105+
else
106+
extra_decoders_channel=""
107+
fi
108+
109+
pip install torchvision-extra-decoders $extra_decoders_channel
104110
echo '::endgroup::'
105111

106112
echo '::group::Collect environment information'

.github/scripts/unittest.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ echo '::endgroup::'
1515
python test/smoke_test.py
1616

1717
# We explicitly ignore the video tests until we resolve https://github.com/pytorch/vision/issues/8162
18-
pytest --ignore-glob="*test_video*" --junit-xml="${RUNNER_TEST_RESULTS_DIR}/test-results.xml" -v --durations=25
18+
pytest --ignore-glob="*test_video*" --ignore-glob="*test_onnx*" --junit-xml="${RUNNER_TEST_RESULTS_DIR}/test-results.xml" -v --durations=25 -k "not TestFxFeatureExtraction"

.github/workflows/tests.yml

+40-39
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ jobs:
5252
python-version:
5353
- "3.9"
5454
- "3.10"
55-
- "3.11"
55+
# TODO put back 3.11 (See blame)
56+
# - "3.11"
5657
- "3.12"
5758
runner: ["macos-m1-stable"]
5859
fail-fast: false
@@ -81,11 +82,12 @@ jobs:
8182
- "3.12"
8283
runner: ["windows.4xlarge"]
8384
gpu-arch-type: ["cpu"]
84-
include:
85-
- python-version: "3.9"
86-
runner: windows.g5.4xlarge.nvidia.gpu
87-
gpu-arch-type: cuda
88-
gpu-arch-version: "11.8"
85+
# TODO: put GPU testing back
86+
# include:
87+
# - python-version: "3.9"
88+
# runner: windows.g5.4xlarge.nvidia.gpu
89+
# gpu-arch-type: cuda
90+
# gpu-arch-version: "11.8"
8991
fail-fast: false
9092
uses: pytorch/test-infra/.github/workflows/windows_job.yml@release/2.7
9193
permissions:
@@ -109,39 +111,38 @@ jobs:
109111
110112
./.github/scripts/unittest.sh
111113
112-
onnx:
113-
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@release/2.7
114-
permissions:
115-
id-token: write
116-
contents: read
117-
with:
118-
repository: pytorch/vision
119-
test-infra-ref: release/2.7
120-
script: |
121-
set -euo pipefail
122-
123-
export PYTHON_VERSION=3.10
124-
export GPU_ARCH_TYPE=cpu
125-
export GPU_ARCH_VERSION=''
126-
127-
./.github/scripts/setup-env.sh
128-
129-
# Prepare conda
130-
CONDA_PATH=$(which conda)
131-
eval "$(${CONDA_PATH} shell.bash hook)"
132-
conda activate ci
133-
134-
echo '::group::Install ONNX'
135-
pip install --progress-bar=off onnx onnxruntime
136-
echo '::endgroup::'
137-
138-
echo '::group::Install testing utilities'
139-
pip install --progress-bar=off pytest "numpy<2"
140-
echo '::endgroup::'
141-
142-
echo '::group::Run ONNX tests'
143-
pytest --junit-xml="${RUNNER_TEST_RESULTS_DIR}/test-results.xml" -v --durations=25 test/test_onnx.py
144-
echo '::endgroup::'
114+
# onnx:
115+
# uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@release/2.7
116+
# permissions:
117+
# id-token: write
118+
# contents: read
119+
# with:
120+
# repository: pytorch/vision
121+
# test-infra-ref: release/2.7
122+
# script: |
123+
# set -euo pipefail
124+
# export PYTHON_VERSION=3.10
125+
# export GPU_ARCH_TYPE=cpu
126+
# export GPU_ARCH_VERSION=''
127+
128+
# ./.github/scripts/setup-env.sh
129+
130+
# # Prepare conda
131+
# CONDA_PATH=$(which conda)
132+
# eval "$(${CONDA_PATH} shell.bash hook)"
133+
# conda activate ci
134+
135+
# echo '::group::Install ONNX'
136+
# pip install --progress-bar=off onnx onnxruntime
137+
# echo '::endgroup::'
138+
139+
# echo '::group::Install testing utilities'
140+
# pip install --progress-bar=off pytest "numpy<2"
141+
# echo '::endgroup::'
142+
143+
# echo '::group::Run ONNX tests'
144+
# pytest --junit-xml="${RUNNER_TEST_RESULTS_DIR}/test-results.xml" -v --durations=25 test/test_onnx.py
145+
# echo '::endgroup::'
145146

146147
unittests-extended:
147148
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@release/2.7

packaging/post_build_script.sh

+14-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
#!/bin/bash
2-
LD_LIBRARY_PATH="/usr/local/lib:$CUDA_HOME/lib64:$LD_LIBRARY_PATH" python packaging/wheel/relocate.py
2+
set -euxo pipefail
33

4-
pip install torchvision-extra-decoders
4+
if [ -n "${CUDA_HOME:-}" ]; then
5+
LD_LIBRARY_PATH="/usr/local/lib:${CUDA_HOME}/lib64:${LD_LIBRARY_PATH}"
6+
fi
7+
8+
python packaging/wheel/relocate.py
9+
10+
if [[ "$(uname)" == "Linux" && "$(uname -m)" != "aarch64" ]]; then
11+
extra_decoders_channel="--pre --index-url https://download.pytorch.org/whl/nightly/cpu"
12+
else
13+
extra_decoders_channel=""
14+
fi
15+
16+
pip install torchvision-extra-decoders $extra_decoders_channel

packaging/pre_build_script.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ else
3636
conda install libwebp -y
3737
conda install libjpeg-turbo -c pytorch
3838
yum install -y freetype gnutls
39-
pip install auditwheel
39+
pip install "auditwheel<6.3.0"
4040
fi
4141

4242
pip install numpy pyyaml future ninja

packaging/wheel/relocate.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515

1616
# Third party imports
1717
if sys.platform == "linux":
18-
from auditwheel.lddtree import lddtree
18+
try:
19+
from auditwheel.lddtree import lddtree
20+
except ImportError:
21+
from auditwheel import lddtree
1922

2023

2124
ALLOWLIST = {

release/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Vision Release Scripts
2+
3+
This folder contains script(s) used for releasing new versions of the Vision package

release/apply-release-changes.py

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#!/usr/bin/env python3
2+
"""
3+
apply-release-changes.py - Cross-platform script to replace main with a specified release version in YML files
4+
5+
This script performs two replacements in YML files in .github/workflows/:
6+
1. Replaces @main with @release/VERSION
7+
2. Replaces 'test-infra-ref: main' with 'test-infra-ref: release/VERSION'
8+
9+
Usage:
10+
python apply-release-changes.py VERSION
11+
12+
Example:
13+
python apply-release-changes.py 2.7
14+
"""
15+
16+
import os
17+
import pathlib
18+
import sys
19+
from typing import Optional
20+
21+
22+
def replace_in_file(file_path: pathlib.Path, old_text: str, new_text: str) -> None:
23+
"""Replace all occurrences of old_text with new_text in the specified file."""
24+
try:
25+
# Try reading the file without specifying encoding to use the default
26+
encoding = None
27+
try:
28+
content = file_path.read_text()
29+
except UnicodeDecodeError:
30+
# If that fails, try with UTF-8
31+
encoding = "utf-8"
32+
content = file_path.read_text(encoding=encoding)
33+
34+
# Perform the replacement
35+
new_content = content.replace(old_text, new_text)
36+
37+
# Only write if changes were made
38+
if new_content != content:
39+
# Write with the same encoding we used to read
40+
if encoding:
41+
file_path.write_text(new_content, encoding=encoding)
42+
else:
43+
file_path.write_text(new_content)
44+
print(f"Updated: {file_path}")
45+
46+
except Exception as e:
47+
print(f"Error processing {file_path}: {e}")
48+
49+
50+
def find_repo_root() -> Optional[pathlib.Path]:
51+
"""Find the git repository root by searching for .git directory."""
52+
# Start from the current directory and traverse upwards
53+
current_path = pathlib.Path.cwd().absolute()
54+
55+
while current_path != current_path.parent:
56+
# Check if .git directory exists
57+
git_dir = current_path / ".git"
58+
if git_dir.exists() and git_dir.is_dir():
59+
return current_path
60+
61+
# Move up one directory
62+
current_path = current_path.parent
63+
64+
# If we get here, we didn't find a repository root
65+
return None
66+
67+
68+
def main() -> None:
69+
# Check if version is provided as command line argument
70+
if len(sys.argv) != 2:
71+
print("Error: Exactly one version parameter is required")
72+
print(f"Usage: python {os.path.basename(__file__)} VERSION")
73+
print("Example: python apply-release-changes.py 2.7")
74+
sys.exit(1)
75+
76+
# Get version from command line argument
77+
version = sys.argv[1]
78+
print(f"Using release version: {version}")
79+
80+
# Find the repository root by searching for .git directory
81+
repo_root = find_repo_root()
82+
if not repo_root:
83+
print("Error: Not inside a git repository. Please run from within a git repository.")
84+
sys.exit(1)
85+
86+
print(f"Repository root found at: {repo_root}")
87+
88+
# Get path to workflow directory
89+
workflow_dir = repo_root / ".github" / "workflows"
90+
91+
# Process all workflow files and perform both replacements on each file
92+
for yml_file in workflow_dir.glob("*.yml"):
93+
replace_in_file(yml_file, "@main", f"@release/{version}")
94+
replace_in_file(yml_file, "test-infra-ref: main", f"test-infra-ref: release/{version}")
95+
96+
97+
if __name__ == "__main__":
98+
print("Starting YML updates...")
99+
main()
100+
print("YML updates completed.")

test/test_image.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -897,12 +897,16 @@ def test_decode_gif(tmpdir, name, scripted):
897897
(decode_gif, re.escape("DGifOpenFileName() failed - 103")),
898898
(decode_webp, "WebPGetFeatures failed."),
899899
pytest.param(
900-
decode_avif, "BMFF parsing failed", marks=pytest.mark.skipif(not IS_LINUX, reason=HEIC_AVIF_MESSAGE)
900+
decode_avif,
901+
"BMFF parsing failed",
902+
# marks=pytest.mark.skipif(not IS_LINUX, reason=HEIC_AVIF_MESSAGE)
903+
marks=pytest.mark.skipif(True, reason="Skipping avif/heic tests for now."),
901904
),
902905
pytest.param(
903906
decode_heic,
904907
"Invalid input: No 'ftyp' box",
905-
marks=pytest.mark.skipif(not IS_LINUX, reason=HEIC_AVIF_MESSAGE),
908+
# marks=pytest.mark.skipif(not IS_LINUX, reason=HEIC_AVIF_MESSAGE),
909+
marks=pytest.mark.skipif(True, reason="Skipping avif/heic tests for now."),
906910
),
907911
],
908912
)
@@ -961,7 +965,8 @@ def test_decode_webp_against_pil(decode_fun, scripted, mode, pil_mode, filename)
961965
img += 123 # make sure image buffer wasn't freed by underlying decoding lib
962966

963967

964-
@pytest.mark.skipif(not IS_LINUX, reason=HEIC_AVIF_MESSAGE)
968+
# @pytest.mark.skipif(not IS_LINUX, reason=HEIC_AVIF_MESSAGE)
969+
@pytest.mark.skipif(True, reason="Skipping avif/heic tests for now.")
965970
@pytest.mark.parametrize("decode_fun", (decode_avif,))
966971
def test_decode_avif(decode_fun):
967972
encoded_bytes = read_file(next(get_images(FAKEDATA_DIR, ".avif")))
@@ -973,7 +978,8 @@ def test_decode_avif(decode_fun):
973978

974979
# Note: decode_image fails because some of these files have a (valid) signature
975980
# we don't recognize. We should probably use libmagic....
976-
@pytest.mark.skipif(not IS_LINUX, reason=HEIC_AVIF_MESSAGE)
981+
# @pytest.mark.skipif(not IS_LINUX, reason=HEIC_AVIF_MESSAGE)
982+
@pytest.mark.skipif(True, reason="Skipping avif/heic tests for now.")
977983
@pytest.mark.parametrize("decode_fun", (decode_avif, decode_heic))
978984
@pytest.mark.parametrize(
979985
"mode, pil_mode",
@@ -1050,7 +1056,8 @@ def test_decode_avif_heic_against_pil(decode_fun, mode, pil_mode, filename):
10501056
torch.testing.assert_close(img, from_pil, rtol=0, atol=3)
10511057

10521058

1053-
@pytest.mark.skipif(not IS_LINUX, reason=HEIC_AVIF_MESSAGE)
1059+
# @pytest.mark.skipif(not IS_LINUX, reason=HEIC_AVIF_MESSAGE)
1060+
@pytest.mark.skipif(True, reason="Skipping avif/heic tests for now.")
10541061
@pytest.mark.parametrize("decode_fun", (decode_heic,))
10551062
def test_decode_heic(decode_fun):
10561063
encoded_bytes = read_file(next(get_images(FAKEDATA_DIR, ".heic")))

torchvision/models/optical_flow/raft.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ def forward(self, image1, image2, num_flow_updates: int = 12):
486486
batch_size, _, h, w = image1.shape
487487
if (h, w) != image2.shape[-2:]:
488488
raise ValueError(f"input images should have the same shape, instead got ({h}, {w}) != {image2.shape[-2:]}")
489-
if not (h % 8 == 0) and (w % 8 == 0):
489+
if not ((h % 8 == 0) and (w % 8 == 0)):
490490
raise ValueError(f"input image H and W should be divisible by 8, instead got {h} (h) and {w} (w)")
491491

492492
fmaps = self.feature_encoder(torch.cat([image1, image2], dim=0))

torchvision/ops/boxes.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ def batched_nms(
7878
_log_api_usage_once(batched_nms)
7979
# Benchmarks that drove the following thresholds are at
8080
# https://github.com/pytorch/vision/issues/1311#issuecomment-781329339
81-
if boxes.numel() > (4000 if boxes.device.type == "cpu" else 20000) and not torchvision._is_tracing():
81+
# and https://github.com/pytorch/vision/pull/8925
82+
if boxes.numel() > (4000 if boxes.device.type == "cpu" else 100_000) and not torchvision._is_tracing():
8283
return _batched_nms_vanilla(boxes, scores, idxs, iou_threshold)
8384
else:
8485
return _batched_nms_coordinate_trick(boxes, scores, idxs, iou_threshold)

torchvision/transforms/v2/_color.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def _check_input(
134134
raise TypeError(f"{name}={value} should be a single number or a sequence with length 2.")
135135

136136
if not bound[0] <= value[0] <= value[1] <= bound[1]:
137-
raise ValueError(f"{name} values should be between {bound}, but got {value}.")
137+
raise ValueError(f"{name} values should be between {bound} and increasing, but got {value}.")
138138

139139
return None if value[0] == value[1] == center else (float(value[0]), float(value[1]))
140140

torchvision/transforms/v2/_geometry.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ class RandomRotation(Transform):
567567
Args:
568568
degrees (sequence or number): Range of degrees to select from.
569569
If degrees is a number instead of sequence like (min, max), the range of degrees
570-
will be (-degrees, +degrees).
570+
will be [-degrees, +degrees].
571571
interpolation (InterpolationMode, optional): Desired interpolation enum defined by
572572
:class:`torchvision.transforms.InterpolationMode`. Default is ``InterpolationMode.NEAREST``.
573573
If input is Tensor, only ``InterpolationMode.NEAREST``, ``InterpolationMode.BILINEAR`` are supported.

0 commit comments

Comments
 (0)