This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen
Bug 481 - Unified object for Matrix, Block, Map
Summary: Unified object for Matrix, Block, Map
Status: RESOLVED FIXED
Alias: None
Product: Eigen
Classification: Unclassified
Component: Core - general (show other bugs)
Version: unspecified
Hardware: All All
: Normal Unknown
Assignee: Nobody
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 111 3.2
  Show dependency treegraph
 
Reported: 2012-06-27 10:22 UTC by Gael Guennebaud
Modified: 2019-12-04 11:44 UTC (History)
3 users (show)



Attachments
a Ref<> class mapping/evaluating any expression to a unique type (6.63 KB, application/octet-stream)
2012-06-27 10:22 UTC, Gael Guennebaud
no flags Details
New version of the Ref<> class (8.75 KB, text/plain)
2012-07-02 16:23 UTC, Gael Guennebaud
no flags Details
usage exemples (1.57 KB, text/plain)
2012-07-02 16:24 UTC, Gael Guennebaud
no flags Details

Description Gael Guennebaud 2012-06-27 10:22:17 UTC
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.
Comment 1 Christoph Hertzberg 2012-07-02 13:48:25 UTC
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.
Comment 2 Gael Guennebaud 2012-07-02 16:23:03 UTC
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.
Comment 3 Gael Guennebaud 2012-07-02 16:24:17 UTC
Created attachment 283 [details]
usage exemples
Comment 4 Gael Guennebaud 2012-07-05 17:05:48 UTC
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...
Comment 5 Gael Guennebaud 2013-02-26 15:12:49 UTC
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.
Comment 6 Nobody 2019-12-04 11:44:54 UTC
-- 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.

Note You need to log in before you can comment on or make changes to this bug.