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 GradNodeGelu {
pub(in crate::ml::autograd) input: Matrix,
pub(in crate::ml::autograd) output_id: u64,
}
impl GradNodeGelu {
pub(in crate::ml::autograd) fn backward(
&self,
gradients: &mut HashMap<u64, Matrix>,
) -> Result<BackwardStatus> {
let Self { input, output_id } = self;
let Some(output_gradient) = gradients.remove(output_id) else {
return Ok(BackwardStatus::Skipped);
};
let input_gradient = ml_matrix::gelu_backward(input, &output_gradient)?;
accumulate_value_gradient(gradients, input.value_id(), input_gradient)?;
Ok(BackwardStatus::Recorded)
}
}
pub(in crate::ml::autograd) struct GradNodeSilu {
pub(in crate::ml::autograd) input: Matrix,
pub(in crate::ml::autograd) output_id: u64,
}
impl GradNodeSilu {
pub(in crate::ml::autograd) fn backward(
&self,
gradients: &mut HashMap<u64, Matrix>,
) -> Result<BackwardStatus> {
let Self { input, output_id } = self;
let Some(output_gradient) = gradients.remove(output_id) else {
return Ok(BackwardStatus::Skipped);
};
let input_gradient = ml_matrix::silu_backward(input, &output_gradient)?;
accumulate_value_gradient(gradients, input.value_id(), input_gradient)?;
Ok(BackwardStatus::Recorded)
}
}
pub(in crate::ml::autograd) struct GradNodeRelu {
pub(in crate::ml::autograd) input: Matrix,
pub(in crate::ml::autograd) output: Matrix,
pub(in crate::ml::autograd) output_id: u64,
}
impl GradNodeRelu {
pub(in crate::ml::autograd) fn backward(
&self,
gradients: &mut HashMap<u64, Matrix>,
) -> Result<BackwardStatus> {
let Self {
input,
output,
output_id,
} = self;
let Some(output_gradient) = gradients.remove(output_id) else {
return Ok(BackwardStatus::Skipped);
};
let input_gradient = ml_matrix::relu_backward(output, &output_gradient)?;
accumulate_value_gradient(gradients, input.value_id(), input_gradient)?;
Ok(BackwardStatus::Recorded)
}
}
pub(in crate::ml::autograd) struct GradNodeTanh {
pub(in crate::ml::autograd) input: Matrix,
pub(in crate::ml::autograd) output: Matrix,
pub(in crate::ml::autograd) output_id: u64,
}
impl GradNodeTanh {
pub(in crate::ml::autograd) fn backward(
&self,
gradients: &mut HashMap<u64, Matrix>,
) -> Result<BackwardStatus> {
let Self {
input,
output,
output_id,
} = self;
let Some(output_gradient) = gradients.remove(output_id) else {
return Ok(BackwardStatus::Skipped);
};
let input_gradient = ml_matrix::tanh_backward(output, &output_gradient)?;
accumulate_value_gradient(gradients, input.value_id(), input_gradient)?;
Ok(BackwardStatus::Recorded)
}
}
pub(in crate::ml::autograd) struct GradNodeSigmoid {
pub(in crate::ml::autograd) input: Matrix,
pub(in crate::ml::autograd) output: Matrix,
pub(in crate::ml::autograd) output_id: u64,
}
impl GradNodeSigmoid {
pub(in crate::ml::autograd) fn backward(
&self,
gradients: &mut HashMap<u64, Matrix>,
) -> Result<BackwardStatus> {
let Self {
input,
output,
output_id,
} = self;
let Some(output_gradient) = gradients.remove(output_id) else {
return Ok(BackwardStatus::Skipped);
};
let input_gradient = ml_matrix::sigmoid_backward(output, &output_gradient)?;
accumulate_value_gradient(gradients, input.value_id(), input_gradient)?;
Ok(BackwardStatus::Recorded)
}
}
pub(in crate::ml::autograd) struct GradNodeLeakyRelu {
pub(in crate::ml::autograd) input: Matrix,
pub(in crate::ml::autograd) alpha: f32,
pub(in crate::ml::autograd) output_id: u64,
}
impl GradNodeLeakyRelu {
pub(in crate::ml::autograd) fn backward(
&self,
gradients: &mut HashMap<u64, Matrix>,
) -> Result<BackwardStatus> {
let Self {
input,
alpha,
output_id,
} = self;
let Some(output_gradient) = gradients.remove(output_id) else {
return Ok(BackwardStatus::Skipped);
};
let input_gradient = ml_matrix::leaky_relu_backward(input, &output_gradient, *alpha)?;
accumulate_value_gradient(gradients, input.value_id(), input_gradient)?;
Ok(BackwardStatus::Recorded)
}
}
pub(in crate::ml::autograd) struct GradNodeElu {
pub(in crate::ml::autograd) input: Matrix,
pub(in crate::ml::autograd) output: Matrix,
pub(in crate::ml::autograd) alpha: f32,
pub(in crate::ml::autograd) output_id: u64,
}
impl GradNodeElu {
pub(in crate::ml::autograd) fn backward(
&self,
gradients: &mut HashMap<u64, Matrix>,
) -> Result<BackwardStatus> {
let Self {
input,
output,
alpha,
output_id,
} = self;
let Some(output_gradient) = gradients.remove(output_id) else {
return Ok(BackwardStatus::Skipped);
};
let input_gradient = ml_matrix::elu_backward(output, &output_gradient, *alpha)?;
accumulate_value_gradient(gradients, input.value_id(), input_gradient)?;
Ok(BackwardStatus::Recorded)
}
}
pub(in crate::ml::autograd) struct GradNodeMish {
pub(in crate::ml::autograd) input: Matrix,
pub(in crate::ml::autograd) output_id: u64,
}
impl GradNodeMish {
pub(in crate::ml::autograd) fn backward(
&self,
gradients: &mut HashMap<u64, Matrix>,
) -> Result<BackwardStatus> {
let Self { input, output_id } = self;
let Some(output_gradient) = gradients.remove(output_id) else {
return Ok(BackwardStatus::Skipped);
};
let input_gradient = ml_matrix::mish_backward(input, &output_gradient)?;
accumulate_value_gradient(gradients, input.value_id(), input_gradient)?;
Ok(BackwardStatus::Recorded)
}
}
pub(in crate::ml::autograd) struct GradNodeSoftplus {
pub(in crate::ml::autograd) input: Matrix,
pub(in crate::ml::autograd) output: Matrix,
pub(in crate::ml::autograd) output_id: u64,
}
impl GradNodeSoftplus {
pub(in crate::ml::autograd) fn backward(
&self,
gradients: &mut HashMap<u64, Matrix>,
) -> Result<BackwardStatus> {
let Self {
input,
output,
output_id,
} = self;
let Some(output_gradient) = gradients.remove(output_id) else {
return Ok(BackwardStatus::Skipped);
};
let input_gradient = ml_matrix::softplus_backward(output, &output_gradient)?;
accumulate_value_gradient(gradients, input.value_id(), input_gradient)?;
Ok(BackwardStatus::Recorded)
}
}