libmir-cuda 0.2.0

CUDA inference backend for libmir
use mircuda::{
    CompileOptions, Compiler, DeviceBuffer, LaunchConfig, Stream, TypedKernel, bf16, cuda_export,
    cuda_kernel_file,
};

use super::super::geometry::{narrow, product, require};
use crate::{Error, Result};

cuda_export!(
    SpliceKernel = "libmir_cuda_vision_embedding_splice_bf16"(
        image: &DeviceBuffer<bf16>, hidden: &mut DeviceBuffer<bf16>,
        image_tokens: u32, hidden_width: u32, destination_start: u32,
    )
);

#[derive(Clone, Debug)]
pub struct VisionEmbeddingSplice {
    kernel: TypedKernel<SpliceKernel>,
    image_tokens: usize,
    hidden_width: usize,
    destination_start: usize,
}

impl VisionEmbeddingSplice {
    pub(crate) fn compile(
        compiler: &Compiler,
        image_tokens: usize,
        hidden_width: usize,
        destination_start: usize,
    ) -> Result<Self> {
        if image_tokens == 0 || hidden_width == 0 {
            return Err(Error::InvalidVisionKernel("invalid embedding splice geometry"));
        }
        let module = compiler.compile(
            cuda_kernel_file!("../../../kernels/vision_splice_bf16.cu"),
            &CompileOptions::default(),
        )?;
        Ok(Self {
            kernel: module.kernel()?,
            image_tokens,
            hidden_width,
            destination_start,
        })
    }

    pub(crate) fn execute(
        &self,
        stream: &Stream,
        image: &DeviceBuffer<bf16>,
        hidden: &mut DeviceBuffer<bf16>,
    ) -> Result<()> {
        let elements = product(self.image_tokens, self.hidden_width)?;
        let destination = product(self.destination_start + self.image_tokens, self.hidden_width)?;
        require("vision splice image", elements, image.len())?;
        require("vision splice destination", destination, hidden.len())?;
        Ok(self.kernel.launch(
            stream,
            LaunchConfig {
                grid: (narrow(elements.div_ceil(256))?, 1, 1),
                block: (256, 1, 1),
                shared_memory_bytes: 0,
            },
            (
                image,
                hidden,
                narrow(self.image_tokens)?,
                narrow(self.hidden_width)?,
                narrow(self.destination_start)?,
            ),
        )?)
    }
}