Download rust/tensor-hw/FFI_CONTRACT.md from Snapkitty/sparse-router-formal: direct link, hf CLI and curl.
- Browser
- Download file 9.01 kB
-
https://huggingface.co/Snapkitty/sparse-router-formal/resolve/main/rust/tensor-hw/FFI_CONTRACT.md
- Command line
-
hf download hf://Snapkitty/sparse-router-formal/rust/tensor-hw/FFI_CONTRACT.md
-
curl -L -o FFI_CONTRACT.md https://huggingface.co/Snapkitty/sparse-router-formal/resolve/main/rust/tensor-hw/FFI_CONTRACT.md
NraayTensor FFI Contract
Overview
The FFI layer provides a C-compatible ABI that bridges:
- Rust
tensor.rs(production hardware layer) - Free Pascal (reference implementation & oracle)
- Formal verification (Kani proofs for correctness)
All operations are defined through a canonical binary protocol (tensor_abi.h) that both implementations must conform to.
Files
C ABI Definition
tensor_abi.hβ Canonical C-compatible tensor descriptor and operation signaturesTensorDescriptorC: packed struct with buffer identity, rank, governance, ownership, generation- Operations:
tensor_allocate,tensor_view,tensor_materialize,tensor_load,tensor_store, etc.
Rust Implementation
tensor_ffi.rsβ Rust FFI layer that wraps the realtensor.rsimplementation- Global registry (
TENSOR_REGISTRY) maps buffer IDs to actual tensor data - Arc-based ownership semantics are preserved through FFI boundary
- Every operation maps directly to tensor logic (no translation layer)
- Global registry (
Pascal Bindings
tensor_abi.pasβ Free Pascal FFI wrapper (calls into Rust via C ABI)- Pascal-idiomatic error handling with exception raising
- Thin wrappers around C FFI calls
- Same semantic contract as Rust
Sparse Router (Work-Stealing)
sparse_router.rsβ RAW_ROUTE algorithm for tensor task scheduling- Memory-locality-aware work stealing
- Region ownership tracking
- Topology-aware routing decisions
sparse_router_kani.rsβ Formal verification of router invariants- 8 proven theorems about routing correctness
- Kani proofs: all tasks routed, locality preserved, no deadlock, migration cost minimized
Conformance Testing
conformance_bridge.rsβ Cross-language validation harness- Rust tests that exercise the FFI
- Oracle functions for descriptor comparison
- Both Rust and Pascal implementations must produce identical results
Core Tensor Descriptor (ABI Contract)
typedef struct {
uint64_t buffer_id; /* Unique buffer identity */
uint64_t base_addr; /* Physical address */
uint64_t offset; /* Offset into buffer */
uint32_t rank; /* Tensor rank (# dimensions) */
uint64_t element_count; /* Total elements */
uint64_t shape_ptr; /* Pointer to shape array */
uint64_t stride_ptr; /* Pointer to stride array */
uint8_t governance; /* B: 0=shared, 1=canonical */
uint8_t ownership; /* OWNED/SHARED/EXCLUSIVE */
uint8_t materialized; /* 0=not, 1=materialized */
uint8_t state; /* Internal state */
uint64_t generation; /* Generation counter (stale detection) */
} tensor_descriptor_t;
Address Calculation (no framework overhead):
address = base + offset + Ξ£(index[i] * stride[i])
Ownership Semantics Through FFI
Allocation
tensor_allocate(rank, shape, element_size)
β TensorDescriptorC { buffer_id=N, generation=G, governance=1 (canonical) }
β Arc<Vec<f32>> created internally
View (Slice)
tensor_view(source, start_indices, end_indices)
β TensorDescriptorC { buffer_id=M (new), generation=G' }
β Arc::clone() increments refcount on source's data
β shape/stride/offset computed, data NOT copied
β is_contiguous recalculated
Materialization
tensor_materialize(source where is_contiguous=false)
β new Arc<Vec> allocated
β strided data copied to new contiguous buffer
β TensorDescriptorC { buffer_id=K (new), generation=G'', governance=1 }
β source buffer remains alive and valid
β ownership is exclusive on new buffer
Deallocation
tensor_deallocate(descriptor)
β Registry entry removed
β Arc is dropped
β if refcount reaches 0, buffer freed
Generation Counter Safety
Every buffer has a generation counter that increments on:
- Allocation β generation = 1
- Materialization β new buffer gets new generation
- Reallocation β if buffer is reassigned
Stale Descriptor Detection:
fn tensor_validate_generation(desc: &TensorDescriptorC) -> Result {
if registry[desc.buffer_id].generation != desc.generation {
return Err("StaleGeneration");
}
Ok(())
}
Prevents use-after-free and races on descriptor validity.
Governance State Machine
SHARED (B=0)
β
ββββββββ΄βββββββ
β β
MATERIALIZE VIEW/SLICE
β β
βΌ βΌ
EXCLUSIVE SHARED (B=0)
(B=1) β
β β
βββββββββββββββββ
Invariants:
B=0: shared view, non-canonical strides permitted, materialization availableB=1: exclusive owner, canonical strides, direct element access- Generation increments on every transition
- Invalid transitions β rejected with fail-closed error
Cross-Language Conformance
For every operation, both Rust and Pascal must produce:
- Identical shape (rank and dimensions)
- Identical strides (same canonical form)
- Identical offset
- Identical element values (same underlying data)
- Identical governance (B value)
- Identical generation (stale check)
- Identical buffer identity (whether shared or independent)
Oracle Function:
fn conformance_compare_descriptors(
rust: &TensorDescriptorC,
pascal: &TensorDescriptorC
) -> ConformanceResult { ... }
If Rust and Pascal produce different descriptors, conformance fails.
Sparse Router (RAW_ROUTE)
Algorithm
route(task):
r β task.memory_region
if RegionTable[r].owner exists:
push(task, Worker[owner].deque)
return owner
candidates β SparseTopology[r]
best β NONE
best_score β -β
for worker in candidates:
score β 0.35 * locality(worker, task)
+ 0.20 * memory_affinity(worker, task)
+ 0.25 * queue_pressure(worker)
+ 0.10 * stealability(worker)
- 0.10 * migration_cost(worker, task)
if score > best_score:
best β worker
best_score β score
if best != NONE:
push(task, Worker[best].deque)
RegionTable[r].owner β best
return best
worker β select_least_loaded_worker()
push(task, Worker[worker].deque)
RegionTable[r].owner β worker
return worker
Kani-Verified Theorems
- Progress: Every task is routed βt: βw such that route(t) = w
- Locality: Locality score dominates queue balance
- Region Consistency: Once region R β worker W, reused until unset
- Migration Cost: High-cost migrations are avoided over balance
- Fallback: Empty topology always assigns via least-loaded fallback
- No Deadlock: No circular region ownership
- Score Bounds: Score β [-1.0, 1.0]
- Stability: Route decisions remain valid until topology changes
Error Handling (Fail-Closed)
All FFI operations return TensorResultC:
typedef struct {
int32_t success; /* 1 = OK, 0 = error */
uint32_t error_code; /* machine-readable code */
char error_msg[256]; /* human-readable message */
} TensorResultC;
Error codes:
1: Invalid pointer or rank2: Zero-element shape3: Buffer not found in registry4: Indices out of bounds5: Stale generation6: Computed address out of bounds7: Shared tensor cannot be mutated
On error: operation is rejected, no partial state is applied.
Test Matrix
See ./tests/ffi/conformance_bridge.rs for comprehensive coverage:
test_allocate_conformsβ Allocation produces canonical descriptortest_view_preserves_data_and_bufferβ Views don't copy, source remains validtest_materialization_creates_new_bufferβ New buffer, source unmodifiedtest_generation_safetyβ Stale descriptors rejectedtest_bounds_checkingβ Out-of-bounds access failstest_shared_ownership_prevents_storeβ Arc refcount prevents mutation
Each test exercises both the Rust FFI and validates against Pascal oracle.
Integration
The FFI layer enables:
- Hardware execution: Tensor descriptors can be mapped directly to hardware registers/DMA
- Cross-language validation: Pascal reference model verifies Rust correctness
- Formal reasoning: Kani proves routing correctness, temporal safety, bounds
- Deterministic execution: No implicit copies, ownership explicit, all state transitions auditable
The FFI is the binary boundary between Rust hardware semantics and Pascal reference semantics. Both must conform to the same ABI contract.