vyre-runtime 0.6.2

Persistent megakernel + io_uring zero-copy streaming runtime for vyre - GPU as VIR0 bytecode interpreter
Documentation
use super::*;
use crate::megakernel::protocol::{slot, ARGS_PER_SLOT, SLOT_WORDS, STATUS_WORD};

fn read_word(buf: &[u8], slot_idx: u32, word_idx: u32) -> u32 {
    let base = (slot_idx as usize) * (SLOT_WORDS as usize) * 4;
    let off = base + (word_idx as usize) * 4;
    u32::from_le_bytes(buf[off..off + 4].try_into().unwrap())
}

#[test]
fn single_descriptor_publishes_normal_slot() {
    let mut ring = Megakernel::try_encode_empty_ring(4).unwrap();
    let slot = SlotDescriptor::single(
        7,
        SlotOpcode::Builtin(BuiltinOpcode::StoreU32),
        vec![11, 13],
    );
    slot.publish_into(&mut ring, 1).unwrap();
    assert_eq!(read_word(&ring, 1, STATUS_WORD), slot::PUBLISHED);
}

#[test]
fn packed_descriptor_uses_packed_opcode() {
    let mut ring = Megakernel::try_encode_empty_ring(2).unwrap();
    let slot = SlotDescriptor::packed(
        3,
        vec![
            PackedOpDescriptor::new(9, vec![1, 2, 3]),
            PackedOpDescriptor::new(10, vec![4]),
        ],
    );
    slot.publish_into(&mut ring, 0).unwrap();
    assert_eq!(read_word(&ring, 0, STATUS_WORD), slot::PUBLISHED);
    assert_eq!(
        read_word(&ring, 0, protocol::OPCODE_WORD),
        protocol::opcode::PACKED_SLOT
    );
}

#[test]
fn batch_descriptor_publishes_sequential_slots() {
    let mut ring = Megakernel::try_encode_empty_ring(4).unwrap();
    let batch = BatchDescriptor::new(
        1,
        vec![
            SlotDescriptor::single(0, SlotOpcode::Builtin(BuiltinOpcode::Nop), vec![]),
            SlotDescriptor::single(0, SlotOpcode::Builtin(BuiltinOpcode::AtomicAdd), vec![1, 2]),
        ],
    );
    let consumed = batch.publish_into(&mut ring).unwrap();
    assert_eq!(consumed, 2);
    assert_eq!(read_word(&ring, 1, STATUS_WORD), slot::PUBLISHED);
    assert_eq!(read_word(&ring, 2, STATUS_WORD), slot::PUBLISHED);
}

#[test]
fn batch_descriptor_rejects_slot_index_overflow_before_publication() {
    let mut ring = Megakernel::try_encode_empty_ring(4).unwrap();
    let before = ring.clone();
    let batch = BatchDescriptor::new(
        u32::MAX,
        vec![
            SlotDescriptor::single(0, SlotOpcode::Builtin(BuiltinOpcode::Nop), vec![]),
            SlotDescriptor::single(0, SlotOpcode::Builtin(BuiltinOpcode::Nop), vec![]),
        ],
    );

    let err = batch.publish_into(&mut ring).unwrap_err();
    assert!(
        err.to_string().contains("overflows u32"),
        "overflowing descriptor batch must fail with an actionable message: {err}"
    );
    assert_eq!(
        ring, before,
        "overflow preflight must not partially publish slots before failing"
    );
}

#[test]
fn normal_slot_respects_wire_arg_budget() {
    let mut ring = Megakernel::try_encode_empty_ring(1).unwrap();
    let slot = SlotDescriptor::single(
        0,
        SlotOpcode::Builtin(BuiltinOpcode::Memcpy),
        vec![0; ARGS_PER_SLOT as usize + 1],
    );
    let err = slot.publish_into(&mut ring, 0).unwrap_err();
    assert!(matches!(err, PipelineError::QueueFull { .. }));
}

#[test]
fn window_descriptor_publishes_required_then_lookahead() {
    let mut ring = Megakernel::try_encode_empty_ring(4).unwrap();
    let window = WindowDescriptor::new(
        1,
        5,
        SlotOpcode::Custom(0xF101),
        77,
        vec![vec![17], vec![42]],
        vec![vec![99]],
    );
    let consumed = window.publish_into(&mut ring).unwrap();
    assert_eq!(consumed, 3);
    assert_eq!(read_word(&ring, 1, STATUS_WORD), slot::PUBLISHED);
    assert_eq!(read_word(&ring, 2, STATUS_WORD), slot::PUBLISHED);
    assert_eq!(read_word(&ring, 3, STATUS_WORD), slot::PUBLISHED);
    assert_eq!(read_word(&ring, 1, protocol::ARG0_WORD), 77);
    assert_eq!(
        read_word(&ring, 1, protocol::ARG0_WORD + 1),
        WindowClass::Required.into_wire()
    );
    assert_eq!(
        read_word(&ring, 3, protocol::ARG0_WORD + 1),
        WindowClass::Lookahead.into_wire()
    );
}

#[test]
fn window_publish_rejects_overflow_before_publication() {
    let mut ring = Megakernel::try_encode_empty_ring(2).unwrap();
    let before = ring.clone();
    let window = WindowDescriptor::new(
        u32::MAX,
        5,
        SlotOpcode::Builtin(BuiltinOpcode::Nop),
        77,
        vec![vec![], vec![]],
        vec![],
    );
    let err = window.publish_into(&mut ring).unwrap_err();
    assert!(
        err.to_string().contains("overflows u32"),
        "overflowing window must fail with an actionable message: {err}"
    );
    assert_eq!(ring, before);
}

#[test]
fn window_publish_rejects_oversized_payload_before_publication() {
    let mut ring = Megakernel::try_encode_empty_ring(2).unwrap();
    let before = ring.clone();
    let window = WindowDescriptor::new(
        0,
        5,
        SlotOpcode::Builtin(BuiltinOpcode::Nop),
        77,
        vec![vec![0; ARGS_PER_SLOT as usize]],
        vec![],
    );
    let err = window.publish_into(&mut ring).unwrap_err();
    assert!(
        err.to_string().contains("too many args"),
        "oversized window payload must fail with an actionable message: {err}"
    );
    assert_eq!(ring, before);
}