Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e0eba26
do not replace unused output with none
beverlylytle Aug 4, 2025
4d5ea2c
atleast clone a
beverlylytle Aug 5, 2025
1fb4ff2
add shallow_copy grad and use it
beverlylytle Aug 5, 2025
365f2c2
update tests
beverlylytle Aug 5, 2025
53a3a70
Merge branch 'main' into remove_none_helper
beverlylytle Aug 5, 2025
66f513e
Merge branch 'main' into remove_none_helper
beverlylytle Aug 6, 2025
dcde92a
Merge branch 'main' into remove_none_helper
beverlylytle Aug 8, 2025
d175430
Merge branch 'main' into remove_none_helper
beverlylytle Aug 14, 2025
8e1f926
add shallow_copy to Symbol.__call__
beverlylytle Aug 15, 2025
f65bc76
Merge branch 'main' into remove_none_helper
beverlylytle Aug 15, 2025
ea22704
only copy proxies
beverlylytle Aug 15, 2025
240fbcd
remove no_passthrough test
beverlylytle Aug 15, 2025
47f88e0
fix liger notebook
beverlylytle Aug 15, 2025
22fb511
skip torch_type in vjp test
beverlylytle Aug 18, 2025
ac85db4
Merge branch 'main' into remove_none_helper
beverlylytle Aug 18, 2025
b71f4a5
fix memory tests and add shallow_copy torch_compile
beverlylytle Aug 18, 2025
9834955
update nvfuser test and add skip reason
beverlylytle Aug 18, 2025
fcbcb33
update nvfuser no_op test
beverlylytle Aug 19, 2025
09eaa90
Merge branch 'main' into remove_none_helper
beverlylytle Aug 19, 2025
cd9e0c3
Merge branch 'main' into remove_none_helper
beverlylytle Aug 20, 2025
292bff5
Merge branch 'main' into remove_none_helper
beverlylytle Aug 21, 2025
a3d02f7
Merge branch 'main' into remove_none_helper
beverlylytle Aug 22, 2025
86de8a7
Merge branch 'main' into remove_none_helper
beverlylytle Aug 22, 2025
66777fd
Merge branch 'main' into remove_none_helper
beverlylytle Aug 22, 2025
bede65a
Merge branch 'main' into remove_none_helper
beverlylytle Aug 22, 2025
345a9f7
Merge branch 'main' into remove_none_helper
t-vi Aug 22, 2025
aaa81b8
Merge branch 'main' into remove_none_helper
beverlylytle Aug 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions notebooks/liger_kernel.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@
},
{
"cell_type": "code",
"execution_count": 7,
"execution_count": null,
"id": "32cd98f0-a36f-4e01-8ae4-6e36adf2699b",
"metadata": {},
"outputs": [],
Expand Down Expand Up @@ -322,11 +322,12 @@
" while bound_symbols:\n",
" bsym = bound_symbols.pop(0)\n",
" if bsym.sym == litgpt_apply_rope:\n",
" for i, bsym2 in enumerate(bound_symbols):\n",
" while bound_symbols:\n",
Comment thread
beverlylytle marked this conversation as resolved.
" bsym2 = bound_symbols.pop(0)\n",
" assert not any(o is bsym.output for o in bsym2.flat_outs)\n",
" if bsym2.sym == litgpt_apply_rope:\n",
" break\n",
" bsym2 = bound_symbols.pop(i)\n",
" new_compute_trace.bound_symbols.append(bsym2.from_bsym())\n",
" assert bsym2.sym == litgpt_apply_rope\n",
"\n",
" output = (bsym.output, bsym2.output)\n",
Expand Down
25 changes: 17 additions & 8 deletions thunder/core/symbol.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,16 @@
from collections.abc import Sequence

import thunder.core.baseutils as baseutils
from thunder.core.baseutils import BoundSymbolInterface, TagBase
import thunder.core.codeutils as codeutils
from thunder.core.codeutils import Printable, Positions
from thunder.core.baseutils import BoundSymbolInterface, TagBase
from thunder.core.utils import FrozenDict, make_hashable
from thunder.core.pytree import tree_flatten_with_dataclass, tree_unflatten, tree_map
from thunder.core.proxies import Proxy, TensorProxy, variableify, CollectionProxy, ProxyTag
from thunder.core.compile_data import get_compile_data
import thunder.core.prims as prims
from thunder.core.proxies import Proxy, TensorProxy, variableify, CollectionProxy, ProxyTag
from thunder.core.pytree import tree_flatten, tree_flatten_with_dataclass, tree_unflatten, tree_map
from thunder.core.trace import get_tracectx, VariableInterface
from thunder.core.utils import FrozenDict, make_hashable

from thunder.core.trace import (
get_tracectx,
VariableInterface,
)

#
# Support for querying "traceable" functions
Expand Down Expand Up @@ -314,6 +312,17 @@ def __call__(self, *args, **kwargs):
else:
trace.push_scope(subsymbols)
result = self.meta(*args, **kwargs)

# To avoid passing an arg directly to output, we make a shallow_copy
flat_results, spec = tree_flatten(result)
flat_args, _ = tree_flatten((args, kwargs))
for i, result_ in enumerate(flat_results):
for arg in flat_args:
if arg is result_ and isinstance(arg, Proxy):
flat_results[i] = prims.shallow_copy(arg)

result = tree_unflatten(flat_results, spec)

trace.pop_scope()

cd = get_compile_data()
Expand Down
17 changes: 1 addition & 16 deletions thunder/core/transform_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,29 +162,14 @@ def dce(trace: Trace, needed_proxies: None | set[Variable] = None) -> Trace:
else:
needed = False

# NOTE This block is run even if we know we're preserving the operation, because it
# may mark some of the operation's outputs as unused
some_unused = False
for out in bsym.flat_proxy_outs:
if variableify(out) in needed_proxies and producer_map[out] == bsym:
needed = True
else:
some_unused = True
break

if needed:
nbsym: BoundSymbol = bsym

# Replaces unused Proxy outputs with None
if some_unused:

def _helper(x):
if isinstance(x, Proxy) and (variableify(x) not in needed_proxies or producer_map[x] != bsym):
return None
return x

nbsym_output = tree_map(_helper, bsym.output)
nbsym = bsym.from_bsym(output=nbsym_output)

Comment thread
beverlylytle marked this conversation as resolved.
# Eliminates no-op subsymbols
# NOTE In general editing subsymbols doesn't do anything, but no-op subsymbols are a pain
# for transforms to deal with. Transforms typically look for a "flattened" version of an
Expand Down
10 changes: 10 additions & 0 deletions thunder/core/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,16 @@ def _cat_prim_grad(tensors: list[TensorProxy], /, dim: int) -> TensorProxy:
register_grad(pids.CAT, _cat_prim_grad)


def _shallow_copy_prim_grad(a: TensorProxy) -> TensorProxy:
fwd = prims.shallow_copy(a)
g = get_grad(fwd)
put_grad(a, g)
return fwd


register_grad(pids.SHALLOW_COPY, _shallow_copy_prim_grad)


def _update_aliases_prim_grad(tensors: tuple[TensorProxy, ...]) -> tuple[TensorProxy, ...]:
fwd_tensors = prims.update_aliases(tensors)
for fwd_t, t in zip(fwd_tensors, tensors):
Expand Down
1 change: 1 addition & 0 deletions thunder/examine/memory_calculation.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"contiguous",
"split",
"torch_wait_prim_impl",
"shallow_copy",
)

# A registry of symbols that require special memory calculation;
Expand Down
10 changes: 10 additions & 0 deletions thunder/executors/nvfuserex_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -1745,6 +1745,16 @@ def clone(a: TensorProxy, *, fd: FusionDefinition, lc_to_nv_map: dict) -> Any:

register_supported(PrimIDs.CLONE, clone, _elementwise_unary_check)


def shallow_copy(a: TensorProxy, *, fd: FusionDefinition, lc_to_nv_map: dict) -> Any:
nva = getnv(a, fd, lc_to_nv_map)

return nva


register_supported(PrimIDs.SHALLOW_COPY, shallow_copy, _elementwise_unary_check)


# update_aliases is disabled. nvfuser does not support it.
# TODO: Enable this once nvfuser supports it.
# def update_aliases(aliases: tuple[TensorProxy], *, fd: FusionDefinition, lc_to_nv_map: dict) -> Any:
Expand Down
1 change: 1 addition & 0 deletions thunder/executors/torch_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ def cuda_device_checker(*args, **kwargs):
# parallel residual paths are used in the transformer block
prims.div.id,
prims.erf.id,
prims.shallow_copy.id,
}
torch_compile_cat_ex._implmap = {
op: ImplInfo(checker=cuda_device_checker) for op in pytorch_ex.implmap if op in supported_ops
Expand Down
7 changes: 7 additions & 0 deletions thunder/tests/opinfos.py
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,13 @@ def _abs_torch(x: torch.Tensor | Number):
dtypes=(datatypes.complex32,),
devicetypes=(devices.DeviceType.CPU,),
),
# PyTorch doesn't support abs for bool on cpu
DecorateInfo(
pytest.mark.skip,
Comment thread
beverlylytle marked this conversation as resolved.
Outdated
"test_core_vs_torch_consistency",
dtypes=(datatypes.bool8,),
devicetypes=(devices.DeviceType.CPU,),
),
# Ref - https://github.com/Lightning-AI/lightning-thunder/issues/2363
DecorateInfo(
pytest.mark.skip,
Expand Down
22 changes: 0 additions & 22 deletions thunder/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2111,28 +2111,6 @@ def func(qkv):
assert "scaled_dot_product_attention" in tuple(bsym.sym.id for bsym in traces[-1].bound_symbols)


@instantiate(dtypes=NOTHING)
def test_no_passthrough_symbol(executor, device, _):
Comment thread
beverlylytle marked this conversation as resolved.
# A test case for the situation reported in
# "backward trace contains symbols not present in forward that cause
# NotImplementedError"
# When an operation simply passes through its input, we should not
# add it to the trace.

def func(x):
return x.type_as(x)

x = make_tensor((2, 2), device=device, dtype=torch.float32)
compiled = executor.make_callable(func)
out = compiled(x)
assert out is x
initial_trace_with_dce = thunder.last_traces(compiled)[3]
assert "Constructed by Dead Code Elimination" in str(initial_trace_with_dce)
assert len(initial_trace_with_dce.bound_symbols) == 2
assert initial_trace_with_dce.bound_symbols[0].sym.id == prims.PrimIDs.UNPACK_TRIVIAL
assert initial_trace_with_dce.bound_symbols[1].sym.id == prims.PrimIDs.RETURN


@instantiate(
dtypes=NOTHING,
# https://github.com/Lightning-AI/lightning-thunder/issues/946
Expand Down
4 changes: 2 additions & 2 deletions thunder/tests/test_examine_memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,5 @@ def test_nanogpt_block():
# We are checking the estimated memory against a fixed value for consistency.
assert max_mem_fw[0] == 381754368
assert sum(max_mem_fw[1].values()) == 375462912
assert max_mem_bw[0] == 641097728
assert sum(max_mem_bw[1].values()) == 440474624
assert max_mem_bw[0] == 741761024
assert sum(max_mem_bw[1].values()) == 541137920
Comment thread
beverlylytle marked this conversation as resolved.
1 change: 1 addition & 0 deletions thunder/tests/test_grad.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"index_put",
"batch_norm",
"instance_norm",
"torch_type",
Comment thread
beverlylytle marked this conversation as resolved.
"type_as",
}

Expand Down
2 changes: 1 addition & 1 deletion thunder/tests/test_torch_compile_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def test_torch_compile_cat_rope_single_fusion():

backward_execution_trace = thunder.last_backward_traces(jfn)[-1]
assert len(get_fusions(backward_execution_trace)) == 1
assert len(backward_execution_trace.bound_symbols) == 14
assert len(backward_execution_trace.bound_symbols) == 15


@pytest.mark.skipif(not is_inductor_supported() or platform.system() == "Windows", reason="inductor unsupported")
Expand Down
6 changes: 3 additions & 3 deletions thunder/transforms/cudagraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,11 +358,11 @@ def transform_trace_post_optimization(self, trace, **kwargs):
assert self.outputs_from_forward is not None, "called on backward without forward before"
assert len(trace.bound_symbols[2].args) == 2 and trace.bound_symbols[2].args[0].name == "saved_for_backward"
assert (
trace.bound_symbols[8].sym.name == "unpack_sequence"
and trace.bound_symbols[8].args[0] is trace.bound_symbols[2].output[0]
trace.bound_symbols[9].sym.name == "unpack_sequence"
and trace.bound_symbols[9].args[0] is trace.bound_symbols[2].output[0]
)

saved_for_backwards_unpacked = trace.bound_symbols[8].output
saved_for_backwards_unpacked = trace.bound_symbols[9].output
assert len(saved_for_backwards_unpacked) == len(self.outputs_from_forward)
for is_static, p_bw in zip(self.outputs_from_forward, saved_for_backwards_unpacked):
if is_static:
Expand Down
Loading