Registered Member
|
Eigen Folks,
I'm trying to use Eigen3's NullaryExpr type, but have experiencing some compiler errors, and cannot find much in the Doxygen about this functionality. Here is my source code:
I'm using Linux G++ 4.4.5, and Eigen 3.0-beta2. I get the following compilation errors & warnings:
I expect this code to compile and work similarly to methods like 'Constant', 'Ones' and 'Zero'. Thanks for considering, -- Charles Wilcox |
Registered Member
|
here is one way to do it
#include <Eigen/Dense> struct DummyGenerator { typedef int result_type; result_type operator()(Eigen::DenseIndex&) const { return 42; } }; // struct DummyGenerator namespace Eigen { template<> struct ei_functor_traits <DummyGenerator> { enum { Cost = 1, PacketAccess = false, IsRepeatable = true }; }; } int main( int argc, char* argv[] ) { Eigen::Vector4d vector = Eigen::Vector4d::NullaryExpr( DummyGenerator() ); return 0; } // main Did not spend a lot time dig around, so I am not sure what does that IsRepeatable mean. I think it should be ok to set it to true for your case. |
Registered Member
|
ri_aje,
Thanks for the quick reply. I tried your mods to my example, and indeed it compiles. Thanks for that. Do you, or anyone else, have a reference to docs on doing this properly? I'd like to know things like: - What do all the values of the apparently required enum mean? - Why isn't there a default template implementation for any functor? - What's the required API and expected behavior of functor's 'operator()'? I actually have a more sophisticated implementation at work that has state and has a relatively high "Cost", and would like to clarify how best to implement and describe this to Eigen. -- Charles Wilcox |
Moderator
|
the Cost will control unrolling, and allow us to determine if it is better to evaluate it N times or to evaluate it once in a temporary and then read N times the temporary (e.g.: for matrix products).
PacketAccess: tell whether your functor is vectorized, if so you must provide a packet() method Repeatable : set it to true if it always return the same, and false otherwise (e.g.: a random number generator will have to set Repeatable to false) There is a default with cost=10, PacketAccess=false and Repeatable=true If M is a nullary expression with associated functor f, then: M(i,j) == f() |
Registered Member
|
ggael,
Thanks for this explanation. My functor has a TR1 'random' variate_generator, which clips results to min/max parameters. So, it sounds like I should be using: - IsRepeatable = false. // It has state that changes on every call. - PacketAccess = false. // I haven't vectorized my functor, neither are the TR1 'random' objects. - Cost = Some_large_unknown_value. // I'm using a mersenne-twister and a gaussian distribution. Is there any implicit "units" for the Cost value, such as CPU cycles? Speculation: Since 'IsRepeatable' will be false, the result will always have to be cached in a temporary, so the Cost-value is moot for that purpose? Then it should just affect loop-unrolling heuristics? Less importantly, if there is a default ei_functor_traits, why would my example not utilize it? I can't immediately find where this is defined in the eigen code. -- Charles Wilcox |
Moderator
|
You are right for all the points. The unit is in CPU cycles, and in your case you can simply use a large values like 1000 to totally disable unrolling.
|
Registered Member
|
ggael,
Thanks for confirming my intuitions, and contributing to such a useful library. -- Charles Wilcox |
Registered Member
|
Charles, how did you manage to pass a random number generator to NullaryExpr? I'm trying to do the same (albeit with boost variate_generator), and I'm having problems with constness:
|
Registered Member
|
I ran into this too. It's annoying. The built-in Random() NullaryExpr uses rand(), which changes a global variable. I flagged my rng as static and the generator object as mutable in my normal-distribution NullaryExpr. If the random number generator isn't static, then it's reseeded every time I use it (making it substantially less useful for random numbers).
|
Registered Member
|
Thanks a lot! Indeed, I tried to do something similar, but seemed to miss something; now I've finally got it.
As an aside, it looks to me that instead of having static rng, you could as well keep a reference to it and store elsewhere; thus you could also use it in other operations as well, improving the quality of generated numbers. |
Registered users: Bing [Bot], Google [Bot], Sogou [Bot]