123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- // 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/.
- #include "main.h"
- #include <Eigen/CXX11/Tensor>
- using Eigen::Tensor;
- using Eigen::array;
- template <int DataLayout>
- static void test_simple_shuffling()
- {
- Tensor<float, 4, DataLayout> tensor(2,3,5,7);
- tensor.setRandom();
- array<ptrdiff_t, 4> shuffles;
- shuffles[0] = 0;
- shuffles[1] = 1;
- shuffles[2] = 2;
- shuffles[3] = 3;
- Tensor<float, 4, DataLayout> no_shuffle;
- no_shuffle = tensor.shuffle(shuffles);
- VERIFY_IS_EQUAL(no_shuffle.dimension(0), 2);
- VERIFY_IS_EQUAL(no_shuffle.dimension(1), 3);
- VERIFY_IS_EQUAL(no_shuffle.dimension(2), 5);
- VERIFY_IS_EQUAL(no_shuffle.dimension(3), 7);
- for (int i = 0; i < 2; ++i) {
- for (int j = 0; j < 3; ++j) {
- for (int k = 0; k < 5; ++k) {
- for (int l = 0; l < 7; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), no_shuffle(i,j,k,l));
- }
- }
- }
- }
- shuffles[0] = 2;
- shuffles[1] = 3;
- shuffles[2] = 1;
- shuffles[3] = 0;
- Tensor<float, 4, DataLayout> shuffle;
- shuffle = tensor.shuffle(shuffles);
- VERIFY_IS_EQUAL(shuffle.dimension(0), 5);
- VERIFY_IS_EQUAL(shuffle.dimension(1), 7);
- VERIFY_IS_EQUAL(shuffle.dimension(2), 3);
- VERIFY_IS_EQUAL(shuffle.dimension(3), 2);
- for (int i = 0; i < 2; ++i) {
- for (int j = 0; j < 3; ++j) {
- for (int k = 0; k < 5; ++k) {
- for (int l = 0; l < 7; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), shuffle(k,l,j,i));
- }
- }
- }
- }
- }
- template <int DataLayout>
- static void test_expr_shuffling()
- {
- Tensor<float, 4, DataLayout> tensor(2,3,5,7);
- tensor.setRandom();
- array<ptrdiff_t, 4> shuffles;
- shuffles[0] = 2;
- shuffles[1] = 3;
- shuffles[2] = 1;
- shuffles[3] = 0;
- Tensor<float, 4, DataLayout> expected;
- expected = tensor.shuffle(shuffles);
- Tensor<float, 4, DataLayout> result(5, 7, 3, 2);
- array<ptrdiff_t, 4> src_slice_dim{{2, 3, 1, 7}};
- array<ptrdiff_t, 4> src_slice_start{{0, 0, 0, 0}};
- array<ptrdiff_t, 4> dst_slice_dim{{1, 7, 3, 2}};
- array<ptrdiff_t, 4> dst_slice_start{{0, 0, 0, 0}};
- for (int i = 0; i < 5; ++i) {
- result.slice(dst_slice_start, dst_slice_dim) =
- tensor.slice(src_slice_start, src_slice_dim).shuffle(shuffles);
- src_slice_start[2] += 1;
- dst_slice_start[0] += 1;
- }
- VERIFY_IS_EQUAL(result.dimension(0), 5);
- VERIFY_IS_EQUAL(result.dimension(1), 7);
- VERIFY_IS_EQUAL(result.dimension(2), 3);
- VERIFY_IS_EQUAL(result.dimension(3), 2);
- for (int i = 0; i < expected.dimension(0); ++i) {
- for (int j = 0; j < expected.dimension(1); ++j) {
- for (int k = 0; k < expected.dimension(2); ++k) {
- for (int l = 0; l < expected.dimension(3); ++l) {
- VERIFY_IS_EQUAL(result(i,j,k,l), expected(i,j,k,l));
- }
- }
- }
- }
- dst_slice_start[0] = 0;
- result.setRandom();
- for (int i = 0; i < 5; ++i) {
- result.slice(dst_slice_start, dst_slice_dim) =
- tensor.shuffle(shuffles).slice(dst_slice_start, dst_slice_dim);
- dst_slice_start[0] += 1;
- }
- for (int i = 0; i < expected.dimension(0); ++i) {
- for (int j = 0; j < expected.dimension(1); ++j) {
- for (int k = 0; k < expected.dimension(2); ++k) {
- for (int l = 0; l < expected.dimension(3); ++l) {
- VERIFY_IS_EQUAL(result(i,j,k,l), expected(i,j,k,l));
- }
- }
- }
- }
- }
- template <int DataLayout>
- static void test_shuffling_as_value()
- {
- Tensor<float, 4, DataLayout> tensor(2,3,5,7);
- tensor.setRandom();
- array<ptrdiff_t, 4> shuffles;
- shuffles[2] = 0;
- shuffles[3] = 1;
- shuffles[1] = 2;
- shuffles[0] = 3;
- Tensor<float, 4, DataLayout> shuffle(5,7,3,2);
- shuffle.shuffle(shuffles) = tensor;
- VERIFY_IS_EQUAL(shuffle.dimension(0), 5);
- VERIFY_IS_EQUAL(shuffle.dimension(1), 7);
- VERIFY_IS_EQUAL(shuffle.dimension(2), 3);
- VERIFY_IS_EQUAL(shuffle.dimension(3), 2);
- for (int i = 0; i < 2; ++i) {
- for (int j = 0; j < 3; ++j) {
- for (int k = 0; k < 5; ++k) {
- for (int l = 0; l < 7; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), shuffle(k,l,j,i));
- }
- }
- }
- }
- array<ptrdiff_t, 4> no_shuffle;
- no_shuffle[0] = 0;
- no_shuffle[1] = 1;
- no_shuffle[2] = 2;
- no_shuffle[3] = 3;
- Tensor<float, 4, DataLayout> shuffle2(5,7,3,2);
- shuffle2.shuffle(shuffles) = tensor.shuffle(no_shuffle);
- for (int i = 0; i < 5; ++i) {
- for (int j = 0; j < 7; ++j) {
- for (int k = 0; k < 3; ++k) {
- for (int l = 0; l < 2; ++l) {
- VERIFY_IS_EQUAL(shuffle2(i,j,k,l), shuffle(i,j,k,l));
- }
- }
- }
- }
- }
- template <int DataLayout>
- static void test_shuffle_unshuffle()
- {
- Tensor<float, 4, DataLayout> tensor(2,3,5,7);
- tensor.setRandom();
- // Choose a random permutation.
- array<ptrdiff_t, 4> shuffles;
- for (int i = 0; i < 4; ++i) {
- shuffles[i] = i;
- }
- array<ptrdiff_t, 4> shuffles_inverse;
- for (int i = 0; i < 4; ++i) {
- const ptrdiff_t index = internal::random<ptrdiff_t>(i, 3);
- shuffles_inverse[shuffles[index]] = i;
- std::swap(shuffles[i], shuffles[index]);
- }
- Tensor<float, 4, DataLayout> shuffle;
- shuffle = tensor.shuffle(shuffles).shuffle(shuffles_inverse);
- VERIFY_IS_EQUAL(shuffle.dimension(0), 2);
- VERIFY_IS_EQUAL(shuffle.dimension(1), 3);
- VERIFY_IS_EQUAL(shuffle.dimension(2), 5);
- VERIFY_IS_EQUAL(shuffle.dimension(3), 7);
- for (int i = 0; i < 2; ++i) {
- for (int j = 0; j < 3; ++j) {
- for (int k = 0; k < 5; ++k) {
- for (int l = 0; l < 7; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), shuffle(i,j,k,l));
- }
- }
- }
- }
- }
- template <int DataLayout>
- static void test_empty_shuffling()
- {
- Tensor<float, 4, DataLayout> tensor(2,3,0,7);
- tensor.setRandom();
- array<ptrdiff_t, 4> shuffles;
- shuffles[0] = 0;
- shuffles[1] = 1;
- shuffles[2] = 2;
- shuffles[3] = 3;
- Tensor<float, 4, DataLayout> no_shuffle;
- no_shuffle = tensor.shuffle(shuffles);
- VERIFY_IS_EQUAL(no_shuffle.dimension(0), 2);
- VERIFY_IS_EQUAL(no_shuffle.dimension(1), 3);
- VERIFY_IS_EQUAL(no_shuffle.dimension(2), 0);
- VERIFY_IS_EQUAL(no_shuffle.dimension(3), 7);
- for (int i = 0; i < 2; ++i) {
- for (int j = 0; j < 3; ++j) {
- for (int k = 0; k < 0; ++k) {
- for (int l = 0; l < 7; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), no_shuffle(i,j,k,l));
- }
- }
- }
- }
- shuffles[0] = 2;
- shuffles[1] = 3;
- shuffles[2] = 1;
- shuffles[3] = 0;
- Tensor<float, 4, DataLayout> shuffle;
- shuffle = tensor.shuffle(shuffles);
- VERIFY_IS_EQUAL(shuffle.dimension(0), 0);
- VERIFY_IS_EQUAL(shuffle.dimension(1), 7);
- VERIFY_IS_EQUAL(shuffle.dimension(2), 3);
- VERIFY_IS_EQUAL(shuffle.dimension(3), 2);
- for (int i = 0; i < 2; ++i) {
- for (int j = 0; j < 3; ++j) {
- for (int k = 0; k < 0; ++k) {
- for (int l = 0; l < 7; ++l) {
- VERIFY_IS_EQUAL(tensor(i,j,k,l), shuffle(k,l,j,i));
- }
- }
- }
- }
- }
- EIGEN_DECLARE_TEST(cxx11_tensor_shuffling)
- {
- CALL_SUBTEST(test_simple_shuffling<ColMajor>());
- CALL_SUBTEST(test_simple_shuffling<RowMajor>());
- CALL_SUBTEST(test_expr_shuffling<ColMajor>());
- CALL_SUBTEST(test_expr_shuffling<RowMajor>());
- CALL_SUBTEST(test_shuffling_as_value<ColMajor>());
- CALL_SUBTEST(test_shuffling_as_value<RowMajor>());
- CALL_SUBTEST(test_shuffle_unshuffle<ColMajor>());
- CALL_SUBTEST(test_shuffle_unshuffle<RowMajor>());
- CALL_SUBTEST(test_empty_shuffling<ColMajor>());
- CALL_SUBTEST(test_empty_shuffling<RowMajor>());
- }
|