/*
 * Copyright (c) 2020-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/core/NEON/kernels/NELogicalKernel.h"

#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/Validate.h"

#include "src/common/utils/Validate.h"
#include "src/core/helpers/AutoConfiguration.h"
#include "src/core/helpers/WindowHelpers.h"

#include <arm_neon.h>

namespace arm_compute
{
namespace kernels
{
namespace
{
static const uint8x8_t  c0_x8     = vdup_n_u8(0);
static const uint8x16_t c0_x16    = vdupq_n_u8(0);
static const uint8x8_t  c1_x8     = vdup_n_u8(1);
static const uint8x16_t c1_x16    = vdupq_n_u8(1);
static const uint32_t   step      = 16;
static const uint32_t   half_step = step / 2;

void neon_logical_and(const uint8_t *src0, const uint8_t *src1, uint8_t *dst, uint32_t len)
{
    ARM_COMPUTE_ASSERT_NOT_NULLPTR(src0);
    ARM_COMPUTE_ASSERT_NOT_NULLPTR(src1);
    ARM_COMPUTE_ASSERT_NOT_NULLPTR(dst);

    for (; len >= step; len -= step)
    {
        vst1q_u8(dst, vandq_u8(vminq_u8(vld1q_u8(src0), c1_x16), vminq_u8(vld1q_u8(src1), c1_x16)));
        src0 += step;
        src1 += step;
        dst += step;
    }

    for (; len >= half_step; len -= half_step)
    {
        vst1_u8(dst, vand_u8(vmin_u8(vld1_u8(src0), c1_x8), vmin_u8(vld1_u8(src1), c1_x8)));
        src0 += half_step;
        src1 += half_step;
        dst += half_step;
    }

    for (; len > 0; --len)
    {
        *dst = (*src0) && (*src1);
        ++src0;
        ++src1;
        ++dst;
    }
}

void neon_logical_and_broadcast(const uint8_t *src, uint8_t broadcast_val, uint8_t *dst, uint32_t len)
{
    ARM_COMPUTE_ASSERT_NOT_NULLPTR(src);
    ARM_COMPUTE_ASSERT_NOT_NULLPTR(dst);

    const auto broadcast_val_clamped_s   = std::min<uint8_t>(broadcast_val, 1);
    const auto broadcast_val_clamped_x16 = vdupq_n_u8(broadcast_val_clamped_s);
    const auto broadcast_val_clamped_x8  = vdup_n_u8(broadcast_val_clamped_s);

    for (; len >= step; len -= step)
    {
        vst1q_u8(dst, vandq_u8(vminq_u8(vld1q_u8(src), c1_x16), broadcast_val_clamped_x16));
        src += step;
        dst += step;
    }

    for (; len >= half_step; len -= half_step)
    {
        vst1_u8(dst, vand_u8(vmin_u8(vld1_u8(src), c1_x8), broadcast_val_clamped_x8));
        src += half_step;
        dst += half_step;
    }

    for (; len > 0; --len)
    {
        *dst = (*src) && broadcast_val_clamped_s;
        ++src;
        ++dst;
    }
}

void neon_logical_or(const uint8_t *src0, const uint8_t *src1, uint8_t *dst, uint32_t len)
{
    ARM_COMPUTE_ASSERT_NOT_NULLPTR(src0);
    ARM_COMPUTE_ASSERT_NOT_NULLPTR(src1);
    ARM_COMPUTE_ASSERT_NOT_NULLPTR(dst);

    for (; len >= step; len -= step)
    {
        vst1q_u8(dst, vorrq_u8(vminq_u8(vld1q_u8(src0), c1_x16), vminq_u8(vld1q_u8(src1), c1_x16)));
        src0 += step;
        src1 += step;
        dst += step;
    }

    for (; len >= half_step; len -= half_step)
    {
        vst1_u8(dst, vorr_u8(vmin_u8(vld1_u8(src0), c1_x8), vmin_u8(vld1_u8(src1), c1_x8)));
        src0 += half_step;
        src1 += half_step;
        dst += half_step;
    }

    for (; len > 0; --len)
    {
        *dst = (*src0) || (*src1);
        ++src0;
        ++src1;
        ++dst;
    }
}

void neon_logical_or_broadcast(const uint8_t *src, uint8_t broadcast_val, uint8_t *dst, uint32_t len)
{
    ARM_COMPUTE_ASSERT_NOT_NULLPTR(src);
    ARM_COMPUTE_ASSERT_NOT_NULLPTR(dst);

    const auto broadcast_val_clamped_s   = std::min<uint8_t>(broadcast_val, 1);
    const auto broadcast_val_clamped_x16 = vdupq_n_u8(broadcast_val_clamped_s);
    const auto broadcast_val_clamped_x8  = vdup_n_u8(broadcast_val_clamped_s);

    for (; len >= step; len -= step)
    {
        vst1q_u8(dst, vorrq_u8(vminq_u8(vld1q_u8(src), c1_x16), broadcast_val_clamped_x16));
        src += step;
        dst += step;
    }

    for (; len >= half_step; len -= half_step)
    {
        vst1_u8(dst, vorr_u8(vmin_u8(vld1_u8(src), c1_x8), broadcast_val_clamped_x8));
        src += half_step;
        dst += half_step;
    }

    for (; len > 0; --len)
    {
        *dst = (*src) || broadcast_val_clamped_s;
        ++src;
        ++dst;
    }
}

void neon_logical_not(const uint8_t *src, uint8_t *dst, uint32_t len)
{
    ARM_COMPUTE_ASSERT_NOT_NULLPTR(src);
    ARM_COMPUTE_ASSERT_NOT_NULLPTR(dst);

    for (; len >= step; len -= step)
    {
        vst1q_u8(dst, vbslq_u8(vceqq_u8(vld1q_u8(src), c0_x16), c1_x16, c0_x16));
        src += step;
        dst += step;
    }

    for (; len >= half_step; len -= half_step)
    {
        vst1_u8(dst, vbsl_u8(vceq_u8(vld1_u8(src), c0_x8), c1_x8, c0_x8));
        src += half_step;
        dst += half_step;
    }

    for (; len > 0; --len)
    {
        *dst = !(*src);
        ++src;
        ++dst;
    }
}

void run_unary(const Window &window, const ITensor *src, ITensor *dst)
{
    Window win{window};
    win.set(Window::DimX, Window::Dimension(0, 1, 1));
    const auto len = window.x().end() - window.x().start();

    Iterator in(src, win);
    Iterator out(dst, win);

    execute_window_loop(
        win, [&](const Coordinates &) { neon_logical_not(in.ptr(), out.ptr(), len); }, in, out);
}

void run_binary(const Window &window, const ITensor *src0, const ITensor *src1, ITensor *dst, LogicalOperation op)
{
    Window src0_win = window.broadcast_if_dimension_le_one(src0->info()->tensor_shape());
    Window src1_win = window.broadcast_if_dimension_le_one(src1->info()->tensor_shape());

    Window win{window};
    win.set(Window::DimX, Window::Dimension(0, 1, 1));

    const bool is_broadcast_across_x = src0->info()->tensor_shape().x() != src1->info()->tensor_shape().x();
    const auto len                   = window.x().end() - window.x().start();

    if (is_broadcast_across_x)
    {
        using LogicalBroadcastUKernelPtr = std::add_pointer<void(const uint8_t *, uint8_t, uint8_t *, uint32_t)>::type;
        LogicalBroadcastUKernelPtr logical_func =
            op == LogicalOperation::Or ? &neon_logical_or_broadcast : &neon_logical_and_broadcast;

        const bool     is_broadcast_input_1 = src1_win.x().step() == 0;
        Window         broadcast_win        = is_broadcast_input_1 ? src1_win : src0_win;
        Window         non_broadcast_win    = !is_broadcast_input_1 ? src1_win : src0_win;
        const ITensor *broadcast_tensor     = is_broadcast_input_1 ? src1 : src0;
        const ITensor *non_broadcast_tensor = !is_broadcast_input_1 ? src1 : src0;
        non_broadcast_win.set(Window::DimX, Window::Dimension(0, 1, 1));

        Iterator broadcast_in(broadcast_tensor, broadcast_win);
        Iterator non_broadcast_in(non_broadcast_tensor, non_broadcast_win);
        Iterator out(dst, win);

        execute_window_loop(
            win,
            [&](const Coordinates &)
            {
                const uint8_t broadcast_value = *broadcast_in.ptr();
                logical_func(non_broadcast_in.ptr(), broadcast_value, out.ptr(), len);
            },
            broadcast_in, non_broadcast_in, out);
    }
    else
    {
        using LogicalUKernelPtr = std::add_pointer<void(const uint8_t *, const uint8_t *, uint8_t *, uint32_t)>::type;
        LogicalUKernelPtr logical_func = op == LogicalOperation::Or ? &neon_logical_or : &neon_logical_and;

        src0_win.set(Window::DimX, Window::Dimension(0, 1, 1));
        src1_win.set(Window::DimX, Window::Dimension(0, 1, 1));

        Iterator in0(src0, src0_win);
        Iterator in1(src1, src1_win);
        Iterator out(dst, win);
        execute_window_loop(
            win, [&](const Coordinates &) { logical_func(in0.ptr(), in1.ptr(), out.ptr(), len); }, in0, in1, out);
    }
}
} // namespace
const char *NELogicalKernel::name() const
{
    return "NELogicalKernel";
}

void NELogicalKernel::configure(const ITensorInfo *input1,
                                const ITensorInfo *input2,
                                ITensorInfo       *output,
                                LogicalOperation   op)
{
    ARM_COMPUTE_ERROR_ON_NULLPTR(input1, output);
    ARM_COMPUTE_ERROR_THROW_ON(validate(input1, input2, output, op));

    _op = op;

    Window      win       = calculate_max_window(*input1, Steps());
    TensorShape out_shape = input1->tensor_shape();
    if (op != LogicalOperation::Not)
    {
        ARM_COMPUTE_ERROR_ON_NULLPTR(input2);
        out_shape = TensorShape::broadcast_shape(input1->tensor_shape(), input2->tensor_shape());
        win       = calculate_max_window(out_shape, Steps());
    }
    ICPPKernel::configure(win);

    // Auto initialize if empty
    set_shape_if_empty(*output, out_shape);
    set_data_type_if_unknown(*output, input1->data_type());
}

Status NELogicalKernel::validate(const ITensorInfo *input1,
                                 const ITensorInfo *input2,
                                 const ITensorInfo *output,
                                 LogicalOperation   op)
{
    ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input1, 1, DataType::U8);
    ARM_COMPUTE_RETURN_ERROR_ON(op == LogicalOperation::Unknown);

    TensorShape out_shape = input1->tensor_shape();
    if (op != LogicalOperation::Not)
    {
        out_shape = TensorShape::broadcast_shape(input1->tensor_shape(), input2->tensor_shape());
        ARM_COMPUTE_RETURN_ERROR_ON_MSG(out_shape.total_size() == 0, "Inputs are not broadcast compatible");
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input1, input2);
    }

    // Checks performed when output is configured
    if ((output != nullptr) && (output->total_size() != 0))
    {
        ARM_COMPUTE_RETURN_ERROR_ON(detail::have_different_dimensions(out_shape, output->tensor_shape(), 0));
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input1, output);
    }

    return Status{};
}

void NELogicalKernel::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(INEKernel::window(), window);
    ARM_COMPUTE_ERROR_ON(tensors.empty());

    const ITensor *src0 = tensors.get_const_tensor(TensorType::ACL_SRC_0);
    const ITensor *src1 = tensors.get_const_tensor(TensorType::ACL_SRC_1);
    ITensor       *dst  = tensors.get_tensor(TensorType::ACL_DST);

    if (_op == LogicalOperation::Not)
    {
        run_unary(window, src0, dst);
    }
    else
    {
        run_binary(window, src0, src1, dst, _op);
    }
}
} // namespace kernels
} // namespace arm_compute
