//
// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include "NeonChannelShuffleWorkload.hpp"
#include "NeonWorkloadUtils.hpp"

#include <aclCommon/ArmComputeTensorHandle.hpp>
#include <aclCommon/ArmComputeTensorUtils.hpp>

#include <armnn/utility/PolymorphicDowncast.hpp>

namespace armnn
{

arm_compute::Status NeonChannelShuffleValidate(const TensorInfo& input,
                                               const TensorInfo& output,
                                               const ChannelShuffleDescriptor& descriptor)
{
    arm_compute::TensorInfo aclInputInfo  = armcomputetensorutils::BuildArmComputeTensorInfo(input);
    arm_compute::TensorInfo aclOutputInfo = armcomputetensorutils::BuildArmComputeTensorInfo(output);

    // In Arm NN and in NNAPI, channel shuffle implementation is datalayout agnostic and it has axis as a parameter.
    // The channel shuffle Implementation for Neon is dependent on datalayout and does not have axis as a parameter,
    // it only supports channel shuffle for 4D tensors in dimension C (1 or 3).
    arm_compute::DataLayout aclDataLayout;
    if (input.GetNumDimensions() == 4)
    {
        switch (descriptor.m_Axis)
        {
            case 1:
                aclDataLayout = ConvertDataLayout(armnn::DataLayout::NCHW);
                break;
            case 3:
                aclDataLayout = ConvertDataLayout(armnn::DataLayout::NHWC);
                break;
            default:
                return arm_compute::Status{arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported axis"};
        }
        aclInputInfo.set_data_layout(aclDataLayout);
        aclOutputInfo.set_data_layout(aclDataLayout);
        return arm_compute::NEChannelShuffleLayer::validate(&aclInputInfo, &aclOutputInfo, descriptor.m_NumGroups);
    }
    else
    {
        return arm_compute::Status{arm_compute::ErrorCode::RUNTIME_ERROR, "Unsupported number of dimensions"};
    }
}

NeonChannelShuffleWorkload::NeonChannelShuffleWorkload(const ChannelShuffleQueueDescriptor& descriptor, 
                                                       const WorkloadInfo& info)
    : NeonBaseWorkload<ChannelShuffleQueueDescriptor>(descriptor, info)
{
    // Report Profiling Details
    ARMNN_REPORT_PROFILING_WORKLOAD_DESC("NeonChannelShufflenWorkload_Construct",
                                         descriptor.m_Parameters,
                                         info,
                                         this->GetGuid());

    m_Data.ValidateInputsOutputs("NeonChannelShuffleWorkload", 1, 1);

    arm_compute::ITensor& input  = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
    arm_compute::ITensor& output = PolymorphicDowncast<IAclTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();

    // In Arm NN and in NNAPI, channel shuffle implementation is datalayout agnostic and it has axis as a parameter.
    // The channel shuffle Implementation for Neon is dependent on datalayout and does not have axis as a parameter,
    // it only supports channel shuffle for 4D tensors in dimension C (1 or 3).
    arm_compute::DataLayout aclDataLayout;
    switch (descriptor.m_Parameters.m_Axis)
    {
        case 1:
            aclDataLayout = ConvertDataLayout(armnn::DataLayout::NCHW);
            break;
        case 3:
            aclDataLayout = ConvertDataLayout(armnn::DataLayout::NHWC);
            break;
        default:
            ARMNN_ASSERT_MSG(false, "Unsupported axis");
            break;
    }
    input.info()->set_data_layout(aclDataLayout);
    output.info()->set_data_layout(aclDataLayout);

    m_ChannelShuffleLayer.configure(&input, &output, descriptor.m_Parameters.m_NumGroups);
}

void NeonChannelShuffleWorkload::Execute() const
{
    ARMNN_SCOPED_PROFILING_EVENT_NEON_GUID("NeonChannelShuffleWorkload_Execute", this->GetGuid());
    m_ChannelShuffleLayer.run();
}

} // namespace armnn
