Skip to content

Propogating Eigen expression templates with local temporaries #1775

@andrjohns

Description

@andrjohns

Description

As first discussed in this comment, there is an issue with matrix functions returning expressions when those expressions use local temporary structures.

A simple example is the following:

#include <Eigen/Core>
#include <iostream>

template<typename T>
decltype(auto) test_fun(const T& x) {
    const Eigen::Ref<const Eigen::VectorXd>& x_ref = x;
    return (x_ref.array() - 5.0).matrix();
}

int main()
{
    Eigen::MatrixXd test_mat(2,2);
    test_mat << 5, 5, 5, 5;

    Eigen::VectorXd test_vec(2);
    test_vec << 5, 5;

    Eigen::VectorXd out = test_fun(test_mat.diagonal()).eval();
    Eigen::VectorXd out2 = test_fun(test_vec).eval();

    std::cout << "Expression:" << std::endl <<
                 out << std::endl << "Vector" <<
                 std::endl << out2 << std::endl;
}

Which returns:

Expression:
-5
 0
Vector
 0
 0

Because the temporary x_ref.array() falls out of scope.

A simple fix that seems to work is to explicitly set the inner stride:

template<typename T>
decltype(auto) test_fun(const T& x) {
    const Eigen::Ref<const Eigen::VectorXd,0,Eigen::InnerStride<> >& x_ref = x;
    return (x_ref.array() - 5.0).matrix();
}

But Eigen's documentation notes that will disable vectorisation.

Current Version:

v3.1.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions