use crate::mamba_ssm::gpu::kernels::{HalfKernel, TypedKernel};
use cudarc::driver::{CudaContext, CudaFunction, CudaModule};
use std::sync::Arc;
pub struct Mamba3Kernels {
_module: Arc<CudaModule>,
pub m3_step_fwd: CudaFunction,
pub m3_burnin_fwd: CudaFunction,
pub m3_burnin_fwd_nosave: CudaFunction,
pub m3_backward_seq: CudaFunction,
pub m3_reduce_d_d: CudaFunction,
pub m3_split: CudaFunction,
pub m3_split_bwd: CudaFunction,
pub bcnorm_fwd: CudaFunction,
pub bcnorm_bwd: CudaFunction,
pub bc_bias_add: CudaFunction,
pub bc_bias_add_bwd: CudaFunction,
pub angle_dt_fwd: CudaFunction,
pub m3_angle_dt_fwd_batch: CudaFunction,
pub m3_angle_dt_fwd_seq: CudaFunction,
pub angle_dt_bwd: CudaFunction,
pub m3_angle_dt_bwd_seq: CudaFunction,
pub rope_fwd: CudaFunction,
pub rope_bwd: CudaFunction,
pub m3_compute_abg: CudaFunction,
pub m3_abg_bwd: CudaFunction,
pub silu_gate_fwd: CudaFunction,
pub silu_gate_bwd: CudaFunction,
pub rmsnorm_gated_fwd: CudaFunction,
pub rmsnorm_gated_bwd: CudaFunction,
pub rmsnorm_fwd: CudaFunction,
pub rmsnorm_bwd: CudaFunction,
pub colsum_accumulate: CudaFunction,
pub reduce_sum_axis0: CudaFunction,
pub vec_add_inplace: CudaFunction,
pub elementwise_mul: CudaFunction,
pub fill_scalar: CudaFunction,
pub cast_f32_to_bf16: CudaFunction,
pub cast_f32_to_f16: CudaFunction,
pub cast_bf16_to_f32: CudaFunction,
pub cast_f16_to_f32: CudaFunction,
pub residual_add: CudaFunction,
pub gather_last_timestep: CudaFunction,
pub adamw_step_f32: CudaFunction,
pub adamw_step_f32_capturable: CudaFunction,
pub m3_preprocess_chunks: CudaFunction,
pub m3_da_cumsum: CudaFunction,
pub m3_chunk_state_fwd: CudaFunction,
pub m3_state_passing_fwd: CudaFunction,
pub m3_writeback_parallel_states: CudaFunction,
pub m3_chunk_scan_fwd: CudaFunction,
pub m3_extract_da_cs_sum: CudaFunction,
pub m3_dqkv: CudaFunction,
pub m3_dqktheta: CudaFunction,
pub m3_ddt_dtrap: CudaFunction,
pub m3_final_grads: CudaFunction,
pub m3_split_typed: TypedKernel,
pub bcnorm_fwd_typed: TypedKernel,
pub bcnorm_fwd_bc_typed: TypedKernel,
pub bc_bias_add_typed: TypedKernel,
pub bc_bias_add_bc_typed: TypedKernel,
pub rope_fwd_typed: TypedKernel,
pub silu_gate_fwd_typed: TypedKernel,
pub rmsnorm_gated_fwd_typed: TypedKernel,
pub m3_step_fwd_typed: TypedKernel,
pub m3_burnin_fwd_typed_bf16: CudaFunction,
pub m3_burnin_fwd_typed_f16: CudaFunction,
pub bcnorm_bwd_typed: TypedKernel,
pub bc_bias_add_bwd_typed: TypedKernel,
pub rope_bwd_typed: TypedKernel,
pub m3_split_bwd_typed: TypedKernel,
pub rmsnorm_gated_bwd_typed: TypedKernel,
pub m3_dqkv_typed: TypedKernel,
pub m3_dqktheta_typed: TypedKernel,
pub m3_preprocess_chunks_typed: TypedKernel,
pub m3_chunk_state_fwd_typed: TypedKernel,
pub m3_writeback_parallel_states_typed: TypedKernel,
pub m3_chunk_scan_fwd_typed: TypedKernel,
pub rmsnorm_fwd_f32in_typed: HalfKernel,
pub residual_add_f32_typed: HalfKernel,
pub gather_last_timestep_typed: TypedKernel,
}
impl Mamba3Kernels {
pub fn compile(ctx: &Arc<CudaContext>, arch: &'static str) -> Result<Self, String> {
let sources = [
include_str!("../../../kernels/_typed_prelude.cuh"),
include_str!("../../../kernels/mamba3_ssd.cu"),
include_str!("../../../kernels/mamba3_ops.cu"),
include_str!("../../../kernels/mamba3_chunked.cu"),
include_str!("../../../kernels/norms.cu"),
include_str!("../../../kernels/elementwise.cu"),
include_str!("../../../kernels/adamw.cu"),
];
let combined: String = sources
.iter()
.map(|s| {
s.lines()
.filter(|l| !l.trim().starts_with("#include \"_typed_prelude.cuh\""))
.collect::<Vec<_>>()
.join("\n")
})
.collect::<Vec<_>>()
.join("\n");
let opts = cudarc::nvrtc::CompileOptions {
arch: Some(arch),
options: vec![
"--fmad=true".to_string(),
"--extra-device-vectorization".to_string(),
],
include_paths: crate::mamba_ssm::gpu::kernels::cuda_include_paths(),
..Default::default()
};
let ptx = cudarc::nvrtc::compile_ptx_with_opts(combined, opts)
.map_err(|e| format!("NVRTC M3 compile failed: {e:?}"))?;
let module = ctx
.load_module(ptx)
.map_err(|e| format!("M3 module load failed: {e:?}"))?;
let get = |name: &str| -> Result<CudaFunction, String> {
module
.load_function(name)
.map_err(|e| format!("M3 kernel '{name}' not found: {e:?}"))
};
Ok(Self {
m3_step_fwd: get("m3_step_fwd")?,
m3_burnin_fwd: get("m3_burnin_fwd")?,
m3_burnin_fwd_nosave: get("m3_burnin_fwd_nosave")?,
m3_backward_seq: get("m3_backward_seq")?,
m3_reduce_d_d: get("m3_reduce_d_D")?,
m3_split: get("m3_split")?,
m3_split_bwd: get("m3_split_bwd")?,
bcnorm_fwd: get("bcnorm_fwd")?,
bcnorm_bwd: get("bcnorm_bwd")?,
bc_bias_add: get("bc_bias_add")?,
bc_bias_add_bwd: get("bc_bias_add_bwd")?,
angle_dt_fwd: get("angle_dt_fwd")?,
m3_angle_dt_fwd_batch: get("m3_angle_dt_fwd_batch")?,
m3_angle_dt_fwd_seq: get("m3_angle_dt_fwd_seq")?,
angle_dt_bwd: get("angle_dt_bwd")?,
m3_angle_dt_bwd_seq: get("m3_angle_dt_bwd_seq")?,
rope_fwd: get("rope_fwd")?,
rope_bwd: get("rope_bwd")?,
m3_compute_abg: get("m3_compute_abg")?,
m3_abg_bwd: get("m3_abg_bwd")?,
silu_gate_fwd: get("silu_gate_fwd")?,
silu_gate_bwd: get("silu_gate_bwd")?,
rmsnorm_gated_fwd: get("rmsnorm_gated_forward")?,
rmsnorm_gated_bwd: get("rmsnorm_gated_backward")?,
rmsnorm_fwd: get("rmsnorm_forward")?,
rmsnorm_bwd: get("rmsnorm_backward")?,
colsum_accumulate: get("colsum_accumulate")?,
reduce_sum_axis0: get("reduce_sum_axis0")?,
vec_add_inplace: get("vec_add_inplace")?,
elementwise_mul: get("elementwise_mul")?,
fill_scalar: get("fill_scalar")?,
cast_f32_to_bf16: get("cast_f32_to_bf16")?,
cast_f32_to_f16: get("cast_f32_to_f16")?,
cast_bf16_to_f32: get("cast_bf16_to_f32")?,
cast_f16_to_f32: get("cast_f16_to_f32")?,
residual_add: get("residual_add")?,
gather_last_timestep: get("gather_last_timestep")?,
adamw_step_f32: get("adamw_step_f32")?,
adamw_step_f32_capturable: get("adamw_step_f32_capturable")?,
m3_preprocess_chunks: get("m3_preprocess_chunks")?,
m3_da_cumsum: get("m3_dA_cumsum")?,
m3_chunk_state_fwd: get("m3_chunk_state_fwd")?,
m3_state_passing_fwd: get("m3_state_passing_fwd")?,
m3_writeback_parallel_states: get("m3_writeback_parallel_states")?,
m3_chunk_scan_fwd: get("m3_chunk_scan_fwd")?,
m3_extract_da_cs_sum: get("m3_extract_da_cs_sum")?,
m3_dqkv: get("m3_dqkv")?,
m3_dqktheta: get("m3_dqktheta")?,
m3_ddt_dtrap: get("m3_ddt_dtrap")?,
m3_final_grads: get("m3_final_grads")?,
m3_split_typed: TypedKernel {
f32: get("m3_split")?,
bf16: get("m3_split_bf16")?,
f16: get("m3_split_f16")?,
},
bcnorm_fwd_typed: TypedKernel {
f32: get("bcnorm_fwd")?,
bf16: get("bcnorm_fwd_bf16")?,
f16: get("bcnorm_fwd_f16")?,
},
bcnorm_fwd_bc_typed: TypedKernel {
f32: get("bcnorm_fwd")?,
bf16: get("bcnorm_fwd_bc_bf16")?,
f16: get("bcnorm_fwd_bc_f16")?,
},
bc_bias_add_typed: TypedKernel {
f32: get("bc_bias_add")?,
bf16: get("bc_bias_add_bf16")?,
f16: get("bc_bias_add_f16")?,
},
bc_bias_add_bc_typed: TypedKernel {
f32: get("bc_bias_add")?,
bf16: get("bc_bias_add_bc_bf16")?,
f16: get("bc_bias_add_bc_f16")?,
},
rope_fwd_typed: TypedKernel {
f32: get("rope_fwd")?,
bf16: get("rope_fwd_bf16")?,
f16: get("rope_fwd_f16")?,
},
silu_gate_fwd_typed: TypedKernel {
f32: get("silu_gate_fwd")?,
bf16: get("silu_gate_fwd_bf16")?,
f16: get("silu_gate_fwd_f16")?,
},
rmsnorm_gated_fwd_typed: TypedKernel {
f32: get("rmsnorm_gated_forward")?,
bf16: get("rmsnorm_gated_forward_bf16")?,
f16: get("rmsnorm_gated_forward_f16")?,
},
m3_step_fwd_typed: TypedKernel {
f32: get("m3_step_fwd")?,
bf16: get("m3_step_fwd_bf16")?,
f16: get("m3_step_fwd_f16")?,
},
m3_burnin_fwd_typed_bf16: get("m3_burnin_fwd_bf16")?,
m3_burnin_fwd_typed_f16: get("m3_burnin_fwd_f16")?,
bcnorm_bwd_typed: TypedKernel {
f32: get("bcnorm_bwd")?,
bf16: get("bcnorm_bwd_bf16")?,
f16: get("bcnorm_bwd_f16")?,
},
bc_bias_add_bwd_typed: TypedKernel {
f32: get("bc_bias_add_bwd")?,
bf16: get("bc_bias_add_bwd_bf16")?,
f16: get("bc_bias_add_bwd_f16")?,
},
rope_bwd_typed: TypedKernel {
f32: get("rope_bwd")?,
bf16: get("rope_bwd_bf16")?,
f16: get("rope_bwd_f16")?,
},
m3_split_bwd_typed: TypedKernel {
f32: get("m3_split_bwd")?,
bf16: get("m3_split_bwd_bf16")?,
f16: get("m3_split_bwd_f16")?,
},
rmsnorm_gated_bwd_typed: TypedKernel {
f32: get("rmsnorm_gated_backward")?,
bf16: get("rmsnorm_gated_backward_bf16")?,
f16: get("rmsnorm_gated_backward_f16")?,
},
m3_dqkv_typed: TypedKernel {
f32: get("m3_dqkv")?,
bf16: get("m3_dqkv_bf16")?,
f16: get("m3_dqkv_f16")?,
},
m3_dqktheta_typed: TypedKernel {
f32: get("m3_dqktheta")?,
bf16: get("m3_dqktheta_bf16")?,
f16: get("m3_dqktheta_f16")?,
},
m3_preprocess_chunks_typed: TypedKernel {
f32: get("m3_preprocess_chunks")?,
bf16: get("m3_preprocess_chunks_bf16")?,
f16: get("m3_preprocess_chunks_f16")?,
},
m3_chunk_state_fwd_typed: TypedKernel {
f32: get("m3_chunk_state_fwd")?,
bf16: get("m3_chunk_state_fwd_bf16")?,
f16: get("m3_chunk_state_fwd_f16")?,
},
m3_writeback_parallel_states_typed: TypedKernel {
f32: get("m3_writeback_parallel_states")?,
bf16: get("m3_writeback_parallel_states_bf16")?,
f16: get("m3_writeback_parallel_states_f16")?,
},
m3_chunk_scan_fwd_typed: TypedKernel {
f32: get("m3_chunk_scan_fwd")?,
bf16: get("m3_chunk_scan_fwd_bf16")?,
f16: get("m3_chunk_scan_fwd_f16")?,
},
rmsnorm_fwd_f32in_typed: HalfKernel {
bf16: get("rmsnorm_forward_f32in_bf16")?,
f16: get("rmsnorm_forward_f32in_f16")?,
},
residual_add_f32_typed: HalfKernel {
bf16: get("residual_add_f32_bf16")?,
f16: get("residual_add_f32_f16")?,
},
gather_last_timestep_typed: TypedKernel {
f32: get("gather_last_timestep_f32")?,
bf16: get("gather_last_timestep_bf16")?,
f16: get("gather_last_timestep_f16")?,
},
_module: module,
})
}
}