// 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 (tensor_strides[dim_index] == 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
