use crate::{Backend, BackendTypes, DeviceOps, get_device_settings};
use burn_std::{DType, QuantScheme, Shape};
#[derive(Debug, Clone)]
pub enum TensorPrimitive<B: BackendTypes> {
Float(B::FloatTensorPrimitive),
QFloat(B::QuantizedTensorPrimitive),
}
impl<B: Backend> TensorPrimitive<B> {
pub fn tensor(self) -> B::FloatTensorPrimitive {
match self {
Self::QFloat(tensor) => {
let dtype = get_device_settings::<B>(&tensor.device()).float_dtype;
B::dequantize(tensor, dtype)
}
Self::Float(tensor) => tensor,
}
}
pub fn get_mut_ref(&mut self) -> &mut B::FloatTensorPrimitive {
match self {
Self::QFloat(_tensor) => todo!(),
Self::Float(tensor) => tensor,
}
}
}
impl<B: BackendTypes> TensorMetadata for TensorPrimitive<B> {
type Device = B::Device;
fn dtype(&self) -> DType {
match self {
TensorPrimitive::Float(tensor) => tensor.dtype(),
TensorPrimitive::QFloat(tensor) => tensor.dtype(),
}
}
fn shape(&self) -> Shape {
match self {
TensorPrimitive::Float(tensor) => tensor.shape(),
TensorPrimitive::QFloat(tensor) => tensor.shape(),
}
}
fn rank(&self) -> usize {
match self {
TensorPrimitive::Float(tensor) => tensor.rank(),
TensorPrimitive::QFloat(tensor) => tensor.rank(),
}
}
fn device(&self) -> Self::Device {
match self {
TensorPrimitive::Float(tensor) => tensor.device(),
TensorPrimitive::QFloat(tensor) => tensor.device(),
}
}
fn can_mut(&self) -> bool {
match self {
TensorPrimitive::Float(tensor) => tensor.can_mut(),
TensorPrimitive::QFloat(tensor) => tensor.can_mut(),
}
}
}
pub trait TensorMetadata: Clone + Send + Sync + core::fmt::Debug {
type Device: DeviceOps;
fn dtype(&self) -> DType;
fn shape(&self) -> Shape;
fn rank(&self) -> usize {
self.shape().num_dims()
}
fn device(&self) -> Self::Device;
fn can_mut(&self) -> bool;
fn scheme(&self) -> QuantScheme {
match self.dtype() {
DType::QFloat(scheme) => scheme,
other => panic!("Quantization scheme is not valid for dtype {other:?}"),
}
}
}