Skip to content

Commit 0cf9206

Browse files
physicsrobclaude
andcommitted
annotate(): dedup path components so sibling-call nesting doesn't double
Sibling functions within one subsystem call each other, each re-pushing its label onto the annotate ContextVar, which accumulated a/b/a/b paths (measured: 48% of the doom render graph carried a repeated component). annotate now appends only components not already active: distinct labels still nest (proj/paint) while dups collapse (paint/paint -> paint; pmrk/R_CheckPlane/pmrk/R_CheckPlane -> pmrk/R_CheckPlane). Graph topology is unaffected (annotation is metadata only). New tests/graph/test_annotate.py covers it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 5f92898 commit 0cf9206

2 files changed

Lines changed: 90 additions & 2 deletions

File tree

tests/graph/test_annotate.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"""``annotate`` / ``annotated`` — hierarchical provenance labels with dedup.
2+
3+
The dedup behavior matters in practice: sibling functions within one
4+
subsystem call each other, each re-pushing its label, which without dedup
5+
accumulates ``a/b/a/b`` paths. ``annotate`` collapses a component that is
6+
already active in the path while still nesting *distinct* labels.
7+
"""
8+
9+
from torchwright.graph import annotate, annotated
10+
from torchwright.graph import node as _node
11+
12+
13+
def _cur():
14+
return _node._current_annotation.get()
15+
16+
17+
def test_basic_nesting():
18+
assert _cur() is None
19+
with annotate("render"):
20+
assert _cur() == "render"
21+
with annotate("texture"):
22+
assert _cur() == "render/texture"
23+
assert _cur() == "render"
24+
assert _cur() is None
25+
26+
27+
def test_distinct_labels_still_nest():
28+
with annotate("proj"):
29+
with annotate("paint"):
30+
assert _cur() == "proj/paint"
31+
32+
33+
def test_dedup_consecutive_same_label():
34+
with annotate("paint"):
35+
with annotate("paint"):
36+
with annotate("paint"):
37+
assert _cur() == "paint"
38+
39+
40+
def test_dedup_compound_label():
41+
with annotate("pmrk/R_CheckPlane"):
42+
with annotate("pmrk/R_CheckPlane"):
43+
assert _cur() == "pmrk/R_CheckPlane"
44+
45+
46+
def test_dedup_interleaved_components():
47+
# the A/B/A/B shape produced by sibling functions calling each other
48+
with annotate("stor/R_StoreWallRange"):
49+
with annotate("pix/R_DrawColumn"):
50+
with annotate("pix/R_DrawColumn"):
51+
with annotate("tex"):
52+
assert _cur() == "stor/R_StoreWallRange/pix/R_DrawColumn/tex"
53+
54+
55+
def test_reset_on_exit_even_on_error():
56+
try:
57+
with annotate("x"):
58+
raise ValueError("boom")
59+
except ValueError:
60+
pass
61+
assert _cur() is None
62+
63+
64+
def test_annotated_decorator_dedup():
65+
@annotated("bsp")
66+
def outer():
67+
@annotated("bsp")
68+
def inner():
69+
return _cur()
70+
71+
return inner()
72+
73+
assert outer() == "bsp"
74+
assert _cur() is None

torchwright/graph/node.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,28 @@ def _verify_tensor_against_value_type(node: "Node", tensor: torch.Tensor) -> Non
4444
def annotate(label: str):
4545
"""Tag all nodes created inside this block with a hierarchical label.
4646
47-
Nesting builds a ``/``-separated path::
47+
Nesting builds a ``/``-separated path. A component already active in the
48+
path is NOT repeated — so sibling functions in one subsystem calling each
49+
other (a natural pattern) stay ``a/b`` instead of accumulating
50+
``a/b/a/b``::
4851
4952
with annotate("render"):
5053
with annotate("texture"):
5154
# nodes get annotation = "render/texture"
55+
with annotate("render"):
56+
# still "render" — re-entering an active scope is a no-op
57+
58+
``label`` may itself be a ``/``-separated path (e.g. ``"pmrk/R_CheckPlane"``);
59+
each component is deduped independently.
5260
"""
5361
current = _current_annotation.get()
54-
new = f"{current}/{label}" if current else label
62+
parts = current.split("/") if current else []
63+
seen = set(parts)
64+
for comp in label.split("/"):
65+
if comp and comp not in seen:
66+
parts.append(comp)
67+
seen.add(comp)
68+
new = "/".join(parts) if parts else current
5569
token = _current_annotation.set(new)
5670
try:
5771
yield

0 commit comments

Comments
 (0)