/*
 * Copyright (c) 2019-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.
 */

#include "arm_compute/runtime/NEON/functions/assembly/NEDepthwiseConvolutionAssemblyDispatch.h"

#include "arm_compute/core/ITensor.h"
#include "arm_compute/core/Utils.h"
#include "arm_compute/core/utils/misc/InfoHelpers.h"
#include "arm_compute/core/utils/misc/ShapeCalculator.h"
#include "arm_compute/core/utils/quantization/AsymmHelpers.h"
#include "src/core/CPP/Validate.h"
#include "src/core/NEON/kernels/assembly/NEDepthwiseConvolutionAssemblyKernelWrapper.h"
#include "src/core/NEON/kernels/convolution/depthwise/depthwise_dilated.hpp"
#include "src/core/NEON/kernels/convolution/depthwise/depthwise_quantized_dilated.hpp"
#include "src/core/helpers/AutoConfiguration.h"

#include "arm_compute/runtime/NEON/NEScheduler.h"

#include "support/MemorySupport.h"

#include <set>

namespace arm_compute
{
namespace
{
std::unique_ptr<depthwise::IDepthwiseConvolution> get_qasymm8_convolver(int kernel_size, int stride_x,
                                                                        int n_batches, int in_rows, int in_cols, int n_channels,
                                                                        int dilation_factor, neon_convolution_kernels::ActivationFunction activation,
                                                                        const qasymm8::QAsymm8Params &wqinfo, const qasymm8::QAsymm8Params &iqinfo, const qasymm8::QAsymm8Params &oqinfo,
                                                                        const qasymm8::QAsymm8RescaleParams &rescale_params,
                                                                        int padding_top, int padding_left, int padding_bottom, int padding_right)
{
    switch(kernel_size)
    {
        case 3:
        {
            switch(stride_x)
            {
                case 1:
                    return arm_compute::support::cpp14::make_unique<depthwise::QAsymm8DilatedDepthwiseConvolution<2, 2, 3, 3, 1, 1>>(
                               n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, wqinfo, iqinfo, oqinfo, rescale_params, padding_top, padding_left, padding_bottom, padding_right);
                case 2:
                    return arm_compute::support::cpp14::make_unique<depthwise::QAsymm8DilatedDepthwiseConvolution<2, 2, 3, 3, 2, 2>>(
                               n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, wqinfo, iqinfo, oqinfo, rescale_params, padding_top, padding_left, padding_bottom, padding_right);
                default:
                    return nullptr;
            }
        }
        case 5:
        {
            switch(stride_x)
            {
                case 1:
                    return arm_compute::support::cpp14::make_unique<depthwise::QAsymm8DilatedDepthwiseConvolution<2, 2, 5, 5, 1, 1>>(
                               n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, wqinfo, iqinfo, oqinfo, rescale_params, padding_top, padding_left, padding_bottom, padding_right);
                case 2:
                    return arm_compute::support::cpp14::make_unique<depthwise::QAsymm8DilatedDepthwiseConvolution<2, 2, 5, 5, 2, 2>>(
                               n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, wqinfo, iqinfo, oqinfo, rescale_params, padding_top, padding_left, padding_bottom, padding_right);
                default:
                    return nullptr;
            }
        }
        default:
            return nullptr;
    }
}

std::unique_ptr<depthwise::IDepthwiseConvolution> get_qsymm8_perchannel_convolver(int kernel_size, int stride_x,
                                                                                  int n_batches, int in_rows, int in_cols, int n_channels,
                                                                                  neon_convolution_kernels::ActivationFunction activation,
                                                                                  const qsymm8::QSymm8PerChannelParams &wqinfo, const qasymm8::QAsymm8Params &iqinfo, const qasymm8::QAsymm8Params &oqinfo,
                                                                                  const qsymm8::QSymm8PerChannelRescaleParams &rescale_params,
                                                                                  int padding_top, int padding_left, int padding_bottom, int padding_right)
{
    switch(kernel_size)
    {
        case 3:
        {
            switch(stride_x)
            {
                case 1:
                    return arm_compute::support::cpp14::make_unique<depthwise::QSymm8HybridPerChannelDepthwiseConvolution<2, 2, 3, 3, 1, 1>>(
                               n_batches, in_rows, in_cols, n_channels, activation, wqinfo, iqinfo, oqinfo, rescale_params, padding_top, padding_left, padding_bottom, padding_right);
                case 2:
                    return arm_compute::support::cpp14::make_unique<depthwise::QSymm8HybridPerChannelDepthwiseConvolution<2, 2, 3, 3, 2, 2>>(
                               n_batches, in_rows, in_cols, n_channels, activation, wqinfo, iqinfo, oqinfo, rescale_params, padding_top, padding_left, padding_bottom, padding_right);
                default:
                    return nullptr;
            }
        }
        case 5:
        {
            switch(stride_x)
            {
                case 1:
                    return arm_compute::support::cpp14::make_unique<depthwise::QSymm8HybridPerChannelDepthwiseConvolution<2, 2, 5, 5, 1, 1>>(
                               n_batches, in_rows, in_cols, n_channels, activation, wqinfo, iqinfo, oqinfo, rescale_params, padding_top, padding_left, padding_bottom, padding_right);
                case 2:
                    return arm_compute::support::cpp14::make_unique<depthwise::QSymm8HybridPerChannelDepthwiseConvolution<2, 2, 5, 5, 2, 2>>(
                               n_batches, in_rows, in_cols, n_channels, activation, wqinfo, iqinfo, oqinfo, rescale_params, padding_top, padding_left, padding_bottom, padding_right);
                default:
                    return nullptr;
            }
        }
        default:
            return nullptr;
    }
}

#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
std::unique_ptr<depthwise::IDepthwiseConvolution> get_fp16_convolver(int kernel_size, int stride_x,
                                                                     int n_batches, int in_rows, int in_cols, int n_channels,
                                                                     int dilation_factor, neon_convolution_kernels::ActivationFunction activation,
                                                                     int padding_top, int padding_left, int padding_bottom, int padding_right)
{
    switch(kernel_size)
    {
        case 3:
        {
            switch(stride_x)
            {
                case 1:
                    return arm_compute::support::cpp14::make_unique<depthwise::DilatedDepthwiseConvolution<3, 3, 3, 3, 1, 1, float16_t, float16_t, float16_t>>(
                               n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, padding_top, padding_left, padding_bottom, padding_right);
                case 2:
                    return arm_compute::support::cpp14::make_unique<depthwise::DilatedDepthwiseConvolution<3, 3, 3, 3, 2, 2, float16_t, float16_t, float16_t>>(
                               n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, padding_top, padding_left, padding_bottom, padding_right);
                default:
                    return nullptr;
            }
        }
        case 5:
        {
            switch(stride_x)
            {
                case 1:
                    return arm_compute::support::cpp14::make_unique<depthwise::DilatedDepthwiseConvolution<3, 3, 5, 5, 1, 1, float16_t, float16_t, float16_t>>(
                               n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, padding_top, padding_left, padding_bottom, padding_right);
                case 2:
                    return arm_compute::support::cpp14::make_unique<depthwise::DilatedDepthwiseConvolution<3, 3, 5, 5, 2, 2, float16_t, float16_t, float16_t>>(
                               n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, padding_top, padding_left, padding_bottom, padding_right);
                default:
                    return nullptr;
            }
        }
        default:
            return nullptr;
    }
}
#endif // __ARM_FEATURE_FP16_VECTOR_ARITHMETIC

std::unique_ptr<depthwise::IDepthwiseConvolution> get_fp32_convolver(int kernel_size, int stride_x,
                                                                     int n_batches, int in_rows, int in_cols, int n_channels,
                                                                     int dilation_factor, neon_convolution_kernels::ActivationFunction activation,
                                                                     int padding_top, int padding_left, int padding_bottom, int padding_right)
{
    switch(kernel_size)
    {
        case 3:
        {
            switch(stride_x)
            {
                case 1:
                    return arm_compute::support::cpp14::make_unique<depthwise::DilatedDepthwiseConvolution<4, 4, 3, 3, 1, 1, float, float, float>>(
                               n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, padding_top, padding_left, padding_bottom, padding_right);
                case 2:
                    return arm_compute::support::cpp14::make_unique<depthwise::DilatedDepthwiseConvolution<3, 3, 3, 3, 2, 2, float, float, float>>(
                               n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, padding_top, padding_left, padding_bottom, padding_right);
                default:
                    return nullptr;
            }
        }
        case 5:
        {
            switch(stride_x)
            {
                case 1:
                    return arm_compute::support::cpp14::make_unique<depthwise::DilatedDepthwiseConvolution<4, 4, 5, 5, 1, 1, float, float, float>>(
                               n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, padding_top, padding_left, padding_bottom, padding_right);
                case 2:
                    return arm_compute::support::cpp14::make_unique<depthwise::DilatedDepthwiseConvolution<3, 3, 5, 5, 2, 2, float, float, float>>(
                               n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, padding_top, padding_left, padding_bottom, padding_right);
                default:
                    return nullptr;
            }
        }
        default:
            return nullptr;
    }
}

std::unique_ptr<depthwise::IDepthwiseConvolution> create_convolver(const ITensor      *input,
                                                                   const ITensor      *weights,
                                                                   ITensor            *output,
                                                                   PadStrideInfo       conv_info,
                                                                   ActivationLayerInfo act_info,
                                                                   const Size2D       &dilation)
{
    ARM_COMPUTE_UNUSED(dilation);
    const DataType    data_type = input->info()->data_type();
    const TensorShape shape     = input->info()->tensor_shape();

    const int n_batches       = shape[3];
    const int in_rows         = shape.z();
    const int in_cols         = shape.y();
    const int n_channels      = shape.x();
    const int dilation_factor = dilation.x();
    const int padding_top     = conv_info.pad_top();
    const int padding_left    = conv_info.pad_left();
    const int padding_bottom  = conv_info.pad_bottom();
    const int padding_right   = conv_info.pad_right();

    const bool is_uniform_quantized    = (data_type == DataType::QASYMM8) && (weights->info()->data_type() == DataType::QASYMM8);
    const bool is_perchannel_quantized = (data_type == DataType::QASYMM8) && (weights->info()->data_type() == DataType::QSYMM8_PER_CHANNEL);

    const unsigned int stride_x    = conv_info.stride().first;
    const unsigned int kernel_size = weights->info()->tensor_shape().y();

    // Map activation function
    neon_convolution_kernels::ActivationFunction activation = neon_convolution_kernels::ActivationFunction::None;
    if(arm_compute::utils::info_helpers::is_relu(act_info))
    {
        activation = neon_convolution_kernels::ActivationFunction::ReLU;
    }
    else if(arm_compute::utils::info_helpers::is_relu6(act_info))
    {
        activation = neon_convolution_kernels::ActivationFunction::ReLU6;
    }

    // Create quantized convolver
    if(is_uniform_quantized)
    {
        const UniformQuantizationInfo input_qinfo   = input->info()->quantization_info().uniform();
        const UniformQuantizationInfo weights_qinfo = weights->info()->quantization_info().uniform();
        const UniformQuantizationInfo output_qinfo  = output->info()->quantization_info().uniform();

        // Check that quantization info are in the range [0, 255]
        ARM_COMPUTE_ERROR_ON(input_qinfo.offset < 0 || input_qinfo.offset > 255);
        ARM_COMPUTE_ERROR_ON(weights_qinfo.offset < 0 || weights_qinfo.offset > 255);
        ARM_COMPUTE_ERROR_ON(output_qinfo.offset < 0 || output_qinfo.offset > 255);
        const qasymm8::QAsymm8Params iqinfo{ static_cast<uint8_t>(input_qinfo.offset), input_qinfo.scale };
        const qasymm8::QAsymm8Params wqinfo{ static_cast<uint8_t>(weights_qinfo.offset), weights_qinfo.scale };
        const qasymm8::QAsymm8Params oqinfo{ static_cast<uint8_t>(output_qinfo.offset), output_qinfo.scale };

        // Calculate rescale parameters
        const float fmultipler  = iqinfo.scale * wqinfo.scale / oqinfo.scale;
        int32_t     qmultiplier = 0;
        int32_t     qshift      = 0;
        quantization::calculate_quantized_multiplier_less_than_one(fmultipler, &qmultiplier, &qshift);
        qasymm8::QAsymm8RescaleParams rescale_params(qshift, qmultiplier, fmultipler);

        return get_qasymm8_convolver(kernel_size, stride_x, n_batches, in_rows, in_cols, n_channels, dilation_factor, activation,
                                     wqinfo, iqinfo, oqinfo, rescale_params, padding_top, padding_left, padding_bottom, padding_right);
    }
    else if(is_perchannel_quantized)
    {
        const UniformQuantizationInfo input_qinfo   = input->info()->quantization_info().uniform();
        const QuantizationInfo        weights_qinfo = weights->info()->quantization_info();
        const UniformQuantizationInfo output_qinfo  = output->info()->quantization_info().uniform();

        // Check that quantization info are in the range [0, 255]
        ARM_COMPUTE_ERROR_ON(input_qinfo.offset < 0 || input_qinfo.offset > 255);
        ARM_COMPUTE_ERROR_ON(output_qinfo.offset < 0 || output_qinfo.offset > 255);
        const qasymm8::QAsymm8Params         iqinfo{ static_cast<uint8_t>(input_qinfo.offset), input_qinfo.scale };
        const qsymm8::QSymm8PerChannelParams wqinfo{ weights_qinfo.scale() };
        const qasymm8::QAsymm8Params         oqinfo{ static_cast<uint8_t>(output_qinfo.offset), output_qinfo.scale };

        // Calculate rescale parameters
        std::vector<float>   fmultipliers;
        std::vector<int32_t> qmultipliers;
        std::vector<int32_t> qshifts;

        for(auto const s : wqinfo.scales)
        {
            const float fmultipler  = iqinfo.scale * s / oqinfo.scale;
            int32_t     qmultiplier = 0;
            int32_t     qshift      = 0;
            quantization::calculate_quantized_multiplier_less_than_one(fmultipler, &qmultiplier, &qshift);
            fmultipliers.push_back(fmultipler);
            qmultipliers.push_back(qmultiplier);
            qshifts.push_back(qshift);
        }

        qsymm8::QSymm8PerChannelRescaleParams rescale_params(qshifts, qmultipliers, fmultipliers);

        return get_qsymm8_perchannel_convolver(kernel_size, stride_x, n_batches, in_rows, in_cols, n_channels, activation,
                                               wqinfo, iqinfo, oqinfo, rescale_params, padding_top, padding_left, padding_bottom, padding_right);
    }
    else
    {
        // Create float convolver
        switch(data_type)
        {
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
            case DataType::F16:
            {
                return get_fp16_convolver(kernel_size, stride_x, n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, padding_top, padding_left, padding_bottom, padding_right);
            }
#endif // __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
            case DataType::F32:
            {
                return get_fp32_convolver(kernel_size, stride_x, n_batches, in_rows, in_cols, n_channels, dilation_factor, activation, padding_top, padding_left, padding_bottom, padding_right);
            }
            default:
                return nullptr;
        }
    }
}
} // namespace

struct NEDepthwiseConvolutionAssemblyDispatch::LocalImpl
{
    std::unique_ptr<depthwise::IDepthwiseConvolution> _dwc_assembly_kernel{ nullptr };
    NEDepthwiseConvolutionAssemblyKernelWrapper       _dwc_acl_kernel{};
};

#ifndef DOXYGEN_SKIP_THIS
NEDepthwiseConvolutionAssemblyDispatch::NEDepthwiseConvolutionAssemblyDispatch(std::shared_ptr<arm_compute::IMemoryManager> memory_manager)
    : _memory_group(std::move(memory_manager)), _input(nullptr), _weights(nullptr), _bias(nullptr), _output(nullptr), _packed_weights(), _workspace(), _is_prepared(false),
      _pImpl(support::cpp14::make_unique<LocalImpl>())
{
}
#endif /* DOXYGEN_SKIP_THIS */

NEDepthwiseConvolutionAssemblyDispatch::~NEDepthwiseConvolutionAssemblyDispatch() = default;

void NEDepthwiseConvolutionAssemblyDispatch::configure(const ITensor             *input,
                                                       const ITensor             *weights,
                                                       const ITensor             *bias,
                                                       ITensor                   *output,
                                                       const PadStrideInfo       &conv_info,
                                                       unsigned int               depth_multiplier,
                                                       const ActivationLayerInfo &act_info,
                                                       const Size2D              &dilation)
{
    ARM_COMPUTE_ERROR_ON_NULLPTR(input, weights, output);
    ARM_COMPUTE_UNUSED(depth_multiplier);
    ARM_COMPUTE_ERROR_THROW_ON(NEDepthwiseConvolutionAssemblyDispatch::validate(input->info(),
                                                                                weights->info(),
                                                                                bias != nullptr ? bias->info() : nullptr,
                                                                                output->info(),
                                                                                conv_info,
                                                                                depth_multiplier,
                                                                                act_info,
                                                                                dilation));

    // Output auto inizialitation if not yet initialized
    const TensorShape output_shape = misc::shape_calculator::compute_depthwise_convolution_shape(*input->info(), *weights->info(), conv_info, depth_multiplier, dilation);
    auto_init_if_empty(*output->info(), input->info()->clone()->set_is_resizable(true).reset_padding().set_tensor_shape(output_shape).set_quantization_info(output->info()->quantization_info()));

    _input       = input;
    _weights     = weights;
    _bias        = bias;
    _output      = output;
    _is_prepared = false;

    // Create convolver
    _pImpl->_dwc_assembly_kernel = create_convolver(input, weights, output, conv_info, act_info, dilation);
    ARM_COMPUTE_ERROR_ON(_pImpl->_dwc_assembly_kernel == nullptr);

    // Create assembly kernel wrapper
    _pImpl->_dwc_acl_kernel.configure(_pImpl->_dwc_assembly_kernel.get());

    constexpr size_t alignment = 128;

    // Create workspace
    const unsigned int num_threads    = NEScheduler::get().num_threads();
    const size_t       workspace_size = _pImpl->_dwc_assembly_kernel->get_working_space_size(num_threads);
    ARM_COMPUTE_ERROR_ON_MSG(workspace_size == 0, "Workspace size cannot be 0 !");
    _workspace.allocator()->init(TensorInfo(TensorShape{ workspace_size }, 1, DataType::S8), alignment);
    _memory_group.manage(&_workspace);
    _workspace.allocator()->allocate();

    // Create packing tensor
    const size_t pack_tensor_size = _pImpl->_dwc_assembly_kernel->get_packed_params_size();
    ARM_COMPUTE_ERROR_ON_MSG(pack_tensor_size == 0, "Pack tensor size cannot be 0 !");
    _packed_weights.allocator()->init(TensorInfo(TensorShape{ pack_tensor_size }, 1, DataType::S8), alignment);
}

Status NEDepthwiseConvolutionAssemblyDispatch::validate(const ITensorInfo         *input,
                                                        const ITensorInfo         *weights,
                                                        const ITensorInfo         *bias,
                                                        const ITensorInfo         *output,
                                                        const PadStrideInfo       &conv_info,
                                                        unsigned int               depth_multiplier,
                                                        const ActivationLayerInfo &act_info,
                                                        const Size2D              &dilation)
{
    ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(input);
    ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::QASYMM8, DataType::F16, DataType::F32);
    if(weights->data_type() != DataType::QSYMM8_PER_CHANNEL)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, weights);
    }
    ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(input, weights);

    // Validate convolver
    ARM_COMPUTE_RETURN_ERROR_ON(!is_optimized_supported(input, weights, conv_info, depth_multiplier, dilation));

    // Validate activation
    const bool is_relu  = arm_compute::utils::info_helpers::is_relu(act_info);
    const bool is_relu6 = arm_compute::utils::info_helpers::is_relu6(act_info);
    ARM_COMPUTE_RETURN_ERROR_ON(act_info.enabled() && !(is_relu || is_relu6));

    // Check bias
    if(bias != nullptr)
    {
        unsigned int channel_idx = get_data_layout_dimension_index(input->data_layout(), DataLayoutDimension::CHANNEL);
        ARM_COMPUTE_RETURN_ERROR_ON(bias->num_dimensions() > 1);
        ARM_COMPUTE_RETURN_ERROR_ON(bias->dimension(0) != weights->dimension(channel_idx));
    }

    // Check output
    if(output->total_size() != 0)
    {
        const TensorShape output_shape = misc::shape_calculator::compute_depthwise_convolution_shape(*input, *weights, conv_info, depth_multiplier, dilation);
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(output->tensor_shape(), output_shape);
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, output);
    }

    // The uniform quantization case will only have 1 scale value in the weights quantization info
    const UniformQuantizationInfo input_qinfo   = input->quantization_info().uniform();
    const QuantizationInfo        weights_qinfo = weights->quantization_info();
    const UniformQuantizationInfo output_qinfo  = output->quantization_info().uniform();
    for(auto const s : weights_qinfo.scale())
    {
        const float fmultipler = input_qinfo.scale * s / output_qinfo.scale;
        ARM_COMPUTE_RETURN_ERROR_ON(fmultipler > 1.f);
    }

    return Status{};
}

bool NEDepthwiseConvolutionAssemblyDispatch::is_optimized_supported(const ITensorInfo *input,
                                                                    const ITensorInfo *weights,
                                                                    PadStrideInfo      conv_info,
                                                                    unsigned int       depth_multiplier,
                                                                    const Size2D      &dilation)
{
    ARM_COMPUTE_ERROR_ON_NULLPTR(input, weights);

    // Reshape input shape if in NHWC format
    const DataLayout data_layout = input->data_layout();
    TensorShape      in_shape{ input->tensor_shape() };
    if(data_layout == DataLayout::NHWC)
    {
        in_shape.set(Window::DimX, input->tensor_shape().y());
        in_shape.set(Window::DimY, input->tensor_shape().z());
        in_shape.set(Window::DimZ, input->tensor_shape().x());
    }

    // Check data type
    // TODO (COMPMID-3004): Add assembly optimized routine for QASYMM8_SIGNED NEDepthwiseConvolutionLayer
    const DataType input_type            = input->data_type();
    const bool     is_input_type_valid   = is_data_type_float(input_type) || input_type == DataType::QASYMM8;
    const DataType weights_type          = weights->data_type();
    const bool     is_weights_type_valid = is_data_type_float(weights_type) || weights_type == DataType::QASYMM8 || weights_type == DataType::QASYMM8_SIGNED
                                           || weights_type == DataType::QSYMM8_PER_CHANNEL;

    // Check weighs size
    std::set<unsigned int> supported_kernel_sizes = { 3, 5 };
    const unsigned int     width_idx              = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
    const unsigned int     height_idx             = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);
    const unsigned int     kernel_w               = weights->dimension(width_idx);
    const unsigned int     kernel_h               = weights->dimension(height_idx);
    bool                   weights_supported      = (kernel_w == kernel_h) && (supported_kernel_sizes.count(kernel_w) != 0);

    // Check for supported strides
    const auto &strides           = conv_info.stride();
    bool        supported_strides = (strides.first == strides.second) && ((strides.first == 1) || (strides.first == 2));

    // Check for supported padding
    const auto    pad_top           = conv_info.pad_top();
    const auto    pad_right         = conv_info.pad_right();
    const auto    pad_bottom        = conv_info.pad_bottom();
    const auto    pad_left          = conv_info.pad_left();
    PadStrideInfo same_pad          = calculate_same_pad(in_shape, TensorShape(kernel_w, kernel_h), conv_info, DataLayout::NCHW, dilation);
    bool          is_same_padding   = (pad_top == same_pad.pad_top()) && (pad_right == same_pad.pad_right()) && (pad_bottom == same_pad.pad_bottom()) && (pad_left == same_pad.pad_left());
    bool          is_valid_padding  = (pad_top == 0) && (pad_right == 0) && (pad_bottom == 0) && (pad_left == 0);
    bool          supported_padding = is_same_padding || is_valid_padding;
    // TODO(COMPMID-2464): Enable once dilated conv with stride 2 is supported
    bool is_dilation_supported = ((dilation == Size2D(1U, 1U)) || ((dilation.x() == dilation.y()) && strides.first == 1));

    if(weights_type == DataType::QSYMM8_PER_CHANNEL)
    {
        is_dilation_supported = is_dilation_supported && (dilation == Size2D(1U, 1U));
    }

    return is_input_type_valid && is_weights_type_valid && weights_supported && supported_strides && supported_padding && (depth_multiplier == 1) && is_dilation_supported;
}

void NEDepthwiseConvolutionAssemblyDispatch::run()
{
    // Prepare assembly kernel
    prepare();

    MemoryGroupResourceScope scope_mg(_memory_group);

    // Setup inputs/outputs
    ARM_COMPUTE_ERROR_ON(_workspace.buffer() == nullptr);
    _pImpl->_dwc_assembly_kernel->set_working_space(static_cast<void *>(_workspace.buffer()));

    ARM_COMPUTE_ERROR_ON(_input->buffer() == nullptr);
    const int   input_element_size = _input->info()->element_size();
    const int   input_batch_stride = _input->info()->strides_in_bytes()[3] / input_element_size;
    const int   input_row_stride   = _input->info()->strides_in_bytes().z() / input_element_size;
    const int   input_col_stride   = _input->info()->strides_in_bytes().y() / input_element_size;
    const void *input_ptr          = _input->buffer() + _input->info()->offset_first_element_in_bytes();
    _pImpl->_dwc_assembly_kernel->set_input(input_ptr, input_batch_stride, input_row_stride, input_col_stride);

    ARM_COMPUTE_ERROR_ON(_output->buffer() == nullptr);
    const int output_element_size = _output->info()->element_size();
    const int output_batch_stride = _output->info()->strides_in_bytes()[3] / output_element_size;
    const int output_row_stride   = _output->info()->strides_in_bytes().z() / output_element_size;
    const int output_col_stride   = _output->info()->strides_in_bytes().y() / output_element_size;
    void     *output_ptr          = _output->buffer() + _output->info()->offset_first_element_in_bytes();
    _pImpl->_dwc_assembly_kernel->set_output(output_ptr, output_batch_stride, output_row_stride, output_col_stride);

    // Schedule assembly kernel
    NEScheduler::get().schedule(&_pImpl->_dwc_acl_kernel, Window::DimX);
}

void NEDepthwiseConvolutionAssemblyDispatch::prepare()
{
    if(!_is_prepared)
    {
        _packed_weights.allocator()->allocate();
        ARM_COMPUTE_ERROR_ON(_packed_weights.buffer() == nullptr);

        // Pack weights and bias
        const int weights_element_size = _weights->info()->element_size();
        const int weights_row_stride   = _weights->info()->strides_in_bytes().z() / weights_element_size;
        const int weights_col_stride   = _weights->info()->strides_in_bytes().y() / weights_element_size;
        _pImpl->_dwc_assembly_kernel->pack_params(_packed_weights.buffer(),
                                                  _weights->buffer() + _weights->info()->offset_first_element_in_bytes(),
                                                  weights_row_stride,
                                                  weights_col_stride,
                                                  (_bias != nullptr) ? _bias->buffer() : nullptr);
        _pImpl->_dwc_assembly_kernel->set_packed_params_buffer(_packed_weights.buffer());

        _weights->mark_as_unused();
        if(_bias != nullptr)
        {
            _bias->mark_as_unused();
        }
        _is_prepared = true;
    }
}
} // namespace arm_compute
