surface lifecycle
how to create, write, read, and release Buffer buffers.
create by size
let surface = new?; // 8 KB
create by tensor shape
for a 4D tensor [1, channels, 1, spatial] in fp16:
let surface = with_shape?; // 64 channels × 128 spatial × 2 bytes = 16 KB
write fp16 data
surface must be locked before CPU access. write handles lock/unlock:
surface.write;
read fp16 data
surface.read;
pass to ANE
surfaces are passed directly to model.run(). the ANE reads/writes
the same physical memory — no copies.
model.run?;
important: do not hold a lock while ANE is running. read and
write lock and unlock automatically. calling run() between
lock/unlock will deadlock.
release
surfaces are released automatically on drop. the underlying IOSurface
is freed via CFRelease.
bulk fp16 conversion
for large buffers, use vectorized NEON conversion:
let f32_data: = vec!;
let mut fp16_data: = vec!;
cast_f32_f16;
let mut back: = vec!;
cast_f16_f32;