use super::GpuBackend;
#[cfg(all(feature = "gpu", not(target_arch = "wasm32")))]
impl GpuBackend {
pub fn vec_add(&mut self, a: &[f32], b: &[f32]) -> Result<Vec<f32>, String> {
if a.len() != b.len() {
return Err(format!("Vector length mismatch: {} != {}", a.len(), b.len()));
}
if a.is_empty() {
return Err("Cannot perform GPU operation on empty vectors".to_string());
}
let device = self.ensure_device()?;
let mut result = vec![0.0f32; a.len()];
device.vec_add(a, b, &mut result)?;
Ok(result)
}
pub fn dot(&mut self, a: &[f32], b: &[f32]) -> Result<f32, String> {
if a.len() != b.len() {
return Err(format!("Vector length mismatch: {} != {}", a.len(), b.len()));
}
let device = self.ensure_device()?;
device.dot(a, b)
}
pub fn relu(&mut self, input: &[f32]) -> Result<Vec<f32>, String> {
let device = self.ensure_device()?;
let mut result = vec![0.0f32; input.len()];
device.relu(input, &mut result)?;
Ok(result)
}
pub fn leaky_relu(&mut self, input: &[f32], negative_slope: f32) -> Result<Vec<f32>, String> {
let device = self.ensure_device()?;
let mut result = vec![0.0f32; input.len()];
device.leaky_relu(input, &mut result, negative_slope)?;
Ok(result)
}
pub fn elu(&mut self, input: &[f32], alpha: f32) -> Result<Vec<f32>, String> {
let device = self.ensure_device()?;
let mut result = vec![0.0f32; input.len()];
device.elu(input, &mut result, alpha)?;
Ok(result)
}
pub fn clip(&mut self, input: &[f32], min_val: f32, max_val: f32) -> Result<Vec<f32>, String> {
let device = self.ensure_device()?;
let mut result = vec![0.0f32; input.len()];
device.clip(input, &mut result, min_val, max_val)?;
Ok(result)
}
pub fn sigmoid(&mut self, input: &[f32]) -> Result<Vec<f32>, String> {
let device = self.ensure_device()?;
let mut result = vec![0.0f32; input.len()];
device.sigmoid(input, &mut result)?;
Ok(result)
}
pub fn tanh(&mut self, input: &[f32]) -> Result<Vec<f32>, String> {
let device = self.ensure_device()?;
let mut result = vec![0.0f32; input.len()];
device.tanh(input, &mut result)?;
Ok(result)
}
pub fn swish(&mut self, input: &[f32]) -> Result<Vec<f32>, String> {
let device = self.ensure_device()?;
let mut result = vec![0.0f32; input.len()];
device.swish(input, &mut result)?;
Ok(result)
}
pub fn gelu(&mut self, input: &[f32]) -> Result<Vec<f32>, String> {
let device = self.ensure_device()?;
let mut result = vec![0.0f32; input.len()];
device.gelu(input, &mut result)?;
Ok(result)
}
pub fn softmax(&mut self, input: &[f32]) -> Result<Vec<f32>, String> {
contract_pre_softmax!(input);
let device = self.ensure_device()?;
let mut result = vec![0.0f32; input.len()];
device.softmax(input, &mut result)?;
contract_post_softmax!(&result);
Ok(result)
}
pub fn log_softmax(&mut self, input: &[f32]) -> Result<Vec<f32>, String> {
contract_pre_log_softmax!(input);
let device = self.ensure_device()?;
let mut result = vec![0.0f32; input.len()];
device.log_softmax(input, &mut result)?;
Ok(result)
}
pub fn convolve2d(
&mut self,
input: &[f32],
kernel: &[f32],
input_rows: usize,
input_cols: usize,
kernel_rows: usize,
kernel_cols: usize,
) -> Result<Vec<f32>, String> {
let device = self.ensure_device()?;
let output_rows = input_rows.saturating_sub(kernel_rows).saturating_add(1);
let output_cols = input_cols.saturating_sub(kernel_cols).saturating_add(1);
let mut result = vec![0.0f32; output_rows * output_cols];
device.convolve2d(
input,
kernel,
&mut result,
input_rows,
input_cols,
kernel_rows,
kernel_cols,
)?;
Ok(result)
}
pub fn matmul(
&mut self,
a: &[f32],
b: &[f32],
m: usize,
k: usize,
n: usize,
) -> Result<Vec<f32>, String> {
let device = self.ensure_device()?;
let mut result = vec![0.0f32; m * n];
device.matmul(a, b, &mut result, m, k, n)?;
Ok(result)
}
pub fn symmetric_eigen(
&mut self,
matrix: &[f32],
n: usize,
) -> Result<(Vec<f32>, Vec<f32>), String> {
let device = self.ensure_device()?;
device.symmetric_eigen(matrix, n)
}
pub fn tiled_sum_2d_gpu(
&mut self,
data: &[f32],
width: usize,
height: usize,
) -> Result<f32, String> {
let device = self.ensure_device()?;
device.tiled_sum_2d(data, width, height)
}
pub fn tiled_max_2d_gpu(
&mut self,
data: &[f32],
width: usize,
height: usize,
) -> Result<f32, String> {
let device = self.ensure_device()?;
device.tiled_max_2d(data, width, height)
}
pub fn tiled_min_2d_gpu(
&mut self,
data: &[f32],
width: usize,
height: usize,
) -> Result<f32, String> {
let device = self.ensure_device()?;
device.tiled_min_2d(data, width, height)
}
}