#![allow(unused_imports)]
use super::helpers::simple_op_flex;
use super::helpers::*;
use crate::proto;
use crate::{CoremlError, Result};
use rlx_ir::op::{Activation, CmpOp, MaskKind, ReduceOp};
use rlx_ir::quant::QuantScheme;
use rlx_ir::{DType, Dim, Graph, NodeId, Op, Shape};
use std::collections::HashMap;
use super::*;
impl<'a> LowerCtx<'a> {
pub(crate) fn lower_activation(
&mut self,
id: NodeId,
act: Activation,
out_name: &str,
) -> Result<()> {
let node = self.graph.node(id);
let x = self.val(node.inputs[0]);
let direct: Option<(&str, Vec<(&str, proto::Argument)>)> = match act {
Activation::Relu => Some(("relu", vec![])),
Activation::Sigmoid => Some(("sigmoid", vec![])),
Activation::Tanh => Some(("tanh", vec![])),
Activation::Exp => Some(("exp", vec![])),
Activation::Log => Some(("log", vec![("epsilon", bind_value(scalar_f32(1e-45)))])),
Activation::Sqrt => Some(("sqrt", vec![])),
Activation::Rsqrt => Some(("rsqrt", vec![("epsilon", bind_value(scalar_f32(1e-12)))])),
Activation::Abs => Some(("abs", vec![])),
Activation::Sin => Some(("sin", vec![])),
Activation::Cos => Some(("cos", vec![])),
Activation::Tan => Some(("tan", vec![])),
Activation::Atan => Some(("atan", vec![])),
Activation::Round => Some(("round", vec![])),
Activation::Gelu => Some(("gelu", vec![("mode", bind_value(scalar_str("EXACT")))])),
Activation::GeluApprox => Some((
"gelu",
vec![("mode", bind_value(scalar_str("TANH_APPROXIMATION")))],
)),
Activation::Silu | Activation::Neg => None,
};
if let Some((ty, mut params)) = direct {
let mut binds = vec![("x", bind_name(&x))];
binds.append(&mut params);
let op = self.simple_op(ty, out_name, &node.shape, binds)?;
self.push_named(id, out_name.to_string(), op);
return Ok(());
}
match act {
Activation::Silu => {
let sig = format!("{out_name}_sig");
let sig_op =
self.simple_op("sigmoid", &sig, &node.shape, vec![("x", bind_name(&x))])?;
self.operations.push(sig_op);
let op = self.simple_op(
"mul",
out_name,
&node.shape,
vec![("x", bind_name(&x)), ("y", bind_name(&sig))],
)?;
self.push_named(id, out_name.to_string(), op);
}
Activation::Neg => {
let op = self.simple_op(
"mul",
out_name,
&node.shape,
vec![("x", bind_name(&x)), ("y", bind_value(scalar_f32(-1.0)))],
)?;
self.push_named(id, out_name.to_string(), op);
}
_ => unreachable!("handled above"),
}
Ok(())
}
}