intel / intel/torch-xpu-ops

[xpu-alignment] embedding_renorm_ derives the row width from stride(0) and faults on a zero-width embedding

Open
#5,152 0 comments 0 reactions 1 assignee Claimed by @laifenxiawucha View on GitHub
ai_generated
Dominant language
Python
Stars
113
Forks
128
Avg merge
5d 13h
Merged PRs (30d)
107

Description

### 🐛 Describe the bug

## Upstream source

- Issue: https://github.com/pytorch/pytorch/issues/195185 - `[CUDA] illegal memory read on renorm_kernel` (OPEN, created 2026-08-28).
- Proposed upstream fix: https://github.com/pytorch/pytorch/pull/195208 (OPEN, unmerged). It changes `aten/src/ATen/native/cuda/Embedding.cu` only, and its regression test is `@onlyOn(["cuda"])`.
- Alignment scan window: `[2026-08-28T00:00:00Z, 2026-08-29T00:00:00Z)`.

## Observed XPU behavior

`F.embedding(indices, weight, max_norm=1.0, norm_type=2.0)` with a zero-width
weight fails on XPU:

```
weight: torch.Size([20, 0]) (1, 1) 0 xpu:0 | stride(0)= 1 size(1)= 0
cpu out: (1, 0)
RESULT: confirmed
reason: XPU embedding_renorm_ on a zero-width weight failed: level_zero backend failed with error: 40 (UR_RESULT_ERROR_OUT_OF_RESOURCES)
```

CPU, given the identical inputs, returns shape `(1, 0)` cleanly. The oracle here
is CPU plus the upstream signature, not a tolerance comparison.

## Root cause and target-path evidence

`src/ATen/native/xpu/sycl/Embedding.cpp:237` takes the same shortcut upstream
names as the CUDA root cause:

```cpp
int dim = self.stride(0);
```

`torch.empty(20, 0).stride()` is `(1, 1)`, so `dim` becomes `1` while the real
row width `self.size(1)` is `0`. `dim` is passed to
`embedding_renorm_template`, and `RenormKernelFunctor::operator()`
(`src/ATen/native/xpu/sycl/Embedding.cpp:100-141`) then runs its accumulation
loop once and dereferences `weights_[base_index]`:

```cpp
for (int i = tid; i < dim_; i += sgSize) {
auto x = static_cast(weights_[base_index + i * weights_stride1_]);
```

The `(20, 0)` weight has zero elements, so that pointer has no backing
allocation - the same invalid read compute-sanitizer reports for CUDA. The fix
is the same one-line change: use `self.size(1)`. The kernel already receives
`weights_stride0`/`weights_stride1` separately for indexing, so it does not
depend on the tensor being contiguous, and `dim == 0` makes both loops execute
zero times without skipping the launch.

Target-path proof that this is the XPU kernel and not setup data or an
unsupported input:

- the log records the weight as resident on `xpu:0` and in exactly the
`stride(0)=1, size(1)=0` state the defect requires;
- the CPU reference ran first on the same inputs and succeeded, so this is not
an input-validation rejection;
- `embedding_renorm_` is dispatched to XPU via `embedding_renorm_xpu_` in
`src/ATen/native/xpu/Embedding.cpp:39`, so no fallback is involved;
- the runner's environment probe was clean and five other reproducers did heavy
XPU work on the same device in the same run, so this is a kernel-level fault
rather than a global environment failure.

The UR error code alone does not distinguish an out-of-bounds device read from a
degenerate launch derived from `dim`; both trace to the same line, and either
way the oracle is violated on the XPU path.

## Reproducer

```python
import torch
import torch.nn.functional as F

weight = torch.empty((20, 0), dtype=torch.float32, device="xpu")
indices = torch.tensor([0], dtype=torch.int64, device="xpu")
print("cpu:", tuple(F.embedding(indices.cpu(), weight.cpu(), max_norm=1.0, norm_type=2.0).shape))
out = F.embedding(indices, weight, max_norm=1.0, norm_type=2.0)
torch.xpu.synchronize()
print("xpu:", tuple(out.shape)) # expected (1, 0)
```

## Environment

`torch 2.15.0.dev20260826+xpu`, Python 3.13.13 (`/opt/conda/bin/python3.13`),
`Intel(R) Arc(TM) Pro B60 Graphics`, `torch.xpu.is_available() == True`, no
environment warnings. Neither upstream fix candidate is present in this build.

## Ownership

The kernel is torch-xpu-ops code. `pytorch/pytorch#195208` fixes only the CUDA
kernel and adds a CUDA-only test, so nothing upstream will fix or detect the XPU
copy. No `pytorch/pytorch` issue or PR claims the XPU work, and no
`intel/torch-xpu-ops` tracker covers it. This XPU fix is independent of whether
`#195208` lands: XPU already diverges from CPU today, and no existing test
asserts the faulting behavior.

Suggested XPU regression test: the same reproducer, mirroring upstream's
`test_embedding_max_norm_zero_embedding_dim`.

### Versions

--

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.