use cubecl::prelude::*;
use cubecl::server::Handle;
use cubecl::zspace::{Shape, Strides};
use super::DspFloat;
pub fn transpose<F: DspFloat>(client: &Client, input: &Handle, output: &Handle, rows: usize, cols: usize) {
transpose_strided::<F>(client, input, output, rows, cols, cols, rows);
}
pub fn transpose_strided<F: DspFloat>(
client: &Client,
input: &Handle,
output: &Handle,
rows: usize,
cols: usize,
in_row_stride: usize,
out_row_stride: usize,
) {
if rows == 0 || cols == 0 {
return;
}
debug_assert!(in_row_stride >= cols && out_row_stride >= rows, "row strides below the row lengths");
if in_row_stride != cols || out_row_stride != rows {
let geom = dspk_core::compute::LaunchGeometry::elementwise(client, rows * cols);
unsafe {
super::kernels::transpose_strided_kernel::launch::<F>(
client,
geom.cube_count,
geom.cube_dim,
BufferArg::from_raw_parts(input.clone(), (rows - 1) * in_row_stride + cols),
BufferArg::from_raw_parts(output.clone(), (cols - 1) * out_row_stride + rows),
rows as u32,
cols as u32,
in_row_stride as u32,
out_row_stride as u32,
);
}
return;
}
let (input, output) = unsafe {
(
TensorBinding::from_raw_parts(input.clone(), Strides::new(&[1, in_row_stride]), Shape::new([cols, rows])),
TensorBinding::from_raw_parts(output.clone(), Strides::new(&[out_row_stride, 1]), Shape::new([cols, rows])),
)
};
cubecl::std::tensor::copy_into(client, input, output, F::elem_type_native());
}