Referencing PR –> PR #174009, altough there were few changes, made afterwards by the reviewers.
Whenever we write tensor[0] in Python, it feels like magic. But under the hood, PyTorch has to route this operation through a massive C++ dispatching engine to figure out if this should run on a CPU or a CUDA GPU…
The Bug: Empty Indices Crashing index.Tensor
The issue behind this PR was deceptively small: torch.ops.aten.index.Tensor(t, []) could crash instead of failing cleanly when the index list was empty. In other words, PyTorch was being asked to perform tensor indexing with no actual indices, and one of the internal code paths did not defend itself against that case.
That sounds like a corner case, but it is exactly the kind of corner case that matters in a system like PyTorch. Indexing is one of the most heavily used operations in the entire stack, and even a tiny inconsistency can surface in surprising places, especially once you start mixing Python frontend code, ATen internals, and backend-specific behavior.
Tracing the Dispatch: Python to ATen
When you write something like x[0] in Python, the operation does not stay in Python for long. It is lowered into ATen, PyTorch’s internal tensor library, where the framework decides how to interpret the indexing request and which backend should handle it.
That path has to answer a lot of questions:
- Is the index list valid?
- Are we doing basic or advanced indexing?
- Do the indices describe a contiguous subspace?
- Should the implementation materialize any optional indices first?
The bug in this PR lived in that validation layer. The problem was not really about a specific device or dtype. It was about what happens when the list of indices is empty and the internal helpers assume there is at least one meaningful tensor to inspect.
The Solution: Fixing IndexingUtils.h and TensorAdvancedIndexing.cpp
The PR made two functional changes in the C++ code and one regression test in Python.
First, IndexingUtils.h was updated so that the helper that checks whether the indexed tensors form a contiguous subspace handles an empty set safely. That is the kind of guard that looks boring in isolation, but it is exactly what keeps an internal helper from wandering into undefined behavior when the input is degenerate.
Second, TensorAdvancedIndexing.cpp now checks the meta path for an empty index list and raises a clear IndexError with the message at least one index must be provided. That is the right failure mode here: fail early, fail explicitly, and fail in a place that tells the caller what is wrong.
Third, the Python test suite gained a regression test that exercises the exact empty-index call:
with self.assertRaisesRegex(IndexError, "at least one index must be provided"):
torch.ops.aten.index.Tensor(t, [])
That test is doing more than checking an error message. It locks in the contract so the bug does not quietly return later after some unrelated refactor.