Great question! The “unbound” label here is not Python’s classic unbound method concept (which was indeed removed in Python 3). Instead, it’s terminology used internally by PyTorch’s C extension (torch._C) to describe a method defined on the C-level TensorBase class that hasn’t been bound to a specific tensor instance yet.
In plain terms: torch.Tensor.mul is the unbound form (a method descriptor on the class), while my_tensor.mul is the bound form (attached to a specific tensor object).
python
import torch
a = torch.tensor([1.0, 2.0])
b = torch.tensor([3.0, 4.0])
print(torch.mul(a, b)) # functional, unbound style
print(torch.Tensor.mul(a, b)) # explicitly unbound — same result
print(a.mul(b)) # bound to instance `a`
All three produce the same result. The unbound label in the help output is just PyTorch’s C extension surfacing the method’s origin, not a Python 2-style unbound method.
An unbound method in PyTorch (and Python in general) refers to a function that belongs to a class or module, but isn’t tied (“bound”) to any specific instance of an object when you call it.
For example, torch.mul is a function in the main torch namespace. Because it is unbound to a specific tensor instance, you have to pass both tensors you want to multiply as arguments:
python
import torch
a = torch.tensor([1, 2, 3])
b = torch.tensor([2, 2, 2])
Using the unbound method (requires passing the tensors as arguments)
result = torch.mul(a, b)
On the other hand, if you use the bound method natively on the tensor object, it automatically knows about the tensor it’s attached to (a), so you only need to pass the second tensor (b):
python
Using the bound method (attached to tensor ‘a’)
result = a.mul(b)
Both do the exact same thing under the hood! The bound method a.mul(b) is essentially just syntactic sugar for the unbound torch.mul(a, b). Hope this clarifies it for you!