Skip to content

Commit 7fddc33

Browse files
authored
Merge branch 'main' into guangyey/accelerator3
2 parents 43a542e + d4c1e74 commit 7fddc33

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1485
-789
lines changed

.ci/docker/requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ tensorboard
2828
jinja2==3.1.3
2929
pytorch-lightning
3030
torchx
31-
torchrl==0.5.0
32-
tensordict==0.5.0
31+
torchrl==0.6.0
32+
tensordict==0.6.0
3333
ax-platform>=0.4.0
3434
nbformat>=5.9.2
3535
datasets

.github/workflows/build-tutorials.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ jobs:
4444
4545
- name: Checkout Tutorials
4646
uses: actions/checkout@v3
47+
with:
48+
fetch-depth: 0
4749

4850
- name: Setup Linux
4951
uses: pytorch/pytorch/.github/actions/setup-linux@main
@@ -115,6 +117,8 @@ jobs:
115117
116118
- name: Checkout Tutorials
117119
uses: actions/checkout@v3
120+
with:
121+
fetch-depth: 0
118122

119123
- name: Setup Linux
120124
uses: pytorch/pytorch/.github/actions/setup-linux@main

.jenkins/build.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ sudo apt-get install -y pandoc
2222
#Install PyTorch Nightly for test.
2323
# Nightly - pip install --pre torch torchvision torchaudio -f https://download.pytorch.org/whl/nightly/cu102/torch_nightly.html
2424
# Install 2.5 to merge all 2.4 PRs - uncomment to install nightly binaries (update the version as needed).
25-
# pip uninstall -y torch torchvision torchaudio torchtext torchdata
26-
# pip3 install torch==2.5.0 torchvision torchaudio --no-cache-dir --index-url https://download.pytorch.org/whl/test/cu124
25+
sudo pip uninstall -y torch torchvision torchaudio torchtext torchdata
26+
sudo pip3 install torch==2.6.0 torchvision --no-cache-dir --index-url https://download.pytorch.org/whl/test/cu124
27+
sudo pip uninstall -y fbgemm-gpu torchrec
28+
sudo pip3 install fbgemm-gpu==1.1.0 torchrec==1.0.0 --no-cache-dir --index-url https://download.pytorch.org/whl/test/cu124
2729

2830
# Install two language tokenizers for Translation with TorchText tutorial
2931
python -m spacy download en_core_web_sm

.jenkins/insert_last_verified.py

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import json
2+
import os
3+
import subprocess
4+
import sys
5+
from datetime import datetime
6+
7+
from bs4 import BeautifulSoup
8+
9+
10+
json_file_path = "tutorials-review-data.json"
11+
12+
# paths to skip from the post-processing script
13+
paths_to_skip = [
14+
"beginner/examples_autograd/two_layer_net_custom_function", # not present in the repo
15+
"beginner/examples_nn/two_layer_net_module", # not present in the repo
16+
"beginner/examples_tensor/two_layer_net_numpy", # not present in the repo
17+
"beginner/examples_tensor/two_layer_net_tensor", # not present in the repo
18+
"beginner/examples_autograd/two_layer_net_autograd", # not present in the repo
19+
"beginner/examples_nn/two_layer_net_optim", # not present in the repo
20+
"beginner/examples_nn/two_layer_net_nn", # not present in the repo
21+
"intermediate/coding_ddpg", # not present in the repo - will delete the carryover
22+
]
23+
# Mapping of source directories to build directories
24+
source_to_build_mapping = {
25+
"beginner": "beginner_source",
26+
"recipes": "recipes_source",
27+
"distributed": "distributed",
28+
"intermediate": "intermediate_source",
29+
"prototype": "prototype_source",
30+
"advanced": "advanced_source",
31+
"": "", # root dir for index.rst
32+
}
33+
34+
def get_git_log_date(file_path, git_log_args):
35+
try:
36+
result = subprocess.run(
37+
["git", "log"] + git_log_args + ["--", file_path],
38+
capture_output=True,
39+
text=True,
40+
check=True,
41+
)
42+
if result.stdout:
43+
date_str = result.stdout.splitlines()[0]
44+
return datetime.strptime(date_str, "%a, %d %b %Y %H:%M:%S %z")
45+
except subprocess.CalledProcessError:
46+
pass
47+
raise ValueError(f"Could not find date for {file_path}")
48+
49+
def get_creation_date(file_path):
50+
return get_git_log_date(file_path, ["--diff-filter=A", "--format=%aD"]).strftime("%b %d, %Y")
51+
52+
53+
def get_last_updated_date(file_path):
54+
return get_git_log_date(file_path, ["-1", "--format=%aD"]).strftime("%b %d, %Y")
55+
56+
# Try to find the source file with the given base path and the extensions .rst and .py
57+
def find_source_file(base_path):
58+
for ext in [".rst", ".py"]:
59+
source_file_path = base_path + ext
60+
if os.path.exists(source_file_path):
61+
return source_file_path
62+
return None
63+
64+
65+
# Function to process a JSON file and insert the "Last Verified" information into the HTML files
66+
def process_json_file(build_dir , json_file_path):
67+
with open(json_file_path, "r", encoding="utf-8") as json_file:
68+
json_data = json.load(json_file)
69+
70+
for entry in json_data:
71+
path = entry["Path"]
72+
last_verified = entry["Last Verified"]
73+
status = entry.get("Status", "")
74+
if path in paths_to_skip:
75+
print(f"Skipping path: {path}")
76+
continue
77+
if status in ["needs update", "not verified"]:
78+
formatted_last_verified = "Not Verified"
79+
elif last_verified:
80+
try:
81+
last_verified_date = datetime.strptime(last_verified, "%Y-%m-%d")
82+
formatted_last_verified = last_verified_date.strftime("%b %d, %Y")
83+
except ValueError:
84+
formatted_last_verified = "Unknown"
85+
else:
86+
formatted_last_verified = "Not Verified"
87+
if status == "deprecated":
88+
formatted_last_verified += "Deprecated"
89+
90+
for build_subdir, source_subdir in source_to_build_mapping.items():
91+
if path.startswith(build_subdir):
92+
html_file_path = os.path.join(build_dir, path + ".html")
93+
base_source_path = os.path.join(
94+
source_subdir, path[len(build_subdir) + 1 :]
95+
)
96+
source_file_path = find_source_file(base_source_path)
97+
break
98+
else:
99+
print(f"Warning: No mapping found for path {path}")
100+
continue
101+
102+
if not os.path.exists(html_file_path):
103+
print(
104+
f"Warning: HTML file not found for path {html_file_path}."
105+
"If this is a new tutorial, please add it to the audit JSON file and set the Verified status and todays's date."
106+
)
107+
continue
108+
109+
if not source_file_path:
110+
print(f"Warning: Source file not found for path {base_source_path}.")
111+
continue
112+
113+
created_on = get_creation_date(source_file_path)
114+
last_updated = get_last_updated_date(source_file_path)
115+
116+
with open(html_file_path, "r", encoding="utf-8") as file:
117+
soup = BeautifulSoup(file, "html.parser")
118+
# Check if the <p> tag with class "date-info-last-verified" already exists
119+
existing_date_info = soup.find("p", {"class": "date-info-last-verified"})
120+
if existing_date_info:
121+
print(
122+
f"Warning: <p> tag with class 'date-info-last-verified' already exists in {html_file_path}"
123+
)
124+
continue
125+
126+
h1_tag = soup.find("h1") # Find the h1 tag to insert the dates
127+
if h1_tag:
128+
date_info_tag = soup.new_tag("p", **{"class": "date-info-last-verified"})
129+
date_info_tag["style"] = "color: #6c6c6d; font-size: small;"
130+
# Add the "Created On", "Last Updated", and "Last Verified" information
131+
date_info_tag.string = (
132+
f"Created On: {created_on} | "
133+
f"Last Updated: {last_updated} | "
134+
f"Last Verified: {formatted_last_verified}"
135+
)
136+
# Insert the new tag after the <h1> tag
137+
h1_tag.insert_after(date_info_tag)
138+
# Save back to the HTML.
139+
with open(html_file_path, "w", encoding="utf-8") as file:
140+
file.write(str(soup))
141+
else:
142+
print(f"Warning: <h1> tag not found in {html_file_path}")
143+
144+
145+
def main():
146+
if len(sys.argv) < 2:
147+
print("Error: Build directory not provided. Exiting.")
148+
exit(1)
149+
build_dir = sys.argv[1]
150+
print(f"Build directory: {build_dir}")
151+
process_json_file(build_dir , json_file_path)
152+
print(
153+
"Finished processing JSON file. Please check the output for any warnings. "
154+
"Pages like `nlp/index.html` are generated only during the full `make docs` "
155+
"or `make html` build. Warnings about these files when you run `make html-noplot` "
156+
"can be ignored."
157+
)
158+
159+
if __name__ == "__main__":
160+
main()

.jenkins/validate_tutorials_built.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@
5151
"intermediate_source/flask_rest_api_tutorial",
5252
"intermediate_source/text_to_speech_with_torchaudio",
5353
"intermediate_source/tensorboard_profiler_tutorial", # reenable after 2.0 release.
54-
"intermediate_source/torch_export_tutorial" # reenable after 2940 is fixed.
54+
"intermediate_source/torch_export_tutorial", # reenable after 2940 is fixed.
55+
"advanced_source/pendulum",
56+
"beginner_source/onnx/export_simple_model_to_onnx_tutorial",
57+
"beginner_source/onnx/onnx_registry_tutorial"
5558
]
5659

5760
def tutorial_source_dirs() -> List[Path]:

.lycheeignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,9 @@ https://pytorch.org/tutorials/beginner/colab/n
1212

1313
# Ignore local host link from intermediate_source/tensorboard_tutorial.rst
1414
http://localhost:6006
15+
16+
# Ignore local host link from recipes_source/deployment_with_flask.rst
17+
http://localhost:5000/predict
18+
19+
# Ignore local host link from advanced_source/cpp_frontend.rst
20+
https://www.uber.com/blog/deep-neuroevolution/

CONTRIBUTING.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,8 @@ described in the preceding sections:
218218
- [NLP From Scratch: Generating Names with a Character-Level RNN
219219
Tutorial](https://pytorch.org/tutorials/intermediate/char_rnn_generation_tutorial.html)
220220

221-
If you are creating a recipe, we recommend that you use [this
222-
template](https://github.com/pytorch/tutorials/blob/tutorials_refresh/recipes_source/recipes/example_recipe.py)
223-
as a guide.
221+
If you are creating a recipe, [this is a good
222+
example.](https://github.com/pytorch/tutorials/blob/main/recipes_source/recipes/what_is_state_dict.py)
224223

225224

226225
# Submission Process #

Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,29 @@ download:
8686
wget https://www.cis.upenn.edu/~jshi/ped_html/PennFudanPed.zip -P $(DATADIR)
8787
unzip -o $(DATADIR)/PennFudanPed.zip -d intermediate_source/data/
8888

89+
download-last-reviewed-json:
90+
@echo "Downloading tutorials-review-data.json..."
91+
curl -o tutorials-review-data.json https://raw.githubusercontent.com/pytorch/tutorials/refs/heads/last-reviewed-data-json/tutorials-review-data.json
92+
@echo "Finished downloading tutorials-review-data.json."
8993
docs:
9094
make download
95+
make download-last-reviewed-json
9196
make html
97+
@python .jenkins/insert_last_verified.py $(BUILDDIR)/html
9298
rm -rf docs
9399
cp -r $(BUILDDIR)/html docs
94100
touch docs/.nojekyll
101+
rm -rf tutorials-review-data.json
95102

96103
html-noplot:
97104
$(SPHINXBUILD) -D plot_gallery=0 -b html $(SPHINXOPTS) "$(SOURCEDIR)" "$(BUILDDIR)/html"
98105
# bash .jenkins/remove_invisible_code_block_batch.sh "$(BUILDDIR)/html"
99106
@echo
107+
make download-last-reviewed-json
100108
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
109+
@echo "Running post-processing script to insert 'Last Verified' dates..."
110+
@python .jenkins/insert_last_verified.py $(BUILDDIR)/html
111+
rm -rf tutorials-review-data.json
101112

102113
clean-cache:
103114
make clean

advanced_source/cpp_autograd.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,9 @@ Out:
255255
[ CPUFloatType{3,4} ]
256256
257257
Please see the documentation for ``torch::autograd::backward``
258-
(`link <https://pytorch.org/cppdocs/api/function_namespacetorch_1_1autograd_1afa9b5d4329085df4b6b3d4b4be48914b.html>`_)
258+
(`link <https://pytorch.org/cppdocs/api/function_namespacetorch_1_1autograd_1a1403bf65b1f4f8c8506a9e6e5312d030.html>`_)
259259
and ``torch::autograd::grad``
260-
(`link <https://pytorch.org/cppdocs/api/function_namespacetorch_1_1autograd_1a1e03c42b14b40c306f9eb947ef842d9c.html>`_)
260+
(`link <https://pytorch.org/cppdocs/api/function_namespacetorch_1_1autograd_1ab9fa15dc09a8891c26525fb61d33401a.html>`_)
261261
for more information on how to use them.
262262

263263
Using custom autograd function in C++
@@ -394,9 +394,9 @@ C++ using the following table:
394394
+--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
395395
| Python | C++ |
396396
+================================+========================================================================================================================================================================+
397-
| ``torch.autograd.backward`` | ``torch::autograd::backward`` (`link <https://pytorch.org/cppdocs/api/function_namespacetorch_1_1autograd_1afa9b5d4329085df4b6b3d4b4be48914b.html>`_) |
397+
| ``torch.autograd.backward`` | ``torch::autograd::backward`` (`link <https://pytorch.org/cppdocs/api/function_namespacetorch_1_1autograd_1a1403bf65b1f4f8c8506a9e6e5312d030.html>`_) |
398398
+--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
399-
| ``torch.autograd.grad`` | ``torch::autograd::grad`` (`link <https://pytorch.org/cppdocs/api/function_namespacetorch_1_1autograd_1a1e03c42b14b40c306f9eb947ef842d9c.html>`_) |
399+
| ``torch.autograd.grad`` | ``torch::autograd::grad`` (`link <https://pytorch.org/cppdocs/api/function_namespacetorch_1_1autograd_1ab9fa15dc09a8891c26525fb61d33401a.html>`_) |
400400
+--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
401401
| ``torch.Tensor.detach`` | ``torch::Tensor::detach`` (`link <https://pytorch.org/cppdocs/api/classat_1_1_tensor.html#_CPPv4NK2at6Tensor6detachEv>`_) |
402402
+--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

advanced_source/cpp_custom_ops.rst

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ Custom C++ and CUDA Operators
1919
* PyTorch 2.4 or later
2020
* Basic understanding of C++ and CUDA programming
2121

22+
.. note::
23+
24+
This tutorial will also work on AMD ROCm with no additional modifications.
25+
2226
PyTorch offers a large library of operators that work on Tensors (e.g. torch.add, torch.sum, etc).
2327
However, you may wish to bring a new custom operator to PyTorch. This tutorial demonstrates the
2428
blessed path to authoring a custom operator written in C++/CUDA.
@@ -63,9 +67,47 @@ Using ``cpp_extension`` is as simple as writing the following ``setup.py``:
6367
6468
If you need to compile CUDA code (for example, ``.cu`` files), then instead use
6569
`torch.utils.cpp_extension.CUDAExtension <https://pytorch.org/docs/stable/cpp_extension.html#torch.utils.cpp_extension.CUDAExtension>`_.
66-
Please see how
67-
`extension-cpp <https://github.com/pytorch/extension-cpp>`_ for an example for
68-
how this is set up.
70+
Please see `extension-cpp <https://github.com/pytorch/extension-cpp>`_ for an
71+
example for how this is set up.
72+
73+
Starting with PyTorch 2.6, you can now build a single wheel for multiple CPython
74+
versions (similar to what you would do for pure python packages). In particular,
75+
if your custom library adheres to the `CPython Stable Limited API
76+
<https://docs.python.org/3/c-api/stable.html>`_ or avoids CPython entirely, you
77+
can build one Python agnostic wheel against a minimum supported CPython version
78+
through setuptools' ``py_limited_api`` flag, like so:
79+
80+
.. code-block:: python
81+
82+
from setuptools import setup, Extension
83+
from torch.utils import cpp_extension
84+
85+
setup(name="extension_cpp",
86+
ext_modules=[
87+
cpp_extension.CppExtension(
88+
"extension_cpp",
89+
["python_agnostic_code.cpp"],
90+
py_limited_api=True)],
91+
cmdclass={'build_ext': cpp_extension.BuildExtension},
92+
options={"bdist_wheel": {"py_limited_api": "cp39"}}
93+
)
94+
95+
Note that you must specify ``py_limited_api=True`` both within ``setup``
96+
and also as an option to the ``"bdist_wheel"`` command with the minimal supported
97+
Python version (in this case, 3.9). This ``setup`` would build one wheel that could
98+
be installed across multiple Python versions ``python>=3.9``. Please see
99+
`torchao <https://github.com/pytorch/ao>`_ for an example.
100+
101+
.. note::
102+
103+
You must verify independently that the built wheel is truly Python agnostic.
104+
Specifying ``py_limited_api`` does not check for any guarantees, so it is possible
105+
to build a wheel that looks Python agnostic but will crash, or worse, be silently
106+
incorrect, in another Python environment. Take care to avoid using unstable CPython
107+
APIs, for example APIs from libtorch_python (in particular pytorch/python bindings,)
108+
and to only use APIs from libtorch (aten objects, operators and the dispatcher).
109+
For example, to give access to custom ops from Python, the library should register
110+
the ops through the dispatcher (covered below!).
69111

70112
Defining the custom op and adding backend implementations
71113
---------------------------------------------------------
@@ -177,7 +219,7 @@ operator specifies how to compute the metadata of output tensors given the metad
177219
The FakeTensor kernel should return dummy Tensors of your choice with
178220
the correct Tensor metadata (shape/strides/``dtype``/device).
179221

180-
We recommend that this be done from Python via the `torch.library.register_fake` API,
222+
We recommend that this be done from Python via the ``torch.library.register_fake`` API,
181223
though it is possible to do this from C++ as well (see
182224
`The Custom Operators Manual <https://pytorch.org/docs/main/notes/custom_operators.html>`_
183225
for more details).
@@ -188,7 +230,9 @@ for more details).
188230
# before calling ``torch.library`` APIs that add registrations for the
189231
# C++ custom operator(s). The following import loads our
190232
# C++ custom operator definitions.
191-
# See the next section for more details.
233+
# Note that if you are striving for Python agnosticism, you should use
234+
# the ``load_library(...)`` API call instead. See the next section for
235+
# more details.
192236
from . import _C
193237
194238
@torch.library.register_fake("extension_cpp::mymuladd")
@@ -214,7 +258,10 @@ of two ways:
214258
1. If you're following this tutorial, importing the Python C extension module
215259
we created will load the C++ custom operator definitions.
216260
2. If your C++ custom operator is located in a shared library object, you can
217-
also use ``torch.ops.load_library("/path/to/library.so")`` to load it.
261+
also use ``torch.ops.load_library("/path/to/library.so")`` to load it. This
262+
is the blessed path for Python agnosticism, as you will not have a Python C
263+
extension module to import. See `torchao __init__.py <https://github.com/pytorch/ao/blob/881e84b4398eddcea6fee4d911fc329a38b5cd69/torchao/__init__.py#L26-L28>`_
264+
for an example.
218265

219266

220267
Adding training (autograd) support for an operator

0 commit comments

Comments
 (0)