use crate::error::Result;
use rayon::prelude::*;
pub struct HardwareMaster;
impl HardwareMaster {
pub fn logical_cpus() -> usize {
num_cpus::get()
}
pub fn physical_cpus() -> usize {
num_cpus::get_physical()
}
pub fn init_global_pool(threads: Option<usize>) -> Result<()> {
let t = threads.unwrap_or_else(Self::logical_cpus);
rayon::ThreadPoolBuilder::new()
.num_threads(t)
.build_global()?;
Ok(())
}
pub fn parallel_process<T, R, F>(items: Vec<T>, f: F) -> Vec<R>
where
T: Send,
R: Send,
F: Fn(T) -> R + Sync + Send,
{
items.into_par_iter().map(f).collect()
}
}
#[cfg(feature = "gpu")]
pub mod gpu {
use wgpu;
pub async fn check_gpu_status() {
let instance = wgpu::Instance::default();
let adapters = instance.enumerate_adapters(wgpu::Backends::all());
for adapter in adapters {
println!("检测到 GPU: {:?}", adapter.get_info().name);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn logical_cpus_positive() {
assert!(HardwareMaster::logical_cpus() >= 1, "逻辑核心数应 ≥ 1");
}
#[test]
fn physical_cpus_positive() {
assert!(HardwareMaster::physical_cpus() >= 1, "物理核心数应 ≥ 1");
}
#[test]
fn parallel_process_preserves_order_and_len() {
let items: Vec<i32> = (0..100).collect();
let doubled = HardwareMaster::parallel_process(items.clone(), |x| x * 2);
assert_eq!(doubled.len(), 100);
assert_eq!(doubled, items.iter().map(|x| x * 2).collect::<Vec<_>>());
}
#[test]
fn parallel_process_empty() {
let out: Vec<i32> = HardwareMaster::parallel_process(Vec::new(), |x| x);
assert!(out.is_empty());
}
}