Skip to content

Commit df2c02b

Browse files
msluszniakSS-JIA
authored andcommitted
Vulkan: fix embedding_texture for non width-packed outputs
embedding_texture.glsl assumed the output texel always packs along the embedding dim: it looked up one index per texel and then read 4 consecutive weight elements. When the output is height packed, which the memory layout pass picks once the weight has more than 16384 rows, each texel holds 4 different rows instead, so every group of 4 output rows got the first row's data shifted by one element. Branch on the output's packed dim and load each component from its own weight row when the packed dim is not the embedding dim. Fixes pytorch#22333. (cherry picked from commit 2e5b071)
1 parent 3114ccc commit df2c02b

2 files changed

Lines changed: 49 additions & 3 deletions

File tree

‎backends/vulkan/runtime/graph/ops/glsl/embedding_texture.glsl‎

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ int load_embedding_idx(const TensorIndex4D out_tidx) {
5050
return in_texel[elem_pos.comp];
5151
}
5252

53+
T load_weight_element(const int embedding_idx, const int dim_idx) {
54+
return T(t_weight[embedding_idx * int(width(weight)) + dim_idx]);
55+
}
56+
57+
// Loads 4 consecutive elements of the embedding dim from a single weight row.
58+
// Only valid when the output texel packs along the embedding (width) dim.
5359
VEC4_T load_weight_texel(const int embedding_idx, const int dim_idx) {
5460
int buf_i = embedding_idx * int(width(weight)) + dim_idx;
5561
VEC4_T weight_texel;
@@ -66,11 +72,34 @@ void main() {
6672
return;
6773
}
6874

69-
TensorIndex4D out_tidx =
75+
const TensorIndex4D out_tidx =
7076
texture_pos_to_tensor4d_idx_simple(outp, out_pos, out_layout);
71-
const int embedding_idx = load_embedding_idx(out_tidx);
7277

73-
const VEC4_T weight_texel = load_weight_texel(embedding_idx, out_tidx.data.x);
78+
const int packed_dim = get_packed_dim(out_layout);
79+
80+
VEC4_T weight_texel = VEC4_T(0);
81+
if (packed_dim == 0) {
82+
// The texel packs 4 consecutive elements of the embedding dim, so every
83+
// component reads from the same weight row.
84+
const int embedding_idx = load_embedding_idx(out_tidx);
85+
weight_texel = load_weight_texel(embedding_idx, out_tidx.data.x);
86+
} else {
87+
// The texel packs 4 consecutive elements of an index dim, so every
88+
// component reads a different weight row at the same embedding dim.
89+
const int packed_dim_limit = safe_idx(outp.sizes, packed_dim);
90+
const int packed_dim_start = safe_idx(out_tidx.data, packed_dim);
91+
const int dim_idx = out_tidx.data.x;
92+
93+
TensorIndex4D lane_tidx = out_tidx;
94+
[[unroll]] for (int i = 0; i < 4; ++i) {
95+
const int packed_idx = packed_dim_start + i;
96+
if (packed_idx < packed_dim_limit) {
97+
safe_set(lane_tidx.data, packed_dim, packed_idx);
98+
weight_texel[i] =
99+
load_weight_element(load_embedding_idx(lane_tidx), dim_idx);
100+
}
101+
}
102+
}
74103

75104
imageStore(t_out, out_pos, weight_texel);
76105
}

‎backends/vulkan/test/test_vulkan_delegate.py‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,23 @@ def forward(self, x):
21312131
(torch.tensor([[0, 1, 0], [4, 2, 0]]),),
21322132
)
21332133

2134+
def test_vulkan_backend_embedding_large_vocab(self):
2135+
# Past 16384 entries the output of the embedding is laid out as a height
2136+
# packed texture, so each texel holds 4 different weight rows instead of
2137+
# 4 elements of the same row. See #22333.
2138+
class EmbeddingModule(torch.nn.Module):
2139+
def __init__(self, embedding):
2140+
super().__init__()
2141+
self.embedding = embedding
2142+
2143+
def forward(self, x):
2144+
return self.embedding(x)
2145+
2146+
self.lower_module_and_test_output(
2147+
EmbeddingModule(torch.nn.Embedding(16385, 4)),
2148+
(torch.tensor([[0, 1, 16384], [7, 16000, 12345]]),),
2149+
)
2150+
21342151
def test_vulkan_backend_embedding_3d(self):
21352152
class EmbeddingModule(torch.nn.Module):
21362153
def __init__(self, embedding):

0 commit comments

Comments
 (0)