use alloc::string::String;
use core::hash::{BuildHasher, Hash, Hasher};
use crate::{
AddressType, OpaqueType, SemanticType, StorageType, Type, TypeHash, VectorSize,
features::{AtomicUsage, Features, TypeUsage},
};
use cubecl_common::profile::TimingMethod;
use enumset::EnumSet;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct HardwareProperties {
pub load_width: u32,
pub plane_size_min: u32,
pub plane_size_max: u32,
pub max_bindings: u32,
pub max_shared_memory_size: usize,
pub max_cube_count: (u32, u32, u32),
pub max_units_per_cube: u32,
pub max_cube_dim: (u32, u32, u32),
pub num_streaming_multiprocessors: Option<u32>,
pub num_cpu_cores: Option<u32>,
pub num_tensor_cores: Option<u32>,
pub min_tensor_cores_dim: Option<u32>,
pub max_vector_size: VectorSize,
pub cube_mma_reserved_shared_memory: usize,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct MemoryDeviceProperties {
pub max_page_size: u64,
pub alignment: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
pub struct DeviceIdentity {
pub name: String,
pub fingerprint: String,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DeviceProperties {
pub features: Features,
pub memory: MemoryDeviceProperties,
pub hardware: HardwareProperties,
pub timing_method: TimingMethod,
pub identity: DeviceIdentity,
}
impl TypeHash for DeviceProperties {
fn write_hash(_hasher: &mut impl core::hash::Hasher) {
}
}
impl DeviceProperties {
pub fn new(
features: Features,
memory_props: MemoryDeviceProperties,
hardware: HardwareProperties,
timing_method: TimingMethod,
identity: DeviceIdentity,
) -> Self {
DeviceProperties {
features,
memory: memory_props,
hardware,
timing_method,
identity,
}
}
pub fn type_usage(&self, ty: StorageType) -> EnumSet<TypeUsage> {
self.features.type_usage(ty)
}
pub fn atomic_type_usage(&self, ty: Type) -> EnumSet<AtomicUsage> {
self.features.atomic_type_usage(ty)
}
pub fn supports_type(&self, ty: impl Into<Type>) -> bool {
self.features.supports_type(ty)
}
pub fn supports_address(&self, ty: impl Into<AddressType>) -> bool {
self.features.supports_address(ty)
}
pub fn register_address_type(&mut self, ty: impl Into<AddressType>) {
self.features.types.address.insert(ty.into());
}
pub fn register_atomic_type_usage(&mut self, ty: Type, uses: impl Into<EnumSet<AtomicUsage>>) {
*self.features.types.atomic.entry(ty).or_default() |= uses.into();
}
pub fn register_type_usage(
&mut self,
ty: impl Into<StorageType>,
uses: impl Into<EnumSet<TypeUsage>>,
) {
*self.features.types.storage.entry(ty.into()).or_default() |= uses.into();
}
pub fn register_semantic_type(&mut self, ty: SemanticType) {
self.features.types.semantic.insert(ty);
}
pub fn register_opaque_type(&mut self, ty: OpaqueType) {
self.features.types.opaque.insert(ty);
}
pub fn checksum(&self) -> u64 {
let state = foldhash::fast::FixedState::default();
let mut hasher = state.build_hasher();
self.features.hash(&mut hasher);
self.hardware.hash(&mut hasher);
hasher.finish()
}
}