Host-device transport#
This reference defines the original journal, bulk, inbound and display transports.
The layouts use little-endian integers and their declared field alignment.
cuda/seam/wire.h is the shared layout header; compile-time checks enforce fixed structure sizes.
The device remains authoritative. Mapped transport carries bounded records and snapshots between device kernels and disk programs. Publication sequences distinguish complete writes from incomplete or overwritten slots. Specialized memory and service transports extend these contracts through separate versioned headers.
The four rings#
| ring | memory | producer | consumer | size |
|---|---|---|---|---|
| device record ring | device | every kernel | the flush node | 65,536 slots at the most |
| host ring | pinned host, one memfd | the flush node | the drain | profile size; 64 MiB on 12g |
| bulk ring | pinned host, one memfd | the bulk flush node | the drain | profile size; 256 MiB on 12g |
| inbound ring | pinned host, one memfd | the feeder or the restore program | the apply node | 4,096 slots |
The sizes come from AOTX_DEVICE_RING_SLOTS and AOTX_HOST_RING_DATA_BYTES in
cuda/seam/seam.cuh, and AOTX_MEM_RING_BYTES in cuda/mem/mem.cuh. aotx_seam_bind gives the
device ring one slot for each 256 bytes of its region, and cuts the count to 65,536
(cuda/seam/seam_host.cu). That ring never crosses the seam. The host ring and the bulk ring
carry blocks; the inbound ring carries records. A data area is a power of two, so a position is a
mask.
The display crossing#
The display mirror carries a fixed cell snapshot in a memfd. It is not a record ring and owns no authoritative state. The feeder reopens that descriptor
read-only and sends it to aotx_tui over <journal>/aotx.sock with SCM_RIGHTS. Both ends bind
or connect through an open descriptor for the journal directory. Only the socket file name counts
against the Unix socket address bound.
The attach socket is a byte stream. A frame starts with one kind byte:
| kind | direction | bytes after the kind |
|---|---|---|
K |
terminal to feeder | one 16-byte aotx_key_body |
L |
terminal to feeder | one 4-byte little-endian length, then that many line bytes |
R |
feeder to terminal | one 4-byte little-endian length, then that many reason bytes |
The mirror descriptor travels with one M payload byte. A terminal sends whole frames. The
feeder may receive a partial frame or several frames in one read and keeps the unused bytes for
the next read. A key becomes one KEY record. A line becomes one INPUT_LINE record. The terminal
never writes an inbound ring and the feeder remains its one producer.
The record#
One record fills one slot of 256 bytes: a header of 64 bytes and a body of 192 bytes. The header
is aotx_record_header, in cuda/seam/wire.h.
| offset | bytes | field | value |
|---|---|---|---|
| 0 | 4 | magic |
0x58544F41 |
| 4 | 2 | layout |
1 |
| 6 | 2 | header_bytes |
64 |
| 8 | 8 | boot_id |
the run that wrote the record |
| 16 | 8 | tick |
device time |
| 24 | 8 | seq |
the publish field; from 1, contiguous |
| 32 | 8 | globaltimer |
device clock sample in nanoseconds |
| 40 | 4 | writer |
the writer identity |
| 44 | 1 | cls |
1 for class A, 2 for class B |
| 45 | 1 | type |
0 through 39; see the record-type table |
| 46 | 2 | flags |
0x0001 replayed, 0x0002 fragment, 0x0004 written during replay, 0x0008 recorded admission required |
| 48 | 4 | body_len |
bytes of the body that carry data, 192 at the most |
| 52 | 8 | source_seq |
original source sequence across replay, else zero |
| 60 | 4 | reserved |
zero |
| 64 | 192 | the body | the layout of the type |
The seq field is the publish field of a slot, and zero means unpublished or under rewrite. The
replayed flag states that a restore applied the record again. The fragment flag continues the
line before it. The replay flag marks a derived record written while replay ran.
The restore program carries the original source sequence in source_seq as low and high 32-bit words.
Replayed records preserve that identity in later journals. Fresh records use zero until their source identity is assigned by the consuming contract.
A writer identity below 1,024 is a system writer (cuda/seam/wire.h, AOTX_WRITER_AGENT_BASE).
Identity 0 is the system, 1 the feeder, 2 the restore program and 3 the console. Agent i writes
as 1024 + i.
The block#
A block comprises the records of one tick. The block header is aotx_block_header in
cuda/seam/wire.h, and it is 64 bytes.
| offset | bytes | field | value |
|---|---|---|---|
| 0 | 4 | magic |
0x4B4C4241 |
| 4 | 2 | layout |
1 |
| 6 | 2 | kind |
0 records, 1 pad, 2 payload |
| 8 | 8 | block_seq |
the publish field; from 1, no gaps |
| 16 | 8 | boot_id |
the run that wrote the block |
| 24 | 8 | tick |
the tick the block carries |
| 32 | 8 | first_seq |
the sequence of the first record, or a payload handle |
| 40 | 4 | record_count |
records that follow the header |
| 44 | 4 | byte_len |
bytes of the block, this header included |
| 48 | 16 | reserved |
zero |
A block of records satisfies byte_len = 64 + 256 * record_count. A block never wraps. A pad
block fills the tail when the next block does not fit there. The block after it starts at offset
zero. A pad block and a payload block contain no record.
The ring preambles#
The host ring and the bulk ring carry aotx_host_ring_preamble of cuda/seam/wire.h, which is
256 bytes. Each shared field has a cache line of its own.
| offset | bytes | field | writer |
|---|---|---|---|
| 0 | 4 | magic |
the producer, once at creation |
| 4 | 2 | layout |
the producer, once at creation |
| 6 | 2 | closed |
the producer, at the end of the run |
| 8 | 8 | boot_id |
the producer, once at creation |
| 16 | 8 | data_bytes |
the producer, once at creation |
| 24 | 8 | preamble_bytes |
the producer, once at creation |
| 64 | 8 | head |
the producer; bytes written, monotonic, not masked |
| 128 | 8 | cursor |
the consumer; bytes drained to disk, monotonic |
| 192 | 8 | last_block_seq |
the producer; the last published block sequence |
The inbound ring carries aotx_inbound_preamble of the same header, which is 192 bytes. It contains
magic, layout and closed at the same three offsets, slot_count at offset 8 and
preamble_bytes at offset 16. The feeder writes head at offset 64 and the device writes
consumed at offset 128, each on a line of its own. A data area begins at preamble_bytes from
the first mapped byte, and the padding bytes are zero.
The one consumer field#
cursor is the only field a consumer writes in a host ring. The drain publishes it with a release
store, after the bytes reach the disk (disk/wire/ring.c, aotx_host_ring_advance). An earlier
store would let the producer count a lost block as safe. The producer reads cursor with an
acquire load and never spins on it. It reads that cursor at tick start for the backpressure decision
(cuda/sched/step.cu, aotx_sched_tick_start), and again in the flush for the pad decision
(cuda/seam/flush.cu, aotx_seam_flush).
The bulk path reads the cursor of its own ring once at tick start (cuda/seam/seam.cuh,
aotx_bulk_tick_start). consumed is its mirror in the inbound ring, and the device is its one
writer. The apply publishes it with a release store when its last block ends
(cuda/seam/inbound.cu, aotx_seam_apply_inbound). The feeder never writes over a slot the
device has not consumed.
Publication and acquisition#
The producer of a block writes in this order (cuda/seam/flush.cu, aotx_seam_flush and
aotx_flush_publish).
- Store zero into
block_seqat the destination of the block. - Fence with system scope.
- Write the block header and the records.
- Fence with system scope.
- Release-store the true
block_seq, which is the last one plus one. - Release-store
head, which grows by the byte length of the block, thenlast_block_seq.
The consumer reads in the opposite order (disk/wire/ring.c, aotx_host_ring_take).
- Acquire-load
head. The ring is empty whencursoris not belowhead. - Read the block at
cursor & (data_bytes - 1). - Acquire-load
block_seq. Zero means a block under write, and the ring reads as empty. - Read
byte_len, check it, and copy the whole block into a private buffer. - Acquire-load
block_seqagain. A value that differs means a torn read; pause and read again. - Check the copy, then move
cursorbybyte_len.
The consumer moves its cursor over a pad block as over any other. Before it accepts a block it
checks these things (disk/wire/ring.c, aotx_host_ring_take, and disk/wire/record.c,
aotx_block_valid). The cursor is on an 8-byte boundary, and a block header fits before the
end of the data area. byte_len is 64 at the least, is inside the buffer, does not run past the
data area, and matches the copy.
The magic and the layout version are the ones this build reads, block_seq is not zero, and `head
- cursor
is not belowbyte_len`. A pad block reaches the end of the data area, and a payload block length is a count of 8 bytes. Every record header contains the record magic, the layout version, a header size of 64 and a body length of 192 at the most.
Sequences and loss#
Block sequences start at 1 and have no gaps, so a consumer knows which sequence comes next. A
block left behind by an earlier pass contains a smaller sequence, and the double-load rule refuses
it. The drain reports a gap and continues, because the blocks that follow are still whole
(disk/drain/drain.c, drain_pass).
Record sequences also start at 1 and are contiguous. A sequence that carries nothing uses a pad
record, so one tick leaves no hole in the sequence space. The flush checks that every record
carries the sequence its position gives it. It cuts the block in front of the first record that
fails (cuda/seam/flush.cu, aotx_seam_flush). Loss therefore reaches the consumer as a gap in
the record sequence, and never as silence. The count of dropped runs is in the next stall
record, in the high bit of held_count (cuda/seam/seam.cuh, AOTX_STALL_OVERRUN).
Making and attaching a ring#
The device process makes each ring (cuda/seam/seam_host.cu, aotx_seam_make). It calls
memfd_create with the close-on-exec flag, named aotx-host-ring, aotx-bulk-ring or
aotx-inbound-ring. It grows the file to the preamble size plus the data area, rounded up to
4,096 bytes. It maps the file with PROT_READ | PROT_WRITE and MAP_SHARED, and sets every byte
to zero. It then registers the mapping with cudaHostRegister and cudaHostRegisterMapped.
aotx_seam_open writes the preamble once, so a late reader still knows the layout, and
aotx_seam_bind gets the device address from cudaHostGetDevicePointer
(cuda/seam/seam_host.cu).
A disk-side program receives the descriptor of the ring it must map and no other. The spawn clears
the close-on-exec flag on the named descriptors and sets it on every other one
(cuda/seam/seam_host.cu, aotx_seam_only). It maps the whole descriptor with the size from
fstat, then attaches. An attach fails when the magic, the layout version or a preamble size is
not the one that build reads (disk/wire/diskwire.h, aotx_host_ring_attach). A consumer performs
one more pass after closed goes to 1, and stops.
The inbound ring#
The producer writes one slot and publishes it (disk/wire/ring.c, aotx_inbound_put). An
input line can use 32 slots at the most. Part zero has no fragment flag. Each later part has
that flag, and each part contains 192 bytes at the most. The feeder or restore program publishes
all parts with one head advance (disk/feed/line.c, aotx_line_publish_records). A reader
therefore sees the complete line or no part of it.
- Read
headwith an acquire load. The slot ishead & (slot_count - 1). - Release-store zero into
seqof that slot. - Write the header fields and the body, and zero the rest of the body.
- Release-store
head + 1intoseq. - Release-store
head + 1intoheadof the preamble.
Publication blocks until a slot is free before step 1. A slot is free when head - consumed is below
slot_count (disk/wire/ring.c, aotx_inbound_wait). The producer stamps boot_id zero,
because the inbound preamble carries no boot identity (disk/feed/feed.c, AOTX_WRITER_FEEDER).
The device stamps its own boot identity when it writes the record to the journal. It accepts the defined inbound types and refuses other types (cuda/seam/inbound.cu, aotx_apply_takes). A refused slot is
counted, and its two sequences use pad records.
| type | number | class | least body_len |
body |
|---|---|---|---|---|
TICK_START |
2 | A | 0; the wall clock is read at 8 | aotx_clock_body, 8 bytes: 0 wall_ns |
INPUT_LINE |
4 | A | 0 | UTF-8 bytes; body_len gives the count |
RESTORE |
8 | B | 32 | aotx_restore_body, 32 bytes: 0 restored_boot_id, 8 last_tick, 16 replayed_count, 24 state_hash |
KEY |
10 | A | 16 | aotx_key_body, 16 bytes: 0 key, 4 codepoint, 8 action, 12 mods |
TOKEN |
14 | A | 192 | aotx_token_body, 192 bytes: 0 slot, 4 token, 8 position, 12 flags, 16 seed, 24 draw, 32 role, 36 text_len, 40:152 reply bytes |
TOOL_REPLY |
17 | A | 192 | aotx_tool_reply_body, 192 bytes: 0 agent, 4 request, 8 status, 12 part, 16 parts, 20 len, 24 the bytes |
SETTING |
21 | A | 80 | aotx_setting_body, 80 bytes: 0 value, 8 scale, 12 key_len, 16:64 key bytes |
IMPORT |
23 | A | 184 | an import head of 184 bytes or a part of 192 bytes |
REMOVE |
24 | A | 64 | aotx_remove_body, 64 name bytes |
SELECTION |
25 | A | 192 | aotx_selection_body: agent, turn, count, pages, summary sequence, at most 20 recalled sequences and the source sequence |
MODEL |
26 | A | 120 | aotx_model_body: placement tick, digest, role and file |
The table lists common fixed bodies. Current input also accepts versioned COGNITIVE, MEDIA, SHARED, POLICY and POLICY_CONTROL records.
An affect build accepts AFFECT records. Each specialized reader validates its complete payload contract.
See aotx_apply_takes in cuda/seam/inbound.cu for outer admission checks.
The magic and layout must match, and body_len cannot exceed 192. A key body
carries the codes of the window library. The action is 1 for a press, 0 for a release and 2 for a
repeat, and a code point event has key zero. A token body carries the seed, the draw and the
reply bytes of a sampled token. A restore applies the token and samples nothing again.
A SETTING body contains an 8-byte value, a 4-byte scale, a 4-byte key length and 64 key bytes. An IMPORT head contains its number, kind, file sizes, digest, name and path. Each IMPORT part contains its number, part, file, offset, length and 172 text bytes. A REMOVE body is one 64-byte name.
A SELECTION body contains the agent, turn, count, page limit, summary sequence and 20 recalled sequences. Its last field contains the source sequence. The apply refuses a selection above the count or profile page limit. It also refuses a recalled sequence that is not before the source.
A MODEL body contains the placement tick, a 32-byte SHA-256 digest, a 16-byte role and a 64-byte file name. A restore validates the manifest role and digest before it places that file.
The bulk ring#
The bulk ring carries the same preamble and the same block header, and a payload never enters a
record. A bulk block has kind 2 and a record_count of zero, and the handle is in
first_seq. The byte_len is 64 plus the payload rounded up to 8 bytes (cuda/seam/bulk.cu,
aotx_seam_bulk_flush). A BULK record in the journal carries the same handle and the exact
length.
A bulk block occupies a position only when the remaining space is zero or is at least 64 bytes
for a block header (cuda/seam/bulk.cu, aotx_bulk_fits). A pad block precedes it when it does not. A
payload block rounds to 8 bytes and a record block rounds to 256. The tail of this ring therefore
reaches a state the host ring cannot. One tick stages 256 payloads at the most, in a staging
region of 8 MB (cuda/seam/seam.cuh, AOTX_BULK_STAGE_MAX). A payload that finds no room is
refused and counted.
Specialized transports#
| State | Layout reference |
|---|---|
| Typed memory and recorded choices | Live memory, cuda/cognitive/live.h |
| Image and audio sources | Image input, cuda/media/wire.h |
| Ordinary service requests | Native service |
| Persistent shared resources | Shared service, cuda/shared/wire.h |
| Creator-policy state and controls | Creator policies |
These transports retain bounded byte counts, explicit publication and device-owned admission. They do not turn a display snapshot or host transport buffer into authoritative cognitive state.