Eliminating temporary values & allocations via Eigen template expressions or Eigen::Ref

math
#1

Hey all,

I know there’ve been several discussions about this topic but I actually can’t find any of them, for which I mostly blame the discourse search tool :P Please edit this post with links to others if you know of some.

I was just reading about Eigen and saw there’s an alternative to the templated Eigen Dense approach to not generating temporaries, and that’s to use Eigen::Ref: http://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html#TopicUsingRefClass

Did anyone try this? Does it perform almost as well? It looks like the kind of thing that we could actually start using immediately, which is a serious pro when compared with the more-perfect but much-more-work approach of retemplating everything to use the eigen base class and calling .eval() judiciously.

#2

I’ve honestly never quite understood the implications of their how to pass arguments to Eigen document.

I believe the core problem is that Eigen does not have a base expression template type that’s universal. I think where we failed before is getting Ref to work with block. Then there’s the issue of Eigen’s not recommending auto for reasons I still don’t understand.

Another angle might be to more generically emplate our function arguments.
Say, instead of

foo(const Matrix<T, -1, 1>& alpha)

we coul use

foo(const C& alpha)

we have metaprograms to pull the base scalar type (T) out of container types (like C).

I spent a few minutes looking and could only find this one.

#3

I’ve honestly never quite understood the implications of all this.

I believe the core problem is that Eigen does not have a base expression template type that’s universal. I think where we failed before is getting Ref to work with block. Then there’s the issue of Eigen’s not recommending auto.

Some of our function arguments could be more agressively templated. Say, instead of

foo(const Matrix<T, -1, 1>& alpha)

we coul use

foo(const C& alpha)

we have metaprograms to pull the base scalar type (T) out of container types (like C).

#4

IIRC the auto type is not always the one you want, so you might evaluate too early and therefore copy too much when dealing with expression templated. I’ve seen some examples where auto really hurts code readability, especially with templated code when what is really need is a type that’s available on hand or can be calculated. There’s a good job-Eigen article on it out there but I just spent a few minutes looking and I can’t find it. Anyway the concerns I have read about it are mild but relevant to code quality.

#5

This is exactly how I wrote some of torten’s functions, sometimes with enable_if.

#6

See: https://eigen.tuxfamily.org/dox/TopicPitfalls.html

The problem isn’t overpromotion (that is, evaluating too early), but just the opposite—it can fail to evaluate and be left in an inefficient partially evaluated mode where it also is still tied to the original values. So it can hurt performance and change semantics.