use tenferro_ops::{ExtensionRegistryError, ExtensionRuleSet};
use tenferro_runtime::{Result, TracedTensor};
#[derive(Clone, Debug)]
pub struct AdContext {
extension_rules: ExtensionRuleSet,
}
impl AdContext {
pub fn builder() -> AdContextBuilder {
AdContextBuilder::default()
}
pub fn extension_rules(&self) -> &ExtensionRuleSet {
&self.extension_rules
}
pub(crate) fn extension_rule_set(&self) -> ExtensionRuleSet {
self.extension_rules.clone()
}
pub fn grad(&self, output: &TracedTensor, wrt: &TracedTensor) -> Result<TracedTensor> {
crate::traced::grad_with_rules(output, wrt, &self.extension_rules)
}
pub fn grad_optional(
&self,
output: &TracedTensor,
wrt: &TracedTensor,
) -> Result<Option<TracedTensor>> {
crate::traced::grad_optional_with_rules(output, wrt, &self.extension_rules)
}
pub fn jvp(
&self,
output: &TracedTensor,
wrt: &TracedTensor,
tangent: &TracedTensor,
) -> Result<TracedTensor> {
crate::traced::jvp_with_rules(output, wrt, tangent, &self.extension_rules)
}
pub fn jvp_optional(
&self,
output: &TracedTensor,
wrt: &TracedTensor,
tangent: &TracedTensor,
) -> Result<Option<TracedTensor>> {
crate::traced::jvp_optional_with_rules(output, wrt, tangent, &self.extension_rules)
}
pub fn vjp(
&self,
output: &TracedTensor,
wrt: &TracedTensor,
cotangent: &TracedTensor,
) -> Result<TracedTensor> {
crate::traced::vjp_with_rules(output, wrt, cotangent, &self.extension_rules)
}
pub fn vjp_optional(
&self,
output: &TracedTensor,
wrt: &TracedTensor,
cotangent: &TracedTensor,
) -> Result<Option<TracedTensor>> {
crate::traced::vjp_optional_with_rules(output, wrt, cotangent, &self.extension_rules)
}
}
#[derive(Clone, Debug, Default)]
pub struct AdContextBuilder {
extension_rule_sets: Vec<ExtensionRuleSet>,
}
impl AdContextBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn with_extension_rules(mut self, rules: ExtensionRuleSet) -> Self {
self.extension_rule_sets.push(rules);
self
}
pub fn build(self) -> std::result::Result<AdContext, ExtensionRegistryError> {
let mut extension_rules = ExtensionRuleSet::new();
for rules in self.extension_rule_sets {
extension_rules.merge(rules)?;
}
Ok(AdContext { extension_rules })
}
}