interpolate.hpp
1 // Copyright (C) 2018-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 
5 #pragma once
6 
7 #include <cstdint>
8 #include <vector>
9 #include "ngraph/attribute_adapter.hpp"
10 #include "ngraph/op/op.hpp"
11 #include "ngraph/op/util/attr_types.hpp"
12 
13 namespace ngraph
14 {
15  namespace op
16  {
17  namespace v0
18  {
19  /// \brief Structure that specifies attributes for interpolation
21  {
22  // specify dimension indices where interpolation is applied, and `axes` is any
23  // unordered list of indeces of different dimensions of input tensor. Required.
24  AxisSet axes;
25  // specifies type of interpolation
26  // one of `nearest`, `linear`, `cubic`, `area`. Required.
27  std::string mode;
28  // a flag that specifies whether to align corners or not.
29  // `true` (default) means the alignment is applied,
30  // `false` means the alignment isn't applied.
31  bool align_corners = true;
32  // a flag that specifies whether to perform anti-aliasing. default is `false`
33  bool antialias = false;
34  // specify the number of pixels to add to the beginning of the image being
35  // interpolated. This addition of pixels is done before interpolation calculation.
36  std::vector<size_t> pads_begin;
37  // specify the number of pixels to add to the end of the image being interpolated.
38  // This addition of pixels is done before interpolation calculation.
39  std::vector<size_t> pads_end;
40  };
41 
42  /// \brief Layer which performs bilinear interpolation
43  class NGRAPH_API Interpolate : public Op
44  {
45  public:
46  NGRAPH_RTTI_DECLARATION;
47 
48  enum class InterpolateMode
49  {
50  nearest,
51  linear,
52  cubic,
53  area
54  };
55 
56  Interpolate() = default;
57  /// \brief Constructs a Interpolate operation
58  ///
59  /// \param image Input image
60  /// \param output_shape Output shape of spatial axes
61  /// \param attrs Interpolation attributes
62  Interpolate(const Output<Node>& image,
63  const Output<Node>& output_shape,
64  const InterpolateAttrs& attrs);
65  bool visit_attributes(AttributeVisitor& visitor) override;
66 
67  void validate_and_infer_types() override;
68 
69  virtual std::shared_ptr<Node>
70  clone_with_new_inputs(const OutputVector& new_args) const override;
71 
72  const InterpolateAttrs& get_attrs() const { return m_attrs; }
73 
74  private:
75  InterpolateAttrs m_attrs;
76  };
77  } // namespace v0
78 
79  namespace v4
80  {
81  class NGRAPH_API Interpolate : public Op
82  {
83  public:
84  NGRAPH_RTTI_DECLARATION;
85 
86  /// \brief Shape calculation mode
87  ///
88  /// sizes - output shape for interpolated axes is calculated using input `sizes`
89  /// scales - output shape for interpolated axes is calculated using input `scales`
90  enum class ShapeCalcMode
91  {
92  sizes,
93  scales
94  };
95 
96  /// \brief Interpolation mode
97  ///
98  /// nearest - nearest interpolation
99  /// linear - linear interpolation as in TensorFlow
100  /// linear_onnx - linear interpolation as in ONNX
101  /// cubic - cubic interpolation
102  enum class InterpolateMode
103  {
104  nearest,
105  linear,
106  linear_onnx,
107  cubic
108  };
109 
110  /// \brief Mode of the calculation of the source coordinate from resized one
111  ///
112  /// These modes are modes from ONNX runtime.
114  {
115  half_pixel,
116  pytorch_half_pixel,
117  asymmetric,
118  tf_half_pixel_for_nn,
119  align_corners
120  };
121 
122  /// \brief Round modes for the nearest interpolation.
123  enum class NearestMode
124  {
125  round_prefer_floor,
126  round_prefer_ceil,
127  floor,
128  ceil,
129  simple
130  };
131 
133  {
134  // specifies type of interpolation
135  // one of `nearest`, `linear`, `linear_onnx`, `cubic` Required.
136  InterpolateMode mode = InterpolateMode::nearest;
137  // specifies shape calculation mode
138  // one of `sizes`, `scales` Required
139  ShapeCalcMode shape_calculation_mode = ShapeCalcMode::sizes;
140  // specify the number of pixels to add to the beginning of the image being
141  // interpolated. This addition of pixels is done before interpolation
142  // calculation.
143  std::vector<size_t> pads_begin;
144  // specify the number of pixels to add to the end of the image being
145  // interpolated. This addition of pixels is done before interpolation
146  // calculation.
147  std::vector<size_t> pads_end;
148  // specifies how to transform the coordinate in the resized tensor to the
149  // coordinate in the original tensor. one of `half_pixel`, `pytorch_half_pixel`,
150  // `asymmetric`, `tf_half_pixel_for_nn`, `align_corners`
151  CoordinateTransformMode coordinate_transformation_mode =
152  CoordinateTransformMode::half_pixel;
153  // specifies round mode when `mode == nearest` and is used only when `mode ==
154  // nearest`. one of `round_prefer_floor`, `round_prefer_ceil`, `floor`, `ceil`,
155  // `simple`
156  NearestMode nearest_mode = NearestMode::round_prefer_floor;
157  // a flag that specifies whether to perform anti-aliasing. default is `false`
158  bool antialias = false;
159  // specifies the parameter *a* for cubic interpolation (see, e.g.
160  // [article](https://ieeexplore.ieee.org/document/1163711/)). *cube_coeff* is
161  // used only when `mode == cubic`
162  double cube_coeff = -0.75f;
163 
164  InterpolateAttrs() = default;
165 
167  ShapeCalcMode shape_calculation_mode,
168  std::vector<size_t> pads_begin,
169  std::vector<size_t> pads_end,
170  CoordinateTransformMode coordinate_transformation_mode =
171  CoordinateTransformMode::half_pixel,
172  NearestMode nearest_mode = NearestMode::round_prefer_floor,
173  bool antialias = false,
174  double cube_coeff = -0.75)
175  : mode(mode)
176  , shape_calculation_mode(shape_calculation_mode)
177  , pads_begin(pads_begin)
178  , pads_end(pads_end)
179  , coordinate_transformation_mode(coordinate_transformation_mode)
180  , nearest_mode(nearest_mode)
181  , antialias(antialias)
182  , cube_coeff(cube_coeff)
183  {
184  }
185  };
186 
187  Interpolate() = default;
188  /// \brief Constructs a Interpolate operation without 'axes' input.
189  ///
190  /// \param image Input image
191  /// \param output_shape Output shape of spatial axes
192  /// \param scales Scales of spatial axes, i.e. output_shape / input_shape
193  /// \param attrs Interpolation attributes
194  Interpolate(const Output<Node>& image,
195  const Output<Node>& output_shape,
196  const Output<Node>& scales,
197  const InterpolateAttrs& attrs);
198 
199  /// \brief Constructs a Interpolate operation with 'axes' input.
200  ///
201  /// \param image Input image
202  /// \param output_shape Output shape of spatial axes
203  /// \param scales Scales of spatial axes, i.e. output_shape / input_shape
204  /// \param axes Interpolation axes
205  /// \param attrs Interpolation attributes
206  Interpolate(const Output<Node>& image,
207  const Output<Node>& output_shape,
208  const Output<Node>& scales,
209  const Output<Node>& axes,
210  const InterpolateAttrs& attrs);
211  bool visit_attributes(AttributeVisitor& visitor) override;
212 
213  void validate_and_infer_types() override;
214 
215  virtual std::shared_ptr<Node>
216  clone_with_new_inputs(const OutputVector& new_args) const override;
217  bool evaluate(const HostTensorVector& outputs,
218  const HostTensorVector& inputs) const override;
219  bool has_evaluate() const override;
220 
221  const InterpolateAttrs& get_attrs() const { return m_attrs; }
222 
223  protected:
224  /// \return The interpolation axes.
225  std::vector<int64_t> get_axes() const;
226 
227  private:
228  bool evaluate_interpolate(const HostTensorVector& outputs,
229  const HostTensorVector& inputs) const;
230  InterpolateAttrs m_attrs;
231 
232  /// \brief Corrects pads_begin and pads_end attributes.
233  ///
234  /// \details When Interpolate-4 is a result of some transformation, it is possible
235  /// that pads_begin.size() != pads_end.size() or
236  /// pads_begin.size() != input_rank. In such case, we should correct
237  /// pads_begin and pads_end, using padding of pads_begin and pads_end by
238  /// zeros or using pads_begin[0 : input_rank], pads_end[0 : input_rank].
239  ///
240  /// Padding of pads_begin is performed when pads_begin.size() < input_rank,
241  /// and pads_begin[0 : input_rank] is used when
242  /// pads_begin.size() < input_rank.
243  ///
244  /// Similarly for pads_end.
245  void correct_pads();
246 
247  /// \brief Calculates input shape after padding.
248  ///
249  /// \param input_shape Shape of input data.
250  ///
251  /// \return Padded input shape, i.e. input_shape + pads_begin + pads_end
252  PartialShape get_padded_input_shape(const PartialShape& input_shape) const;
253 
254  /// \brief Infers output shape using scales.
255  ///
256  /// \param output_shape[in,out] output shape
257  /// \param axes Interpolation axes
258  /// \param scales Scales for interpolated axes
259  /// \param padded_input_shape input shape after padding
260  void infer_using_scales(PartialShape& output_shape,
261  const std::vector<int64_t>& axes,
262  const std::vector<float>& scales,
263  const PartialShape& padded_input_shape) const;
264 
265  /// \brief Infers output shape using sizes.
266  ///
267  /// \param output_shape[in,out] output shape
268  /// \param axes Interpolation axes
269  /// \param sizes sizes for interpolated axes
270  void infer_using_shapes(PartialShape& output_shape,
271  const std::vector<int64_t>& axes,
272  const std::vector<int64_t>& sizes) const;
273  };
274  } // namespace v4
275 
276  using v0::Interpolate;
277  using v0::InterpolateAttrs;
278  } // namespace op
279 
280  //---------------------------------------- v0 --------------------------------------------------
281  NGRAPH_API
282  std::ostream& operator<<(std::ostream& s, const op::v0::Interpolate::InterpolateMode& type);
283 
284  template <>
285  class NGRAPH_API AttributeAdapter<op::v0::Interpolate::InterpolateMode>
286  : public EnumAttributeAdapterBase<op::v0::Interpolate::InterpolateMode>
287  {
288  public:
289  AttributeAdapter(op::v0::Interpolate::InterpolateMode& value)
291  {
292  }
293 
294  static constexpr DiscreteTypeInfo type_info{
295  "AttributeAdapter<op::v0::Interpolate::InterpolateMode>", 0};
296  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
297  };
298 
299  //---------------------------------------- v4 --------------------------------------------------
300 
301  NGRAPH_API
302  std::ostream& operator<<(std::ostream& s, const op::v4::Interpolate::InterpolateMode& type);
303 
304  template <>
305  class NGRAPH_API AttributeAdapter<op::v4::Interpolate::InterpolateMode>
306  : public EnumAttributeAdapterBase<op::v4::Interpolate::InterpolateMode>
307  {
308  public:
311  {
312  }
313 
314  static constexpr DiscreteTypeInfo type_info{
315  "AttributeAdapter<op::v4::Interpolate::InterpolateMode>", 4};
316  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
317  };
318 
319  NGRAPH_API
320  std::ostream& operator<<(std::ostream& s,
322 
323  template <>
324  class NGRAPH_API AttributeAdapter<op::v4::Interpolate::CoordinateTransformMode>
325  : public EnumAttributeAdapterBase<op::v4::Interpolate::CoordinateTransformMode>
326  {
327  public:
330  {
331  }
332 
333  static constexpr DiscreteTypeInfo type_info{
334  "AttributeAdapter<op::v4::Interpolate::CoordinateTransformMode>", 4};
335  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
336  };
337 
338  NGRAPH_API
339  std::ostream& operator<<(std::ostream& s, const op::v4::Interpolate::NearestMode& type);
340 
341  template <>
342  class NGRAPH_API AttributeAdapter<op::v4::Interpolate::NearestMode>
343  : public EnumAttributeAdapterBase<op::v4::Interpolate::NearestMode>
344  {
345  public:
348  {
349  }
350 
351  static constexpr DiscreteTypeInfo type_info{
352  "AttributeAdapter<op::v4::Interpolate::NearestMode>", 4};
353  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
354  };
355 
356  NGRAPH_API
357  std::ostream& operator<<(std::ostream& s, const op::v4::Interpolate::ShapeCalcMode& type);
358 
359  template <>
360  class NGRAPH_API AttributeAdapter<op::v4::Interpolate::ShapeCalcMode>
361  : public EnumAttributeAdapterBase<op::v4::Interpolate::ShapeCalcMode>
362  {
363  public:
366  {
367  }
368 
369  static constexpr DiscreteTypeInfo type_info{
370  "AttributeAdapter<op::v4::Interpolate::ShapeCalcMode>", 4};
371  const DiscreteTypeInfo& get_type_info() const override { return type_info; }
372  };
373 } // namespace ngraph
An AttributeAdapter "captures" an attribute as an AT& and makes it available as a ValueAccessor<VAT>.
Definition: attribute_adapter.hpp:161
Visits the attributes of a node, primarily for serialization-like tasks.
Definition: attribute_visitor.hpp:59
A set of axes.
Definition: axis_set.hpp:19
Access an enum via a string.
Definition: attribute_adapter.hpp:168
A handle for one of a node's outputs.
Definition: node_output.hpp:33
Class representing a shape that may be partially or totally dynamic.
Definition: partial_shape.hpp:34
Root of all actual ops.
Definition: op.hpp:17
Layer which performs bilinear interpolation.
Definition: interpolate.hpp:44
Interpolate(const Output< Node > &image, const Output< Node > &output_shape, const InterpolateAttrs &attrs)
Constructs a Interpolate operation.
void validate_and_infer_types() override
Verifies that attributes and inputs are consistent and computes output shapes and element types....
Definition: interpolate.hpp:82
bool has_evaluate() const override
Allows to get information about availability of evaluate method for the current operation.
InterpolateMode
Interpolation mode.
Definition: interpolate.hpp:103
CoordinateTransformMode
Mode of the calculation of the source coordinate from resized one.
Definition: interpolate.hpp:114
Interpolate(const Output< Node > &image, const Output< Node > &output_shape, const Output< Node > &scales, const InterpolateAttrs &attrs)
Constructs a Interpolate operation without 'axes' input.
void validate_and_infer_types() override
Verifies that attributes and inputs are consistent and computes output shapes and element types....
std::vector< int64_t > get_axes() const
bool evaluate(const HostTensorVector &outputs, const HostTensorVector &inputs) const override
Evaluates the op on input_values putting results in output_values.
Interpolate(const Output< Node > &image, const Output< Node > &output_shape, const Output< Node > &scales, const Output< Node > &axes, const InterpolateAttrs &attrs)
Constructs a Interpolate operation with 'axes' input.
ShapeCalcMode
Shape calculation mode.
Definition: interpolate.hpp:91
NearestMode
Round modes for the nearest interpolation.
Definition: interpolate.hpp:124
The Intel nGraph C++ API.
Definition: attribute_adapter.hpp:16
Definition: type.hpp:27
Structure that specifies attributes for interpolation.
Definition: interpolate.hpp:21
Definition: interpolate.hpp:133