luma-cuda 0.3.2

luma cuda implement
use luma_tensor::Layout;
use crate::builder_arg;
use crate::kernel;
use crate::{Cuda, CudaError, CudaResult};
use cudarc::driver::{CudaSlice, DeviceRepr, LaunchConfig, PushKernelArg};

pub(crate) fn launch_copy_offset<T: DeviceRepr>(
    device: &Cuda,
    kernel_name: &str,
    module: &kernel::Module,
    src: &CudaSlice<T>,
    layout: &Layout,
    dst: &CudaSlice<T>,
    dst_offset: usize,
) -> CudaResult<()> {
    let dims = layout.dims();
    let elem_count = layout.shape().element_count();
    let num_dims = dims.len();
    let func = device.load_function(kernel_name, module)?;

    let mut builder = func.builder();
    let dims = device.memcpy_stod(dims)?;
    let strides = device.memcpy_stod(layout.stride())?;
    let src_view = src.slice(layout.start_offset()..);
    builder_arg!(builder, elem_count);
    builder_arg!(builder, num_dims);
    builder.arg(&dims);
    builder.arg(&strides);
    builder.arg(&dst_offset);
    builder.arg(&src_view);
    builder.arg(dst);

    let config = LaunchConfig::for_num_elems(elem_count as u32);
    unsafe { builder.launch(config) }.map_err(CudaError::CudaDriver)?;
    Ok(())
}

pub(crate) fn launch_copy2d<T: DeviceRepr>(
    device: &Cuda,
    kernel_name: &str,
    module: &kernel::Module,
    d1: usize,
    d2: usize,
    src_s: usize,
    dst_s: usize,
    src: &CudaSlice<T>,
    src_offset: usize,
    dst: &CudaSlice<T>,
    dst_offset: usize,
) -> CudaResult<()> {
    let func = device.load_function(kernel_name, module)?;
    let total = d1 * d2;

    let mut builder = func.builder();
    let src_view = src.slice(src_offset..);
    let dst_view = dst.slice(dst_offset..);
    builder_arg!(builder, d1);
    builder_arg!(builder, d2);
    builder_arg!(builder, src_s);
    builder_arg!(builder, dst_s);
    builder.arg(&src_view);
    builder.arg(&dst_view);

    let config = LaunchConfig::for_num_elems(total as u32);
    unsafe { builder.launch(config) }.map_err(CudaError::CudaDriver)?;
    Ok(())
}