tract_hir/ops/array/
reshape.rs1use crate::infer::*;
2use crate::internal::*;
3
4#[derive(Debug, Clone, new, Default, Hash)]
5pub struct Reshape {}
6
7impl Expansion for Reshape {
8 fn name(&self) -> StaticName {
9 "Reshape".into()
10 }
11
12 fn rules<'r, 'p: 'r, 's: 'r>(
13 &'s self,
14 s: &mut Solver<'r>,
15 inputs: &'p [TensorProxy],
16 outputs: &'p [TensorProxy],
17 ) -> InferenceResult {
18 s.equals(&outputs[0].datum_type, &inputs[0].datum_type)?;
19 s.given_2(&inputs[0].shape, &inputs[1].value, move |s, ishape, shape| {
20 let shape = shape.cast_to::<TDim>()?;
21 let shape = shape.as_slice::<TDim>()?;
22 let oshape = tract_core::ops::change_axes::compute_shape_with_tf_rules(&ishape, shape)
23 .with_context(|| format!("Reshaping {ishape:?} to {shape:?}"))?;
24 s.equals(&outputs[0].shape, ShapeFactoid::from(oshape))
25 })
26 }
27
28 fn wire(
29 &self,
30 prefix: &str,
31 model: &mut TypedModel,
32 inputs: &[OutletId],
33 ) -> TractResult<TVec<OutletId>> {
34 if let Some(ref shape) = model.outlet_fact(inputs[1])?.konst {
35 let input_shape: TVec<TDim> = model.outlet_fact(inputs[0])?.shape.to_tvec();
36 let shape = shape.cast_to::<TDim>()?;
37 let shape = shape.as_slice::<TDim>()?;
38 let mut wire = tvec!(inputs[0]);
39 for (ix, op) in to_axis_ops_with_tf_rules(&input_shape, shape)?.into_iter().enumerate() {
40 wire = model.wire_node(format!("{prefix}.{ix}"), op, &wire)?;
41 }
42 return Ok(wire);
43 }
44 bail!("shape input is variable")
45 }
46}