runmat-execution 0.6.2

Portable identities, handles, resource models, value payloads, and protocol contracts for RunMat execution
Documentation
use std::collections::BTreeSet;

use runmat_execution::{
    Digest, ExecutableComponentDescriptor, ExecutableComponentKind, ExecutableComponentPayload,
    ExecutableComponentRevisions, ExecutableEntrypointKind, ExecutableIdentity,
    ExecutableOptionalSection, ExecutableSectionSupport, ExecutableUnitEnvelope,
    ExecutableUnitManifest, ProgramEnvironment, ProgramRevision, SectionRequirement,
    EXECUTABLE_UNIT_SCHEMA_VERSION,
};
use runmat_types::{
    CapabilityRequirement, CapabilitySet, ForeignAffinity, ForeignCapability, ForeignLifetime,
    ForeignOwnership, ForeignRequirement, ForeignTypeIdentity, InteropManifest, LabCount,
    ParallelAccess, ParallelManifest, ParallelRandomnessPolicy, ParallelRegionId,
    ParallelVariableContract, ParallelVariableRole, ParforContract, ProgramFunctionId,
    ProgramPointId, ProgramSourceId, ProgramSpan, RegionContract, RegionId, RegionProvenance,
    RegionValueId, SpmdContract, SpmdLabRequirement, ValueFact, ValueKindFact, WasmInteropPolicy,
    INTEROP_MANIFEST_SCHEMA_VERSION, PARALLEL_MANIFEST_SCHEMA_VERSION,
    REGION_CONTRACT_SCHEMA_VERSION,
};

fn program() -> ProgramRevision {
    ProgramRevision::new(
        Digest::sha256(b"graph"),
        Digest::sha256(b"sources"),
        ProgramEnvironment::new(
            1,
            1,
            Digest::sha256(b"runtime"),
            Digest::sha256(b"catalog"),
            "matlab",
        )
        .unwrap(),
    )
    .unwrap()
}

fn region(ordinal: u32) -> RegionContract {
    let function = ProgramFunctionId(0);
    RegionContract {
        schema_version: REGION_CONTRACT_SCHEMA_VERSION,
        id: RegionId { function, ordinal },
        source: ProgramSourceId(0),
        span: ProgramSpan {
            start: u64::from(ordinal),
            end: u64::from(ordinal) + 1,
        },
        entry: ProgramPointId {
            function,
            block: ordinal,
            position: 0,
        },
        exits: Vec::new(),
        live_in: Vec::new(),
        live_out: Vec::new(),
        value_facts: Vec::new(),
        effects: Default::default(),
        capabilities: Default::default(),
        guards: Vec::new(),
        provenance: RegionProvenance::Inferred,
    }
}

fn manifest() -> ExecutableUnitManifest {
    let program = program();
    let catalog_fingerprint = *program.catalog_fingerprint();
    let parfor = ParallelRegionId(RegionId {
        function: ProgramFunctionId(0),
        ordinal: 1,
    });
    let spmd = ParallelRegionId(RegionId {
        function: ProgramFunctionId(0),
        ordinal: 2,
    });
    let loop_variable = RegionValueId {
        function: ProgramFunctionId(0),
        local: 0,
    };
    let revisions = ExecutableComponentRevisions {
        catalog_schema: 1,
        catalog_fingerprint,
        contract_schema: 1,
        contract_fingerprint: Digest::sha256(b"contracts"),
        analysis_schema: 1,
        mir_schema: 1,
        bytecode_schema: 1,
        vm_layout_schema: 1,
        function_registry_schema: 1,
        source_map_schema: 1,
        region_schema: REGION_CONTRACT_SCHEMA_VERSION,
        interop_schema: INTEROP_MANIFEST_SCHEMA_VERSION,
        parallel_schema: PARALLEL_MANIFEST_SCHEMA_VERSION,
    };
    let components = component_payloads()
        .iter()
        .map(|payload| {
            ExecutableComponentDescriptor::from_payload(payload.kind, 1, &payload.bytes).unwrap()
        })
        .collect();
    ExecutableUnitManifest {
        schema_version: EXECUTABLE_UNIT_SCHEMA_VERSION,
        identity: ExecutableIdentity {
            program,
            root_package: "example@1.0.0".into(),
            entrypoint: "main".into(),
            entrypoint_function: ProgramFunctionId(0),
            entrypoint_kind: ExecutableEntrypointKind::Function,
            source_digest: Digest::sha256(b"main.m"),
        },
        revisions,
        components,
        capabilities: CapabilitySet(BTreeSet::from([
            CapabilityRequirement::ForeignRuntime,
            CapabilityRequirement::ParallelRuntime,
            CapabilityRequirement::DistributedRuntime,
        ])),
        regions: vec![region(1), region(2)],
        interop: InteropManifest {
            schema_version: INTEROP_MANIFEST_SCHEMA_VERSION,
            foreign_types: vec![ForeignRequirement {
                type_identity: ForeignTypeIdentity {
                    family: "java".into(),
                    name: "java.lang.Object".into(),
                    version: 1,
                },
                ownership: ForeignOwnership::Shared,
                affinity: ForeignAffinity::OriginProcess,
                lifetime: ForeignLifetime::Session,
                capabilities: vec![ForeignCapability::Invoke],
                wasm: WasmInteropPolicy::HostBridge,
            }],
            adapters: Vec::new(),
        },
        parallel: ParallelManifest {
            schema_version: PARALLEL_MANIFEST_SCHEMA_VERSION,
            parfor_regions: vec![ParforContract {
                id: parfor,
                loop_variable,
                iterable: ValueFact::unknown(runmat_types::DynamicReason::RuntimeValue),
                variables: vec![ParallelVariableContract {
                    value: loop_variable,
                    role: ParallelVariableRole::Loop,
                    access: ParallelAccess::ReadWrite,
                    fact: ValueFact::scalar(ValueKindFact::Logical),
                    transferable: true,
                }],
                maximum_workers: Some(LabCount(4)),
                capabilities: Default::default(),
                randomness: ParallelRandomnessPolicy::DeterministicSubstreams,
            }],
            spmd_regions: vec![SpmdContract {
                id: spmd,
                labs: SpmdLabRequirement::Range {
                    minimum: LabCount(1),
                    maximum: LabCount(4),
                },
                captures: Vec::new(),
                capabilities: Default::default(),
            }],
            distributed_values: Vec::new(),
            collectives: Vec::new(),
        },
        optional_sections: vec![ExecutableOptionalSection::new(
            "runmat.profile",
            1,
            SectionRequirement::Optional,
            b"profile-v1".to_vec(),
        )],
    }
}

fn component_payloads() -> Vec<ExecutableComponentPayload> {
    ExecutableComponentKind::REQUIRED
        .into_iter()
        .map(|kind| {
            ExecutableComponentPayload::new(kind, format!("{kind:?}-v1").into_bytes()).unwrap()
        })
        .collect()
}

fn round_trip_vector() {
    let manifest = manifest();
    manifest.validate().unwrap();
    let bytes = manifest.canonical_bytes().unwrap();
    assert_eq!(
        ExecutableUnitManifest::from_canonical_bytes(&bytes).unwrap(),
        manifest
    );
    assert_eq!(manifest.cache_key().unwrap(), Digest::sha256(&bytes));
}

#[test]
fn executable_manifest_round_trips_all_contract_families() {
    round_trip_vector();
    assert_eq!(
        manifest().cache_key().unwrap().to_string(),
        "sha256:f19f3e2aab64c58611c48210de564e6b9a2d275a4d4b96c5285ac636efa00c7f"
    );
}

#[test]
fn complete_envelope_round_trips_and_binds_every_payload() {
    let envelope = ExecutableUnitEnvelope::new(manifest(), component_payloads()).unwrap();
    let bytes = envelope.canonical_bytes().unwrap();
    assert_eq!(
        ExecutableUnitEnvelope::from_canonical_bytes(&bytes).unwrap(),
        envelope
    );
    assert_eq!(envelope.cache_key().unwrap(), Digest::sha256(bytes));

    let mut tampered = envelope.clone();
    tampered.payloads[0].bytes.push(0);
    assert!(tampered.validate().is_err());

    let mut reordered = envelope;
    reordered.payloads.swap(0, 1);
    assert!(reordered.validate().is_err());
}

#[test]
fn manifest_requires_each_component_once_with_matching_schema() {
    let mut missing = manifest();
    missing.components.pop();
    assert!(missing.validate().is_err());

    let mut reordered = manifest();
    reordered.components.swap(0, 1);
    assert!(reordered.validate().is_err());

    let mut wrong_schema = manifest();
    wrong_schema.components[0].schema_version += 1;
    assert!(wrong_schema.validate().is_err());
}

#[test]
fn optional_sections_are_preserved_but_required_sections_need_support() {
    let mut manifest = manifest();
    let unsupported = ExecutableSectionSupport::default();
    manifest.validate_for(&unsupported).unwrap();

    manifest.optional_sections[0].requirement = SectionRequirement::Required;
    assert!(manifest.validate_for(&unsupported).is_err());
    let supported = ExecutableSectionSupport::new([("runmat.profile".to_string(), 1)]).unwrap();
    manifest.validate_for(&supported).unwrap();
}

#[test]
fn versions_capabilities_digests_and_cache_inputs_are_enforced() {
    let baseline = manifest();
    let baseline_key = baseline.cache_key().unwrap();

    let mut changed = baseline.clone();
    changed.revisions.contract_fingerprint = Digest::sha256(b"contracts-v2");
    assert_ne!(changed.cache_key().unwrap(), baseline_key);

    let mut wrong_version = baseline.clone();
    wrong_version.schema_version += 1;
    assert!(wrong_version.validate().is_err());

    let mut missing_capability = baseline.clone();
    missing_capability
        .capabilities
        .0
        .remove(&CapabilityRequirement::ForeignRuntime);
    assert!(missing_capability.validate().is_err());

    let mut tampered = baseline;
    tampered.optional_sections[0].payload.push(0);
    assert!(tampered.validate().is_err());
}

#[test]
fn decoder_rejects_unknown_core_fields_and_noncanonical_json() {
    let bytes = manifest().canonical_bytes().unwrap();
    let mut value = serde_json::from_slice::<serde_json::Value>(&bytes).unwrap();
    value["future_core_field"] = serde_json::json!(true);
    assert!(serde_json::from_value::<ExecutableUnitManifest>(value).is_err());

    let mut nested_program = serde_json::from_slice::<serde_json::Value>(&bytes).unwrap();
    nested_program["identity"]["program"]["future_program_field"] = serde_json::json!(true);
    assert!(serde_json::from_value::<ExecutableUnitManifest>(nested_program).is_err());

    let mut nested_contract = serde_json::from_slice::<serde_json::Value>(&bytes).unwrap();
    nested_contract["regions"][0]["span"]["future_span_field"] = serde_json::json!(true);
    assert!(serde_json::from_value::<ExecutableUnitManifest>(nested_contract).is_err());

    let mut noncanonical = bytes;
    noncanonical.push(b'\n');
    assert!(ExecutableUnitManifest::from_canonical_bytes(&noncanonical).is_err());
}

#[cfg(target_arch = "wasm32")]
#[wasm_bindgen_test::wasm_bindgen_test]
fn wasm_uses_the_same_executable_manifest_vector() {
    round_trip_vector();
}