Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ select = [
"RUF100", # see: https://docs.astral.sh/ruff/rules/unused-noqa/
]
ignore = [
"E731", # Do not assign a lambda expression, use a def
"E501", # todo: Line too long (235 > 120 characters)
# TODO(crcrpar): Resolves the following ignores as these are added while enabling ruff check in pre-commit
"F821", # https://docs.astral.sh/ruff/rules/undefined-name/
Expand Down
17 changes: 13 additions & 4 deletions thunder/benchmarks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,15 @@
def list_benchmarks(use_classname: bool = True) -> None:
print("Available benchmarks:")

name_fn = lambda x: x[0]
if not use_classname:
name_fn = lambda x: x[1].name
if use_classname:

def name_fn(x):
return x[0]

else:

def name_fn(x):
return x[1].name

for x in sorted(benchmarks, key=name_fn):
name = name_fn(x)
Expand Down Expand Up @@ -486,7 +492,10 @@ def _run_benchmark(
# Determines the "wait for computation function," to be run after calls to make_batch() and the benchmark
# function to ensure that computation has finished
devices: list[str] = benchmark.devices
wait_for_computation_fn = lambda: None

def wait_for_computation_fn():
return None

for device in devices:
device: thunder.core.devices.Device = thunder.core.devices.device_from_string(device)
if device.devicetype is thunder.core.devices.DeviceType.CUDA:
Expand Down
19 changes: 13 additions & 6 deletions thunder/benchmarks/benchmark_litgpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,9 @@ def setup_distributed(self, model):
size_auto_wrap_policy = functools.partial(
size_based_auto_wrap_policy, min_num_params=self.fsdp_bucket_params
)
zero_bucket_wrap_policy = lambda module, recurse, nonwrapped_numel: nonwrapped_numel >= 0

def zero_bucket_wrap_policy(module, recurse, nonwrapped_numel):
return nonwrapped_numel >= 0

self.bucketing_mode = self.bucketing_mode or "block"
custom_wrap_policy = {
Expand Down Expand Up @@ -657,7 +659,9 @@ def setup_activation_checkpointing(self):
)
return

check_fn = lambda submodule: isinstance(submodule, Block)
def check_fn(submodule):
return isinstance(submodule, Block)

apply_activation_checkpointing(self.model, checkpoint_wrapper_fn=checkpoint_wrapper, check_fn=check_fn)

# TODO(crcrpar): Think of apply `torch.compile` or `thunder.jit` per block/module
Expand Down Expand Up @@ -737,10 +741,13 @@ def calculate_model_flops(self):
meta_model = self.init_model()

x = torch.randint(0, 1, (self.micro_batch_size, meta_model.config.block_size), device=meta)
model_fwd = lambda: meta_model(x)
model_loss = lambda y: torch.nn.functional.cross_entropy(
y.reshape(-1, y.size(-1)), x.reshape(-1), ignore_index=-1
)

def model_fwd():
return meta_model(x)

def model_loss(y):
return torch.nn.functional.cross_entropy(y.reshape(-1, y.size(-1)), x.reshape(-1), ignore_index=-1)

self.perf_metrics["model_flops"] = measure_flops(meta_model, model_fwd, model_loss)
finally:
self.device = device
Expand Down
5 changes: 4 additions & 1 deletion thunder/benchmarks/targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,10 @@ def test_hf_transformers(
fn = executor(b.fn())

if compute_type == ComputeType.TRAINING_BACKWARD:
return_fn = lambda *args, **kwargs: fn(*args, **kwargs).loss

def return_fn(*args, **kwargs):
return fn(*args, **kwargs).loss

else:
kwargs["labels"] = None
return_fn = fn
Expand Down
15 changes: 10 additions & 5 deletions thunder/core/proxies.py
Original file line number Diff line number Diff line change
Expand Up @@ -1275,7 +1275,9 @@ def _infer_tensor_properties(
else:
# deferred computation of numel
# TODO: similar to how `shape` is handled, this should be CSE or lifted for efficiency
_numel = lambda *args: reduce(operator.mul, _shape, 1)

def _numel(*args):
return reduce(operator.mul, _shape, 1)

# TODO Alias rank to ndim?
_ndim = len(_shape)
Expand Down Expand Up @@ -2017,11 +2019,14 @@ def tensorproxy(t: torch.Tensor, /, *, name: None | str, history: None | tuple =
shape_pr = ProvenanceRecord(
PseudoInst.LOAD_ATTR, inputs=[copy.copy(history), wrap_const("shape").provenance]
)
dim_pr = lambda idx: ProvenanceRecord(
PseudoInst.BINARY_SUBSCR, inputs=[shape_pr, wrap_const(idx).provenance]
)

def dim_pr(idx):
return ProvenanceRecord(PseudoInst.BINARY_SUBSCR, inputs=[shape_pr, wrap_const(idx).provenance])

else:
dim_pr = lambda idx: None

def dim_pr(idx):
return None

shape = tuple(
IntegerProxy(
Expand Down
8 changes: 6 additions & 2 deletions thunder/core/pytree.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,12 @@ def register_pytree_node_dataclass(cls):
def unpack(cls) -> dict:
return {field.name: getattr(cls, field.name) for field in dataclasses.fields(cls)}

_flatten = lambda obj: tree_flatten(unpack(obj), namespace=OPTREE_NAMESPACE)
_unflatten = lambda spec, children: cls(**spec.unflatten(children))
def _flatten(obj):
return tree_flatten(unpack(obj), namespace=OPTREE_NAMESPACE)

def _unflatten(spec, children):
return cls(**spec.unflatten(children))

optree.register_pytree_node(cls, _flatten, _unflatten, namespace=OPTREE_NAMESPACE)
return cls

Expand Down
5 changes: 4 additions & 1 deletion thunder/core/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -3102,7 +3102,10 @@ def _split_saved_for_backward_into_tensors_and_other(
Returns:
tuple[Sequence[Variable], Sequence[Variable]]: Tuple of tensors and other.
"""
is_tensor = lambda x: isinstance(x, TensorProxy)

def is_tensor(x):
return isinstance(x, TensorProxy)

other, tensors = utils.partition(is_tensor, saved_for_backward)
return tuple(tensors), tuple(other)

Expand Down
5 changes: 4 additions & 1 deletion thunder/executors/fa3ex.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ def fa3_bwd_impl(
dq, dk, dv = torch.empty_like(q), torch.empty_like(k), torch.empty_like(v)

# fa3 bwd requires last dim to be contiguous: https://github.com/Dao-AILab/flash-attention/issues/1109#issuecomment-2270043573
maybe_contiguous = lambda x: x.contiguous() if x.stride(-1) != 1 else x

def maybe_contiguous(x):
return x.contiguous() if x.stride(-1) != 1 else x

dq, dk, dv = (maybe_contiguous(a) for a in (q, k, v))

if softmax_scale is None:
Expand Down
16 changes: 11 additions & 5 deletions thunder/executors/triton_crossentropy_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,10 @@ def forward(
# result = torch.empty_like(indices, dtype=dtype, device=device)
neg_logprobs = torch.empty_like(logits, dtype=buffer_dtype, device=device)
weights_buffer = torch.empty_like(result, dtype=buffer_dtype)
grid = lambda opt: (logits.numel() // n_cols,)

def grid(opt):
return (logits.numel() // n_cols,)

log_size_logits = int(math.log(math.prod(logits.shape) / n_cols))
_forward[grid](
logits,
Expand Down Expand Up @@ -512,10 +515,13 @@ def backward(ctx, dneg_logprobs):
# run the kernel
# neg_logprobs will be modified in place to become our gradient:
n_cols = neg_logprobs.shape[-1]
grid = lambda opt: (
neg_logprobs.numel() // n_cols,
triton.cdiv(n_cols, opt["BLOCK"]),
)

def grid(opt):
return (
neg_logprobs.numel() // n_cols,
triton.cdiv(n_cols, opt["BLOCK"]),
)

log_size_logits = int(math.log(math.prod(neg_logprobs.shape) / n_cols))
_backward[grid](
neg_logprobs,
Expand Down
5 changes: 4 additions & 1 deletion thunder/tests/distributed/test_tensor_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,10 @@ def forward(self, x):
for p_name, p_ref in layer.named_parameters(recurse=False):
param_fqn = f"{l_name}.{p_name}"
ref_grad = p_ref.grad
msg = lambda err_msg: f"[{prefix} {param_fqn}] {err_msg}"

def msg(err_msg):
return f"[{prefix} {param_fqn}] {err_msg}"

if is_tensor_parallel and (ref_grad.ndim > 1 or dim == 0):
ref_grad = ref_grad.chunk(self.world_size, dim)[self.rank]
grad = tp_model.get_parameter(param_fqn).grad
Expand Down
5 changes: 4 additions & 1 deletion thunder/tests/test_grad.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,10 @@ def _thunder_to_torch_args(args, kwargs, dtype):
Returns:
tuple: (args, kwargs) with values converted to Torch dtypes if they are of the given dtype.
"""
mapper = lambda x: ltorch.to_torch_dtype(x) if isinstance(x, dtype) else x

def mapper(x):
return ltorch.to_torch_dtype(x) if isinstance(x, dtype) else x

args = tree_map(mapper, args)
kwargs = tree_map(mapper, kwargs)
return args, kwargs
Expand Down
12 changes: 9 additions & 3 deletions thunder/tests/test_interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,8 +380,11 @@ def fn2(a, b):


def test_build_map_dict_merge(jit):
addall = lambda *args, **kwargs: sum(args) + sum(kwargs.values())
foo = lambda *args, **kwargs: addall(*args, **kwargs)
def addall(*args, **kwargs):
return sum(args) + sum(kwargs.values())

def foo(*args, **kwargs):
return addall(*args, **kwargs)

assert any(i.opname == "BUILD_MAP" for i in dis.get_instructions(foo))
assert any(i.opname == "DICT_MERGE" for i in dis.get_instructions(foo))
Expand All @@ -396,7 +399,10 @@ def test_build_map_dict_merge(jit):

with pytest.raises(KeyError, match="got multiple values for keyword argument"):
d = {"a": 3, "b": 4}
mergefail = lambda **kwargs: addall(**kwargs, **d)

def mergefail(**kwargs):
return addall(**kwargs, **d)

jfail = jit(mergefail)
jfail(**kwargs)

Expand Down
4 changes: 3 additions & 1 deletion thunder/tests/test_networks.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,9 @@ def forward_backward_peak(m, inp):
m = litgpt_model.GPT.from_name("llama2-like")
inp = torch.ones((1, 2048), dtype=torch.int64)

check_fn = lambda submodule: isinstance(submodule, litgpt_model.Block)
def check_fn(submodule):
return isinstance(submodule, litgpt_model.Block)

apply_activation_checkpointing(m, checkpoint_wrapper_fn=checkpoint_wrapper, check_fn=check_fn)

# warmup, allocate grads etc.
Expand Down
5 changes: 4 additions & 1 deletion thunder/tests/test_torch_library_custom_op.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ def mul_triton_kernel(
def mul_triton(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
output = torch.empty_like(x)
n_elements = output.numel()
grid = lambda meta: (triton.cdiv(n_elements, meta["BLOCK_SIZE"]),)

def grid(meta):
return (triton.cdiv(n_elements, meta["BLOCK_SIZE"]),)

torch.library.wrap_triton(mul_triton_kernel)[grid](x, y, output, n_elements, BLOCK_SIZE=1024)
return output

Expand Down
5 changes: 4 additions & 1 deletion thunder/tests/test_torch_library_custom_op_with_lists.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,10 @@ def list_mul_triton(tensors: list[torch.Tensor]) -> list[torch.Tensor]:
y = tensors[1]
output = torch.empty_like(x)
n_elements = output.numel()
grid = lambda meta: (triton.cdiv(n_elements, meta["BLOCK_SIZE"]),)

def grid(meta):
return (triton.cdiv(n_elements, meta["BLOCK_SIZE"]),)

torch.library.wrap_triton(list_mul_triton_kernel)[grid](x, y, output, n_elements, BLOCK_SIZE=1024)
return [output]

Expand Down
Loading