entrenar/efficiency/device/
apple.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7pub struct AppleSiliconInfo {
8 pub chip: String,
10 pub p_cores: u32,
12 pub e_cores: u32,
14 pub gpu_cores: u32,
16 pub neural_cores: u32,
18 pub unified_memory_bytes: u64,
20}
21
22impl AppleSiliconInfo {
23 pub fn new(chip: impl Into<String>) -> Self {
25 Self {
26 chip: chip.into(),
27 p_cores: 0,
28 e_cores: 0,
29 gpu_cores: 0,
30 neural_cores: 16, unified_memory_bytes: 0,
32 }
33 }
34
35 pub fn with_cores(mut self, p_cores: u32, e_cores: u32, gpu_cores: u32) -> Self {
37 self.p_cores = p_cores;
38 self.e_cores = e_cores;
39 self.gpu_cores = gpu_cores;
40 self
41 }
42
43 pub fn with_memory(mut self, bytes: u64) -> Self {
45 self.unified_memory_bytes = bytes;
46 self
47 }
48
49 pub fn total_cpu_cores(&self) -> u32 {
51 self.p_cores + self.e_cores
52 }
53
54 pub fn unified_memory_gb(&self) -> f64 {
56 self.unified_memory_bytes as f64 / (1024.0 * 1024.0 * 1024.0)
57 }
58
59 #[cfg(target_os = "macos")]
61 pub fn detect() -> Option<Self> {
62 let arch = std::env::consts::ARCH;
64 if arch != "aarch64" {
65 return None;
66 }
67
68 let chip = std::process::Command::new("sysctl")
70 .args(["-n", "machdep.cpu.brand_string"])
71 .output()
72 .ok()
73 .and_then(|output| String::from_utf8(output.stdout).ok())
74 .map(|s| s.trim().to_string())
75 .unwrap_or_else(|| "Apple Silicon".to_string());
76
77 let p_cores = std::process::Command::new("sysctl")
79 .args(["-n", "hw.perflevel0.logicalcpu"])
80 .output()
81 .ok()
82 .and_then(|output| String::from_utf8(output.stdout).ok())
83 .and_then(|s| s.trim().parse().ok())
84 .unwrap_or(0);
85
86 let e_cores = std::process::Command::new("sysctl")
87 .args(["-n", "hw.perflevel1.logicalcpu"])
88 .output()
89 .ok()
90 .and_then(|output| String::from_utf8(output.stdout).ok())
91 .and_then(|s| s.trim().parse().ok())
92 .unwrap_or(0);
93
94 let memory = std::process::Command::new("sysctl")
96 .args(["-n", "hw.memsize"])
97 .output()
98 .ok()
99 .and_then(|output| String::from_utf8(output.stdout).ok())
100 .and_then(|s| s.trim().parse().ok())
101 .unwrap_or(0);
102
103 Some(
104 Self::new(chip)
105 .with_cores(p_cores, e_cores, 0) .with_memory(memory),
107 )
108 }
109
110 #[cfg(not(target_os = "macos"))]
111 pub fn detect() -> Option<Self> {
112 None
113 }
114}