namespace ov::op::v1

namespace v1 {

// classes

class Add;
class AvgPool;
class BatchToSpace;
class BinaryConvolution;
class Broadcast;
class ConvertLike;
class Convolution;
class ConvolutionBackpropData;
class DeformableConvolution;
class DeformablePSROIPooling;
class Divide;
class Equal;
class FloorMod;
class Gather;
class GatherTree;
class Greater;
class GreaterEqual;
class GroupConvolution;
class GroupConvolutionBackpropData;
class Less;
class LessEqual;
class LogicalAnd;
class LogicalNot;
class LogicalOr;
class LogicalXor;
class MaxPool;
class Maximum;
class Minimum;
class Mod;
class Multiply;
class NonMaxSuppression;
class NotEqual;
class OneHot;
class Pad;
class Power;
class ReduceLogicalAnd;
class ReduceLogicalOr;
class ReduceMax;
class ReduceMean;
class ReduceMin;
class ReduceProd;
class ReduceSum;
class Reshape;
class Reverse;
class Select;
class Softmax;
class SpaceToBatch;
class Split;
class StridedSlice;
class Subtract;
class TopK;
class Transpose;
class VariadicSplit;

// global functions

template <class T>
void shape_infer(
    const ov::op::v1::BatchToSpace \* op,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes,
    const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data = {}
    );

template <class T>
void shape_infer(
    const ov::op::v1::Broadcast \* op,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes,
    const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data = {}
    );

template <class ConvType>
int64_t calculate_num_spatial(
    const ConvType \* op,
    const PartialShape& input_shape,
    const PartialShape& filters_shape,
    const int64_t& num_non_spatial_data_dims,
    const int64_t& num_non_spatial_filter_dims
    );

template <class ConvType>
void update_and_validate_attributes(ConvType \* op);

template <class T>
bool dynamic_check(const int64_t& num_spatial);

bool dynamic_check< PartialShape >(const int64_t& num_spatial);

template <class ConvType, class ShapeType>
bool resolve_auto_pad_for_shape(
    const ConvType \* op,
    CoordinateDiff& pads_begin,
    CoordinateDiff& pads_end,
    const std::vector<ShapeType>& input_shapes,
    const int64_t& num_non_spatial_data_dims,
    const int64_t& num_non_spatial_filter_dims
    );

template <class ConvType, class ShapeType>
void calculate_output_spatial_dims_for_convolution(
    const ConvType \* op,
    const ShapeType& input_shape,
    const ShapeType& filters_shape,
    ShapeType& output_shape,
    const int64_t& num_spatial,
    const Strides& strides,
    const Strides& dilations,
    const CoordinateDiff& pads_begin,
    const CoordinateDiff& pads_end,
    const int64_t& num_non_spatial_data_dims,
    const int64_t& num_non_spatial_filter_dims
    );

template <class T>
void shape_infer(
    const Convolution \* op,
    const CoordinateDiff& pads_begin,
    const CoordinateDiff& pads_end,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes
    );

template <class T>
void shape_infer(
    const GroupConvolution \* op,
    const CoordinateDiff& pads_begin,
    const CoordinateDiff& pads_end,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes
    );

template <class ConvType>
int64_t calculate_num_spatial(
    const ConvType \* op,
    const PartialShape& input_shape,
    const PartialShape& filters_shape,
    const PartialShape& output_shapes_shape,
    const int64_t& num_non_spatial_data_dims,
    const int64_t& num_non_spatial_filter_dims
    );

template <class ConvType>
void update_and_validate_attributes_back_prop(ConvType \* op);

template <class ConvType, class ShapeType>
bool resolve_auto_pad_for_shape_back_prop(
    const ConvType \* op,
    CoordinateDiff& pads_begin,
    CoordinateDiff& pads_end,
    const std::vector<ShapeType>& input_shapes,
    ShapeType& output_spatial_shape,
    const int64_t& num_non_spatial_data_dims,
    const int64_t& num_non_spatial_filter_dims
    );

template <class ConvType, class ShapeType>
void calculate_output_spatial_dims_for_convolution_back_prop_data(
    const ConvType \* op,
    const ShapeType& input_shape,
    const ShapeType& filters_shape,
    const ShapeType& output_rank,
    ShapeType& output_shape,
    const int64_t& num_spatial,
    const Strides& strides,
    const Strides& dilations,
    const CoordinateDiff& pads_begin,
    const CoordinateDiff& pads_end,
    const CoordinateDiff& output_padding,
    const int64_t& num_non_spatial_data_dims,
    const int64_t& num_non_spatial_filter_dims
    );

template <class T>
void shape_infer(
    const ConvolutionBackpropData \* op,
    const CoordinateDiff& pads_begin,
    const CoordinateDiff& pads_end,
    const T& output_shape_from_input,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes
    );

template <class T>
void shape_infer(
    const GroupConvolutionBackpropData \* op,
    const CoordinateDiff& pads_begin,
    const CoordinateDiff& pads_end,
    const T& output_shape_from_input,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes
    );

template <class T>
void shape_infer(
    const GatherTree \* op,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes
    );

void resolve_axis(OneHot \* op);

template <class T>
void shape_infer(
    const OneHot \* op,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes,
    const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data = {}
    );

template <class T>
void shape_infer(
    const Pad \* op,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes,
    const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data = {}
    );

template <class T>
void shape_infer(
    const Select \* op,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes
    );

template <class T>
void shape_infer(
    const ov::op::v1::SpaceToBatch \* op,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes,
    const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data = {}
    );

template <typename T>
void shape_infer(
    const Split \* op,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes,
    const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data = {}
    );

template <class T>
void shape_infer(
    const StridedSlice \* op,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes,
    const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data = {}
    );

template <typename T>
void shape_infer(
    const TopK \* op,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes,
    const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data = {}
    );

template <typename T>
void shape_infer(
    const VariadicSplit \* op,
    const std::vector<T>& input_shapes,
    std::vector<T>& output_shapes,
    const std::map<size_t, std::shared_ptr<ngraph::runtime::HostTensor>>& constant_data = {}
    );

} // namespace v1