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

#include "../DriverTestHelpers.hpp"
#include "../TestTensor.hpp"

#include <boost/array.hpp>
#include <boost/test/data/test_case.hpp>

BOOST_AUTO_TEST_SUITE(MeanTests)

using namespace android::hardware;
using namespace driverTestHelpers;
using namespace armnn_driver;

namespace
{

static const boost::array<armnn::Compute, 2> COMPUTE_DEVICES = {{ armnn::Compute::CpuRef, armnn::Compute::GpuAcc }};

void MeanTestImpl(const TestTensor& input,
                  const hidl_vec<uint32_t>& axisDimensions,
                  const int32_t* axisValues,
                  int32_t keepDims,
                  const TestTensor& expectedOutput,
                  bool fp16Enabled,
                  armnn::Compute computeDevice)
{
    auto driver = std::make_unique<ArmnnDriver>(DriverOptions(computeDevice, fp16Enabled));

    V1_1::Model model = {};
    AddInputOperand (model, input.GetDimensions());
    AddTensorOperand(model, axisDimensions, const_cast<int32_t*>(axisValues), V1_0::OperandType::TENSOR_INT32);
    AddIntOperand   (model, keepDims);
    AddOutputOperand(model, expectedOutput.GetDimensions());

    model.operations.resize(1);
    model.operations[0].type               = V1_1::OperationType::MEAN;
    model.operations[0].inputs             = hidl_vec<uint32_t>{ 0, 1, 2 };
    model.operations[0].outputs            = hidl_vec<uint32_t>{ 3 };
    model.relaxComputationFloat32toFloat16 = fp16Enabled;

    android::sp<V1_0::IPreparedModel> preparedModel = PrepareModel(model, *driver);

    // The request's memory pools will follow the same order as the inputs
    DataLocation inLoc    = {};
    inLoc.poolIndex       = 0;
    inLoc.offset          = 0;
    inLoc.length          = input.GetNumElements() * sizeof(float);
    RequestArgument inArg = {};
    inArg.location        = inLoc;
    inArg.dimensions      = input.GetDimensions();

    // An additional memory pool is needed for the output
    DataLocation outLoc    = {};
    outLoc.poolIndex       = 1;
    outLoc.offset          = 0;
    outLoc.length          = expectedOutput.GetNumElements() * sizeof(float);
    RequestArgument outArg = {};
    outArg.location        = outLoc;
    outArg.dimensions      = expectedOutput.GetDimensions();

    // Make the request based on the arguments
    Request request = {};
    request.inputs  = hidl_vec<RequestArgument>{ inArg };
    request.outputs = hidl_vec<RequestArgument>{ outArg };

    // Set the input data
    AddPoolAndSetData(input.GetNumElements(), request, input.GetData());

    // Add memory for the output
    android::sp<IMemory> outMemory = AddPoolAndGetData(expectedOutput.GetNumElements(), request);
    const float* outputData = static_cast<const float*>(static_cast<void*>(outMemory->getPointer()));

    ErrorStatus execStatus = Execute(preparedModel, request);
    BOOST_TEST(execStatus == ErrorStatus::NONE);

    const float* expectedOutputData = expectedOutput.GetData();
    for (unsigned int i = 0; i < expectedOutput.GetNumElements(); i++)
    {
        BOOST_TEST(outputData[i] == expectedOutputData[i]);
    }
}

} // anonymous namespace

BOOST_DATA_TEST_CASE(MeanNoKeepDimsTest, COMPUTE_DEVICES)
{
    TestTensor input{ armnn::TensorShape{ 4, 3, 2 }, { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f,
                                                       11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f,
                                                       20.0f, 21.0f, 22.0f, 23.0f, 24.0f } };
    hidl_vec<uint32_t> axisDimensions = { 2 };
    int32_t axisValues[] = { 0, 1 };
    int32_t keepDims = 0;
    TestTensor expectedOutput{ armnn::TensorShape{ 2 }, { 12.0f, 13.0f } };

    MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, false, sample);
}

BOOST_DATA_TEST_CASE(MeanKeepDimsTest, COMPUTE_DEVICES)
{
    TestTensor input{ armnn::TensorShape{ 1, 1, 3, 2 }, { 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f } };
    hidl_vec<uint32_t> axisDimensions = { 1 };
    int32_t axisValues[] = { 2 };
    int32_t keepDims = 1;
    TestTensor expectedOutput{ armnn::TensorShape{ 1, 1, 1, 2 }, {  2.0f, 2.0f } };

    MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, false, sample);
}

BOOST_DATA_TEST_CASE(MeanFp16NoKeepDimsTest, COMPUTE_DEVICES)
{
    TestTensor input{ armnn::TensorShape{ 4, 3, 2 }, { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f,
                                                       11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f,
                                                       20.0f, 21.0f, 22.0f, 23.0f, 24.0f } };
    hidl_vec<uint32_t> axisDimensions = { 2 };
    int32_t axisValues[] = { 0, 1 };
    int32_t keepDims = 0;
    TestTensor expectedOutput{ armnn::TensorShape{ 2 }, { 12.0f, 13.0f } };

    MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, sample);
}

BOOST_DATA_TEST_CASE(MeanFp16KeepDimsTest, COMPUTE_DEVICES)
{
    TestTensor input{ armnn::TensorShape{ 1, 1, 3, 2 }, { 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f } };
    hidl_vec<uint32_t> axisDimensions = { 1 };
    int32_t axisValues[] = { 2 };
    int32_t keepDims = 1;
    TestTensor expectedOutput{ armnn::TensorShape{ 1, 1, 1, 2 }, {  2.0f, 2.0f } };

    MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, sample);
}

BOOST_AUTO_TEST_SUITE_END()
