use num_complex::{Complex32, Complex64};
use tenferro_tensor::{DType, ElementwiseReadOp};
use threadteam::Exec;
use crate::buffer_pool::{BufferPool, PoolScalar};
use crate::{Tensor, TensorRead, TensorWrite, TypedTensor};
use super::{copy_tensor_read_into, elementwise};
pub(crate) fn elementwise_read_into_fallback_with_pool(
buffers: &mut BufferPool,
op: ElementwiseReadOp,
inputs: &[TensorRead<'_>],
out: TensorWrite<'_>,
mut exec: Exec<'_>,
) -> crate::Result<()> {
let result = match op {
ElementwiseReadOp::Add => elementwise::add_read_with_pool(
buffers,
inputs[0].clone(),
inputs[1].clone(),
exec.reborrow(),
)?,
ElementwiseReadOp::Subtract => elementwise::sub_read_with_pool(
buffers,
inputs[0].clone(),
inputs[1].clone(),
exec.reborrow(),
)?,
ElementwiseReadOp::Multiply => elementwise::mul_read_with_pool(
buffers,
inputs[0].clone(),
inputs[1].clone(),
exec.reborrow(),
)?,
ElementwiseReadOp::Negate => {
elementwise::neg_read_with_pool(buffers, inputs[0].clone(), exec.reborrow())?
}
ElementwiseReadOp::Conj => {
elementwise::conj_read_with_pool(buffers, inputs[0].clone(), exec.reborrow())?
}
ElementwiseReadOp::Divide => elementwise::div_read_with_pool(
buffers,
inputs[0].clone(),
inputs[1].clone(),
exec.reborrow(),
)?,
_ => {
return Err(crate::Error::unsupported(
"CpuEngine::elementwise_read_into",
format!("CPU backend does not implement {op:?}"),
))
}
};
let copied = copy_tensor_read_into(
"CpuEngine::elementwise_read_into",
TensorRead::from_tensor(&result),
out,
exec,
);
reclaim_tensor(buffers, result);
copied
}
pub(crate) fn reclaim_tensor(buffers: &mut BufferPool, tensor: Tensor) {
match tensor.dtype() {
DType::F32 => reclaim_tensor_typed::<f32>(buffers, tensor),
DType::F64 => reclaim_tensor_typed::<f64>(buffers, tensor),
DType::I32 => reclaim_tensor_typed::<i32>(buffers, tensor),
DType::I64 => reclaim_tensor_typed::<i64>(buffers, tensor),
DType::Bool => reclaim_tensor_typed::<bool>(buffers, tensor),
DType::C32 => reclaim_tensor_typed::<Complex32>(buffers, tensor),
DType::C64 => reclaim_tensor_typed::<Complex64>(buffers, tensor),
DType::External(_) => {}
}
}
fn reclaim_tensor_typed<T: tenferro_cpu_basic::PoolScalar>(
buffers: &mut BufferPool,
tensor: Tensor,
) {
if let Ok(typed) = tensor.into_typed::<T>() {
reclaim_typed(buffers, typed);
}
}
pub(crate) fn reclaim_typed<T: PoolScalar>(pool: &mut BufferPool, typed: TypedTensor<T>) {
if typed.backend_buffer().is_some() {
return;
}
if let Ok(data) = typed.into_host_vec() {
T::pool_release(pool, data);
}
}
#[cfg(test)]
mod tests;