This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen

Bug 984

Summary: Fusing the evaluation of multiple expressions
Product: Eigen Reporter: Gael Guennebaud <gael.guennebaud>
Component: Core - expression templatesAssignee: Nobody <eigen.nobody>
Status: DECISIONNEEDED ---    
Severity: Optimization CC: chtz, gael.guennebaud, jacob.benoit.1, neumann, rmlarsen
Priority: Lowest    
Version: 3.4 (development)   
Hardware: All   
OS: All   
Whiteboard:
Bug Depends on: 110    
Bug Blocks: 401, 1608    

Description Gael Guennebaud 2015-03-30 17:10:59 UTC
The following forum entry make me though about the possibility to evaluate multiple expressions at once. By overloading DenseBase::operator,(DenseBase<Other>&), a possible API could be:

A,B = expression1, expression2;

If A and B appears to be compatible (same size, same alignement, etc.), then there evaluation could be merged in a single loop reducing cache misses if expression1 and expression2 access to same entries.
Comment 1 Christoph Hertzberg 2015-03-30 17:27:35 UTC
That sounds interesting indeed.
With that we could also provide mechanisms to write functions which return multiple expression, similar to Matlab's [Q,R]=qr(A) syntax.

I guess, we'd either need assignments return expressions as well (Bug 110), or we'll need to write either 
  (A,B) = expr1, expr2;
or
   A,B  = (expr1, expr2);
or a combination of all of them, to make this work.

I make this block 3.4, but we can postpone it to any later release if this turns out to be too complicated.
Comment 2 Rasmus Munk Larsen 2016-02-23 22:41:33 UTC
Could we simply rely on std::tie for implementing this in 3.4?
Comment 3 Christoph Hertzberg 2016-02-24 08:23:13 UTC
Unfortunately, std::tie would lose C++03 compatibility. But I agree that this would be a consistent syntax, otherwise.
Perhaps, we can simply implement Eigen::tie(...)?
Comment 4 Gael Guennebaud 2016-03-01 08:07:42 UTC
I think we need our own tie/tuple anyway because we want our own implementation of operator= for such tuple...

Will be also useful to implement minmax, vectorwise-minmax, sincos...
Comment 5 Gael Guennebaud 2019-02-16 10:09:45 UTC
Following the example given in bug 1680,

> StateSines = yi.array().sin();
> StateCosines = yi.array().cos();

It could be something like:

tie(S,C) = tie(yi.array().sin(), yi.array().cos());

or even

tie(S,C) = vi.array().sincos();
Comment 6 neumann 2019-02-16 21:00:20 UTC
https://godbolt.org/z/2pWgXj

guard with EIGEN_HAS_CPP17 and maybe add constexpr ;)
Comment 7 Gael Guennebaud 2019-02-17 12:34:00 UTC
The goal is rather to fuse the evaluation loops to save on both computation and memory accesses. So instead of generating something like:

  for(i...)
    s[i] = sin(v[i]);
  for(i...)
    c[i] = cos(v[i]);

we would generate:

  for(i...) {
    [s[i],c[i]] = sincos(v[i]);
  }
Comment 8 neumann 2019-02-18 21:16:53 UTC
My post was more about the syntax then the actual sincos implementation. Compilers can optimize it given the correct flags. But I was yet unable to get the calls to sincos in my program (might have to add .eval() to my code)

https://godbolt.org/z/8XPG7g

(increase size to 16 and gcc won't use sincos anymore)
Comment 9 Nobody 2019-12-04 14:25:15 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/984.