romeric / Fastor

A lightweight high performance tensor algebra framework for modern C++

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using auto as function return type causes wrong result when calculation is finally evaluated

Apocalyt opened this issue · comments

I happened to come across this strange result when working on some algorithm development.
Here is a condensed example code:

auto testFunc(Fastor::Tensor<double, 2, 1> tensor1, Fastor::Tensor<double, 2, 1> tensor2) {
    std::cout << tensor1 % transpose(tensor1) + tensor2 % transpose(tensor2) << std::endl;
    return tensor1 % transpose(tensor1) + tensor2 % transpose(tensor2);
}

Fastor::Tensor<double, 2, 2> testFunc2(Fastor::Tensor<double, 2, 1> tensor1, Fastor::Tensor<double, 2, 1> tensor2) {
    std::cout << tensor1 % transpose(tensor1) + tensor2 % transpose(tensor2) << std::endl;
    return tensor1 % transpose(tensor1) + tensor2 % transpose(tensor2);
}

int main() {
    Fastor::Tensor<double, 2, 1> t1 = {{1.0}, {1.0}};
    Fastor::Tensor<double, 2, 1> t2 = {{0.0}, {0.0}};

    std::cout << testFunc(t1, t2) << std::endl;
    std::cout << "-------------" << std::endl;
    std::cout << testFunc2(t1, t2) << std::endl;
}

This outputs the following after compiled and run:

[1, 1]
[1, 1]

[0, 0]
[0, 0]


[1, 1]
[1, 1]

[1, 1]
[1, 1]

I suppose something goes wrong when the operators get returned out instead of the the matrices being evaluated at end of function.

Are you able to get the same result? I suppose this should work even when actual evaluation happens outside the original function? I also tried passing by const reference thinking that maybe it tries to evaluate variables that have gone out of scope, but got the same result.

I used this version to get the result: https://platformio.org/lib/show/11298/Fastor/installation

commented

This is a well-known issue with expression templates. It has been discussed here multiple times (see #95 for example) for a technical discussion on this topic. See the wiki page for a clear explanation of this: https://github.com/romeric/Fastor/wiki/Pitfalls-&-gotchas

In short do not use auto as return type when you are returning tensor expressions. This issue is not specific to Fastor. Other expression templatte libraries have the same issue.

Hope that helps

Sorry for opening a duplicate issue and thanks for the links to the explanations.

I am a bit surprised this happens even if the tensors used in the calculation are passed by reference to the function. I was building some template code where output dimensions depend on template parameters. I guess I can still use auto and the evaluate-function for that.