singe-kernel 0.1.0-alpha.4

Reusable CPU and GPU kernels.
Documentation
use super::*;

#[cfg(feature = "dtype-f32")]
/// Causal left-window attention.
///
/// For query absolute position `q_abs`, only keys satisfying `key_abs <= q_abs` and `key_abs + window > q_abs` are visible.
/// KV heads are mapped with contiguous grouped-query attention semantics.
pub fn sliding_window_attention_f32(
    stream: &Arc<Stream>,
    out: DevicePointer<f32>,
    query: DevicePointer<f32>,
    key: DevicePointer<f32>,
    value: DevicePointer<f32>,
    batch: usize,
    query_len: usize,
    key_len: usize,
    heads: usize,
    kv_heads: usize,
    head_dim: usize,
    query_start: usize,
    key_start: usize,
    window: usize,
    query_batch_stride: usize,
    key_batch_stride: usize,
    value_batch_stride: usize,
    output_batch_stride: usize,
    query_sequence_stride: usize,
    key_sequence_stride: usize,
    value_sequence_stride: usize,
    output_sequence_stride: usize,
    query_head_stride: usize,
    key_head_stride: usize,
    value_head_stride: usize,
    output_head_stride: usize,
    scale: f32,
    output_scale: f32,
) -> Result<()> {
    checked_device_pointer(out)?;
    checked_device_pointer(query)?;
    checked_device_pointer(key)?;
    checked_device_pointer(value)?;

    let params = SlidingWindowAttention::create(
        batch,
        query_len,
        key_len,
        heads,
        kv_heads,
        head_dim,
        query_start,
        key_start,
        window,
        query_batch_stride,
        key_batch_stride,
        value_batch_stride,
        output_batch_stride,
        query_sequence_stride,
        key_sequence_stride,
        value_sequence_stride,
        output_sequence_stride,
        query_head_stride,
        key_head_stride,
        value_head_stride,
        output_head_stride,
        scale,
        output_scale,
    )?;
    let SlidingWindowAttention {
        batch,
        query_len,
        key_len,
        heads,
        kv_heads,
        query_start,
        key_start,
        window,
        output_len: output_len_i32,
        output_values_per_batch,
        query_batch_stride,
        key_batch_stride,
        value_batch_stride,
        output_batch_stride,
        query_sequence_stride,
        key_sequence_stride,
        value_sequence_stride,
        output_sequence_stride,
        query_head_stride,
        key_head_stride,
        value_head_stride,
        output_head_stride,
        grid,
    } = params;

    match (head_dim, window) {
        (32, 128) => unsafe {
            kernel_attention::sliding_window_attention_f32_hd32_w128(
                out,
                query,
                key,
                value,
                batch,
                query_len,
                key_len,
                heads,
                kv_heads,
                query_start,
                key_start,
                window,
                query_batch_stride,
                key_batch_stride,
                value_batch_stride,
                output_batch_stride,
                query_sequence_stride,
                key_sequence_stride,
                value_sequence_stride,
                output_sequence_stride,
                query_head_stride,
                key_head_stride,
                value_head_stride,
                output_head_stride,
                scale,
                output_scale,
                output_len_i32,
                output_values_per_batch,
            )
        }
        .grid(grid)
        .enqueue_on(stream)?,
        (64, 750) => unsafe {
            kernel_attention::sliding_window_attention_f32_hd64_w750(
                out,
                query,
                key,
                value,
                batch,
                query_len,
                key_len,
                heads,
                kv_heads,
                query_start,
                key_start,
                window,
                query_batch_stride,
                key_batch_stride,
                value_batch_stride,
                output_batch_stride,
                query_sequence_stride,
                key_sequence_stride,
                value_sequence_stride,
                output_sequence_stride,
                query_head_stride,
                key_head_stride,
                value_head_stride,
                output_head_stride,
                scale,
                output_scale,
                output_len_i32,
                output_values_per_batch,
            )
        }
        .grid(grid)
        .enqueue_on(stream)?,
        (64, 1024) => unsafe {
            kernel_attention::sliding_window_attention_f32_hd64_w1024(
                out,
                query,
                key,
                value,
                batch,
                query_len,
                key_len,
                heads,
                kv_heads,
                query_start,
                key_start,
                window,
                query_batch_stride,
                key_batch_stride,
                value_batch_stride,
                output_batch_stride,
                query_sequence_stride,
                key_sequence_stride,
                value_sequence_stride,
                output_sequence_stride,
                query_head_stride,
                key_head_stride,
                value_head_stride,
                output_head_stride,
                scale,
                output_scale,
                output_len_i32,
                output_values_per_batch,
            )
        }
        .grid(grid)
        .enqueue_on(stream)?,
        (4, _) => unsafe {
            kernel_attention::sliding_window_attention_f32_hd4(
                out,
                query,
                key,
                value,
                batch,
                query_len,
                key_len,
                heads,
                kv_heads,
                query_start,
                key_start,
                window,
                query_batch_stride,
                key_batch_stride,
                value_batch_stride,
                output_batch_stride,
                query_sequence_stride,
                key_sequence_stride,
                value_sequence_stride,
                output_sequence_stride,
                query_head_stride,
                key_head_stride,
                value_head_stride,
                output_head_stride,
                scale,
                output_scale,
                output_len_i32,
                output_values_per_batch,
            )
        }
        .grid(grid)
        .enqueue_on(stream)?,
        (8, _) => unsafe {
            kernel_attention::sliding_window_attention_f32_hd8(
                out,
                query,
                key,
                value,
                batch,
                query_len,
                key_len,
                heads,
                kv_heads,
                query_start,
                key_start,
                window,
                query_batch_stride,
                key_batch_stride,
                value_batch_stride,
                output_batch_stride,
                query_sequence_stride,
                key_sequence_stride,
                value_sequence_stride,
                output_sequence_stride,
                query_head_stride,
                key_head_stride,
                value_head_stride,
                output_head_stride,
                scale,
                output_scale,
                output_len_i32,
                output_values_per_batch,
            )
        }
        .grid(grid)
        .enqueue_on(stream)?,
        (16, _) => unsafe {
            kernel_attention::sliding_window_attention_f32_hd16(
                out,
                query,
                key,
                value,
                batch,
                query_len,
                key_len,
                heads,
                kv_heads,
                query_start,
                key_start,
                window,
                query_batch_stride,
                key_batch_stride,
                value_batch_stride,
                output_batch_stride,
                query_sequence_stride,
                key_sequence_stride,
                value_sequence_stride,
                output_sequence_stride,
                query_head_stride,
                key_head_stride,
                value_head_stride,
                output_head_stride,
                scale,
                output_scale,
                output_len_i32,
                output_values_per_batch,
            )
        }
        .grid(grid)
        .enqueue_on(stream)?,
        (32, _) => unsafe {
            kernel_attention::sliding_window_attention_f32_hd32(
                out,
                query,
                key,
                value,
                batch,
                query_len,
                key_len,
                heads,
                kv_heads,
                query_start,
                key_start,
                window,
                query_batch_stride,
                key_batch_stride,
                value_batch_stride,
                output_batch_stride,
                query_sequence_stride,
                key_sequence_stride,
                value_sequence_stride,
                output_sequence_stride,
                query_head_stride,
                key_head_stride,
                value_head_stride,
                output_head_stride,
                scale,
                output_scale,
                output_len_i32,
                output_values_per_batch,
            )
        }
        .grid(grid)
        .enqueue_on(stream)?,
        (64, _) => unsafe {
            kernel_attention::sliding_window_attention_f32_hd64(
                out,
                query,
                key,
                value,
                batch,
                query_len,
                key_len,
                heads,
                kv_heads,
                query_start,
                key_start,
                window,
                query_batch_stride,
                key_batch_stride,
                value_batch_stride,
                output_batch_stride,
                query_sequence_stride,
                key_sequence_stride,
                value_sequence_stride,
                output_sequence_stride,
                query_head_stride,
                key_head_stride,
                value_head_stride,
                output_head_stride,
                scale,
                output_scale,
                output_len_i32,
                output_values_per_batch,
            )
        }
        .grid(grid)
        .enqueue_on(stream)?,
        _ => {
            return Err(Error::UnsupportedWidth {
                op: "sliding_window_attention_f32 head_dim".into(),
                width: head_dim,
            });
        }
    };
    Ok(())
}