use crate::adaptive_compilation::OptimizationLevel;
use crate::{CompilationStrategy, ComputationGraph, JitError, JitResult};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc, RwLock,
};
pub struct HardwareTuner {
hardware_info: Arc<RwLock<HardwareInfo>>,
tuning_profiles: Arc<RwLock<HashMap<String, TuningProfile>>>,
auto_tuning_enabled: AtomicBool,
config: HardwareTuningConfig,
}
#[derive(Debug, Clone)]
pub struct HardwareTuningConfig {
pub enable_auto_detection: bool,
pub enable_arch_optimizations: bool,
pub enable_simd_optimizations: bool,
pub enable_cache_optimizations: bool,
pub enable_power_optimizations: bool,
pub enable_thermal_optimizations: bool,
pub tuning_aggressiveness: f64,
pub profile_cache_size: usize,
}
impl Default for HardwareTuningConfig {
fn default() -> Self {
Self {
enable_auto_detection: true,
enable_arch_optimizations: true,
enable_simd_optimizations: true,
enable_cache_optimizations: true,
enable_power_optimizations: true,
enable_thermal_optimizations: false, tuning_aggressiveness: 0.7,
profile_cache_size: 100,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HardwareInfo {
pub cpu_info: CpuInfo,
pub memory_info: MemoryInfo,
pub cache_info: CacheInfo,
pub simd_capabilities: SimdCapabilities,
pub power_info: PowerInfo,
pub thermal_info: ThermalInfo,
pub architecture: Architecture,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CpuInfo {
pub vendor: String,
pub model: String,
pub family: u32,
pub model_number: u32,
pub stepping: u32,
pub cores: usize,
pub logical_cores: usize,
pub base_frequency: u64, pub max_frequency: u64, pub features: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryInfo {
pub total_memory: usize, pub available_memory: usize, pub memory_bandwidth: u64, pub memory_latency: u32, pub numa_nodes: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheInfo {
pub l1_instruction_cache: CacheLevel,
pub l1_data_cache: CacheLevel,
pub l2_cache: CacheLevel,
pub l3_cache: Option<CacheLevel>,
pub l4_cache: Option<CacheLevel>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheLevel {
pub size: usize, pub associativity: usize,
pub line_size: usize, pub latency: u32, pub shared: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SimdCapabilities {
pub sse: bool,
pub sse2: bool,
pub sse3: bool,
pub ssse3: bool,
pub sse41: bool,
pub sse42: bool,
pub avx: bool,
pub avx2: bool,
pub avx512f: bool,
pub avx512dq: bool,
pub avx512vl: bool,
pub avx512bw: bool,
pub fma: bool,
pub neon: bool, pub sve: bool, pub vector_width: usize, }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PowerInfo {
pub max_power: f64, pub current_power: f64, pub power_limit: f64, pub energy_efficiency: f64, pub battery_powered: bool,
pub power_management_enabled: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ThermalInfo {
pub current_temperature: f64, pub max_temperature: f64, pub thermal_design_power: f64, pub thermal_throttling: bool,
pub cooling_solution: CoolingSolution,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum CoolingSolution {
Passive,
ActiveAir,
Liquid,
Custom,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Architecture {
X86_64,
X86,
Aarch64,
Arm,
Riscv64,
Wasm32,
Unknown,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TuningProfile {
pub name: String,
pub architecture: Architecture,
pub optimization_hints: HashMap<String, String>,
pub compilation_flags: Vec<String>,
pub simd_preferences: SimdPreferences,
pub cache_strategy: CacheStrategy,
pub power_strategy: PowerStrategy,
pub performance_characteristics: PerformanceCharacteristics,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SimdPreferences {
pub preferred_width: usize,
pub auto_vectorization: bool,
pub manual_vectorization: bool,
pub preferred_instructions: Vec<String>,
pub alignment_requirements: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheStrategy {
pub prefetch_strategy: PrefetchStrategy,
pub blocking_factor: usize,
pub cache_line_size: usize,
pub working_set_optimization: bool,
pub data_layout_optimization: bool,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum PrefetchStrategy {
None,
Conservative,
Aggressive,
Adaptive,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PowerStrategy {
pub frequency_scaling: bool,
pub core_parking: bool,
pub voltage_scaling: bool,
pub idle_optimization: bool,
pub energy_efficiency_priority: f64, }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceCharacteristics {
pub integer_throughput: f64, pub float_throughput: f64, pub memory_bandwidth_efficiency: f64, pub branch_prediction_accuracy: f64, pub cache_efficiency: f64, pub simd_efficiency: f64, }
#[derive(Debug, Clone)]
pub struct TuningRecommendation {
pub optimization_type: HardwareOptimizationType,
pub confidence: f64,
pub expected_improvement: f64,
pub implementation_cost: f64,
pub description: String,
pub parameters: HashMap<String, String>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum HardwareOptimizationType {
SimdVectorization,
CacheOptimization,
BranchOptimization,
MemoryPrefetching,
PowerOptimization,
ThermalOptimization,
InstructionSelection,
PipelineOptimization,
RegisterAllocation,
MemoryBandwidth,
}
impl HardwareTuner {
pub fn new(config: HardwareTuningConfig) -> JitResult<Self> {
let hardware_info = Self::detect_hardware()?;
let tuning_profiles = Self::initialize_profiles(&hardware_info)?;
Ok(Self {
hardware_info: Arc::new(RwLock::new(hardware_info)),
tuning_profiles: Arc::new(RwLock::new(tuning_profiles)),
auto_tuning_enabled: AtomicBool::new(config.enable_auto_detection),
config,
})
}
pub fn detect_hardware() -> JitResult<HardwareInfo> {
let cpu_info = Self::detect_cpu_info()?;
let memory_info = Self::detect_memory_info()?;
let cache_info = Self::detect_cache_info()?;
let simd_capabilities = Self::detect_simd_capabilities()?;
let power_info = Self::detect_power_info()?;
let thermal_info = Self::detect_thermal_info()?;
let architecture = Self::detect_architecture()?;
Ok(HardwareInfo {
cpu_info,
memory_info,
cache_info,
simd_capabilities,
power_info,
thermal_info,
architecture,
})
}
pub fn generate_tuning_recommendations(
&self,
graph: &ComputationGraph,
) -> JitResult<Vec<TuningRecommendation>> {
let hardware = self
.hardware_info
.read()
.map_err(|_| JitError::RuntimeError("Failed to read hardware info".to_string()))?;
let mut recommendations = Vec::new();
if self.config.enable_simd_optimizations {
recommendations.extend(self.analyze_simd_opportunities(graph, &hardware)?);
}
if self.config.enable_cache_optimizations {
recommendations.extend(self.analyze_cache_opportunities(graph, &hardware)?);
}
if self.config.enable_arch_optimizations {
recommendations.extend(self.analyze_architecture_opportunities(graph, &hardware)?);
}
if self.config.enable_power_optimizations {
recommendations.extend(self.analyze_power_opportunities(graph, &hardware)?);
}
if self.config.enable_thermal_optimizations {
recommendations.extend(self.analyze_thermal_opportunities(graph, &hardware)?);
}
recommendations.sort_by(|a, b| {
b.expected_improvement
.partial_cmp(&a.expected_improvement)
.unwrap_or(std::cmp::Ordering::Equal)
});
Ok(recommendations)
}
pub fn apply_hardware_optimizations(
&self,
strategy: &mut CompilationStrategy,
recommendations: &[TuningRecommendation],
) -> JitResult<usize> {
let mut applied_count = 0;
for recommendation in recommendations {
if recommendation.confidence < 0.6 {
continue; }
match recommendation.optimization_type {
HardwareOptimizationType::SimdVectorization => {
if self.apply_simd_optimization(strategy, recommendation)? {
applied_count += 1;
}
}
HardwareOptimizationType::CacheOptimization => {
if self.apply_cache_optimization(strategy, recommendation)? {
applied_count += 1;
}
}
HardwareOptimizationType::PowerOptimization => {
if self.apply_power_optimization(strategy, recommendation)? {
applied_count += 1;
}
}
HardwareOptimizationType::InstructionSelection => {
if self.apply_instruction_selection(strategy, recommendation)? {
applied_count += 1;
}
}
_ => {
}
}
}
Ok(applied_count)
}
pub fn get_hardware_info(&self) -> JitResult<HardwareInfo> {
let hardware = self
.hardware_info
.read()
.map_err(|_| JitError::RuntimeError("Failed to read hardware info".to_string()))?;
Ok(hardware.clone())
}
pub fn update_hardware_info(&self) -> JitResult<()> {
if self.auto_tuning_enabled.load(Ordering::Relaxed) {
let new_hardware_info = Self::detect_hardware()?;
if let Ok(mut hardware) = self.hardware_info.write() {
*hardware = new_hardware_info;
}
}
Ok(())
}
fn detect_cpu_info() -> JitResult<CpuInfo> {
Ok(CpuInfo {
vendor: std::env::consts::ARCH.to_string(),
model: "Generic".to_string(),
family: 0,
model_number: 0,
stepping: 0,
cores: num_cpus::get_physical(),
logical_cores: num_cpus::get(),
base_frequency: 2400, max_frequency: 3600, features: Self::detect_cpu_features(),
})
}
fn detect_cpu_features() -> Vec<String> {
#[cfg_attr(not(target_arch = "x86_64"), allow(unused_mut))]
let mut features = Vec::new();
#[cfg(target_arch = "x86_64")]
{
if is_x86_feature_detected!("sse") {
features.push("sse".to_string());
}
if is_x86_feature_detected!("sse2") {
features.push("sse2".to_string());
}
if is_x86_feature_detected!("sse3") {
features.push("sse3".to_string());
}
if is_x86_feature_detected!("ssse3") {
features.push("ssse3".to_string());
}
if is_x86_feature_detected!("sse4.1") {
features.push("sse4.1".to_string());
}
if is_x86_feature_detected!("sse4.2") {
features.push("sse4.2".to_string());
}
if is_x86_feature_detected!("avx") {
features.push("avx".to_string());
}
if is_x86_feature_detected!("avx2") {
features.push("avx2".to_string());
}
if is_x86_feature_detected!("fma") {
features.push("fma".to_string());
}
}
features
}
fn detect_memory_info() -> JitResult<MemoryInfo> {
Ok(MemoryInfo {
total_memory: 16 * 1024 * 1024 * 1024, available_memory: 8 * 1024 * 1024 * 1024, memory_bandwidth: 25600, memory_latency: 100, numa_nodes: 1,
})
}
fn detect_cache_info() -> JitResult<CacheInfo> {
Ok(CacheInfo {
l1_instruction_cache: CacheLevel {
size: 32 * 1024, associativity: 8,
line_size: 64,
latency: 4,
shared: false,
},
l1_data_cache: CacheLevel {
size: 32 * 1024, associativity: 8,
line_size: 64,
latency: 4,
shared: false,
},
l2_cache: CacheLevel {
size: 256 * 1024, associativity: 8,
line_size: 64,
latency: 12,
shared: false,
},
l3_cache: Some(CacheLevel {
size: 8 * 1024 * 1024, associativity: 16,
line_size: 64,
latency: 40,
shared: true,
}),
l4_cache: None,
})
}
fn detect_simd_capabilities() -> JitResult<SimdCapabilities> {
let mut capabilities = SimdCapabilities {
sse: false,
sse2: false,
sse3: false,
ssse3: false,
sse41: false,
sse42: false,
avx: false,
avx2: false,
avx512f: false,
avx512dq: false,
avx512vl: false,
avx512bw: false,
fma: false,
neon: false,
sve: false,
vector_width: 128, };
#[cfg(target_arch = "x86_64")]
{
capabilities.sse = is_x86_feature_detected!("sse");
capabilities.sse2 = is_x86_feature_detected!("sse2");
capabilities.sse3 = is_x86_feature_detected!("sse3");
capabilities.ssse3 = is_x86_feature_detected!("ssse3");
capabilities.sse41 = is_x86_feature_detected!("sse4.1");
capabilities.sse42 = is_x86_feature_detected!("sse4.2");
capabilities.avx = is_x86_feature_detected!("avx");
capabilities.avx2 = is_x86_feature_detected!("avx2");
capabilities.fma = is_x86_feature_detected!("fma");
if capabilities.avx2 {
capabilities.vector_width = 256;
} else if capabilities.avx {
capabilities.vector_width = 256;
} else if capabilities.sse2 {
capabilities.vector_width = 128;
}
}
#[cfg(target_arch = "aarch64")]
{
capabilities.neon = true; capabilities.vector_width = 128;
}
Ok(capabilities)
}
fn detect_power_info() -> JitResult<PowerInfo> {
Ok(PowerInfo {
max_power: 95.0, current_power: 35.0, power_limit: 95.0, energy_efficiency: 100.0, battery_powered: false,
power_management_enabled: true,
})
}
fn detect_thermal_info() -> JitResult<ThermalInfo> {
Ok(ThermalInfo {
current_temperature: 45.0, max_temperature: 85.0, thermal_design_power: 95.0, thermal_throttling: false,
cooling_solution: CoolingSolution::ActiveAir,
})
}
fn detect_architecture() -> JitResult<Architecture> {
match std::env::consts::ARCH {
"x86_64" => Ok(Architecture::X86_64),
"x86" => Ok(Architecture::X86),
"aarch64" => Ok(Architecture::Aarch64),
"arm" => Ok(Architecture::Arm),
"riscv64" => Ok(Architecture::Riscv64),
"wasm32" => Ok(Architecture::Wasm32),
_ => Ok(Architecture::Unknown),
}
}
fn initialize_profiles(hardware: &HardwareInfo) -> JitResult<HashMap<String, TuningProfile>> {
let mut profiles = HashMap::new();
let arch_profile = Self::create_architecture_profile(hardware)?;
profiles.insert(hardware.architecture.to_string(), arch_profile);
if hardware.simd_capabilities.avx2 {
let avx2_profile = Self::create_avx2_profile(hardware)?;
profiles.insert("avx2".to_string(), avx2_profile);
}
if hardware.simd_capabilities.avx {
let avx_profile = Self::create_avx_profile(hardware)?;
profiles.insert("avx".to_string(), avx_profile);
}
Ok(profiles)
}
fn create_architecture_profile(hardware: &HardwareInfo) -> JitResult<TuningProfile> {
let mut optimization_hints = HashMap::new();
let mut compilation_flags = Vec::new();
match hardware.architecture {
Architecture::X86_64 => {
optimization_hints.insert("target_arch".to_string(), "x86_64".to_string());
compilation_flags.push("-march=native".to_string());
compilation_flags.push("-mtune=native".to_string());
}
Architecture::Aarch64 => {
optimization_hints.insert("target_arch".to_string(), "aarch64".to_string());
compilation_flags.push("-march=native".to_string());
}
_ => {}
}
Ok(TuningProfile {
name: format!("{:?}_default", hardware.architecture),
architecture: hardware.architecture.clone(),
optimization_hints,
compilation_flags,
simd_preferences: SimdPreferences {
preferred_width: hardware.simd_capabilities.vector_width,
auto_vectorization: true,
manual_vectorization: false,
preferred_instructions: Vec::new(),
alignment_requirements: 16,
},
cache_strategy: CacheStrategy {
prefetch_strategy: PrefetchStrategy::Conservative,
blocking_factor: hardware.cache_info.l1_data_cache.size / 4,
cache_line_size: hardware.cache_info.l1_data_cache.line_size,
working_set_optimization: true,
data_layout_optimization: true,
},
power_strategy: PowerStrategy {
frequency_scaling: hardware.power_info.power_management_enabled,
core_parking: false,
voltage_scaling: false,
idle_optimization: true,
energy_efficiency_priority: 0.3, },
performance_characteristics: PerformanceCharacteristics {
integer_throughput: 2.0,
float_throughput: 1.5,
memory_bandwidth_efficiency: 0.7,
branch_prediction_accuracy: 0.95,
cache_efficiency: 0.8,
simd_efficiency: 0.6,
},
})
}
fn create_avx2_profile(hardware: &HardwareInfo) -> JitResult<TuningProfile> {
let mut base_profile = Self::create_architecture_profile(hardware)?;
base_profile.name = "avx2_optimized".to_string();
base_profile.compilation_flags.push("-mavx2".to_string());
base_profile.compilation_flags.push("-mfma".to_string());
base_profile.simd_preferences.preferred_width = 256;
base_profile.simd_preferences.auto_vectorization = true;
base_profile.simd_preferences.preferred_instructions = vec![
"vmulpd".to_string(),
"vaddpd".to_string(),
"vfmadd231pd".to_string(),
];
base_profile.simd_preferences.alignment_requirements = 32;
base_profile.performance_characteristics.simd_efficiency = 0.9;
Ok(base_profile)
}
fn create_avx_profile(hardware: &HardwareInfo) -> JitResult<TuningProfile> {
let mut base_profile = Self::create_architecture_profile(hardware)?;
base_profile.name = "avx_optimized".to_string();
base_profile.compilation_flags.push("-mavx".to_string());
base_profile.simd_preferences.preferred_width = 256;
base_profile.simd_preferences.alignment_requirements = 32;
base_profile.performance_characteristics.simd_efficiency = 0.8;
Ok(base_profile)
}
fn analyze_simd_opportunities(
&self,
graph: &ComputationGraph,
hardware: &HardwareInfo,
) -> JitResult<Vec<TuningRecommendation>> {
let mut recommendations = Vec::new();
for (node_id, node) in graph.nodes() {
if node.is_vectorizable() && hardware.simd_capabilities.avx2 {
recommendations.push(TuningRecommendation {
optimization_type: HardwareOptimizationType::SimdVectorization,
confidence: 0.8,
expected_improvement: 0.3, implementation_cost: 0.2,
description: format!("Vectorize node {} with AVX2", node_id.index()),
parameters: [
("vector_width".to_string(), "256".to_string()),
("instruction_set".to_string(), "avx2".to_string()),
]
.into(),
});
}
}
Ok(recommendations)
}
fn analyze_cache_opportunities(
&self,
graph: &ComputationGraph,
hardware: &HardwareInfo,
) -> JitResult<Vec<TuningRecommendation>> {
let mut recommendations = Vec::new();
for (node_id, node) in graph.nodes() {
if node.has_memory_access() {
let working_set_size = node.estimate_working_set_size();
let l3_cache_size = hardware
.cache_info
.l3_cache
.as_ref()
.map(|c| c.size)
.unwrap_or(0);
if working_set_size > l3_cache_size {
recommendations.push(TuningRecommendation {
optimization_type: HardwareOptimizationType::CacheOptimization,
confidence: 0.7,
expected_improvement: 0.15, implementation_cost: 0.3,
description: format!("Cache-blocking for node {}", node_id.index()),
parameters: [
("block_size".to_string(), (l3_cache_size / 2).to_string()),
(
"cache_line_size".to_string(),
hardware.cache_info.l1_data_cache.line_size.to_string(),
),
]
.into(),
});
}
}
}
Ok(recommendations)
}
fn analyze_architecture_opportunities(
&self,
_graph: &ComputationGraph,
hardware: &HardwareInfo,
) -> JitResult<Vec<TuningRecommendation>> {
let mut recommendations = Vec::new();
match hardware.architecture {
Architecture::X86_64 => {
if hardware.simd_capabilities.fma {
recommendations.push(TuningRecommendation {
optimization_type: HardwareOptimizationType::InstructionSelection,
confidence: 0.9,
expected_improvement: 0.1, implementation_cost: 0.1,
description: "Use FMA instructions for multiply-add operations".to_string(),
parameters: [("use_fma".to_string(), "true".to_string())].into(),
});
}
}
_ => {}
}
Ok(recommendations)
}
fn analyze_power_opportunities(
&self,
_graph: &ComputationGraph,
hardware: &HardwareInfo,
) -> JitResult<Vec<TuningRecommendation>> {
let mut recommendations = Vec::new();
if hardware.power_info.battery_powered {
recommendations.push(TuningRecommendation {
optimization_type: HardwareOptimizationType::PowerOptimization,
confidence: 0.6,
expected_improvement: 0.05, implementation_cost: 0.1,
description: "Enable power-efficient compilation for battery operation".to_string(),
parameters: [
("optimize_for_power".to_string(), "true".to_string()),
("frequency_scaling".to_string(), "enabled".to_string()),
]
.into(),
});
}
Ok(recommendations)
}
fn analyze_thermal_opportunities(
&self,
_graph: &ComputationGraph,
hardware: &HardwareInfo,
) -> JitResult<Vec<TuningRecommendation>> {
let mut recommendations = Vec::new();
if hardware.thermal_info.thermal_throttling {
recommendations.push(TuningRecommendation {
optimization_type: HardwareOptimizationType::ThermalOptimization,
confidence: 0.7,
expected_improvement: 0.08, implementation_cost: 0.2,
description: "Reduce computational intensity to avoid thermal throttling"
.to_string(),
parameters: [
("thermal_aware".to_string(), "true".to_string()),
(
"max_temperature".to_string(),
hardware.thermal_info.max_temperature.to_string(),
),
]
.into(),
});
}
Ok(recommendations)
}
fn apply_simd_optimization(
&self,
strategy: &mut CompilationStrategy,
recommendation: &TuningRecommendation,
) -> JitResult<bool> {
if let Some(vector_width) = recommendation.parameters.get("vector_width") {
strategy
.compilation_flags
.custom_flags
.push(format!("-mvector-width={}", vector_width));
}
if let Some(instruction_set) = recommendation.parameters.get("instruction_set") {
strategy
.compilation_flags
.custom_flags
.push(format!("-m{}", instruction_set));
}
strategy.compilation_flags.enable_vectorization = true;
Ok(true)
}
fn apply_cache_optimization(
&self,
strategy: &mut CompilationStrategy,
recommendation: &TuningRecommendation,
) -> JitResult<bool> {
if let Some(block_size) = recommendation.parameters.get("block_size") {
strategy
.compilation_flags
.custom_flags
.push(format!("-fcache-block-size={}", block_size));
}
if let Some(cache_line_size) = recommendation.parameters.get("cache_line_size") {
strategy
.compilation_flags
.custom_flags
.push(format!("-fcache-line-size={}", cache_line_size));
}
Ok(true)
}
fn apply_power_optimization(
&self,
strategy: &mut CompilationStrategy,
_recommendation: &TuningRecommendation,
) -> JitResult<bool> {
strategy.optimization_level = OptimizationLevel::Size; strategy
.compilation_flags
.custom_flags
.push("-fpower-efficient".to_string());
Ok(true)
}
fn apply_instruction_selection(
&self,
strategy: &mut CompilationStrategy,
recommendation: &TuningRecommendation,
) -> JitResult<bool> {
if recommendation.parameters.get("use_fma") == Some(&"true".to_string()) {
strategy
.compilation_flags
.custom_flags
.push("-mfma".to_string());
}
Ok(true)
}
}
impl std::fmt::Display for Architecture {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Architecture::X86_64 => write!(f, "x86_64"),
Architecture::X86 => write!(f, "x86"),
Architecture::Aarch64 => write!(f, "aarch64"),
Architecture::Arm => write!(f, "arm"),
Architecture::Riscv64 => write!(f, "riscv64"),
Architecture::Wasm32 => write!(f, "wasm32"),
Architecture::Unknown => write!(f, "unknown"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_hardware_detection() {
let hardware_info = HardwareTuner::detect_hardware().unwrap();
assert!(hardware_info.cpu_info.cores > 0);
assert!(hardware_info.cpu_info.logical_cores > 0);
}
#[test]
fn test_simd_detection() {
let simd_caps = HardwareTuner::detect_simd_capabilities().unwrap();
assert!(simd_caps.vector_width >= 128);
}
#[test]
fn test_architecture_detection() {
let arch = HardwareTuner::detect_architecture().unwrap();
assert_ne!(arch, Architecture::Unknown);
}
#[test]
fn test_tuning_profile_creation() {
let hardware_info = HardwareTuner::detect_hardware().unwrap();
let profile = HardwareTuner::create_architecture_profile(&hardware_info).unwrap();
assert_eq!(profile.architecture, hardware_info.architecture);
assert!(!profile.compilation_flags.is_empty());
}
#[test]
fn test_hardware_tuner_creation() {
let config = HardwareTuningConfig::default();
let tuner = HardwareTuner::new(config).unwrap();
let hardware_info = tuner.get_hardware_info().unwrap();
assert!(hardware_info.cpu_info.cores > 0);
}
}