// 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>
//
// 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 <iostream>
#include <chrono>
#include <ctime>

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

using Eigen::array;
using Eigen::SyclDevice;
using Eigen::Tensor;
using Eigen::TensorMap;
// Absolute slack for accumulation-order differences between device and host float convolutions.
static const float error_threshold = 1024 * NumTraits<float>::epsilon();

template <typename DataType, int DataLayout, typename IndexType>
static void test_larg_expr1D(const Eigen::SyclDevice& sycl_device) {
  IndexType indim0 = 53;
  IndexType indim1 = 55;
  IndexType indim2 = 51;
  IndexType outdim0 = 50;
  IndexType outdim1 = 55;
  IndexType outdim2 = 51;
  Eigen::array<IndexType, 3> input_dims = {{indim0, indim1, indim2}};
  Eigen::array<IndexType, 1> kernel_dims = {{4}};
  Eigen::array<IndexType, 3> result_dims = {{outdim0, outdim1, outdim2}};

  Tensor<DataType, 3, DataLayout, IndexType> input(input_dims);
  Tensor<DataType, 1, DataLayout, IndexType> kernel(kernel_dims);
  Tensor<DataType, 3, DataLayout, IndexType> result(result_dims);
  Tensor<DataType, 3, DataLayout, IndexType> result_host(result_dims);

  Eigen::array<IndexType, 1> dims3{0};

  input.setRandom();
  kernel.setRandom();
  result.setZero();
  result_host.setZero();

  std::size_t input_bytes = input.size() * sizeof(DataType);
  std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
  std::size_t result_bytes = result.size() * sizeof(DataType);

  DataType* d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
  DataType* d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
  DataType* d_result = static_cast<DataType*>(sycl_device.allocate(result_bytes));

  Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_input(d_input, input_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout, IndexType> > gpu_kernel(d_kernel, kernel_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_result(d_result, result_dims);
  sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
  sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);

  gpu_result.device(sycl_device) = gpu_input.convolve(gpu_kernel, dims3);
  sycl_device.memcpyDeviceToHost(result.data(), d_result, result_bytes);

  result_host = input.convolve(kernel, dims3);

  for (IndexType i = 0; i < outdim0; i++) {
    for (IndexType j = 0; j < outdim1; j++) {
      for (IndexType k = 0; k < outdim2; k++) {
        if (!(Eigen::internal::isApprox(result(i, j, k), result_host(i, j, k), error_threshold))) {
          std::cout << std::setprecision(16) << "mismatch detected at index  ( " << i << " , " << j << ", " << k
                    << " ) "
                    << " \t " << result(i, j, k) << " vs " << result_host(i, j, k) << std::endl;
          assert(false);
        }
      }
    }
  }
  sycl_device.deallocate(d_input);
  sycl_device.deallocate(d_kernel);
  sycl_device.deallocate(d_result);
}

template <typename DataType, int DataLayout, typename IndexType>
static void test_larg_expr2D(const Eigen::SyclDevice& sycl_device) {
  IndexType indim0 = 53;
  IndexType indim1 = 55;
  IndexType indim2 = 51;
  IndexType outdim0 = 50;
  IndexType outdim1 = 51;
  IndexType outdim2 = 51;
  Eigen::array<IndexType, 3> input_dims = {{indim0, indim1, indim2}};
  Eigen::array<IndexType, 2> kernel_dims = {{4, 5}};
  Eigen::array<IndexType, 3> result_dims = {{outdim0, outdim1, outdim2}};

  Tensor<DataType, 3, DataLayout, IndexType> input(input_dims);
  Tensor<DataType, 2, DataLayout, IndexType> kernel(kernel_dims);
  Tensor<DataType, 3, DataLayout, IndexType> result(result_dims);
  Tensor<DataType, 3, DataLayout, IndexType> result_host(result_dims);

  Eigen::array<IndexType, 2> dims3{{0, 1}};

  input.setRandom();
  kernel.setRandom();
  result.setZero();
  result_host.setZero();

  std::size_t input_bytes = input.size() * sizeof(DataType);
  std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
  std::size_t result_bytes = result.size() * sizeof(DataType);

  DataType* d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
  DataType* d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
  DataType* d_result = static_cast<DataType*>(sycl_device.allocate(result_bytes));

  Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_input(d_input, input_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_kernel(d_kernel, kernel_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_result(d_result, result_dims);
  sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
  sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);

  gpu_result.device(sycl_device) = gpu_input.convolve(gpu_kernel, dims3);
  sycl_device.memcpyDeviceToHost(result.data(), d_result, result_bytes);

  result_host = input.convolve(kernel, dims3);

  for (IndexType i = 0; i < outdim0; i++) {
    for (IndexType j = 0; j < outdim1; j++) {
      for (IndexType k = 0; k < outdim2; k++) {
        if (!(Eigen::internal::isApprox(result(i, j, k), result_host(i, j, k), error_threshold))) {
          std::cout << std::setprecision(16) << "mismatch detected at index  ( " << i << " , " << j << ", " << k
                    << " ) "
                    << " \t " << result(i, j, k) << " vs " << result_host(i, j, k) << std::endl;
          assert(false);
        }
      }
    }
  }
  sycl_device.deallocate(d_input);
  sycl_device.deallocate(d_kernel);
  sycl_device.deallocate(d_result);
}

template <typename DataType, int DataLayout, typename IndexType>
static void test_larg_expr3D(const Eigen::SyclDevice& sycl_device) {
  IndexType indim0 = 53;
  IndexType indim1 = 55;
  IndexType indim2 = 51;
  IndexType outdim0 = 50;
  IndexType outdim1 = 51;
  IndexType outdim2 = 49;
  Eigen::array<IndexType, 3> input_dims = {{indim0, indim1, indim2}};
  Eigen::array<IndexType, 3> kernel_dims = {{4, 5, 3}};
  Eigen::array<IndexType, 3> result_dims = {{outdim0, outdim1, outdim2}};

  Tensor<DataType, 3, DataLayout, IndexType> input(input_dims);
  Tensor<DataType, 3, DataLayout, IndexType> kernel(kernel_dims);
  Tensor<DataType, 3, DataLayout, IndexType> result(result_dims);
  Tensor<DataType, 3, DataLayout, IndexType> result_host(result_dims);

  Eigen::array<IndexType, 3> dims3{{0, 1, 2}};

  input.setRandom();
  kernel.setRandom();
  result.setZero();
  result_host.setZero();

  std::size_t input_bytes = input.size() * sizeof(DataType);
  std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
  std::size_t result_bytes = result.size() * sizeof(DataType);

  DataType* d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
  DataType* d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
  DataType* d_result = static_cast<DataType*>(sycl_device.allocate(result_bytes));

  Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_input(d_input, input_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_kernel(d_kernel, kernel_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 3, DataLayout, IndexType> > gpu_result(d_result, result_dims);
  sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
  sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);

  gpu_result.device(sycl_device) = gpu_input.convolve(gpu_kernel, dims3);
  sycl_device.memcpyDeviceToHost(result.data(), d_result, result_bytes);

  result_host = input.convolve(kernel, dims3);

  for (IndexType i = 0; i < outdim0; i++) {
    for (IndexType j = 0; j < outdim1; j++) {
      for (IndexType k = 0; k < outdim2; k++) {
        if (!(Eigen::internal::isApprox(result(i, j, k), result_host(i, j, k), error_threshold))) {
          std::cout << std::setprecision(16) << "mismatch detected at index  ( " << i << " , " << j << ", " << k
                    << " ) "
                    << " \t " << result(i, j, k) << " vs " << result_host(i, j, k) << std::endl;
          assert(false);
        }
      }
    }
  }
  sycl_device.deallocate(d_input);
  sycl_device.deallocate(d_kernel);
  sycl_device.deallocate(d_result);
}

template <typename DataType, int DataLayout, typename IndexType>
static void test_evals(const Eigen::SyclDevice& sycl_device) {
  Eigen::array<IndexType, 2> input_dims = {{3, 3}};
  Eigen::array<IndexType, 1> kernel_dims = {{2}};
  Eigen::array<IndexType, 2> result_dims = {{2, 3}};

  Tensor<DataType, 2, DataLayout, IndexType> input(input_dims);
  Tensor<DataType, 1, DataLayout, IndexType> kernel(kernel_dims);
  Tensor<DataType, 2, DataLayout, IndexType> result(result_dims);

  Eigen::array<IndexType, 1> dims3{0};

  input.setRandom();
  kernel.setRandom();
  result.setZero();

  std::size_t input_bytes = input.size() * sizeof(DataType);
  std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
  std::size_t result_bytes = result.size() * sizeof(DataType);

  DataType* d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
  DataType* d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
  DataType* d_result = static_cast<DataType*>(sycl_device.allocate(result_bytes));

  Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_input(d_input, input_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout, IndexType> > gpu_kernel(d_kernel, kernel_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_result(d_result, result_dims);
  sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
  sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);

  gpu_result.device(sycl_device) = gpu_input.convolve(gpu_kernel, dims3);
  sycl_device.memcpyDeviceToHost(result.data(), d_result, result_bytes);

  VERIFY_IS_APPROX(result(0, 0), input(0, 0) * kernel(0) + input(1, 0) * kernel(1));  // index 0
  VERIFY_IS_APPROX(result(0, 1), input(0, 1) * kernel(0) + input(1, 1) * kernel(1));  // index 2
  VERIFY_IS_APPROX(result(0, 2), input(0, 2) * kernel(0) + input(1, 2) * kernel(1));  // index 4
  VERIFY_IS_APPROX(result(1, 0), input(1, 0) * kernel(0) + input(2, 0) * kernel(1));  // index 1
  VERIFY_IS_APPROX(result(1, 1), input(1, 1) * kernel(0) + input(2, 1) * kernel(1));  // index 3
  VERIFY_IS_APPROX(result(1, 2), input(1, 2) * kernel(0) + input(2, 2) * kernel(1));  // index 5

  sycl_device.deallocate(d_input);
  sycl_device.deallocate(d_kernel);
  sycl_device.deallocate(d_result);
}

template <typename DataType, int DataLayout, typename IndexType>
static void test_expr(const Eigen::SyclDevice& sycl_device) {
  Eigen::array<IndexType, 2> input_dims = {{3, 3}};
  Eigen::array<IndexType, 2> kernel_dims = {{2, 2}};
  Eigen::array<IndexType, 2> result_dims = {{2, 2}};

  Tensor<DataType, 2, DataLayout, IndexType> input(input_dims);
  Tensor<DataType, 2, DataLayout, IndexType> kernel(kernel_dims);
  Tensor<DataType, 2, DataLayout, IndexType> result(result_dims);

  input.setRandom();
  kernel.setRandom();
  Eigen::array<IndexType, 2> dims;
  dims[0] = 0;
  dims[1] = 1;

  std::size_t input_bytes = input.size() * sizeof(DataType);
  std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
  std::size_t result_bytes = result.size() * sizeof(DataType);

  DataType* d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
  DataType* d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
  DataType* d_result = static_cast<DataType*>(sycl_device.allocate(result_bytes));

  Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_input(d_input, input_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_kernel(d_kernel, kernel_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 2, DataLayout, IndexType> > gpu_result(d_result, result_dims);
  sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
  sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);

  gpu_result.device(sycl_device) = gpu_input.convolve(gpu_kernel, dims);
  sycl_device.memcpyDeviceToHost(result.data(), d_result, result_bytes);

  VERIFY_IS_APPROX(result(0, 0), input(0, 0) * kernel(0, 0) + input(0, 1) * kernel(0, 1) + input(1, 0) * kernel(1, 0) +
                                     input(1, 1) * kernel(1, 1));
  VERIFY_IS_APPROX(result(0, 1), input(0, 1) * kernel(0, 0) + input(0, 2) * kernel(0, 1) + input(1, 1) * kernel(1, 0) +
                                     input(1, 2) * kernel(1, 1));
  VERIFY_IS_APPROX(result(1, 0), input(1, 0) * kernel(0, 0) + input(1, 1) * kernel(0, 1) + input(2, 0) * kernel(1, 0) +
                                     input(2, 1) * kernel(1, 1));
  VERIFY_IS_APPROX(result(1, 1), input(1, 1) * kernel(0, 0) + input(1, 2) * kernel(0, 1) + input(2, 1) * kernel(1, 0) +
                                     input(2, 2) * kernel(1, 1));

  sycl_device.deallocate(d_input);
  sycl_device.deallocate(d_kernel);
  sycl_device.deallocate(d_result);
}

template <typename DataType, int DataLayout, typename IndexType>
static void test_modes(const Eigen::SyclDevice& sycl_device) {
  Eigen::array<IndexType, 1> input_dims = {{3}};
  Eigen::array<IndexType, 1> kernel_dims = {{3}};

  Tensor<DataType, 1, DataLayout, IndexType> input(input_dims);
  Tensor<DataType, 1, DataLayout, IndexType> kernel(kernel_dims);

  input.setRandom();
  kernel.setRandom();
  Eigen::array<IndexType, 1> dims;
  dims[0] = 0;

  input(0) = 1.0f;
  input(1) = 2.0f;
  input(2) = 3.0f;
  kernel(0) = 0.5f;
  kernel(1) = 1.0f;
  kernel(2) = 0.0f;

  Eigen::array<std::pair<IndexType, IndexType>, 1> padding;

  // Emulate VALID mode (as defined in
  // http://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html).
  padding[0] = std::make_pair(0, 0);
  Tensor<DataType, 1, DataLayout, IndexType> valid(1);

  std::size_t input_bytes = input.size() * sizeof(DataType);
  std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
  std::size_t valid_bytes = valid.size() * sizeof(DataType);

  DataType* d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
  DataType* d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
  DataType* d_valid = static_cast<DataType*>(sycl_device.allocate(valid_bytes));

  Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout, IndexType> > gpu_input(d_input, input_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout, IndexType> > gpu_kernel(d_kernel, kernel_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout, IndexType> > gpu_valid(d_valid, valid.dimensions());
  sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
  sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);

  gpu_valid.device(sycl_device) = gpu_input.pad(padding).convolve(gpu_kernel, dims);
  sycl_device.memcpyDeviceToHost(valid.data(), d_valid, valid_bytes);

  VERIFY_IS_EQUAL(valid.dimension(0), 1);
  VERIFY_IS_APPROX(valid(0), 2.5f);

  // Emulate SAME mode (as defined in
  // http://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html).
  padding[0] = std::make_pair(1, 1);
  Tensor<DataType, 1, DataLayout, IndexType> same(3);
  std::size_t same_bytes = same.size() * sizeof(DataType);
  DataType* d_same = static_cast<DataType*>(sycl_device.allocate(same_bytes));
  Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout, IndexType> > gpu_same(d_same, same.dimensions());
  gpu_same.device(sycl_device) = gpu_input.pad(padding).convolve(gpu_kernel, dims);
  sycl_device.memcpyDeviceToHost(same.data(), d_same, same_bytes);

  VERIFY_IS_EQUAL(same.dimension(0), 3);
  VERIFY_IS_APPROX(same(0), 1.0f);
  VERIFY_IS_APPROX(same(1), 2.5f);
  VERIFY_IS_APPROX(same(2), 4.0f);

  // Emulate FULL mode (as defined in
  // http://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html).
  padding[0] = std::make_pair(2, 2);

  Tensor<DataType, 1, DataLayout, IndexType> full(5);
  std::size_t full_bytes = full.size() * sizeof(DataType);
  DataType* d_full = static_cast<DataType*>(sycl_device.allocate(full_bytes));
  Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout, IndexType> > gpu_full(d_full, full.dimensions());
  gpu_full.device(sycl_device) = gpu_input.pad(padding).convolve(gpu_kernel, dims);
  sycl_device.memcpyDeviceToHost(full.data(), d_full, full_bytes);

  VERIFY_IS_EQUAL(full.dimension(0), 5);
  VERIFY_IS_APPROX(full(0), 0.0f);
  VERIFY_IS_APPROX(full(1), 1.0f);
  VERIFY_IS_APPROX(full(2), 2.5f);
  VERIFY_IS_APPROX(full(3), 4.0f);
  VERIFY_IS_APPROX(full(4), 1.5f);

  sycl_device.deallocate(d_input);
  sycl_device.deallocate(d_kernel);
  sycl_device.deallocate(d_valid);
  sycl_device.deallocate(d_same);
  sycl_device.deallocate(d_full);
}

template <typename DataType, int DataLayout, typename IndexType>
static void test_strides(const Eigen::SyclDevice& sycl_device) {
  Eigen::array<IndexType, 1> input_dims = {{13}};
  Eigen::array<IndexType, 1> kernel_dims = {{3}};

  Tensor<DataType, 1, DataLayout, IndexType> input(input_dims);
  Tensor<DataType, 1, DataLayout, IndexType> kernel(kernel_dims);
  Tensor<DataType, 1, DataLayout, IndexType> result(2);

  input.setRandom();
  kernel.setRandom();
  Eigen::array<IndexType, 1> dims;
  dims[0] = 0;

  Eigen::array<IndexType, 1> stride_of_3;
  stride_of_3[0] = 3;
  Eigen::array<IndexType, 1> stride_of_2;
  stride_of_2[0] = 2;

  std::size_t input_bytes = input.size() * sizeof(DataType);
  std::size_t kernel_bytes = kernel.size() * sizeof(DataType);
  std::size_t result_bytes = result.size() * sizeof(DataType);

  DataType* d_input = static_cast<DataType*>(sycl_device.allocate(input_bytes));
  DataType* d_kernel = static_cast<DataType*>(sycl_device.allocate(kernel_bytes));
  DataType* d_result = static_cast<DataType*>(sycl_device.allocate(result_bytes));

  Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout, IndexType> > gpu_input(d_input, input_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout, IndexType> > gpu_kernel(d_kernel, kernel_dims);
  Eigen::TensorMap<Eigen::Tensor<DataType, 1, DataLayout, IndexType> > gpu_result(d_result, result.dimensions());
  sycl_device.memcpyHostToDevice(d_input, input.data(), input_bytes);
  sycl_device.memcpyHostToDevice(d_kernel, kernel.data(), kernel_bytes);

  gpu_result.device(sycl_device) = gpu_input.stride(stride_of_3).convolve(gpu_kernel, dims).stride(stride_of_2);
  sycl_device.memcpyDeviceToHost(result.data(), d_result, result_bytes);

  VERIFY_IS_EQUAL(result.dimension(0), 2);
  VERIFY_IS_APPROX(result(0), (input(0) * kernel(0) + input(3) * kernel(1) + input(6) * kernel(2)));
  VERIFY_IS_APPROX(result(1), (input(6) * kernel(0) + input(9) * kernel(1) + input(12) * kernel(2)));
}

template <typename Dev_selector>
void tensorConvolutionPerDevice(Dev_selector& s) {
  QueueInterface queueInterface(s);
  auto sycl_device = Eigen::SyclDevice(&queueInterface);
  test_larg_expr1D<float, RowMajor, int64_t>(sycl_device);
  test_larg_expr1D<float, ColMajor, int64_t>(sycl_device);
  test_larg_expr2D<float, RowMajor, int64_t>(sycl_device);
  test_larg_expr2D<float, ColMajor, int64_t>(sycl_device);
  test_larg_expr3D<float, RowMajor, int64_t>(sycl_device);
  test_larg_expr3D<float, ColMajor, int64_t>(sycl_device);
  test_evals<float, ColMajor, int64_t>(sycl_device);
  test_evals<float, RowMajor, int64_t>(sycl_device);
  test_expr<float, ColMajor, int64_t>(sycl_device);
  test_expr<float, RowMajor, int64_t>(sycl_device);
  test_modes<float, ColMajor, int64_t>(sycl_device);
  test_modes<float, RowMajor, int64_t>(sycl_device);
  test_strides<float, ColMajor, int64_t>(sycl_device);
  test_strides<float, RowMajor, int64_t>(sycl_device);
}

EIGEN_DECLARE_TEST(tensor_convolution_sycl) {
  for (const auto& device : Eigen::get_sycl_supported_devices()) {
    CALL_SUBTEST(tensorConvolutionPerDevice(device));
  }
}
