Skip to content

Commit 18673fc

Browse files
authored
Merge pull request #1 from wherobots/ryan/torch-2.12-support
build: lock torch 2.12 and cap <2.13
2 parents fa5c293 + 64c1d17 commit 18673fc

4 files changed

Lines changed: 332 additions & 1 deletion

File tree

‎.github/workflows/test.yml‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
name: test
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
workflow_dispatch:
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
- name: Install uv
15+
uses: astral-sh/setup-uv@v6
16+
with:
17+
python-version: "3.12"
18+
enable-cache: true
19+
- name: Run tests
20+
run: uv run --frozen pytest -q

‎pyproject.toml‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ authors = [
1313
]
1414
classifiers = [ "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.12" ]
1515
dependencies = [
16-
"torch>=2.8",
16+
"torch>=2.8,<2.13",
1717
]
1818

1919
[project.urls]
@@ -27,6 +27,15 @@ package-dir = {"" = "src"}
2727
where = ["src"]
2828
include = ["wherobots_export*"]
2929

30+
[dependency-groups]
31+
dev = [
32+
"numpy",
33+
"pytest>=8",
34+
]
35+
3036
[[tool.uv.index]]
3137
name = "pytorch-cpu"
3238
url = "https://download.pytorch.org/whl/cpu"
39+
40+
[tool.uv.sources]
41+
torch = { index = "pytorch-cpu" }

‎tests/test_export.py‎

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from pathlib import Path
2+
3+
import pytest
4+
import torch
5+
from torch.export.pt2_archive._package import load_pt2
6+
7+
from wherobots_export.torch.export import create_example_input_from_shape, save
8+
9+
10+
class TinyModel(torch.nn.Module):
11+
def __init__(self) -> None:
12+
super().__init__()
13+
self.conv = torch.nn.Conv2d(3, 4, kernel_size=3, padding=1)
14+
15+
def forward(self, pixels: torch.Tensor) -> torch.Tensor:
16+
return self.conv(pixels).mean(dim=(2, 3))
17+
18+
19+
class Normalize(torch.nn.Module):
20+
def forward(self, pixels: torch.Tensor) -> torch.Tensor:
21+
return (pixels - 0.5) / 0.5
22+
23+
24+
def test_save_creates_nonempty_pt2(tmp_path: Path) -> None:
25+
output_file = tmp_path / "model.pt2"
26+
save(model=TinyModel(), output_file=output_file, input_shape=[1, 3, 32, 32], device="cpu")
27+
assert output_file.exists()
28+
assert output_file.stat().st_size > 0
29+
30+
31+
def test_save_dynamic_batch_roundtrip(tmp_path: Path) -> None:
32+
model = TinyModel().eval()
33+
output_file = tmp_path / "model.pt2"
34+
save(model=model, output_file=output_file, input_shape=[-1, 3, 32, 32], device="cpu")
35+
36+
contents = load_pt2(str(output_file))
37+
assert set(contents.exported_programs) == {"model"}
38+
39+
exported = contents.exported_programs["model"].module()
40+
pixels = torch.randn(4, 3, 32, 32) # batch differs from the export-time example
41+
torch.testing.assert_close(exported(pixels), model(pixels))
42+
43+
44+
def test_save_with_transforms_packages_both(tmp_path: Path) -> None:
45+
output_file = tmp_path / "model.pt2"
46+
save(
47+
model=TinyModel(),
48+
output_file=output_file,
49+
input_shape=[-1, 3, 32, 32],
50+
device="cpu",
51+
transforms=Normalize(),
52+
)
53+
contents = load_pt2(str(output_file))
54+
assert set(contents.exported_programs) == {"model", "transforms"}
55+
56+
57+
def test_create_example_input_rejects_all_dynamic() -> None:
58+
with pytest.raises(ValueError):
59+
create_example_input_from_shape([-1, -1, -1, -1])
60+
61+
62+
def test_create_example_input_fills_dynamic_dims() -> None:
63+
example = create_example_input_from_shape([-1, 3, -1, -1], shape_default_value=64)
64+
assert example.shape == (2, 3, 64, 64)

‎uv.lock‎

Lines changed: 238 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)