use std::sync::Arc;
use crate::config::MambaConfig;
use crate::mamba_ssm::gpu::context::GpuCtx;
use crate::mamba_ssm::gpu::dtype::WeightDtype;
use crate::mamba_ssm::gpu::weights::{GpuMambaMixedWeights, GpuMambaTrainWeights};
use crate::weights::MambaWeights;
pub struct GpuMambaTrainMixedWeights {
pub master: GpuMambaTrainWeights,
pub compute: GpuMambaMixedWeights,
pub dtype: WeightDtype,
}
impl GpuMambaTrainMixedWeights {
pub fn from_cpu(
stream: &Arc<cudarc::driver::CudaStream>,
cpu: &MambaWeights,
cfg: &MambaConfig,
dtype: WeightDtype,
) -> Result<Self, String> {
let master = GpuMambaTrainWeights::from_cpu(stream, cpu)?;
let compute = GpuMambaMixedWeights::from_cpu(stream, cpu, cfg, dtype)?;
Ok(Self {
master,
compute,
dtype,
})
}
pub fn sync_master_to_compute(&self, ctx: &GpuCtx) -> Result<(), String> {
sync_f32(ctx, &self.master.input_proj_b, &self.compute.input_proj_b)?;
for (mw, cw) in self.master.layers.iter().zip(&self.compute.layers) {
sync_f32(ctx, &mw.norm_weight, &cw.norm_weight)?;
sync_f32(ctx, &mw.conv1d_weight, &cw.conv1d_weight)?;
sync_f32(ctx, &mw.conv1d_bias, &cw.conv1d_bias)?;
sync_f32(ctx, &mw.dt_proj_b, &cw.dt_proj_b)?;
sync_f32(ctx, &mw.d_param, &cw.d_param)?;
}
sync_f32(ctx, &self.master.norm_f_weight, &self.compute.norm_f_weight)?;
Ok(())
}
}
fn sync_f32(
ctx: &GpuCtx,
master: &crate::mamba_ssm::gpu::buffers::GpuBuffer,
compute: &crate::mamba_ssm::gpu::buffers::WeightSliceDyn,
) -> Result<(), String> {
let n_elems = master.len();
debug_assert_eq!(n_elems, compute.len_elems());
if n_elems == 0 {
return Ok(());
}
let bytes = n_elems * 4;
let res = unsafe {
cudarc::driver::sys::cuMemcpyDtoDAsync_v2(
compute.ptr(),
master.cached_ptr(),
bytes,
ctx.stream.cu_stream(),
)
};
if res != cudarc::driver::sys::CUresult::CUDA_SUCCESS {
return Err(format!("sync_f32 D2D failed: {res:?}"));
}
Ok(())
}