We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Dtypes and Numerics step 1 of 6
What dtype comes out
Mixing dtypes in one operation is legal and the result’s dtype follows rules that are mostly obvious and have one genuine surprise in them.
Between tensors: the wider one wins
int32 + float32 -> float32 float beats int
float16 + float32 -> float32 wider float wins
bool + int8 -> int8 bool is the narrowest of all
Categories rank bool < integer < floating < complex, and within a category
the wider wins.
Between a tensor and a Python number: the tensor wins
This is the surprise.
int64 tensor + 1.5 -> float32 not float64
int32 tensor + 2 -> int32 not int64
A Python scalar is weak. It participates in the category ranking, so
adding a float to an integer tensor does move you to floating point, but it
does not drag you to the widest type in that category. You get the default
floating dtype, which is float32.
If Python scalars promoted normally, x + 1.5 on a float16 tensor would
silently produce float32 and every mixed-precision model would fall out of
half precision on the first bias add. The weak rule is what stops that:
float16 tensor + 1.5 -> float16 stays half
float16 tensor + torch.tensor([1.5]) -> float32 widened
A zero-dimensional tensor is weak too
int64 + torch.tensor(1.5) 0-dim, weak -> float32
int64 + torch.tensor([1.5]) 1-dim, strong -> float32
float16 + torch.tensor(1.5) 0-dim, weak -> float16
float16 + torch.tensor([1.5]) 1-dim, strong -> float32
The rule is about rank, not about being a Python object. A 0-dim tensor
is treated as a scalar for promotion, which is usually what you want and is
worth knowing before it surprises you: loss * scale behaves differently
depending on whether scale is torch.tensor(2.0) or torch.tensor([2.0]).
Why you should care
Silent widening is a memory and speed regression that no test catches: the numbers are right and the tensor is twice the size. Silent narrowing is worse, because it is a correctness bug.
When it matters, say what you want:
x.to(torch.float32)
torch.tensor(1.5, dtype=torch.float64)
Your task
def result_dtype(a_dtype: str, b_dtype: str) -> str
Both arguments name a dtype, except that "pyfloat" and "pyint" mean a
plain Python number rather than a tensor. Return the name of the dtype the
addition produces, without the torch. prefix.
Build the operands and ask. That is the intended solution.
Stuck?
PyTorch reference solution
Sign in to attempt this problem and reveal the reference solution.