The output used to move after the small model's warmup had linked the
warp to its address, which needed the warp to link again by dropping a
private tinygrad cached property. Had that ever stopped working, the
small model's own warp would have kept writing the freed memory.
modeld now asks the adapter's coherent_warp() (Jetlink's make_coherent
with Jetlink on, off legacy9d) and load_verified_model moves the small
model's warp output before warmup(), as Jetlink's own warp moves its
output before its first call. CatalogWarp only reads the answer
(warp_copied): sent from where it is, or copied out, chosen once.
tinygrad maps the warp's QCOM output write-combined, which the CPU reads
uncached: CatalogWarp spent ~2.9 ms a frame copying the frame out, out
of the 46 ms a host has to answer in. It now moves the output to
IO-coherent write-back memory with Jetlink's warp.make_coherent, as
Jetlink's own warp does, and the link sends straight from it (0.22 ms
measured for Jetlink's warp). The warp has run by then, and tinygrad
bakes a held buffer's address in at link time, so its program links
again on the next call. If the kernel refuses the memory, the frame is
copied out as before, and the adapter's log says which.
TinyJit's per-call input checks are left alone: 0.045 ms a call on a
Mac under this tinygrad, not the ~1 ms they cost under Jetlink's.
warp.make_coherent is public, for an adapter's own warp: it moves a QCOM
output to memory the CPU reads cached, as Jetlink's warp does.
CREDITS.md and JETLINK.md name the new revision.
CatalogModelState.warp_frames is the warp branch of run(), which run()
and CatalogWarp now both call, so the link enqueues exactly what the JIT
was captured with and reads npy and input_queues live rather than as
they were when it was built. CatalogWarp binds the output once (the
captured JIT returns the same buffer every call), reuses one pair of
warm-up frames for the probe and frees them, and drops their blob
cache entries. model_warp lets a failure raise without logging it
too: Jetlink logs it as it keeps the small model.
Jetlink's stock driving warp is a legacy9d pickle, which a native02e
modeld cannot load, so the link never took over there. The adapter's
model_warp (Jetlink's optional hook since 0605e34) now hands Jetlink
the small model's own camera warp (CatalogWarp) on any other runtime:
the same JIT, inputs and blob cache, read into host memory after each
frame, with a probe at load that refuses an output not read live.
Under legacy9d it returns None and Jetlink loads the stock pickle.
From #253, without its edit to jetlink_repo or the hold tolerance
override.
The adapter may now supply the warp the link sends (ModelSide.model_warp,
optional; what it returns is checked against interface.FrameWarp before
the frame loop). Without one, or when it returns None, Jetlink loads the
stock driving warp pickle as before. API stays 3.
CREDITS.md and JETLINK.md name the new revision.
Discard a preempted clock pair and try up to three fresh pairs while
retaining the 1 ms accepted span and all existing freshness/resume gates.
Yield after receive-only decoder construction so normal UI collection
refreshes before full physical admission, Offroad request or input.
Recorded d5 clock failure; reproduced timing regressions; 250 focused
native cases, lint/type checks and independent source/evidence review.
No vehicle commands, device deployment or physical cure claim.
Clarify connection stages across wireless, adapter, USB, and tablet options with regression coverage for progress states and responsive layouts.
(cherry picked from commit 489dad0e7733127c7a9654c9a7491d1ab8a554a4)