diff --git a/onnx/src/ops/cast.rs b/onnx/src/ops/cast.rs index f63e483..7ad2471 100644 --- a/onnx/src/ops/cast.rs +++ b/onnx/src/ops/cast.rs @@ -66,7 +66,7 @@ impl ElementWiseMiniOp for Cast { node: &TypedNode, ) -> TractResult> { let from = model.outlet_fact(node.inputs[0])?.datum_type; - if from == self.to || (from == TDim::datum_type() && self.to == i32::datum_type()) { + if from == self.to { Ok(Some(TypedModelPatch::replace_single_op(model, node, &node.inputs, Identity)?)) } else if from == String::datum_type() && self.to == f32::datum_type() { Ok(None) diff --git a/onnx/src/ops/math/clip.rs b/onnx/src/ops/math/clip.rs index 5fe33d5..0a240e5 100644 --- a/onnx/src/ops/math/clip.rs +++ b/onnx/src/ops/math/clip.rs @@ -54,12 +54,8 @@ impl Expansion for Clip11 { 1 + self.input_min.is_some() as usize + self.input_max.is_some() as usize, )?; check_output_arity(outputs, 1)?; - if let Some(input) = self.input_min { - s.equals(&inputs[0].datum_type, &inputs[input].datum_type)?; - } - if let Some(input) = self.input_max { - s.equals(&inputs[0].datum_type, &inputs[input].datum_type)?; - } + // Relaxed for streaming cache-len clamps: bounds may be I64 constants while the + // clamped value is a symbolic TDim. wire() casts the bounds to the input dtype. s.equals(&inputs[0].datum_type, &outputs[0].datum_type)?; s.equals(&inputs[0].shape, &outputs[0].shape)?; Ok(()) @@ -71,21 +67,30 @@ impl Expansion for Clip11 { model: &mut TypedModel, inputs: &[OutletId], ) -> TractResult> { + let dt = model.outlet_fact(inputs[0])?.datum_type; let mut wire = inputs[0]; if let Some(min) = self.input_min { + let mut b = inputs[min]; + if model.outlet_fact(b)?.datum_type != dt { + b = model.wire_node(format!("{name}.min.cast"), tract_core::ops::cast::cast(dt), &[b])?[0]; + } wire = wire_with_rank_broadcast( format!("{name}.min"), model, tract_hir::ops::math::max(), - &[wire, inputs[min]], + &[wire, b], )?[0]; } if let Some(max) = self.input_max { + let mut b = inputs[max]; + if model.outlet_fact(b)?.datum_type != dt { + b = model.wire_node(format!("{name}.max.cast"), tract_core::ops::cast::cast(dt), &[b])?[0]; + } wire = wire_with_rank_broadcast( format!("{name}.max"), model, tract_hir::ops::math::min(), - &[wire, inputs[max]], + &[wire, b], )?[0]; } Ok(tvec!(wire))