Skip to content

to_executorch segfaults when constant tensors are in device memory #21545

Description

@shoumikhin

Serializing a program with CUDA parameters segfaults the emitter

to_executorch() crashes with a segmentation fault when a program's constant
tensors live in device memory. The emitter reads a constant's storage through a
host pointer cast, with no check of where that storage actually is:

# exir/emit/_emitter.py, _tensor_spec_to_evalue
buffer_data = bytes(
    ctypes.cast(
        typing.cast(torch.UntypedStorage, spec.storage).data_ptr(),
        ctypes.POINTER(spec_array_type),
    ).contents
)

data_ptr() on a CUDA storage is a device address, so ctypes.cast reads device
memory from the host.

Reproducer, on a machine with a CUDA build of torch:

import torch
from torch.export import export
from executorch.exir import to_edge_transform_and_lower

model = torch.nn.Sequential(torch.nn.Linear(4, 3), torch.nn.ReLU()).eval().cuda()
example = torch.ones(2, 4).cuda()
program = to_edge_transform_and_lower(export(model, (example,))).to_executorch()

The faulthandler traceback points straight at the cast:

Fatal Python error: Segmentation fault
Current thread ...:
  File ".../executorch/exir/emit/_emitter.py", line 460 in _tensor_spec_to_evalue

The same script with host parameters succeeds, which is the workaround: keep
parameters on the host and let the partitioner see the device only through the
example input.

Suggested fix: copy the storage to the host before serializing when it is not
already there, or fail with a clear message instead of reading device memory
from the host.

Found while running an end-to-end delegate export on Linux aarch64. Not specific
to any one backend, since the crash is in the shared serialization path.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions