1#![allow(unused_variables)] use super::traits::{
13 AsyncOperationHandle, DeviceMemory, DeviceStatus, HardwareBackend, HardwareDevice, MemoryType,
14};
15use super::{
16 DataType, HardwareCapabilities, HardwareConfig, HardwareMetrics, HardwareResult, HardwareType,
17};
18use crate::errors::TrustformersError;
19use async_trait::async_trait;
20use serde::{Deserialize, Serialize};
21use std::collections::HashMap;
22use std::sync::{Arc, Mutex};
23use std::time::{Duration, SystemTime};
24use tokio::time;
25
26#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
28pub enum AsicType {
29 AIInference,
31 NPU,
33 TPU,
35 DSP,
37 VPU,
39 Crypto,
41 EdgeAI,
43 Custom(String),
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
49pub struct AsicVendor {
50 pub name: String,
52 pub id: u16,
54 pub driver_version: String,
56 pub firmware_version: String,
58 pub support_contact: Option<String>,
60}
61
62#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
64pub struct AsicSpec {
65 pub asic_type: AsicType,
67 pub vendor: AsicVendor,
69 pub model: String,
71 pub revision: String,
73 pub process_node: Option<u16>,
75 pub die_size: Option<f64>,
77 pub package: Option<String>,
79 pub frequency_range: Option<(u32, u32)>,
81 pub power_range: Option<(f64, f64)>,
83 pub temperature_range: Option<(f64, f64)>,
85}
86
87#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
89pub struct AsicDeviceConfig {
90 pub base_config: HardwareConfig,
92 pub spec: AsicSpec,
94 pub clock_frequency: Option<u32>,
96 pub voltage: Option<f64>,
98 pub power_limit: Option<f64>,
100 pub thermal_limit: Option<f64>,
102 pub memory_config: AsicMemoryConfig,
104 pub instruction_set: Option<String>,
106 pub init_params: HashMap<String, String>,
108}
109
110#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
112pub struct AsicMemoryConfig {
113 pub on_chip_memory: Option<usize>,
115 pub off_chip_memory: Option<usize>,
117 pub memory_bandwidth: Option<f64>,
119 pub memory_latency: Option<f64>,
121 pub cache_config: CacheConfig,
123}
124
125#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
127pub struct CacheConfig {
128 pub l1_size: Option<usize>,
130 pub l2_size: Option<usize>,
132 pub l3_size: Option<usize>,
134 pub line_size: Option<usize>,
136 pub associativity: Option<u8>,
138}
139
140#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
142pub struct AsicOperationSet {
143 pub name: String,
145 pub operations: Vec<String>,
147 pub performance: HashMap<String, f64>,
149 pub memory_requirements: HashMap<String, usize>,
151 pub precision_support: Vec<DataType>,
153 pub instruction_encoding: Option<String>,
155}
156
157pub struct AsicDevice {
159 config: AsicDeviceConfig,
161 status: Arc<Mutex<DeviceStatus>>,
163 capabilities: HardwareCapabilities,
165 operation_sets: Vec<AsicOperationSet>,
167 memory_pools: Arc<Mutex<HashMap<String, Vec<DeviceMemory>>>>,
169 active_operations: Arc<Mutex<HashMap<String, AsyncOperationHandle>>>,
171 driver: Option<Box<dyn AsicDriver>>,
173 performance_monitor: Arc<Mutex<AsicPerformanceMonitor>>,
175}
176
177#[async_trait]
179pub trait AsicDriver: Send + Sync {
180 async fn initialize(&mut self, config: &AsicDeviceConfig) -> HardwareResult<()>;
182
183 async fn execute_instruction(&self, instruction: &[u8]) -> HardwareResult<Vec<u8>>;
185
186 async fn read_register(&self, address: u64) -> HardwareResult<u64>;
188
189 async fn write_register(&self, address: u64, value: u64) -> HardwareResult<()>;
191
192 async fn transfer_to_device(&self, data: &[u8], address: u64) -> HardwareResult<()>;
194
195 async fn transfer_from_device(&self, address: u64, size: usize) -> HardwareResult<Vec<u8>>;
197
198 async fn get_status(&self) -> HardwareResult<DeviceStatus>;
200
201 async fn reset(&mut self) -> HardwareResult<()>;
203
204 async fn configure(&mut self, config: &AsicDeviceConfig) -> HardwareResult<()>;
206
207 async fn get_metrics(&self) -> HardwareResult<HardwareMetrics>;
209}
210
211#[derive(Debug, Clone)]
213pub struct AsicPerformanceMonitor {
214 pub operation_counters: HashMap<String, u64>,
216 pub metrics: HardwareMetrics,
218 pub thermal_history: Vec<(SystemTime, f64)>,
220 pub power_history: Vec<(SystemTime, f64)>,
222 pub error_counters: HashMap<String, u64>,
224 pub utilization_history: Vec<(SystemTime, f64)>,
226}
227
228impl AsicDevice {
229 pub fn new(config: AsicDeviceConfig) -> Self {
231 let capabilities = Self::build_capabilities(&config);
232 let operation_sets = Self::build_operation_sets(&config);
233
234 Self {
235 config,
236 status: Arc::new(Mutex::new(DeviceStatus::default())),
237 capabilities,
238 operation_sets,
239 memory_pools: Arc::new(Mutex::new(HashMap::new())),
240 active_operations: Arc::new(Mutex::new(HashMap::new())),
241 driver: None,
242 performance_monitor: Arc::new(Mutex::new(AsicPerformanceMonitor::new())),
243 }
244 }
245
246 pub fn set_driver(&mut self, driver: Box<dyn AsicDriver>) {
248 self.driver = Some(driver);
249 }
250
251 fn build_capabilities(config: &AsicDeviceConfig) -> HardwareCapabilities {
253 let mut capabilities = HardwareCapabilities::default();
254
255 match config.spec.asic_type {
257 AsicType::AIInference | AsicType::NPU => {
258 capabilities.data_types = vec![
259 DataType::F32,
260 DataType::F16,
261 DataType::BF16,
262 DataType::I8,
263 DataType::I16,
264 DataType::I32,
265 ];
266 },
267 AsicType::TPU => {
268 capabilities.data_types = vec![DataType::F32, DataType::BF16, DataType::I8];
269 },
270 AsicType::DSP => {
271 capabilities.data_types = vec![
272 DataType::F32,
273 DataType::F64,
274 DataType::I16,
275 DataType::I32,
276 DataType::Complex64,
277 DataType::Complex128,
278 ];
279 },
280 AsicType::VPU => {
281 capabilities.data_types = vec![DataType::F16, DataType::I8, DataType::U8];
282 },
283 AsicType::Crypto => {
284 capabilities.data_types =
285 vec![DataType::U8, DataType::U16, DataType::U32, DataType::U64];
286 },
287 AsicType::EdgeAI => {
288 capabilities.data_types = vec![DataType::F16, DataType::I8, DataType::U8];
289 },
290 AsicType::Custom(_) => {
291 capabilities.data_types = vec![DataType::F32, DataType::I32];
293 },
294 }
295
296 if let Some(on_chip) = config.memory_config.on_chip_memory {
298 capabilities.memory_size = Some(on_chip);
299 } else if let Some(off_chip) = config.memory_config.off_chip_memory {
300 capabilities.memory_size = Some(off_chip);
301 }
302
303 if let Some(freq) = config.clock_frequency {
305 capabilities.clock_frequency = Some(freq as u64 * 1_000_000); }
307
308 capabilities.operations = match config.spec.asic_type {
310 AsicType::AIInference | AsicType::NPU => vec![
311 "matmul".to_string(),
312 "conv2d".to_string(),
313 "activation".to_string(),
314 "pooling".to_string(),
315 "normalization".to_string(),
316 "attention".to_string(),
317 ],
318 AsicType::TPU => vec![
319 "matmul".to_string(),
320 "conv2d".to_string(),
321 "systolic_array".to_string(),
322 ],
323 AsicType::DSP => vec![
324 "fft".to_string(),
325 "filter".to_string(),
326 "transform".to_string(),
327 "correlation".to_string(),
328 ],
329 AsicType::VPU => vec![
330 "conv2d".to_string(),
331 "pooling".to_string(),
332 "resize".to_string(),
333 "color_space".to_string(),
334 ],
335 AsicType::Crypto => vec![
336 "encrypt".to_string(),
337 "decrypt".to_string(),
338 "hash".to_string(),
339 "signature".to_string(),
340 ],
341 AsicType::EdgeAI => vec![
342 "inference".to_string(),
343 "quantization".to_string(),
344 "compression".to_string(),
345 ],
346 AsicType::Custom(_) => vec!["custom_op".to_string()],
347 };
348
349 capabilities
350 }
351
352 fn build_operation_sets(config: &AsicDeviceConfig) -> Vec<AsicOperationSet> {
354 let mut operation_sets = Vec::new();
355
356 match config.spec.asic_type {
357 AsicType::AIInference | AsicType::NPU => {
358 operation_sets.push(AsicOperationSet {
359 name: "ml_ops".to_string(),
360 operations: vec![
361 "matmul".to_string(),
362 "conv2d".to_string(),
363 "activation".to_string(),
364 "pooling".to_string(),
365 "normalization".to_string(),
366 "attention".to_string(),
367 ],
368 performance: [
369 ("matmul".to_string(), 1000.0),
370 ("conv2d".to_string(), 800.0),
371 ("activation".to_string(), 2000.0),
372 ]
373 .into(),
374 memory_requirements: [
375 ("matmul".to_string(), 1024 * 1024),
376 ("conv2d".to_string(), 2048 * 1024),
377 ]
378 .into(),
379 precision_support: vec![DataType::F32, DataType::F16, DataType::I8],
380 instruction_encoding: Some("custom_ml".to_string()),
381 });
382 },
383 AsicType::TPU => {
384 operation_sets.push(AsicOperationSet {
385 name: "tensor_ops".to_string(),
386 operations: vec![
387 "matmul".to_string(),
388 "conv2d".to_string(),
389 "systolic_array".to_string(),
390 ],
391 performance: [
392 ("matmul".to_string(), 2000.0),
393 ("systolic_array".to_string(), 3000.0),
394 ]
395 .into(),
396 memory_requirements: [
397 ("matmul".to_string(), 512 * 1024),
398 ("systolic_array".to_string(), 1024 * 1024),
399 ]
400 .into(),
401 precision_support: vec![DataType::F32, DataType::BF16, DataType::I8],
402 instruction_encoding: Some("tpu_v4".to_string()),
403 });
404 },
405 AsicType::DSP => {
406 operation_sets.push(AsicOperationSet {
407 name: "signal_ops".to_string(),
408 operations: vec![
409 "fft".to_string(),
410 "filter".to_string(),
411 "transform".to_string(),
412 "correlation".to_string(),
413 ],
414 performance: [("fft".to_string(), 1500.0), ("filter".to_string(), 1200.0)]
415 .into(),
416 memory_requirements: [
417 ("fft".to_string(), 256 * 1024),
418 ("filter".to_string(), 128 * 1024),
419 ]
420 .into(),
421 precision_support: vec![DataType::F32, DataType::F64, DataType::Complex64],
422 instruction_encoding: Some("dsp_v2".to_string()),
423 });
424 },
425 _ => {
426 operation_sets.push(AsicOperationSet {
428 name: "basic_ops".to_string(),
429 operations: vec!["generic_op".to_string()],
430 performance: [("generic_op".to_string(), 100.0)].into(),
431 memory_requirements: [("generic_op".to_string(), 64 * 1024)].into(),
432 precision_support: vec![DataType::F32],
433 instruction_encoding: None,
434 });
435 },
436 }
437
438 operation_sets
439 }
440
441 pub fn get_operation_set(&self, name: &str) -> Option<&AsicOperationSet> {
443 self.operation_sets.iter().find(|ops| ops.name == name)
444 }
445
446 #[allow(dead_code)]
448 async fn update_performance_metrics(&self) -> HardwareResult<()> {
449 if let Some(driver) = &self.driver {
450 let metrics = driver.get_metrics().await?;
451 let mut monitor = self.performance_monitor.lock().expect("Lock poisoned");
452
453 monitor
454 .thermal_history
455 .push((SystemTime::now(), metrics.temperature.unwrap_or(0.0)));
456 monitor.power_history.push((SystemTime::now(), metrics.power_consumption));
457 monitor.utilization_history.push((SystemTime::now(), metrics.utilization));
458 monitor.metrics = metrics;
459
460 if monitor.thermal_history.len() > 1000 {
462 monitor.thermal_history.drain(..500);
463 }
464 if monitor.power_history.len() > 1000 {
465 monitor.power_history.drain(..500);
466 }
467 if monitor.utilization_history.len() > 1000 {
468 monitor.utilization_history.drain(..500);
469 }
470 }
471 Ok(())
472 }
473
474 pub fn get_performance_statistics(&self) -> HashMap<String, f64> {
476 let monitor = self.performance_monitor.lock().expect("Lock poisoned");
477 let mut stats = HashMap::new();
478
479 if !monitor.utilization_history.is_empty() {
481 let avg_util = monitor.utilization_history.iter().map(|(_, util)| util).sum::<f64>()
482 / monitor.utilization_history.len() as f64;
483 stats.insert("avg_utilization".to_string(), avg_util);
484 }
485
486 if !monitor.thermal_history.is_empty() {
488 let avg_temp = monitor.thermal_history.iter().map(|(_, temp)| temp).sum::<f64>()
489 / monitor.thermal_history.len() as f64;
490 stats.insert("avg_temperature".to_string(), avg_temp);
491 }
492
493 if !monitor.power_history.is_empty() {
495 let avg_power = monitor.power_history.iter().map(|(_, power)| power).sum::<f64>()
496 / monitor.power_history.len() as f64;
497 stats.insert("avg_power".to_string(), avg_power);
498 }
499
500 for (op, count) in &monitor.operation_counters {
502 stats.insert(format!("op_{}", op), *count as f64);
503 }
504
505 stats
506 }
507}
508
509#[async_trait]
510impl HardwareDevice for AsicDevice {
511 fn device_id(&self) -> &str {
512 &self.config.base_config.device_id
513 }
514
515 fn hardware_type(&self) -> HardwareType {
516 HardwareType::ASIC
517 }
518
519 fn capabilities(&self) -> &HardwareCapabilities {
520 &self.capabilities
521 }
522
523 async fn initialize(&mut self, config: &HardwareConfig) -> HardwareResult<()> {
524 self.config.base_config = config.clone();
526
527 if let Some(driver) = &mut self.driver {
529 driver.initialize(&self.config).await?;
530 }
531
532 let mut status = self.status.lock().expect("Lock poisoned");
534 status.online = true;
535 status.busy = false;
536 status.error = None;
537
538 Ok(())
539 }
540
541 async fn shutdown(&mut self) -> HardwareResult<()> {
542 let operations = {
544 let mut ops = self.active_operations.lock().expect("Lock poisoned");
545 let handles: Vec<_> = ops.keys().cloned().collect();
546 ops.clear();
547 handles
548 };
549
550 {
552 let mut status = self.status.lock().expect("Lock poisoned");
553 status.online = false;
554 status.busy = false;
555 }
556
557 if let Some(driver) = &mut self.driver {
559 driver.reset().await?;
560 }
561
562 Ok(())
563 }
564
565 fn is_available(&self) -> bool {
566 let status = self.status.lock().expect("Lock poisoned");
567 status.online && !status.busy
568 }
569
570 fn status(&self) -> DeviceStatus {
571 self.status.lock().expect("Lock poisoned").clone()
572 }
573
574 async fn metrics(&self) -> HardwareResult<HardwareMetrics> {
575 if let Some(driver) = &self.driver {
576 driver.get_metrics().await
577 } else {
578 Ok(HardwareMetrics {
579 ops_per_second: 0.0,
580 memory_bandwidth: 0.0,
581 utilization: 0.0,
582 power_consumption: 0.0,
583 temperature: None,
584 error_rate: 0.0,
585 latency: 0.0,
586 throughput: 0.0,
587 })
588 }
589 }
590
591 async fn reset(&mut self) -> HardwareResult<()> {
592 if let Some(driver) = &mut self.driver {
594 driver.reset().await?;
595 }
596
597 self.memory_pools.lock().expect("Lock poisoned").clear();
599
600 self.active_operations.lock().expect("Lock poisoned").clear();
602
603 let mut monitor = self.performance_monitor.lock().expect("Lock poisoned");
605 monitor.operation_counters.clear();
606 monitor.thermal_history.clear();
607 monitor.power_history.clear();
608 monitor.error_counters.clear();
609 monitor.utilization_history.clear();
610
611 Ok(())
612 }
613
614 async fn allocate_memory(&mut self, size: usize) -> HardwareResult<DeviceMemory> {
615 let address = (size.wrapping_mul(12345)) % 0x100000000; let memory = DeviceMemory {
618 address,
619 size,
620 memory_type: MemoryType::Local,
621 device_id: self.device_id().to_string(),
622 };
623
624 let mut pools = self.memory_pools.lock().expect("Lock poisoned");
626 pools.entry("default".to_string()).or_default().push(memory.clone());
627
628 Ok(memory)
629 }
630
631 async fn free_memory(&mut self, memory: DeviceMemory) -> HardwareResult<()> {
632 let mut pools = self.memory_pools.lock().expect("Lock poisoned");
634 if let Some(pool) = pools.get_mut("default") {
635 pool.retain(|m| m.address != memory.address);
636 }
637
638 Ok(())
639 }
640
641 async fn synchronize(&self) -> HardwareResult<()> {
642 let has_operations = {
644 let operations = self.active_operations.lock().expect("Lock poisoned");
645 !operations.is_empty()
646 };
647
648 if has_operations {
649 time::sleep(Duration::from_millis(1)).await;
651 }
652
653 Ok(())
654 }
655}
656
657impl Default for AsicPerformanceMonitor {
658 fn default() -> Self {
659 Self::new()
660 }
661}
662
663impl AsicPerformanceMonitor {
664 pub fn new() -> Self {
666 Self {
667 operation_counters: HashMap::new(),
668 metrics: HardwareMetrics {
669 ops_per_second: 0.0,
670 memory_bandwidth: 0.0,
671 utilization: 0.0,
672 power_consumption: 0.0,
673 temperature: None,
674 error_rate: 0.0,
675 latency: 0.0,
676 throughput: 0.0,
677 },
678 thermal_history: Vec::new(),
679 power_history: Vec::new(),
680 error_counters: HashMap::new(),
681 utilization_history: Vec::new(),
682 }
683 }
684
685 pub fn record_operation(&mut self, operation: &str) {
687 *self.operation_counters.entry(operation.to_string()).or_insert(0) += 1;
688 }
689
690 pub fn record_error(&mut self, error_type: &str) {
692 *self.error_counters.entry(error_type.to_string()).or_insert(0) += 1;
693 }
694
695 pub fn get_operation_stats(&self) -> HashMap<String, u64> {
697 self.operation_counters.clone()
698 }
699
700 pub fn get_error_stats(&self) -> HashMap<String, u64> {
702 self.error_counters.clone()
703 }
704}
705
706pub struct AsicBackend {
708 name: String,
710 version: String,
712 #[allow(dead_code)]
714 supported_types: Vec<AsicType>,
715 device_configs: HashMap<String, AsicDeviceConfig>,
717 driver_factory: Option<Box<dyn AsicDriverFactory>>,
719}
720
721pub trait AsicDriverFactory: Send + Sync {
723 fn create_driver(&self, asic_type: &AsicType) -> HardwareResult<Box<dyn AsicDriver>>;
725
726 fn is_available(&self, asic_type: &AsicType) -> bool;
728
729 fn get_requirements(&self, asic_type: &AsicType) -> Vec<String>;
731}
732
733impl AsicBackend {
734 pub fn new(name: String, version: String) -> Self {
736 Self {
737 name,
738 version,
739 supported_types: vec![
740 AsicType::AIInference,
741 AsicType::NPU,
742 AsicType::TPU,
743 AsicType::DSP,
744 AsicType::VPU,
745 AsicType::Crypto,
746 AsicType::EdgeAI,
747 ],
748 device_configs: HashMap::new(),
749 driver_factory: None,
750 }
751 }
752
753 pub fn set_driver_factory(&mut self, factory: Box<dyn AsicDriverFactory>) {
755 self.driver_factory = Some(factory);
756 }
757
758 pub fn add_device_config(&mut self, device_id: String, config: AsicDeviceConfig) {
760 self.device_configs.insert(device_id, config);
761 }
762
763 pub async fn create_asic_device(
765 &self,
766 config: &AsicDeviceConfig,
767 ) -> HardwareResult<AsicDevice> {
768 let mut device = AsicDevice::new(config.clone());
769
770 if let Some(factory) = &self.driver_factory {
772 if factory.is_available(&config.spec.asic_type) {
773 let driver = factory.create_driver(&config.spec.asic_type)?;
774 device.set_driver(driver);
775 }
776 }
777
778 Ok(device)
779 }
780}
781
782#[async_trait]
783impl HardwareBackend for AsicBackend {
784 fn name(&self) -> &str {
785 &self.name
786 }
787
788 fn version(&self) -> &str {
789 &self.version
790 }
791
792 async fn discover_devices(&self) -> HardwareResult<Vec<Box<dyn HardwareDevice>>> {
793 let mut devices = Vec::new();
794
795 for (device_id, config) in &self.device_configs {
797 let device = self.create_asic_device(config).await?;
798 devices.push(Box::new(device) as Box<dyn HardwareDevice>);
799 }
800
801 Ok(devices)
802 }
803
804 async fn create_device(
805 &self,
806 config: &HardwareConfig,
807 ) -> HardwareResult<Box<dyn HardwareDevice>> {
808 if config.hardware_type != HardwareType::ASIC {
809 return Err(TrustformersError::invalid_config(
810 "Invalid hardware type for ASIC backend".to_string(),
811 ));
812 }
813
814 if let Some(asic_config) = self.device_configs.get(&config.device_id) {
816 let device = self.create_asic_device(asic_config).await?;
817 Ok(Box::new(device) as Box<dyn HardwareDevice>)
818 } else {
819 Err(TrustformersError::model_error(format!(
820 "ASIC device {} not found",
821 config.device_id
822 )))
823 }
824 }
825
826 fn is_compatible(&self, hardware_type: HardwareType) -> bool {
827 hardware_type == HardwareType::ASIC
828 }
829
830 fn supported_operations(&self) -> &[String] {
831 use std::sync::OnceLock;
832 static OPERATIONS: OnceLock<Vec<String>> = OnceLock::new();
833 OPERATIONS.get_or_init(|| {
834 vec![
835 "matmul".to_string(),
836 "conv2d".to_string(),
837 "activation".to_string(),
838 "pooling".to_string(),
839 "fft".to_string(),
840 "filter".to_string(),
841 "encrypt".to_string(),
842 "decrypt".to_string(),
843 ]
844 })
845 }
846
847 fn validate_config(&self, config: &HardwareConfig) -> HardwareResult<()> {
848 if config.hardware_type != HardwareType::ASIC {
849 return Err(TrustformersError::invalid_config(
850 "Invalid hardware type for ASIC backend".to_string(),
851 ));
852 }
853
854 if !self.device_configs.contains_key(&config.device_id) {
856 return Err(TrustformersError::invalid_config(format!(
857 "ASIC device configuration for {} not found",
858 config.device_id
859 )));
860 }
861
862 Ok(())
863 }
864}
865
866impl Default for AsicDeviceConfig {
867 fn default() -> Self {
868 Self {
869 base_config: HardwareConfig::default(),
870 spec: AsicSpec {
871 asic_type: AsicType::AIInference,
872 vendor: AsicVendor {
873 name: "Generic".to_string(),
874 id: 0,
875 driver_version: "1.0.0".to_string(),
876 firmware_version: "1.0.0".to_string(),
877 support_contact: None,
878 },
879 model: "Generic AI ASIC".to_string(),
880 revision: "1.0".to_string(),
881 process_node: Some(7),
882 die_size: Some(100.0),
883 package: Some("BGA".to_string()),
884 frequency_range: Some((1000, 2000)),
885 power_range: Some((10.0, 100.0)),
886 temperature_range: Some((-40.0, 85.0)),
887 },
888 clock_frequency: Some(1500),
889 voltage: Some(1.0),
890 power_limit: Some(75.0),
891 thermal_limit: Some(85.0),
892 memory_config: AsicMemoryConfig::default(),
893 instruction_set: Some("generic_v1".to_string()),
894 init_params: HashMap::new(),
895 }
896 }
897}
898
899impl Default for AsicMemoryConfig {
900 fn default() -> Self {
901 Self {
902 on_chip_memory: Some(1024 * 1024), off_chip_memory: Some(1024 * 1024 * 1024), memory_bandwidth: Some(100.0), memory_latency: Some(10.0), cache_config: CacheConfig::default(),
907 }
908 }
909}
910
911impl Default for CacheConfig {
912 fn default() -> Self {
913 Self {
914 l1_size: Some(64 * 1024), l2_size: Some(256 * 1024), l3_size: Some(1024 * 1024), line_size: Some(64), associativity: Some(8), }
920 }
921}
922
923impl std::fmt::Display for AsicType {
924 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
925 match self {
926 AsicType::AIInference => write!(f, "AI Inference"),
927 AsicType::NPU => write!(f, "NPU"),
928 AsicType::TPU => write!(f, "TPU"),
929 AsicType::DSP => write!(f, "DSP"),
930 AsicType::VPU => write!(f, "VPU"),
931 AsicType::Crypto => write!(f, "Crypto"),
932 AsicType::EdgeAI => write!(f, "Edge AI"),
933 AsicType::Custom(name) => write!(f, "Custom({})", name),
934 }
935 }
936}
937
938#[cfg(test)]
939mod tests {
940 use super::*;
941 use tokio;
942
943 #[tokio::test]
944 async fn test_asic_device_creation() {
945 let config = AsicDeviceConfig::default();
946 let device = AsicDevice::new(config);
947
948 assert_eq!(device.hardware_type(), HardwareType::ASIC);
949 assert_eq!(device.device_id(), "default");
950 assert!(!device.is_available()); }
952
953 #[tokio::test]
954 async fn test_asic_device_initialization() {
955 let config = AsicDeviceConfig::default();
956 let mut device = AsicDevice::new(config);
957
958 let hw_config = HardwareConfig::default();
959 device.initialize(&hw_config).await.expect("async operation failed");
960
961 assert!(device.is_available());
962 assert!(device.status().online);
963 }
964
965 #[tokio::test]
966 async fn test_asic_memory_allocation() {
967 let config = AsicDeviceConfig::default();
968 let mut device = AsicDevice::new(config);
969
970 let memory = device.allocate_memory(1024).await.expect("async operation failed");
971 assert_eq!(memory.size, 1024);
972 assert_eq!(memory.memory_type, MemoryType::Local);
973
974 device.free_memory(memory).await.expect("async operation failed");
975 }
976
977 #[test]
978 fn test_asic_backend_compatibility() {
979 let backend = AsicBackend::new("test".to_string(), "1.0".to_string());
980
981 assert!(backend.is_compatible(HardwareType::ASIC));
982 assert!(!backend.is_compatible(HardwareType::CPU));
983 assert!(!backend.is_compatible(HardwareType::GPU));
984 }
985
986 #[test]
987 fn test_asic_type_display() {
988 assert_eq!(AsicType::AIInference.to_string(), "AI Inference");
989 assert_eq!(AsicType::NPU.to_string(), "NPU");
990 assert_eq!(
991 AsicType::Custom("MyASIC".to_string()).to_string(),
992 "Custom(MyASIC)"
993 );
994 }
995
996 #[test]
997 fn test_asic_capabilities_building() {
998 let config = AsicDeviceConfig::default();
999 let capabilities = AsicDevice::build_capabilities(&config);
1000
1001 assert!(capabilities.data_types.contains(&DataType::F32));
1002 assert!(capabilities.data_types.contains(&DataType::F16));
1003 assert!(capabilities.operations.contains(&"matmul".to_string()));
1004 }
1005
1006 #[test]
1007 fn test_asic_operation_sets() {
1008 let config = AsicDeviceConfig::default();
1009 let operation_sets = AsicDevice::build_operation_sets(&config);
1010
1011 assert!(!operation_sets.is_empty());
1012 assert!(operation_sets.iter().any(|ops| ops.name == "ml_ops"));
1013 }
1014
1015 #[test]
1016 fn test_performance_monitor() {
1017 let mut monitor = AsicPerformanceMonitor::new();
1018
1019 monitor.record_operation("matmul");
1020 monitor.record_operation("matmul");
1021 monitor.record_operation("conv2d");
1022 monitor.record_error("timeout");
1023
1024 let op_stats = monitor.get_operation_stats();
1025 assert_eq!(op_stats.get("matmul"), Some(&2));
1026 assert_eq!(op_stats.get("conv2d"), Some(&1));
1027
1028 let error_stats = monitor.get_error_stats();
1029 assert_eq!(error_stats.get("timeout"), Some(&1));
1030 }
1031
1032 #[test]
1033 fn test_asic_config_defaults() {
1034 let config = AsicDeviceConfig::default();
1035
1036 assert_eq!(config.spec.asic_type, AsicType::AIInference);
1037 assert_eq!(config.spec.vendor.name, "Generic");
1038 assert_eq!(config.clock_frequency, Some(1500));
1039 assert_eq!(config.memory_config.on_chip_memory, Some(1024 * 1024));
1040 }
1041}