// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2016
// Mehdi Goli    Codeplay Software Ltd.
// Ralph Potter  Codeplay Software Ltd.
// Luke Iwanski  Codeplay Software Ltd.
// Contact: <eigen@codeplay.com>
// Benoit Steiner <benoit.steiner.goog@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// SPDX-License-Identifier: MPL-2.0

#define EIGEN_TEST_NO_LONGDOUBLE
#define EIGEN_TEST_NO_COMPLEX

#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int64_t
#define EIGEN_USE_SYCL

#include "main.h"
#include <contrib/Eigen/Tensor>

using Eigen::array;
using Eigen::SyclDevice;
using Eigen::Tensor;
using Eigen::TensorMap;

template <typename DataType, int DataLayout, typename IndexType>
static void test_simple_reshape(const Eigen::SyclDevice& sycl_device) {
  typename Tensor<DataType, 5, DataLayout, IndexType>::Dimensions dim1(2, 3, 1, 7, 1);
  typename Tensor<DataType, 3, DataLayout, IndexType>::Dimensions dim2(2, 3, 7);
  typename Tensor<DataType, 2, DataLayout, IndexType>::Dimensions dim3(6, 7);
  typename Tensor<DataType, 2, DataLayout, IndexType>::Dimensions dim4(2, 21);

  Tensor<DataType, 5, DataLayout, IndexType> tensor1(dim1);
  Tensor<DataType, 3, DataLayout, IndexType> tensor2(dim2);
  Tensor<DataType, 2, DataLayout, IndexType> tensor3(dim3);
  Tensor<DataType, 2, DataLayout, IndexType> tensor4(dim4);

  tensor1.setRandom();

  DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(tensor1.size() * sizeof(DataType)));
  DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(tensor2.size() * sizeof(DataType)));
  DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(tensor3.size() * sizeof(DataType)));
  DataType* gpu_data4 = static_cast<DataType*>(sycl_device.allocate(tensor4.size() * sizeof(DataType)));

  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu1(gpu_data1, dim1);
  TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu2(gpu_data2, dim2);
  TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> gpu3(gpu_data3, dim3);
  TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> gpu4(gpu_data4, dim4);

  sycl_device.memcpyHostToDevice(gpu_data1, tensor1.data(), (tensor1.size()) * sizeof(DataType));

  gpu2.device(sycl_device) = gpu1.reshape(dim2);
  sycl_device.memcpyDeviceToHost(tensor2.data(), gpu_data2, (tensor1.size()) * sizeof(DataType));

  gpu3.device(sycl_device) = gpu1.reshape(dim3);
  sycl_device.memcpyDeviceToHost(tensor3.data(), gpu_data3, (tensor3.size()) * sizeof(DataType));

  gpu4.device(sycl_device) = gpu1.reshape(dim2).reshape(dim4);
  sycl_device.memcpyDeviceToHost(tensor4.data(), gpu_data4, (tensor4.size()) * sizeof(DataType));
  for (IndexType i = 0; i < 2; ++i) {
    for (IndexType j = 0; j < 3; ++j) {
      for (IndexType k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(tensor1(i, j, 0, k, 0), tensor2(i, j, k));  /// ColMajor
        if (static_cast<int>(DataLayout) == static_cast<int>(ColMajor)) {
          VERIFY_IS_EQUAL(tensor1(i, j, 0, k, 0), tensor3(i + 2 * j, k));  /// ColMajor
          VERIFY_IS_EQUAL(tensor1(i, j, 0, k, 0), tensor4(i, j + 3 * k));  /// ColMajor
        } else {
          // VERIFY_IS_EQUAL(tensor1(i,j,0,k,0), tensor2(i,j,k));      /// RowMajor
          VERIFY_IS_EQUAL(tensor1(i, j, 0, k, 0), tensor4(i, j * 7 + k));  /// RowMajor
          VERIFY_IS_EQUAL(tensor1(i, j, 0, k, 0), tensor3(i * 3 + j, k));  /// RowMajor
        }
      }
    }
  }
  sycl_device.deallocate(gpu_data1);
  sycl_device.deallocate(gpu_data2);
  sycl_device.deallocate(gpu_data3);
  sycl_device.deallocate(gpu_data4);
}

template <typename DataType, int DataLayout, typename IndexType>
static void test_reshape_as_lvalue(const Eigen::SyclDevice& sycl_device) {
  typename Tensor<DataType, 3, DataLayout, IndexType>::Dimensions dim1(2, 3, 7);
  typename Tensor<DataType, 2, DataLayout, IndexType>::Dimensions dim2(6, 7);
  typename Tensor<DataType, 5, DataLayout, IndexType>::Dimensions dim3(2, 3, 1, 7, 1);
  Tensor<DataType, 3, DataLayout, IndexType> tensor(dim1);
  Tensor<DataType, 2, DataLayout, IndexType> tensor2d(dim2);
  Tensor<DataType, 5, DataLayout, IndexType> tensor5d(dim3);

  tensor.setRandom();

  DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(tensor.size() * sizeof(DataType)));
  DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(tensor2d.size() * sizeof(DataType)));
  DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(tensor5d.size() * sizeof(DataType)));

  TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu1(gpu_data1, dim1);
  TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> gpu2(gpu_data2, dim2);
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu3(gpu_data3, dim3);

  sycl_device.memcpyHostToDevice(gpu_data1, tensor.data(), (tensor.size()) * sizeof(DataType));

  gpu2.reshape(dim1).device(sycl_device) = gpu1;
  sycl_device.memcpyDeviceToHost(tensor2d.data(), gpu_data2, (tensor2d.size()) * sizeof(DataType));

  gpu3.reshape(dim1).device(sycl_device) = gpu1;
  sycl_device.memcpyDeviceToHost(tensor5d.data(), gpu_data3, (tensor5d.size()) * sizeof(DataType));

  for (IndexType i = 0; i < 2; ++i) {
    for (IndexType j = 0; j < 3; ++j) {
      for (IndexType k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(tensor5d(i, j, 0, k, 0), tensor(i, j, k));
        if (static_cast<int>(DataLayout) == static_cast<int>(ColMajor)) {
          VERIFY_IS_EQUAL(tensor2d(i + 2 * j, k), tensor(i, j, k));  /// ColMajor
        } else {
          VERIFY_IS_EQUAL(tensor2d(i * 3 + j, k), tensor(i, j, k));  /// RowMajor
        }
      }
    }
  }
  sycl_device.deallocate(gpu_data1);
  sycl_device.deallocate(gpu_data2);
  sycl_device.deallocate(gpu_data3);
}

template <typename DataType, int DataLayout, typename IndexType>
static void test_strided_slice_as_rhs_sycl(const Eigen::SyclDevice& sycl_device) {
  IndexType sizeDim1 = 2;
  IndexType sizeDim2 = 3;
  IndexType sizeDim3 = 5;
  IndexType sizeDim4 = 7;
  IndexType sizeDim5 = 11;
  typedef Eigen::DSizes<IndexType, 5> Index5;
  Index5 strides(1L, 1L, 1L, 1L, 1L);
  Index5 indicesStart(1L, 2L, 3L, 4L, 5L);
  Index5 indicesStop(2L, 3L, 4L, 5L, 6L);
  Index5 lengths(1L, 1L, 1L, 1L, 1L);

  array<IndexType, 5> tensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4, sizeDim5}};
  Tensor<DataType, 5, DataLayout, IndexType> tensor(tensorRange);
  tensor.setRandom();

  array<IndexType, 5> slice1_range = {{1, 1, 1, 1, 1}};
  Tensor<DataType, 5, DataLayout, IndexType> slice1(slice1_range);
  Tensor<DataType, 5, DataLayout, IndexType> slice_stride1(slice1_range);

  DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(tensor.size() * sizeof(DataType)));
  DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(slice1.size() * sizeof(DataType)));
  DataType* gpu_data_stride2 = static_cast<DataType*>(sycl_device.allocate(slice_stride1.size() * sizeof(DataType)));

  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu1(gpu_data1, tensorRange);
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu2(gpu_data2, slice1_range);
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu_stride2(gpu_data_stride2, slice1_range);

  Eigen::DSizes<IndexType, 5> indices(1, 2, 3, 4, 5);
  Eigen::DSizes<IndexType, 5> sizes(1, 1, 1, 1, 1);
  sycl_device.memcpyHostToDevice(gpu_data1, tensor.data(), (tensor.size()) * sizeof(DataType));
  gpu2.device(sycl_device) = gpu1.slice(indices, sizes);
  sycl_device.memcpyDeviceToHost(slice1.data(), gpu_data2, (slice1.size()) * sizeof(DataType));

  gpu_stride2.device(sycl_device) = gpu1.stridedSlice(indicesStart, indicesStop, strides);
  sycl_device.memcpyDeviceToHost(slice_stride1.data(), gpu_data_stride2, (slice_stride1.size()) * sizeof(DataType));

  VERIFY_IS_EQUAL(slice1(0, 0, 0, 0, 0), tensor(1, 2, 3, 4, 5));
  VERIFY_IS_EQUAL(slice_stride1(0, 0, 0, 0, 0), tensor(1, 2, 3, 4, 5));

  array<IndexType, 5> slice2_range = {{1, 1, 2, 2, 3}};
  Tensor<DataType, 5, DataLayout, IndexType> slice2(slice2_range);
  Tensor<DataType, 5, DataLayout, IndexType> strideSlice2(slice2_range);

  DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(slice2.size() * sizeof(DataType)));
  DataType* gpu_data_stride3 = static_cast<DataType*>(sycl_device.allocate(strideSlice2.size() * sizeof(DataType)));
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu3(gpu_data3, slice2_range);
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu_stride3(gpu_data_stride3, slice2_range);
  Eigen::DSizes<IndexType, 5> indices2(1, 1, 3, 4, 5);
  Eigen::DSizes<IndexType, 5> sizes2(1, 1, 2, 2, 3);
  Index5 strides2(1L, 1L, 1L, 1L, 1L);
  Index5 indicesStart2(1L, 1L, 3L, 4L, 5L);
  Index5 indicesStop2(2L, 2L, 5L, 6L, 8L);

  gpu3.device(sycl_device) = gpu1.slice(indices2, sizes2);
  sycl_device.memcpyDeviceToHost(slice2.data(), gpu_data3, (slice2.size()) * sizeof(DataType));

  gpu_stride3.device(sycl_device) = gpu1.stridedSlice(indicesStart2, indicesStop2, strides2);
  sycl_device.memcpyDeviceToHost(strideSlice2.data(), gpu_data_stride3, (strideSlice2.size()) * sizeof(DataType));

  for (IndexType i = 0; i < 2; ++i) {
    for (IndexType j = 0; j < 2; ++j) {
      for (IndexType k = 0; k < 3; ++k) {
        VERIFY_IS_EQUAL(slice2(0, 0, i, j, k), tensor(1, 1, 3 + i, 4 + j, 5 + k));
        VERIFY_IS_EQUAL(strideSlice2(0, 0, i, j, k), tensor(1, 1, 3 + i, 4 + j, 5 + k));
      }
    }
  }
  sycl_device.deallocate(gpu_data1);
  sycl_device.deallocate(gpu_data2);
  sycl_device.deallocate(gpu_data3);
}

template <typename DataType, int DataLayout, typename IndexType>
static void test_strided_slice_write_sycl(const Eigen::SyclDevice& sycl_device) {
  typedef Tensor<DataType, 2, DataLayout, IndexType> Tensor2f;
  typedef Eigen::DSizes<IndexType, 2> Index2;
  IndexType sizeDim1 = 7L;
  IndexType sizeDim2 = 11L;
  array<IndexType, 2> tensorRange = {{sizeDim1, sizeDim2}};
  Tensor<DataType, 2, DataLayout, IndexType> tensor(tensorRange), tensor2(tensorRange);
  IndexType sliceDim1 = 2;
  IndexType sliceDim2 = 3;
  array<IndexType, 2> sliceRange = {{sliceDim1, sliceDim2}};
  Tensor2f slice(sliceRange);
  Index2 strides(1L, 1L);
  Index2 indicesStart(3L, 4L);
  Index2 indicesStop(5L, 7L);
  Index2 lengths(2L, 3L);

  DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(tensor.size() * sizeof(DataType)));
  DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(tensor2.size() * sizeof(DataType)));
  DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(slice.size() * sizeof(DataType)));
  TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> gpu1(gpu_data1, tensorRange);
  TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> gpu2(gpu_data2, tensorRange);
  TensorMap<Tensor<DataType, 2, DataLayout, IndexType>> gpu3(gpu_data3, sliceRange);

  tensor.setRandom();
  sycl_device.memcpyHostToDevice(gpu_data1, tensor.data(), (tensor.size()) * sizeof(DataType));
  gpu2.device(sycl_device) = gpu1;

  slice.setRandom();
  sycl_device.memcpyHostToDevice(gpu_data3, slice.data(), (slice.size()) * sizeof(DataType));

  gpu1.slice(indicesStart, lengths).device(sycl_device) = gpu3;
  gpu2.stridedSlice(indicesStart, indicesStop, strides).device(sycl_device) = gpu3;
  sycl_device.memcpyDeviceToHost(tensor.data(), gpu_data1, (tensor.size()) * sizeof(DataType));
  sycl_device.memcpyDeviceToHost(tensor2.data(), gpu_data2, (tensor2.size()) * sizeof(DataType));

  for (IndexType i = 0; i < sizeDim1; i++)
    for (IndexType j = 0; j < sizeDim2; j++) {
      VERIFY_IS_EQUAL(tensor(i, j), tensor2(i, j));
    }
  sycl_device.deallocate(gpu_data1);
  sycl_device.deallocate(gpu_data2);
  sycl_device.deallocate(gpu_data3);
}

template <typename DataType, int DataLayout, typename IndexType>
static void test_strided_slice_reverse_packet_sycl(const Eigen::SyclDevice& sycl_device) {
  typedef Tensor<DataType, 2, DataLayout, IndexType> Tensor2;
  typedef Eigen::DSizes<IndexType, 2> Index2;

  const array<IndexType, 2> input_range = {{31, 37}};
  const array<IndexType, 2> slice_range = {{29, 34}};
  constexpr bool IsColMajor = static_cast<int>(DataLayout) == static_cast<int>(ColMajor);
  const Index2 strides(IsColMajor ? -1 : 1, IsColMajor ? 1 : -1);
  const Index2 start(IsColMajor ? 29 : 1, IsColMajor ? 2 : 35);
  const Index2 stop(IsColMajor ? 0 : 30, IsColMajor ? 36 : 1);

  Tensor2 input(input_range);
  Tensor2 slice(slice_range);
  Tensor2 src(slice_range);
  Tensor2 dst(input_range);
  Tensor2 dst_ref(input_range);
  input.setRandom();
  src.setRandom();
  dst = input;
  dst_ref = input;

  DataType* gpu_input_data = static_cast<DataType*>(sycl_device.allocate(input.size() * sizeof(DataType)));
  DataType* gpu_slice_data = static_cast<DataType*>(sycl_device.allocate(slice.size() * sizeof(DataType)));
  DataType* gpu_dst_data = static_cast<DataType*>(sycl_device.allocate(dst.size() * sizeof(DataType)));
  TensorMap<Tensor2> gpu_input(gpu_input_data, input_range);
  TensorMap<Tensor2> gpu_slice(gpu_slice_data, slice_range);
  TensorMap<Tensor2> gpu_dst(gpu_dst_data, input_range);

  sycl_device.memcpyHostToDevice(gpu_input_data, input.data(), input.size() * sizeof(DataType));
  gpu_slice.device(sycl_device) = gpu_input.stridedSlice(start, stop, strides);
  sycl_device.memcpyDeviceToHost(slice.data(), gpu_slice_data, slice.size() * sizeof(DataType));
  for (IndexType i = 0; i < slice.dimension(0); ++i) {
    for (IndexType j = 0; j < slice.dimension(1); ++j) {
      VERIFY_IS_EQUAL(slice(i, j), input(start[0] + i * strides[0], start[1] + j * strides[1]));
    }
  }

  sycl_device.memcpyHostToDevice(gpu_slice_data, src.data(), src.size() * sizeof(DataType));
  sycl_device.memcpyHostToDevice(gpu_dst_data, dst.data(), dst.size() * sizeof(DataType));
  gpu_dst.stridedSlice(start, stop, strides).device(sycl_device) = gpu_slice;
  sycl_device.memcpyDeviceToHost(dst.data(), gpu_dst_data, dst.size() * sizeof(DataType));
  for (IndexType i = 0; i < src.dimension(0); ++i) {
    for (IndexType j = 0; j < src.dimension(1); ++j) {
      dst_ref(start[0] + i * strides[0], start[1] + j * strides[1]) = src(i, j);
    }
  }
  for (IndexType i = 0; i < dst.dimension(0); ++i) {
    for (IndexType j = 0; j < dst.dimension(1); ++j) {
      VERIFY_IS_EQUAL(dst(i, j), dst_ref(i, j));
    }
  }

  sycl_device.deallocate(gpu_input_data);
  sycl_device.deallocate(gpu_slice_data);
  sycl_device.deallocate(gpu_dst_data);
}

template <typename OutIndex, typename DSizes>
Eigen::array<OutIndex, DSizes::count> To32BitDims(const DSizes& in) {
  Eigen::array<OutIndex, DSizes::count> out;
  for (int i = 0; i < DSizes::count; ++i) {
    out[i] = in[i];
  }
  return out;
}

template <class DataType, int DataLayout, typename IndexType, typename ConvertedIndexType>
int run_eigen(const SyclDevice& sycl_device) {
  using TensorI64 = Tensor<DataType, 5, DataLayout, IndexType>;
  using TensorI32 = Tensor<DataType, 5, DataLayout, ConvertedIndexType>;
  using TensorMI64 = TensorMap<TensorI64>;
  using TensorMI32 = TensorMap<TensorI32>;
  Eigen::array<IndexType, 5> tensor_range{{4, 1, 1, 1, 6}};
  Eigen::array<IndexType, 5> slice_range{{4, 1, 1, 1, 3}};

  TensorI64 out_tensor_gpu(tensor_range);
  TensorI64 out_tensor_cpu(tensor_range);
  out_tensor_cpu.setRandom();

  TensorI64 sub_tensor(slice_range);
  sub_tensor.setRandom();

  DataType* out_gpu_data = static_cast<DataType*>(sycl_device.allocate(out_tensor_cpu.size() * sizeof(DataType)));
  DataType* sub_gpu_data = static_cast<DataType*>(sycl_device.allocate(sub_tensor.size() * sizeof(DataType)));
  TensorMI64 out_gpu(out_gpu_data, tensor_range);
  TensorMI64 sub_gpu(sub_gpu_data, slice_range);

  sycl_device.memcpyHostToDevice(out_gpu_data, out_tensor_cpu.data(), out_tensor_cpu.size() * sizeof(DataType));
  sycl_device.memcpyHostToDevice(sub_gpu_data, sub_tensor.data(), sub_tensor.size() * sizeof(DataType));

  Eigen::array<ConvertedIndexType, 5> slice_offset_32{{0, 0, 0, 0, 3}};
  Eigen::array<ConvertedIndexType, 5> slice_range_32{{4, 1, 1, 1, 3}};
  TensorMI32 out_cpu_32(out_tensor_cpu.data(), To32BitDims<ConvertedIndexType>(out_tensor_cpu.dimensions()));
  TensorMI32 sub_cpu_32(sub_tensor.data(), To32BitDims<ConvertedIndexType>(sub_tensor.dimensions()));
  TensorMI32 out_gpu_32(out_gpu.data(), To32BitDims<ConvertedIndexType>(out_gpu.dimensions()));
  TensorMI32 sub_gpu_32(sub_gpu.data(), To32BitDims<ConvertedIndexType>(sub_gpu.dimensions()));

  out_gpu_32.slice(slice_offset_32, slice_range_32).device(sycl_device) = sub_gpu_32;

  out_cpu_32.slice(slice_offset_32, slice_range_32) = sub_cpu_32;

  sycl_device.memcpyDeviceToHost(out_tensor_gpu.data(), out_gpu_data, out_tensor_cpu.size() * sizeof(DataType));
  int has_err = 0;
  for (IndexType i = 0; i < out_tensor_cpu.size(); ++i) {
    auto exp = out_tensor_cpu(i);
    auto val = out_tensor_gpu(i);
    if (val != exp) {
      std::cout << "#" << i << " got " << val << " but expected " << exp << std::endl;
      has_err = 1;
    }
  }
  sycl_device.deallocate(out_gpu_data);
  sycl_device.deallocate(sub_gpu_data);
  return has_err;
}

template <typename DataType, typename dev_Selector>
void sycl_morphing_test_per_device(dev_Selector s) {
  QueueInterface queueInterface(s);
  auto sycl_device = Eigen::SyclDevice(&queueInterface);
  test_simple_reshape<DataType, RowMajor, int64_t>(sycl_device);
  test_simple_reshape<DataType, ColMajor, int64_t>(sycl_device);
  test_reshape_as_lvalue<DataType, RowMajor, int64_t>(sycl_device);
  test_reshape_as_lvalue<DataType, ColMajor, int64_t>(sycl_device);
  test_strided_slice_write_sycl<DataType, ColMajor, int64_t>(sycl_device);
  test_strided_slice_write_sycl<DataType, RowMajor, int64_t>(sycl_device);
  test_strided_slice_reverse_packet_sycl<DataType, ColMajor, int64_t>(sycl_device);
  test_strided_slice_reverse_packet_sycl<DataType, RowMajor, int64_t>(sycl_device);
  test_strided_slice_as_rhs_sycl<DataType, ColMajor, int64_t>(sycl_device);
  test_strided_slice_as_rhs_sycl<DataType, RowMajor, int64_t>(sycl_device);
  run_eigen<float, RowMajor, long, int>(sycl_device);
}
EIGEN_DECLARE_TEST(tensor_morphing_sycl) {
  for (const auto& device : Eigen::get_sycl_supported_devices()) {
    CALL_SUBTEST(sycl_morphing_test_per_device<half>(device));
    CALL_SUBTEST(sycl_morphing_test_per_device<float>(device));
  }
}
