/*
 * Copyright (c) 2018-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.
 */
#include "src/cpu/kernels/CpuPermuteKernel.h"

#include "arm_compute/core/Error.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/ITensor.h"
#include "arm_compute/core/TensorInfo.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/core/utils/misc/ShapeCalculator.h"
#include "arm_compute/core/Validate.h"

#include "src/core/helpers/AutoConfiguration.h"
#include "src/core/helpers/WindowHelpers.h"

namespace
{
#include "src/core/NEON/kernels/convolution/common/shims.hpp"
} // namespace

namespace arm_compute
{
namespace cpu
{
namespace kernels
{
namespace
{
inline bool is_permutation_supported(const PermutationVector &v)
{
    static const std::array<PermutationVector, 2>  permutations2 = {{
         PermutationVector(0U, 1U),
         PermutationVector(1U, 0U),
    }};
    static const std::array<PermutationVector, 6>  permutations3 = {{
         PermutationVector(2U, 0U, 1U),
         PermutationVector(1U, 2U, 0U),
         PermutationVector(0U, 1U, 2U),
         PermutationVector(0U, 2U, 1U),
         PermutationVector(1U, 0U, 2U),
         PermutationVector(2U, 1U, 0U),
    }};
    static const std::array<PermutationVector, 24> permutations4 = {
        {PermutationVector(0U, 1U, 2U, 3U), PermutationVector(1U, 0U, 2U, 3U), PermutationVector(2U, 0U, 1U, 3U),
         PermutationVector(0U, 2U, 1U, 3U), PermutationVector(1U, 2U, 0U, 3U), PermutationVector(2U, 1U, 0U, 3U),
         PermutationVector(2U, 1U, 3U, 0U), PermutationVector(1U, 2U, 3U, 0U), PermutationVector(3U, 2U, 1U, 0U),
         PermutationVector(2U, 3U, 1U, 0U), PermutationVector(1U, 3U, 2U, 0U), PermutationVector(3U, 1U, 2U, 0U),
         PermutationVector(3U, 0U, 2U, 1U), PermutationVector(0U, 3U, 2U, 1U), PermutationVector(2U, 3U, 0U, 1U),
         PermutationVector(3U, 2U, 0U, 1U), PermutationVector(0U, 2U, 3U, 1U), PermutationVector(2U, 0U, 3U, 1U),
         PermutationVector(1U, 0U, 3U, 2U), PermutationVector(0U, 1U, 3U, 2U), PermutationVector(3U, 1U, 0U, 2U),
         PermutationVector(1U, 3U, 0U, 2U), PermutationVector(0U, 3U, 1U, 2U), PermutationVector(3U, 0U, 1U, 2U)}};

    return (permutations2.end() != std::find(permutations2.begin(), permutations2.end(), v)) ||
           (permutations3.end() != std::find(permutations3.begin(), permutations3.end(), v)) ||
           (permutations4.end() != std::find(permutations4.begin(), permutations4.end(), v));
}

Status validate_arguments(const ITensorInfo *src, const ITensorInfo *dst, const PermutationVector &perm)
{
    ARM_COMPUTE_RETURN_ERROR_ON(src->data_type() == DataType::UNKNOWN);
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(!is_permutation_supported(perm), "PermutationVector not supported.");

    const TensorShape dst_shape = misc::shape_calculator::compute_permutation_output_shape(*src, perm);

    // Validate configured destination
    if (dst->total_size() != 0)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(dst->tensor_shape(), dst_shape);
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_QUANTIZATION_INFO(src, dst);
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(src, dst);
    }

    return Status{};
}

template <typename T>
void run_permute(const Window &window, const ITensor *src, const ITensor *dst, const PermutationVector &perm)
{
    const DataLayout src_layout = src->info()->data_layout();

    // Source window
    Window window_src = window;

    // we only support these two configs in src/core/NEON/kernels/convolution/common/shims.hpp, for all others
    // we have to fall back to C++
    if ((src_layout == DataLayout::NCHW && perm == PermutationVector{2U, 0U, 1U}) ||
        (src_layout == DataLayout::NHWC && perm == PermutationVector{1U, 2U, 0U}))
    {
        window_src.set(Window::DimX,
                       Window::Dimension(window.x().start(), window.x().end(), window.x().end() - window.x().start()));
        window_src.set(Window::DimY,
                       Window::Dimension(window.y().start(), window.y().end(), window.y().end() - window.y().start()));
        window_src.set(Window::DimZ,
                       Window::Dimension(window.z().start(), window.z().end(), window.z().end() - window.z().start()));
        window_src.set(3, Window::Dimension(window[3].start(), window[3].end(), window[3].end() - window[3].start()));
    }

    // Destination window
    Window                  window_dst(window);
    const Window::Dimension zero_window = Window::Dimension(0, 0, 0);
    for (size_t d = 0; d <= dst->info()->num_dimensions(); ++d)
    {
        window_dst.set(d, zero_window);
    }

    // Create iterators
    Iterator src_it(src, window_src);
    Iterator dst_it(dst, window_dst);

    int in_row_stride     = 0;
    int in_col_stride     = 0;
    int in_channel_stride = 0;
    int in_batch_stride   = 0;
    int n_cols            = 0;
    int n_rows            = 0;
    int n_channels        = 0;
    int n_batches         = 0;

    switch (src_layout)
    {
        case DataLayout::NCHW:
        {
            in_row_stride     = src->info()->strides_in_bytes().y() / sizeof(T);
            in_channel_stride = src->info()->strides_in_bytes().z() / sizeof(T);
            in_batch_stride   = src->info()->strides_in_bytes()[3] / sizeof(T);
            n_cols            = src->info()->tensor_shape().x();
            n_rows            = window_src.y().step();
            n_channels        = src->info()->tensor_shape().z();
            n_batches         = src->info()->tensor_shape()[3];
            break;
        }
        case DataLayout::NHWC:
        {
            in_col_stride   = src->info()->strides_in_bytes().y() / sizeof(T);
            in_row_stride   = src->info()->strides_in_bytes().z() / sizeof(T);
            in_batch_stride = src->info()->strides_in_bytes()[3] / sizeof(T);
            n_channels      = src->info()->tensor_shape().x();
            n_cols          = window_src.y().step();
            n_rows          = src->info()->tensor_shape().z();
            n_batches       = src->info()->tensor_shape()[3];
            break;
        }
        default:
        {
            ARM_COMPUTE_ERROR("Invalid source data layout.");
            break;
        }
    }

    // CHW -> HWC
    if (src_layout == DataLayout::NCHW && perm == PermutationVector{2U, 0U, 1U})
    {
        const int out_channel_stride = dst->info()->strides_in_bytes().x() / sizeof(T);
        const int out_col_stride     = dst->info()->strides_in_bytes().y() / sizeof(T);
        const int out_row_stride     = dst->info()->strides_in_bytes().z() / sizeof(T);
        const int out_batch_stride   = dst->info()->strides_in_bytes()[3] / sizeof(T);
        execute_window_loop(
            window_src,
            [&](const Coordinates &id)
            {
                const int idx = id[0] * out_col_stride + id[1] * out_row_stride + id[2] * out_channel_stride;
                reorder::nchw_to_nhwc(reinterpret_cast<const T *>(src_it.ptr()),
                                      reinterpret_cast<T *>(dst_it.ptr()) + idx, n_batches, n_channels, n_rows, n_cols,
                                      in_batch_stride, in_channel_stride, in_row_stride, out_batch_stride,
                                      out_row_stride, out_col_stride);
            },
            src_it, dst_it);
    }
    // HWC -> CHW
    else if (src_layout == DataLayout::NHWC && perm == PermutationVector{1U, 2U, 0U})
    {
        const int out_col_stride     = dst->info()->strides_in_bytes().x() / sizeof(T);
        const int out_row_stride     = dst->info()->strides_in_bytes().y() / sizeof(T);
        const int out_channel_stride = dst->info()->strides_in_bytes().z() / sizeof(T);
        const int out_batch_stride   = dst->info()->strides_in_bytes()[3] / sizeof(T);
        execute_window_loop(
            window_src,
            [&](const Coordinates &id)
            {
                const int idx = id[0] * out_channel_stride + id[1] * out_col_stride + id[2] * out_row_stride;
                reorder::nhwc_to_nchw(reinterpret_cast<const T *>(src_it.ptr()),
                                      reinterpret_cast<T *>(dst_it.ptr()) + idx, n_batches, n_rows, n_cols, n_channels,
                                      in_batch_stride, in_row_stride, in_col_stride, out_batch_stride,
                                      out_channel_stride, out_row_stride);
            },
            src_it, dst_it);
    }
    else
    {
        // All other cases fall back to C++
        // Permute strides
        Strides strides      = dst->info()->strides_in_bytes();
        Strides perm_strides = strides;
        permute_strides(perm_strides, perm);
        const int perm_stride_3 = src->info()->num_dimensions() >= 4 ? perm_strides[3] : 0;
        execute_window_loop(
            window,
            [&](const Coordinates &id)
            {
                const int idx =
                    id[0] * perm_strides[0] + id[1] * perm_strides[1] + id[2] * perm_strides[2] + id[3] * perm_stride_3;
                *(reinterpret_cast<T *>(dst_it.ptr() + idx)) = *(reinterpret_cast<const T *>(src_it.ptr()));
            },
            src_it, dst_it);
    }
}
} // namespace

void CpuPermuteKernel::configure(const ITensorInfo *src, ITensorInfo *dst, const PermutationVector &perm)
{
    ARM_COMPUTE_ERROR_ON_NULLPTR(src, dst);
    const TensorShape dst_shape = misc::shape_calculator::compute_permutation_output_shape(*src, perm);
    // Destination auto inizialitation if not yet initialized
    auto_init_if_empty(*dst, src->clone()->set_tensor_shape(dst_shape));

    // Perform validation step
    ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(src, dst, perm));

    _perm = perm;

    // Configure kernel window
    Window win = calculate_max_window(*src, Steps());

    // This kernel doesn't need padding so update_window_and_padding() can be skipped

    ICpuKernel::configure(win);
}

Status CpuPermuteKernel::validate(const ITensorInfo *src, const ITensorInfo *dst, const PermutationVector &perm)
{
    ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(src, dst, perm));
    return Status{};
}

void CpuPermuteKernel::run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info)
{
    ARM_COMPUTE_UNUSED(info);
    ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this);
    ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(ICpuKernel::window(), window);

    const auto src = tensors.get_const_tensor(TensorType::ACL_SRC);
    auto       dst = tensors.get_tensor(TensorType::ACL_DST);

    switch (src->info()->element_size())
    {
        case 1:
            run_permute<uint8_t>(window, src, dst, _perm);
            break;
        case 2:
            run_permute<uint16_t>(window, src, dst, _perm);
            break;
        case 4:
            run_permute<uint32_t>(window, src, dst, _perm);
            break;
        default:
            ARM_COMPUTE_ERROR("Element size not supported");
            break;
    }
}

const char *CpuPermuteKernel::name() const
{
    return "CpuPermuteKernel";
}
} // namespace kernels
} // namespace cpu
} // namespace arm_compute
