use crate::ml::autograd::node::operation::BackwardStatus;
use crate::ml::autograd::tape::backward::accumulate_value_gradient;
use crate::ml::matrix as ml_matrix;
use crate::{Matrix, Result};
use std::collections::HashMap;
pub(in crate::ml::autograd) struct GradNodeSwiglu {
pub(in crate::ml::autograd) gate: Matrix,
pub(in crate::ml::autograd) up: Matrix,
pub(in crate::ml::autograd) output_id: u64,
}
impl GradNodeSwiglu {
pub(in crate::ml::autograd) fn backward(
&self,
gradients: &mut HashMap<u64, Matrix>,
) -> Result<BackwardStatus> {
let Self {
gate,
up,
output_id,
} = self;
let Some(output_gradient) = gradients.remove(output_id) else {
return Ok(BackwardStatus::Skipped);
};
let (gate_gradient, up_gradient) = ml_matrix::swiglu_backward(gate, up, &output_gradient)?;
accumulate_value_gradient(gradients, gate.value_id(), gate_gradient)?;
accumulate_value_gradient(gradients, up.value_id(), up_gradient)?;
Ok(BackwardStatus::Recorded)
}
}
pub(in crate::ml::autograd) struct GradNodeSiluMul {
pub(in crate::ml::autograd) input: Matrix,
pub(in crate::ml::autograd) intermediate_size: usize,
pub(in crate::ml::autograd) output_id: u64,
}
impl GradNodeSiluMul {
pub(in crate::ml::autograd) fn backward(
&self,
gradients: &mut HashMap<u64, Matrix>,
) -> Result<BackwardStatus> {
let Self {
input,
intermediate_size,
output_id,
} = self;
let Some(output_gradient) = gradients.remove(output_id) else {
return Ok(BackwardStatus::Skipped);
};
let input_gradient =
crate::ml::matrix::silu_mul_backward(input, &output_gradient, *intermediate_size)?;
accumulate_value_gradient(gradients, input.value_id(), input_gradient)?;
Ok(BackwardStatus::Recorded)
}
}