0

Why the first index of a multidimensional matrix of Eigen::Tensor able to loop through all the members of the tensor successfully?

I am new to Eigen::Tensor library and still testing it to adopt it for my code.

#include <Eigen/CXX11/Tensor>

using namespace Eigen;

int main()
{
    Tensor<double, 3> t3d (2, 3, 4);
    t3d.setValues(
        {{{0, 6, 12, 18}, {2, 8, 14, 20}, {4, 10, 16, 22}},
         {{1, 7, 13, 19}, {3, 9, 15, 21}, {5, 11, 17, 23}}});
    for (int i = 0; i < t3d.size(); ++i)
    {
        cout << t3d(i, 0, 0) << '\t';
    }
}

It should give an error of some type (core dumped, etc.) or access unassigned portions of the memory to give random values. Surprisingly, this correctly outputs all the members of the tensor:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

2 Answers2

1

As of today, the behavior of accessing out-of-range elements of an Eigen::Tensor is not documented. But you can actually have it generate assertions when compiling with -DEIGEN_INTERNAL_DEBUGGING (however, this can make execution significantly slower).

Godbolt-Demo: https://godbolt.org/z/RrnjXS

chtz
  • 17,329
  • 4
  • 26
  • 56
1

Use chtz's answer to obtain the bounds checking. But there is an underlying mistaken assumption in your question. The tensor is just a block of memory accessed by data[a*k + b*j + i]. Therefore, if you change the access to data[i] but run through the entire array without exceeding the total size, you won't get any core dump/uninitialized value/UB.

The bounds checking in chtz answer will assert that the index in the ith dimension doesn't exceed the size of that dimension and not that of the entire size of the tensor. Thus, it's a more stringent constraint.

Avi Ginsburg
  • 10,323
  • 3
  • 29
  • 56
  • Yes I know that. But when I am NOT using a single index as in ```data[i]```, but using multiple indexes like ```data(i,j,k)```, then there should at least be a warning by the compiler. Using a single index denotes that I am trying to access all of the tensor members but multiple indexes means something else entirely. – mechieCoder Nov 01 '19 at 08:24
  • 1
    The compiler can’t warn you, as any static asserts will need runtime knowledge. If you want runtime asserts, use the method in chtz‘s answer. – Avi Ginsburg Nov 01 '19 at 08:27
  • You are right. The compiler cannot warn before the program is run. I meant to say that there should be an error, as there is when a similar code is executed for the matrix class: ```Matrix t2d; t2d << 0, 1, 2, 3, 4, 5; for (int i = 0; i < t2d.size(); ++i) { cout << t2d(i, 0); }``` – mechieCoder Nov 01 '19 at 08:50