viennacl / viennacl-dev

Developer repository for ViennaCL. Visit http://viennacl.sourceforge.net/ for the latest releases.
Other
281 stars 89 forks source link

‘const class viennacl::matrix_expression<const viennacl::matrix_base<float>, const viennacl::matrix_base<float>, viennacl::op_element_binary<viennacl::op_prod> >’ has no member named ‘size’ #224

Open tsmithe opened 7 years ago

tsmithe commented 7 years ago

Offending code (R is a dense matrix of scalar type FloatT):

  viennacl::vector<FloatT> norms = viennacl::linalg::element_sqrt
    (viennacl::linalg::row_sum
     (viennacl::linalg::element_prod(R, R)));

Adding a temporary avoids the problem:

  viennacl::vector<FloatT> norms = viennacl::linalg::element_sqrt
    (viennacl::vector<FloatT>(viennacl::linalg::row_sum
                              (viennacl::linalg::element_prod(R, R))));
tsmithe commented 7 years ago

Also, I fairly often find that if I write in an 'almost-always-auto' style, hoping that the compiler will do clever things with my expression trees (avoiding temporaries, kernel fusion, etc), I run into this kind of error.

karlrupp commented 7 years ago

Arbitrary nesting of expressions (like in the above case) will produce temporaries if the expression gets too complex. This is a limitation of how ViennaCL deals with different backends.

From the performance point of view, one would prefer to identify "slow" easily, e.g. by compilation errors. From the usability point of view, one often just wants to "get going" and worry about possible performance bottlenecks later. What is your preference in this case?

tsmithe commented 7 years ago

I think it doesn't matter to me, as a user, whether ViennaCL goes for compilation errors or just "gets going". But I think the error referenced here (and others like it) is a bit opaque: it arises not explicitly because of performance issues, but rather suggests that the performance issue (requirement for an explicit temporary) arises because row_sum returns an object with no size method (ie, a matrix). In other cases, perhaps the remedy is the same -- insert a temporary -- but the error message is also somewhat opaque.

I suppose what I am getting at is this: compilation errors are fine, but they should be informative, and ideally consistent!

Perhaps ViennaCL could use some template magic to provide a function like viennacl::force_temporary(...) or viennacl::insert_temporary(...), which would make the bottleneck explicit, but also allow 'get-going' AAA style? Perhaps that's redundant; it is easy enough just to write the full temporary type out explicitly... (In any case, I feel that the user should be guided rather than confused by any compilation errors.)