馃悰 Describe the bug
The view_convert shader combo lists generate uint8 -> int32 but not the reverse, so a graph containing an int32 -> uint8 view_convert lowers cleanly through VulkanPartitioner and then aborts at run time:
libc++abi: terminating due to uncaught exception of type vkcompute::vkapi::Error:
Exception raised from get_shader_info at backends/vulkan/runtime/api/ShaderRegistry.cpp:54:
(it != listings_.end()) is false! Could not find ShaderInfo with name view_convert_buffer_int32_uint8
backends/vulkan/runtime/graph/ops/glsl/view_convert_buffer.yaml (and the _texture twin):
- parameter_values: [uint8, float]
- parameter_values: [uint8, half]
- parameter_values: [uint8, int32] # <- present
- parameter_values: [float, int32] # <- no [int32, uint8]
Repro. Lower sentence-transformers/all-MiniLM-L6-v2 with VulkanPartitioner and run it. The conversion arrives through the attention mask:
import torch, torch.nn as nn, torch.nn.functional as F
from transformers import AutoModel
from executorch.backends.vulkan.partitioner.vulkan_partitioner import VulkanPartitioner
from executorch.exir import to_edge_transform_and_lower, EdgeCompileConfig
class Emb(nn.Module):
def __init__(self):
super().__init__()
self.model = AutoModel.from_pretrained(
"sentence-transformers/all-MiniLM-L6-v2", attn_implementation="eager")
def forward(self, input_ids, attention_mask):
tok = self.model(input_ids=input_ids, attention_mask=attention_mask)[0]
mask = attention_mask.unsqueeze(-1).expand(tok.size()).float()
summed = torch.sum(tok * mask, 1, keepdim=True)
counts = torch.sum(mask, 1, keepdim=True).clamp(min=1e-9)
return F.normalize((summed / counts).squeeze(1), p=2, dim=1)
ep = torch.export.export(
Emb().eval(),
(torch.zeros(1, 128, dtype=torch.int64), torch.ones(1, 128, dtype=torch.int64)))
prog = to_edge_transform_and_lower(
{"forward": ep}, partitioner=[VulkanPartitioner()],
compile_config=EdgeCompileConfig(
_core_aten_ops_exception_list=[torch.ops.aten.linear.default])).to_executorch()
open("minilm_vulkan.pte", "wb").write(prog.buffer)
Lowering reports a clean 2-blob partition; executor_runner then aborts on device.
Expected behavior
Either generate the variant, or have the partitioner decline the node so it stays on host. Silently accepting at AOT and aborting at run time is the worst of the three, because the failure only appears on a device.
Fix
view_convert is a plain elementwise OUT_T(t_inp[...]) cast, so the pair needs nothing beyond being listed. Verified on a Galaxy S26 Ultra (Adreno 840): with the variant generated, all-MiniLM-L6-v2 runs and its embedding matches the eager reference to cosine 0.99999726 (max abs deviation 4.0e-04), bit-identical across 90 in-process replays.
PR: #22321
Versions
ExecuTorch main @ c27baa8. Android arm64-v8a, NDK 27.1, Galaxy S26 Ultra (Adreno 840). Python 3.10, torch 2.13.0.
馃悰 Describe the bug
The
view_convertshader combo lists generateuint8 -> int32but not the reverse, so a graph containing anint32 -> uint8view_convert lowers cleanly throughVulkanPartitionerand then aborts at run time:backends/vulkan/runtime/graph/ops/glsl/view_convert_buffer.yaml(and the_texturetwin):Repro. Lower
sentence-transformers/all-MiniLM-L6-v2withVulkanPartitionerand run it. The conversion arrives through the attention mask:Lowering reports a clean 2-blob partition;
executor_runnerthen aborts on device.Expected behavior
Either generate the variant, or have the partitioner decline the node so it stays on host. Silently accepting at AOT and aborting at run time is the worst of the three, because the failure only appears on a device.
Fix
view_convertis a plain elementwiseOUT_T(t_inp[...])cast, so the pair needs nothing beyond being listed. Verified on a Galaxy S26 Ultra (Adreno 840): with the variant generated, all-MiniLM-L6-v2 runs and its embedding matches the eager reference to cosine 0.99999726 (max abs deviation 4.0e-04), bit-identical across 90 in-process replays.PR: #22321
Versions
ExecuTorch
main@ c27baa8. Android arm64-v8a, NDK 27.1, Galaxy S26 Ultra (Adreno 840). Python 3.10, torch 2.13.0.