SNAPKITTYWEST's picture
Relicense under the Sovereign Leviathan covenant; remove MIT and Apache
29f097e verified
|
Raw History Blame Contribute Delete
11.4 kB

NraayTensor Hardware Implementation Layer

Rust hardware layer for NraayTensor with explicit state transitions, generation-based safety, and fail-closed validation.

Overview

This crate implements the core hardware tensor primitives for the NraayTensor system:

  • Buffer management with generation counters and Arc-based ownership
  • Ownership state machine (B_layout, B_own) with explicit transitions
  • Memory address calculation with stride handling for multi-dimensional indexing
  • Tensor views and slicing (zero-copy Arc::clone, never copy data)
  • Materialization barrier (transactional copy-on-write with source preservation)
  • Hardware-safe C-compatible descriptors (#[repr(C)] for FFI)
  • Governance state engine with fail-closed validation gates
  • Sparse work-stealing scheduler (RAW_ROUTE with memory locality heuristic)

Core Principles

1. Explicit State Transitions

Every operation transitions ownership and governance state through a documented state machine:

  • VIEW → (shared, canonical or non-canonical)
  • SLICE → (shared, non-canonical)
  • MATERIALIZE → (exclusive, canonical) with new buffer
  • TRANSPOSE → (non-canonical strides)

2. Generation Counter Safety

Each buffer has a generation counter that increments on allocation/materialization:

  • Prevents use-after-free via stale descriptor detection
  • Every view holds buffer_id + generation
  • Operations validate generation match before access

3. Fail-Closed Validation

All operations validate preconditions before modifying state:

  • Bounds checking on all indices
  • Mutability checks (exclusive owner only)
  • Stale generation rejection
  • No partial state application on error

4. No Hidden Ownership Changes

All ownership transitions are explicit:

  • VIEW always returns shared (B_own: 1 → 0)
  • Arc::clone is transparent (no hidden increments)
  • Refcount checked to enforce exclusivity

Architecture

Modules

Module Purpose LOC
buffer.rs Buffer allocation, generation counters, Arc ownership 180
ownership.rs State machine (B_layout, B_own) with transitions 240
memory.rs Address calculation, stride handling, MemoryLayout 310
view.rs Tensor views, slicing, transpose, reshape (zero-copy) 320
materialize.rs Transactional materialization (read→alloc→copy→install) 290
descriptor.rs C-compatible #[repr(C)] TensorDescriptor 280
governance.rs Validation gates for all operations 310
routing.rs RAW_ROUTE sparse work-stealing scheduler 380
error.rs Fail-closed error types 50
lib.rs Core TensorHardware API & integration 200
Total 2,560

API Reference

Tensor Hardware Context

pub struct TensorHardware {
    validator: GovernanceValidator,
    materializer: MaterializationBarrier,
    router: SparseRouter,
}

impl TensorHardware {
    pub fn allocate(&mut self, shape: Vec<usize>) -> Result<(Buffer, TensorView)>;
    pub fn create_view(&mut self, view: &TensorView, buffer: &Buffer) -> Result<TensorView>;
    pub fn slice(&mut self, view: &TensorView, buffer: &Buffer, 
                 ranges: &[(usize, usize, usize)]) -> Result<TensorView>;
    pub fn transpose(&mut self, view: &TensorView, buffer: &Buffer, 
                     permutation: &[usize]) -> Result<TensorView>;
    pub fn reshape(&mut self, view: &TensorView, buffer: &Buffer, 
                   new_shape: Vec<usize>) -> Result<TensorView>;
    pub fn materialize(&mut self, view: &TensorView, 
                       buffer: &Buffer) -> Result<MaterializationResult>;
    pub fn get(&mut self, view: &TensorView, buffer: &Buffer, 
               indices: &[usize]) -> Result<f32>;
    pub fn set(&mut self, view: &TensorView, buffer: &Buffer, 
               indices: &[usize], value: f32) -> Result<()>;
    pub fn release(&mut self, view: &TensorView, buffer: &Buffer) -> Result<()>;
}

Buffer Management

pub struct Buffer {
    data: Arc<Vec<f32>>,
    generation: u64,
    id: u64,
    is_owner: bool,
}

impl Buffer {
    pub fn allocate(id: u64, size: usize) -> Result<Self>;
    pub fn strong_count(&self) -> usize;
    pub fn is_exclusive(&self) -> bool;
    pub fn validate_generation(&self, gen: u64) -> Result<()>;
    pub fn check_mutable(&self) -> Result<()>;
}

Ownership State Machine

pub struct OwnershipToken {
    pub is_owner: bool,      // B_own: 1 = exclusive, 0 = shared
    pub is_canonical: bool,  // B_layout: 1 = canonical, 0 = non-canonical
    pub version: u32,        // State transition counter
}

impl OwnershipToken {
    pub fn new_exclusive() -> Self;
    pub fn transition_to_shared(&self) -> Result<Self>;
    pub fn transition_to_non_canonical(&self) -> Result<Self>;
    pub fn transition_to_materialized(&self) -> Result<Self>;
    pub fn can_mutate_directly(&self) -> bool;
    pub fn needs_materialization(&self) -> bool;
}

Tensor Views

pub struct TensorView {
    buffer_handle: BufferHandle,
    shape: Vec<usize>,
    strides: Vec<usize>,
    offset: usize,
    ownership: OwnershipToken,
}

impl TensorView {
    pub fn from_buffer(buffer: &Buffer, layout: MemoryLayout) -> Self;
    pub fn share(&self) -> Result<Self>;
    pub fn slice(&self, ranges: &[(usize, usize, usize)]) -> Result<Self>;
    pub fn transpose(&self, permutation: &[usize]) -> Result<Self>;
    pub fn reshape(&self, new_shape: Vec<usize>) -> Result<Self>;
    pub fn address_for(&self, indices: &[usize]) -> Result<usize>;
}

Materialization

pub struct MaterializationBarrier;

impl MaterializationBarrier {
    pub fn materialize(&mut self, view: &TensorView, 
                       buffer: &Buffer) -> Result<MaterializationResult>;
}

pub struct MaterializationResult {
    pub new_buffer: Buffer,
    pub new_view: TensorView,
    pub source_buffer_id: u64,
}

Hardware Descriptor

#[repr(C)]
pub struct TensorDescriptor {
    pub buffer_id: u64,
    pub offset: u64,
    pub rank: u32,
    pub element_count: u64,
    pub shape_ptr: u64,
    pub stride_ptr: u64,
    pub ownership: u8,      // OwnershipCode
    pub governance: u8,     // GovernanceCode
    pub materialization: u8, // MaterializationCode
    pub generation: u64,
}

Governance Validation

pub struct GovernanceValidator;

impl GovernanceValidator {
    pub fn validate_view(&mut self, view: &TensorView, buffer: &Buffer) -> Result<()>;
    pub fn validate_access(&mut self, view: &TensorView, buffer: &Buffer, 
                          indices: &[usize], is_write: bool) -> Result<()>;
    pub fn validate_slice(&mut self, view: &TensorView, 
                         ranges: &[(usize, usize, usize)]) -> Result<()>;
    pub fn validate_materialize(&mut self, view: &TensorView, 
                                buffer: &Buffer) -> Result<()>;
}

Work-Stealing Router

pub struct SparseRouter;

impl SparseRouter {
    pub fn new() -> Self;
    pub fn register_worker(&mut self, id: WorkerId, locality_distance: f32);
    pub fn route(&mut self, task: &Task) -> WorkerId;
    pub fn region_owner(&self, region: RegionId) -> Option<WorkerId>;
}

pub struct Task {
    pub id: u64,
    pub region: RegionId,
    pub size: usize,
}

Usage Examples

Allocate and Access Elements

let mut hw = TensorHardware::new();

// Allocate exclusive, canonical 10x10 tensor
let (buffer, view) = hw.allocate(vec![10, 10])?;

// Set element (requires exclusive ownership)
hw.set(&view, &buffer, &[2, 3], 42.0)?;

// Get element (read-only, allowed on shared too)
let val = hw.get(&view, &buffer, &[2, 3])?;
assert_eq!(val, 42.0);

Create Shared Views (Zero-Copy)

// Create shared view (Arc::clone, no data copy)
let shared = hw.create_view(&view, &buffer)?;

// Can read from shared
let val = hw.get(&shared, &buffer, &[2, 3])?;

// Cannot write to shared
hw.set(&shared, &buffer, &[2, 3], 50.0)?; // ❌ Err(SharedTensorMutation)

Slicing (Non-Destructive)

// Slice [2:5, 3:7] (creates shared view with new shape)
let sliced = hw.slice(&view, &buffer, &[(2, 5, 1), (3, 7, 1)])?;

// New shape, same data
assert_eq!(sliced.shape, vec![3, 4]);

// Source tensor unchanged
assert!(view.is_exclusive());

Transpose (Non-Canonical Strides)

// Transpose swaps dimensions → non-canonical strides
let transposed = hw.transpose(&view, &buffer, &[1, 0])?;

// Cannot directly access (non-canonical)
assert!(!transposed.is_contiguous());

// Needs materialization to make canonical

Materialization (Transactional Copy-On-Write)

// Materialize non-canonical to contiguous buffer
let result = hw.materialize(&transposed, &buffer)?;

// New buffer is exclusive and canonical
assert!(result.new_view.is_exclusive());
assert!(result.new_view.is_contiguous());

// Original buffer still valid
assert!(buffer.is_exclusive());

Governance Validation

let mut validator = GovernanceValidator::new();

// Validate view against buffer
validator.validate_view(&view, &buffer)?;

// Validate element access
validator.validate_access(&view, &buffer, &[0, 0], true)?;

// Get operation sequence
let ops = validator.sequence();

Work-Stealing Scheduling

let mut router = SparseRouter::new();

// Register workers
router.register_worker(WorkerId(0), 0.5);  // close
router.register_worker(WorkerId(1), 1.5);  // far

// Route task to best worker
let task = Task {
    id: 1,
    region: RegionId(100),
    size: 1024,
};

let worker = router.route(&task);

// Same region tasks go to same worker (locality)
let task2 = Task { id: 2, region: RegionId(100), size: 512 };
assert_eq!(router.route(&task2), worker);

Testing

All 49 unit tests pass:

cargo test --lib

Test coverage:

  • Buffer allocation and generation
  • Ownership state transitions
  • Memory address calculation
  • View creation and slicing
  • Materialization workflow
  • Governance validation
  • Error handling (fail-closed)
  • Routing and scheduling

Performance Characteristics

  • Allocation: O(n) where n = element count
  • View/Slice: O(rank) - no data copy
  • Address calculation: O(rank)
  • Materialize: O(n) - single sequential pass
  • Element access: O(1) after bounds validation

Safety Model

  1. Generation Counter: Stale descriptor detection
  2. Arc Reference Counting: Exclusive ownership enforcement
  3. Bounds Checking: All indices validated before access
  4. Fail-Closed Validation: No partial state on error
  5. Type Safety: Rust's type system + explicit ownership tokens

FFI Compatibility

The descriptor (#[repr(C)]) is compatible with:

  • Pascal (Free Pascal FFI)
  • C/C++ bindings
  • Hardware interfaces (DMA, registers)

Size: 72 bytes (64-bit aligned)

Dependencies

  • thiserror — Error type derivation
  • parking_lot — Parking lot mutex (optional)
  • atomic — Atomic types

License

Sovereign Leviathan covenant (LicenseRef-Sovereign-Leviathan-SL-AGPL3-001), AGPL-3.0 based

References

  • Architecture: Design Phase NraayTensor specification
  • Formal Verification: Kani proofs in ffi/sparse_router_kani.rs
  • FFI Contract: FFI_CONTRACT.md
  • Example Usage: examples/core_operations.rs