oxirs_embed/
evolutionary_nas_eval.rs1use crate::evolutionary_nas_types::{
6 ArchitectureCandidate, EvaluationDataset, HardwareTarget, PerformanceMetrics, ProfilingResult,
7};
8use anyhow::Result;
9use scirs2_core::random::Random;
10use std::collections::HashMap;
11use std::sync::Arc;
12use tokio::sync::RwLock;
13
14pub struct HardwareProfiler {
18 pub target_hardware: HardwareTarget,
19 pub profiling_history: Vec<ProfilingResult>,
20}
21
22pub struct FitnessEvaluator {
26 pub datasets: HashMap<String, EvaluationDataset>,
27 pub hardware_profiler: HardwareProfiler,
28 pub evaluation_cache: Arc<RwLock<HashMap<String, PerformanceMetrics>>>,
29}
30
31impl FitnessEvaluator {
32 pub async fn evaluate_candidate_performance(
37 &self,
38 _candidate: &ArchitectureCandidate,
39 ) -> Result<PerformanceMetrics> {
40 let mut random = Random::default();
41 Ok(PerformanceMetrics {
42 training_accuracy: random.random_range(0.7f32..0.95f32),
43 validation_accuracy: random.random_range(0.65f32..0.9f32),
44 test_accuracy: None,
45 training_time: random.random_range(100.0f64..1000.0f64),
46 inference_time_ms: random.random_range(0.1f32..10.0f32),
47 memory_usage_mb: random.random_range(100.0f32..2000.0f32),
48 energy_consumption: Some(random.random_range(10.0f32..100.0f32)),
49 model_size: random.random_range(1_000_000usize..50_000_000usize),
50 flops: random.random_range(1_000_000u64..100_000_000u64),
51 })
52 }
53}
54
55pub fn compute_proxy_accuracy(candidate: &ArchitectureCandidate) -> f32 {
62 let num_nodes = candidate.genome.nodes.len() as f32;
63 let num_active = candidate
64 .genome
65 .connections
66 .iter()
67 .filter(|c| c.active)
68 .count() as f32;
69
70 let capacity = (num_nodes.ln_1p() + num_active.ln_1p()) / 10.0;
72 capacity.clamp(0.5, 0.95)
73}
74
75pub fn estimate_memory_mb(candidate: &ArchitectureCandidate) -> f32 {
77 candidate.genome.nodes.len() as f32 * 0.5 + candidate.genome.connections.len() as f32 * 0.01
79}
80
81pub fn estimate_flops(candidate: &ArchitectureCandidate) -> u64 {
83 let active_conns = candidate
85 .genome
86 .connections
87 .iter()
88 .filter(|c| c.active)
89 .count() as u64;
90 active_conns * 1_000
91}
92
93pub fn should_stop_early(generation_best_fitness: &[f32], patience: usize, min_delta: f32) -> bool {
100 if generation_best_fitness.len() < patience + 1 {
101 return false;
102 }
103 let window = &generation_best_fitness[generation_best_fitness.len() - patience - 1..];
104 let oldest = window[0];
105 let newest = *window.last().expect("window must have elements");
106 (newest - oldest).abs() < min_delta
107}