/*
 * Copyright (c) 2018-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 "arm_compute/core/Types.h"
#include "arm_compute/core/utils/misc/ShapeCalculator.h"
#include "arm_compute/runtime/CL/CLTensor.h"
#include "arm_compute/runtime/CL/CLTensorAllocator.h"
#include "src/gpu/cl/kernels/ClGemmReshapeRhsMatrixKernel.h"
#include "tests/CL/CLAccessor.h"
#include "tests/CL/Helper.h"
#include "tests/PaddingCalculator.h"
#include "tests/datasets/ShapeDatasets.h"
#include "tests/framework/Asserts.h"
#include "tests/framework/Macros.h"
#include "tests/framework/datasets/Datasets.h"
#include "tests/validation/Validation.h"
#include "tests/validation/fixtures/GEMMReshapeRHSMatrixFixture.h"

namespace arm_compute
{
namespace test
{
namespace validation
{
namespace
{
// *INDENT-OFF*
// clang-format off
/** Batch size values to test */
const auto b_values = framework::dataset::make("batchsize", 1, 3);

/** N0 values to test */
const auto n0_values_nt_s32 = framework::dataset::make("N0", { 1, 2, 3 });
const auto n0_values_nt_s16 = framework::dataset::make("N0", { 4, 8 });
const auto n0_values_nt_s8 = framework::dataset::make("N0", { 16 });
const auto n0_values_t_s32 = framework::dataset::make("N0", { 4, 8 });
const auto n0_values_t_s16 = framework::dataset::make("N0", { 16 });
const auto n0_values_t_s8 = framework::dataset::make("N0", { 2, 3 });

/** K0 values to test */
const auto k0_values_nt_s32 = framework::dataset::make("K0", { 1, 2 });
const auto k0_values_nt_s16 = framework::dataset::make("K0", { 16 });
const auto k0_values_nt_s8 = framework::dataset::make("K0", { 3,4 });
const auto k0_values_t_s32 = framework::dataset::make("K0", { 2, 3 });
const auto k0_values_t_s16 = framework::dataset::make("K0", { 4, 8 });
const auto k0_values_t_s8 = framework::dataset::make("K0", { 16 });

/** H0 values to test */
const auto h0_values = framework::dataset::make("H0", 1, 4);

/** Interleave values to test */
const auto i_values = framework::dataset::make("interleave", { true, false });
} // namespace

using namespace arm_compute::misc::shape_calculator;
using namespace arm_compute::opencl::kernels;

// Initialize the output tensor with zero and fill the border with zero
using CLGEMMReshapeRHSMatrix = CLSynthetizeOperatorInitOutputWithZeroAndWithZeroConstantBorder<ClGemmReshapeRhsMatrixKernel, 16>;

template <typename T>
using CLGEMMReshapeRHSMatrixFixture = GEMMReshapeRHSMatrixValidationFixture<CLTensor, CLAccessor, CLGEMMReshapeRHSMatrix, T>;

TEST_SUITE(CL)
TEST_SUITE(GEMMReshapeRHSMatrix)

// *INDENT-OFF*
// clang-format off
DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(
               framework::dataset::make("InputInfo", { TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32),
                                                       TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32),    // Mismatching data types
                                                       TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32),    // Wrong n0 value
                                                       TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32),    // Wrong k0 value
                                                       TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32),    // Wrong h0 value
                                                       TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32),    // n0 > 16
                                                       TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32),    // k0 > 16
                                                       TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32),    // k0 == 1 && transpose
                                                     }),
               framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(64U, 2U, 2U), 1, DataType::F32),
                                                       TensorInfo(TensorShape(32U, 2U, 2U), 1, DataType::F16),
                                                       TensorInfo(TensorShape(32U, 2U, 2U), 1, DataType::F32),
                                                       TensorInfo(TensorShape(32U, 2U, 2U), 1, DataType::F32),
                                                       TensorInfo(TensorShape(32U, 2U, 2U), 1, DataType::F32),
                                                       TensorInfo(TensorShape(32U, 2U, 2U), 1, DataType::F32),
                                                       TensorInfo(TensorShape(32U, 2U, 2U), 1, DataType::F32),
                                                       TensorInfo(TensorShape(32U, 2U, 2U), 1, DataType::F32),
                                                     })),
                framework::dataset::make("N0",{ 4, 0, 4, 4, 4, 17, 4, 4 })),
                framework::dataset::make("K0",{ 4, 4, 0, 4, 4, 4, 17, 1 })),
                framework::dataset::make("H0",{ 4, 4, 4, 0, 4, 4, 4, 4 })),
               framework::dataset::make("Expected", { false, false, false, false, false, false, false})),
               input_info, output_info, n0, k0, h0, expected)
{
    GEMMRHSMatrixInfo rhs_info;
    rhs_info.n0 = n0;
    rhs_info.k0 = k0;
    rhs_info.h0 = h0;
    rhs_info.transpose = true;
    rhs_info.interleave = true;

    bool has_error = bool(ClGemmReshapeRhsMatrixKernel::validate(&input_info.clone()->set_is_resizable(false), (output_info.total_size() == 0) ? nullptr : &output_info.clone()->set_is_resizable(false), rhs_info));
    ARM_COMPUTE_EXPECT(has_error == expected, framework::LogLevel::ERRORS);
}

DATA_TEST_CASE(ValidatePadding, framework::DatasetMode::ALL, combine(combine(combine(combine(
               framework::dataset::make("InputShape", { TensorShape(32U, 16U, 1U),
                                                        TensorShape(32U, 16U, 2U)
                                                     }),
                framework::dataset::make("N0",{ 4 })),
                framework::dataset::make("K0",{ 4, 8, 16 })),
                framework::dataset::make("H0",{ 1, 2, 4 })),
                framework::dataset::make("DataType",{ DataType::F32, DataType::F16 })),
               input_shape, n0, k0, h0, data_type)
{
    CLTensor input;
    CLTensor output;

    input.info()->init(input_shape, 1, data_type);

    unsigned int padding = 0;

    GEMMRHSMatrixInfo rhs_info;
    rhs_info.n0 = n0;
    rhs_info.k0 = k0;
    rhs_info.h0 = h0;
    rhs_info.transpose = true;
    rhs_info.interleave = true;
    rhs_info.export_to_cl_image = image2d_from_buffer_supported(CLKernelLibrary::get().get_device()) && (get_cl_image_pitch_alignment(CLKernelLibrary::get().get_device()) != 0);

    if(rhs_info.export_to_cl_image)
    {
        TensorShape output_shape = compute_rhs_reshaped_shape(*input.info(), rhs_info);
        constexpr unsigned int num_floats_per_pixel = 4;

        const unsigned int pixel_aligment      = get_cl_image_pitch_alignment(CLKernelLibrary::get().get_device());
        const unsigned int row_pitch_alignment = pixel_aligment * num_floats_per_pixel;
        const unsigned int round_up_width      = ((output_shape[0] + row_pitch_alignment - 1) / row_pitch_alignment) * row_pitch_alignment;

        padding = round_up_width - output_shape[0];
    }

    ClGemmReshapeRhsMatrixKernel kernel;

    kernel.configure(CLKernelLibrary::get().get_compile_context(), input.info(), output.info(), rhs_info);

    ARM_COMPUTE_EXPECT((output.info()->padding().right == padding), framework::LogLevel::ERRORS);
}
// clang-format on
// *INDENT-ON*

// Run S32 tests only for transpose = false
FIXTURE_DATA_TEST_CASE(S32_NT, CLGEMMReshapeRHSMatrixFixture<int>, framework::DatasetMode::ALL,
                       combine(combine(combine(combine(combine(combine(combine(datasets::SmallGEMMReshape2DShapes(),
                                                                               b_values),
                                                                       framework::dataset::make("DataType", DataType::S32)),
                                                               n0_values_nt_s32),
                                                       k0_values_nt_s32),
                                               h0_values),
                                       i_values),
                               framework::dataset::make("transpose", false)))
{
    // Validate output
    validate(CLAccessor(_target), _reference);
}

// Run S32 tests only for transpose = true
FIXTURE_DATA_TEST_CASE(S32_T, CLGEMMReshapeRHSMatrixFixture<int>, framework::DatasetMode::ALL,
                       combine(combine(combine(combine(combine(combine(combine(datasets::SmallGEMMReshape2DShapes(),
                                                                               b_values),
                                                                       framework::dataset::make("DataType", DataType::S32)),
                                                               n0_values_t_s32),
                                                       k0_values_t_s32),
                                               h0_values),
                                       i_values),
                               framework::dataset::make("transpose", true)))
{
    // Validate output
    validate(CLAccessor(_target), _reference);
}

// Run S16 tests only for transpose = false
FIXTURE_DATA_TEST_CASE(S16_NT, CLGEMMReshapeRHSMatrixFixture<short>, framework::DatasetMode::ALL,
                       combine(combine(combine(combine(combine(combine(combine(datasets::SmallGEMMReshape2DShapes(),
                                                                               b_values),
                                                                       framework::dataset::make("DataType", DataType::S16)),
                                                               n0_values_nt_s16),
                                                       k0_values_nt_s16),
                                               h0_values),
                                       i_values),
                               framework::dataset::make("transpose", false)))
{
    // Validate output
    validate(CLAccessor(_target), _reference);
}

// Run S16 tests only for transpose = true
FIXTURE_DATA_TEST_CASE(S16_T, CLGEMMReshapeRHSMatrixFixture<short>, framework::DatasetMode::ALL,
                       combine(combine(combine(combine(combine(combine(combine(datasets::SmallGEMMReshape2DShapes(),
                                                                               b_values),
                                                                       framework::dataset::make("DataType", DataType::S16)),
                                                               n0_values_t_s16),
                                                       k0_values_t_s16),
                                               h0_values),
                                       i_values),
                               framework::dataset::make("transpose", true)))
{
    // Validate output
    validate(CLAccessor(_target), _reference);
}

// Run S8 tests only for transpose = false
FIXTURE_DATA_TEST_CASE(S8_NT, CLGEMMReshapeRHSMatrixFixture<char>, framework::DatasetMode::ALL,
                       combine(combine(combine(combine(combine(combine(combine(datasets::SmallGEMMReshape2DShapes(),
                                                                               b_values),
                                                                       framework::dataset::make("DataType", DataType::S8)),
                                                               n0_values_nt_s8),
                                                       k0_values_nt_s8),
                                               h0_values),
                                       i_values),
                               framework::dataset::make("transpose", false)))
{
    // Validate output
    validate(CLAccessor(_target), _reference);
}

// Run S8 tests only for transpose = true
FIXTURE_DATA_TEST_CASE(S8_T, CLGEMMReshapeRHSMatrixFixture<char>, framework::DatasetMode::ALL,
                       combine(combine(combine(combine(combine(combine(combine(datasets::SmallGEMMReshape2DShapes(),
                                                                               b_values),
                                                                       framework::dataset::make("DataType", DataType::S8)),
                                                               n0_values_t_s8),
                                                       k0_values_t_s8),
                                               h0_values),
                                       i_values),
                               framework::dataset::make("transpose", true)))
{
    // Validate output
    validate(CLAccessor(_target), _reference);
}

TEST_SUITE_END() // GEMMReshapeRHSMatrix
TEST_SUITE_END() // CL
} // namespace validation
} // namespace test
} // namespace arm_compute
