/*
 * Copyright (c) 2021-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.
 */
#include "src/cpu/operators/CpuActivation.h"

#include "arm_compute/runtime/NEON/NEScheduler.h"

#include "src/common/IOperator.h"
#include "src/common/utils/LegacySupport.h"
#include "src/common/utils/Log.h"
#include "src/cpu/CpuContext.h"
#include "src/cpu/kernels/CpuActivationKernel.h"

namespace arm_compute
{
namespace cpu
{
void CpuActivation::configure(const ITensorInfo *input, ITensorInfo *output, const ActivationLayerInfo &activation_info)
{
    ARM_COMPUTE_LOG_PARAMS(input, output, activation_info);
    auto k = std::make_unique<kernels::CpuActivationKernel>();
    k->configure(input, output, activation_info);
    _kernel = std::move(k);
}

Status
CpuActivation::validate(const ITensorInfo *input, const ITensorInfo *output, const ActivationLayerInfo &activation_info)
{
    return kernels::CpuActivationKernel::validate(input, output, activation_info);
}

void CpuActivation::run(ITensorPack &tensors)
{
    ARM_COMPUTE_ERROR_ON_MSG(tensors.empty(), "No inputs provided");
    auto split_dimension = static_cast<kernels::CpuActivationKernel *>(_kernel.get())->get_split_dimension_hint();
    NEScheduler::get().schedule_op(_kernel.get(), split_dimension, _kernel->window(), tensors);
}

std::tuple<IOperator *, StatusCode> CpuContext::create_activation(const AclTensorDescriptor     &src,
                                                                  const AclTensorDescriptor     &dst,
                                                                  const AclActivationDescriptor &act,
                                                                  bool                           is_validate)
{
    TensorInfo src_info = detail::convert_to_legacy_tensor_info(src);
    TensorInfo dst_info = detail::convert_to_legacy_tensor_info(dst);
    auto       info     = detail::convert_to_activation_info(act);

    if (is_validate &&
        !bool(CpuActivation::validate(&src_info.set_is_resizable(false), &dst_info.set_is_resizable(false), info)))
    {
        return std::make_tuple(nullptr, StatusCode::UnsupportedConfig);
    }

    auto act_op = std::make_unique<cpu::CpuActivation>();
    act_op->configure(&src_info, &dst_info, info);

    auto op = new arm_compute::IOperator(static_cast<IContext *>(this));
    if (op == nullptr)
    {
        ARM_COMPUTE_LOG_ERROR_ACL("Couldn't allocate internal resources");
        return std::make_tuple(nullptr, StatusCode::OutOfMemory);
    }
    op->set_internal_operator(std::move(act_op));

    return std::make_tuple(op, StatusCode::Success);
}
} // namespace cpu
} // namespace arm_compute
