// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2018 Andy Davis <andydavis@google.com>
// Copyright (C) 2018 Eugene Zhulenev <ezhulenev@google.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

#include "main.h"

#include <algorithm>
#include <set>

#include <Eigen/Tensor>

using Eigen::ColMajor;
using Eigen::Index;
using Eigen::RowMajor;
using Eigen::Tensor;
using Eigen::internal::TensorBlockShapeType;

static TensorOpCost zeroCost() { return {0, 0, 0}; }

template <typename T>
static const T& choose(int layout, const T& col, const T& row) {
  return layout == ColMajor ? col : row;
}

static TensorBlockShapeType RandomShape() {
  return internal::random<bool>() ? TensorBlockShapeType::kUniformAllDims : TensorBlockShapeType::kSkewedInnerDims;
}

template <int NumDims>
static size_t RandomTargetSize(const DSizes<Index, NumDims>& dims) {
  return internal::random<size_t>(1, dims.TotalSize());
}

template <int NumDims>
static DSizes<Index, NumDims> RandomDims() {
  array<Index, NumDims> dims;
  for (int i = 0; i < NumDims; ++i) {
    dims[i] = internal::random<int>(1, 20);
  }
  return DSizes<Index, NumDims>(dims);
}

template <typename T>
static T* GenerateRandomData(const Index& size) {
  T* data = new T[size];
  for (int i = 0; i < size; ++i) {
    data[i] = internal::random<T>();
  }
  return data;
}

template <int NumDims>
static void Debug(DSizes<Index, NumDims> dims) {
  for (int i = 0; i < NumDims; ++i) {
    std::cout << dims[i] << "; ";
  }
  std::cout << std::endl;
}

template <int Layout>
static void test_block_mapper_sanity() {
  typedef internal::TensorBlockMapper<2, Layout> TensorBlockMapper;

  DSizes<Index, 2> tensor_dims(100, 100);

  // Test uniform blocks.
  TensorBlockMapper uniform_block_mapper(tensor_dims, {TensorBlockShapeType::kUniformAllDims, 100, zeroCost()});

  VERIFY_IS_EQUAL(uniform_block_mapper.blockCount(), 100);
  VERIFY_IS_EQUAL(uniform_block_mapper.blockTotalSize(), 100);

  // 10x10 blocks
  auto uniform_b0 = uniform_block_mapper.blockDescriptor(0);
  VERIFY_IS_EQUAL(uniform_b0.dimensions().at(0), 10);
  VERIFY_IS_EQUAL(uniform_b0.dimensions().at(1), 10);

  // Test skewed to inner dims blocks.
  TensorBlockMapper skewed_block_mapper(tensor_dims, {TensorBlockShapeType::kSkewedInnerDims, 100, zeroCost()});

  VERIFY_IS_EQUAL(skewed_block_mapper.blockCount(), 100);
  VERIFY_IS_EQUAL(skewed_block_mapper.blockTotalSize(), 100);

  // 1x100 (100x1) rows/cols depending on a tensor layout.
  auto skewed_b0 = skewed_block_mapper.blockDescriptor(0);
  VERIFY_IS_EQUAL(skewed_b0.dimensions().at(0), choose(Layout, 100, 1));
  VERIFY_IS_EQUAL(skewed_b0.dimensions().at(1), choose(Layout, 1, 100));
}

// Given a TensorBlock "visit" every element accessible though it, and a keep an
// index in the visited set. Verify that every coeff accessed only once.
template <int NumDims, int Layout>
static void UpdateCoeffSet(const DSizes<Index, NumDims>& tensor_strides,
                           const internal::TensorBlockDescriptor<NumDims>& block, Index first_coeff_index,
                           int dim_index, std::set<Index>* visited_coeffs) {
  const DSizes<Index, NumDims>& block_sizes = block.dimensions();

  for (int i = 0; i < block_sizes[dim_index]; ++i) {
    if (dim_index == choose(Layout, 0, NumDims - 1)) {
      typedef std::pair<std::set<Index>::iterator, bool> ReturnType;
      ReturnType inserted = visited_coeffs->insert(first_coeff_index + i);
      VERIFY_IS_EQUAL(inserted.second, true);
    } else {
      int next_dim_index = dim_index + choose(Layout, -1, 1);
      UpdateCoeffSet<NumDims, Layout>(tensor_strides, block, first_coeff_index, next_dim_index, visited_coeffs);
      first_coeff_index += tensor_strides[dim_index];
    }
  }
}

template <typename T, int NumDims, int Layout>
static void test_block_mapper_maps_every_element() {
  typedef internal::TensorBlockMapper<NumDims, Layout> TensorBlockMapper;

  DSizes<Index, NumDims> dims = RandomDims<NumDims>();
  DSizes<Index, NumDims> strides = internal::strides<Layout>(dims);

  // Keep track of elements indices available via block access.
  std::set<Index> coeff_set;

  // Try different combinations of block types and sizes.
  TensorBlockMapper block_mapper(dims, {RandomShape(), RandomTargetSize(dims), zeroCost()});

  for (int i = 0; i < block_mapper.blockCount(); ++i) {
    auto block = block_mapper.blockDescriptor(i);
    UpdateCoeffSet<NumDims, Layout>(strides, block, block.offset(), choose(Layout, NumDims - 1, 0), &coeff_set);
  }

  // Verify that every coefficient in the original Tensor is accessible through
  // TensorBlock only once.
  Index total_coeffs = dims.TotalSize();
  VERIFY_IS_EQUAL(Index(coeff_set.size()), total_coeffs);
  VERIFY_IS_EQUAL(*coeff_set.begin(), 0);
  VERIFY_IS_EQUAL(*coeff_set.rbegin(), total_coeffs - 1);
}

template <typename Scalar, typename StorageIndex, int Dim>
class EqualityChecker {
  const Scalar* input_data;
  const DSizes<StorageIndex, Dim>&input_dims, &input_strides, &output_dims, &output_strides;
  void check_recursive(const Scalar* input, const Scalar* output, int depth = 0) const {
    if (depth == Dim) {
      VERIFY_IS_EQUAL(*input, *output);
      return;
    }

    for (int i = 0; i < output_dims[depth]; ++i) {
      check_recursive(input + i % input_dims[depth] * input_strides[depth], output + i * output_strides[depth],
                      depth + 1);
    }
  }

 public:
  EqualityChecker(const Scalar* input_data_, const DSizes<StorageIndex, Dim>& input_dims_,
                  const DSizes<StorageIndex, Dim>& input_strides_, const DSizes<StorageIndex, Dim>& output_dims_,
                  const DSizes<StorageIndex, Dim>& output_strides_)
      : input_data(input_data_),
        input_dims(input_dims_),
        input_strides(input_strides_),
        output_dims(output_dims_),
        output_strides(output_strides_) {}

  void operator()(const Scalar* output_data) const { check_recursive(input_data, output_data); }
};

template <int Layout>
static void test_uniform_block_shape() {
  typedef internal::TensorBlockDescriptor<5> TensorBlock;
  typedef internal::TensorBlockMapper<5, Layout> TensorBlockMapper;

  {
    // Test shape 'UniformAllDims' with uniform 'max_coeff count'.
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 5 * 5 * 5 * 5 * 5;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    for (int i = 0; i < 5; ++i) {
      VERIFY_IS_EQUAL(5, block.dimensions()[i]);
    }
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  }

  // Test shape 'UniformAllDims' with larger 'max_coeff count' which spills
  // partially into first inner-most dimension.
  EIGEN_IF_CONSTEXPR (Layout == ColMajor) {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 7 * 5 * 5 * 5 * 5;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(7, block.dimensions()[0]);
    for (int i = 1; i < 5; ++i) {
      VERIFY_IS_EQUAL(5, block.dimensions()[i]);
    }
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  } else {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 5 * 5 * 5 * 5 * 6;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(6, block.dimensions()[4]);
    for (int i = 3; i >= 0; --i) {
      VERIFY_IS_EQUAL(5, block.dimensions()[i]);
    }
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  }

  // Test shape 'UniformAllDims' with larger 'max_coeff count' which spills
  // fully into first inner-most dimension.
  EIGEN_IF_CONSTEXPR (Layout == ColMajor) {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 11 * 5 * 5 * 5 * 5;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(11, block.dimensions()[0]);
    for (int i = 1; i < 5; ++i) {
      VERIFY_IS_EQUAL(5, block.dimensions()[i]);
    }
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  } else {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 5 * 5 * 5 * 5 * 7;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(7, block.dimensions()[4]);
    for (int i = 3; i >= 0; --i) {
      VERIFY_IS_EQUAL(5, block.dimensions()[i]);
    }
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  }

  // Test shape 'UniformAllDims' with larger 'max_coeff count' which spills
  // fully into first few inner-most dimensions.
  EIGEN_IF_CONSTEXPR (Layout == ColMajor) {
    DSizes<Index, 5> dims(7, 5, 6, 17, 7);
    const Index max_coeff_count = 7 * 5 * 6 * 7 * 5;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(7, block.dimensions()[0]);
    VERIFY_IS_EQUAL(5, block.dimensions()[1]);
    VERIFY_IS_EQUAL(6, block.dimensions()[2]);
    VERIFY_IS_EQUAL(7, block.dimensions()[3]);
    VERIFY_IS_EQUAL(5, block.dimensions()[4]);
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  } else {
    DSizes<Index, 5> dims(7, 5, 6, 9, 7);
    const Index max_coeff_count = 5 * 5 * 5 * 6 * 7;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(7, block.dimensions()[4]);
    VERIFY_IS_EQUAL(6, block.dimensions()[3]);
    VERIFY_IS_EQUAL(5, block.dimensions()[2]);
    VERIFY_IS_EQUAL(5, block.dimensions()[1]);
    VERIFY_IS_EQUAL(5, block.dimensions()[0]);
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  }

  // Test shape 'UniformAllDims' with full allocation to all dims.
  EIGEN_IF_CONSTEXPR (Layout == ColMajor) {
    DSizes<Index, 5> dims(7, 5, 6, 17, 7);
    const Index max_coeff_count = 7 * 5 * 6 * 17 * 7;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(7, block.dimensions()[0]);
    VERIFY_IS_EQUAL(5, block.dimensions()[1]);
    VERIFY_IS_EQUAL(6, block.dimensions()[2]);
    VERIFY_IS_EQUAL(17, block.dimensions()[3]);
    VERIFY_IS_EQUAL(7, block.dimensions()[4]);
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  } else {
    DSizes<Index, 5> dims(7, 5, 6, 9, 7);
    const Index max_coeff_count = 7 * 5 * 6 * 9 * 7;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kUniformAllDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(7, block.dimensions()[4]);
    VERIFY_IS_EQUAL(9, block.dimensions()[3]);
    VERIFY_IS_EQUAL(6, block.dimensions()[2]);
    VERIFY_IS_EQUAL(5, block.dimensions()[1]);
    VERIFY_IS_EQUAL(7, block.dimensions()[0]);
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  }
}

template <int Layout>
static void test_skewed_inner_dim_block_shape() {
  typedef internal::TensorBlockDescriptor<5> TensorBlock;
  typedef internal::TensorBlockMapper<5, Layout> TensorBlockMapper;

  // Test shape 'SkewedInnerDims' with partial allocation to inner-most dim.
  EIGEN_IF_CONSTEXPR (Layout == ColMajor) {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 10 * 1 * 1 * 1 * 1;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(10, block.dimensions()[0]);
    for (int i = 1; i < 5; ++i) {
      VERIFY_IS_EQUAL(1, block.dimensions()[i]);
    }
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  } else {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 1 * 1 * 1 * 1 * 6;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(6, block.dimensions()[4]);
    for (int i = 3; i >= 0; --i) {
      VERIFY_IS_EQUAL(1, block.dimensions()[i]);
    }
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  }

  // Test shape 'SkewedInnerDims' with full allocation to inner-most dim.
  EIGEN_IF_CONSTEXPR (Layout == ColMajor) {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 11 * 1 * 1 * 1 * 1;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(11, block.dimensions()[0]);
    for (int i = 1; i < 5; ++i) {
      VERIFY_IS_EQUAL(1, block.dimensions()[i]);
    }
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  } else {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 1 * 1 * 1 * 1 * 7;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(7, block.dimensions()[4]);
    for (int i = 3; i >= 0; --i) {
      VERIFY_IS_EQUAL(1, block.dimensions()[i]);
    }
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  }

  // Test shape 'SkewedInnerDims' with full allocation to inner-most dim,
  // and partial allocation to second inner-dim.
  EIGEN_IF_CONSTEXPR (Layout == ColMajor) {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 11 * 3 * 1 * 1 * 1;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(11, block.dimensions()[0]);
    VERIFY_IS_EQUAL(3, block.dimensions()[1]);
    for (int i = 2; i < 5; ++i) {
      VERIFY_IS_EQUAL(1, block.dimensions()[i]);
    }
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  } else {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 1 * 1 * 1 * 15 * 7;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(7, block.dimensions()[4]);
    VERIFY_IS_EQUAL(15, block.dimensions()[3]);
    for (int i = 2; i >= 0; --i) {
      VERIFY_IS_EQUAL(1, block.dimensions()[i]);
    }
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  }

  // Test shape 'SkewedInnerDims' with full allocation to inner-most dim,
  // and partial allocation to third inner-dim.
  EIGEN_IF_CONSTEXPR (Layout == ColMajor) {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 11 * 5 * 5 * 1 * 1;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(11, block.dimensions()[0]);
    VERIFY_IS_EQUAL(5, block.dimensions()[1]);
    VERIFY_IS_EQUAL(5, block.dimensions()[2]);
    for (int i = 3; i < 5; ++i) {
      VERIFY_IS_EQUAL(1, block.dimensions()[i]);
    }
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  } else {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 1 * 1 * 5 * 17 * 7;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(7, block.dimensions()[4]);
    VERIFY_IS_EQUAL(17, block.dimensions()[3]);
    VERIFY_IS_EQUAL(5, block.dimensions()[2]);
    for (int i = 1; i >= 0; --i) {
      VERIFY_IS_EQUAL(1, block.dimensions()[i]);
    }
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  }

  // Test shape 'SkewedInnerDims' with full allocation to all dims.
  EIGEN_IF_CONSTEXPR (Layout == ColMajor) {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 11 * 5 * 6 * 17 * 7;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(11, block.dimensions()[0]);
    VERIFY_IS_EQUAL(5, block.dimensions()[1]);
    VERIFY_IS_EQUAL(6, block.dimensions()[2]);
    VERIFY_IS_EQUAL(17, block.dimensions()[3]);
    VERIFY_IS_EQUAL(7, block.dimensions()[4]);
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  } else {
    DSizes<Index, 5> dims(11, 5, 6, 17, 7);
    const Index max_coeff_count = 11 * 5 * 6 * 17 * 7;
    TensorBlockMapper block_mapper(dims, {TensorBlockShapeType::kSkewedInnerDims, max_coeff_count, zeroCost()});
    TensorBlock block = block_mapper.blockDescriptor(0);
    VERIFY_IS_EQUAL(7, block.dimensions()[4]);
    VERIFY_IS_EQUAL(17, block.dimensions()[3]);
    VERIFY_IS_EQUAL(6, block.dimensions()[2]);
    VERIFY_IS_EQUAL(5, block.dimensions()[1]);
    VERIFY_IS_EQUAL(11, block.dimensions()[0]);
    VERIFY(block.dimensions().TotalSize() <= max_coeff_count);
  }
}

template <int Layout>
static void test_empty_dims(const internal::TensorBlockShapeType block_shape) {
  // Test blocking of tensors with zero dimensions:
  //  - we must not crash on asserts and divisions by zero
  //  - we must not return block with zero dimensions
  //    (recipe for overflows/underflows, divisions by zero and NaNs later)
  //  - total block count must be zero
  {
    typedef internal::TensorBlockMapper<1, Layout> TensorBlockMapper;

    DSizes<Index, 1> dims(0);
    for (size_t max_coeff_count = 0; max_coeff_count < 2; ++max_coeff_count) {
      TensorBlockMapper block_mapper(dims, {block_shape, max_coeff_count, zeroCost()});
      VERIFY_IS_EQUAL(block_mapper.blockCount(), 0);
      VERIFY(block_mapper.blockTotalSize() >= 1);
    }
  }

  {
    typedef internal::TensorBlockMapper<2, Layout> TensorBlockMapper;

    for (int dim1 = 0; dim1 < 3; ++dim1) {
      for (int dim2 = 0; dim2 < 3; ++dim2) {
        DSizes<Index, 2> dims(dim1, dim2);
        for (size_t max_coeff_count = 0; max_coeff_count < 2; ++max_coeff_count) {
          TensorBlockMapper block_mapper(dims, {block_shape, max_coeff_count, zeroCost()});
          if (dim1 * dim2 == 0) {
            VERIFY_IS_EQUAL(block_mapper.blockCount(), 0);
          }
          VERIFY(block_mapper.blockTotalSize() >= 1);
        }
      }
    }
  }
}

#define TEST_LAYOUTS(NAME)        \
  CALL_SUBTEST(NAME<ColMajor>()); \
  CALL_SUBTEST(NAME<RowMajor>())

#define TEST_LAYOUTS_AND_DIMS(TYPE, NAME)    \
  CALL_SUBTEST((NAME<TYPE, 1, ColMajor>())); \
  CALL_SUBTEST((NAME<TYPE, 1, RowMajor>())); \
  CALL_SUBTEST((NAME<TYPE, 2, ColMajor>())); \
  CALL_SUBTEST((NAME<TYPE, 2, RowMajor>())); \
  CALL_SUBTEST((NAME<TYPE, 3, ColMajor>())); \
  CALL_SUBTEST((NAME<TYPE, 3, RowMajor>())); \
  CALL_SUBTEST((NAME<TYPE, 4, ColMajor>())); \
  CALL_SUBTEST((NAME<TYPE, 4, RowMajor>())); \
  CALL_SUBTEST((NAME<TYPE, 5, ColMajor>())); \
  CALL_SUBTEST((NAME<TYPE, 5, RowMajor>()))

#define TEST_LAYOUTS_WITH_ARG(NAME, ARG) \
  CALL_SUBTEST(NAME<ColMajor>(ARG));     \
  CALL_SUBTEST(NAME<RowMajor>(ARG))

EIGEN_DECLARE_TEST(tensor_block_access) {
  TEST_LAYOUTS(test_block_mapper_sanity);
  TEST_LAYOUTS_AND_DIMS(float, test_block_mapper_maps_every_element);
  TEST_LAYOUTS(test_uniform_block_shape);
  TEST_LAYOUTS(test_skewed_inner_dim_block_shape);
  TEST_LAYOUTS_WITH_ARG(test_empty_dims, TensorBlockShapeType::kUniformAllDims);
  TEST_LAYOUTS_WITH_ARG(test_empty_dims, TensorBlockShapeType::kSkewedInnerDims);
}

#undef TEST_LAYOUTS
#undef TEST_LAYOUTS_WITH_ARG
