libmir-cuda 0.1.0

CUDA inference backend for libmir
use runtime::kv::BlockTable;
use uuid::Uuid;

use super::super::CudaMoeModelSession;
use crate::{CudaBackend, Result};

#[allow(clippy::cast_precision_loss, clippy::print_stderr)]
pub(super) fn run(
    backend: &CudaBackend,
    sequential: &mut CudaMoeModelSession,
    prefill: &mut CudaMoeModelSession,
    prompt: &[u32],
    table: &mut BlockTable,
) -> Result<()> {
    const REPEATS: usize = 10;
    let started = backend.inner.context.create_event(true)?;
    let completed = backend.inner.context.create_event(true)?;
    let decode_profile = std::env::var_os("LIBMIR_CUDA_PROFILE_DECODE").is_some();
    let profiler = decode_profile
        .then(|| backend.inner.context.start_profiler_range())
        .transpose()?;
    started.record(&backend.inner.stream)?;
    for _ in 0..REPEATS {
        for (index, token) in prompt.iter().copied().enumerate() {
            table.set_token_len(index + 1);
            sequential.decode(Uuid::nil(), token, table)?;
        }
    }
    completed.record(&backend.inner.stream)?;
    completed.synchronize()?;
    if let Some(profiler) = profiler {
        profiler.stop()?;
    }
    let sequential_ms = started.elapsed_ms(&completed)? / REPEATS as f32;

    table.set_token_len(prompt.len());
    prefill.prefill_from(Uuid::nil(), prompt, 0, table)?;
    backend.inner.stream.synchronize()?;
    let profiler = (!decode_profile)
        .then(|| backend.inner.context.start_profiler_range())
        .transpose()?;
    started.record(&backend.inner.stream)?;
    for _ in 0..REPEATS {
        prefill.prefill_from(Uuid::nil(), prompt, 0, table)?;
    }
    completed.record(&backend.inner.stream)?;
    completed.synchronize()?;
    if let Some(profiler) = profiler {
        profiler.stop()?;
    }
    let prefill_ms = started.elapsed_ms(&completed)? / REPEATS as f32;
    let tokens = prompt.len() as f32;
    eprintln!(
        "sequential prefill: {sequential_ms:.3} ms, {:.1} tok/s",
        tokens * 1_000.0 / sequential_ms
    );
    eprintln!(
        "batched prefill:    {prefill_ms:.3} ms, {:.1} tok/s",
        tokens * 1_000.0 / prefill_ms
    );
    Ok(())
}