Files
markbaseengine/Sources/MarkBaseServer/DynamicConcurrency.swift
T
MarkBase Admin 8a66b9086a
CI / build (push) Waiting to run
CI / unit-tests (push) Blocked by required conditions
CI / lint (push) Blocked by required conditions
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
2026-07-05 13:29:25 +08:00

111 lines
3.6 KiB
Swift

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
)
}
}