// 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>
void test_sycl_mem_transfers(const Eigen::SyclDevice& sycl_device) {
  IndexType sizeDim1 = 5;
  IndexType sizeDim2 = 5;
  IndexType sizeDim3 = 1;
  array<IndexType, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
  Tensor<DataType, 3, DataLayout, IndexType> in1(tensorRange);
  Tensor<DataType, 3, DataLayout, IndexType> out1(tensorRange);
  Tensor<DataType, 3, DataLayout, IndexType> out2(tensorRange);
  Tensor<DataType, 3, DataLayout, IndexType> out3(tensorRange);

  in1 = in1.random();

  DataType* gpu_data1 = static_cast<DataType*>(sycl_device.allocate(in1.size() * sizeof(DataType)));
  DataType* gpu_data2 = static_cast<DataType*>(sycl_device.allocate(out1.size() * sizeof(DataType)));

  TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu1(gpu_data1, tensorRange);
  TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu2(gpu_data2, tensorRange);

  sycl_device.memcpyHostToDevice(gpu_data1, in1.data(), (in1.size()) * sizeof(DataType));
  sycl_device.memcpyHostToDevice(gpu_data2, in1.data(), (in1.size()) * sizeof(DataType));
  gpu1.device(sycl_device) = gpu1 * 3.14f;
  gpu2.device(sycl_device) = gpu2 * 2.7f;
  sycl_device.memcpyDeviceToHost(out1.data(), gpu_data1, (out1.size()) * sizeof(DataType));
  sycl_device.memcpyDeviceToHost(out2.data(), gpu_data1, (out2.size()) * sizeof(DataType));
  sycl_device.memcpyDeviceToHost(out3.data(), gpu_data2, (out3.size()) * sizeof(DataType));
  sycl_device.synchronize();

  for (IndexType i = 0; i < in1.size(); ++i) {
    //  std::cout << "SYCL DATA : " << out1(i) << "  vs  CPU DATA : " << in1(i) * 3.14f << "\n";
    VERIFY_IS_APPROX(out1(i), in1(i) * 3.14f);
    VERIFY_IS_APPROX(out2(i), in1(i) * 3.14f);
    VERIFY_IS_APPROX(out3(i), in1(i) * 2.7f);
  }

  sycl_device.deallocate(gpu_data1);
  sycl_device.deallocate(gpu_data2);
}

template <typename DataType, int DataLayout, typename IndexType>
void test_sycl_mem_sync(const Eigen::SyclDevice& sycl_device) {
  IndexType size = 20;
  array<IndexType, 1> tensorRange = {{size}};
  Tensor<DataType, 1, DataLayout, IndexType> in1(tensorRange);
  Tensor<DataType, 1, DataLayout, IndexType> in2(tensorRange);
  Tensor<DataType, 1, DataLayout, IndexType> out(tensorRange);

  in1 = in1.random();
  in2 = in1;

  DataType* gpu_data = static_cast<DataType*>(sycl_device.allocate(in1.size() * sizeof(DataType)));

  TensorMap<Tensor<DataType, 1, DataLayout, IndexType>> gpu1(gpu_data, tensorRange);
  sycl_device.memcpyHostToDevice(gpu_data, in1.data(), (in1.size()) * sizeof(DataType));
  sycl_device.synchronize();
  in1.setZero();

  sycl_device.memcpyDeviceToHost(out.data(), gpu_data, out.size() * sizeof(DataType));
  sycl_device.synchronize();

  for (IndexType i = 0; i < in1.size(); ++i) {
    VERIFY_IS_APPROX(out(i), in2(i));
  }

  sycl_device.deallocate(gpu_data);
}

template <typename DataType, int DataLayout, typename IndexType>
void test_sycl_mem_sync_offsets(const Eigen::SyclDevice& sycl_device) {
  using tensor_type = Tensor<DataType, 1, DataLayout, IndexType>;
  IndexType full_size = 32;
  IndexType half_size = full_size / 2;
  array<IndexType, 1> tensorRange = {{full_size}};
  tensor_type in1(tensorRange);
  tensor_type out(tensorRange);

  DataType* gpu_data = static_cast<DataType*>(sycl_device.allocate(full_size * sizeof(DataType)));
  TensorMap<tensor_type> gpu1(gpu_data, tensorRange);

  in1 = in1.random();
  // Copy all data to device, then permute on copy back to host
  sycl_device.memcpyHostToDevice(gpu_data, in1.data(), full_size * sizeof(DataType));
  sycl_device.memcpyDeviceToHost(out.data(), gpu_data + half_size, half_size * sizeof(DataType));
  sycl_device.memcpyDeviceToHost(out.data() + half_size, gpu_data, half_size * sizeof(DataType));

  for (IndexType i = 0; i < half_size; ++i) {
    VERIFY_IS_APPROX(out(i), in1(i + half_size));
    VERIFY_IS_APPROX(out(i + half_size), in1(i));
  }

  in1 = in1.random();
  out.setZero();
  // Permute copies to device, then copy all back to host
  sycl_device.memcpyHostToDevice(gpu_data + half_size, in1.data(), half_size * sizeof(DataType));
  sycl_device.memcpyHostToDevice(gpu_data, in1.data() + half_size, half_size * sizeof(DataType));
  sycl_device.memcpyDeviceToHost(out.data(), gpu_data, full_size * sizeof(DataType));

  for (IndexType i = 0; i < half_size; ++i) {
    VERIFY_IS_APPROX(out(i), in1(i + half_size));
    VERIFY_IS_APPROX(out(i + half_size), in1(i));
  }

  in1 = in1.random();
  out.setZero();
  DataType* gpu_data_out = static_cast<DataType*>(sycl_device.allocate(full_size * sizeof(DataType)));
  TensorMap<tensor_type> gpu2(gpu_data_out, tensorRange);
  // Copy all to device, permute copies on device, then copy all back to host
  sycl_device.memcpyHostToDevice(gpu_data, in1.data(), full_size * sizeof(DataType));
  sycl_device.memcpy(gpu_data_out + half_size, gpu_data, half_size * sizeof(DataType));
  sycl_device.memcpy(gpu_data_out, gpu_data + half_size, half_size * sizeof(DataType));
  sycl_device.memcpyDeviceToHost(out.data(), gpu_data_out, full_size * sizeof(DataType));

  for (IndexType i = 0; i < half_size; ++i) {
    VERIFY_IS_APPROX(out(i), in1(i + half_size));
    VERIFY_IS_APPROX(out(i + half_size), in1(i));
  }

  sycl_device.deallocate(gpu_data_out);
  sycl_device.deallocate(gpu_data);
}

template <typename DataType, int DataLayout, typename IndexType>
void test_sycl_memset_offsets(const Eigen::SyclDevice& sycl_device) {
  using tensor_type = Tensor<DataType, 1, DataLayout, IndexType>;
  IndexType full_size = 32;
  IndexType half_size = full_size / 2;
  array<IndexType, 1> tensorRange = {{full_size}};
  tensor_type cpu_out(tensorRange);
  tensor_type out(tensorRange);

  cpu_out.setZero();

  std::memset(cpu_out.data(), 0, half_size * sizeof(DataType));
  std::memset(cpu_out.data() + half_size, 1, half_size * sizeof(DataType));

  DataType* gpu_data = static_cast<DataType*>(sycl_device.allocate(full_size * sizeof(DataType)));
  TensorMap<tensor_type> gpu1(gpu_data, tensorRange);

  sycl_device.memset(gpu_data, 0, half_size * sizeof(DataType));
  sycl_device.memset(gpu_data + half_size, 1, half_size * sizeof(DataType));
  sycl_device.memcpyDeviceToHost(out.data(), gpu_data, full_size * sizeof(DataType));

  for (IndexType i = 0; i < full_size; ++i) {
    VERIFY_IS_APPROX(out(i), cpu_out(i));
  }

  sycl_device.deallocate(gpu_data);
}

template <typename DataType, int DataLayout, typename IndexType>
void test_sycl_computations(const Eigen::SyclDevice& sycl_device) {
  IndexType sizeDim1 = 100;
  IndexType sizeDim2 = 10;
  IndexType sizeDim3 = 20;
  array<IndexType, 3> tensorRange = {{sizeDim1, sizeDim2, sizeDim3}};
  Tensor<DataType, 3, DataLayout, IndexType> in1(tensorRange);
  Tensor<DataType, 3, DataLayout, IndexType> in2(tensorRange);
  Tensor<DataType, 3, DataLayout, IndexType> in3(tensorRange);
  Tensor<DataType, 3, DataLayout, IndexType> out(tensorRange);

  in2 = in2.random();
  in3 = in3.random();

  DataType* gpu_in1_data = static_cast<DataType*>(sycl_device.allocate(in1.size() * sizeof(DataType)));
  DataType* gpu_in2_data = static_cast<DataType*>(sycl_device.allocate(in2.size() * sizeof(DataType)));
  DataType* gpu_in3_data = static_cast<DataType*>(sycl_device.allocate(in3.size() * sizeof(DataType)));
  DataType* gpu_out_data = static_cast<DataType*>(sycl_device.allocate(out.size() * sizeof(DataType)));

  TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu_in1(gpu_in1_data, tensorRange);
  TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu_in2(gpu_in2_data, tensorRange);
  TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu_in3(gpu_in3_data, tensorRange);
  TensorMap<Tensor<DataType, 3, DataLayout, IndexType>> gpu_out(gpu_out_data, tensorRange);

  /// a=1.2f
  gpu_in1.device(sycl_device) = gpu_in1.constant(1.2f);
  sycl_device.memcpyDeviceToHost(in1.data(), gpu_in1_data, (in1.size()) * sizeof(DataType));
  sycl_device.synchronize();

  for (IndexType i = 0; i < sizeDim1; ++i) {
    for (IndexType j = 0; j < sizeDim2; ++j) {
      for (IndexType k = 0; k < sizeDim3; ++k) {
        VERIFY_IS_APPROX(in1(i, j, k), 1.2f);
      }
    }
  }
  printf("a=1.2f Test passed\n");

  /// a=b*1.2f
  gpu_out.device(sycl_device) = gpu_in1 * 1.2f;
  sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data, (out.size()) * sizeof(DataType));
  sycl_device.synchronize();

  for (IndexType i = 0; i < sizeDim1; ++i) {
    for (IndexType j = 0; j < sizeDim2; ++j) {
      for (IndexType k = 0; k < sizeDim3; ++k) {
        VERIFY_IS_APPROX(out(i, j, k), in1(i, j, k) * 1.2f);
      }
    }
  }
  printf("a=b*1.2f Test Passed\n");

  /// c=a*b
  sycl_device.memcpyHostToDevice(gpu_in2_data, in2.data(), (in2.size()) * sizeof(DataType));
  gpu_out.device(sycl_device) = gpu_in1 * gpu_in2;
  sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data, (out.size()) * sizeof(DataType));
  sycl_device.synchronize();

  for (IndexType i = 0; i < sizeDim1; ++i) {
    for (IndexType j = 0; j < sizeDim2; ++j) {
      for (IndexType k = 0; k < sizeDim3; ++k) {
        VERIFY_IS_APPROX(out(i, j, k), in1(i, j, k) * in2(i, j, k));
      }
    }
  }
  printf("c=a*b Test Passed\n");

  /// c=a+b
  gpu_out.device(sycl_device) = gpu_in1 + gpu_in2;
  sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data, (out.size()) * sizeof(DataType));
  sycl_device.synchronize();
  for (IndexType i = 0; i < sizeDim1; ++i) {
    for (IndexType j = 0; j < sizeDim2; ++j) {
      for (IndexType k = 0; k < sizeDim3; ++k) {
        VERIFY_IS_APPROX(out(i, j, k), in1(i, j, k) + in2(i, j, k));
      }
    }
  }
  printf("c=a+b Test Passed\n");

  /// c=a*a
  gpu_out.device(sycl_device) = gpu_in1 * gpu_in1;
  sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data, (out.size()) * sizeof(DataType));
  sycl_device.synchronize();
  for (IndexType i = 0; i < sizeDim1; ++i) {
    for (IndexType j = 0; j < sizeDim2; ++j) {
      for (IndexType k = 0; k < sizeDim3; ++k) {
        VERIFY_IS_APPROX(out(i, j, k), in1(i, j, k) * in1(i, j, k));
      }
    }
  }
  printf("c= a*a Test Passed\n");

  // a*3.14f + b*2.7f
  gpu_out.device(sycl_device) = gpu_in1 * gpu_in1.constant(3.14f) + gpu_in2 * gpu_in2.constant(2.7f);
  sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data, (out.size()) * sizeof(DataType));
  sycl_device.synchronize();
  for (IndexType i = 0; i < sizeDim1; ++i) {
    for (IndexType j = 0; j < sizeDim2; ++j) {
      for (IndexType k = 0; k < sizeDim3; ++k) {
        VERIFY_IS_APPROX(out(i, j, k), in1(i, j, k) * 3.14f + in2(i, j, k) * 2.7f);
      }
    }
  }
  printf("a*3.14f + b*2.7f Test Passed\n");

  /// d= (a>0.5? b:c)
  sycl_device.memcpyHostToDevice(gpu_in3_data, in3.data(), (in3.size()) * sizeof(DataType));
  gpu_out.device(sycl_device) = (gpu_in1 > gpu_in1.constant(0.5f)).select(gpu_in2, gpu_in3);
  sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data, (out.size()) * sizeof(DataType));
  sycl_device.synchronize();
  for (IndexType i = 0; i < sizeDim1; ++i) {
    for (IndexType j = 0; j < sizeDim2; ++j) {
      for (IndexType k = 0; k < sizeDim3; ++k) {
        VERIFY_IS_APPROX(out(i, j, k), (in1(i, j, k) > 0.5f) ? in2(i, j, k) : in3(i, j, k));
      }
    }
  }
  printf("d= (a>0.5? b:c) Test Passed\n");
  sycl_device.deallocate(gpu_in1_data);
  sycl_device.deallocate(gpu_in2_data);
  sycl_device.deallocate(gpu_in3_data);
  sycl_device.deallocate(gpu_out_data);
}
template <typename Scalar1, typename Scalar2, int DataLayout, typename IndexType>
static void test_sycl_cast(const Eigen::SyclDevice& sycl_device) {
  IndexType size = 20;
  array<IndexType, 1> tensorRange = {{size}};
  Tensor<Scalar1, 1, DataLayout, IndexType> in(tensorRange);
  Tensor<Scalar2, 1, DataLayout, IndexType> out(tensorRange);
  Tensor<Scalar2, 1, DataLayout, IndexType> out_host(tensorRange);

  in = in.random();

  Scalar1* gpu_in_data = static_cast<Scalar1*>(sycl_device.allocate(in.size() * sizeof(Scalar1)));
  Scalar2* gpu_out_data = static_cast<Scalar2*>(sycl_device.allocate(out.size() * sizeof(Scalar2)));

  TensorMap<Tensor<Scalar1, 1, DataLayout, IndexType>> gpu_in(gpu_in_data, tensorRange);
  TensorMap<Tensor<Scalar2, 1, DataLayout, IndexType>> gpu_out(gpu_out_data, tensorRange);
  sycl_device.memcpyHostToDevice(gpu_in_data, in.data(), (in.size()) * sizeof(Scalar1));
  gpu_out.device(sycl_device) = gpu_in.template cast<Scalar2>();
  sycl_device.memcpyDeviceToHost(out.data(), gpu_out_data, out.size() * sizeof(Scalar2));
  out_host = in.template cast<Scalar2>();
  for (IndexType i = 0; i < size; i++) {
    VERIFY_IS_APPROX(out(i), out_host(i));
  }
  printf("cast Test Passed\n");
  sycl_device.deallocate(gpu_in_data);
  sycl_device.deallocate(gpu_out_data);
}
template <typename DataType, typename dev_Selector>
void sycl_computing_test_per_device(dev_Selector s) {
  QueueInterface queueInterface(s);
  auto sycl_device = Eigen::SyclDevice(&queueInterface);
  test_sycl_mem_transfers<DataType, RowMajor, int64_t>(sycl_device);
  test_sycl_computations<DataType, RowMajor, int64_t>(sycl_device);
  test_sycl_mem_sync<DataType, RowMajor, int64_t>(sycl_device);
  test_sycl_mem_sync_offsets<DataType, RowMajor, int64_t>(sycl_device);
  test_sycl_memset_offsets<DataType, RowMajor, int64_t>(sycl_device);
  test_sycl_mem_transfers<DataType, ColMajor, int64_t>(sycl_device);
  test_sycl_computations<DataType, ColMajor, int64_t>(sycl_device);
  test_sycl_mem_sync<DataType, ColMajor, int64_t>(sycl_device);
  test_sycl_cast<DataType, int, RowMajor, int64_t>(sycl_device);
  test_sycl_cast<DataType, int, ColMajor, int64_t>(sycl_device);
}

EIGEN_DECLARE_TEST(tensor_sycl) {
  for (const auto& device : Eigen::get_sycl_supported_devices()) {
    CALL_SUBTEST(sycl_computing_test_per_device<float>(device));
  }
}
