|Re: [eigen] AutoDiffScalar|
[ Thread Index |
| More lists.tuxfamily.org/eigen Archives
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] AutoDiffScalar
- From: Björn Piltz <bjornpiltz@xxxxxxxxxxxxxx>
- Date: Fri, 6 Nov 2009 13:34:10 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=gamma; h=domainkey-signature:mime-version:received:reply-to:in-reply-to :references:date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=DhKYSteTqYkYxZq7chAPWzcvXmDcsACYQS8qd+O0Ivo=; b=PvZAeAQj1lmAB+E6LMRCeB4GJ8P6uOTQvHlaapPK+Vo5aRd+3zxy7Q2WgsvsnTnW2h nFd1FsjTZ1svs5+plWKzS3s4PUnzvqutlBvUCh1rgIjYQfpuK9OCfsplYu85/X4cDh+w wHaTS7IpYhptsdGA3fe8OJyJTcfPw9Hw6zX6M=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=googlemail.com; s=gamma; h=mime-version:reply-to:in-reply-to:references:date:message-id :subject:from:to:content-type:content-transfer-encoding; b=w8gkvYuopxcYd88oSOagmZRsIO8fwT+hxhVevsMp4PO047sSRf8+1aPce4TTNfNiGe wyEjuh3YH9vjBtYHa83dfimA1yHKdHrOiiBDtCBjzZ/y+Bh/nbqti7hcKQGV+kZoJ25W WA26uTNWRb3yqcEjJPcuMF1vKsCalS5XjsCc0=
Thanks for responding!
> * I think your "RealScalar prec => const RealScalar& prec" change is useless because, e.g., for a MatrixXd, or an AutoDiffScalar<VectorXd>, RealScalar==double. Basically, whatever the complexity of the coeffecient type, RealScalar type should always be equal to a primitive scalar type. Benoit, what do you think, shall I undo that change while doing the merge ? https://bitbucket.org/bjornpiltz/autodiff/changeset/d2bf8e746508/
I don't think it is true that RealScalar is always a primitive. the
RealScalar of an AutoDiffScalar is the Scalar of DerType. Defining a
AutoDiffScalar<Vector< AutoDiffScalar< VectorXd>>> didn't compile with
error C2719: formal parameter with __declspec(align('16')) won't be aligned
> * Why did you add ei_unused() ? What is its purpose ?
On MSVC I got a lot of warnings about unused parameters. It's not
important though and perhaps warning C4100 should simply be added to
> In CompressedStorage:
> * The behavior of the reserve() function looks even more odd than before. Unless you have strong arguments, I will remove the optional reserveSizeFactor parameter and update resize/append accordingly.
> * I don't understand the purpose of your changes in the ctor. E.g., it is fundamental that "CompressedStorage data(size);" is equivalent to "CompressedStorage data; data.resize(size);"
I had a two problems with how the terms resize/reserve were used.
1. My understanding is (from using stl) that reserve(int N) makes
place internally for N elements - not currentSize()+N.
2. Calling resize() in the constructor effectively fills the storage
with dangling pointers. Why would you want that to be the default
behaviour? I almost think the function resize() should be made
I also found the parameter reserveSizeFactor a bit goofy, but I just
kept it. I wouldn't mind a hard coded growth strategy.
I moved some code around so that the ctor is the only place where
memory is allocated and it is always freed in the dtor.
> * Your change in realloacate kills performances if, e.g., Scalar==AutoDiffScalar<VectorXf> because here we really want shallow copies. I agree that using memcpy is unsafe if the Scalar object creates a child-object which itself reference the parent... but recall that here we are designing containers for numerical values, not general containers. So I think it is fine to use memcpy here. Also a memcpy is much faster than simple for loops, and it is very important to provide optimal performances here.
Ah, this point is key. I really don't care so much about the other
changes, but this memcpy() caused a nasty crash when doing second
derivatives. AFAICT memcpy is inherently dangerous on anything but POD
types. I'll look into exactly why my code crashed.
So to sum up: The two showstoppers for my use-case were passing
RealScalar by value(doesn't compile) and the memcpy(ugly crash).
It is my understanding that to allow for non-POD Scalars in Eigen,
these two changes have to be made.
On the other hand, I certainly don't want to make Eigen slower for
How about expanding NumTraits to let Eigen know if a Scalar is a POD
or not. That way we can also make ei_construct_elements_of_array() and
ei_destruct_elements_of_array() more performant as well by not calling
placement new and dtor on PODs. Qt does something like this in
QVector. It might be worth taking a look at.
And at the same time, it would be really nice to have the Type
"PrimitiveScalar" or similar which always refers to a POD. Look at my
Finally, I'm sorry to make a fuzz about a quite exotic use case, but
I think Eigen has to decide whether matrices of matrices should be
supported or not.