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