Menu

Return expression from function

mmoeller
2016-05-31
2016-06-06
  • mmoeller

    mmoeller - 2016-05-31

    Dear all,

    I struggle with the problem to create an expression within a function and return the expression (not its evaluation into a vector). The following piece if code is meant to illustrate the problem:

    #include <iostream>
    #include <chrono>
    
    #include <viennacl/vector.hpp>
    
    template<typename T1, typename T2, typename T3>
    auto calculate(const T1& a1, const T2& a2, const T3& a3)
        -> decltype( viennacl::linalg::element_div(viennacl::linalg::element_prod(a1,a1) +
                                                                                                     viennacl::linalg::element_prod(a2,a2),
                                                                                                     viennacl::linalg::element_prod(a3,a3)) )
    {
        return viennacl::linalg::element_div(viennacl::linalg::element_prod(a1,a1) +
                                                                                        viennacl::linalg::element_prod(a2,a2),
                                                                                        viennacl::linalg::element_prod(a3,a3));
    }
    
    int main()
    {
    
        typedef viennacl::vector<float> vector;
    
        vector density(100), momentum_x(100), momentum_y(100), result(100);
    
        for (auto i=0; i<density.size(); i++)
            density(i) = 2.0;
        for (auto i=0; i<momentum_x.size(); i++)
            momentum_x(i) = 1.0;
        for (auto i=0; i<momentum_y.size(); i++)
            momentum_y(i) = 2.0;
    
        result = viennacl::linalg::element_div(viennacl::linalg::element_prod(momentum_x,momentum_x) +
                                                                     viennacl::linalg::element_prod(momentum_y,momentum_y),
                                                                     viennacl::linalg::element_prod(density,density));
    
        std::cout << result(0) << std::endl;
    
        result = calculate(momentum_x, momentum_y, density);
    
        std::cout << result(0) << std::endl;
    
        return 0;
    }
    

    The direct assembly of the expression in the main function with immediate evaluation works fine. However, the call to the calculate functions yields:

    viennacl-debug(10578,0x7fff7751a000) malloc: *** mach_vm_map(size=562938571542528) failed (error code=3)
    *** error: can't allocate region
    *** set a breakpoint in malloc_error_break to debug
    terminate called after throwing an instance of 'std::bad_alloc'
      what():  std::bad_alloc
    Abort trap: 6
    

    It appears to me that element_prod and element_quot return temporaries which are just stored via const refs in the expression, and hence, they are no longer available outside the calculate function. Any help on returning expressions from functions is appreciated.

    Best,
    Matthias

     
  • Karl Rupp

    Karl Rupp - 2016-06-01

    Hi Matthias,

    I haven't looked into the issue in detail yet, but my first guess is the same as yours: Most likely,
    viennacl::linalg::element_prod(a1,a1) + viennacl::linalg::element_prod(a2,a2)
    inside calculate() generates a temporary, which then goes out of scope (and is hence destroyed) before result = calculate(...) is executed.

    I'll try to reproduce the issue and report back.

    Best regards,
    Karli

     
    • mmoeller

      mmoeller - 2016-06-01

      Hi Karli,

      I have been experimenting with several expression template libraries and some of them really have difficulties with composing the expression inside functions and returning them as expressions. The code given (and attached to this post) can be directly compiled.

      Best regards,
      Matthias

       
  • Karl Rupp

    Karl Rupp - 2016-06-04

    Hi Matthias,

    thanks for the debugging code. I looked at the backtraces, which confirm what we expected: The temporary created inside calculate() goes out of scope before the evaluation is completed.

    In order to fix this, the whole expression template engine in ViennaCL would have to be redesigned. This is not going to happen within the 1.x.y release series. The problem can be addressed in ViennaCL 2.0.0 (with a better separation of expression templates and actual operations), but this will take at least a couple more months.

    Best regards,
    Karli

     
  • mmoeller

    mmoeller - 2016-06-05

    Dear Karli,

    I would highly appreciate of this feature can be addressed in ViennaCL 2.x.y.
    If you would like to know more about my usage of ViennaCL (in a real research code), which might rise some more ideas to be considered in a redesigned ViennaCL library, I can eplain to you in a personal email.

    Best regards,
    Matthias

     
  • Karl Rupp

    Karl Rupp - 2016-06-06

    Dear Matthias,

    yes, I'm very interested in your thoughts on how we can further enhance ViennaCL. Please send your ideas to rupp AT iue.tuwien.ac.at

    Thanks! :-)

     

Log in to post a comment.