/*
 * Copyright (c) 2019 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_BACKENDS_FUSED_DEPTHWISE_CONVOLUTION_BATCH_NORMALIZATION_FUNCTION_H__
#define __ARM_COMPUTE_GRAPH_BACKENDS_FUSED_DEPTHWISE_CONVOLUTION_BATCH_NORMALIZATION_FUNCTION_H__

#include "arm_compute/core/Types.h"
#include "arm_compute/runtime/IFunction.h"

namespace arm_compute
{
namespace graph
{
namespace backends
{
/** Wrapper function to first apply {NE, CL}BatchNormalizationLayer on the weights and then run {NE, CL}DepthwiseConvolutionLayer with the modified weights */
template <typename TargetInfo, typename FusedLayerTypes>
class FusedDepthwiseConvolutionBatchNormalizationFunction : public IFunction
{
public:
    using TensorType         = typename TargetInfo::TensorType;
    using TensorConcreteType = typename TargetInfo::TensorConcreteType;

    FusedDepthwiseConvolutionBatchNormalizationFunction()
        : _depth_conv_layer(), _fused_batch_norm_layer(), _fused_bias(), _is_prepared(false)
    {
    }

    /** Set the input and output tensors.
     *
     * @param[in]  input            Source tensor. 3 lower dimensions represent a single input [width, height, IFM],
     *                              while every optional dimension from 4 and above represent a batch of inputs.
     *                              Data types supported: F16/F32.
     * @param[in]  weights          Weights tensor.  These are 3D tensors with shape [kernel_x, kernel_y, IFM]. Data type supported: Same as @p input.
     * @param[in]  bias             Biases tensor. Shared biases supported. Biases are 1D tensor with dimensions [IFM].
     *                              Data type supported: Should match @p input data type.
     * @param[out] output           Destination tensor. 3 lower dimensions represent a single output [width, height, OFM], while the rest represent batch of outputs.
     *                              Data types supported: Same as @p input.
     * @param[in]  mean             Mean values tensor. 1 dimension with size equal to the feature maps [FM]. Data types supported: Same as @p input
     * @param[in]  var              Variance values tensor. 1 dimension with size equal to the feature maps [FM]. Data types supported: Same as @p input
     * @param[in]  beta             Beta values tensor info. 1 dimension with size equal to the feature maps [FM]. If not provided, default value for beta is 0. Data types supported: Same as @p input
     * @param[in]  gamma            Gamma values tensor info. 1 dimension with size equal to the feature maps [FM]. If not provided, default value for gamma is 1. Data types supported: Same as @p input
     * @param[in]  epsilon          Small value to avoid division with zero. Default value is 0.001f.
     * @param[in]  conv_info        Contains padding and stride information described in @ref PadStrideInfo.
     * @param[in]  depth_multiplier Multiplier to apply to the input's depth in order to retrieve the output's depth. Defaults to 1.
     * @param[in]  fused_act        Activation layer information in case of a fused activation.
     *
     */
    void configure(TensorType       *input,
                   TensorType       *weights,
                   TensorType       *bias,
                   TensorType       *output,
                   const TensorType *mean,
                   const TensorType *var,
                   const TensorType *beta,
                   const TensorType *gamma,
                   float epsilon, const PadStrideInfo &conv_info, unsigned int depth_multiplier, ActivationLayerInfo const &fused_act)
    {
        // We don't run any validate, as we assume that the layers have been already validated
        const bool        has_bias = (bias != nullptr);
        const TensorType *bias_to_use;

        // We check if the layer has a bias. If yes, use it in-place. If not, we need to create one
        // as batch normalization might end up with a bias != 0
        if(has_bias)
        {
            _fused_batch_norm_layer.configure(weights, mean, var, nullptr, nullptr, bias, beta, gamma, epsilon, FuseBatchNormalizationType::DEPTHWISECONVOLUTION);
            bias_to_use = bias;
        }
        else
        {
            _fused_batch_norm_layer.configure(weights, mean, var, nullptr, &_fused_bias, nullptr, beta, gamma, epsilon, FuseBatchNormalizationType::DEPTHWISECONVOLUTION);
            bias_to_use = &_fused_bias;
        }

        _depth_conv_layer.configure(input, weights, bias_to_use, output, conv_info, depth_multiplier, fused_act.enabled() ? fused_act : ActivationLayerInfo());

        if(!has_bias)
        {
            _fused_bias.allocator()->allocate();
        }
    }

    // Inherited methods overridden:
    void run()
    {
        prepare();
        _depth_conv_layer.run();
    }

    void prepare()
    {
        if(!_is_prepared)
        {
            _fused_batch_norm_layer.run();
            _is_prepared = true;
        }
    }

private:
    typename FusedLayerTypes::DepthwiseConvolutionLayer _depth_conv_layer;
    typename FusedLayerTypes::FuseBatchNormalization    _fused_batch_norm_layer;
    TensorConcreteType                                  _fused_bias;
    bool                                                _is_prepared;
};
} // namespace backends
} // namespace graph
} // namespace arm_compute

#endif /* __ARM_COMPUTE_GRAPH_BACKENDS_FUSED_DEPTHWISE_CONVOLUTION_BATCH_NORMALIZATION_FUNCTION_H__ */
