/*
 * Copyright (c) 2018-2020 ARM Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifndef ARM_COMPUTE_GRAPH_GRAPH_BUILDER_H
#define ARM_COMPUTE_GRAPH_GRAPH_BUILDER_H

#include "arm_compute/graph/ITensorAccessor.h"
#include "arm_compute/graph/LayerDescriptors.h"
#include "arm_compute/graph/Types.h"

namespace arm_compute
{
namespace graph
{
// Forward declaration
class Graph;

/** Graph builder class
 *
 * Builds and compiles a graph
 */
class GraphBuilder final
{
public:
    /** Adds a Const node to the graph
     *
     * @param[in] g        Graph to add the node to
     * @param[in] params   Common node parameters
     * @param[in] desc     Tensor descriptor of the node
     * @param[in] accessor (Optional) Accessor of the const node data
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_const_node(Graph &g, NodeParams params, const TensorDescriptor &desc, ITensorAccessorUPtr accessor = nullptr);
    /** Adds an input layer node to the graph
     *
     * @param[in] g        Graph to add the node to
     * @param[in] params   Common node parameters
     * @param[in] desc     Tensor descriptor of the Tensor
     * @param[in] accessor (Optional) Accessor of the input node data
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_input_node(Graph &g, NodeParams params, const TensorDescriptor &desc, ITensorAccessorUPtr accessor = nullptr);
    /** Adds an output layer node to the graph
     *
     * @param[in] g        Graph to add the node to
     * @param[in] params   Common node parameters
     * @param[in] input    Input to the output node as a NodeID-Index pair
     * @param[in] accessor (Optional) Accessor of the output node data
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_output_node(Graph &g, NodeParams params, NodeIdxPair input, ITensorAccessorUPtr accessor = nullptr);
    /** Adds an activation layer node to the graph
     *
     * @param[in] g              Graph to add the node to
     * @param[in] params         Common node parameters
     * @param[in] input          Input to the activation layer node as a NodeID-Index pair
     * @param[in] act_info       Activation layer information
     * @param[in] out_quant_info (Optional) Output quantization info
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_activation_node(Graph &g, NodeParams params, NodeIdxPair input, ActivationLayerInfo act_info,
                                      const QuantizationInfo &out_quant_info = QuantizationInfo());
    /** Adds a batch normalization layer node to the graph
     *
     * @param[in] g              Graph to add the node to
     * @param[in] params         Common node parameters
     * @param[in] input          Input to the batch normalization layer node as a NodeID-Index pair
     * @param[in] epsilon        Epsilon parameter
     * @param[in] mean_accessor  Const Node ID that contains the mean values
     * @param[in] var_accessor   Const Node ID that contains the variance values
     * @param[in] beta_accessor  Const Node ID that contains the beta values. Can be EmptyNodeID
     * @param[in] gamma_accessor Const Node ID that contains the gamma values. Can be EmptyNodeID
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_batch_normalization_node(Graph &g, NodeParams params, NodeIdxPair input, float epsilon,
                                               ITensorAccessorUPtr mean_accessor = nullptr, ITensorAccessorUPtr var_accessor = nullptr,
                                               ITensorAccessorUPtr beta_accessor = nullptr, ITensorAccessorUPtr gamma_accessor = nullptr);
    /** Adds a bounding box transform layer node to the graph
     *
     * @param[in] g      Graph to add the node to
     * @param[in] params Common node parameters
     * @param[in] input  Input to the bounding box transform layer node as a NodeID-Index pair
     * @param[in] deltas Deltas input to the bounding box transform layer node as a NodeID-Index pair
     * @param[in] info   Bounding Box Transform information
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_bounding_box_transform_node(Graph &g, NodeParams params, NodeIdxPair input, NodeIdxPair deltas, BoundingBoxTransformInfo info);
    /** Adds an channel shuffle layer node to the graph
     *
     * @param[in] g          Graph to add the node to
     * @param[in] params     Common node parameters
     * @param[in] input      Input to the activation layer node as a NodeID-Index pair
     * @param[in] num_groups Number of groups
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_channel_shuffle_node(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_groups);
    /** Adds a convolution layer node to the graph
     *
     * TODO (COMPMID-1113): Add a graph descriptor for convolution layer node
     *
     * @param[in] g                     Graph to add the node to
     * @param[in] params                Common node parameters
     * @param[in] input                 Input to the convolution layer node as a NodeID-Index pair
     * @param[in] kernel_spatial_extend Spatial extend of convolution kernels
     * @param[in] depth                 Number of convolution kernels
     * @param[in] conv_info             Convolution layer information
     * @param[in] num_groups            (Optional) Number of groups for a grouped convolution. Defaults to 1
     * @param[in] method                (Optional) Convolution method to use
     * @param[in] fast_math_hint        (Optional) Fast math hint
     * @param[in] weights_accessor      (Optional) Accessor of the weights node data
     * @param[in] bias_accessor         (Optional) Accessor of the bias node data
     * @param[in] weights_quant_info    (Optional) Weights quantization info
     * @param[in] out_quant_info        (Optional) Output quantization info
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_convolution_node(Graph &g, NodeParams params, NodeIdxPair input,
                                       Size2D kernel_spatial_extend, unsigned int depth, PadStrideInfo conv_info, unsigned int num_groups = 1,
                                       ConvolutionMethod method = ConvolutionMethod::Default, FastMathHint fast_math_hint = FastMathHint::Disabled,
                                       ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr,
                                       const QuantizationInfo &weights_quant_info = QuantizationInfo(),
                                       const QuantizationInfo &out_quant_info     = QuantizationInfo());
    /** Adds a deconvolution layer node to the graph
     *
     * @param[in] g                     Graph to add the node to
     * @param[in] params                Common node parameters
     * @param[in] input                 Input to the convolution layer node as a NodeID-Index pair
     * @param[in] kernel_spatial_extend Spatial extend of convolution kernels
     * @param[in] depth                 Number of convolution kernels
     * @param[in] deconv_info           Convolution layer information
     * @param[in] weights_accessor      (Optional) Accessor of the weights node data
     * @param[in] bias_accessor         (Optional) Accessor of the bias node data
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_deconvolution_node(Graph &g, NodeParams params, NodeIdxPair input,
                                         Size2D kernel_spatial_extend, unsigned int depth, PadStrideInfo deconv_info,
                                         ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr);
    /** Adds a depth concatenate node to the graph
     *
     * @param[in] g                 Graph to add the node to
     * @param[in] params            Common node parameters
     * @param[in] inputs            Inputs to the concatenate layer node as a NodeID-Index pair
     * @param[in] concat_descriptor Concatenation layer descriptor
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_concatenate_node(Graph &g, NodeParams params, const std::vector<NodeIdxPair> &inputs, const descriptors::ConcatLayerDescriptor &concat_descriptor);
    /** Adds a depth-wise convolution layer node to the graph
     *
     * @param[in] g                     Graph to add the node to
     * @param[in] params                Common node parameters
     * @param[in] input                 Input to the depthwise convolution layer node as a NodeID-Index pair
     * @param[in] kernel_spatial_extend Spatial extend of convolution kernels
     * @param[in] conv_info             Convolution layer information
     * @param[in] depth_multiplier      (Optional) Depth multiplier parameter.
     * @param[in] method                (Optional) Convolution method to use
     * @param[in] weights_accessor      (Optional) Accessor of the weights node data
     * @param[in] bias_accessor         (Optional) Accessor of the bias node data
     * @param[in] quant_info            (Optional) Weights quantization info
     * @param[in] out_quant_info        (Optional) Output quantization info
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_depthwise_convolution_node(Graph &g, NodeParams params, NodeIdxPair input,
                                                 Size2D kernel_spatial_extend, PadStrideInfo conv_info, int depth_multiplier = 1,
                                                 DepthwiseConvolutionMethod method    = DepthwiseConvolutionMethod::Default,
                                                 ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr, const QuantizationInfo &quant_info = QuantizationInfo(),
                                                 const QuantizationInfo &out_quant_info = QuantizationInfo());
    /** Adds an element-wise layer node to the graph
     *
     * @param[in] g         Graph to add the node to
     * @param[in] params    Common node parameters
     * @param[in] input0    First input to the element-wise operation layer node as a NodeID-Index pair
     * @param[in] input1    Second input to the element-wise operation layer node as a NodeID-Index pair
     * @param[in] operation Element-wise operation to perform
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_elementwise_node(Graph &g, NodeParams params, NodeIdxPair input0, NodeIdxPair input1, EltwiseOperation operation);
    /** Adds a dequantization node to the graph
     *
     * @param[in] g      Graph to add the node to
     * @param[in] params Common node parameters
     * @param[in] input  Input to the dequantization node as a NodeID-Index pair
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_dequantization_node(Graph &g, NodeParams params, NodeIdxPair input);
    /** Adds a detection output layer node to the graph
     *
     * @param[in] g              Graph to add the node to
     * @param[in] params         Common node parameters
     * @param[in] input_loc      Location input to the detection output layer node as a NodeID-Index pair
     * @param[in] input_conf     Confidence input to the detection output layer node as a NodeID-Index pair
     * @param[in] input_priorbox PriorBox input to the detection output layer node as a NodeID-Index pair
     * @param[in] detect_info    Detection output layer parameters
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_detection_output_node(Graph &g, NodeParams params, NodeIdxPair input_loc, NodeIdxPair input_conf, NodeIdxPair input_priorbox, const DetectionOutputLayerInfo &detect_info);
    /** Adds a detection post process layer node to the graph
     *
     * @param[in] g                      Graph to add the node to
     * @param[in] params                 Common node parameters
     * @param[in] input_box_encoding     Boxes input to the detection output layer node as a NodeID-Index pair
     * @param[in] input_class_prediction Class prediction input to the detection output layer node as a NodeID-Index pair
     * @param[in] detect_info            Detection output layer parameters
     * @param[in] anchors_accessor       (Optional) Const Node ID that contains the anchor values
     * @param[in] anchor_quant_info      (Optional) Anchor quantization info
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_detection_post_process_node(Graph &g, NodeParams params, NodeIdxPair input_box_encoding, NodeIdxPair input_class_prediction,
                                                  const DetectionPostProcessLayerInfo &detect_info, ITensorAccessorUPtr anchors_accessor = nullptr,
                                                  const QuantizationInfo &anchor_quant_info = QuantizationInfo());
    /** Adds a Dummy node to the graph
     *
     * @note this node if for debugging purposes. Just alters the shape of the graph pipeline as requested.
     *
     * @param[in] g      Graph to add the node to
     * @param[in] params Common node parameters
     * @param[in] input  Input to the dummy node as a NodeID-Index pair
     * @param[in] shape  Output shape
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_dummy_node(Graph &g, NodeParams params, NodeIdxPair input, TensorShape shape);
    /** Adds a flatten layer node to the graph
     *
     * @param[in] g      Graph to add the node to
     * @param[in] params Common node parameters
     * @param[in] input  Input to the flatten layer node as a NodeID-Index pair
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_flatten_node(Graph &g, NodeParams params, NodeIdxPair input);
    /** Adds a fully connected layer node to the graph
     *
     * @param[in] g              Graph to add the layer to
     * @param[in] params         Common node parameters
     * @param[in] input          Input to the fully connected layer node as a NodeID-Index pair
     * @param[in] num_outputs    Number of output neurons
     * @param[in] weights_nid    Node ID of the weights node data
     * @param[in] bias_nid       (Optional) Node ID of the bias node data. Defaults to EmptyNodeID
     * @param[in] fc_info        (Optional) Fully connected layer metadata
     * @param[in] out_quant_info (Optional) Output quantization info
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_fully_connected_layer(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_outputs,
                                            NodeID weights_nid, NodeID bias_nid = EmptyNodeID,
                                            const FullyConnectedLayerInfo fc_info        = FullyConnectedLayerInfo(),
                                            const QuantizationInfo       &out_quant_info = QuantizationInfo());
    /** Adds a fully connected layer node to the graph
     *
     * @param[in] g                  Graph to add the layer to
     * @param[in] params             Common node parameters
     * @param[in] input              Input to the fully connected layer node as a NodeID-Index pair
     * @param[in] num_outputs        Number of output neurons
     * @param[in] weights_accessor   (Optional) Accessor of the weights node data
     * @param[in] bias_accessor      (Optional) Accessor of the bias node data
     * @param[in] fc_info            (Optional) Fully connected layer metadata
     * @param[in] weights_quant_info (Optional) Weights quantization info
     * @param[in] out_quant_info     (Optional) Output quantization info
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_fully_connected_layer(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_outputs,
                                            ITensorAccessorUPtr weights_accessor = nullptr, ITensorAccessorUPtr bias_accessor = nullptr,
                                            const FullyConnectedLayerInfo fc_info            = FullyConnectedLayerInfo(),
                                            const QuantizationInfo       &weights_quant_info = QuantizationInfo(),
                                            const QuantizationInfo       &out_quant_info     = QuantizationInfo());
    /** Adds a generate proposals layer node to the graph
     *
     * @param[in] g       Graph to add the layer to
     * @param[in] params  Common node parameters
     * @param[in] scores  Input scores to the generate proposals layer node as a NodeID-Index pair
     * @param[in] deltas  Input deltas to the generate proposals layer node as a NodeID-Index pair
     * @param[in] anchors Input anchors to the generate proposals layer node as a NodeID-Index pair
     * @param[in] info    Generate proposals operation information
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_generate_proposals_node(Graph &g, NodeParams params, NodeIdxPair scores, NodeIdxPair deltas,
                                              NodeIdxPair anchors, GenerateProposalsInfo info);
    /** Adds a normalization layer node to the graph
     *
     * @param[in] g         Graph to add the node to
     * @param[in] params    Common node parameters
     * @param[in] input     Input to the normalization layer node as a NodeID-Index pair
     * @param[in] norm_info Normalization layer information
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_normalization_node(Graph &g, NodeParams params, NodeIdxPair input, NormalizationLayerInfo norm_info);
    /** Adds a normalize planar YUV layer node to the graph
     *
     * @param[in] g             Graph to add the node to
     * @param[in] params        Common node parameters
     * @param[in] input         Input to the normalize planar YUV layer node as a NodeID-Index pair
     * @param[in] mean_accessor Const Node ID that contains the mean values
     * @param[in] std_accessor  Const Node ID that contains the variance values
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_normalize_planar_yuv_node(Graph &g, NodeParams params, NodeIdxPair input,
                                                ITensorAccessorUPtr mean_accessor = nullptr, ITensorAccessorUPtr std_accessor = nullptr);
    /** Adds a pad layer node to the graph
     *
     * @param[in] g         Graph to add the node to
     * @param[in] params    Common node parameters
     * @param[in] input     Input to the reshape layer node as a NodeID-Index pair
     * @param[in] paddings  The padding for each spatial dimension of the input tensor. The pair padding[i]
     *                      specifies the front and the end padding in the i-th dimension.
     * @param[in] pad_value Padding value to be used. Defaults to 0
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_pad_node(Graph &g, NodeParams params, NodeIdxPair input, const PaddingList &paddings, PixelValue pad_value = PixelValue());
    /** Adds a permute layer node to the graph
     *
     * @param[in] g      Graph to add the node to
     * @param[in] params Common node parameters
     * @param[in] input  Input to the reshape layer node as a NodeID-Index pair
     * @param[in] perm   Permutation vector
     * @param[in] layout (Optional) Data layout to assign to permuted tensor.
     *                    If UNKNOWN then the input's layout will be used.
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_permute_node(Graph &g, NodeParams params, NodeIdxPair input, PermutationVector perm, DataLayout layout = DataLayout::UNKNOWN);
    /** Adds a pooling layer node to the graph
     *
     * @param[in] g         Graph to add the node to
     * @param[in] params    Common node parameters
     * @param[in] input     Input to the pooling layer node as a NodeID-Index pair
     * @param[in] pool_info Pooling layer information
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_pooling_node(Graph &g, NodeParams params, NodeIdxPair input, PoolingLayerInfo pool_info);
    /** Adds a prelu layer node to the graph
     *
     * @param[in] g      Graph to add the node to
     * @param[in] params Common node parameters
     * @param[in] input  Input to the PRelu node as a NodeID-Index pair
     * @param[in] alpha  Alpha input to the PRelu node as a NodeID-Index pair
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_prelu_node(Graph &g, NodeParams params, NodeIdxPair input, NodeIdxPair alpha);
    /** Adds a print layer node to the graph
     *
     * @param[in] g           Graph to add the node to
     * @param[in] params      Common node parameters
     * @param[in] input       Input to the print layer node as a NodeID-Index pair
     * @param[in] stream      Output stream.
     * @param[in] format_info (Optional) Format info.
     * @param[in] transform   (Optional) Transformation function to be applied to the input tensor before printing.
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_print_node(Graph &g, NodeParams params, NodeIdxPair input, std::ostream &stream, const IOFormatInfo &format_info = IOFormatInfo(),
                                 const std::function<ITensor *(ITensor *)> transform = nullptr);
    /** Adds a priorbox layer node to the graph
     *
     * @param[in] g          Graph to add the node to
     * @param[in] params     Common node parameters
     * @param[in] input0     First input to the priorbox layer node as a NodeID-Index pair
     * @param[in] input1     Second input to the priorbox layer node as a NodeID-Index pair
     * @param[in] prior_info PriorBox parameters
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_priorbox_node(Graph &g, NodeParams params, NodeIdxPair input0, NodeIdxPair input1, const PriorBoxLayerInfo &prior_info);
    /** Adds a quantization layer node to the graph
     *
     * @param[in] g              Graph to add the node to
     * @param[in] params         Common node parameters
     * @param[in] input          Input to the quantization layer node as a NodeID-Index pair
     * @param[in] out_quant_info Output quantization info
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_quantization_node(Graph &g, NodeParams params, NodeIdxPair input, const QuantizationInfo &out_quant_info);
    /** Adds a reorg layer node to the graph
     *
     * @param[in] g      Graph to add the node to
     * @param[in] params Common node parameters
     * @param[in] input  Input to the reorg layer node as a NodeID-Index pair
     * @param[in] stride Stride value to use for reorganizing the values in the output tensor.
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_reorg_node(Graph &g, NodeParams params, NodeIdxPair input, int stride);
    /** Adds a reshape layer node to the graph
     *
     * @param[in] g      Graph to add the node to
     * @param[in] params Common node parameters
     * @param[in] input  Input to the reshape layer node as a NodeID-Index pair
     * @param[in] shape  Output reshaped shape
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_reshape_node(Graph &g, NodeParams params, NodeIdxPair input, TensorShape shape);
    /** Adds a resize layer node to the graph
     *
     * @param[in] g            Graph to add the node to
     * @param[in] params       Common node parameters
     * @param[in] input        Input to the reshape layer node as a NodeID-Index pair
     * @param[in] policy       Interpolation policy
     * @param[in] width_scale  Width scaling factor
     * @param[in] height_scale Height scaling factor
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_resize_node(Graph &g, NodeParams params, NodeIdxPair input, InterpolationPolicy policy, float width_scale, float height_scale);
    /** Adds a ROI align layer node to the graph
     *
     * @param[in] g         Graph to add the node to
     * @param[in] params    Common node parameters
     * @param[in] input     Input to the reshape layer node as a NodeID-Index pair
     * @param[in] rois      Input containing the ROIs.
     * @param[in] pool_info Contains pooling operation information described in @ref ROIPoolingLayerInfo.
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_roi_align_node(Graph &g, NodeParams params, NodeIdxPair input, NodeIdxPair rois, ROIPoolingLayerInfo pool_info);
    /** Adds a scale layer node to the graph
     * This layer computes a product of the input with a scale (read from mul_accessor) and it applies an offset (read from add_accessor).
     * output = input * mul_w + add_w
     *
     * @param[in] g            Graph to add the layer to
     * @param[in] params       Common node parameters
     * @param[in] input        Input to the fully connected layer node as a NodeID-Index pair
     * @param[in] mul_accessor (Optional) Accessor of the mul node data
     * @param[in] add_accessor (Optional) Accessor of the add node data
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_scale_layer(Graph &g, const NodeParams &params, NodeIdxPair input,
                                  ITensorAccessorUPtr mul_accessor = nullptr, ITensorAccessorUPtr add_accessor = nullptr);
    /** Adds a softmax node to the graph
     *
     * @param[in] g      Graph to add the node to
     * @param[in] params Common node parameters
     * @param[in] input  Input to the softmax layer node as a NodeID-Index pair
     * @param[in] beta   Beta parameter
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_softmax_node(Graph &g, NodeParams params, NodeIdxPair input, float beta = 1.f);
    /** Adds a slice node to the graph
     *
     * @param[in] g      Graph to add the node to
     * @param[in] params Common node parameters
     * @param[in] input  Input to the slice layer node as a NodeID-Index pair
     * @param[in] starts The starts of the dimensions of the input tensor to be sliced. The length must be of rank(input).
     * @param[in] ends   The ends of the dimensions of the input tensor to be sliced. The length must be of rank(input).
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_slice_node(Graph &g, NodeParams params, NodeIdxPair input, Coordinates &starts, Coordinates &ends);
    /** Adds a split node to the graph
     *
     * @param[in] g          Graph to add the node to
     * @param[in] params     Common node parameters
     * @param[in] input      Input to the split layer node as a NodeID-Index pair
     * @param[in] num_splits Number of different splits
     * @param[in] axis       (Optional) Split axis. Defaults to 0
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_split_node(Graph &g, NodeParams params, NodeIdxPair input, unsigned int num_splits, unsigned int axis = 0);
    /** Adds a stack layer node to the graph
     *
     * @param[in] g      Graph to add the node to
     * @param[in] params Common node parameters
     * @param[in] inputs Inputs to the reorg layer node as a NodeID-Index pair
     * @param[in] axis   Axis along which the input tensors have to be packed
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_stack_node(Graph &g, NodeParams params, const std::vector<NodeIdxPair> &inputs, int axis);
    /** Adds an upsample layer to the graph
     *
     * @param[in] g                 Graph to add the node to
     * @param[in] params            Common node parameters
     * @param[in] input             Input to the yolo layer node as a NodeID-Index pair
     * @param[in] info              Upsample layer stride info
     * @param[in] upsampling_policy Upsampling policy used
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_upsample_node(Graph &g, NodeParams params, NodeIdxPair input, Size2D info, InterpolationPolicy upsampling_policy);
    /** Adds a yolo layer to the graph
     *
     * @param[in] g           Graph to add the node to
     * @param[in] params      Common node parameters
     * @param[in] input       Input to the yolo layer node as a NodeID-Index pair
     * @param[in] act_info    Activation layer parameters
     * @param[in] num_classes Number of classes to activate
     *
     * @return Node ID of the created node, EmptyNodeID in case of error
     */
    static NodeID add_yolo_node(Graph &g, NodeParams params, NodeIdxPair input, ActivationLayerInfo act_info, int32_t num_classes);
};
} // namespace graph
} // namespace arm_compute
#endif /* ARM_COMPUTE_GRAPH_GRAPH_BUILDER_H */
