Summary
Taking ref w = holders[0] from a List and calling origin_of(w.buf) on a device buffer field to instantiate a GPU kernel crashes the Mojo 1.0.0 compiler. No diagnostic — just the crash handler:
Please submit a bug report to https://github.com/modular/modular/issues
#0 0x... _mh_execute_header (.../mojo+...)
Bisected: List + ref alone compiles, and reading plain fields through the ref compiles. The trigger is specifically origin_of() on a device buffer reached through a ref into a List. The identical code with the buffer in a plain local variable compiles. A runtime segfault variant exists too: indexing the List at the enqueue call site (holders[0].buf.unsafe_ptr()) instead of taking a ref.
Minimal reproducer (Mojo 1.0.0, MAX 26.5.0, Apple M4 Pro, macOS 26.5)
from max.gpu.host import DeviceContext, DeviceBuffer
from std.gpu import thread_idx
from std.memory import UnsafePointer
struct Holder(Movable):
var buf: DeviceBuffer[DType.float32]
def __init__(out self, ctx: DeviceContext, n: Int) raises:
self.buf = ctx.enqueue_create_buffer[DType.float32](n)
def kern[
xo: Origin[mut=False], yo: MutOrigin
](x: UnsafePointer[Float32, xo], y: UnsafePointer[Float32, yo]):
y[Int(thread_idx.x)] = x[Int(thread_idx.x)] * 2.0
def main() raises:
var ctx = DeviceContext()
var n = 8
var holders = List[Holder]()
holders.append(Holder(ctx, n))
with holders[0].buf.map_to_host() as h:
for i in range(n):
h[i] = Float32(i)
var out = ctx.enqueue_create_buffer[DType.float32](n)
ref w = holders[0]
ctx.enqueue_function[kern[origin_of(w.buf), origin_of(out)]](
w.buf.unsafe_ptr(), out.unsafe_ptr(), grid_dim=1, block_dim=n
)
ctx.synchronize()
with out.map_to_host() as h:
print("first row:", h[0])
Expected
Compiles; running it should print first row: 0.0 and the kernel should write x * 2.
Actual
The compiler crashes while compiling main (crash handler, no error message pointing at the cause).
Workaround (validated in production)
Pass the struct as a function parameter first and call origin_of() on the parameter's fields — that compiles and runs. The workaround is why the Speck runtime passes layer weights through forward_layer(...) instead of reaching into a List at enqueue sites.
A compiler crash with no diagnostic is worse than an error message; the bisect above is a small reproduction.
Environment: Mojo 1.0.0 (ed45d567), MAX 26.5.0, macOS 26.5, Apple M4 Pro, Metal backend.
Summary
Taking ref w = holders[0] from a List and calling origin_of(w.buf) on a device buffer field to instantiate a GPU kernel crashes the Mojo 1.0.0 compiler. No diagnostic — just the crash handler:
Bisected: List + ref alone compiles, and reading plain fields through the ref compiles. The trigger is specifically origin_of() on a device buffer reached through a ref into a List. The identical code with the buffer in a plain local variable compiles. A runtime segfault variant exists too: indexing the List at the enqueue call site (holders[0].buf.unsafe_ptr()) instead of taking a ref.
Minimal reproducer (Mojo 1.0.0, MAX 26.5.0, Apple M4 Pro, macOS 26.5)
Expected
Compiles; running it should print first row: 0.0 and the kernel should write x * 2.
Actual
The compiler crashes while compiling main (crash handler, no error message pointing at the cause).
Workaround (validated in production)
Pass the struct as a function parameter first and call origin_of() on the parameter's fields — that compiles and runs. The workaround is why the Speck runtime passes layer weights through forward_layer(...) instead of reaching into a List at enqueue sites.
A compiler crash with no diagnostic is worse than an error message; the bisect above is a small reproduction.
Environment: Mojo 1.0.0 (ed45d567), MAX 26.5.0, macOS 26.5, Apple M4 Pro, Metal backend.