use mircuda::{DeviceBuffer, bf16};
use super::{AutoBf16Plan, CudaBackend};
use crate::{CudaTensor, DensePlanRequest, Error, Result};
#[derive(Debug)]
pub struct Bf16Projection {
operation: AutoBf16Plan,
}
impl CudaBackend {
pub fn prepare_bf16_projection(&self, request: DensePlanRequest) -> Result<Bf16Projection> {
Ok(Bf16Projection {
operation: AutoBf16Plan::new(self, request)?,
})
}
}
impl Bf16Projection {
pub fn execute(
&mut self,
input: &DeviceBuffer<bf16>,
weight: &CudaTensor,
output: &mut DeviceBuffer<bf16>,
) -> Result<()> {
let expected =
[self.operation.request().output_features, self.operation.request().input_features];
if weight.shape() != expected {
return Err(Error::InvalidLinearWeight {
name: weight.name().into(),
expected,
actual: weight.shape().to_vec(),
});
}
let weight = weight.as_bf16().ok_or_else(|| Error::DTypeMismatch {
name: weight.name().into(),
expected: "BF16",
})?;
self.operation.execute(input, weight, output)
}
}