#ifndef GRAPH_INTERFACE_SHAPE_INFER_HPP
#define GRAPH_INTERFACE_SHAPE_INFER_HPP
#include <algorithm>
#include <cmath>
#include <functional>
#include <string>
#include <utility>
#include <vector>
#include "graph/interface/logical_tensor.hpp"
#include "graph/interface/op.hpp"
#include "common/verbose.hpp"
namespace dnnl {
namespace impl {
namespace graph {
dims canonicalize(const dims &shape, const std::string &format);
inline dims ncx2nxc(const dims &shape);
inline dims make_data_dims(
const std::string &format, const dim_t n, const dim_t c, const dims &x);
inline dims make_filter_dims(
const std::string &format, const dim_t i, const dim_t o, const dims &x);
bool validate(const dims &inferred, const dims &expected);
inline dims get_dense_strides(const dims &shape);
inline bool every_shape_is_known(const std::vector<logical_tensor_t *> <s);
inline bool verify_shapes_in_range(const std::vector<logical_tensor_t *> <s,
const size_t begin, const size_t end,
const std::function<bool(const dims)> &validator);
void set_shape_and_strides(logical_tensor_t <, const dims &shape);
inline void set_shapes_in_range(const std::vector<logical_tensor_t *> <s,
const size_t begin, const size_t end, const dims &shape);
status_t infer_auto_pad(const dim_t in_dim, const dim_t stride,
const dim_t kernel, const dim_t dilation, const std::string &auto_pad,
dim_t &pad_begin, dim_t &pad_end, bool is_deconv = false);
status_t broadcast(const dims &lhs, const dims &rhs, dims &broadcasted);
std::string dims2str(const dims &dims);
status_t one_way_broadcast(const dims &lhs, const dims &rhs);
inline void infer_conv_ncx_oix(const dims &src_dims, const dims &fil_dims,
const dims &strides, const dims &dilations, const dims &pads_begin,
const dims &pads_end, dims &output_dims);
status_t infer_conv_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_conv_bprop_data_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_conv_bprop_filters_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_convtranspose_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
inline void infer_convtranspose_ncx_oix(const dims &src_dims,
const dims &fil_dims, const dims &strides, const dims &dilations,
const dims &pads_begin, const dims &pads_end, dims &output_dims);
status_t infer_convtranspose_bprop_data_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_convtranspose_bprop_filters_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_conv_bprop_filters_output_shape_common(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs, const size_t in_num);
status_t infer_pool_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_pool_bwd_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_matmul_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dropout_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_identity_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_softmax_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t identity_output_shape_on_pos(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs,
std::vector<std::pair<uint32_t, uint32_t>> &positions);
status_t infer_bias_backprop_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_bias_add_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_norm_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_norm_bprop_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_elemwise_arithmetic_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_bn_fwd_train_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_bn_bwd_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_concat_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_unsupported_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_reduce_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_select_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_static_reshape_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_static_transpose_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_interpolate_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_prelu_bwd_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_groupnorm_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dummy_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_conv_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_convtranspose_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_convtranspose_bwd_data_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_convtranspose_bwd_weight_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_pool_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_permute_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_to_group_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_from_group_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_unsqueeze_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_bn_folding_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_conv_bwd_data_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_conv_bwd_weight_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_squeeze_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_batchnorm_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_batchnorm_bwd_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_constant_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_pool_bwd_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_binary_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_binary_select_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_sdpa_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_host_scalar_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_layernorm_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_gated_mlp_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_softmax_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
status_t infer_dnnl_sdpa_bwd_output_shape(op_t *n,
std::vector<logical_tensor_t *> &inputs,
std::vector<logical_tensor_t *> &outputs);
} } }
#endif