/*
 * 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_LAYERS_H
#define ARM_COMPUTE_GRAPH_LAYERS_H

#include "arm_compute/graph/GraphBuilder.h"
#include "arm_compute/graph/Types.h"
#include "arm_compute/graph/frontend/ILayer.h"
#include "arm_compute/graph/frontend/IStream.h"
#include "arm_compute/graph/frontend/SubStream.h"

#include "arm_compute/core/utils/misc/Utility.h"

#include <memory>
#include <string>

namespace arm_compute
{
namespace graph
{
namespace frontend
{
/** Input Layer */
class InputLayer final : public ILayer
{
public:
    /** Construct an input layer.
     *
     * @param[in] desc     Description of input tensor.
     * @param[in] accessor Accessor to get input tensor data from.
     */
    InputLayer(TensorDescriptor desc, ITensorAccessorUPtr accessor)
        : _desc(desc), _accessor(std::move(accessor))
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams common_params = { name(), s.hints().target_hint };
        return GraphBuilder::add_input_node(s.graph(), common_params, _desc, std::move(_accessor));
    }

private:
    TensorDescriptor    _desc;
    ITensorAccessorUPtr _accessor;
};

/** Constant Layer */
class ConstantLayer final : public ILayer
{
public:
    /** Construct a constant layer.
     *
     * @param[in] desc     Description of input tensor.
     * @param[in] accessor Accessor to get input tensor data from.
     */
    ConstantLayer(TensorDescriptor desc, ITensorAccessorUPtr accessor)
        : _desc(desc), _accessor(std::move(accessor))
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams common_params = { name(), s.hints().target_hint };
        return GraphBuilder::add_const_node(s.graph(), common_params, _desc, std::move(_accessor));
    }

private:
    TensorDescriptor    _desc;
    ITensorAccessorUPtr _accessor;
};

/** Output Layer */
class OutputLayer final : public ILayer
{
public:
    /** Construct an output layer.
     *
     * @param[in] accessor       Accessor to give output tensor data to.
     * @param[in] connection_idx (Optional) Input connection index
     */
    OutputLayer(ITensorAccessorUPtr accessor, unsigned int connection_idx = 0)
        : _accessor(std::move(accessor)), _connection_idx(connection_idx)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), _connection_idx };
        return GraphBuilder::add_output_node(s.graph(), common_params, input, std::move(_accessor));
    }

private:
    ITensorAccessorUPtr _accessor;
    unsigned int        _connection_idx;
};

/** Activation Layer */
class ActivationLayer final : public ILayer
{
public:
    /** Construct an activation layer.
     *
     * @param[in] act_info       Activation information
     * @param[in] out_quant_info (Optional) Output quantization info
     */
    ActivationLayer(ActivationLayerInfo    act_info,
                    const QuantizationInfo out_quant_info = QuantizationInfo())
        : _act_info(act_info),
          _out_quant_info(std::move(out_quant_info))
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_activation_node(s.graph(), common_params, input, _act_info, std::move(_out_quant_info));
    }

private:
    ActivationLayerInfo    _act_info;
    const QuantizationInfo _out_quant_info;
};

/** Batchnormalization Layer */
class BatchNormalizationLayer final : public ILayer
{
public:
    /** Construct a batch normalization layer.
     *
     * @param[in] mean    Accessor to get mean tensor data from.
     * @param[in] var     Accessor to get var tensor data from.
     * @param[in] gamma   (Optional) Accessor to get gamma tensor data from. Default: nullptr.
     * @param[in] beta    (Optional) Accessor to get beta tensor data from. Default: nullptr.
     * @param[in] epsilon (Optional) Epsilon value. Default: 0.001.
     */
    BatchNormalizationLayer(ITensorAccessorUPtr mean,
                            ITensorAccessorUPtr var,
                            ITensorAccessorUPtr gamma   = nullptr,
                            ITensorAccessorUPtr beta    = nullptr,
                            float               epsilon = 0.001f)
        : _mean(std::move(mean)), _var(std::move(var)), _gamma(std::move(gamma)), _beta(std::move(beta)), _epsilon(epsilon)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        ARM_COMPUTE_ERROR_ON(_mean == nullptr);
        ARM_COMPUTE_ERROR_ON(_var == nullptr);

        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_batch_normalization_node(s.graph(), common_params, input, _epsilon,
                                                          std::move(_mean), std::move(_var), std::move(_beta), std::move(_gamma));
    }

private:
    ITensorAccessorUPtr _mean;
    ITensorAccessorUPtr _var;
    ITensorAccessorUPtr _gamma;
    ITensorAccessorUPtr _beta;
    float               _epsilon;
};

/** Bounding Box Transform Layer */
class BoundingBoxTransformLayer final : public ILayer
{
public:
    /** Construct a bounding box transform layer.
     *
     * @param[in] sub_stream_input  Graph sub-stream for the input
     * @param[in] sub_stream_deltas Graph sub-stream for the deltas
     * @param[in] info              Contains BoundingBox operation information described in @ref BoundingBoxTransformInfo.
     */
    BoundingBoxTransformLayer(SubStream &&sub_stream_input, SubStream &&sub_stream_deltas, BoundingBoxTransformInfo info)
        : _ss_input(sub_stream_input), _ss_deltas(sub_stream_deltas), _bbox_info(info)
    {
    }

    /** Create layer and add to the given stream.
     *
     * @param[in] s Stream to add layer to.
     *
     * @return ID of the created node.
     */
    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { _ss_input.tail_node(), 0 };
        NodeIdxPair deltas        = { _ss_deltas.tail_node(), 0 };
        return GraphBuilder::add_bounding_box_transform_node(s.graph(), common_params, input, deltas, _bbox_info);
    }

private:
    SubStream                _ss_input;
    SubStream                _ss_deltas;
    BoundingBoxTransformInfo _bbox_info;
};

/** Channel Shuffle Layer */
class ChannelShuffleLayer final : public ILayer
{
public:
    /** Construct a Channel Shuffle layer.
     *
     * @param[in] num_groups Number of groups
     */
    ChannelShuffleLayer(unsigned int num_groups)
        : _num_groups(num_groups)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_channel_shuffle_node(s.graph(), common_params, input, _num_groups);
    }

private:
    unsigned int _num_groups;
};

/** Concat Layer */
class ConcatLayer final : public ILayer
{
public:
    /** Construct a concatenation layer
     *
     * @param[in] sub_stream1      First graph branch
     * @param[in] sub_stream2      Second graph branch
     * @param[in] rest_sub_streams Rest sub-graph branches
     */
    template <typename... Ts>
    ConcatLayer(SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&... rest_sub_streams)
        : _sub_streams(), _concat_descriptor(DataLayoutDimension::CHANNEL)
    {
        _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream1)));
        _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream2)));

        utility::for_each([&](SubStream && sub_stream)
        {
            _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream)));
        },
        std::move(rest_sub_streams)...);
    }
    /** Construct a concatenation layer
     *
     * @param[in] concat_descriptor Concat layer descriptor
     * @param[in] sub_stream1       First graph branch
     * @param[in] sub_stream2       Second graph branch
     * @param[in] rest_sub_streams  Rest sub-graph branches
     */
    template <typename... Ts>
    ConcatLayer(descriptors::ConcatLayerDescriptor concat_descriptor, SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&... rest_sub_streams)
        : _sub_streams(), _concat_descriptor(concat_descriptor)
    {
        _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream1)));
        _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream2)));

        utility::for_each([&](SubStream && sub_stream)
        {
            _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream)));
        },
        std::move(rest_sub_streams)...);
    }
    /** Construct a concat layer
     *
     * @param[in] sub_stream Sub-stream
     */
    template <typename... Ts>
    ConcatLayer(SubStream &&sub_stream)
        : _sub_streams(), _concat_descriptor(DataLayoutDimension::CHANNEL)
    {
        _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream)));
    }
    NodeID create_layer(IStream &s) override
    {
        NodeID     nid           = EmptyNodeID;
        NodeParams common_params = { name(), s.hints().target_hint };
        if(_sub_streams.size() == 1 && _sub_streams.at(0) != nullptr)
        {
            nid = _sub_streams[0]->tail_node();
        }
        else
        {
            // Collect tail nodes and concatenate
            std::vector<NodeIdxPair> nodes;
            for(auto &ss : _sub_streams)
            {
                if(ss && (ss->tail_node() != EmptyNodeID))
                {
                    const auto tail_node = s.graph().node(ss->tail_node());
                    if(tail_node != nullptr && tail_node->type() != NodeType::Output)
                    {
                        nodes.push_back({ ss->tail_node(), 0 });
                    }
                }
            }
            nid = GraphBuilder::add_concatenate_node(s.graph(), common_params, nodes, _concat_descriptor);
        }
        return nid;
    }

private:
    std::vector<std::unique_ptr<SubStream>> _sub_streams;
    descriptors::ConcatLayerDescriptor      _concat_descriptor;
};

/** Convolution Layer */
class ConvolutionLayer final : public ILayer
{
public:
    /** Construct a convolution layer.
     *
     * @param[in] conv_width         Convolution width.
     * @param[in] conv_height        Convolution height.
     * @param[in] ofm                Output feature map.
     * @param[in] weights            Accessor to get kernel weights from.
     * @param[in] bias               Accessor to get kernel bias from.
     * @param[in] conv_info          Padding and stride information.
     * @param[in] num_groups         (Optional) Number of groups. Default: 1.
     * @param[in] weights_quant_info (Optional) Weights quantization information
     * @param[in] out_quant_info     (Optional) Output quantization info
     */
    ConvolutionLayer(unsigned int           conv_width,
                     unsigned int           conv_height,
                     unsigned int           ofm,
                     ITensorAccessorUPtr    weights,
                     ITensorAccessorUPtr    bias,
                     PadStrideInfo          conv_info,
                     unsigned int           num_groups         = 1,
                     const QuantizationInfo weights_quant_info = QuantizationInfo(),
                     const QuantizationInfo out_quant_info     = QuantizationInfo())
        : _conv_width(conv_width),
          _conv_height(conv_height),
          _ofm(ofm),
          _conv_info(std::move(conv_info)),
          _num_groups(num_groups),
          _weights(std::move(weights)),
          _bias(std::move(bias)),
          _weights_quant_info(std::move(weights_quant_info)),
          _out_quant_info(std::move(out_quant_info))
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeIdxPair input         = { s.tail_node(), 0 };
        NodeParams  common_params = { name(), s.hints().target_hint };
        return GraphBuilder::add_convolution_node(s.graph(), common_params, input,
                                                  Size2D(_conv_width, _conv_height), _ofm, _conv_info, _num_groups,
                                                  s.hints().convolution_method_hint, s.hints().fast_math_hint,
                                                  std::move(_weights), std::move(_bias), std::move(_weights_quant_info), std::move(_out_quant_info));
    }

private:
    unsigned int           _conv_width;
    unsigned int           _conv_height;
    unsigned int           _ofm;
    const PadStrideInfo    _conv_info;
    unsigned int           _num_groups;
    ITensorAccessorUPtr    _weights;
    ITensorAccessorUPtr    _bias;
    const QuantizationInfo _weights_quant_info;
    const QuantizationInfo _out_quant_info;
};

/** Deconvolution Layer */
class DeconvolutionLayer final : public ILayer
{
public:
    /** Construct a convolution layer.
     *
     * @param[in] conv_width  Convolution width.
     * @param[in] conv_height Convolution height.
     * @param[in] ofm         Output feature map.
     * @param[in] weights     Accessor to get kernel weights from.
     * @param[in] bias        Accessor to get kernel bias from.
     * @param[in] deconv_info Padding and stride information.
     */
    DeconvolutionLayer(unsigned int        conv_width,
                       unsigned int        conv_height,
                       unsigned int        ofm,
                       ITensorAccessorUPtr weights,
                       ITensorAccessorUPtr bias,
                       PadStrideInfo       deconv_info)
        : _conv_width(conv_width),
          _conv_height(conv_height),
          _ofm(ofm),
          _deconv_info(std::move(deconv_info)),
          _weights(std::move(weights)),
          _bias(std::move(bias))
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeIdxPair input         = { s.tail_node(), 0 };
        NodeParams  common_params = { name(), s.hints().target_hint };
        return GraphBuilder::add_deconvolution_node(s.graph(), common_params, input,
                                                    Size2D(_conv_width, _conv_height), _ofm, _deconv_info,
                                                    std::move(_weights), std::move(_bias));
    }

private:
    unsigned int        _conv_width;
    unsigned int        _conv_height;
    unsigned int        _ofm;
    const PadStrideInfo _deconv_info;
    ITensorAccessorUPtr _weights;
    ITensorAccessorUPtr _bias;
};

/** Depthwise Convolution Layer */
class DepthwiseConvolutionLayer final : public ILayer
{
public:
    /** Construct a depthwise convolution layer.
     *
     * @param[in] conv_width         Convolution width.
     * @param[in] conv_height        Convolution height.
     * @param[in] weights            Accessor to get kernel weights from.
     * @param[in] bias               Accessor to get kernel bias from.
     * @param[in] conv_info          Padding and stride information.
     * @param[in] depth_multiplier   (Optional) Depth multiplier parameter.
     * @param[in] weights_quant_info (Optional) Quantization info used for weights
     * @param[in] out_quant_info     (Optional) Output quantization info
     */
    DepthwiseConvolutionLayer(unsigned int           conv_width,
                              unsigned int           conv_height,
                              ITensorAccessorUPtr    weights,
                              ITensorAccessorUPtr    bias,
                              PadStrideInfo          conv_info,
                              int                    depth_multiplier   = 1,
                              const QuantizationInfo weights_quant_info = QuantizationInfo(),
                              const QuantizationInfo out_quant_info     = QuantizationInfo())
        : _conv_width(conv_width),
          _conv_height(conv_height),
          _conv_info(std::move(conv_info)),
          _weights(std::move(weights)),
          _bias(std::move(bias)),
          _depth_multiplier(depth_multiplier),
          _weights_quant_info(std::move(weights_quant_info)),
          _out_quant_info(std::move(out_quant_info))
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeIdxPair input         = { s.tail_node(), 0 };
        NodeParams  common_params = { name(), s.hints().target_hint };
        return GraphBuilder::add_depthwise_convolution_node(s.graph(), common_params,
                                                            input, Size2D(_conv_width, _conv_height), _conv_info, _depth_multiplier,
                                                            s.hints().depthwise_convolution_method_hint,
                                                            std::move(_weights), std::move(_bias), std::move(_weights_quant_info), std::move(_out_quant_info));
    }

private:
    unsigned int           _conv_width;
    unsigned int           _conv_height;
    const PadStrideInfo    _conv_info;
    ITensorAccessorUPtr    _weights;
    ITensorAccessorUPtr    _bias;
    int                    _depth_multiplier;
    const QuantizationInfo _weights_quant_info;
    const QuantizationInfo _out_quant_info;
};

/** DepthToSpace Layer */
class DepthToSpaceLayer final : public ILayer
{
public:
    /** Construct an DepthToSpace layer.
     *
     * @param[in] block_shape Block size to rearranged
     */
    DepthToSpaceLayer(int32_t block_shape)
        : _block_shape(block_shape)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_depth_to_space_node(s.graph(), common_params, input, _block_shape);
    }

private:
    int32_t _block_shape;
};

/** Dequantization Layer */
class DequantizationLayer final : public ILayer
{
public:
    /** Construct a dequantization layer.
     *
     */
    DequantizationLayer()
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_dequantization_node(s.graph(), common_params, input);
    }
};

/** DetectionOutput Layer */
class DetectionOutputLayer final : public ILayer
{
public:
    /** Construct a detection output layer.
     *
     * @param[in] sub_stream_conf  Confidence graph sub-stream.
     * @param[in] sub_stream_prior PriorBox graph sub-stream.
     * @param[in] detect_info      DetectionOutput parameters.
     */
    DetectionOutputLayer(SubStream &&sub_stream_conf, SubStream &&sub_stream_prior, const DetectionOutputLayerInfo &detect_info)
        : _ss_conf(std::move(sub_stream_conf)), _ss_prior(std::move(sub_stream_prior)), _detect_info(detect_info)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params  = { name(), s.hints().target_hint };
        NodeIdxPair input_loc      = { s.tail_node(), 0 };
        NodeIdxPair input_conf     = { _ss_conf.tail_node(), 0 };
        NodeIdxPair input_priorbox = { _ss_prior.tail_node(), 0 };
        return GraphBuilder::add_detection_output_node(s.graph(), common_params, input_loc, input_conf, input_priorbox, _detect_info);
    }

private:
    SubStream                _ss_conf;
    SubStream                _ss_prior;
    DetectionOutputLayerInfo _detect_info;
};
/** DetectionOutputPostProcess Layer */
class DetectionPostProcessLayer final : public ILayer
{
public:
    /** Construct a detection output layer.
     *
     * @param[in] sub_stream_class_prediction Class prediction graph sub-stream.
     * @param[in] detect_info                 DetectionOutput parameters.
     * @param[in] anchors                     Accessor to get anchors tensor data from.
     * @param[in] out_quant_info              (Optional) Output quantization info
     */
    DetectionPostProcessLayer(SubStream &&sub_stream_class_prediction, DetectionPostProcessLayerInfo detect_info, ITensorAccessorUPtr anchors,
                              const QuantizationInfo out_quant_info = QuantizationInfo())
        : _sub_stream_class_prediction(std::move(sub_stream_class_prediction)), _detect_info(detect_info), _anchors(std::move(anchors)), _out_quant_info(std::move(out_quant_info))
    {
    }

    NodeID create_layer(IStream &s) override
    {
        ARM_COMPUTE_ERROR_ON(_anchors == nullptr);

        NodeParams  common_params          = { name(), s.hints().target_hint };
        NodeIdxPair input_box_encoding     = { s.tail_node(), 0 };
        NodeIdxPair input_class_prediction = { _sub_stream_class_prediction.tail_node(), 0 };
        return GraphBuilder::add_detection_post_process_node(s.graph(), common_params, input_box_encoding, input_class_prediction, _detect_info, std::move(_anchors), std::move(_out_quant_info));
    }

private:
    SubStream                     _sub_stream_class_prediction;
    DetectionPostProcessLayerInfo _detect_info;
    ITensorAccessorUPtr           _anchors;
    const QuantizationInfo        _out_quant_info;
};
/** Dummy Layer */
class DummyLayer final : public ILayer
{
public:
    /** Construct a dummy layer.
     *
     * @param[in] shape Output shape
     */
    DummyLayer(TensorShape shape)
        : _shape(shape)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_dummy_node(s.graph(), common_params, input, _shape);
    }

private:
    TensorShape _shape;
};

class EltwiseLayer final : public ILayer
{
public:
    /** Construct an element-wise operation layer
     *
     * @param[in] sub_stream0 First graph sub-stream
     * @param[in] sub_stream1 First graph sub-stream
     * @param[in] op          Element-wise operation to perform
     */
    EltwiseLayer(SubStream &&sub_stream0, SubStream &&sub_stream1, EltwiseOperation op)
        : _ss0(std::move(sub_stream0)), _ss1(std::move(sub_stream1)), _op(op)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input0        = { _ss0.tail_node(), 0 };
        NodeIdxPair input1        = { _ss1.tail_node(), 0 };

        return GraphBuilder::add_elementwise_node(s.graph(), common_params, input0, input1, _op);
    }

private:
    SubStream        _ss0;
    SubStream        _ss1;
    EltwiseOperation _op;
};
/** Flatten Layer */
class FlattenLayer final : public ILayer
{
public:
    /** Construct a flatten layer. */
    FlattenLayer()
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_flatten_node(s.graph(), common_params, input);
    }
};

/** Fully Connected Layer */
class FullyConnectedLayer final : public ILayer
{
public:
    /** Construct a fully connected layer.
     *
     * @param[in] num_outputs        Number of outputs.
     * @param[in] weights            Accessor to get weights from.
     * @param[in] bias               Accessor to get bias from.
     * @param[in] fc_info            (Optional) Fully connected layer metadata
     * @param[in] weights_quant_info (Optional) Weights quantization information
     * @param[in] out_quant_info     (Optional) Output quantization info
     */
    FullyConnectedLayer(unsigned int                  num_outputs,
                        ITensorAccessorUPtr           weights,
                        ITensorAccessorUPtr           bias,
                        const FullyConnectedLayerInfo fc_info            = FullyConnectedLayerInfo(),
                        const QuantizationInfo        weights_quant_info = QuantizationInfo(),
                        const QuantizationInfo        out_quant_info     = QuantizationInfo())
        : _num_outputs(num_outputs),
          _weights(std::move(weights)),
          _bias(std::move(bias)),
          _weights_ss(nullptr),
          _bias_ss(nullptr),
          _fc_info(fc_info),
          _weights_quant_info(std::move(weights_quant_info)),
          _out_quant_info(std::move(out_quant_info))
    {
    }

    /** Construct a fully connected layer.
     *
     * @param[in] num_outputs        Number of outputs.
     * @param[in] sub_stream_weights Graph sub-stream for the weights.
     * @param[in] sub_stream_bias    Graph sub-stream for the bias.
     * @param[in] fc_info            (Optional) Fully connected layer metadata
     * @param[in] weights_quant_info (Optional) Weights quantization information
     * @param[in] out_quant_info     (Optional) Output quantization info
     */
    FullyConnectedLayer(unsigned int                  num_outputs,
                        SubStream                     sub_stream_weights,
                        SubStream                     sub_stream_bias,
                        const FullyConnectedLayerInfo fc_info            = FullyConnectedLayerInfo(),
                        const QuantizationInfo        weights_quant_info = QuantizationInfo(),
                        const QuantizationInfo        out_quant_info     = QuantizationInfo())
        : _num_outputs(num_outputs),
          _weights(nullptr),
          _bias(nullptr),
          _weights_ss(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream_weights))),
          _bias_ss(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream_bias))),
          _fc_info(fc_info),
          _weights_quant_info(std::move(weights_quant_info)),
          _out_quant_info(std::move(out_quant_info))
    {
    }

    /** Create layer and add to the given stream.
     *
     * @param[in] s Stream to add layer to.
     *
     * @return ID of the created node.
     */
    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        if(_weights != nullptr)
        {
            return GraphBuilder::add_fully_connected_layer(s.graph(), common_params, input, _num_outputs,
                                                           std::move(_weights), std::move(_bias), _fc_info,
                                                           std::move(_weights_quant_info), std::move(_out_quant_info));
        }
        else
        {
            ARM_COMPUTE_ERROR_ON(_weights_ss == nullptr);

            NodeID bias_nid = (_bias_ss == nullptr) ? EmptyNodeID : _bias_ss->tail_node();
            return GraphBuilder::add_fully_connected_layer(s.graph(), common_params, input, _num_outputs,
                                                           _weights_ss->tail_node(), bias_nid, _fc_info,
                                                           std::move(_out_quant_info));
        }
    }

private:
    unsigned int                  _num_outputs;
    ITensorAccessorUPtr           _weights;
    ITensorAccessorUPtr           _bias;
    std::unique_ptr<SubStream>    _weights_ss;
    std::unique_ptr<SubStream>    _bias_ss;
    const FullyConnectedLayerInfo _fc_info;
    const QuantizationInfo        _weights_quant_info;
    const QuantizationInfo        _out_quant_info;
};

/** Generate Proposals Layer */
class GenerateProposalsLayer final : public ILayer
{
public:
    /** Construct a generate proposals layer.
     *
     * @param[in] ss_scores  Graph sub-stream for the scores.
     * @param[in] ss_deltas  Graph sub-stream for the deltas.
     * @param[in] ss_anchors Graph sub-stream for the anchors.
     * @param[in] info       Generate Proposals operation information.
     */
    GenerateProposalsLayer(SubStream &&ss_scores, SubStream &&ss_deltas, SubStream &&ss_anchors, GenerateProposalsInfo info)
        : _ss_scores(std::move(ss_scores)), _ss_deltas(std::move(ss_deltas)), _ss_anchors(std::move(ss_anchors)), _info(info)
    {
    }

    /** Create layer and add to the given stream.
     *
     * @param[in] s Stream to add layer to.
     *
     * @return ID of the created node.
     */
    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair scores        = { _ss_scores.tail_node(), 0 };
        NodeIdxPair deltas        = { _ss_deltas.tail_node(), 0 };
        NodeIdxPair anchors       = { _ss_anchors.tail_node(), 0 };
        return GraphBuilder::add_generate_proposals_node(s.graph(), common_params, scores, deltas, anchors, _info);
    }

private:
    SubStream             _ss_scores;
    SubStream             _ss_deltas;
    SubStream             _ss_anchors;
    GenerateProposalsInfo _info;
};

/** Normalization Layer */
class NormalizationLayer final : public ILayer
{
public:
    /** Construct a normalization layer.
     *
     * @param[in] norm_info Normalization information.
     */
    NormalizationLayer(NormalizationLayerInfo norm_info)
        : _norm_info(norm_info)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_normalization_node(s.graph(), common_params, input, _norm_info);
    }

private:
    NormalizationLayerInfo _norm_info;
};

/** Normalize planar YUV Layer */
class NormalizePlanarYUVLayer final : public ILayer
{
public:
    /** Construct a normalize planar YUV layer.
     *
     * @param[in] mean Accessor to get mean tensor data from.
     * @param[in] std  Accessor to get std tensor data from.
     */
    NormalizePlanarYUVLayer(ITensorAccessorUPtr mean,
                            ITensorAccessorUPtr std)
        : _mean(std::move(mean)), _std(std::move(std))
    {
    }

    NodeID create_layer(IStream &s) override
    {
        ARM_COMPUTE_ERROR_ON(_mean == nullptr);
        ARM_COMPUTE_ERROR_ON(_std == nullptr);

        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_normalize_planar_yuv_node(s.graph(), common_params, input,
                                                           std::move(_mean), std::move(_std));
    }

private:
    ITensorAccessorUPtr _mean;
    ITensorAccessorUPtr _std;
};

/** Pad Layer */
class PadLayer final : public ILayer
{
public:
    /** Construct a pad layer.
     *
     * @param[in] padding   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 use. Defaults to 0.
     */
    PadLayer(PaddingList padding, PixelValue pad_value = PixelValue())
        : _padding(padding), _pad_value(pad_value)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_pad_node(s.graph(), common_params, input, _padding, _pad_value);
    }

private:
    PaddingList _padding;
    PixelValue  _pad_value;
};

/** Permute Layer */
class PermuteLayer final : public ILayer
{
public:
    /** Construct a permute layer.
     *
     * @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.
     */
    PermuteLayer(PermutationVector perm, DataLayout layout = DataLayout::UNKNOWN)
        : _perm(perm), _layout(layout)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_permute_node(s.graph(), common_params, input, _perm, _layout);
    }

private:
    PermutationVector _perm;
    DataLayout        _layout;
};

/** Pooling Layer */
class PoolingLayer final : public ILayer
{
public:
    /** Construct a pooling layer.
     *
     * @param[in] pool_info Pooling information.
     */
    PoolingLayer(PoolingLayerInfo pool_info)
        : _pool_info(pool_info)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_pooling_node(s.graph(), common_params, input, _pool_info);
    }

private:
    PoolingLayerInfo _pool_info;
};

/** PRelu Layer */
class PReluLayer final : public ILayer
{
public:
    /** Construct an PRelu operation layer
     *
     * @param[in] sub_stream0 First graph sub-stream
     * @param[in] sub_stream1 First graph sub-stream
     */
    PReluLayer(SubStream &&sub_stream0, SubStream &&sub_stream1)
        : _ss0(std::move(sub_stream0)), _ss1(std::move(sub_stream1))
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { _ss0.tail_node(), 0 };
        NodeIdxPair alpha         = { _ss1.tail_node(), 0 };

        return GraphBuilder::add_prelu_node(s.graph(), common_params, input, alpha);
    }

private:
    SubStream _ss0;
    SubStream _ss1;
};

/** Print Layer */
class PrintLayer final : public ILayer
{
public:
    /** Construct a print layer.
     *
     * Example usage to locally dequantize and print a tensor:
     *
     * Tensor *output = new Tensor();
     * const auto transform = [output](ITensor *input)
     * {
     *     output->allocator()->init(*input->info());
     *     output->info()->set_data_type(DataType::F32);
     *     output->allocator()->allocate();
     *
     *     Window win;
     *     win.use_tensor_dimensions(input->info()->tensor_shape());
     *     Iterator in(input, win);
     *     Iterator out(output, win);
     *     execute_window_loop(win, [&](const Coordinates &)
     *     {
     *         *(reinterpret_cast<float *>(out.ptr())) = dequantize_qasymm8(*in.ptr(), input->info()->quantization_info().uniform());
     *     }, in, out);
     *
     *     return output;
     * };
     *
     * graph << InputLayer(input_descriptor.set_quantization_info(in_quant_info), get_input_accessor(common_params, nullptr, false))
     *       << ...
     *       << \\ CNN Layers
     *       << ...
     *       << PrintLayer(std::cout, IOFormatInfo(), transform)
     *       << ...
     *       << OutputLayer(get_output_accessor(common_params, 5));
     *
     * @param[in] stream      Output stream.
     * @param[in] format_info (Optional) Format info.
     * @param[in] transform   (Optional) Input transform function.
     */
    PrintLayer(std::ostream &stream, const IOFormatInfo &format_info = IOFormatInfo(), const std::function<ITensor *(ITensor *)> transform = nullptr)
        : _stream(stream), _format_info(format_info), _transform(transform)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_print_node(s.graph(), common_params, input, _stream, _format_info, _transform);
    }

private:
    std::ostream                             &_stream;
    const IOFormatInfo                       &_format_info;
    const std::function<ITensor *(ITensor *)> _transform;
};

/** PriorBox Layer */
class PriorBoxLayer final : public ILayer
{
public:
    /** Construct a priorbox layer.
     *
     * @param[in] sub_stream First graph sub-stream
     * @param[in] prior_info PriorBox parameters.
     */
    PriorBoxLayer(SubStream &&sub_stream, const PriorBoxLayerInfo &prior_info)
        : _ss(std::move(sub_stream)), _prior_info(prior_info)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input0        = { s.tail_node(), 0 };
        NodeIdxPair input1        = { _ss.tail_node(), 0 };
        return GraphBuilder::add_priorbox_node(s.graph(), common_params, input0, input1, _prior_info);
    }

private:
    SubStream         _ss;
    PriorBoxLayerInfo _prior_info;
};

/** Quantization Layer */
class QuantizationLayer final : public ILayer
{
public:
    /** Construct a quantization layer.
     *
     * @param[in] out_quant_info Output tensor quantization info
     */
    QuantizationLayer(QuantizationInfo out_quant_info)
        : _out_quant_info(out_quant_info)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_quantization_node(s.graph(), common_params, input, _out_quant_info);
    }

private:
    QuantizationInfo _out_quant_info;
};

/** Reorg Layer */
class ReorgLayer final : public ILayer
{
public:
    /** Construct a reorg layer.
     *
     * @param[in] stride Stride value to use for reorganizing the values in the output tensor.
     *                   It defines the spatial distance between 2 consecutive pixels in the x and y direction
     */
    ReorgLayer(int stride)
        : _stride(stride)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_reorg_node(s.graph(), common_params, input, _stride);
    }

private:
    int _stride;
};

/** Reshape Layer */
class ReshapeLayer final : public ILayer
{
public:
    /** Construct a reshape layer.
     *
     * @param[in] shape Target shape.
     */
    ReshapeLayer(TensorShape shape)
        : _shape(shape)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_reshape_node(s.graph(), common_params, input, _shape);
    }

private:
    TensorShape _shape;
};

/** Resize Layer */
class ResizeLayer final : public ILayer
{
public:
    ResizeLayer(InterpolationPolicy policy, float width_scale, float height_scale)
        : _policy(policy), _width_scale(width_scale), _height_scale(height_scale)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_resize_node(s.graph(), common_params, input, _policy, _width_scale, _height_scale);
    }

private:
    InterpolationPolicy _policy;
    float               _width_scale;
    float               _height_scale;
};

/** ROIAlign Layer */
class ROIAlignLayer final : public ILayer
{
public:
    /** Construct a RoiAlign layer.
     *
     * @param[in] sub_stream_input Graph sub-stream for the input
     * @param[in] sub_stream_rois  Graph sub-stream for the rois
     * @param[in] pool_info        Pooling information.
     */
    ROIAlignLayer(SubStream &&sub_stream_input, SubStream &&sub_stream_rois, ROIPoolingLayerInfo pool_info)
        : _ss_input(sub_stream_input), _ss_rois(sub_stream_rois), _pool_info(pool_info)
    {
    }

    /** Prevent instances of this class from being copy constructed */
    ROIAlignLayer(const ROIAlignLayer &) = delete;
    /** Prevent instances of this class from being copied */
    ROIAlignLayer &operator=(const ROIAlignLayer &) = delete;

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { _ss_input.tail_node(), 0 };
        NodeIdxPair rois          = { _ss_rois.tail_node(), 0 };
        return GraphBuilder::add_roi_align_node(s.graph(), common_params, input, rois, _pool_info);
    }

private:
    SubStream           _ss_input;
    SubStream           _ss_rois;
    ROIPoolingLayerInfo _pool_info;
};

/** Scale Layer */
class ScaleLayer final : public ILayer
{
public:
    /** Construct a scale layer.
     *
     * @param[in] mul_w Accessor to get mul weight from.
     * @param[in] add_w Accessor to get add weight from.
     */
    ScaleLayer(ITensorAccessorUPtr mul_w,
               ITensorAccessorUPtr add_w)
        : _mul_w(std::move(mul_w)), _add_w(std::move(add_w))
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_scale_layer(s.graph(), common_params, input, std::move(_mul_w), std::move(_add_w));
    }

private:
    ITensorAccessorUPtr _mul_w;
    ITensorAccessorUPtr _add_w;
};

/** Slice Layer */
class SliceLayer final : public ILayer
{
public:
    /** Construct a slice layer.
     *
     * @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).
     */
    SliceLayer(Coordinates &starts, Coordinates &ends)
        : _starts(starts), _ends(ends)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_slice_node(s.graph(), common_params, input, _starts, _ends);
    }

private:
    Coordinates _starts;
    Coordinates _ends;
};

/** Softmax Layer */
class SoftmaxLayer final : public ILayer
{
public:
    /** Construct a softmax layer.
     *
     * @param[in] beta (Optional) Beta value. Default 1.0.
     */
    SoftmaxLayer(float beta = 1.0f)
        : _beta(beta)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_softmax_node(s.graph(), common_params, input, _beta);
    }

private:
    float _beta;
};

/** Stack Layer */
class StackLayer final : public ILayer
{
public:
    /** Construct a concatenation layer
     *
     * @param[in] sub_stream1      First graph branch
     * @param[in] sub_stream2      Second graph branch
     * @param[in] rest_sub_streams Rest sub-graph branches
     */
    template <typename... Ts>
    StackLayer(SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&... rest_sub_streams)
        : _sub_streams(), _axis(0)
    {
        _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream1)));
        _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream2)));

        utility::for_each([&](SubStream && sub_stream)
        {
            _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream)));
        },
        std::move(rest_sub_streams)...);
    }
    /** Construct a concatenation layer
     *
     * @param[in] axis             Stack layer axis along which to stack the inputs
     * @param[in] sub_stream1      First graph branch
     * @param[in] sub_stream2      Second graph branch
     * @param[in] rest_sub_streams Rest sub-graph branches
     */
    template <typename... Ts>
    StackLayer(int axis, SubStream &&sub_stream1, SubStream &&sub_stream2, Ts &&... rest_sub_streams)
        : _sub_streams(), _axis(axis)
    {
        _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream1)));
        _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream2)));

        utility::for_each([&](SubStream && sub_stream)
        {
            _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream)));
        },
        std::move(rest_sub_streams)...);
    }
    /** Construct a concat layer
     *
     * @param[in] sub_stream Sub-stream
     */
    template <typename... Ts>
    StackLayer(SubStream &&sub_stream)
        : _sub_streams(), _axis(0)
    {
        _sub_streams.push_back(arm_compute::support::cpp14::make_unique<SubStream>(std::move(sub_stream)));
    }
    NodeID create_layer(IStream &s) override
    {
        NodeID     nid           = EmptyNodeID;
        NodeParams common_params = { name(), s.hints().target_hint };
        if(_sub_streams.size() == 1 && _sub_streams.at(0) != nullptr)
        {
            nid = _sub_streams[0]->tail_node();
        }
        else
        {
            // Collect tail nodes and stack
            std::vector<NodeIdxPair> nodes;
            for(auto &ss : _sub_streams)
            {
                if(ss && (ss->tail_node() != EmptyNodeID))
                {
                    const auto tail_node = s.graph().node(ss->tail_node());
                    if(tail_node != nullptr && tail_node->type() != NodeType::Output)
                    {
                        nodes.push_back({ ss->tail_node(), 0 });
                    }
                }
            }
            nid = GraphBuilder::add_stack_node(s.graph(), common_params, nodes, _axis);
        }
        return nid;
    }

private:
    std::vector<std::unique_ptr<SubStream>> _sub_streams;
    int                                     _axis;
};

/** Upsample Layer */
class UpsampleLayer final : public ILayer
{
public:
    /** Construct a Upsample layer.
     *
     * @param[in] info              Stride info
     * @param[in] upsampling_policy Upsampling policy
     */
    UpsampleLayer(Size2D info, InterpolationPolicy upsampling_policy)
        : _info(info), _upsampling_policy(upsampling_policy)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_upsample_node(s.graph(), common_params, input, _info, _upsampling_policy);
    }

private:
    Size2D              _info;
    InterpolationPolicy _upsampling_policy;
};

/** YOLO Layer */
class YOLOLayer final : public ILayer
{
public:
    /** Construct a YOLO layer.
     *
     * @param[in] act_info    Activation info
     * @param[in] num_classes Number of classes to activate
     */
    YOLOLayer(ActivationLayerInfo act_info, int32_t num_classes)
        : _act_info(act_info), _num_classes(num_classes)
    {
    }

    NodeID create_layer(IStream &s) override
    {
        NodeParams  common_params = { name(), s.hints().target_hint };
        NodeIdxPair input         = { s.tail_node(), 0 };
        return GraphBuilder::add_yolo_node(s.graph(), common_params, input, _act_info, _num_classes);
    }

private:
    ActivationLayerInfo _act_info;
    int32_t             _num_classes;
};
} // namespace frontend
} // namespace graph
} // namespace arm_compute
#endif /* ARM_COMPUTE_GRAPH_LAYERS_H */
