vyre-runtime 0.7.2

Persistent megakernel + io_uring zero-copy streaming runtime for vyre typed programs
Documentation
//! No CPU fallback wording  -  runtime-level contract.
//!
//! Guarantees that error messages and source code never imply a CPU
//! fallback path exists.

use vyre_runtime::resident_work_queue::{
    descriptor::{BatchDescriptor, BuiltinOpcode, SlotDescriptor, SlotOpcode},
    protocol, ResidentIoQueue, ResidentWorkQueue, IO_SLOT_COUNT,
};
use vyre_runtime::PipelineError;

fn assert_no_cpu_wording(err: &PipelineError) {
    let msg = err.to_string().to_lowercase();
    assert!(!msg.contains("cpu"), "error must never mention CPU: {msg}");
    assert!(
        !msg.contains("fallback"),
        "error must never mention fallback: {msg}"
    );
    assert!(
        !msg.contains("software"),
        "error must never imply software emulation: {msg}"
    );
}

#[test]
fn encoder_errors_never_suggest_cpu_fallback() {
    let too_many_slots = (u32::MAX / protocol::SLOT_WORDS) + 1;
    assert_no_cpu_wording(
        &ResidentWorkQueue::try_encode_empty_ring(too_many_slots).expect_err("must fail"),
    );

    assert_no_cpu_wording(
        &ResidentWorkQueue::try_encode_control(false, 1, u32::MAX).expect_err("must fail"),
    );

    assert_no_cpu_wording(
        &ResidentWorkQueue::try_encode_empty_debug_log(u32::MAX).expect_err("must fail"),
    );
}

#[test]
fn queue_full_errors_never_suggest_cpu_fallback() {
    let mut ring = ResidentWorkQueue::encode_empty_ring(1).unwrap();
    let err = ResidentWorkQueue::publish_slot(
        &mut ring,
        0,
        0,
        protocol::opcode::NOP,
        &[0u32; (protocol::ARGS_PER_SLOT + 1) as usize],
    )
    .expect_err("too many args must fail");
    assert_no_cpu_wording(&err);

    let err = ResidentIoQueue::new(0).expect_err("zero slots must fail");
    assert_no_cpu_wording(&err);

    let err = ResidentIoQueue::new(IO_SLOT_COUNT + 1).expect_err("oversized must fail");
    assert_no_cpu_wording(&err);
}

#[test]
fn batch_descriptor_errors_never_suggest_cpu_fallback() {
    let mut ring = ResidentWorkQueue::encode_empty_ring(1).unwrap();
    let batch = BatchDescriptor::new(
        0,
        vec![
            SlotDescriptor::single(0, SlotOpcode::Builtin(BuiltinOpcode::Nop), vec![]),
            SlotDescriptor::single(0, SlotOpcode::Builtin(BuiltinOpcode::Nop), vec![]),
        ],
    );
    let err = batch
        .publish_into(&mut ring)
        .expect_err("overflow must fail");
    assert_no_cpu_wording(&err);
}