mirror of
https://github.com/ruvnet/RuView
synced 2026-08-05 19:41:44 +00:00
d803bfe2b1
git-subtree-dir: vendor/ruvector git-subtree-split: b64c21726f2bb37286d9ee36a7869fef60cc6900
353 lines
10 KiB
Rust
353 lines
10 KiB
Rust
//! iOS Capability Detection & Optimization Module
|
|
//!
|
|
//! Provides runtime detection of iOS-specific features and optimization hints.
|
|
//! Works with both WasmKit native and Safari WebAssembly runtimes.
|
|
|
|
// ============================================
|
|
// Capability Flags
|
|
// ============================================
|
|
|
|
/// iOS device capability flags (bit flags)
|
|
#[repr(u32)]
|
|
pub enum Capability {
|
|
/// WASM SIMD128 support (iOS 16.4+)
|
|
Simd128 = 1 << 0,
|
|
/// Bulk memory operations
|
|
BulkMemory = 1 << 1,
|
|
/// Mutable globals
|
|
MutableGlobals = 1 << 2,
|
|
/// Reference types
|
|
ReferenceTypes = 1 << 3,
|
|
/// Multi-value returns
|
|
MultiValue = 1 << 4,
|
|
/// Tail call optimization
|
|
TailCall = 1 << 5,
|
|
/// Relaxed SIMD (iOS 17+)
|
|
RelaxedSimd = 1 << 6,
|
|
/// Exception handling
|
|
ExceptionHandling = 1 << 7,
|
|
/// Memory64 (large memory)
|
|
Memory64 = 1 << 8,
|
|
/// Threads (SharedArrayBuffer)
|
|
Threads = 1 << 9,
|
|
}
|
|
|
|
/// Runtime capabilities structure
|
|
#[derive(Clone, Debug, Default)]
|
|
pub struct RuntimeCapabilities {
|
|
/// Bitfield of supported capabilities
|
|
pub flags: u32,
|
|
/// Estimated CPU cores (for parallelism hints)
|
|
pub cpu_cores: u8,
|
|
/// Available memory in MB
|
|
pub memory_mb: u32,
|
|
/// Device generation hint (A11=11, A12=12, etc.)
|
|
pub device_gen: u8,
|
|
/// iOS version major (16, 17, etc.)
|
|
pub ios_version: u8,
|
|
}
|
|
|
|
impl RuntimeCapabilities {
|
|
/// Check if a capability is available
|
|
#[inline]
|
|
pub fn has(&self, cap: Capability) -> bool {
|
|
(self.flags & (cap as u32)) != 0
|
|
}
|
|
|
|
/// Check if SIMD is available
|
|
#[inline]
|
|
pub fn has_simd(&self) -> bool {
|
|
self.has(Capability::Simd128)
|
|
}
|
|
|
|
/// Check if relaxed SIMD is available (FMA, etc.)
|
|
#[inline]
|
|
pub fn has_relaxed_simd(&self) -> bool {
|
|
self.has(Capability::RelaxedSimd)
|
|
}
|
|
|
|
/// Check if threading is available
|
|
#[inline]
|
|
pub fn has_threads(&self) -> bool {
|
|
self.has(Capability::Threads)
|
|
}
|
|
|
|
/// Get recommended batch size for operations
|
|
#[inline]
|
|
pub fn recommended_batch_size(&self) -> usize {
|
|
if self.has_simd() {
|
|
if self.device_gen >= 15 { 256 } // A15+ (iPhone 13+)
|
|
else if self.device_gen >= 13 { 128 } // A13-A14
|
|
else { 64 } // A11-A12
|
|
} else {
|
|
32 // Fallback
|
|
}
|
|
}
|
|
|
|
/// Get recommended embedding cache size
|
|
#[inline]
|
|
pub fn recommended_cache_size(&self) -> usize {
|
|
let base = if self.memory_mb >= 4096 { 1000 } // 4GB+ devices
|
|
else if self.memory_mb >= 2048 { 500 }
|
|
else { 100 };
|
|
base
|
|
}
|
|
}
|
|
|
|
// ============================================
|
|
// Compile-time Detection
|
|
// ============================================
|
|
|
|
/// Detect capabilities at compile time
|
|
pub const fn compile_time_capabilities() -> u32 {
|
|
let mut flags = 0u32;
|
|
|
|
// SIMD128
|
|
if cfg!(target_feature = "simd128") {
|
|
flags |= Capability::Simd128 as u32;
|
|
}
|
|
|
|
// Bulk memory (always enabled in our build)
|
|
if cfg!(target_feature = "bulk-memory") {
|
|
flags |= Capability::BulkMemory as u32;
|
|
}
|
|
|
|
// Mutable globals (always enabled in our build)
|
|
if cfg!(target_feature = "mutable-globals") {
|
|
flags |= Capability::MutableGlobals as u32;
|
|
}
|
|
|
|
flags
|
|
}
|
|
|
|
/// Get compile-time capability report
|
|
#[no_mangle]
|
|
pub extern "C" fn get_compile_capabilities() -> u32 {
|
|
compile_time_capabilities()
|
|
}
|
|
|
|
// ============================================
|
|
// Optimization Strategies
|
|
// ============================================
|
|
|
|
/// Optimization strategy for different device tiers
|
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
#[repr(u8)]
|
|
pub enum OptimizationTier {
|
|
/// Minimal - older devices, focus on memory
|
|
Minimal = 0,
|
|
/// Balanced - mid-range devices
|
|
Balanced = 1,
|
|
/// Performance - high-end devices, maximize speed
|
|
Performance = 2,
|
|
/// Ultra - latest devices with all features
|
|
Ultra = 3,
|
|
}
|
|
|
|
impl OptimizationTier {
|
|
/// Determine tier from capabilities
|
|
pub fn from_capabilities(caps: &RuntimeCapabilities) -> Self {
|
|
if caps.device_gen >= 15 && caps.has_relaxed_simd() {
|
|
OptimizationTier::Ultra
|
|
} else if caps.device_gen >= 13 && caps.has_simd() {
|
|
OptimizationTier::Performance
|
|
} else if caps.has_simd() {
|
|
OptimizationTier::Balanced
|
|
} else {
|
|
OptimizationTier::Minimal
|
|
}
|
|
}
|
|
|
|
/// Get embedding dimension for this tier
|
|
pub fn embedding_dim(&self) -> usize {
|
|
match self {
|
|
OptimizationTier::Ultra => 128,
|
|
OptimizationTier::Performance => 64,
|
|
OptimizationTier::Balanced => 64,
|
|
OptimizationTier::Minimal => 32,
|
|
}
|
|
}
|
|
|
|
/// Get attention heads for this tier
|
|
pub fn attention_heads(&self) -> usize {
|
|
match self {
|
|
OptimizationTier::Ultra => 8,
|
|
OptimizationTier::Performance => 4,
|
|
OptimizationTier::Balanced => 4,
|
|
OptimizationTier::Minimal => 2,
|
|
}
|
|
}
|
|
|
|
/// Get Q-learning state buckets for this tier
|
|
pub fn state_buckets(&self) -> usize {
|
|
match self {
|
|
OptimizationTier::Ultra => 64,
|
|
OptimizationTier::Performance => 32,
|
|
OptimizationTier::Balanced => 16,
|
|
OptimizationTier::Minimal => 8,
|
|
}
|
|
}
|
|
}
|
|
|
|
// ============================================
|
|
// Memory Optimization
|
|
// ============================================
|
|
|
|
/// Memory pool configuration for iOS
|
|
#[derive(Clone, Debug)]
|
|
pub struct MemoryConfig {
|
|
/// Main pool size in bytes
|
|
pub main_pool_bytes: usize,
|
|
/// Embedding cache entries
|
|
pub cache_entries: usize,
|
|
/// History buffer size
|
|
pub history_size: usize,
|
|
/// Use memory-mapped I/O hint
|
|
pub use_mmap: bool,
|
|
}
|
|
|
|
impl MemoryConfig {
|
|
/// Create config for given optimization tier
|
|
pub fn for_tier(tier: OptimizationTier) -> Self {
|
|
match tier {
|
|
OptimizationTier::Ultra => Self {
|
|
main_pool_bytes: 4 * 1024 * 1024, // 4MB
|
|
cache_entries: 1000,
|
|
history_size: 200,
|
|
use_mmap: true,
|
|
},
|
|
OptimizationTier::Performance => Self {
|
|
main_pool_bytes: 2 * 1024 * 1024, // 2MB
|
|
cache_entries: 500,
|
|
history_size: 100,
|
|
use_mmap: true,
|
|
},
|
|
OptimizationTier::Balanced => Self {
|
|
main_pool_bytes: 1 * 1024 * 1024, // 1MB
|
|
cache_entries: 200,
|
|
history_size: 50,
|
|
use_mmap: false,
|
|
},
|
|
OptimizationTier::Minimal => Self {
|
|
main_pool_bytes: 512 * 1024, // 512KB
|
|
cache_entries: 100,
|
|
history_size: 25,
|
|
use_mmap: false,
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
// ============================================
|
|
// Swift Bridge Info
|
|
// ============================================
|
|
|
|
/// Information for Swift integration
|
|
#[repr(C)]
|
|
pub struct SwiftBridgeInfo {
|
|
/// WASM module version
|
|
pub version_major: u8,
|
|
pub version_minor: u8,
|
|
pub version_patch: u8,
|
|
/// Feature flags
|
|
pub feature_flags: u32,
|
|
/// Recommended embedding dimension
|
|
pub embedding_dim: u16,
|
|
/// Recommended batch size
|
|
pub batch_size: u16,
|
|
}
|
|
|
|
/// Get bridge info for Swift
|
|
#[no_mangle]
|
|
pub extern "C" fn get_bridge_info() -> SwiftBridgeInfo {
|
|
SwiftBridgeInfo {
|
|
version_major: 0,
|
|
version_minor: 1,
|
|
version_patch: 0,
|
|
feature_flags: compile_time_capabilities(),
|
|
embedding_dim: 64,
|
|
batch_size: if cfg!(target_feature = "simd128") { 128 } else { 32 },
|
|
}
|
|
}
|
|
|
|
// ============================================
|
|
// Neural Engine Offload Hints
|
|
// ============================================
|
|
|
|
/// Operations that could benefit from Neural Engine offload
|
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
#[repr(u8)]
|
|
pub enum NeuralEngineOp {
|
|
/// Batch embedding generation
|
|
BatchEmbed = 0,
|
|
/// Large matrix multiply (attention)
|
|
MatMul = 1,
|
|
/// Softmax over large sequences
|
|
Softmax = 2,
|
|
/// Similarity search over many vectors
|
|
BatchSimilarity = 3,
|
|
}
|
|
|
|
/// Check if operation should be offloaded to Neural Engine
|
|
pub fn should_offload_to_ane(op: NeuralEngineOp, size: usize) -> bool {
|
|
// Neural Engine is efficient for larger batch sizes
|
|
match op {
|
|
NeuralEngineOp::BatchEmbed => size >= 50,
|
|
NeuralEngineOp::MatMul => size >= 100,
|
|
NeuralEngineOp::Softmax => size >= 256,
|
|
NeuralEngineOp::BatchSimilarity => size >= 100,
|
|
}
|
|
}
|
|
|
|
// ============================================
|
|
// Performance Hints Export
|
|
// ============================================
|
|
|
|
/// Get recommended parameters for given device memory (MB)
|
|
#[no_mangle]
|
|
pub extern "C" fn get_recommended_config(memory_mb: u32) -> u64 {
|
|
// Pack config into u64: [cache_size:16][batch_size:16][dim:16][heads:16]
|
|
let (cache, batch, dim, heads) = if memory_mb >= 4096 {
|
|
(1000u16, 256u16, 128u16, 8u16)
|
|
} else if memory_mb >= 2048 {
|
|
(500u16, 128u16, 64u16, 4u16)
|
|
} else if memory_mb >= 1024 {
|
|
(200u16, 64u16, 64u16, 4u16)
|
|
} else {
|
|
(100u16, 32u16, 32u16, 2u16)
|
|
};
|
|
|
|
((cache as u64) << 48) | ((batch as u64) << 32) | ((dim as u64) << 16) | (heads as u64)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_compile_capabilities() {
|
|
let caps = compile_time_capabilities();
|
|
// Should have bulk memory and mutable globals at minimum
|
|
assert!(caps != 0 || !cfg!(target_feature = "bulk-memory"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_optimization_tier() {
|
|
let caps = RuntimeCapabilities {
|
|
flags: Capability::Simd128 as u32,
|
|
cpu_cores: 6,
|
|
memory_mb: 4096,
|
|
device_gen: 14,
|
|
ios_version: 17,
|
|
};
|
|
let tier = OptimizationTier::from_capabilities(&caps);
|
|
assert_eq!(tier, OptimizationTier::Performance);
|
|
}
|
|
|
|
#[test]
|
|
fn test_memory_config() {
|
|
let config = MemoryConfig::for_tier(OptimizationTier::Performance);
|
|
assert_eq!(config.cache_entries, 500);
|
|
}
|
|
}
|