// 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 "main.h"
#include <contrib/Eigen/Tensor>

using Eigen::Tensor;
static const int DataLayout = ColMajor;

template <typename DataType, typename IndexType>
static void test_simple_image_patch_sycl(const Eigen::SyclDevice& sycl_device) {
  IndexType sizeDim1 = 2;
  IndexType sizeDim2 = 3;
  IndexType sizeDim3 = 5;
  IndexType sizeDim4 = 7;
  array<IndexType, 4> tensorColMajorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4}};
  array<IndexType, 4> tensorRowMajorRange = {{sizeDim4, sizeDim3, sizeDim2, sizeDim1}};
  Tensor<DataType, 4, DataLayout, IndexType> tensor_col_major(tensorColMajorRange);
  Tensor<DataType, 4, RowMajor, IndexType> tensor_row_major(tensorRowMajorRange);
  tensor_col_major.setRandom();

  DataType* gpu_data_col_major =
      static_cast<DataType*>(sycl_device.allocate(tensor_col_major.size() * sizeof(DataType)));
  DataType* gpu_data_row_major =
      static_cast<DataType*>(sycl_device.allocate(tensor_row_major.size() * sizeof(DataType)));
  TensorMap<Tensor<DataType, 4, ColMajor, IndexType>> gpu_col_major(gpu_data_col_major, tensorColMajorRange);
  TensorMap<Tensor<DataType, 4, RowMajor, IndexType>> gpu_row_major(gpu_data_row_major, tensorRowMajorRange);

  sycl_device.memcpyHostToDevice(gpu_data_col_major, tensor_col_major.data(),
                                 (tensor_col_major.size()) * sizeof(DataType));
  gpu_row_major.device(sycl_device) = gpu_col_major.swap_layout();
  sycl_device.memcpyDeviceToHost(tensor_row_major.data(), gpu_data_row_major,
                                 (tensor_col_major.size()) * sizeof(DataType));

  VERIFY_IS_EQUAL(tensor_col_major.dimension(0), tensor_row_major.dimension(3));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(1), tensor_row_major.dimension(2));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(2), tensor_row_major.dimension(1));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(3), tensor_row_major.dimension(0));

  // Single pixel patch: ColMajor
  array<IndexType, 5> patchColMajorTensorRange = {{sizeDim1, 1, 1, sizeDim2 * sizeDim3, sizeDim4}};
  Tensor<DataType, 5, DataLayout, IndexType> single_patch_col_major(patchColMajorTensorRange);
  size_t patchTensorBuffSize = single_patch_col_major.size() * sizeof(DataType);
  DataType* gpu_data_single_patch_col_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu_single_patch_col_major(gpu_data_single_patch_col_major,
                                                                                   patchColMajorTensorRange);
  gpu_single_patch_col_major.device(sycl_device) = gpu_col_major.extract_image_patches(1, 1);
  sycl_device.memcpyDeviceToHost(single_patch_col_major.data(), gpu_data_single_patch_col_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(single_patch_col_major.dimension(0), 2);
  VERIFY_IS_EQUAL(single_patch_col_major.dimension(1), 1);
  VERIFY_IS_EQUAL(single_patch_col_major.dimension(2), 1);
  VERIFY_IS_EQUAL(single_patch_col_major.dimension(3), 3 * 5);
  VERIFY_IS_EQUAL(single_patch_col_major.dimension(4), 7);

  // Single pixel patch: RowMajor
  array<IndexType, 5> patchRowMajorTensorRange = {{sizeDim4, sizeDim2 * sizeDim3, 1, 1, sizeDim1}};
  Tensor<DataType, 5, RowMajor, IndexType> single_patch_row_major(patchRowMajorTensorRange);
  patchTensorBuffSize = single_patch_row_major.size() * sizeof(DataType);
  DataType* gpu_data_single_patch_row_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, RowMajor, IndexType>> gpu_single_patch_row_major(gpu_data_single_patch_row_major,
                                                                                 patchRowMajorTensorRange);
  gpu_single_patch_row_major.device(sycl_device) = gpu_row_major.extract_image_patches(1, 1);
  sycl_device.memcpyDeviceToHost(single_patch_row_major.data(), gpu_data_single_patch_row_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(single_patch_row_major.dimension(0), 7);
  VERIFY_IS_EQUAL(single_patch_row_major.dimension(1), 3 * 5);
  VERIFY_IS_EQUAL(single_patch_row_major.dimension(2), 1);
  VERIFY_IS_EQUAL(single_patch_row_major.dimension(3), 1);
  VERIFY_IS_EQUAL(single_patch_row_major.dimension(4), 2);

  for (IndexType i = 0; i < tensor_col_major.size(); ++i) {
    // ColMajor
    if (tensor_col_major.data()[i] != single_patch_col_major.data()[i]) {
      std::cout << "Mismatch detected at index colmajor " << i << " : " << tensor_col_major.data()[i] << " vs "
                << single_patch_col_major.data()[i] << std::endl;
    }
    VERIFY_IS_EQUAL(single_patch_col_major.data()[i], tensor_col_major.data()[i]);
    // RowMajor
    if (tensor_row_major.data()[i] != single_patch_row_major.data()[i]) {
      std::cout << "Mismatch detected at index row major" << i << " : " << tensor_row_major.data()[i] << " vs "
                << single_patch_row_major.data()[i] << std::endl;
    }
    VERIFY_IS_EQUAL(single_patch_row_major.data()[i], tensor_row_major.data()[i]);
    VERIFY_IS_EQUAL(tensor_col_major.data()[i], tensor_row_major.data()[i]);
    VERIFY_IS_EQUAL(single_patch_col_major.data()[i], single_patch_row_major.data()[i]);
  }

  // Entire image patch: ColMajor
  patchColMajorTensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim2 * sizeDim3, sizeDim4}};
  Tensor<DataType, 5, DataLayout, IndexType> entire_image_patch_col_major(patchColMajorTensorRange);
  patchTensorBuffSize = entire_image_patch_col_major.size() * sizeof(DataType);
  DataType* gpu_data_entire_image_patch_col_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu_entire_image_patch_col_major(
      gpu_data_entire_image_patch_col_major, patchColMajorTensorRange);
  gpu_entire_image_patch_col_major.device(sycl_device) = gpu_col_major.extract_image_patches(3, 5);
  sycl_device.memcpyDeviceToHost(entire_image_patch_col_major.data(), gpu_data_entire_image_patch_col_major,
                                 patchTensorBuffSize);

  VERIFY_IS_EQUAL(entire_image_patch_col_major.dimension(0), 2);
  VERIFY_IS_EQUAL(entire_image_patch_col_major.dimension(1), 3);
  VERIFY_IS_EQUAL(entire_image_patch_col_major.dimension(2), 5);
  VERIFY_IS_EQUAL(entire_image_patch_col_major.dimension(3), 3 * 5);
  VERIFY_IS_EQUAL(entire_image_patch_col_major.dimension(4), 7);

  // Entire image patch: RowMajor
  patchRowMajorTensorRange = {{sizeDim4, sizeDim2 * sizeDim3, sizeDim3, sizeDim2, sizeDim1}};
  Tensor<DataType, 5, RowMajor, IndexType> entire_image_patch_row_major(patchRowMajorTensorRange);
  patchTensorBuffSize = entire_image_patch_row_major.size() * sizeof(DataType);
  DataType* gpu_data_entire_image_patch_row_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, RowMajor, IndexType>> gpu_entire_image_patch_row_major(
      gpu_data_entire_image_patch_row_major, patchRowMajorTensorRange);
  gpu_entire_image_patch_row_major.device(sycl_device) = gpu_row_major.extract_image_patches(3, 5);
  sycl_device.memcpyDeviceToHost(entire_image_patch_row_major.data(), gpu_data_entire_image_patch_row_major,
                                 patchTensorBuffSize);

  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(0), 7);
  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(1), 3 * 5);
  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(2), 5);
  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(3), 3);
  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(4), 2);

  for (IndexType i = 0; i < 3; ++i) {
    for (IndexType j = 0; j < 5; ++j) {
      IndexType patchId = i + 3 * j;
      for (IndexType r = 0; r < 3; ++r) {
        for (IndexType c = 0; c < 5; ++c) {
          for (IndexType d = 0; d < 2; ++d) {
            for (IndexType b = 0; b < 7; ++b) {
              DataType expected_col_major = 0.0f;
              DataType expected_row_major = 0.0f;
              if (r - 1 + i >= 0 && c - 2 + j >= 0 && r - 1 + i < 3 && c - 2 + j < 5) {
                expected_col_major = tensor_col_major(d, r - 1 + i, c - 2 + j, b);
                expected_row_major = tensor_row_major(b, c - 2 + j, r - 1 + i, d);
              }
              // ColMajor
              if (entire_image_patch_col_major(d, r, c, patchId, b) != expected_col_major) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(entire_image_patch_col_major(d, r, c, patchId, b), expected_col_major);
              // RowMajor
              if (entire_image_patch_row_major(b, patchId, c, r, d) != expected_row_major) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(entire_image_patch_row_major(b, patchId, c, r, d), expected_row_major);
              // Check that ColMajor and RowMajor agree.
              VERIFY_IS_EQUAL(expected_col_major, expected_row_major);
            }
          }
        }
      }
    }
  }

  // 2D patch: ColMajor
  patchColMajorTensorRange = {{sizeDim1, 2, 2, sizeDim2 * sizeDim3, sizeDim4}};
  Tensor<DataType, 5, DataLayout, IndexType> twod_patch_col_major(patchColMajorTensorRange);
  patchTensorBuffSize = twod_patch_col_major.size() * sizeof(DataType);
  DataType* gpu_data_twod_patch_col_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu_twod_patch_col_major(gpu_data_twod_patch_col_major,
                                                                                 patchColMajorTensorRange);
  gpu_twod_patch_col_major.device(sycl_device) = gpu_col_major.extract_image_patches(2, 2);
  sycl_device.memcpyDeviceToHost(twod_patch_col_major.data(), gpu_data_twod_patch_col_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(twod_patch_col_major.dimension(0), 2);
  VERIFY_IS_EQUAL(twod_patch_col_major.dimension(1), 2);
  VERIFY_IS_EQUAL(twod_patch_col_major.dimension(2), 2);
  VERIFY_IS_EQUAL(twod_patch_col_major.dimension(3), 3 * 5);
  VERIFY_IS_EQUAL(twod_patch_col_major.dimension(4), 7);

  // 2D patch: RowMajor
  patchRowMajorTensorRange = {{sizeDim4, sizeDim2 * sizeDim3, 2, 2, sizeDim1}};
  Tensor<DataType, 5, RowMajor, IndexType> twod_patch_row_major(patchRowMajorTensorRange);
  patchTensorBuffSize = twod_patch_row_major.size() * sizeof(DataType);
  DataType* gpu_data_twod_patch_row_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, RowMajor, IndexType>> gpu_twod_patch_row_major(gpu_data_twod_patch_row_major,
                                                                               patchRowMajorTensorRange);
  gpu_twod_patch_row_major.device(sycl_device) = gpu_row_major.extract_image_patches(2, 2);
  sycl_device.memcpyDeviceToHost(twod_patch_row_major.data(), gpu_data_twod_patch_row_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(0), 7);
  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(1), 3 * 5);
  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(2), 2);
  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(3), 2);
  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(4), 2);

  // Based on the calculation described in TensorTraits.h, padding happens to be 0.
  IndexType row_padding = 0;
  IndexType col_padding = 0;
  IndexType stride = 1;

  for (IndexType i = 0; i < 3; ++i) {
    for (IndexType j = 0; j < 5; ++j) {
      IndexType patchId = i + 3 * j;
      for (IndexType r = 0; r < 2; ++r) {
        for (IndexType c = 0; c < 2; ++c) {
          for (IndexType d = 0; d < 2; ++d) {
            for (IndexType b = 0; b < 7; ++b) {
              DataType expected_col_major = 0.0f;
              DataType expected_row_major = 0.0f;
              IndexType row_offset = r * stride + i - row_padding;
              IndexType col_offset = c * stride + j - col_padding;
              // ColMajor
              if (row_offset >= 0 && col_offset >= 0 && row_offset < tensor_col_major.dimension(1) &&
                  col_offset < tensor_col_major.dimension(2)) {
                expected_col_major = tensor_col_major(d, row_offset, col_offset, b);
              }
              if (twod_patch_col_major(d, r, c, patchId, b) != expected_col_major) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(twod_patch_col_major(d, r, c, patchId, b), expected_col_major);

              // RowMajor
              if (row_offset >= 0 && col_offset >= 0 && row_offset < tensor_row_major.dimension(2) &&
                  col_offset < tensor_row_major.dimension(1)) {
                expected_row_major = tensor_row_major(b, col_offset, row_offset, d);
              }
              if (twod_patch_row_major(b, patchId, c, r, d) != expected_row_major) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(twod_patch_row_major(b, patchId, c, r, d), expected_row_major);
              // Check that ColMajor and RowMajor agree.
              VERIFY_IS_EQUAL(expected_col_major, expected_row_major);
            }
          }
        }
      }
    }
  }

  sycl_device.deallocate(gpu_data_col_major);
  sycl_device.deallocate(gpu_data_row_major);
  sycl_device.deallocate(gpu_data_single_patch_col_major);
  sycl_device.deallocate(gpu_data_single_patch_row_major);
  sycl_device.deallocate(gpu_data_entire_image_patch_col_major);
  sycl_device.deallocate(gpu_data_entire_image_patch_row_major);
  sycl_device.deallocate(gpu_data_twod_patch_col_major);
  sycl_device.deallocate(gpu_data_twod_patch_row_major);
}

// Verifies VALID padding (no padding) with incrementing values.
template <typename DataType, typename IndexType>
static void test_patch_padding_valid_sycl(const Eigen::SyclDevice& sycl_device) {
  IndexType input_depth = 3;
  IndexType input_rows = 3;
  IndexType input_cols = 3;
  IndexType input_batches = 1;
  IndexType ksize = 2;   // Corresponds to the Rows and Cols for tensor.extract_image_patches<>.
  IndexType stride = 2;  // Only same stride is supported.

  array<IndexType, 4> tensorColMajorRange = {{input_depth, input_rows, input_cols, input_batches}};
  array<IndexType, 4> tensorRowMajorRange = {{input_batches, input_cols, input_rows, input_depth}};
  Tensor<DataType, 4, DataLayout, IndexType> tensor_col_major(tensorColMajorRange);
  Tensor<DataType, 4, RowMajor, IndexType> tensor_row_major(tensorRowMajorRange);

  DataType* gpu_data_col_major =
      static_cast<DataType*>(sycl_device.allocate(tensor_col_major.size() * sizeof(DataType)));
  DataType* gpu_data_row_major =
      static_cast<DataType*>(sycl_device.allocate(tensor_row_major.size() * sizeof(DataType)));
  TensorMap<Tensor<DataType, 4, ColMajor, IndexType>> gpu_col_major(gpu_data_col_major, tensorColMajorRange);
  TensorMap<Tensor<DataType, 4, RowMajor, IndexType>> gpu_row_major(gpu_data_row_major, tensorRowMajorRange);

  sycl_device.memcpyHostToDevice(gpu_data_col_major, tensor_col_major.data(),
                                 (tensor_col_major.size()) * sizeof(DataType));
  gpu_row_major.device(sycl_device) = gpu_col_major.swap_layout();
  sycl_device.memcpyDeviceToHost(tensor_row_major.data(), gpu_data_row_major,
                                 (tensor_col_major.size()) * sizeof(DataType));

  VERIFY_IS_EQUAL(tensor_col_major.dimension(0), tensor_row_major.dimension(3));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(1), tensor_row_major.dimension(2));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(2), tensor_row_major.dimension(1));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(3), tensor_row_major.dimension(0));

  // Initializes tensor with incrementing numbers.
  for (IndexType i = 0; i < tensor_col_major.size(); ++i) {
    tensor_col_major.data()[i] = i + 1;
  }
  // ColMajor
  array<IndexType, 5> patchColMajorTensorRange = {{input_depth, ksize, ksize, 1, input_batches}};
  Tensor<DataType, 5, DataLayout, IndexType> result_col_major(patchColMajorTensorRange);
  size_t patchTensorBuffSize = result_col_major.size() * sizeof(DataType);
  DataType* gpu_data_result_col_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu_result_col_major(gpu_data_result_col_major,
                                                                             patchColMajorTensorRange);
  gpu_result_col_major.device(sycl_device) =
      gpu_col_major.extract_image_patches(ksize, ksize, stride, stride, 1, 1, PADDING_VALID);
  sycl_device.memcpyDeviceToHost(result_col_major.data(), gpu_data_result_col_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(result_col_major.dimension(0), input_depth);    // depth
  VERIFY_IS_EQUAL(result_col_major.dimension(1), ksize);          // kernel rows
  VERIFY_IS_EQUAL(result_col_major.dimension(2), ksize);          // kernel cols
  VERIFY_IS_EQUAL(result_col_major.dimension(3), 1);              // number of patches
  VERIFY_IS_EQUAL(result_col_major.dimension(4), input_batches);  // number of batches

  // RowMajor
  array<IndexType, 5> patchRowMajorTensorRange = {{input_batches, 1, ksize, ksize, input_depth}};
  Tensor<DataType, 5, RowMajor, IndexType> result_row_major(patchRowMajorTensorRange);
  patchTensorBuffSize = result_row_major.size() * sizeof(DataType);
  DataType* gpu_data_result_row_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, RowMajor, IndexType>> gpu_result_row_major(gpu_data_result_row_major,
                                                                           patchRowMajorTensorRange);
  gpu_result_row_major.device(sycl_device) =
      gpu_row_major.extract_image_patches(ksize, ksize, stride, stride, 1, 1, PADDING_VALID);
  sycl_device.memcpyDeviceToHost(result_row_major.data(), gpu_data_result_row_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(result_col_major.dimension(0), result_row_major.dimension(4));
  VERIFY_IS_EQUAL(result_col_major.dimension(1), result_row_major.dimension(3));
  VERIFY_IS_EQUAL(result_col_major.dimension(2), result_row_major.dimension(2));
  VERIFY_IS_EQUAL(result_col_major.dimension(3), result_row_major.dimension(1));
  VERIFY_IS_EQUAL(result_col_major.dimension(4), result_row_major.dimension(0));

  // No padding is carried out.
  IndexType row_padding = 0;
  IndexType col_padding = 0;

  for (IndexType i = 0; (i + stride + ksize - 1) < input_rows; i += stride) {    // input rows
    for (IndexType j = 0; (j + stride + ksize - 1) < input_cols; j += stride) {  // input cols
      IndexType patchId = i + input_rows * j;
      for (IndexType r = 0; r < ksize; ++r) {                // patch rows
        for (IndexType c = 0; c < ksize; ++c) {              // patch cols
          for (IndexType d = 0; d < input_depth; ++d) {      // depth
            for (IndexType b = 0; b < input_batches; ++b) {  // batch
              DataType expected_col_major = 0.0f;
              DataType expected_row_major = 0.0f;
              IndexType row_offset = r + i - row_padding;
              IndexType col_offset = c + j - col_padding;
              if (row_offset >= 0 && col_offset >= 0 && row_offset < input_rows && col_offset < input_cols) {
                expected_col_major = tensor_col_major(d, row_offset, col_offset, b);
                expected_row_major = tensor_row_major(b, col_offset, row_offset, d);
              }
              // ColMajor
              if (result_col_major(d, r, c, patchId, b) != expected_col_major) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(result_col_major(d, r, c, patchId, b), expected_col_major);
              // RowMajor
              if (result_row_major(b, patchId, c, r, d) != expected_row_major) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(result_row_major(b, patchId, c, r, d), expected_row_major);
              // Check that ColMajor and RowMajor agree.
              VERIFY_IS_EQUAL(expected_col_major, expected_row_major);
            }
          }
        }
      }
    }
  }
  sycl_device.deallocate(gpu_data_col_major);
  sycl_device.deallocate(gpu_data_row_major);
  sycl_device.deallocate(gpu_data_result_col_major);
  sycl_device.deallocate(gpu_data_result_row_major);
}

// Verifies VALID padding (no padding) with the same value.
template <typename DataType, typename IndexType>
static void test_patch_padding_valid_same_value_sycl(const Eigen::SyclDevice& sycl_device) {
  IndexType input_depth = 1;
  IndexType input_rows = 5;
  IndexType input_cols = 5;
  IndexType input_batches = 2;
  IndexType ksize = 3;   // Corresponds to the Rows and Cols for tensor.extract_image_patches<>.
  IndexType stride = 2;  // Only same stride is supported.
  // ColMajor

  array<IndexType, 4> tensorColMajorRange = {{input_depth, input_rows, input_cols, input_batches}};
  array<IndexType, 4> tensorRowMajorRange = {{input_batches, input_cols, input_rows, input_depth}};
  Tensor<DataType, 4, DataLayout, IndexType> tensor_col_major(tensorColMajorRange);
  Tensor<DataType, 4, RowMajor, IndexType> tensor_row_major(tensorRowMajorRange);

  DataType* gpu_data_col_major =
      static_cast<DataType*>(sycl_device.allocate(tensor_col_major.size() * sizeof(DataType)));
  DataType* gpu_data_row_major =
      static_cast<DataType*>(sycl_device.allocate(tensor_row_major.size() * sizeof(DataType)));
  TensorMap<Tensor<DataType, 4, ColMajor, IndexType>> gpu_col_major(gpu_data_col_major, tensorColMajorRange);
  TensorMap<Tensor<DataType, 4, RowMajor, IndexType>> gpu_row_major(gpu_data_row_major, tensorRowMajorRange);
  gpu_col_major.device(sycl_device) = gpu_col_major.constant(11.0f);
  gpu_row_major.device(sycl_device) = gpu_col_major.swap_layout();
  sycl_device.memcpyDeviceToHost(tensor_col_major.data(), gpu_data_col_major,
                                 (tensor_col_major.size()) * sizeof(DataType));
  sycl_device.memcpyDeviceToHost(tensor_row_major.data(), gpu_data_row_major,
                                 (tensor_row_major.size()) * sizeof(DataType));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(0), tensor_row_major.dimension(3));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(1), tensor_row_major.dimension(2));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(2), tensor_row_major.dimension(1));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(3), tensor_row_major.dimension(0));

  array<IndexType, 5> patchColMajorTensorRange = {{input_depth, ksize, ksize, 4, input_batches}};
  Tensor<DataType, 5, DataLayout, IndexType> result_col_major(patchColMajorTensorRange);
  size_t patchTensorBuffSize = result_col_major.size() * sizeof(DataType);
  DataType* gpu_data_result_col_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu_result_col_major(gpu_data_result_col_major,
                                                                             patchColMajorTensorRange);
  gpu_result_col_major.device(sycl_device) =
      gpu_col_major.extract_image_patches(ksize, ksize, stride, stride, 1, 1, PADDING_VALID);
  sycl_device.memcpyDeviceToHost(result_col_major.data(), gpu_data_result_col_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(result_col_major.dimension(0), input_depth);    // depth
  VERIFY_IS_EQUAL(result_col_major.dimension(1), ksize);          // kernel rows
  VERIFY_IS_EQUAL(result_col_major.dimension(2), ksize);          // kernel cols
  VERIFY_IS_EQUAL(result_col_major.dimension(3), 4);              // number of patches
  VERIFY_IS_EQUAL(result_col_major.dimension(4), input_batches);  // number of batches

  // RowMajor
  array<IndexType, 5> patchRowMajorTensorRange = {{input_batches, 4, ksize, ksize, input_depth}};
  Tensor<DataType, 5, RowMajor, IndexType> result_row_major(patchRowMajorTensorRange);
  patchTensorBuffSize = result_row_major.size() * sizeof(DataType);
  DataType* gpu_data_result_row_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, RowMajor, IndexType>> gpu_result_row_major(gpu_data_result_row_major,
                                                                           patchRowMajorTensorRange);
  gpu_result_row_major.device(sycl_device) =
      gpu_row_major.extract_image_patches(ksize, ksize, stride, stride, 1, 1, PADDING_VALID);
  sycl_device.memcpyDeviceToHost(result_row_major.data(), gpu_data_result_row_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(result_col_major.dimension(0), result_row_major.dimension(4));
  VERIFY_IS_EQUAL(result_col_major.dimension(1), result_row_major.dimension(3));
  VERIFY_IS_EQUAL(result_col_major.dimension(2), result_row_major.dimension(2));
  VERIFY_IS_EQUAL(result_col_major.dimension(3), result_row_major.dimension(1));
  VERIFY_IS_EQUAL(result_col_major.dimension(4), result_row_major.dimension(0));

  // No padding is carried out.
  IndexType row_padding = 0;
  IndexType col_padding = 0;

  for (IndexType i = 0; (i + stride + ksize - 1) <= input_rows; i += stride) {    // input rows
    for (IndexType j = 0; (j + stride + ksize - 1) <= input_cols; j += stride) {  // input cols
      IndexType patchId = i + input_rows * j;
      for (IndexType r = 0; r < ksize; ++r) {                // patch rows
        for (IndexType c = 0; c < ksize; ++c) {              // patch cols
          for (IndexType d = 0; d < input_depth; ++d) {      // depth
            for (IndexType b = 0; b < input_batches; ++b) {  // batch
              DataType expected_col_major = 0.0f;
              DataType expected_row_major = 0.0f;
              IndexType row_offset = r + i - row_padding;
              IndexType col_offset = c + j - col_padding;
              if (row_offset >= 0 && col_offset >= 0 && row_offset < input_rows && col_offset < input_cols) {
                expected_col_major = tensor_col_major(d, row_offset, col_offset, b);
                expected_row_major = tensor_row_major(b, col_offset, row_offset, d);
              }
              // ColMajor
              if (result_col_major(d, r, c, patchId, b) != expected_col_major) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(result_col_major(d, r, c, patchId, b), expected_col_major);
              // RowMajor
              if (result_row_major(b, patchId, c, r, d) != expected_row_major) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(result_row_major(b, patchId, c, r, d), expected_row_major);
              // Check that ColMajor and RowMajor agree.
              VERIFY_IS_EQUAL(expected_col_major, expected_row_major);
            }
          }
        }
      }
    }
  }
}

// Verifies SAME padding.
template <typename DataType, typename IndexType>
static void test_patch_padding_same_sycl(const Eigen::SyclDevice& sycl_device) {
  IndexType input_depth = 3;
  IndexType input_rows = 4;
  IndexType input_cols = 2;
  IndexType input_batches = 1;
  IndexType ksize = 2;   // Corresponds to the Rows and Cols for tensor.extract_image_patches<>.
  IndexType stride = 2;  // Only same stride is supported.

  // ColMajor
  array<IndexType, 4> tensorColMajorRange = {{input_depth, input_rows, input_cols, input_batches}};
  array<IndexType, 4> tensorRowMajorRange = {{input_batches, input_cols, input_rows, input_depth}};
  Tensor<DataType, 4, DataLayout, IndexType> tensor_col_major(tensorColMajorRange);
  Tensor<DataType, 4, RowMajor, IndexType> tensor_row_major(tensorRowMajorRange);

  DataType* gpu_data_col_major =
      static_cast<DataType*>(sycl_device.allocate(tensor_col_major.size() * sizeof(DataType)));
  DataType* gpu_data_row_major =
      static_cast<DataType*>(sycl_device.allocate(tensor_row_major.size() * sizeof(DataType)));
  TensorMap<Tensor<DataType, 4, ColMajor, IndexType>> gpu_col_major(gpu_data_col_major, tensorColMajorRange);
  TensorMap<Tensor<DataType, 4, RowMajor, IndexType>> gpu_row_major(gpu_data_row_major, tensorRowMajorRange);

  sycl_device.memcpyHostToDevice(gpu_data_col_major, tensor_col_major.data(),
                                 (tensor_col_major.size()) * sizeof(DataType));
  gpu_row_major.device(sycl_device) = gpu_col_major.swap_layout();
  sycl_device.memcpyDeviceToHost(tensor_row_major.data(), gpu_data_row_major,
                                 (tensor_col_major.size()) * sizeof(DataType));

  VERIFY_IS_EQUAL(tensor_col_major.dimension(0), tensor_row_major.dimension(3));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(1), tensor_row_major.dimension(2));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(2), tensor_row_major.dimension(1));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(3), tensor_row_major.dimension(0));

  // Initializes tensor with incrementing numbers.
  for (IndexType i = 0; i < tensor_col_major.size(); ++i) {
    tensor_col_major.data()[i] = i + 1;
  }

  array<IndexType, 5> patchColMajorTensorRange = {{input_depth, ksize, ksize, 2, input_batches}};
  Tensor<DataType, 5, DataLayout, IndexType> result_col_major(patchColMajorTensorRange);
  size_t patchTensorBuffSize = result_col_major.size() * sizeof(DataType);
  DataType* gpu_data_result_col_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu_result_col_major(gpu_data_result_col_major,
                                                                             patchColMajorTensorRange);
  gpu_result_col_major.device(sycl_device) =
      gpu_col_major.extract_image_patches(ksize, ksize, stride, stride, PADDING_SAME);
  sycl_device.memcpyDeviceToHost(result_col_major.data(), gpu_data_result_col_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(result_col_major.dimension(0), input_depth);    // depth
  VERIFY_IS_EQUAL(result_col_major.dimension(1), ksize);          // kernel rows
  VERIFY_IS_EQUAL(result_col_major.dimension(2), ksize);          // kernel cols
  VERIFY_IS_EQUAL(result_col_major.dimension(3), 2);              // number of patches
  VERIFY_IS_EQUAL(result_col_major.dimension(4), input_batches);  // number of batches

  // RowMajor

  array<IndexType, 5> patchRowMajorTensorRange = {{input_batches, 2, ksize, ksize, input_depth}};
  Tensor<DataType, 5, RowMajor, IndexType> result_row_major(patchRowMajorTensorRange);
  patchTensorBuffSize = result_row_major.size() * sizeof(DataType);
  DataType* gpu_data_result_row_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, RowMajor, IndexType>> gpu_result_row_major(gpu_data_result_row_major,
                                                                           patchRowMajorTensorRange);
  gpu_result_row_major.device(sycl_device) =
      gpu_row_major.extract_image_patches(ksize, ksize, stride, stride, PADDING_SAME);
  sycl_device.memcpyDeviceToHost(result_row_major.data(), gpu_data_result_row_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(result_col_major.dimension(0), result_row_major.dimension(4));
  VERIFY_IS_EQUAL(result_col_major.dimension(1), result_row_major.dimension(3));
  VERIFY_IS_EQUAL(result_col_major.dimension(2), result_row_major.dimension(2));
  VERIFY_IS_EQUAL(result_col_major.dimension(3), result_row_major.dimension(1));
  VERIFY_IS_EQUAL(result_col_major.dimension(4), result_row_major.dimension(0));

  // Based on the calculation described in TensorTraits.h, padding happens to be 0.
  IndexType row_padding = 0;
  IndexType col_padding = 0;

  for (IndexType i = 0; (i + stride + ksize - 1) <= input_rows; i += stride) {    // input rows
    for (IndexType j = 0; (j + stride + ksize - 1) <= input_cols; j += stride) {  // input cols
      IndexType patchId = i + input_rows * j;
      for (IndexType r = 0; r < ksize; ++r) {                // patch rows
        for (IndexType c = 0; c < ksize; ++c) {              // patch cols
          for (IndexType d = 0; d < input_depth; ++d) {      // depth
            for (IndexType b = 0; b < input_batches; ++b) {  // batch
              DataType expected_col_major = 0.0f;
              DataType expected_row_major = 0.0f;
              IndexType row_offset = r * stride + i - row_padding;
              IndexType col_offset = c * stride + j - col_padding;
              if (row_offset >= 0 && col_offset >= 0 && row_offset < input_rows && col_offset < input_cols) {
                expected_col_major = tensor_col_major(d, row_offset, col_offset, b);
                expected_row_major = tensor_row_major(b, col_offset, row_offset, d);
              }
              // ColMajor
              if (result_col_major(d, r, c, patchId, b) != expected_col_major) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(result_col_major(d, r, c, patchId, b), expected_col_major);
              // RowMajor
              if (result_row_major(b, patchId, c, r, d) != expected_row_major) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(result_row_major(b, patchId, c, r, d), expected_row_major);
              // Check that ColMajor and RowMajor agree.
              VERIFY_IS_EQUAL(expected_col_major, expected_row_major);
            }
          }
        }
      }
    }
  }
}

template <typename DataType, typename IndexType>
static void test_patch_no_extra_dim_sycl(const Eigen::SyclDevice& sycl_device) {
  IndexType sizeDim1 = 2;
  IndexType sizeDim2 = 3;
  IndexType sizeDim3 = 5;

  // ColMajor
  array<IndexType, 3> tensorColMajorRange = {{sizeDim1, sizeDim2, sizeDim3}};
  array<IndexType, 3> tensorRowMajorRange = {{sizeDim3, sizeDim2, sizeDim1}};
  Tensor<DataType, 3, DataLayout, IndexType> tensor_col_major(tensorColMajorRange);
  tensor_col_major.setRandom();
  Tensor<DataType, 3, RowMajor, IndexType> tensor_row_major(tensorRowMajorRange);

  DataType* gpu_data_col_major =
      static_cast<DataType*>(sycl_device.allocate(tensor_col_major.size() * sizeof(DataType)));
  DataType* gpu_data_row_major =
      static_cast<DataType*>(sycl_device.allocate(tensor_row_major.size() * sizeof(DataType)));
  TensorMap<Tensor<DataType, 3, ColMajor, IndexType>> gpu_col_major(gpu_data_col_major, tensorColMajorRange);
  TensorMap<Tensor<DataType, 3, RowMajor, IndexType>> gpu_row_major(gpu_data_row_major, tensorRowMajorRange);

  sycl_device.memcpyHostToDevice(gpu_data_col_major, tensor_col_major.data(),
                                 (tensor_col_major.size()) * sizeof(DataType));
  gpu_row_major.device(sycl_device) = gpu_col_major.swap_layout();
  sycl_device.memcpyDeviceToHost(tensor_row_major.data(), gpu_data_row_major,
                                 (tensor_row_major.size()) * sizeof(DataType));

  VERIFY_IS_EQUAL(tensor_col_major.dimension(0), tensor_row_major.dimension(2));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(1), tensor_row_major.dimension(1));
  VERIFY_IS_EQUAL(tensor_col_major.dimension(2), tensor_row_major.dimension(0));

  // Single pixel patch: ColMajor
  array<IndexType, 4> patchColMajorTensorRange = {{sizeDim1, 1, 1, sizeDim2 * sizeDim3}};
  Tensor<DataType, 4, DataLayout, IndexType> single_patch_col_major(patchColMajorTensorRange);
  size_t patchTensorBuffSize = single_patch_col_major.size() * sizeof(DataType);
  DataType* gpu_data_single_patch_col_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 4, DataLayout, IndexType>> gpu_single_patch_col_major(gpu_data_single_patch_col_major,
                                                                                   patchColMajorTensorRange);
  gpu_single_patch_col_major.device(sycl_device) = gpu_col_major.extract_image_patches(1, 1);
  sycl_device.memcpyDeviceToHost(single_patch_col_major.data(), gpu_data_single_patch_col_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(single_patch_col_major.dimension(0), sizeDim1);
  VERIFY_IS_EQUAL(single_patch_col_major.dimension(1), 1);
  VERIFY_IS_EQUAL(single_patch_col_major.dimension(2), 1);
  VERIFY_IS_EQUAL(single_patch_col_major.dimension(3), sizeDim2 * sizeDim3);

  // Single pixel patch: RowMajor
  array<IndexType, 4> patchRowMajorTensorRange = {{sizeDim2 * sizeDim3, 1, 1, sizeDim1}};
  Tensor<DataType, 4, RowMajor, IndexType> single_patch_row_major(patchRowMajorTensorRange);
  patchTensorBuffSize = single_patch_row_major.size() * sizeof(DataType);
  DataType* gpu_data_single_patch_row_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 4, RowMajor, IndexType>> gpu_single_patch_row_major(gpu_data_single_patch_row_major,
                                                                                 patchRowMajorTensorRange);
  gpu_single_patch_row_major.device(sycl_device) = gpu_row_major.extract_image_patches(1, 1);
  sycl_device.memcpyDeviceToHost(single_patch_row_major.data(), gpu_data_single_patch_row_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(single_patch_row_major.dimension(0), sizeDim2 * sizeDim3);
  VERIFY_IS_EQUAL(single_patch_row_major.dimension(1), 1);
  VERIFY_IS_EQUAL(single_patch_row_major.dimension(2), 1);
  VERIFY_IS_EQUAL(single_patch_row_major.dimension(3), sizeDim1);

  for (IndexType i = 0; i < tensor_col_major.size(); ++i) {
    // ColMajor
    if (tensor_col_major.data()[i] != single_patch_col_major.data()[i]) {
      std::cout << "Mismatch detected at index " << i << " : " << tensor_col_major.data()[i] << " vs "
                << single_patch_col_major.data()[i] << std::endl;
    }
    VERIFY_IS_EQUAL(single_patch_col_major.data()[i], tensor_col_major.data()[i]);
    // RowMajor
    if (tensor_row_major.data()[i] != single_patch_row_major.data()[i]) {
      std::cout << "Mismatch detected at index " << i << " : " << tensor_col_major.data()[i] << " vs "
                << single_patch_row_major.data()[i] << std::endl;
    }
    VERIFY_IS_EQUAL(single_patch_row_major.data()[i], tensor_row_major.data()[i]);
    VERIFY_IS_EQUAL(tensor_col_major.data()[i], tensor_row_major.data()[i]);
    VERIFY_IS_EQUAL(single_patch_col_major.data()[i], single_patch_row_major.data()[i]);
  }

  // Entire image patch: ColMajor
  patchColMajorTensorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim2 * sizeDim3}};
  Tensor<DataType, 4, DataLayout, IndexType> entire_image_patch_col_major(patchColMajorTensorRange);
  patchTensorBuffSize = entire_image_patch_col_major.size() * sizeof(DataType);
  DataType* gpu_data_entire_image_patch_col_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 4, DataLayout, IndexType>> gpu_entire_image_patch_col_major(
      gpu_data_entire_image_patch_col_major, patchColMajorTensorRange);
  gpu_entire_image_patch_col_major.device(sycl_device) = gpu_col_major.extract_image_patches(3, 5);
  sycl_device.memcpyDeviceToHost(entire_image_patch_col_major.data(), gpu_data_entire_image_patch_col_major,
                                 patchTensorBuffSize);

  VERIFY_IS_EQUAL(entire_image_patch_col_major.dimension(0), 2);
  VERIFY_IS_EQUAL(entire_image_patch_col_major.dimension(1), 3);
  VERIFY_IS_EQUAL(entire_image_patch_col_major.dimension(2), 5);
  VERIFY_IS_EQUAL(entire_image_patch_col_major.dimension(3), 3 * 5);

  // Entire image patch: RowMajor
  patchRowMajorTensorRange = {{sizeDim2 * sizeDim3, sizeDim3, sizeDim2, sizeDim1}};
  Tensor<DataType, 4, RowMajor, IndexType> entire_image_patch_row_major(patchRowMajorTensorRange);
  patchTensorBuffSize = entire_image_patch_row_major.size() * sizeof(DataType);
  DataType* gpu_data_entire_image_patch_row_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 4, RowMajor, IndexType>> gpu_entire_image_patch_row_major(
      gpu_data_entire_image_patch_row_major, patchRowMajorTensorRange);
  gpu_entire_image_patch_row_major.device(sycl_device) = gpu_row_major.extract_image_patches(3, 5);
  sycl_device.memcpyDeviceToHost(entire_image_patch_row_major.data(), gpu_data_entire_image_patch_row_major,
                                 patchTensorBuffSize);
  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(0), 3 * 5);
  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(1), 5);
  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(2), 3);
  VERIFY_IS_EQUAL(entire_image_patch_row_major.dimension(3), 2);

  for (IndexType i = 0; i < 3; ++i) {
    for (IndexType j = 0; j < 5; ++j) {
      IndexType patchId = i + 3 * j;
      for (IndexType r = 0; r < 3; ++r) {
        for (IndexType c = 0; c < 5; ++c) {
          for (IndexType d = 0; d < 2; ++d) {
            DataType expected_col_major = 0.0f;
            DataType expected_row_major = 0.0f;
            if (r - 1 + i >= 0 && c - 2 + j >= 0 && r - 1 + i < 3 && c - 2 + j < 5) {
              expected_col_major = tensor_col_major(d, r - 1 + i, c - 2 + j);
              expected_row_major = tensor_row_major(c - 2 + j, r - 1 + i, d);
            }
            // ColMajor
            if (entire_image_patch_col_major(d, r, c, patchId) != expected_col_major) {
              std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d
                        << std::endl;
            }
            VERIFY_IS_EQUAL(entire_image_patch_col_major(d, r, c, patchId), expected_col_major);
            // RowMajor
            if (entire_image_patch_row_major(patchId, c, r, d) != expected_row_major) {
              std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d
                        << std::endl;
            }
            VERIFY_IS_EQUAL(entire_image_patch_row_major(patchId, c, r, d), expected_row_major);
            // Check that ColMajor and RowMajor agree.
            VERIFY_IS_EQUAL(expected_col_major, expected_row_major);
          }
        }
      }
    }
  }

  // 2D patch: ColMajor
  patchColMajorTensorRange = {{sizeDim1, 2, 2, sizeDim2 * sizeDim3}};
  Tensor<DataType, 4, DataLayout, IndexType> twod_patch_col_major(patchColMajorTensorRange);
  patchTensorBuffSize = twod_patch_col_major.size() * sizeof(DataType);
  DataType* gpu_data_twod_patch_col_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 4, DataLayout, IndexType>> gpu_twod_patch_col_major(gpu_data_twod_patch_col_major,
                                                                                 patchColMajorTensorRange);
  gpu_twod_patch_col_major.device(sycl_device) = gpu_col_major.extract_image_patches(2, 2);
  sycl_device.memcpyDeviceToHost(twod_patch_col_major.data(), gpu_data_twod_patch_col_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(twod_patch_col_major.dimension(0), 2);
  VERIFY_IS_EQUAL(twod_patch_col_major.dimension(1), 2);
  VERIFY_IS_EQUAL(twod_patch_col_major.dimension(2), 2);
  VERIFY_IS_EQUAL(twod_patch_col_major.dimension(3), 3 * 5);

  // 2D patch: RowMajor
  patchRowMajorTensorRange = {{sizeDim2 * sizeDim3, 2, 2, sizeDim1}};
  Tensor<DataType, 4, RowMajor, IndexType> twod_patch_row_major(patchRowMajorTensorRange);
  patchTensorBuffSize = twod_patch_row_major.size() * sizeof(DataType);
  DataType* gpu_data_twod_patch_row_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 4, RowMajor, IndexType>> gpu_twod_patch_row_major(gpu_data_twod_patch_row_major,
                                                                               patchRowMajorTensorRange);
  gpu_twod_patch_row_major.device(sycl_device) = gpu_row_major.extract_image_patches(2, 2);
  sycl_device.memcpyDeviceToHost(twod_patch_row_major.data(), gpu_data_twod_patch_row_major, patchTensorBuffSize);
  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(0), 3 * 5);
  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(1), 2);
  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(2), 2);
  VERIFY_IS_EQUAL(twod_patch_row_major.dimension(3), 2);

  // Based on the calculation described in TensorTraits.h, padding happens to be 0.
  IndexType row_padding = 0;
  IndexType col_padding = 0;
  IndexType stride = 1;

  for (IndexType i = 0; i < 3; ++i) {
    for (IndexType j = 0; j < 5; ++j) {
      IndexType patchId = i + 3 * j;
      for (IndexType r = 0; r < 2; ++r) {
        for (IndexType c = 0; c < 2; ++c) {
          for (IndexType d = 0; d < 2; ++d) {
            DataType expected_col_major = 0.0f;
            DataType expected_row_major = 0.0f;
            IndexType row_offset = r * stride + i - row_padding;
            IndexType col_offset = c * stride + j - col_padding;
            // ColMajor
            if (row_offset >= 0 && col_offset >= 0 && row_offset < tensor_col_major.dimension(1) &&
                col_offset < tensor_col_major.dimension(2)) {
              expected_col_major = tensor_col_major(d, row_offset, col_offset);
            }
            if (twod_patch_col_major(d, r, c, patchId) != expected_col_major) {
              std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d
                        << std::endl;
            }
            VERIFY_IS_EQUAL(twod_patch_col_major(d, r, c, patchId), expected_col_major);
            // RowMajor
            if (row_offset >= 0 && col_offset >= 0 && row_offset < tensor_row_major.dimension(1) &&
                col_offset < tensor_row_major.dimension(0)) {
              expected_row_major = tensor_row_major(col_offset, row_offset, d);
            }
            if (twod_patch_row_major(patchId, c, r, d) != expected_row_major) {
              std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c << " d=" << d
                        << std::endl;
            }
            VERIFY_IS_EQUAL(twod_patch_row_major(patchId, c, r, d), expected_row_major);
            // Check that ColMajor and RowMajor agree.
            VERIFY_IS_EQUAL(expected_col_major, expected_row_major);
          }
        }
      }
    }
  }

  sycl_device.deallocate(gpu_data_col_major);
  sycl_device.deallocate(gpu_data_row_major);
  sycl_device.deallocate(gpu_data_single_patch_col_major);
  sycl_device.deallocate(gpu_data_single_patch_row_major);
  sycl_device.deallocate(gpu_data_entire_image_patch_col_major);
  sycl_device.deallocate(gpu_data_entire_image_patch_row_major);
  sycl_device.deallocate(gpu_data_twod_patch_col_major);
  sycl_device.deallocate(gpu_data_twod_patch_row_major);
}

template <typename DataType, typename IndexType>
static void test_imagenet_patches_sycl(const Eigen::SyclDevice& sycl_device) {
  // Test the code on typical configurations used by the 'imagenet' benchmarks at
  // https://github.com/soumith/convnet-benchmarks
  // ColMajor
  IndexType sizeDim1 = 3;
  IndexType sizeDim2 = 128;
  IndexType sizeDim3 = 128;
  IndexType sizeDim4 = 16;
  array<IndexType, 4> tensorColMajorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4}};
  Tensor<DataType, 4, DataLayout, IndexType> l_in_col_major(tensorColMajorRange);
  l_in_col_major.setRandom();

  DataType* gpu_data_l_in_col_major =
      static_cast<DataType*>(sycl_device.allocate(l_in_col_major.size() * sizeof(DataType)));
  TensorMap<Tensor<DataType, 4, ColMajor, IndexType>> gpu_l_in_col_major(gpu_data_l_in_col_major, tensorColMajorRange);

  sycl_device.memcpyHostToDevice(gpu_data_l_in_col_major, l_in_col_major.data(),
                                 (l_in_col_major.size()) * sizeof(DataType));

  array<IndexType, 5> patchTensorRange = {{sizeDim1, 11, 11, sizeDim2 * sizeDim3, sizeDim4}};
  Tensor<DataType, 5, DataLayout, IndexType> l_out_col_major(patchTensorRange);
  size_t patchTensorBuffSize = l_out_col_major.size() * sizeof(DataType);
  DataType* gpu_data_l_out_col_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu_l_out_col_major(gpu_data_l_out_col_major, patchTensorRange);
  gpu_l_out_col_major.device(sycl_device) = gpu_l_in_col_major.extract_image_patches(11, 11);
  sycl_device.memcpyDeviceToHost(l_out_col_major.data(), gpu_data_l_out_col_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(l_out_col_major.dimension(0), sizeDim1);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(1), 11);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(2), 11);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(3), sizeDim2 * sizeDim3);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(4), sizeDim4);

  // RowMajor
  patchTensorRange = {{sizeDim4, sizeDim2 * sizeDim3, 11, 11, sizeDim1}};
  Tensor<DataType, 5, RowMajor, IndexType> l_out_row_major(patchTensorRange);
  patchTensorBuffSize = l_out_row_major.size() * sizeof(DataType);
  DataType* gpu_data_l_out_row_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, RowMajor, IndexType>> gpu_l_out_row_major(gpu_data_l_out_row_major, patchTensorRange);
  gpu_l_out_row_major.device(sycl_device) = gpu_l_in_col_major.swap_layout().extract_image_patches(11, 11);
  sycl_device.memcpyDeviceToHost(l_out_row_major.data(), gpu_data_l_out_row_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(l_out_row_major.dimension(0), sizeDim4);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(1), sizeDim2 * sizeDim3);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(2), 11);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(3), 11);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(4), sizeDim1);

  for (IndexType b = 0; b < 16; ++b) {
    for (IndexType i = 0; i < 128; ++i) {
      for (IndexType j = 0; j < 128; ++j) {
        IndexType patchId = i + 128 * j;
        for (IndexType c = 0; c < 11; ++c) {
          for (IndexType r = 0; r < 11; ++r) {
            for (IndexType d = 0; d < 3; ++d) {
              DataType expected = 0.0f;
              if (r - 5 + i >= 0 && c - 5 + j >= 0 && r - 5 + i < 128 && c - 5 + j < 128) {
                expected = l_in_col_major(d, r - 5 + i, c - 5 + j, b);
              }
              // ColMajor
              if (l_out_col_major(d, r, c, patchId, b) != expected) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(l_out_col_major(d, r, c, patchId, b), expected);
              // RowMajor
              if (l_out_row_major(b, patchId, c, r, d) != expected) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(l_out_row_major(b, patchId, c, r, d), expected);
            }
          }
        }
      }
    }
  }

  // ColMajor
  sycl_device.deallocate(gpu_data_l_in_col_major);
  sycl_device.deallocate(gpu_data_l_out_col_major);
  sizeDim1 = 16;
  sizeDim2 = 64;
  sizeDim3 = 64;
  sizeDim4 = 32;
  tensorColMajorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4}};
  l_in_col_major.resize(tensorColMajorRange);
  l_in_col_major.setRandom();
  gpu_data_l_in_col_major = static_cast<DataType*>(sycl_device.allocate(l_in_col_major.size() * sizeof(DataType)));
  TensorMap<Tensor<DataType, 4, ColMajor, IndexType>> gpu_l_in_col_major_resize1(gpu_data_l_in_col_major,
                                                                                 tensorColMajorRange);

  patchTensorRange = {{sizeDim1, 9, 9, sizeDim2 * sizeDim3, sizeDim4}};
  l_out_col_major.resize(patchTensorRange);
  patchTensorBuffSize = l_out_col_major.size() * sizeof(DataType);
  gpu_data_l_out_col_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu_l_out_col_major_resize1(gpu_data_l_out_col_major,
                                                                                    patchTensorRange);
  sycl_device.memcpyHostToDevice(gpu_data_l_in_col_major, l_in_col_major.data(),
                                 (l_in_col_major.size()) * sizeof(DataType));
  gpu_l_out_col_major_resize1.device(sycl_device) = gpu_l_in_col_major_resize1.extract_image_patches(9, 9);
  sycl_device.memcpyDeviceToHost(l_out_col_major.data(), gpu_data_l_out_col_major, patchTensorBuffSize);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(0), 16);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(1), 9);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(2), 9);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(3), 64 * 64);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(4), 32);

  // RowMajor
  sycl_device.deallocate(gpu_data_l_out_row_major);
  patchTensorRange = {{sizeDim4, sizeDim2 * sizeDim3, 9, 9, sizeDim1}};
  l_out_row_major.resize(patchTensorRange);
  patchTensorBuffSize = l_out_row_major.size() * sizeof(DataType);
  gpu_data_l_out_row_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, RowMajor, IndexType>> gpu_l_out_row_major_resize1(gpu_data_l_out_row_major,
                                                                                  patchTensorRange);
  gpu_l_out_row_major_resize1.device(sycl_device) =
      gpu_l_in_col_major_resize1.swap_layout().extract_image_patches(9, 9);
  sycl_device.memcpyDeviceToHost(l_out_row_major.data(), gpu_data_l_out_row_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(l_out_row_major.dimension(0), 32);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(1), 64 * 64);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(2), 9);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(3), 9);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(4), 16);

  for (IndexType b = 0; b < 32; ++b) {
    for (IndexType i = 0; i < 64; ++i) {
      for (IndexType j = 0; j < 64; ++j) {
        IndexType patchId = i + 64 * j;
        for (IndexType c = 0; c < 9; ++c) {
          for (IndexType r = 0; r < 9; ++r) {
            for (IndexType d = 0; d < 16; ++d) {
              DataType expected = 0.0f;
              if (r - 4 + i >= 0 && c - 4 + j >= 0 && r - 4 + i < 64 && c - 4 + j < 64) {
                expected = l_in_col_major(d, r - 4 + i, c - 4 + j, b);
              }
              // ColMajor
              if (l_out_col_major(d, r, c, patchId, b) != expected) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(l_out_col_major(d, r, c, patchId, b), expected);
              // RowMajor
              if (l_out_row_major(b, patchId, c, r, d) != expected) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(l_out_row_major(b, patchId, c, r, d), expected);
            }
          }
        }
      }
    }
  }

  // ColMajor

  sycl_device.deallocate(gpu_data_l_in_col_major);
  sycl_device.deallocate(gpu_data_l_out_col_major);
  sizeDim1 = 32;
  sizeDim2 = 16;
  sizeDim3 = 16;
  sizeDim4 = 32;
  tensorColMajorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4}};
  l_in_col_major.resize(tensorColMajorRange);
  l_in_col_major.setRandom();
  gpu_data_l_in_col_major = static_cast<DataType*>(sycl_device.allocate(l_in_col_major.size() * sizeof(DataType)));
  TensorMap<Tensor<DataType, 4, ColMajor, IndexType>> gpu_l_in_col_major_resize2(gpu_data_l_in_col_major,
                                                                                 tensorColMajorRange);

  patchTensorRange = {{sizeDim1, 7, 7, sizeDim2 * sizeDim3, sizeDim4}};
  l_out_col_major.resize(patchTensorRange);
  patchTensorBuffSize = l_out_col_major.size() * sizeof(DataType);
  gpu_data_l_out_col_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu_l_out_col_major_resize2(gpu_data_l_out_col_major,
                                                                                    patchTensorRange);
  sycl_device.memcpyHostToDevice(gpu_data_l_in_col_major, l_in_col_major.data(),
                                 (l_in_col_major.size()) * sizeof(DataType));
  gpu_l_out_col_major_resize2.device(sycl_device) = gpu_l_in_col_major_resize2.extract_image_patches(7, 7);
  sycl_device.memcpyDeviceToHost(l_out_col_major.data(), gpu_data_l_out_col_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(l_out_col_major.dimension(0), 32);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(1), 7);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(2), 7);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(3), 16 * 16);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(4), 32);

  // RowMajor
  sycl_device.deallocate(gpu_data_l_out_row_major);
  patchTensorRange = {{sizeDim4, sizeDim2 * sizeDim3, 7, 7, sizeDim1}};
  l_out_row_major.resize(patchTensorRange);
  patchTensorBuffSize = l_out_row_major.size() * sizeof(DataType);
  gpu_data_l_out_row_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, RowMajor, IndexType>> gpu_l_out_row_major_resize2(gpu_data_l_out_row_major,
                                                                                  patchTensorRange);
  gpu_l_out_row_major_resize2.device(sycl_device) =
      gpu_l_in_col_major_resize2.swap_layout().extract_image_patches(7, 7);
  sycl_device.memcpyDeviceToHost(l_out_row_major.data(), gpu_data_l_out_row_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(l_out_row_major.dimension(0), 32);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(1), 16 * 16);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(2), 7);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(3), 7);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(4), 32);

  for (IndexType b = 0; b < 32; ++b) {
    for (IndexType i = 0; i < 16; ++i) {
      for (IndexType j = 0; j < 16; ++j) {
        IndexType patchId = i + 16 * j;
        for (IndexType c = 0; c < 7; ++c) {
          for (IndexType r = 0; r < 7; ++r) {
            for (IndexType d = 0; d < 32; ++d) {
              DataType expected = 0.0f;
              if (r - 3 + i >= 0 && c - 3 + j >= 0 && r - 3 + i < 16 && c - 3 + j < 16) {
                expected = l_in_col_major(d, r - 3 + i, c - 3 + j, b);
              }
              // ColMajor
              if (l_out_col_major(d, r, c, patchId, b) != expected) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(l_out_col_major(d, r, c, patchId, b), expected);
              // RowMajor
              if (l_out_row_major(b, patchId, c, r, d) != expected) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(l_out_row_major(b, patchId, c, r, d), expected);
            }
          }
        }
      }
    }
  }

  // ColMajor
  sycl_device.deallocate(gpu_data_l_in_col_major);
  sycl_device.deallocate(gpu_data_l_out_col_major);
  sizeDim1 = 64;
  sizeDim2 = 13;
  sizeDim3 = 13;
  sizeDim4 = 32;
  tensorColMajorRange = {{sizeDim1, sizeDim2, sizeDim3, sizeDim4}};
  l_in_col_major.resize(tensorColMajorRange);
  l_in_col_major.setRandom();
  gpu_data_l_in_col_major = static_cast<DataType*>(sycl_device.allocate(l_in_col_major.size() * sizeof(DataType)));
  TensorMap<Tensor<DataType, 4, ColMajor, IndexType>> gpu_l_in_col_major_resize3(gpu_data_l_in_col_major,
                                                                                 tensorColMajorRange);

  patchTensorRange = {{sizeDim1, 3, 3, sizeDim2 * sizeDim3, sizeDim4}};
  l_out_col_major.resize(patchTensorRange);
  patchTensorBuffSize = l_out_col_major.size() * sizeof(DataType);
  gpu_data_l_out_col_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, DataLayout, IndexType>> gpu_l_out_col_major_resize3(gpu_data_l_out_col_major,
                                                                                    patchTensorRange);
  sycl_device.memcpyHostToDevice(gpu_data_l_in_col_major, l_in_col_major.data(),
                                 (l_in_col_major.size()) * sizeof(DataType));
  gpu_l_out_col_major_resize3.device(sycl_device) = gpu_l_in_col_major_resize3.extract_image_patches(3, 3);
  sycl_device.memcpyDeviceToHost(l_out_col_major.data(), gpu_data_l_out_col_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(l_out_col_major.dimension(0), 64);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(1), 3);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(2), 3);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(3), 13 * 13);
  VERIFY_IS_EQUAL(l_out_col_major.dimension(4), 32);

  // RowMajor
  sycl_device.deallocate(gpu_data_l_out_row_major);
  patchTensorRange = {{sizeDim4, sizeDim2 * sizeDim3, 3, 3, sizeDim1}};
  l_out_row_major.resize(patchTensorRange);
  patchTensorBuffSize = l_out_row_major.size() * sizeof(DataType);
  gpu_data_l_out_row_major = static_cast<DataType*>(sycl_device.allocate(patchTensorBuffSize));
  TensorMap<Tensor<DataType, 5, RowMajor, IndexType>> gpu_l_out_row_major_resize3(gpu_data_l_out_row_major,
                                                                                  patchTensorRange);
  gpu_l_out_row_major_resize3.device(sycl_device) =
      gpu_l_in_col_major_resize3.swap_layout().extract_image_patches(3, 3);
  sycl_device.memcpyDeviceToHost(l_out_row_major.data(), gpu_data_l_out_row_major, patchTensorBuffSize);

  VERIFY_IS_EQUAL(l_out_row_major.dimension(0), 32);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(1), 13 * 13);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(2), 3);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(3), 3);
  VERIFY_IS_EQUAL(l_out_row_major.dimension(4), 64);

  for (IndexType b = 0; b < 32; ++b) {
    for (IndexType i = 0; i < 13; ++i) {
      for (IndexType j = 0; j < 13; ++j) {
        IndexType patchId = i + 13 * j;
        for (IndexType c = 0; c < 3; ++c) {
          for (IndexType r = 0; r < 3; ++r) {
            for (IndexType d = 0; d < 64; ++d) {
              DataType expected = 0.0f;
              if (r - 1 + i >= 0 && c - 1 + j >= 0 && r - 1 + i < 13 && c - 1 + j < 13) {
                expected = l_in_col_major(d, r - 1 + i, c - 1 + j, b);
              }
              // ColMajor
              if (l_out_col_major(d, r, c, patchId, b) != expected) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(l_out_col_major(d, r, c, patchId, b), expected);
              // RowMajor
              if (l_out_row_major(b, patchId, c, r, d) != expected) {
                std::cout << "Mismatch detected at index i=" << i << " j=" << j << " r=" << r << " c=" << c
                          << " d=" << d << " b=" << b << std::endl;
              }
              VERIFY_IS_EQUAL(l_out_row_major(b, patchId, c, r, d), expected);
            }
          }
        }
      }
    }
  }
  sycl_device.deallocate(gpu_data_l_in_col_major);
  sycl_device.deallocate(gpu_data_l_out_col_major);
  sycl_device.deallocate(gpu_data_l_out_row_major);
}

template <typename DataType, typename dev_Selector>
void sycl_tensor_image_patch_test_per_device(dev_Selector s) {
  QueueInterface queueInterface(s);
  auto sycl_device = Eigen::SyclDevice(&queueInterface);
  test_simple_image_patch_sycl<DataType, int64_t>(sycl_device);
  test_patch_padding_valid_sycl<DataType, int64_t>(sycl_device);
  test_patch_padding_valid_same_value_sycl<DataType, int64_t>(sycl_device);
  test_patch_padding_same_sycl<DataType, int64_t>(sycl_device);
  test_patch_no_extra_dim_sycl<DataType, int64_t>(sycl_device);
  test_imagenet_patches_sycl<DataType, int64_t>(sycl_device);
}
EIGEN_DECLARE_TEST(tensor_image_patch_sycl) {
  for (const auto& device : Eigen::get_sycl_supported_devices()) {
    CALL_SUBTEST(sycl_tensor_image_patch_test_per_device<float>(device));
  }
}
