//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include "ClSplitterWorkload.hpp"

#include "ClWorkloadUtils.hpp"

#include <aclCommon/ArmComputeTensorUtils.hpp>
#include <aclCommon/ArmComputeUtils.hpp>
#include <arm_compute/runtime/CL/functions/CLSplit.h>
#include <backendsCommon/CpuTensorHandle.hpp>
#include <cl/ClTensorHandle.hpp>


namespace armnn
{

using namespace armcomputetensorutils;

namespace
{
    unsigned int CalcAclAxis(unsigned int numDimensions, unsigned int splitAxis)
    {
        return (numDimensions - splitAxis) - 1;
    }

} //namespace

arm_compute::Status ClSplitterWorkloadValidate(const TensorInfo& input,
                                               const std::vector<std::reference_wrapper<TensorInfo>>& outputs,
                                               unsigned int splitAxis)
{
    const arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input);

    size_t numOutputs = outputs.size();

    std::vector<arm_compute::TensorInfo> aclOutputs;
    aclOutputs.reserve(numOutputs);

    std::vector<arm_compute::ITensorInfo*> aclOutputPtr;
    aclOutputPtr.reserve(numOutputs);

    for (size_t i = 0u; i < outputs.size(); ++i)
    {
        aclOutputs.emplace_back(BuildArmComputeTensorInfo(outputs[i]));
        aclOutputPtr.emplace_back(&aclOutputs.back());
    }

    unsigned int aclAxis = CalcAclAxis(input.GetNumDimensions(), splitAxis);
    return arm_compute::CLSplit::validate(&aclInputInfo, aclOutputPtr, aclAxis);
}

ClSplitterWorkload::ClSplitterWorkload(const SplitterQueueDescriptor& descriptor, const WorkloadInfo& info)
        : BaseWorkload<SplitterQueueDescriptor>(descriptor, info)
{
    bool allOutputsAreSubtensors = true;

    // Check that all outputs are sub-tensors
    for (auto output : m_Data.m_Outputs)
    {
        if (output && !output->GetParent())
        {
            // Non sub-tensor input found so we need to execute the split function
            allOutputsAreSubtensors = false;
            break;
        }
    }

    if (allOutputsAreSubtensors)
    {
        // Can skip configuring the split function since it's not executed
        return;
    }

    arm_compute::ICLTensor& input = boost::polymorphic_pointer_downcast<IClTensorHandle>(
            m_Data.m_Inputs[0])->GetTensor();

    std::vector<arm_compute::ICLTensor *> aclOutputs;
    for (auto output : m_Data.m_Outputs)
    {
        arm_compute::ICLTensor& aclOutput  = boost::polymorphic_pointer_downcast<IClTensorHandle>(output)->GetTensor();
        aclOutputs.emplace_back(&aclOutput);
    }

    // Create the layer function

    // Configure input and output tensors
    std::set<unsigned int> splitAxis = ComputeSplitAxis(descriptor.m_Parameters, m_Data.m_Inputs[0]->GetShape());
    if (splitAxis.size() != 1)
    {
        throw InvalidArgumentException("Cannot derive split axis from SplitterDescriptor");
    }

    unsigned int aclAxis = CalcAclAxis(descriptor.m_Parameters.GetNumDimensions(), *splitAxis.begin());
    auto layer = std::make_unique<arm_compute::CLSplit>();
    layer->configure(&input, aclOutputs, aclAxis);

    // Prepare
    layer->prepare();

    m_Layer = std::move(layer);
}

void ClSplitterWorkload::Execute() const
{
    if (m_Layer)
    {
        ARMNN_SCOPED_PROFILING_EVENT_CL("ClSplitterWorkload_Execute");
        m_Layer->run();
    }
}

} //namespace armnn
