/*
 * Copyright (c) 2017-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_NEGEMMWINOGRADCONVOLUTIONLAYERKERNEL_H
#define ARM_COMPUTE_NEGEMMWINOGRADCONVOLUTIONLAYERKERNEL_H

#include "arm_compute/core/NEON/INEKernel.h"
#include "arm_compute/core/NEON/kernels/convolution/common/convolution.hpp"
#include "arm_compute/core/NEON/kernels/convolution/common/tensor.hpp"
#include "arm_compute/core/NEON/kernels/convolution/winograd/winograd_layer.hpp"

namespace arm_compute
{
class ITensor;

/** Interface for the NEON kernel to perform Winograd input transform. */
template <typename T>
class INEWinogradLayerTransformInputKernel : public INEKernel
{
public:
    /** Get the working space required to perform the transformation.
     *
     * Note, the working space is only required when performing the
     * transformation - hence it can be reused whenever the transformation is
     * not running.
     *
     * @param num_threads The greatest number of threads that will be used to execute the transform.
     * @return Size of working space required in bytes.
     */
    virtual unsigned int get_working_space_size(unsigned int num_threads) const = 0;

    /** Determine how much memory (in units of TIn) to allocate for the
     * transformed input.
     *
     * @param[in] num_batches  Number of batches in the input tensor.
     * @param[in] num_channels Number of feature maps in the input tensor.
     * @param[in] num_rows     Number of rows in each feature map.
     * @param[in] num_cols     Number of columns in each feature map.
     * @param[in] same_padding Use "SAME" padding, otherwise use "VALID".
     *
     * @return Storage size (in units of TIn) required.
     */
    virtual unsigned int get_input_storage_size(int num_batches, int num_channels, int num_rows, int num_cols, bool same_padding) const = 0;

    /** Gets the stride between matrices in the input worspace
     *
     * @param[in] num_batches  Number of batches in the input tensor.
     * @param[in] num_channels Number of feature maps in the input tensor.
     * @param[in] num_rows     Number of rows in each feature map.
     * @param[in] num_cols     Number of columns in each feature map.
     * @param[in] same_padding Use "SAME" padding, otherwise use "VALID".
     *
     * @return Stride expressed in bytes.
     */
    virtual int get_matrix_stride(int num_batches, int num_channels, int num_rows, int num_cols, bool same_padding) const = 0;

    /** Configure the output transform kernel.
     *
     * @param[in]  input_nhwc    Input tensor in NHWC data layout format.
     * @param[in]  num_batches   Number of batches in input tensor.
     * @param[in]  num_rows      Number of rows in input tensor.
     * @param[in]  num_cols      Number of columns in input tensor.
     * @param[in]  num_channels  Number of channels in input tensor.
     * @param[in]  padding       Padding type.
     * @param[out] output        Base of output matrices.
     * @param[in]  matrix_stride Stride between output matrices.
     * @param[in]  workspace     Tensor to be used as the working space during the computation.
     */
    virtual void configure(const ITensor *input_nhwc, const int num_batches, const int num_rows, const int num_cols, const int num_channels,
                           const PaddingType padding, ITensor *output, const int matrix_stride, ITensor *workspace) = 0;

    /** Destructor */
    virtual ~INEWinogradLayerTransformInputKernel()
    {
    }
};

/** NEON kernel to perform Winograd input transform. */
template <typename T, int OutputTileRows, int OutputTileCols, int KernelRows, int KernelCols>
class NEWinogradLayerTransformInputKernel : public INEWinogradLayerTransformInputKernel<T>
{
public:
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEWinogradLayerTransformInputKernel(const NEWinogradLayerTransformInputKernel &) = delete;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEWinogradLayerTransformInputKernel &operator=(const NEWinogradLayerTransformInputKernel &) = delete;
    /** Allow instances of this class to be moved */
    NEWinogradLayerTransformInputKernel(NEWinogradLayerTransformInputKernel &&) = default;
    /** Allow instances of this class to be moved */
    NEWinogradLayerTransformInputKernel &operator=(NEWinogradLayerTransformInputKernel &&) = default;
    /** Default destructor */
    ~NEWinogradLayerTransformInputKernel() = default;

    /** Determine how much memory (in units of TIn) to allocate for the
     * transformed input.
     *
     * @param[in] num_batches  Number of batches in the input tensor.
     * @param[in] num_channels Number of feature maps in the input tensor.
     * @param[in] num_rows     Number of rows in each feature map.
     * @param[in] num_cols     Number of columns in each feature map.
     * @param[in] same_padding Use "SAME" padding, otherwise use "VALID".
     *
     * @return Storage size (in units of TIn) required.
     */
    unsigned int get_input_storage_size(
        int  num_batches,
        int  num_channels,
        int  num_rows,
        int  num_cols,
        bool same_padding) const override;

    /** Get the working space required to perform the transformation.
     *
     * Note, the working space is only required when performing the
     * transformation - hence it can be reused whenever the transformation is
     * not running.
     *
     * @param[in] num_threads The greatest number of threads that will be used to execute the transform.
     *
     * @return Size of working space required in bytes.
     */
    unsigned int get_working_space_size(unsigned int num_threads) const override;

    /** Gets the stride between matrices in the input worspace
     *
     * @param[in] num_batches  Number of batches in the input tensor.
     * @param[in] num_channels Number of feature maps in the input tensor.
     * @param[in] num_rows     Number of rows in each feature map.
     * @param[in] num_cols     Number of columns in each feature map.
     * @param[in] same_padding Use "SAME" padding, otherwise use "VALID".
     *
     * @return Stride expressed in bytes.
     */
    int get_matrix_stride(
        int  num_batches,
        int  num_channels,
        int  num_rows,
        int  num_cols,
        bool same_padding) const override;

    /** Default constructor */
    NEWinogradLayerTransformInputKernel();

    const char *name() const override
    {
        return "NEWinogradLayerTransformInputKernel";
    }

    /** Configure the output transform kernel.
     *
     * @param[in]  input_nhwc    Input tensor.  Data types supported: F32. Layout supported NHWC.
     * @param[in]  num_batches   Number of batches in input tensor.
     * @param[in]  num_rows      Number of rows in input tensor.
     * @param[in]  num_cols      Number of columns in input tensor.
     * @param[in]  num_channels  Number of channels in input tensor.
     * @param[in]  padding       Padding type.
     * @param[out] output        Base of output matrices.
     * @param[in]  matrix_stride Stride between output matrices.
     * @param[in]  workspace     Tensor to be used as the working space during the computation.
     */
    void configure(
        const ITensor    *input_nhwc,
        const int         num_batches,
        const int         num_rows,
        const int         num_cols,
        const int         num_channels,
        const PaddingType padding,
        ITensor          *output,
        const int         matrix_stride,
        ITensor          *workspace) override;

    // Inherited methods overridden:
    void run(const Window &window, const ThreadInfo &info) override;

    /** Winograd base kernel */
    using WinogradBase = winograd::WinogradGEMM<OutputTileRows, OutputTileCols, KernelRows, KernelCols, winograd::WinogradRoots::Integers>;
    /** Winograd convolution kernel */
    using WinogradConv = typename WinogradBase::template Convolution<T, T>;

    /** Static function to check if given info will lead to a valid configuration of @ref NEWinogradLayerTransformInputKernel
     *
     * @param[in] input         First tensor input info. Data types supported: F32.
     * @param[in] output        Output tensor info. Data types supported: same as @p input.
     * @param[in] winograd_info Contains Winograd's information described in @ref WinogradInfo
     *
     * @return a status
     */
    static Status validate(const ITensorInfo *input, const ITensorInfo *output, const WinogradInfo &winograd_info);

private:
    using InputTransform = typename WinogradBase::template InputTransform<T, T>;

    std::unique_ptr<InputTransform> _transform{ nullptr };
    const ITensor                  *_input_nhwc;
    int                             _num_batches;    /**< Number of batches in input tensor. */
    int                             _num_rows;       /**< Number of rows in input tensor. */
    int                             _num_cols;       /**< Number of columns in input tensor. */
    int                             _num_channels;   /**< Number of channels in input tensor. */
    PaddingType                     _padding;        /**< Padding type. */
    ITensor                        *_output;         /**< Base of output matrices. */
    int                             _matrix_stride;  /**< Stride between output matrices. */
    int                             _padding_top;    /**< Padding to apply to the top of the image. */
    int                             _padding_left;   /**< Padding to apply to the left of the image. */
    int                             _padding_right;  /**< Padding to apply to the right of the image. */
    int                             _padding_bottom; /**< Padding to apply to the bottom of the image. */
    ITensor                        *_workspace;
};

/** Interface for the NEON kernel to perform Winograd output transform. */
template <typename T>
class INEWinogradLayerTransformOutputKernel : public INEKernel
{
public:
    /** Get the working space required to perform the transformation.
     *
     * Note, the working space is only required when performing the
     * transformation - hence it can be reused whenever the transformation is
     * not running.
     *
     * @param[in] num_threads The greatest number of threads that will be used to execute the transform.
     *
     * @return Size of working space required in bytes.
     */
    virtual unsigned int get_working_space_size(unsigned int num_threads) const = 0;

    /** Determine how much memory (in units of TOut) to allocate for the
     * (Winograd domain) output.
     *
     * @param[in] num_batches         Number of batches in the output tensor.
     * @param[in] num_rows            Number of rows in each feature map of the input tensor.
     * @param[in] num_cols            Number of columns in each feature map of the input tensor.
     * @param[in] num_output_channels Number of feature maps in the output tensor.
     *
     * @return Storage size (in units of TOut) required.
     */
    virtual unsigned int get_output_storage_size(int num_batches, int num_rows, int num_cols, int num_output_channels) const = 0;

    /** Gets the stride between matrices in the output worspace
     *
     * @param[in] num_batches         Number of batches in the output tensor.
     * @param[in] num_rows            Number of rows in each feature map of the input tensor.
     * @param[in] num_cols            Number of columns in each feature map of the input tensor.
     * @param[in] num_output_channels Number of feature maps in the output tensor.
     *
     * @return Stride expressed in bytes.
     */
    virtual int get_matrix_stride(int num_batches, int num_rows, int num_cols, int num_output_channels) const = 0;

    /** Get the output shape of a convolution.
     *
     * @param[in] num_rows     Number of rows in each feature map of the input tensor.
     * @param[in] num_cols     Number of columns in each feature map of the input tensor.
     * @param[in] padding_same True if padding is SAME, false otherwise
     *
     * @return Shape of the output tensor
     */
    virtual std::pair<unsigned int, unsigned int> get_output_shape(
        int  num_rows,    /* Number of rows in each feature map of the input tensor. */
        int  num_cols,    /* Number of columns in each feature map of the input tensor. */
        bool padding_same /* True if padding is SAME, false otherwise */
    ) const = 0;

    /** Configure the output transform kernel.
     *
     * @param[in]  biases             Pointer to the biases tensor.
     * @param[in]  transformed_output Pointer to working space for the output tensor in the Winograd domain.
     * @param[in]  matrix_stride      Output matrix stride, can be computed with winograd::WinogradGEMM<2, 2, 3, 3>::Convolution<float, float>::get_output_matrix_stride()
     * @param[out] output_nhwc        Pointer to a tensor in NHWC data layout ordered output tensor, in the spatial domain.
     * @param[in]  num_batches        Number of batches in the input tensor.
     * @param[in]  num_rows           Number of rows in output tensor.
     * @param[in]  num_cols           Number of columns in output tensor.
     * @param[in]  num_channels       Number of feature maps in the output tensor.
     * @param[in]  workspace          Tensor to be used as the working space during the computation.
     * @param[in]  activation         Activation to be used
     */
    virtual void configure(
        const ITensor              *biases,
        const ITensor              *transformed_output,
        const int                   matrix_stride,
        ITensor                    *output_nhwc,
        const int                   num_batches,
        const int                   num_rows,
        const int                   num_cols,
        const int                   num_channels,
        ITensor                    *workspace,
        const arm_gemm::Activation &activation) = 0;

    virtual ~INEWinogradLayerTransformOutputKernel()
    {
    }
};

/** NEON kernel to perform Winograd output transform. */
template <typename T, int OutputTileRows, int OutputTileCols, int KernelRows, int KernelCols>
class NEWinogradLayerTransformOutputKernel : public INEWinogradLayerTransformOutputKernel<T>
{
public:
    const char *name() const override
    {
        return "NEWinogradLayerTransformOutputKernel";
    }
    /** Constructor */
    NEWinogradLayerTransformOutputKernel();

    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEWinogradLayerTransformOutputKernel(const NEWinogradLayerTransformOutputKernel &) = delete;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEWinogradLayerTransformOutputKernel &operator=(const NEWinogradLayerTransformOutputKernel &) = delete;
    /** Allow instances of this class to be moved */
    NEWinogradLayerTransformOutputKernel(NEWinogradLayerTransformOutputKernel &&) = default;
    /** Allow instances of this class to be moved */
    NEWinogradLayerTransformOutputKernel &operator=(NEWinogradLayerTransformOutputKernel &&) = default;
    /** Default destructor */
    ~NEWinogradLayerTransformOutputKernel() = default;

    // Inherited methods overridden:
    /** Determine how much memory (in units of TOut) to allocate for the
     * (Winograd domain) output.
     *
     * @param[in] num_batches         Number of batches in the output tensor.
     * @param[in] num_rows            Number of rows in each feature map of the input tensor.
     * @param[in] num_cols            Number of columns in each feature map of the input tensor.
     * @param[in] num_output_channels Number of feature maps in the output tensor.
     *
     * @return Storage size (in units of TOut) required.
     */
    unsigned int get_output_storage_size(int num_batches, int num_rows, int num_cols, int num_output_channels) const override;

    /** Gets the stride between matrices in the output worspace
     *
     * @param[in] num_batches         Number of batches in the output tensor.
     * @param[in] num_rows            Number of rows in each feature map of the input tensor.
     * @param[in] num_cols            Number of columns in each feature map of the input tensor.
     * @param[in] num_output_channels Number of feature maps in the output tensor.
     *
     * @return Stride expressed in bytes.
     */
    int get_matrix_stride(int num_batches, int num_rows, int num_cols, int num_output_channels) const override;
    /** Get the output shape of a convolution.
     *
     * @param[in] num_rows     Number of rows in each feature map of the input tensor.
     * @param[in] num_cols     Number of columns in each feature map of the input tensor.
     * @param[in] padding_same True if padding is SAME, false otherwise
     *
     * @return Shape of the output tensor
     */
    std::pair<unsigned int, unsigned int> get_output_shape(
        int  num_rows, /* Number of rows in each feature map of the input tensor. */
        int  num_cols, /* Number of columns in each feature map of the input tensor. */
        bool padding_same) const override;

    /** Get the working space required to perform the transformation.
     *
     * Note, the working space is only required when performing the
     * transformation - hence it can be reused whenever the transformation is
     * not running.
     *
     * @param[in] num_threads The greatest number of threads that will be used to execute the transform.
     *
     * @return Size of working space required in bytes.
     */
    unsigned int get_working_space_size(unsigned int num_threads) const override;

    /** Configure the output transform kernel.
     *
     * @param[in]  biases             Pointer to the biases tensor.
     * @param[in]  transformed_output Pointer to working space for the output tensor in the Winograd domain.
     * @param[in]  matrix_stride      Output matrix stride, can be computed with winograd::WinogradGEMM<2, 2, 3, 3>::Convolution<float, float>::get_output_matrix_stride()
     * @param[out] output_nhwc        Pointer to a tensor with NHWC data layout, in the spatial domain.
     * @param[in]  num_batches        Number of batches in the input tensor.
     * @param[in]  num_rows           Number of rows in output tensor.
     * @param[in]  num_cols           Number of columns in output tensor.
     * @param[in]  num_channels       Number of feature maps in the output tensor.
     * @param[in]  workspace          Tensor to be used as the working space during the computation.
     * @param[in]  activation         Activation to be used
     */
    void configure(
        const ITensor              *biases,
        const ITensor              *transformed_output,
        const int                   matrix_stride,
        ITensor                    *output_nhwc,
        const int                   num_batches,
        const int                   num_rows,
        const int                   num_cols,
        const int                   num_channels,
        ITensor                    *workspace,
        const arm_gemm::Activation &activation) override;

    void run(const Window &window, const ThreadInfo &info) override;

    /** Static function to check if given info will lead to a valid configuration of @ref NEWinogradLayerTransformOutputKernel
     *
     * @param[in] input         Source tensor info with shape [C, N, 16, batches] or [C, N, 36, batches]. Data types supported: F32.
     * @param[in] bias          Biases tensor info. Shared biases supported. Biases are 1D tensor with dimensions [OFM]. It can be a nullptr. Data type supported: as @p input
     * @param[in] output        Destination tensor info with shape [output_convolved_dims.width, output_convolved_dims.height, C, batches]. Data type supported: same as @p input
     * @param[in] winograd_info Contains Winograd's information described in @ref WinogradInfo
     *
     * @return a status
     */
    static Status validate(const ITensorInfo *input, const ITensorInfo *bias, const ITensorInfo *output, const WinogradInfo &winograd_info);

private:
    using WinogradBase    = winograd::WinogradGEMM<OutputTileRows, OutputTileCols, KernelRows, KernelCols, winograd::WinogradRoots::Integers>;
    using WinogradConv    = typename WinogradBase::template Convolution<T, T>;
    using OutputTransform = typename WinogradBase::template OutputTransform<T, T>;

    std::unique_ptr<OutputTransform> _transform{ nullptr };
    const ITensor                   *_biases;
    const ITensor                   *_transformed_output;
    ITensor                         *_workspace;
    int                              _matrix_stride;
    int                              _matrix_row_stride;
    ITensor                         *_output_nhwc;
    int                              _num_batches;
    int                              _num_rows;
    int                              _num_cols;
    int                              _num_channels;
};

/** Interface for the NEON kernel to perform Winograd weights transform. */
template <typename T>
class INEWinogradLayerTransformWeightsKernel : public INEKernel
{
public:
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    INEWinogradLayerTransformWeightsKernel(const INEWinogradLayerTransformWeightsKernel &) = default;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    INEWinogradLayerTransformWeightsKernel &operator=(const INEWinogradLayerTransformWeightsKernel &) = default;
    /** Allow instances of this class to be moved */
    INEWinogradLayerTransformWeightsKernel(INEWinogradLayerTransformWeightsKernel &&) = default;
    /** Allow instances of this class to be moved */
    INEWinogradLayerTransformWeightsKernel &operator=(INEWinogradLayerTransformWeightsKernel &&) = default;

    INEWinogradLayerTransformWeightsKernel()
    {
    }
    virtual ~INEWinogradLayerTransformWeightsKernel()
    {
    }
    /** Determine how much memory (in units of T) to allocate for the
     * transformed weights.
     *
     * @param[in] num_output_channels Number of output feature maps.
     * @param[in] num_input_channels  Number of input feature maps.
     *
     * @return Storage size (in units of T) required.
     */
    virtual unsigned int get_weight_storage_size(int num_output_channels, int num_input_channels) const = 0;
    /** Gets the stride between matrices in the kernel worspace
     *
     * @param[in] num_output_channels Number of output feature maps.
     * @param[in] num_input_channels  Number of input feature maps.
     *
     * @return Stride expressed in bytes.
     */
    virtual int get_matrix_stride(int num_output_channels, int num_input_channels) const = 0;

    /** Configure the weights transform kernel.
     *
     * @param[in]  weights_hwio        Pointer to the weights tensor
     * @param[out] output              Pointer to working space for the output tensor in the Winograd domain.
     * @param[in]  matrix_stride       Stride across matrices in the output workspace.
     * @param[in]  num_output_channels Number of filters.
     * @param[in]  num_input_channels  Number of channels in each filter.
     */

    virtual void configure(const ITensor *weights_hwio, ITensor *output, const int matrix_stride, const int num_output_channels, const int num_input_channels) = 0;

    /** Static function to check if given info will lead to a valid configuration of @ref NEWinogradLayerTransformWeightsKernel
     *
     * @param[in] input   First tensor input info. Data types supported: F32.
     * @param[in] weights Weights tensor info. Data types supported: same as @p input.
     *
     * @return a status
     */
    static Status validate(const ITensorInfo *input, const ITensorInfo *weights);
};

/** NEON kernel to perform Winograd weights transform. */
template <typename T, int OutputTileRows, int OutputTileCols, int KernelRows, int KernelCols>
class NEWinogradLayerTransformWeightsKernel final : public INEWinogradLayerTransformWeightsKernel<T>
{
public:
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEWinogradLayerTransformWeightsKernel(const NEWinogradLayerTransformWeightsKernel &) = delete;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NEWinogradLayerTransformWeightsKernel &operator=(const NEWinogradLayerTransformWeightsKernel &) = delete;
    /** Allow instances of this class to be moved */
    NEWinogradLayerTransformWeightsKernel(NEWinogradLayerTransformWeightsKernel &&) = default;
    /** Allow instances of this class to be moved */
    NEWinogradLayerTransformWeightsKernel &operator=(NEWinogradLayerTransformWeightsKernel &&) = default;
    /** Default destructor */
    ~NEWinogradLayerTransformWeightsKernel() = default;

    /** Default constructor. */
    NEWinogradLayerTransformWeightsKernel();
    const char *name() const override
    {
        return "NEWinogradLayerTransformWeightsKernel";
    }

    /** Static function to check if given info will lead to a valid configuration of @ref NEWinogradLayerTransformWeightsKernel
     *
     * @param[in] input         Source tensor info. The input is a 4D tensor with dimensions [kernel_x, kernel_y, IFM, OFM] (NCHW data layout).
     *                          kernel_x must be 3 and equal to kernel_y. Data types supported: F32.
     * @param[in] output        Destination tensor info. The output is a 3D tensor with dimensions [OFM, IFM, 16] or [OFM, IFM, 36]. Data type supported: same as @p input
     * @param[in] winograd_info Contains Winograd's information described in @ref WinogradInfo
     *
     * @return a status
     */
    static Status validate(const ITensorInfo *input, const ITensorInfo *output, const WinogradInfo &winograd_info);

    // Inherited methods overridden:

#ifndef DOXYGEN_SKIP_THIS
    /** Configure the weights transform kernel.
     *
     * @param[in]  weights_hwio        Pointer to the weights tensor
     * @param[out] output              Pointer to working space for the output tensor in the Winograd domain.
     * @param[in]  matrix_stride       Stride across matrices in the output workspace.
     * @param[in]  num_output_channels Number of filters.
     * @param[in]  num_input_channels  Number of channels in each filter.
     */
    void configure(const ITensor *weights_hwio, ITensor *output, const int matrix_stride, const int num_output_channels, const int num_input_channels) override;
#endif /* DOXYGEN_SKIP_THIS */

    /** Determine how much memory (in units of T) to allocate for the
     * transformed weights.
     *
     * @param[in] num_output_channels Number of output feature maps.
     * @param[in] num_input_channels  Number of input feature maps.
     *
     * @return Storage size (in units of T) required.
     */
    unsigned int get_weight_storage_size(int num_output_channels, int num_input_channels) const override;

    /** Gets the stride between matrices in the input worspace
     *
     * @param[in] num_output_channels Number of output feature maps.
     * @param[in] num_input_channels  Number of input feature maps.
     *
     * @return Stride expressed in bytes.
     */
    int get_matrix_stride(int num_output_channels, int num_input_channels) const override;
    void run(const Window &window, const ThreadInfo &info) override;
    bool is_parallelisable() const override;

private:
    using WinogradBase     = winograd::WinogradGEMM<OutputTileRows, OutputTileCols, KernelRows, KernelCols, winograd::WinogradRoots::Integers>;
    using WinogradConv     = typename WinogradBase::template Convolution<T, T>;
    using WeightsTransform = typename WinogradBase::template WeightsTransform<T, T>;

    std::unique_ptr<WeightsTransform> _transform{ nullptr };
    const ITensor                    *_weights_hwio;
    ITensor                          *_output;
    int                               _matrix_stride;
    int                               _num_output_channels;
    int                               _num_input_channels;
};

/** NEON kernel to perform Winograd. */
template <typename TIn, typename TOut, int OutputTileRows, int OutputTileCols, int KernelRows, int KernelCols>
class NEWinogradLayerConfiguration
{
public:
    /** Winograd base kernel */
    using WinogradBase = winograd::WinogradGEMM<OutputTileRows, OutputTileCols, KernelRows, KernelCols, winograd::WinogradRoots::Integers>;
    /** Winograd convolution kernel */

    using WinogradConv = typename WinogradBase::template Convolution<TIn, TOut>;

    using TransformInputKernel   = NEWinogradLayerTransformInputKernel<TIn, OutputTileRows, OutputTileCols, KernelRows, KernelCols>;
    using TransformWeightsKernel = NEWinogradLayerTransformWeightsKernel<TIn, OutputTileRows, OutputTileCols, KernelRows, KernelCols>;
    using TransformOutputKernel  = NEWinogradLayerTransformOutputKernel<TOut, OutputTileRows, OutputTileCols, KernelRows, KernelCols>;
};

} // namespace arm_compute
#endif /*ARM_COMPUTE_NEGEMMWINOGRADCONVOLUTIONLAYERKERNEL_H*/
