Created attachment 280 [details] a Ref<> class mapping/evaluating any expression to a unique type This entry is related to the "Eigen Types as Parameters for Functions" thread of the ML. The goal is to provide a way to write nom templated functions taking any expression as argument. Before describing the solution, let's have a look at the following self-explanatory example: #include <iostream> #include <Eigen/Dense> using namespace Eigen; void foo1(Ref<VectorXf> a) { } void foo2(Ref<const VectorXf> a) { } int main() { VectorXf a(10); const VectorXf& ac(a); VectorBlock<VectorXf> ab(a,0,3); MatrixXf A(10,10); const VectorBlock<VectorXf> abc(a,0,3); foo1(a); //foo1(ac); // does not compile because ac is const foo1(ab); foo1(a.head(4)); foo1(abc); foo1(A.col(3)); foo1(A.row(3)); // copied into a temp because innerstride!=1 foo2(A*A.col(1)); // evaluated into a temp foo2(ac.head(5)); foo2(ac); foo2(a); foo2(ab); foo2(a.head(4)); foo2(a+a); // evaluated into a temp return 0; } The attached file add a Ref<> class taking the same template parameters as Map<>, but in contrary to Map<>, Ref<> is designed to map any Eigen's expression. Is the expression cannot be represented as a pointer+strides then the expression is evaluated into a temporary owned by the Ref<> object. By default, for a matrix object, Ref<> allows a pointer+outerstride and imposes innerstride==1. For a vector object, Ref<> also imposes innerstride==1. The later means that a row expression of a column major matrix will be evaluated into a temp. Unless the argument is read only once, this extra copy is preferable performance wise. Of course advanced users can finely control what they want to accept, e.g.: void foo(Ref<VectorXf,0,InnerStride<> > vec); will accept A.row(i) without any extra copy but at the cost of slower computations regardless of the actual innerstride. Currently one can also control the required alignment with the second template parameter: void foo(Ref<Vector4f,Aligned> vec); will only accept vector expressions of 4 elements sequentially stored and whose first entry is aligned on a 16bytes boundary. This is totally useless for dynamic sized expression, but might be useful for small fixed ones.
For a really clean solution, I would suggest solving bug 58 first, i.e. make Ref a special case of a direct access type. You could then avoid storing information twice, e.g. if you have temporaries with dynamic dimensions.
Created attachment 282 [details] New version of the Ref<> class Here is an updated version of the proposed Ref class that forbids evaluation for non-const arguments. This version also fixes many shortcomings (matrices, innerstrides, storage orders, etc.), but there are still many! This is still a proof of concept.
Created attachment 283 [details] usage exemples
An initial version has been commited: https://bitbucket.org/eigen/eigen/changeset/a34b903ce4b5/ changeset: a34b903ce4b5 user: ggael date: 2012-07-05 17:00:28 summary: Bug 481 step 1: add a new Ref<> class for non templated function arguments Still need to write proper unit tests and avoid duplication of rows/cols/data...
An here goes a proper unit test: https://bitbucket.org/eigen/eigen/commits/ad5257230f05/ changeset: ad5257230f05 user: ggael date: 2013-02-26 15:10:00 summary: Add a unit test for Ref.h and fix an extra copy. This should close this bug.
-- GitLab Migration Automatic Message -- This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/481.