math icon indicating copy to clipboard operation
math copied to clipboard

[FR] Supporting Eigen::Tensor

Open SteveBronder opened this issue 4 years ago • 3 comments

Description

It would be a lot of work, but I think if we supported Eigen's Tensor types we could use those for much more efficient array structures.

In Stan, when we have something like

data {
  matrix[N, M] Y[3, 4, 5];
}

What we actually have in the C++ is something like

std::vector<std::vector<std::vector<Eigen::MatrixXd>>> Y;

Under the hood this translates to a big structure of pointers pointing to other pointers. In pseudocode the above structure is almost something like

double**** Y;

This also makes it a bit trickier to give optimization advice because for matrices we are column major, but it's actually more optimal to access arrays as if we are going over row major constructed memory.

Eigen's Tensor module supports multi-dimensional objects like we currently have for arrays. For the example above

Eigen::Tensor<double, 5> t(N, M, 3, 4, 5);

This is nice because now our data structure is simply a double* with memory in column major order. Another benefit of this is with the new matrix type we can use our current scheme and place an Eigen Tensor into the var like

var_value<Eigen::Tensor<double, 5>>

There's a lot of things to sort out for this to work. The docs are here. Essentially anywhere that currently accepts an std::vector<> needs to accept an Eigen::Tensor. Some functions will need new specializations, but other functions that already accept either Eigen::Vector or std::vector<> types should require minimal changes. A good first step may be to get the distributions working with 1 dimensional tensors.

For the Stan repo we would need reading in and out tensors from a var_context as well as operating on them via the serializer and deserializer. For stanc we would need to change the current code that uses std::vector<> to generate an Eigen::Tensor<> instead.

I personally am not sure I'd have time to work on this, but for anyone that is interested I'd be happy to do reviews!

Current Version:

v4.1.0

SteveBronder avatar Jul 12 '21 17:07 SteveBronder

Some other considerations are that we would need to use the plugin extension and add to_matrix(), to_vector(), and to_row_vector() so if we have a Stan structure like

matrix[N, M] Y[2, 3, 4];

Once we access the outer dimensions of the array part the stanc compiler need to know it is now working with a matrix. I'm putting a little godbolt below with a tensor setup if anyone wants to play with it

https://godbolt.org/

SteveBronder avatar Jul 12 '21 18:07 SteveBronder

I really like this! Do we need to be concerned that Tensor is in the unsupported modules?

andrjohns avatar Jul 13 '21 14:07 andrjohns

Ty! It's maintained by Google so idt so. It's only in unsupported because it requires c++11

SteveBronder avatar Jul 13 '21 17:07 SteveBronder