v2: Initial clean branch with unit tests + CI/CD pipeline
- Started from ac75faa (initial E4B-MarkBase integration)
- Kept Sources/ (all engine code) + Package.swift + .gitignore
- Removed all ad-hoc tests, documentation, scripts, Python files
- Added Tests/00_Unit/ (MathTest, TokenizerTest, SamplerTest)
- Added .gitea/workflows/ci.yaml (build + unit tests + lint)
- Added Scripts/check_resources.sh (memory-aware test runner)
- Added Tests/Manifest.json (resource requirements for all tests)
- Focus: 4-bit quantized models only
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
import Foundation
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Dynamic Concurrency Controller
|
||||
// Automatically adjusts concurrency based on system resources
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
/// Memory statistics
|
||||
public struct MemoryStats {
|
||||
public let total: UInt64
|
||||
public let available: UInt64
|
||||
public let used: UInt64
|
||||
public let percentage: Double
|
||||
|
||||
public init(total: UInt64, available: UInt64, used: UInt64) {
|
||||
self.total = total
|
||||
self.available = available
|
||||
self.used = used
|
||||
self.percentage = total > 0 ? Double(used) / Double(total) : 0
|
||||
}
|
||||
}
|
||||
|
||||
/// Dynamic concurrency controller
|
||||
public actor DynamicConcurrencyController {
|
||||
private var currentMax: Int
|
||||
private let minConcurrency: Int
|
||||
private let maxConcurrency: Int
|
||||
private let modelMemoryEstimate: UInt64
|
||||
|
||||
/// Concurrency adjustment event
|
||||
public struct ConcurrencyEvent {
|
||||
public let timestamp: Date
|
||||
public let oldMax: Int
|
||||
public let newMax: Int
|
||||
public let reason: String
|
||||
}
|
||||
|
||||
/// Event handler
|
||||
public var onConcurrencyChange: ((ConcurrencyEvent) -> Void)?
|
||||
|
||||
public init(
|
||||
initialConcurrency: Int = 4,
|
||||
minConcurrency: Int = 1,
|
||||
maxConcurrency: Int = 16,
|
||||
modelMemoryEstimate: UInt64 = 9 * 1024 * 1024 * 1024 // 9GB for 12B
|
||||
) {
|
||||
self.currentMax = initialConcurrency
|
||||
self.minConcurrency = minConcurrency
|
||||
self.maxConcurrency = maxConcurrency
|
||||
self.modelMemoryEstimate = modelMemoryEstimate
|
||||
}
|
||||
|
||||
/// Get current max concurrency
|
||||
public func getCurrentMax() -> Int {
|
||||
return currentMax
|
||||
}
|
||||
|
||||
/// Adjust concurrency based on current memory
|
||||
@discardableResult
|
||||
public func adjust() -> ConcurrencyEvent? {
|
||||
let oldMax = currentMax
|
||||
|
||||
// Simplified: use available memory estimation
|
||||
// In production, you would use actual memory stats
|
||||
let recommendedConcurrency = 4 // Default for now
|
||||
|
||||
let newMax = max(minConcurrency, min(maxConcurrency, recommendedConcurrency))
|
||||
|
||||
if newMax != oldMax {
|
||||
let event = ConcurrencyEvent(
|
||||
timestamp: Date(),
|
||||
oldMax: oldMax,
|
||||
newMax: newMax,
|
||||
reason: "Automatic adjustment"
|
||||
)
|
||||
|
||||
currentMax = newMax
|
||||
onConcurrencyChange?(event)
|
||||
return event
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Get recommended concurrency for a given model size
|
||||
public static func recommendConcurrency(
|
||||
modelMemoryBytes: UInt64,
|
||||
totalMemory: UInt64,
|
||||
reservedMemory: UInt64 = 2 * 1024 * 1024 * 1024 // 2GB reserved
|
||||
) -> Int {
|
||||
let availableMemory = totalMemory - reservedMemory
|
||||
let concurrency = Int(availableMemory / modelMemoryBytes)
|
||||
return max(1, concurrency)
|
||||
}
|
||||
}
|
||||
|
||||
/// Memory monitor using system information
|
||||
public actor MemoryMonitor {
|
||||
public init() {}
|
||||
|
||||
/// Get current memory statistics (simplified)
|
||||
public func getStats() -> MemoryStats {
|
||||
// Simplified implementation
|
||||
return MemoryStats(
|
||||
total: 48 * 1024 * 1024 * 1024, // 48GB
|
||||
available: 32 * 1024 * 1024 * 1024, // 32GB
|
||||
used: 16 * 1024 * 1024 * 1024 // 16GB
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user