use crate::decision::Policy;
use crate::gpu::GpuPolicy;
use crate::math::MathMode;
use crate::error::{ArchXResult, ArchXError};
use crate::core::CoreEngine;
pub struct SovereignBuilder {
policy: Policy,
gpu_policy: GpuPolicy,
gpu_enabled: bool,
math_mode: MathMode,
max_threads: Option<usize>,
profiling: bool,
engine: &'static CoreEngine,
}
impl SovereignBuilder {
pub fn new() -> Self {
Self {
policy: Policy::Balanced,
gpu_policy: GpuPolicy::Adaptive,
gpu_enabled: true,
math_mode: MathMode::Balanced,
max_threads: None,
profiling: false,
engine: CoreEngine::global(),
}
}
pub fn with_policy(mut self, policy: Policy) -> Self {
self.policy = policy;
self.engine.scheduler.set_policy(policy);
self
}
pub fn with_gpu(mut self, policy: GpuPolicy) -> Self {
self.gpu_policy = policy;
self.gpu_enabled = policy != GpuPolicy::ForceCpu;
self.engine.scheduler.set_gpu_policy(policy);
self
}
pub fn enable_gpu(mut self, enabled: bool) -> Self {
self.gpu_enabled = enabled;
self
}
pub fn with_mode(mut self, mode: MathMode) -> Self {
self.math_mode = mode;
self
}
pub fn max_threads(mut self, count: usize) -> Self {
self.max_threads = Some(count);
self
}
pub fn profile(mut self, enabled: bool) -> Self {
self.profiling = enabled;
self
}
pub fn add(self, a: &[f32], b: &[f32], out: &mut [f32]) -> ArchXResult<()> {
if a.len() != b.len() || a.len() != out.len() {
return Err(ArchXError::InvalidInput("Slices must have identical lengths".to_string()));
}
self.pre_exec();
self.engine.engine.add(a, b, out, self.math_mode.into())
.map_err(|e| ArchXError::ExecutionError(e.to_string()))
}
pub fn sub(self, a: &[f32], b: &[f32], out: &mut [f32]) -> ArchXResult<()> {
if a.len() != b.len() || a.len() != out.len() {
return Err(ArchXError::InvalidInput("Slices must have identical lengths".to_string()));
}
self.pre_exec();
self.engine.engine.sub(a, b, out, self.math_mode.into())
.map_err(|e| ArchXError::ExecutionError(e.to_string()))
}
pub fn mul(self, a: &[f32], b: &[f32], out: &mut [f32]) -> ArchXResult<()> {
if a.len() != b.len() || a.len() != out.len() {
return Err(ArchXError::InvalidInput("Slices must have identical lengths".to_string()));
}
self.pre_exec();
self.engine.engine.mul(a, b, out, self.math_mode.into())
.map_err(|e| ArchXError::ExecutionError(e.to_string()))
}
pub fn dot(self, a: &[f32], b: &[f32]) -> ArchXResult<f32> {
if a.len() != b.len() {
return Err(ArchXError::InvalidInput("Slices must have identical lengths".to_string()));
}
self.pre_exec();
self.engine.engine.dot(a, b, self.math_mode.into())
.map_err(|e| ArchXError::ExecutionError(e.to_string()))
}
pub fn sum(self, a: &[f32]) -> ArchXResult<f32> {
self.pre_exec();
self.engine.engine.sum(a, self.math_mode.into())
.map_err(|e| ArchXError::ExecutionError(e.to_string()))
}
pub fn run<F, R>(self, f: F) -> R
where
F: FnOnce() -> R
{
self.pre_exec();
self.engine.scheduler.run(f).expect("Task execution failed")
}
fn pre_exec(&self) {
let state = self.engine.hardware.capture_state();
if self.profiling {
println!("[ArchX Core v3.0] Policy: {:?}, GPU: {:?}, Mode: {:?}, Memory: {} GB",
self.policy, self.gpu_policy, self.math_mode, state.available_memory_gb);
}
}
}