// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// SPDX-License-Identifier: MPL-2.0

#include "main.h"

#include <Eigen/Tensor>

using Eigen::Tensor;

template <typename>
static void test_simple_reshape() {
  Tensor<float, 5> tensor1(2, 3, 1, 7, 1);
  tensor1.setRandom();

  Tensor<float, 3> tensor2(2, 3, 7);
  Tensor<float, 2> tensor3(6, 7);
  Tensor<float, 2> tensor4(2, 21);

  Tensor<float, 3>::Dimensions dim1(2, 3, 7);
  tensor2 = tensor1.reshape(dim1);
  Tensor<float, 2>::Dimensions dim2(6, 7);
  tensor3 = tensor1.reshape(dim2);
  Tensor<float, 2>::Dimensions dim3(2, 21);
  tensor4 = tensor1.reshape(dim1).reshape(dim3);

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(tensor1(i, j, 0, k, 0), tensor2(i, j, k));
        VERIFY_IS_EQUAL(tensor1(i, j, 0, k, 0), tensor3(i + 2 * j, k));
        VERIFY_IS_EQUAL(tensor1(i, j, 0, k, 0), tensor4(i, j + 3 * k));
      }
    }
  }
}

template <typename>
static void test_static_reshape() {
  using Eigen::type2index;

  Tensor<float, 5> tensor(2, 3, 1, 7, 1);
  tensor.setRandom();

  // New dimensions: [2, 3, 7]
  Eigen::IndexList<type2index<2>, type2index<3>, type2index<7>> dim;
  Tensor<float, 3> reshaped = tensor.reshape(static_cast<Eigen::DSizes<ptrdiff_t, 3>>(dim));

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(tensor(i, j, 0, k, 0), reshaped(i, j, k));
      }
    }
  }
}

template <typename>
static void test_reshape_in_expr() {
  // The TensorMaps below alias the matrix data as default-layout (col-major)
  // tensors, so pin the matrices to ColMajor: MatrixXf would not match under
  // EIGEN_DEFAULT_TO_ROW_MAJOR.
  typedef Matrix<float, Dynamic, Dynamic, ColMajor> Mtx;
  Mtx m1(2, 3 * 5 * 7 * 11);
  Mtx m2(3 * 5 * 7 * 11, 13);
  m1.setRandom();
  m2.setRandom();
  Mtx m3 = m1 * m2;

  TensorMap<Tensor<float, 5>> tensor1(m1.data(), 2, 3, 5, 7, 11);
  TensorMap<Tensor<float, 5>> tensor2(m2.data(), 3, 5, 7, 11, 13);
  Tensor<float, 2>::Dimensions newDims1(2, 3 * 5 * 7 * 11);
  Tensor<float, 2>::Dimensions newDims2(3 * 5 * 7 * 11, 13);
  typedef Tensor<float, 1>::DimensionPair DimPair;
  array<DimPair, 1> contract_along{{DimPair(1, 0)}};
  Tensor<float, 2> tensor3(2, 13);
  tensor3 = tensor1.reshape(newDims1).contract(tensor2.reshape(newDims2), contract_along);

  Map<Mtx> res(tensor3.data(), 2, 13);
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 13; ++j) {
      VERIFY_IS_APPROX(res(i, j), m3(i, j));
    }
  }
}

template <typename>
static void test_reshape_as_lvalue() {
  Tensor<float, 3> tensor(2, 3, 7);
  tensor.setRandom();

  Tensor<float, 2> tensor2d(6, 7);
  Tensor<float, 3>::Dimensions dim(2, 3, 7);
  tensor2d.reshape(dim) = tensor;

  float scratch[2 * 3 * 1 * 7 * 1];
  TensorMap<Tensor<float, 5>> tensor5d(scratch, 2, 3, 1, 7, 1);
  tensor5d.reshape(dim).device(Eigen::DefaultDevice()) = tensor;

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(tensor2d(i + 2 * j, k), tensor(i, j, k));
        VERIFY_IS_EQUAL(tensor5d(i, j, 0, k, 0), tensor(i, j, k));
      }
    }
  }
}

template <typename T, int DataLayout>
static void test_simple_slice() {
  Tensor<T, 5, DataLayout> tensor(2, 3, 5, 7, 11);
  tensor.setRandom();

  Tensor<T, 5, DataLayout> slice1(1, 1, 1, 1, 1);
  Eigen::DSizes<ptrdiff_t, 5> indices(1, 2, 3, 4, 5);
  Eigen::DSizes<ptrdiff_t, 5> sizes(1, 1, 1, 1, 1);
  slice1 = tensor.slice(indices, sizes);
  VERIFY_IS_EQUAL(slice1(0, 0, 0, 0, 0), tensor(1, 2, 3, 4, 5));

  Tensor<T, 5, DataLayout> slice2(1, 1, 2, 2, 3);
  Eigen::DSizes<ptrdiff_t, 5> indices2(1, 1, 3, 4, 5);
  Eigen::DSizes<ptrdiff_t, 5> sizes2(1, 1, 2, 2, 3);
  slice2 = tensor.slice(indices2, sizes2);
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 2; ++j) {
      for (int k = 0; k < 3; ++k) {
        VERIFY_IS_EQUAL(slice2(0, 0, i, j, k), tensor(1, 1, 3 + i, 4 + j, 5 + k));
      }
    }
  }
}

template <typename T>
static void test_const_slice() {
  const T b[1] = {42};
  TensorMap<Tensor<const T, 1>> m(b, 1);
  DSizes<DenseIndex, 1> offsets;
  offsets[0] = 0;
  TensorRef<const Tensor<const T, 1>> slice_ref(m.slice(offsets, m.dimensions()));
  VERIFY_IS_EQUAL(slice_ref(0), 42);
}

template <typename T, int DataLayout>
static void test_slice_in_expr() {
  typedef Matrix<T, Dynamic, Dynamic, DataLayout> Mtx;
  Mtx m1(7, 7);
  Mtx m2(3, 3);
  m1.setRandom();
  m2.setRandom();

  Mtx m3 = m1.block(1, 2, 3, 3) * m2.block(0, 2, 3, 1);

  TensorMap<Tensor<T, 2, DataLayout>> tensor1(m1.data(), 7, 7);
  TensorMap<Tensor<T, 2, DataLayout>> tensor2(m2.data(), 3, 3);
  Tensor<T, 2, DataLayout> tensor3(3, 1);
  typedef typename Tensor<T, 1>::DimensionPair DimPair;
  array<DimPair, 1> contract_along{{DimPair(1, 0)}};

  Eigen::DSizes<ptrdiff_t, 2> indices1(1, 2);
  Eigen::DSizes<ptrdiff_t, 2> sizes1(3, 3);
  Eigen::DSizes<ptrdiff_t, 2> indices2(0, 2);
  Eigen::DSizes<ptrdiff_t, 2> sizes2(3, 1);
  tensor3 = tensor1.slice(indices1, sizes1).contract(tensor2.slice(indices2, sizes2), contract_along);

  Map<Mtx> res(tensor3.data(), 3, 1);
  for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 1; ++j) {
      VERIFY_IS_APPROX(res(i, j), m3(i, j));
    }
  }

  // Take an arbitrary slice of an arbitrarily sized tensor.
  TensorMap<Tensor<const T, 2, DataLayout>> tensor4(m1.data(), 7, 7);
  Tensor<T, 1, DataLayout> tensor6 =
      tensor4.reshape(DSizes<ptrdiff_t, 1>(7 * 7)).exp().slice(DSizes<ptrdiff_t, 1>(0), DSizes<ptrdiff_t, 1>(35));
  for (int i = 0; i < 35; ++i) {
    VERIFY_IS_APPROX(tensor6(i), expf(tensor4.data()[i]));
  }
}

template <typename T, int DataLayout>
static void test_slice_as_lvalue() {
  Tensor<T, 3, DataLayout> tensor1(2, 2, 7);
  tensor1.setRandom();
  Tensor<T, 3, DataLayout> tensor2(2, 2, 7);
  tensor2.setRandom();
  Tensor<T, 3, DataLayout> tensor3(4, 3, 5);
  tensor3.setRandom();
  Tensor<T, 3, DataLayout> tensor4(4, 3, 2);
  tensor4.setRandom();
  Tensor<T, 3, DataLayout> tensor5(10, 13, 12);
  tensor5.setRandom();

  Tensor<T, 3, DataLayout> result(4, 5, 7);
  Eigen::DSizes<ptrdiff_t, 3> sizes12(2, 2, 7);
  Eigen::DSizes<ptrdiff_t, 3> first_slice(0, 0, 0);
  result.slice(first_slice, sizes12) = tensor1;
  Eigen::DSizes<ptrdiff_t, 3> second_slice(2, 0, 0);
  result.slice(second_slice, sizes12).device(Eigen::DefaultDevice()) = tensor2;

  Eigen::DSizes<ptrdiff_t, 3> sizes3(4, 3, 5);
  Eigen::DSizes<ptrdiff_t, 3> third_slice(0, 2, 0);
  result.slice(third_slice, sizes3) = tensor3;

  Eigen::DSizes<ptrdiff_t, 3> sizes4(4, 3, 2);
  Eigen::DSizes<ptrdiff_t, 3> fourth_slice(0, 2, 5);
  result.slice(fourth_slice, sizes4) = tensor4;

  for (int j = 0; j < 2; ++j) {
    for (int k = 0; k < 7; ++k) {
      for (int i = 0; i < 2; ++i) {
        VERIFY_IS_EQUAL(result(i, j, k), tensor1(i, j, k));
        VERIFY_IS_EQUAL(result(i + 2, j, k), tensor2(i, j, k));
      }
    }
  }
  for (int i = 0; i < 4; ++i) {
    for (int j = 2; j < 5; ++j) {
      for (int k = 0; k < 5; ++k) {
        VERIFY_IS_EQUAL(result(i, j, k), tensor3(i, j - 2, k));
      }
      for (int k = 5; k < 7; ++k) {
        VERIFY_IS_EQUAL(result(i, j, k), tensor4(i, j - 2, k - 5));
      }
    }
  }

  Eigen::DSizes<ptrdiff_t, 3> sizes5(4, 5, 7);
  Eigen::DSizes<ptrdiff_t, 3> fifth_slice(0, 0, 0);
  result.slice(fifth_slice, sizes5) = tensor5.slice(fifth_slice, sizes5);
  for (int i = 0; i < 4; ++i) {
    for (int j = 2; j < 5; ++j) {
      for (int k = 0; k < 7; ++k) {
        VERIFY_IS_EQUAL(result(i, j, k), tensor5(i, j, k));
      }
    }
  }
}

template <typename T, int DataLayout>
static void test_slice_raw_data() {
  Tensor<T, 4, DataLayout> tensor(3, 5, 7, 11);
  tensor.setRandom();

  Eigen::DSizes<ptrdiff_t, 4> offsets(1, 2, 3, 4);
  Eigen::DSizes<ptrdiff_t, 4> extents(1, 1, 1, 1);
  typedef TensorEvaluator<decltype(tensor.slice(offsets, extents)), DefaultDevice> SliceEvaluator;
  auto slice1 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
  VERIFY_IS_EQUAL(slice1.dimensions().TotalSize(), 1);
  VERIFY_IS_EQUAL(slice1.data()[0], tensor(1, 2, 3, 4));

  if (DataLayout == ColMajor) {
    extents = Eigen::DSizes<ptrdiff_t, 4>(2, 1, 1, 1);
    auto slice2 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
    VERIFY_IS_EQUAL(slice2.dimensions().TotalSize(), 2);
    VERIFY_IS_EQUAL(slice2.data()[0], tensor(1, 2, 3, 4));
    VERIFY_IS_EQUAL(slice2.data()[1], tensor(2, 2, 3, 4));
  } else {
    extents = Eigen::DSizes<ptrdiff_t, 4>(1, 1, 1, 2);
    auto slice2 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
    VERIFY_IS_EQUAL(slice2.dimensions().TotalSize(), 2);
    VERIFY_IS_EQUAL(slice2.data()[0], tensor(1, 2, 3, 4));
    VERIFY_IS_EQUAL(slice2.data()[1], tensor(1, 2, 3, 5));
  }

  extents = Eigen::DSizes<ptrdiff_t, 4>(1, 2, 1, 1);
  auto slice3 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
  VERIFY_IS_EQUAL(slice3.dimensions().TotalSize(), 2);
  VERIFY_IS_EQUAL(slice3.data(), static_cast<T*>(0));

  if (DataLayout == ColMajor) {
    offsets = Eigen::DSizes<ptrdiff_t, 4>(0, 2, 3, 4);
    extents = Eigen::DSizes<ptrdiff_t, 4>(3, 2, 1, 1);
    auto slice4 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
    VERIFY_IS_EQUAL(slice4.dimensions().TotalSize(), 6);
    for (int i = 0; i < 3; ++i) {
      for (int j = 0; j < 2; ++j) {
        VERIFY_IS_EQUAL(slice4.data()[i + 3 * j], tensor(i, 2 + j, 3, 4));
      }
    }
  } else {
    offsets = Eigen::DSizes<ptrdiff_t, 4>(1, 2, 3, 0);
    extents = Eigen::DSizes<ptrdiff_t, 4>(1, 1, 2, 11);
    auto slice4 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
    VERIFY_IS_EQUAL(slice4.dimensions().TotalSize(), 22);
    for (int l = 0; l < 11; ++l) {
      for (int k = 0; k < 2; ++k) {
        VERIFY_IS_EQUAL(slice4.data()[l + 11 * k], tensor(1, 2, 3 + k, l));
      }
    }
  }

  if (DataLayout == ColMajor) {
    offsets = Eigen::DSizes<ptrdiff_t, 4>(0, 0, 0, 4);
    extents = Eigen::DSizes<ptrdiff_t, 4>(3, 5, 7, 2);
    auto slice5 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
    VERIFY_IS_EQUAL(slice5.dimensions().TotalSize(), 210);
    for (int i = 0; i < 3; ++i) {
      for (int j = 0; j < 5; ++j) {
        for (int k = 0; k < 7; ++k) {
          for (int l = 0; l < 2; ++l) {
            int slice_index = i + 3 * (j + 5 * (k + 7 * l));
            VERIFY_IS_EQUAL(slice5.data()[slice_index], tensor(i, j, k, l + 4));
          }
        }
      }
    }
  } else {
    offsets = Eigen::DSizes<ptrdiff_t, 4>(1, 0, 0, 0);
    extents = Eigen::DSizes<ptrdiff_t, 4>(2, 5, 7, 11);
    auto slice5 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
    VERIFY_IS_EQUAL(slice5.dimensions().TotalSize(), 770);
    for (int l = 0; l < 11; ++l) {
      for (int k = 0; k < 7; ++k) {
        for (int j = 0; j < 5; ++j) {
          for (int i = 0; i < 2; ++i) {
            int slice_index = l + 11 * (k + 7 * (j + 5 * i));
            VERIFY_IS_EQUAL(slice5.data()[slice_index], tensor(i + 1, j, k, l));
          }
        }
      }
    }
  }

  offsets = Eigen::DSizes<ptrdiff_t, 4>(0, 0, 0, 0);
  extents = Eigen::DSizes<ptrdiff_t, 4>(3, 5, 7, 11);
  auto slice6 = SliceEvaluator(tensor.slice(offsets, extents), DefaultDevice());
  VERIFY_IS_EQUAL(slice6.dimensions().TotalSize(), 3 * 5 * 7 * 11);
  VERIFY_IS_EQUAL(slice6.data(), tensor.data());
}

template <typename T, int DataLayout>
static void test_strided_slice() {
  typedef Tensor<T, 5, DataLayout> Tensor5f;
  typedef Eigen::DSizes<Eigen::DenseIndex, 5> Index5;
  typedef Tensor<T, 2, DataLayout> Tensor2f;
  typedef Eigen::DSizes<Eigen::DenseIndex, 2> Index2;
  Tensor<T, 5, DataLayout> tensor(2, 3, 5, 7, 11);
  Tensor<T, 2, DataLayout> tensor2(7, 11);
  tensor.setRandom();
  tensor2.setRandom();

  if (true) {
    Tensor2f slice(2, 3);
    Index2 strides(-2, -1);
    Index2 indicesStart(5, 7);
    Index2 indicesStop(0, 4);
    slice = tensor2.stridedSlice(indicesStart, indicesStop, strides);
    for (int j = 0; j < 2; ++j) {
      for (int k = 0; k < 3; ++k) {
        VERIFY_IS_EQUAL(slice(j, k), tensor2(5 - 2 * j, 7 - k));
      }
    }
  }

  if (true) {
    Tensor2f slice(0, 1);
    Index2 strides(1, 1);
    Index2 indicesStart(5, 4);
    Index2 indicesStop(5, 5);
    slice = tensor2.stridedSlice(indicesStart, indicesStop, strides);
  }

  if (true) {  // test clamped degenerate interavls
    Tensor2f slice(7, 11);
    Index2 strides(1, -1);
    Index2 indicesStart(-3, 20);  // should become 0,10
    Index2 indicesStop(20, -11);  // should become 11, -1
    slice = tensor2.stridedSlice(indicesStart, indicesStop, strides);
    for (int j = 0; j < 7; ++j) {
      for (int k = 0; k < 11; ++k) {
        VERIFY_IS_EQUAL(slice(j, k), tensor2(j, 10 - k));
      }
    }
  }

  if (true) {
    Tensor5f slice1(1, 1, 1, 1, 1);
    Eigen::DSizes<Eigen::DenseIndex, 5> indicesStart(1, 2, 3, 4, 5);
    Eigen::DSizes<Eigen::DenseIndex, 5> indicesStop(2, 3, 4, 5, 6);
    Eigen::DSizes<Eigen::DenseIndex, 5> strides(1, 1, 1, 1, 1);
    slice1 = tensor.stridedSlice(indicesStart, indicesStop, strides);
    VERIFY_IS_EQUAL(slice1(0, 0, 0, 0, 0), tensor(1, 2, 3, 4, 5));
  }

  if (true) {
    Tensor5f slice(1, 1, 2, 2, 3);
    Index5 start(1, 1, 3, 4, 5);
    Index5 stop(2, 2, 5, 6, 8);
    Index5 strides(1, 1, 1, 1, 1);
    slice = tensor.stridedSlice(start, stop, strides);
    for (int i = 0; i < 2; ++i) {
      for (int j = 0; j < 2; ++j) {
        for (int k = 0; k < 3; ++k) {
          VERIFY_IS_EQUAL(slice(0, 0, i, j, k), tensor(1, 1, 3 + i, 4 + j, 5 + k));
        }
      }
    }
  }

  if (true) {
    Tensor5f slice(1, 1, 2, 2, 3);
    Index5 strides3(1, 1, -2, 1, -1);
    Index5 indices3Start(1, 1, 4, 4, 7);
    Index5 indices3Stop(2, 2, 0, 6, 4);
    slice = tensor.stridedSlice(indices3Start, indices3Stop, strides3);
    for (int i = 0; i < 2; ++i) {
      for (int j = 0; j < 2; ++j) {
        for (int k = 0; k < 3; ++k) {
          VERIFY_IS_EQUAL(slice(0, 0, i, j, k), tensor(1, 1, 4 - 2 * i, 4 + j, 7 - k));
        }
      }
    }
  }

  if (false) {  // tests degenerate interval
    Tensor5f slice(1, 1, 2, 2, 3);
    Index5 strides3(1, 1, 2, 1, 1);
    Index5 indices3Start(1, 1, 4, 4, 7);
    Index5 indices3Stop(2, 2, 0, 6, 4);
    slice = tensor.stridedSlice(indices3Start, indices3Stop, strides3);
  }
}

template <typename T, int DataLayout>
static void test_strided_slice_write() {
  typedef Tensor<T, 2, DataLayout> Tensor2f;
  typedef Eigen::DSizes<Eigen::DenseIndex, 2> Index2;

  Tensor<T, 2, DataLayout> tensor(7, 11), tensor2(7, 11);
  tensor.setRandom();
  tensor2 = tensor;
  Tensor2f slice(2, 3);

  slice.setRandom();

  Index2 strides(1, 1);
  Index2 indicesStart(3, 4);
  Index2 indicesStop(5, 7);
  Index2 lengths(2, 3);

  tensor.slice(indicesStart, lengths) = slice;
  tensor2.stridedSlice(indicesStart, indicesStop, strides) = slice;

  for (int i = 0; i < 7; i++)
    for (int j = 0; j < 11; j++) {
      VERIFY_IS_EQUAL(tensor(i, j), tensor2(i, j));
    }
}

template <typename T, int DataLayout>
static void test_strided_slice_packet_access() {
  typedef Tensor<T, 2, DataLayout> Tensor2;
  typedef Eigen::DSizes<Eigen::DenseIndex, 2> Index2;

  // The strided-slice evaluators forward the nested evaluator's packet
  // access; the packet methods below are exercised through the executor.
  typedef Eigen::TensorStridingSlicingOp<const Index2, const Index2, const Index2, const Tensor2> SliceOp;
  typedef TensorEvaluator<const SliceOp, DefaultDevice> SliceEval;
  typedef TensorEvaluator<const Tensor2, DefaultDevice> ArgEval;
  static_assert(int(SliceEval::PacketAccess) == int(ArgEval::PacketAccess),
                "strided slice must forward the nested evaluator's packet access");

  // Sizes with partial-packet tails for every packet size in use.
  Tensor2 tensor(31, 37);
  tensor.setRandom();

  // Stride patterns covering, in each storage order: the identity fast path,
  // contiguous inner loads, reversed (-1) inner loads, and the non-unit and
  // boundary-crossing gather fallback.
  const Eigen::DenseIndex stride_patterns[][2] = {{1, 1}, {1, 2}, {2, 1}, {-1, 1}, {1, -1}, {-2, 3}, {3, -2}, {-1, -1}};

  for (const auto& sp : stride_patterns) {
    const Index2 strides(sp[0], sp[1]);
    const Index2 start(sp[0] > 0 ? 1 : 29, sp[1] > 0 ? 2 : 35);
    const Index2 stop(sp[0] > 0 ? 30 : 0, sp[1] > 0 ? 36 : 1);

    // Reads through the packet path.
    Tensor2 slice = tensor.stridedSlice(start, stop, strides);
    for (Eigen::DenseIndex i = 0; i < slice.dimension(0); ++i) {
      for (Eigen::DenseIndex j = 0; j < slice.dimension(1); ++j) {
        VERIFY_IS_EQUAL(slice(i, j), tensor(start[0] + i * strides[0], start[1] + j * strides[1]));
      }
    }

    // Expression-sourced reads (no direct data access in the argument).
    Tensor2 expr_slice = (tensor * tensor.constant(T(2))).stridedSlice(start, stop, strides);
    for (Eigen::DenseIndex i = 0; i < expr_slice.dimension(0); ++i) {
      for (Eigen::DenseIndex j = 0; j < expr_slice.dimension(1); ++j) {
        VERIFY_IS_EQUAL(expr_slice(i, j), T(2) * tensor(start[0] + i * strides[0], start[1] + j * strides[1]));
      }
    }

    // Writes through the packet path, against a scalar-loop reference.
    Tensor2 dst_ref = tensor;
    Tensor2 dst = tensor;
    Tensor2 src(slice.dimension(0), slice.dimension(1));
    src.setRandom();
    dst.stridedSlice(start, stop, strides) = src;
    for (Eigen::DenseIndex i = 0; i < src.dimension(0); ++i) {
      for (Eigen::DenseIndex j = 0; j < src.dimension(1); ++j) {
        dst_ref(start[0] + i * strides[0], start[1] + j * strides[1]) = src(i, j);
      }
    }
    for (Eigen::DenseIndex i = 0; i < dst.dimension(0); ++i) {
      for (Eigen::DenseIndex j = 0; j < dst.dimension(1); ++j) {
        VERIFY_IS_EQUAL(dst(i, j), dst_ref(i, j));
      }
    }
  }

  // Full-range unit-stride slice: the identity fast path.
  {
    const Eigen::array<Eigen::DenseIndex, 2> strides = {{1, 1}};
    const Eigen::array<Eigen::DenseIndex, 2> start = {{0, 0}};
    const Eigen::array<Eigen::DenseIndex, 2> stop = {{31, 37}};
    Tensor2 slice = tensor.stridedSlice(start, stop, strides);
    Tensor2 destination(31, 37);
    destination.setZero();
    destination.stridedSlice(start, stop, strides) = tensor;
    for (Eigen::DenseIndex i = 0; i < 31; ++i) {
      for (Eigen::DenseIndex j = 0; j < 37; ++j) {
        VERIFY_IS_EQUAL(slice(i, j), tensor(i, j));
        VERIFY_IS_EQUAL(destination(i, j), tensor(i, j));
      }
    }
  }
}

template <typename = void>
static void test_strided_slice_packet_cost() {
  typedef Tensor<float, 2> Tensor2;
  typedef Eigen::DSizes<Eigen::DenseIndex, 2> Index2;

  Tensor2 tensor(32, 32);
  tensor.setRandom();
  const Index2 start(0, 0);
  const Index2 stop(32, 32);
  const Index2 strides(2, 2);
  auto expression = tensor.exp();
  auto slice = expression.stridedSlice(start, stop, strides);

  DefaultDevice device;
  TensorEvaluator<const decltype(expression), DefaultDevice> expression_evaluator(expression, device);
  TensorEvaluator<const decltype(slice), DefaultDevice> slice_evaluator(slice, device);
  const TensorOpCost scalar_expression_cost = expression_evaluator.costPerCoeff(false);
  const TensorOpCost packet_slice_cost = slice_evaluator.costPerCoeff(true);

  // A gathered packet evaluates the nested expression coefficient by
  // coefficient and must not receive the nested evaluator's packet discount.
  VERIFY(packet_slice_cost.compute_cycles() >= scalar_expression_cost.compute_cycles());
}

template <typename T, int DataLayout>
static void test_composition() {
  Eigen::Tensor<T, 2, DataLayout> matrix(7, 11);
  matrix.setRandom();

  const DSizes<ptrdiff_t, 3> newDims(1, 1, 11);
  Eigen::Tensor<T, 3, DataLayout> tensor =
      matrix.slice(DSizes<ptrdiff_t, 2>(2, 0), DSizes<ptrdiff_t, 2>(1, 11)).reshape(newDims);

  VERIFY_IS_EQUAL(tensor.dimensions().TotalSize(), 11);
  VERIFY_IS_EQUAL(tensor.dimension(0), 1);
  VERIFY_IS_EQUAL(tensor.dimension(1), 1);
  VERIFY_IS_EQUAL(tensor.dimension(2), 11);
  for (int i = 0; i < 11; ++i) {
    VERIFY_IS_EQUAL(tensor(0, 0, i), matrix(2, i));
  }
}

template <typename T, int DataLayout>
static void test_empty_slice() {
  Tensor<T, 3, DataLayout> tensor(2, 3, 5);
  tensor.setRandom();
  Tensor<T, 3, DataLayout> copy = tensor;

  // empty size in first dimension
  Eigen::DSizes<ptrdiff_t, 3> indices1(1, 2, 3);
  Eigen::DSizes<ptrdiff_t, 3> sizes1(0, 1, 2);
  Tensor<T, 3, DataLayout> slice1(0, 1, 2);
  slice1.setRandom();
  tensor.slice(indices1, sizes1) = slice1;

  // empty size in second dimension
  Eigen::DSizes<ptrdiff_t, 3> indices2(1, 2, 3);
  Eigen::DSizes<ptrdiff_t, 3> sizes2(1, 0, 2);
  Tensor<T, 3, DataLayout> slice2(1, 0, 2);
  slice2.setRandom();
  tensor.slice(indices2, sizes2) = slice2;

  // empty size in third dimension
  Eigen::DSizes<ptrdiff_t, 3> indices3(1, 2, 3);
  Eigen::DSizes<ptrdiff_t, 3> sizes3(1, 1, 0);
  Tensor<T, 3, DataLayout> slice3(1, 1, 0);
  slice3.setRandom();
  tensor.slice(indices3, sizes3) = slice3;

  // empty size in first and second dimension
  Eigen::DSizes<ptrdiff_t, 3> indices4(1, 2, 3);
  Eigen::DSizes<ptrdiff_t, 3> sizes4(0, 0, 2);
  Tensor<T, 3, DataLayout> slice4(0, 0, 2);
  slice4.setRandom();
  tensor.slice(indices4, sizes4) = slice4;

  // empty size in second and third dimension
  Eigen::DSizes<ptrdiff_t, 3> indices5(1, 2, 3);
  Eigen::DSizes<ptrdiff_t, 3> sizes5(1, 0, 0);
  Tensor<T, 3, DataLayout> slice5(1, 0, 0);
  slice5.setRandom();
  tensor.slice(indices5, sizes5) = slice5;

  // empty size in all dimensions
  Eigen::DSizes<ptrdiff_t, 3> indices6(1, 2, 3);
  Eigen::DSizes<ptrdiff_t, 3> sizes6(0, 0, 0);
  Tensor<T, 3, DataLayout> slice6(0, 0, 0);
  slice6.setRandom();
  tensor.slice(indices6, sizes6) = slice6;

  // none of these operations should change the tensor's components
  // because all of the rvalue slices have at least one zero dimension
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 5; ++k) {
        VERIFY_IS_EQUAL(tensor(i, j, k), copy(i, j, k));
      }
    }
  }
}

#define CALL_SUBTEST_PART(PART) CALL_SUBTEST_##PART

#define CALL_SUBTESTS_TYPES_LAYOUTS(PART, NAME)       \
  CALL_SUBTEST_PART(PART)((NAME<float, ColMajor>())); \
  CALL_SUBTEST_PART(PART)((NAME<float, RowMajor>())); \
  CALL_SUBTEST_PART(PART)((NAME<bool, ColMajor>()));  \
  CALL_SUBTEST_PART(PART)((NAME<bool, RowMajor>()))

// The type/layout sweeps reach CALL_SUBTEST_N through CALL_SUBTESTS_TYPES_LAYOUTS,
// which the configure-time suffix scan cannot see; list the parts explicitly.
// EIGEN_SUFFIXES;1;2;3;4;5;6;7;8
EIGEN_DECLARE_TEST(tensor_morphing) {
  CALL_SUBTEST_1(test_simple_reshape<void>());
  CALL_SUBTEST_1(test_static_reshape<void>());
  CALL_SUBTEST_1(test_reshape_as_lvalue<void>());
  CALL_SUBTEST_1(test_reshape_in_expr<void>());
  CALL_SUBTEST_1(test_const_slice<float>());
  // test_slice_in_expr uses a matrix product, so it cannot join the
  // bool-sweeping CALL_SUBTESTS_TYPES_LAYOUTS batches below.
  CALL_SUBTEST_1((test_slice_in_expr<float, ColMajor>()));
  CALL_SUBTEST_1((test_slice_in_expr<float, RowMajor>()));

  CALL_SUBTESTS_TYPES_LAYOUTS(2, test_simple_slice);
  CALL_SUBTESTS_TYPES_LAYOUTS(3, test_slice_as_lvalue);
  CALL_SUBTESTS_TYPES_LAYOUTS(4, test_slice_raw_data);
  CALL_SUBTESTS_TYPES_LAYOUTS(5, test_strided_slice_write);
  CALL_SUBTESTS_TYPES_LAYOUTS(6, test_strided_slice);
  CALL_SUBTESTS_TYPES_LAYOUTS(7, test_composition);

  CALL_SUBTEST_8((test_strided_slice_packet_access<float, ColMajor>()));
  CALL_SUBTEST_8((test_strided_slice_packet_access<float, RowMajor>()));
  CALL_SUBTEST_8((test_strided_slice_packet_access<double, ColMajor>()));
  CALL_SUBTEST_8((test_strided_slice_packet_access<double, RowMajor>()));
  CALL_SUBTEST_8(test_strided_slice_packet_cost<>());
}
