// 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_simple_slice(const Eigen::SyclDevice& sycl_device) {
  IndexType sizeDim1 = 2;
  IndexType sizeDim2 = 3;
  IndexType sizeDim3 = 5;
  IndexType sizeDim4 = 7;
  IndexType sizeDim5 = 11;
  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);

  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)));
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu1(gpu_data1, tensorRange);
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu2(gpu_data2, 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));
  VERIFY_IS_EQUAL(slice1(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);
  DataType* gpu_data3 = static_cast<DataType*>(sycl_device.allocate(slice2.size() * sizeof(DataType)));
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu3(gpu_data3, slice2_range);
  Eigen::DSizes<IndexType, 5> indices2(1, 1, 3, 4, 5);
  Eigen::DSizes<IndexType, 5> sizes2(1, 1, 2, 2, 3);
  gpu3.device(sycl_device) = gpu1.slice(indices2, sizes2);
  sycl_device.memcpyDeviceToHost(slice2.data(), gpu_data3, (slice2.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));
      }
    }
  }
  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_slice<DataType, RowMajor, int64_t>(sycl_device);
  test_simple_slice<DataType, ColMajor, int64_t>(sycl_device);
  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));
  }
}
