/*
 * Copyright (c) 2017-2021 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_TEST_DEPTHWISE_CONVOLUTION_FIXTURE
#define ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_FIXTURE

#include "arm_compute/core/TensorShape.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/core/utils/misc/ShapeCalculator.h"
#include "tests/AssetsLibrary.h"
#include "tests/Globals.h"
#include "tests/IAccessor.h"
#include "tests/framework/Asserts.h"
#include "tests/framework/Fixture.h"
#include "tests/validation/Helpers.h"
#include "tests/validation/reference/ActivationLayer.h"
#include "tests/validation/reference/DepthwiseConvolutionLayer.h"

#include "utils/Utils.h"

#include <random>

namespace arm_compute
{
namespace test
{
namespace validation
{
using namespace arm_compute::misc::shape_calculator;

template <typename TensorType, typename AccessorType, typename FunctionType, typename T, typename TW>
class DepthwiseConvolutionLayerValidationGenericFixture : public framework::Fixture
{
public:
    using TBias = typename std::conditional < std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value, int32_t, T >::type;

public:
    template <typename...>
    void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, Size2D dilation,
               unsigned int depth_multiplier, DataType input_data_type, DataType weights_data_type,
               QuantizationInfo input_quantization_info, QuantizationInfo weights_quantization_info, QuantizationInfo output_quantization_info,
               DataLayout data_layout, ActivationLayerInfo act_info, bool mixed_layout = false, bool in_place = false)
    {
        ARM_COMPUTE_ERROR_ON(mixed_layout && in_place);
        _mixed_layout              = mixed_layout;
        _input_shape               = in_shape;
        _input_data_type           = input_data_type;
        _weights_data_type         = weights_data_type;
        _input_quantization_info   = input_quantization_info;
        _weights_quantization_info = weights_quantization_info;
        _output_quantization_info  = output_quantization_info;
        _data_layout               = data_layout;
        _pad_stride_info           = pad_stride_info;
        _act_info                  = act_info;
        _depth_multiplier          = depth_multiplier;
        _dilation                  = dilation;
        _in_place                  = in_place;

        _bias_data_type = is_data_type_quantized(_input_data_type) ? DataType::S32 : _input_data_type;

        _weights_shape = TensorShape(kernel_size.width, kernel_size.height);

        const TensorInfo      in_info(_input_shape, 1, _input_data_type);
        const TensorInfo      we_info(_weights_shape, 1, _weights_data_type);
        const ConvolutionInfo info{ _pad_stride_info, _depth_multiplier, _act_info, _dilation };
        _output_shape = compute_depthwise_convolution_shape(in_info, we_info, info);

        _weights_shape.set(2, _output_shape.z());
        _biases_shape = TensorShape(_weights_shape[2]);
    }

    void configure_target()
    {
        TensorShape input_shape   = _input_shape;
        TensorShape weights_shape = _weights_shape;
        TensorShape output_shape  = _output_shape;

        if(_data_layout == DataLayout::NHWC)
        {
            permute(input_shape, PermutationVector(2U, 0U, 1U));
            permute(weights_shape, PermutationVector(2U, 0U, 1U));
            permute(output_shape, PermutationVector(2U, 0U, 1U));
        }

        // Create tensors
        _src                      = create_tensor<TensorType>(input_shape, _input_data_type, 1, _input_quantization_info, _data_layout);
        _weights                  = create_tensor<TensorType>(weights_shape, _weights_data_type, 1, _weights_quantization_info, _data_layout);
        _biases                   = create_tensor<TensorType>(_biases_shape, _bias_data_type, 1, _input_quantization_info, _data_layout);
        TensorType *target_to_use = nullptr;
        if(!_in_place)
        {
            _target       = create_tensor<TensorType>(output_shape, _input_data_type, 1, _output_quantization_info, _data_layout);
            target_to_use = &_target;
        }

        add_padding_x({ &_src, &_biases }, _data_layout);
        add_padding_x({ &_weights }, _data_layout, true);
        if(!_in_place)
        {
            add_padding_x({ &_target }, _data_layout);
        }

        // Create Depthwise Convolution configure function
        _dwc.configure(&_src, &_weights, &_biases, target_to_use, _pad_stride_info, _depth_multiplier, _act_info, _dilation);

        ARM_COMPUTE_ASSERT(_src.info()->is_resizable());
        ARM_COMPUTE_ASSERT(_weights.info()->is_resizable());
        ARM_COMPUTE_ASSERT(_biases.info()->is_resizable());
        ARM_COMPUTE_ASSERT(_target.info()->is_resizable());
    }

    void allocate_and_run_target()
    {
        // Allocate tensors
        _src.allocator()->allocate();
        _weights.allocator()->allocate();
        _biases.allocator()->allocate();

        ARM_COMPUTE_ASSERT(!_src.info()->is_resizable());
        ARM_COMPUTE_ASSERT(!_weights.info()->is_resizable());
        ARM_COMPUTE_ASSERT(!_biases.info()->is_resizable());

        if(!_in_place)
        {
            _target.allocator()->allocate();
            ARM_COMPUTE_ASSERT(!_target.info()->is_resizable());
        }

        // Fill tensors
        fill(AccessorType(_src), 0);
        fill(AccessorType(_weights), 1);
        fill(AccessorType(_biases), 2);

        if(_mixed_layout)
        {
            mix_layout(_dwc, _src, _target);
        }
        else
        {
            // Compute function
            _dwc.run();
        }
    }

    void compute_reference()
    {
        SimpleTensor<T>     src{ _input_shape, _input_data_type, 1, _input_quantization_info };
        SimpleTensor<TW>    weights{ _weights_shape, _weights_data_type, 1, _weights_quantization_info };
        SimpleTensor<TBias> biases{ _biases_shape, _bias_data_type, 1, _input_quantization_info };

        fill(src, 0);
        fill(weights, 1);
        fill(biases, 2);

        SimpleTensor<T> depth_out = reference::depthwise_convolution(src, weights, biases, _output_shape, _pad_stride_info, _depth_multiplier, _dilation, _output_quantization_info);
        _reference                = (_act_info.enabled()) ? reference::activation_layer<T>(depth_out, _act_info) : depth_out;
    }

protected:
    void mix_layout(FunctionType &layer, TensorType &src, TensorType &dst)
    {
        ARM_COMPUTE_ERROR_ON(_in_place);
        // Test Multi DataLayout graph cases, when the data layout changes after configure
        src.info()->set_data_layout(_data_layout == DataLayout::NCHW ? DataLayout::NHWC : DataLayout::NCHW);
        dst.info()->set_data_layout(_data_layout == DataLayout::NCHW ? DataLayout::NHWC : DataLayout::NCHW);

        // Compute Convolution function
        layer.run();

        // Reinstating original data layout for the test suite to properly check the values
        src.info()->set_data_layout(_data_layout);
        dst.info()->set_data_layout(_data_layout);
    }

    template <typename U>
    void fill(U &&tensor, int i)
    {
        switch(tensor.data_type())
        {
            case DataType::QASYMM8:
            {
                std::uniform_int_distribution<uint8_t> distribution(0, 15);
                library->fill(tensor, distribution, i);
                break;
            }
            case DataType::QASYMM8_SIGNED:
            case DataType::QSYMM8_PER_CHANNEL:
            {
                std::uniform_int_distribution<int8_t> distribution(-10, 10);
                library->fill(tensor, distribution, i);
                break;
            }
            case DataType::F16:
            {
                arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
                library->fill(tensor, distribution, i);
                break;
            }
            case DataType::F32:
            {
                std::uniform_real_distribution<float> distribution(-1.0f, 1.0f);
                library->fill(tensor, distribution, i);
                break;
            }
            case DataType::S32:
            {
                std::uniform_int_distribution<int32_t> distribution(-100, 100);
                library->fill(tensor, distribution, i);
                break;
            }
            default:
                library->fill_tensor_uniform(tensor, i);
        }
    }

    TensorType      _target{};
    SimpleTensor<T> _reference{};

    TensorType   _src{};
    TensorType   _weights{};
    TensorType   _biases{};
    FunctionType _dwc{};

    TensorShape         _input_shape{};
    TensorShape         _weights_shape{};
    TensorShape         _biases_shape{};
    TensorShape         _output_shape{};
    DataType            _input_data_type{};
    DataType            _weights_data_type{};
    DataType            _bias_data_type{};
    QuantizationInfo    _input_quantization_info{};
    QuantizationInfo    _weights_quantization_info{};
    QuantizationInfo    _output_quantization_info{};
    DataLayout          _data_layout{};
    PadStrideInfo       _pad_stride_info{};
    ActivationLayerInfo _act_info{};
    unsigned int        _depth_multiplier{};
    Size2D              _dilation{};
    bool                _mixed_layout{ false };
    bool                _in_place{ false };
};

template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool mixed_layout = false, bool in_place = false>
class DepthwiseConvolutionLayerValidationFixture : public DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, T>
{
public:
    template <typename...>
    void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, Size2D dilation, unsigned int depth_multiplier, DataType data_type, DataLayout data_layout,
               ActivationLayerInfo act_info)
    {
        DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, T>::setup(in_shape, kernel_size, pad_stride_info, dilation, depth_multiplier,
                                                                                                               data_type, data_type, QuantizationInfo(), QuantizationInfo(), QuantizationInfo(),
                                                                                                               data_layout, act_info, mixed_layout, in_place);
    }
};

template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
class DepthwiseConvolutionLayerNativeValidationFixture : public DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, T>
{
public:
    template <typename...>
    void setup(size_t width, size_t height, size_t channel, size_t batch, Size2D kernel_size, size_t depth_multiplier, Size2D dilation, Size2D stride, bool padding_valid, DataType data_type,
               DataLayout data_layout)
    {
        _dilation         = dilation;
        _depth_multiplier = depth_multiplier;
        _data_type        = data_type;
        _data_layout      = data_layout;

        _input_shape   = TensorShape(width, height, channel, batch);
        _weights_shape = TensorShape(kernel_size.width, kernel_size.height, channel * _depth_multiplier);
        _biases_shape  = TensorShape(_weights_shape.z());

        if(padding_valid)
        {
            _conv_info = PadStrideInfo(stride.width, stride.height);
        }
        else
        {
            _conv_info = calculate_same_pad(_input_shape, _weights_shape, PadStrideInfo(stride.width, stride.height), DataLayout::NCHW, _dilation);
        }
    }

    void configure_target()
    {
        TensorShape input_shape   = _input_shape;
        TensorShape weights_shape = _weights_shape;

        if(_data_layout == DataLayout::NHWC)
        {
            permute(input_shape, PermutationVector(2U, 0U, 1U));
            permute(weights_shape, PermutationVector(2U, 0U, 1U));
        }

        // Create tensors
        _src     = create_tensor<TensorType>(input_shape, _data_type, 1, QuantizationInfo(), _data_layout);
        _weights = create_tensor<TensorType>(weights_shape, _data_type, 1, QuantizationInfo(), _data_layout);
        _biases  = create_tensor<TensorType>(_biases_shape, _data_type, 1, QuantizationInfo(), _data_layout);
        _target  = create_tensor<TensorType>(TensorShape(), _data_type, 1, QuantizationInfo(), _data_layout);

        add_padding_x({ &_src, &_biases, &_target }, _data_layout);
        add_padding_x({ &_weights }, _data_layout, true);
        add_padding_y({ &_src, &_target }, _data_layout);

        // Create Depthwise Convolution configure function
        const ConvolutionInfo info
        {
            _conv_info, _depth_multiplier, ActivationLayerInfo(), _dilation
        };
        _dwc.configure(_src.info(), _weights.info(), _biases.info(), _target.info(), info);

        ARM_COMPUTE_ASSERT(_src.info()->is_resizable());
        ARM_COMPUTE_ASSERT(_weights.info()->is_resizable());
        ARM_COMPUTE_ASSERT(_biases.info()->is_resizable());
        ARM_COMPUTE_ASSERT(_target.info()->is_resizable());
    }

    void allocate_and_run_target()
    {
        // Allocate tensors
        _src.allocator()->allocate();
        _weights.allocator()->allocate();
        _biases.allocator()->allocate();
        _target.allocator()->allocate();

        ARM_COMPUTE_ASSERT(!_src.info()->is_resizable());
        ARM_COMPUTE_ASSERT(!_weights.info()->is_resizable());
        ARM_COMPUTE_ASSERT(!_biases.info()->is_resizable());
        ARM_COMPUTE_ASSERT(!_target.info()->is_resizable());

        // Fill tensors
        fill(AccessorType(_src), 0);
        fill(AccessorType(_weights), 1);
        fill(AccessorType(_biases), 2);

        arm_compute::ITensorPack pack;
        pack.add_const_tensor(arm_compute::TensorType::ACL_SRC_0, &_src);
        pack.add_const_tensor(arm_compute::TensorType::ACL_SRC_1, &_weights);
        pack.add_const_tensor(arm_compute::TensorType::ACL_SRC_2, &_biases);
        pack.add_tensor(arm_compute::TensorType::ACL_DST, &_target);

        // Compute function
        _dwc.run(pack);
    }

    void compute_reference()
    {
        SimpleTensor<T> src{ _input_shape, _data_type };
        SimpleTensor<T> weights{ _weights_shape, _data_type };
        SimpleTensor<T> biases{ _biases_shape, _data_type };

        fill(src, 0);
        fill(weights, 1);
        fill(biases, 2);

        const ConvolutionInfo info{ _conv_info, _depth_multiplier, ActivationLayerInfo(), _dilation };
        const TensorShape     dst_shape = compute_depthwise_convolution_shape(TensorInfo(_input_shape, 1, _data_type), TensorInfo(_weights_shape, 1, _data_type), info);
        _reference                      = reference::depthwise_convolution(src, weights, biases, dst_shape, _conv_info, _depth_multiplier, _dilation);
    }

protected:
    template <typename U>
    void fill(U &&tensor, int i)
    {
        switch(tensor.data_type())
        {
            case DataType::F32:
            {
                std::uniform_real_distribution<float> distribution(-1.0f, 1.0f);
                library->fill(tensor, distribution, i);
                break;
            }
            default:
                library->fill_tensor_uniform(tensor, i);
        }
    }

    TensorType      _target{};
    SimpleTensor<T> _reference{};

    TensorType   _src{};
    TensorType   _weights{};
    TensorType   _biases{};
    FunctionType _dwc{};

    TensorShape   _input_shape{};
    TensorShape   _weights_shape{};
    TensorShape   _biases_shape{};
    DataType      _data_type{};
    DataLayout    _data_layout{};
    PadStrideInfo _conv_info{};
    Size2D        _dilation{};
    unsigned int  _depth_multiplier{};
};

template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool in_place = false>
class DepthwiseConvolutionLayerNativeConfigurableValidationFixture : public DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, T>
{
public:
    template <typename...>
    void setup(size_t width, size_t height, size_t channel, size_t batch, Size2D kernel_size, size_t depth_multiplier, Size2D dilation, Size2D stride, bool padding_valid, DataType data_type,
               DataLayout data_layout, const ActivationLayerInfo &act_info, unsigned int n0, bool export_to_cl_image)
    {
        _dilation           = dilation;
        _depth_multiplier   = depth_multiplier;
        _data_type          = data_type;
        _data_layout        = data_layout;
        _act_info           = act_info;
        _n0                 = n0;
        _export_to_cl_image = export_to_cl_image;
        _in_place           = in_place;

        _input_shape   = TensorShape(width, height, channel, batch);
        _weights_shape = TensorShape(kernel_size.width, kernel_size.height, channel * _depth_multiplier);
        _biases_shape  = TensorShape(_weights_shape.z());

        if(padding_valid)
        {
            _conv_info = calculate_same_pad(_input_shape, _weights_shape, PadStrideInfo(stride.width, stride.height), DataLayout::NCHW, _dilation);
        }
        else
        {
            _conv_info = PadStrideInfo(stride.width, stride.height);
        }
    }

    void configure_target()
    {
        TensorShape input_shape   = _input_shape;
        TensorShape weights_shape = _weights_shape;

        if(_data_layout == DataLayout::NHWC)
        {
            permute(input_shape, PermutationVector(2U, 0U, 1U));
            permute(weights_shape, PermutationVector(2U, 0U, 1U));
        }

        // Create tensors
        _src                      = create_tensor<TensorType>(input_shape, _data_type, 1, QuantizationInfo(), _data_layout);
        _weights                  = create_tensor<TensorType>(weights_shape, _data_type, 1, QuantizationInfo(), _data_layout);
        _biases                   = create_tensor<TensorType>(_biases_shape, _data_type, 1, QuantizationInfo(), _data_layout);
        TensorType *target_to_use = nullptr;
        if(!_in_place)
        {
            _target       = create_tensor<TensorType>(TensorShape(), _data_type, 1, QuantizationInfo(), _data_layout);
            target_to_use = &_target;
        }

        DWCComputeKernelInfo dwc_info;
        dwc_info.n0                         = _n0;
        dwc_info.m0                         = _conv_info.stride().first == 1 && _dilation.x() == 1 ? 8 : 1;
        dwc_info.export_weights_to_cl_image = _export_to_cl_image;

#if defined(ARM_COMPUTE_OPENCL_ENABLED)
        if(_export_to_cl_image)
        {
            _validate_output |= image2d_from_buffer_supported(CLKernelLibrary::get().get_device());
            _validate_output |= (get_cl_image_pitch_alignment(CLKernelLibrary::get().get_device()) != 0);
        }
#endif // ARM_COMPUTE_OPENCL_ENABLED

        const ConvolutionInfo conv_kernel_info
        {
            _conv_info, _depth_multiplier, _act_info, _dilation
        };

        add_padding_x({ &_src, &_biases, &_target }, _data_layout);
        add_padding_x({ &_weights }, _data_layout, _export_to_cl_image); // Don't add left padding if cl image will be used

        // Create Depthwise Convolution configure function
        _dwc.configure(&_src, &_weights, &_biases, target_to_use, dwc_info, conv_kernel_info);

        ARM_COMPUTE_ASSERT(_src.info()->is_resizable());
        ARM_COMPUTE_ASSERT(_weights.info()->is_resizable());
        ARM_COMPUTE_ASSERT(_biases.info()->is_resizable());
        ARM_COMPUTE_ASSERT(_target.info()->is_resizable());
    }

    void allocate_and_run_target()
    {
        // Allocate tensors
        _src.allocator()->allocate();
        _weights.allocator()->allocate();
        _biases.allocator()->allocate();

        ARM_COMPUTE_ASSERT(!_src.info()->is_resizable());
        ARM_COMPUTE_ASSERT(!_weights.info()->is_resizable());
        ARM_COMPUTE_ASSERT(!_biases.info()->is_resizable());
        if(!_in_place)
        {
            _target.allocator()->allocate();
            ARM_COMPUTE_ASSERT(!_target.info()->is_resizable());
        }

        // Fill tensors
        fill(AccessorType(_src), 0);
        fill(AccessorType(_weights), 1);
        fill(AccessorType(_biases), 2);

        // Test Multi DataLayout graph cases, when the data layout changes after configure
        _src.info()->set_data_layout(_data_layout == DataLayout::NCHW ? DataLayout::NHWC : DataLayout::NCHW);
        if(!_in_place)
        {
            _target.info()->set_data_layout(_data_layout == DataLayout::NCHW ? DataLayout::NHWC : DataLayout::NCHW);
        }

        // Compute function
        if(_validate_output)
        {
            _dwc.run();
        }

        // Reinstating original data layout for the test suite to properly check the values
        if(!_in_place)
        {
            _target.info()->set_data_layout(_data_layout);
        }
    }

    void compute_reference()
    {
        SimpleTensor<T> src{ _input_shape, _data_type };
        SimpleTensor<T> weights{ _weights_shape, _data_type };
        SimpleTensor<T> biases{ _biases_shape, _data_type };

        fill(src, 0);
        fill(weights, 1);
        fill(biases, 2);

        const ConvolutionInfo info{ _conv_info, _depth_multiplier, _act_info, _dilation };
        const TensorShape     dst_shape = compute_depthwise_convolution_shape(TensorInfo(_input_shape, 1, _data_type), TensorInfo(_weights_shape, 1, _data_type), info);
        if(_validate_output)
        {
            _reference = reference::activation_layer(reference::depthwise_convolution(src, weights, biases, dst_shape, _conv_info, _depth_multiplier, _dilation), _act_info);
        }
    }

protected:
    template <typename U>
    void fill(U &&tensor, int i)
    {
        switch(tensor.data_type())
        {
            case DataType::F32:
            {
                std::uniform_real_distribution<float> distribution(-1.0f, 1.0f);
                library->fill(tensor, distribution, i);
                break;
            }
            case DataType::F16:
            {
                arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -1.0f, 1.0f };
                library->fill(tensor, distribution, i);
                break;
            }
            default:
                library->fill_tensor_uniform(tensor, i);
        }
    }

    TensorType      _target{};
    SimpleTensor<T> _reference{};

    TensorType   _src{};
    TensorType   _weights{};
    TensorType   _biases{};
    FunctionType _dwc{};

    TensorShape         _input_shape{};
    TensorShape         _weights_shape{};
    TensorShape         _biases_shape{};
    DataType            _data_type{};
    DataLayout          _data_layout{};
    PadStrideInfo       _conv_info{};
    ActivationLayerInfo _act_info{};
    Size2D              _dilation{};
    unsigned int        _depth_multiplier{};
    unsigned int        _n0{};
    bool                _export_to_cl_image{};
    bool                _validate_output{ true };
    bool                _in_place{ false };
};

template <typename TensorType, typename AccessorType, typename FunctionType, typename T, bool mixed_layout = false, bool in_place = false>
class DepthwiseConvolutionLayerValidationQuantizedFixture : public DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, T>
{
public:
    template <typename...>
    void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, Size2D dilation, unsigned int depth_multiplier, DataType data_type,
               QuantizationInfo input_quantization_info, QuantizationInfo output_quantization_info, DataLayout data_layout, ActivationLayerInfo act_info)
    {
        DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, T>::setup(in_shape, kernel_size, pad_stride_info, dilation, depth_multiplier, data_type,
                                                                                                               data_type, input_quantization_info, input_quantization_info, output_quantization_info,
                                                                                                               data_layout, act_info, mixed_layout, in_place);
    }
};

template <typename TensorType, typename AccessorType, typename FunctionType, typename T, typename TW, bool in_place = false>
class DepthwiseConvolutionLayerValidationQuantizedPerChannelFixture : public DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, TW>
{
public:
    template <typename...>
    void setup(TensorShape in_shape, Size2D kernel_size, PadStrideInfo pad_stride_info, Size2D dilation, unsigned int depth_multiplier, DataType input_data_type, DataType weights_data_type,
               QuantizationInfo input_quantization_info, QuantizationInfo output_quantization_info, DataLayout data_layout, ActivationLayerInfo act_info)
    {
        const float out_scale = output_quantization_info.uniform().scale;
        const float in_scale  = input_quantization_info.uniform().scale;

        std::vector<float>                    weights_scales{};
        std::mt19937                          gen(library->seed());
        std::uniform_real_distribution<float> dis(0.01f, out_scale / in_scale);
        for(size_t i = 0; i < in_shape.z() * depth_multiplier; ++i)
        {
            weights_scales.push_back(dis(gen));
        }

        DepthwiseConvolutionLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T, TW>::setup(in_shape, kernel_size, pad_stride_info, dilation, depth_multiplier,
                                                                                                                input_data_type, weights_data_type,
                                                                                                                input_quantization_info, QuantizationInfo(weights_scales), output_quantization_info,
                                                                                                                data_layout, act_info, false, in_place);
    }
};
} // namespace validation
} // namespace test
} // namespace arm_compute
#endif /* ARM_COMPUTE_TEST_DEPTHWISE_CONVOLUTION_FIXTURE */
