/*
 * Copyright (c) 2017-2022 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_TENSOR_LIBRARY_H
#define ARM_COMPUTE_TEST_TENSOR_LIBRARY_H

#include "arm_compute/core/Coordinates.h"
#include "arm_compute/core/Error.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/TensorInfo.h"
#include "arm_compute/core/TensorShape.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/core/Window.h"
#include "support/Random.h"
#include "tests/RawTensor.h"
#include "tests/TensorCache.h"
#include "tests/Utils.h"
#include "tests/framework/Exceptions.h"
#include "utils/Utils.h"

#include <algorithm>
#include <cstddef>
#include <fstream>
#include <random>
#include <string>
#include <type_traits>
#include <vector>

namespace arm_compute
{
namespace test
{
/** Factory class to create and fill tensors.
 *
 * Allows to initialise tensors from loaded images or by specifying the shape
 * explicitly. Furthermore, provides methods to fill tensors with the content of
 * loaded images or with random values.
 */
class AssetsLibrary final
{
public:
    using RangePair = std::pair<float, float>;

public:
    /** Initialises the library with a @p path to the assets directory.
     * Furthermore, sets the seed for the random generator to @p seed.
     *
     * @param[in] path Path to load assets from.
     * @param[in] seed Seed used to initialise the random number generator.
     */
    AssetsLibrary(std::string path, std::random_device::result_type seed);

    /** Path to assets directory used to initialise library.
     *
     * @return the path to the assets directory.
     */
    std::string path() const;

    /** Seed that is used to fill tensors with random values.
     *
     * @return the initial random seed.
     */
    std::random_device::result_type seed() const;

    /** Provides a tensor shape for the specified image.
     *
     * @param[in] name Image file used to look up the raw tensor.
     *
     * @return the tensor shape for the specified image.
     */
    TensorShape get_image_shape(const std::string &name);

    /** Provides a constant raw tensor for the specified image.
     *
     * @param[in] name Image file used to look up the raw tensor.
     *
     * @return a raw tensor for the specified image.
     */
    const RawTensor &get(const std::string &name) const;

    /** Provides a raw tensor for the specified image.
     *
     * @param[in] name Image file used to look up the raw tensor.
     *
     * @return a raw tensor for the specified image.
     */
    RawTensor get(const std::string &name);

    /** Creates an uninitialised raw tensor with the given @p data_type and @p
     * num_channels. The shape is derived from the specified image.
     *
     * @param[in] name         Image file used to initialise the tensor.
     * @param[in] data_type    Data type used to initialise the tensor.
     * @param[in] num_channels Number of channels used to initialise the tensor.
     *
     * @return a raw tensor for the specified image.
     */
    RawTensor get(const std::string &name, DataType data_type, int num_channels = 1) const;

    /** Provides a contant raw tensor for the specified image after it has been
     * converted to @p format.
     *
     * @param[in] name   Image file used to look up the raw tensor.
     * @param[in] format Format used to look up the raw tensor.
     *
     * @return a raw tensor for the specified image.
     */
    const RawTensor &get(const std::string &name, Format format) const;

    /** Provides a raw tensor for the specified image after it has been
     * converted to @p format.
     *
     * @param[in] name   Image file used to look up the raw tensor.
     * @param[in] format Format used to look up the raw tensor.
     *
     * @return a raw tensor for the specified image.
     */
    RawTensor get(const std::string &name, Format format);

    /** Provides a contant raw tensor for the specified channel after it has
     * been extracted form the given image.
     *
     * @param[in] name    Image file used to look up the raw tensor.
     * @param[in] channel Channel used to look up the raw tensor.
     *
     * @note The channel has to be unambiguous so that the format can be
     *       inferred automatically.
     *
     * @return a raw tensor for the specified image channel.
     */
    const RawTensor &get(const std::string &name, Channel channel) const;

    /** Provides a raw tensor for the specified channel after it has been
     * extracted form the given image.
     *
     * @param[in] name    Image file used to look up the raw tensor.
     * @param[in] channel Channel used to look up the raw tensor.
     *
     * @note The channel has to be unambiguous so that the format can be
     *       inferred automatically.
     *
     * @return a raw tensor for the specified image channel.
     */
    RawTensor get(const std::string &name, Channel channel);

    /** Provides a constant raw tensor for the specified channel after it has
     * been extracted form the given image formatted to @p format.
     *
     * @param[in] name    Image file used to look up the raw tensor.
     * @param[in] format  Format used to look up the raw tensor.
     * @param[in] channel Channel used to look up the raw tensor.
     *
     * @return a raw tensor for the specified image channel.
     */
    const RawTensor &get(const std::string &name, Format format, Channel channel) const;

    /** Provides a raw tensor for the specified channel after it has been
     * extracted form the given image formatted to @p format.
     *
     * @param[in] name    Image file used to look up the raw tensor.
     * @param[in] format  Format used to look up the raw tensor.
     * @param[in] channel Channel used to look up the raw tensor.
     *
     * @return a raw tensor for the specified image channel.
     */
    RawTensor get(const std::string &name, Format format, Channel channel);

    /** Puts garbage values all around the tensor for testing purposes
     *
     * @param[in, out] tensor       To be filled tensor.
     * @param[in]      distribution Distribution used to fill the tensor's surroundings.
     * @param[in]      seed_offset  The offset will be added to the global seed before initialising the random generator.
     */
    template <typename T, typename D>
    void fill_borders_with_garbage(T &&tensor, D &&distribution, std::random_device::result_type seed_offset) const;

    /** Fills the specified @p tensor with random values drawn from @p
     * distribution.
     *
     * @param[in, out] tensor       To be filled tensor.
     * @param[in]      distribution Distribution used to fill the tensor.
     * @param[in]      seed_offset  The offset will be added to the global seed before initialising the random generator.
     *
     * @note The @p distribution has to provide operator(Generator &) which
     *       will be used to draw samples.
     */
    template <typename T, typename D>
    void fill(T &&tensor, D &&distribution, std::random_device::result_type seed_offset) const;

    template <typename T, typename D>
    void fill_boxes(T &&tensor, D &&distribution, std::random_device::result_type seed_offset) const;

    /** Fills the specified @p raw tensor with random values drawn from @p
     * distribution.
     *
     * @param[in, out] vec          To be filled vector.
     * @param[in]      distribution Distribution used to fill the tensor.
     * @param[in]      seed_offset  The offset will be added to the global seed before initialising the random generator.
     *
     * @note The @p distribution has to provide operator(Generator &) which
     *       will be used to draw samples.
     */
    template <typename T, typename D>
    void fill(std::vector<T> &vec, D &&distribution, std::random_device::result_type seed_offset) const;

    /** Fills the specified @p raw tensor with random values drawn from @p
     * distribution.
     *
     * @param[in, out] raw          To be filled raw.
     * @param[in]      distribution Distribution used to fill the tensor.
     * @param[in]      seed_offset  The offset will be added to the global seed before initialising the random generator.
     *
     * @note The @p distribution has to provide operator(Generator &) which
     *       will be used to draw samples.
     */
    template <typename D>
    void fill(RawTensor &raw, D &&distribution, std::random_device::result_type seed_offset) const;

    /** Fills the specified @p tensor with the content of the specified image
     * converted to the given format.
     *
     * @param[in, out] tensor To be filled tensor.
     * @param[in]      name   Image file used to fill the tensor.
     * @param[in]      format Format of the image used to fill the tensor.
     *
     * @warning No check is performed that the specified format actually
     *          matches the format of the tensor.
     */
    template <typename T>
    void fill(T &&tensor, const std::string &name, Format format) const;

    /** Fills the raw tensor with the content of the specified image
     * converted to the given format.
     *
     * @param[in, out] raw    To be filled raw tensor.
     * @param[in]      name   Image file used to fill the tensor.
     * @param[in]      format Format of the image used to fill the tensor.
     *
     * @warning No check is performed that the specified format actually
     *          matches the format of the tensor.
     */
    void fill(RawTensor &raw, const std::string &name, Format format) const;

    /** Fills the specified @p tensor with the content of the specified channel
     * extracted from the given image.
     *
     * @param[in, out] tensor  To be filled tensor.
     * @param[in]      name    Image file used to fill the tensor.
     * @param[in]      channel Channel of the image used to fill the tensor.
     *
     * @note The channel has to be unambiguous so that the format can be
     *       inferred automatically.
     *
     * @warning No check is performed that the specified format actually
     *          matches the format of the tensor.
     */
    template <typename T>
    void fill(T &&tensor, const std::string &name, Channel channel) const;

    /** Fills the raw tensor with the content of the specified channel
     * extracted from the given image.
     *
     * @param[in, out] raw     To be filled raw tensor.
     * @param[in]      name    Image file used to fill the tensor.
     * @param[in]      channel Channel of the image used to fill the tensor.
     *
     * @note The channel has to be unambiguous so that the format can be
     *       inferred automatically.
     *
     * @warning No check is performed that the specified format actually
     *          matches the format of the tensor.
     */
    void fill(RawTensor &raw, const std::string &name, Channel channel) const;

    /** Fills the specified @p tensor with the content of the specified channel
     * extracted from the given image after it has been converted to the given
     * format.
     *
     * @param[in, out] tensor  To be filled tensor.
     * @param[in]      name    Image file used to fill the tensor.
     * @param[in]      format  Format of the image used to fill the tensor.
     * @param[in]      channel Channel of the image used to fill the tensor.
     *
     * @warning No check is performed that the specified format actually
     *          matches the format of the tensor.
     */
    template <typename T>
    void fill(T &&tensor, const std::string &name, Format format, Channel channel) const;

    /** Fills the raw tensor with the content of the specified channel
     * extracted from the given image after it has been converted to the given
     * format.
     *
     * @param[in, out] raw     To be filled raw tensor.
     * @param[in]      name    Image file used to fill the tensor.
     * @param[in]      format  Format of the image used to fill the tensor.
     * @param[in]      channel Channel of the image used to fill the tensor.
     *
     * @warning No check is performed that the specified format actually
     *          matches the format of the tensor.
     */
    void fill(RawTensor &raw, const std::string &name, Format format, Channel channel) const;

    /** Fills the specified @p tensor with the content of the raw tensor.
     *
     * @param[in, out] tensor To be filled tensor.
     * @param[in]      raw    Raw tensor used to fill the tensor.
     *
     * @warning No check is performed that the specified format actually
     *          matches the format of the tensor.
     */
    template <typename T>
    void fill(T &&tensor, RawTensor raw) const;

    /** Fill a tensor with uniform distribution
     *
     * @param[in, out] tensor      To be filled tensor.
     * @param[in]      seed_offset The offset will be added to the global seed before initialising the random generator.
     */
    template <typename T>
    void fill_tensor_uniform(T &&tensor, std::random_device::result_type seed_offset) const;

    /** Fill a tensor with uniform distribution
     *
     * @param[in, out] tensor      To be filled tensor.
     * @param[in]      seed_offset The offset will be added to the global seed before initialising the random generator.
     * @param[in]      low         lowest value in the range (inclusive)
     * @param[in]      high        highest value in the range (inclusive)
     *
     * @note    @p low and @p high must be of the same type as the data type of @p tensor
     */
    template <typename T, typename D>
    void fill_tensor_uniform(T &&tensor, std::random_device::result_type seed_offset, D low, D high) const;

    /** Fill a tensor with uniform distribution across the specified range
     *
     * @param[in, out] tensor               To be filled tensor.
     * @param[in]      seed_offset          The offset will be added to the global seed before initialising the random generator.
     * @param[in]      excluded_range_pairs Ranges to exclude from the generator
     */
    template <typename T>
    void fill_tensor_uniform_ranged(T                                          &&tensor,
                                    std::random_device::result_type              seed_offset,
                                    const std::vector<AssetsLibrary::RangePair> &excluded_range_pairs) const;

    /** Fills the specified @p tensor with data loaded from .npy (numpy binary) in specified path.
     *
     * @param[in, out] tensor To be filled tensor.
     * @param[in]      name   Data file.
     *
     * @note The numpy array stored in the binary .npy file must be row-major in the sense that it
     * must store elements within a row consecutively in the memory, then rows within a 2D slice,
     * then 2D slices within a 3D slice and so on. Note that it imposes no restrictions on what
     * indexing convention is used in the numpy array. That is, the numpy array can be either fortran
     * style or C style as long as it adheres to the rule above.
     *
     * More concretely, the orders of dimensions for each style are as follows:
     * C-style (numpy default):
     *      array[HigherDims..., Z, Y, X]
     * Fortran style:
     *      array[X, Y, Z, HigherDims...]
     */
    template <typename T>
    void fill_layer_data(T &&tensor, std::string name) const;

    /** Fill a tensor with a constant value
     *
     * @param[in, out] tensor To be filled tensor.
     * @param[in]      value  Value to be assigned to all elements of the input tensor.
     *
     * @note    @p value must be of the same type as the data type of @p tensor
     */
    template <typename T, typename D>
    void fill_tensor_value(T &&tensor, D value) const;

    /** Fill a tensor with a given vector with static values.
     *
     * @param[in, out] tensor To be filled tensor.
     * @param[in]      values A vector containing values
     *
     * To cope with various size tensors, the vector size doens't have to be
     * the same as tensor's size. If the size of the tensor is larger than the vector,
     * the iterator the vector will keep iterating and wrap around. If the vector is
     * larger, values located after the required size won't be used.
     */
    template <typename T, typename DataType>
    void fill_static_values(T &&tensor, const std::vector<DataType> &values) const;

    // Function type to generate a number to fill tensors.
    template <typename ResultType>
    using GeneratorFunctionType = std::function<ResultType(void)>;
    /** Fill a tensor with a value generator function.
     *
     * @param[in, out] tensor         To be filled tensor.
     * @param[in]      generate_value A function that generates values.
     */
    template <typename T, typename ResultType>
    void fill_with_generator(T &&tensor, const GeneratorFunctionType<ResultType> &generate_value) const;

private:
    // Function prototype to convert between image formats.
    using Converter = void (*)(const RawTensor &src, RawTensor &dst);
    // Function prototype to extract a channel from an image.
    using Extractor = void (*)(const RawTensor &src, RawTensor &dst);
    // Function prototype to load an image file.
    using Loader = RawTensor (*)(const std::string &path);

    const Converter &get_converter(Format src, Format dst) const;
    const Converter &get_converter(DataType src, Format dst) const;
    const Converter &get_converter(Format src, DataType dst) const;
    const Converter &get_converter(DataType src, DataType dst) const;
    const Extractor &get_extractor(Format format, Channel) const;
    const Loader &get_loader(const std::string &extension) const;

    /** Creates a raw tensor from the specified image.
     *
     * @param[in] name To be loaded image file.
     *
     * @note If use_single_image is true @p name is ignored and the user image
     *       is loaded instead.
     */
    RawTensor load_image(const std::string &name) const;

    /** Provides a raw tensor for the specified image and format.
     *
     * @param[in] name   Image file used to look up the raw tensor.
     * @param[in] format Format used to look up the raw tensor.
     *
     * If the tensor has already been requested before the cached version will
     * be returned. Otherwise the tensor will be added to the cache.
     *
     * @note If use_single_image is true @p name is ignored and the user image
     *       is loaded instead.
     */
    const RawTensor &find_or_create_raw_tensor(const std::string &name, Format format) const;

    /** Provides a raw tensor for the specified image, format and channel.
     *
     * @param[in] name    Image file used to look up the raw tensor.
     * @param[in] format  Format used to look up the raw tensor.
     * @param[in] channel Channel used to look up the raw tensor.
     *
     * If the tensor has already been requested before the cached version will
     * be returned. Otherwise the tensor will be added to the cache.
     *
     * @note If use_single_image is true @p name is ignored and the user image
     *       is loaded instead.
     */
    const RawTensor &find_or_create_raw_tensor(const std::string &name, Format format, Channel channel) const;

    mutable TensorCache             _cache{};
    mutable arm_compute::Mutex      _format_lock{};
    mutable arm_compute::Mutex      _channel_lock{};
    const std::string               _library_path;
    std::random_device::result_type _seed;
};

namespace detail
{
template <typename T>
inline std::vector<std::pair<T, T>> convert_range_pair(const std::vector<AssetsLibrary::RangePair> &excluded_range_pairs)
{
    std::vector<std::pair<T, T>> converted;
    std::transform(excluded_range_pairs.begin(),
                   excluded_range_pairs.end(),
                   std::back_inserter(converted),
                   [](const AssetsLibrary::RangePair & p)
    {
        return std::pair<T, T>(static_cast<T>(p.first), static_cast<T>(p.second));
    });
    return converted;
}

/* Read npy header and check the payload is suitable for the specified type and shape
 *
 * @param[in] stream         ifstream of the npy file
 * @param[in] expect_typestr Expected typestr
 * @param[in] expect_shape   Shape of tensor expected to receive the data
 *
 * @note Advances stream to the beginning of the data payload
 */
void validate_npy_header(std::ifstream &stream, const std::string &expect_typestr, const TensorShape &expect_shape);
} // namespace detail

template <typename T, typename D>
void AssetsLibrary::fill_borders_with_garbage(T &&tensor, D &&distribution, std::random_device::result_type seed_offset) const
{
    const PaddingSize padding_size = tensor.padding();

    Window window;
    window.set(0, Window::Dimension(-padding_size.left, tensor.shape()[0] + padding_size.right, 1));
    if(tensor.shape().num_dimensions() > 1)
    {
        window.set(1, Window::Dimension(-padding_size.top, tensor.shape()[1] + padding_size.bottom, 1));
    }

    std::mt19937 gen(_seed + seed_offset);

    execute_window_loop(window, [&](const Coordinates & id)
    {
        TensorShape shape = tensor.shape();

        // If outside of valid region
        if(id.x() < 0 || id.x() >= static_cast<int>(shape.x()) || id.y() < 0 || id.y() >= static_cast<int>(shape.y()))
        {
            using ResultType         = typename std::remove_reference<D>::type::result_type;
            const ResultType value   = distribution(gen);
            void *const      out_ptr = tensor(id);
            store_value_with_data_type(out_ptr, value, tensor.data_type());
        }
    });
}

template <typename T, typename D>
void AssetsLibrary::fill_boxes(T &&tensor, D &&distribution, std::random_device::result_type seed_offset) const
{
    using DistributionType = typename std::remove_reference<D>::type;
    using ResultType       = typename DistributionType::result_type;

    std::mt19937   gen(_seed + seed_offset);
    TensorShape    shape(tensor.shape());
    const uint32_t num_boxes = tensor.num_elements() / 4;
    // Iterate over all elements
    DistributionType size_dist{ ResultType(0.f), ResultType(1.f) };
    for(uint32_t element_idx = 0; element_idx < num_boxes * 4; element_idx += 4)
    {
        const ResultType delta   = size_dist(gen);
        const ResultType epsilon = size_dist(gen);
        const ResultType left    = distribution(gen);
        const ResultType top     = distribution(gen);
        const ResultType right   = left + delta;
        const ResultType bottom  = top + epsilon;
        const std::tuple<ResultType, ResultType, ResultType, ResultType> box(left, top, right, bottom);
        Coordinates x1              = index2coord(shape, element_idx);
        Coordinates y1              = index2coord(shape, element_idx + 1);
        Coordinates x2              = index2coord(shape, element_idx + 2);
        Coordinates y2              = index2coord(shape, element_idx + 3);
        ResultType &target_value_x1 = reinterpret_cast<ResultType *>(tensor(x1))[0];
        ResultType &target_value_y1 = reinterpret_cast<ResultType *>(tensor(y1))[0];
        ResultType &target_value_x2 = reinterpret_cast<ResultType *>(tensor(x2))[0];
        ResultType &target_value_y2 = reinterpret_cast<ResultType *>(tensor(y2))[0];
        store_value_with_data_type(&target_value_x1, std::get<0>(box), tensor.data_type());
        store_value_with_data_type(&target_value_y1, std::get<1>(box), tensor.data_type());
        store_value_with_data_type(&target_value_x2, std::get<2>(box), tensor.data_type());
        store_value_with_data_type(&target_value_y2, std::get<3>(box), tensor.data_type());
    }
    fill_borders_with_garbage(tensor, distribution, seed_offset);
}

template <typename T, typename D>
void AssetsLibrary::fill(std::vector<T> &vec, D &&distribution, std::random_device::result_type seed_offset) const
{
    ARM_COMPUTE_ERROR_ON_MSG(vec.empty(), "Vector must not be empty");

    using ResultType = typename std::remove_reference<D>::type::result_type;

    std::mt19937 gen(_seed + seed_offset);
    for(size_t i = 0; i < vec.size(); ++i)
    {
        const ResultType value = distribution(gen);

        vec[i] = value;
    }
}

template <typename T, typename ResultType>
void AssetsLibrary::fill_with_generator(T &&tensor, const GeneratorFunctionType<ResultType> &generate_value) const
{
    const bool  is_nhwc = tensor.data_layout() == DataLayout::NHWC;
    TensorShape shape(tensor.shape());

    if(is_nhwc)
    {
        // Ensure that the equivalent tensors will be filled for both data layouts
        permute(shape, PermutationVector(1U, 2U, 0U));
    }

    // Iterate over all elements
    const uint32_t num_elements = tensor.num_elements();
    for(uint32_t element_idx = 0; element_idx < num_elements; ++element_idx)
    {
        Coordinates id = index2coord(shape, element_idx);

        if(is_nhwc)
        {
            // Write in the correct id for permuted shapes
            permute(id, PermutationVector(2U, 0U, 1U));
        }

        // Iterate over all channels
        for(int channel = 0; channel < tensor.num_channels(); ++channel)
        {
            const ResultType value        = generate_value();
            ResultType      &target_value = reinterpret_cast<ResultType *>(tensor(id))[channel];

            store_value_with_data_type(&target_value, value, tensor.data_type());
        }
    }
}

template <typename T, typename D>
void AssetsLibrary::fill(T &&tensor, D &&distribution, std::random_device::result_type seed_offset) const
{
    using ResultType = typename std::remove_reference<D>::type::result_type;
    std::mt19937 gen(_seed + seed_offset);

    GeneratorFunctionType<ResultType> number_generator = [&]()
    {
        const ResultType value = distribution(gen);
        return value;
    };

    fill_with_generator(tensor, number_generator);
    fill_borders_with_garbage(tensor, distribution, seed_offset);
}

template <typename T, typename DataType>
void AssetsLibrary::fill_static_values(T &&tensor, const std::vector<DataType> &values) const
{
    auto                            it             = values.begin();
    GeneratorFunctionType<DataType> get_next_value = [&]()
    {
        const DataType value = *it;
        ++it;

        if(it == values.end())
        {
            it = values.begin();
        }

        return value;
    };

    fill_with_generator(tensor, get_next_value);
}

template <typename D>
void AssetsLibrary::fill(RawTensor &raw, D &&distribution, std::random_device::result_type seed_offset) const
{
    std::mt19937 gen(_seed + seed_offset);

    for(size_t offset = 0; offset < raw.size(); offset += raw.element_size())
    {
        using ResultType       = typename std::remove_reference<D>::type::result_type;
        const ResultType value = distribution(gen);

        store_value_with_data_type(raw.data() + offset, value, raw.data_type());
    }
}

template <typename T>
void AssetsLibrary::fill(T &&tensor, const std::string &name, Format format) const
{
    const RawTensor &raw = get(name, format);

    for(size_t offset = 0; offset < raw.size(); offset += raw.element_size())
    {
        const Coordinates id = index2coord(raw.shape(), offset / raw.element_size());

        const RawTensor::value_type *const raw_ptr = raw.data() + offset;
        const auto                         out_ptr = static_cast<RawTensor::value_type *>(tensor(id));
        std::copy_n(raw_ptr, raw.element_size(), out_ptr);
    }
}

template <typename T>
void AssetsLibrary::fill(T &&tensor, const std::string &name, Channel channel) const
{
    fill(std::forward<T>(tensor), name, get_format_for_channel(channel), channel);
}

template <typename T>
void AssetsLibrary::fill(T &&tensor, const std::string &name, Format format, Channel channel) const
{
    const RawTensor &raw = get(name, format, channel);

    for(size_t offset = 0; offset < raw.size(); offset += raw.element_size())
    {
        const Coordinates id = index2coord(raw.shape(), offset / raw.element_size());

        const RawTensor::value_type *const raw_ptr = raw.data() + offset;
        const auto                         out_ptr = static_cast<RawTensor::value_type *>(tensor(id));
        std::copy_n(raw_ptr, raw.element_size(), out_ptr);
    }
}

template <typename T>
void AssetsLibrary::fill(T &&tensor, RawTensor raw) const
{
    for(size_t offset = 0; offset < raw.size(); offset += raw.element_size())
    {
        const Coordinates id = index2coord(raw.shape(), offset / raw.element_size());

        const RawTensor::value_type *const raw_ptr = raw.data() + offset;
        const auto                         out_ptr = static_cast<RawTensor::value_type *>(tensor(id));
        std::copy_n(raw_ptr, raw.element_size(), out_ptr);
    }
}

template <typename T>
void AssetsLibrary::fill_tensor_uniform(T &&tensor, std::random_device::result_type seed_offset) const
{
    switch(tensor.data_type())
    {
        case DataType::U8:
        case DataType::QASYMM8:
        {
            std::uniform_int_distribution<unsigned int> distribution_u8(std::numeric_limits<uint8_t>::lowest(), std::numeric_limits<uint8_t>::max());
            fill(tensor, distribution_u8, seed_offset);
            break;
        }
        case DataType::S8:
        case DataType::QSYMM8:
        case DataType::QSYMM8_PER_CHANNEL:
        case DataType::QASYMM8_SIGNED:
        {
            std::uniform_int_distribution<int> distribution_s8(std::numeric_limits<int8_t>::lowest(), std::numeric_limits<int8_t>::max());
            fill(tensor, distribution_s8, seed_offset);
            break;
        }
        case DataType::U16:
        {
            std::uniform_int_distribution<uint16_t> distribution_u16(std::numeric_limits<uint16_t>::lowest(), std::numeric_limits<uint16_t>::max());
            fill(tensor, distribution_u16, seed_offset);
            break;
        }
        case DataType::S16:
        case DataType::QSYMM16:
        {
            std::uniform_int_distribution<int16_t> distribution_s16(std::numeric_limits<int16_t>::lowest(), std::numeric_limits<int16_t>::max());
            fill(tensor, distribution_s16, seed_offset);
            break;
        }
        case DataType::U32:
        {
            std::uniform_int_distribution<uint32_t> distribution_u32(std::numeric_limits<uint32_t>::lowest(), std::numeric_limits<uint32_t>::max());
            fill(tensor, distribution_u32, seed_offset);
            break;
        }
        case DataType::S32:
        {
            std::uniform_int_distribution<int32_t> distribution_s32(std::numeric_limits<int32_t>::lowest(), std::numeric_limits<int32_t>::max());
            fill(tensor, distribution_s32, seed_offset);
            break;
        }
        case DataType::U64:
        {
            std::uniform_int_distribution<uint64_t> distribution_u64(std::numeric_limits<uint64_t>::lowest(), std::numeric_limits<uint64_t>::max());
            fill(tensor, distribution_u64, seed_offset);
            break;
        }
        case DataType::S64:
        {
            std::uniform_int_distribution<int64_t> distribution_s64(std::numeric_limits<int64_t>::lowest(), std::numeric_limits<int64_t>::max());
            fill(tensor, distribution_s64, seed_offset);
            break;
        }
        case DataType::BFLOAT16:
        {
            // It doesn't make sense to check [-inf, inf], so hard code it to a big number
            arm_compute::utils::uniform_real_distribution_16bit<bfloat16> distribution_bf16{ -1000.f, 1000.f };
            fill(tensor, distribution_bf16, seed_offset);
            break;
        }
        case DataType::F16:
        {
            // It doesn't make sense to check [-inf, inf], so hard code it to a big number
            arm_compute::utils::uniform_real_distribution_16bit<half> distribution_f16{ -100.f, 100.f };
            fill(tensor, distribution_f16, seed_offset);
            break;
        }
        case DataType::F32:
        {
            // It doesn't make sense to check [-inf, inf], so hard code it to a big number
            std::uniform_real_distribution<float> distribution_f32(-1000.f, 1000.f);
            fill(tensor, distribution_f32, seed_offset);
            break;
        }
        case DataType::F64:
        {
            // It doesn't make sense to check [-inf, inf], so hard code it to a big number
            std::uniform_real_distribution<double> distribution_f64(-1000.f, 1000.f);
            fill(tensor, distribution_f64, seed_offset);
            break;
        }
        case DataType::SIZET:
        {
            std::uniform_int_distribution<size_t> distribution_sizet(std::numeric_limits<size_t>::lowest(), std::numeric_limits<size_t>::max());
            fill(tensor, distribution_sizet, seed_offset);
            break;
        }
        default:
            ARM_COMPUTE_ERROR("NOT SUPPORTED!");
    }
}

template <typename T>
void AssetsLibrary::fill_tensor_uniform_ranged(T                                          &&tensor,
                                               std::random_device::result_type              seed_offset,
                                               const std::vector<AssetsLibrary::RangePair> &excluded_range_pairs) const
{
    using namespace arm_compute::utils::random;

    switch(tensor.data_type())
    {
        case DataType::U8:
        case DataType::QASYMM8:
        {
            const auto                          converted_pairs = detail::convert_range_pair<uint32_t>(excluded_range_pairs);
            RangedUniformDistribution<uint32_t> distribution_u8(std::numeric_limits<uint8_t>::lowest(),
                                                                std::numeric_limits<uint8_t>::max(),
                                                                converted_pairs);
            fill(tensor, distribution_u8, seed_offset);
            break;
        }
        case DataType::S8:
        case DataType::QSYMM8:
        {
            const auto                         converted_pairs = detail::convert_range_pair<int32_t>(excluded_range_pairs);
            RangedUniformDistribution<int32_t> distribution_s8(std::numeric_limits<int8_t>::lowest(),
                                                               std::numeric_limits<int8_t>::max(),
                                                               converted_pairs);
            fill(tensor, distribution_s8, seed_offset);
            break;
        }
        case DataType::U16:
        {
            const auto                          converted_pairs = detail::convert_range_pair<uint16_t>(excluded_range_pairs);
            RangedUniformDistribution<uint16_t> distribution_u16(std::numeric_limits<uint16_t>::lowest(),
                                                                 std::numeric_limits<uint16_t>::max(),
                                                                 converted_pairs);
            fill(tensor, distribution_u16, seed_offset);
            break;
        }
        case DataType::S16:
        case DataType::QSYMM16:
        {
            const auto                         converted_pairs = detail::convert_range_pair<int16_t>(excluded_range_pairs);
            RangedUniformDistribution<int16_t> distribution_s16(std::numeric_limits<int16_t>::lowest(),
                                                                std::numeric_limits<int16_t>::max(),
                                                                converted_pairs);
            fill(tensor, distribution_s16, seed_offset);
            break;
        }
        case DataType::U32:
        {
            const auto                          converted_pairs = detail::convert_range_pair<uint32_t>(excluded_range_pairs);
            RangedUniformDistribution<uint32_t> distribution_u32(std::numeric_limits<uint32_t>::lowest(),
                                                                 std::numeric_limits<uint32_t>::max(),
                                                                 converted_pairs);
            fill(tensor, distribution_u32, seed_offset);
            break;
        }
        case DataType::S32:
        {
            const auto                         converted_pairs = detail::convert_range_pair<int32_t>(excluded_range_pairs);
            RangedUniformDistribution<int32_t> distribution_s32(std::numeric_limits<int32_t>::lowest(),
                                                                std::numeric_limits<int32_t>::max(),
                                                                converted_pairs);
            fill(tensor, distribution_s32, seed_offset);
            break;
        }
        case DataType::BFLOAT16:
        {
            // It doesn't make sense to check [-inf, inf], so hard code it to a big number
            const auto                          converted_pairs = detail::convert_range_pair<bfloat16>(excluded_range_pairs);
            RangedUniformDistribution<bfloat16> distribution_bf16(bfloat16(-1000.f), bfloat16(1000.f), converted_pairs);
            fill(tensor, distribution_bf16, seed_offset);
            break;
        }
        case DataType::F16:
        {
            // It doesn't make sense to check [-inf, inf], so hard code it to a big number
            const auto                      converted_pairs = detail::convert_range_pair<half>(excluded_range_pairs);
            RangedUniformDistribution<half> distribution_f16(half(-100.f), half(100.f), converted_pairs);
            fill(tensor, distribution_f16, seed_offset);
            break;
        }
        case DataType::F32:
        {
            // It doesn't make sense to check [-inf, inf], so hard code it to a big number
            const auto                       converted_pairs = detail::convert_range_pair<float>(excluded_range_pairs);
            RangedUniformDistribution<float> distribution_f32(-1000.f, 1000.f, converted_pairs);
            fill(tensor, distribution_f32, seed_offset);
            break;
        }
        default:
            ARM_COMPUTE_ERROR("NOT SUPPORTED!");
    }
}

template <typename T, typename D>
void AssetsLibrary::fill_tensor_uniform(T &&tensor, std::random_device::result_type seed_offset, D low, D high) const
{
    switch(tensor.data_type())
    {
        case DataType::U8:
        case DataType::QASYMM8:
        {
            ARM_COMPUTE_ERROR_ON(!(std::is_same<uint8_t, D>::value));
            std::uniform_int_distribution<uint32_t> distribution_u8(low, high);
            fill(tensor, distribution_u8, seed_offset);
            break;
        }
        case DataType::S8:
        case DataType::QSYMM8:
        case DataType::QASYMM8_SIGNED:
        {
            ARM_COMPUTE_ERROR_ON(!(std::is_same<int8_t, D>::value));
            std::uniform_int_distribution<int32_t> distribution_s8(low, high);
            fill(tensor, distribution_s8, seed_offset);
            break;
        }
        case DataType::U16:
        {
            ARM_COMPUTE_ERROR_ON(!(std::is_same<uint16_t, D>::value));
            std::uniform_int_distribution<uint16_t> distribution_u16(low, high);
            fill(tensor, distribution_u16, seed_offset);
            break;
        }
        case DataType::S16:
        case DataType::QSYMM16:
        {
            ARM_COMPUTE_ERROR_ON(!(std::is_same<int16_t, D>::value));
            std::uniform_int_distribution<int16_t> distribution_s16(low, high);
            fill(tensor, distribution_s16, seed_offset);
            break;
        }
        case DataType::U32:
        {
            ARM_COMPUTE_ERROR_ON(!(std::is_same<uint32_t, D>::value));
            std::uniform_int_distribution<uint32_t> distribution_u32(low, high);
            fill(tensor, distribution_u32, seed_offset);
            break;
        }
        case DataType::S32:
        {
            ARM_COMPUTE_ERROR_ON(!(std::is_same<int32_t, D>::value));
            std::uniform_int_distribution<int32_t> distribution_s32(low, high);
            fill(tensor, distribution_s32, seed_offset);
            break;
        }
        case DataType::U64:
        {
            ARM_COMPUTE_ERROR_ON(!(std::is_same<uint64_t, D>::value));
            std::uniform_int_distribution<uint64_t> distribution_u64(low, high);
            fill(tensor, distribution_u64, seed_offset);
            break;
        }
        case DataType::S64:
        {
            ARM_COMPUTE_ERROR_ON(!(std::is_same<int64_t, D>::value));
            std::uniform_int_distribution<int64_t> distribution_s64(low, high);
            fill(tensor, distribution_s64, seed_offset);
            break;
        }
        case DataType::BFLOAT16:
        {
            arm_compute::utils::uniform_real_distribution_16bit<bfloat16> distribution_bf16{ float(low), float(high) };
            fill(tensor, distribution_bf16, seed_offset);
            break;
        }
        case DataType::F16:
        {
            arm_compute::utils::uniform_real_distribution_16bit<half> distribution_f16{ float(low), float(high) };
            fill(tensor, distribution_f16, seed_offset);
            break;
        }
        case DataType::F32:
        {
            ARM_COMPUTE_ERROR_ON(!(std::is_same<float, D>::value));
            std::uniform_real_distribution<float> distribution_f32(low, high);
            fill(tensor, distribution_f32, seed_offset);
            break;
        }
        case DataType::F64:
        {
            ARM_COMPUTE_ERROR_ON(!(std::is_same<double, D>::value));
            std::uniform_real_distribution<double> distribution_f64(low, high);
            fill(tensor, distribution_f64, seed_offset);
            break;
        }
        case DataType::SIZET:
        {
            ARM_COMPUTE_ERROR_ON(!(std::is_same<size_t, D>::value));
            std::uniform_int_distribution<size_t> distribution_sizet(low, high);
            fill(tensor, distribution_sizet, seed_offset);
            break;
        }
        default:
            ARM_COMPUTE_ERROR("NOT SUPPORTED!");
    }
}

template <typename T>
void AssetsLibrary::fill_layer_data(T &&tensor, std::string name) const
{
#ifdef _WIN32
    const std::string path_separator("\\");
#else  /* _WIN32 */
    const std::string path_separator("/");
#endif /* _WIN32 */
    const std::string path = _library_path + path_separator + name;

    // Open file
    std::ifstream stream(path, std::ios::in | std::ios::binary);
    if(!stream.good())
    {
        throw framework::FileNotFound("Could not load npy file: " + path);
    }

    validate_npy_header(stream, tensor.data_type(), tensor.shape());

    // Read data
    if(tensor.padding().empty())
    {
        // If tensor has no padding read directly from stream.
        stream.read(reinterpret_cast<char *>(tensor.data()), tensor.size());
    }
    else
    {
        // If tensor has padding accessing tensor elements through execution window.
        Window window;
        window.use_tensor_dimensions(tensor.shape());

        execute_window_loop(window, [&](const Coordinates & id)
        {
            stream.read(reinterpret_cast<char *>(tensor(id)), tensor.element_size());
        });
    }
}

template <typename T, typename D>
void AssetsLibrary::fill_tensor_value(T &&tensor, D value) const
{
    fill_tensor_uniform(tensor, 0, value, value);
}
} // namespace test
} // namespace arm_compute
#endif /* ARM_COMPUTE_TEST_TENSOR_LIBRARY_H */
