Celestia and the Eigen library

Discussion forum for Celestia developers; topics may only be started by members of the developers group, but anyone can post replies.
Topic author
chris
Site Admin
Posts: 4211
Joined: 28.01.2002
With us: 22 years 9 months
Location: Seattle, Washington, USA

Celestia and the Eigen library

Post #1by chris » 16.07.2009, 13:24

I thought I'd start a topic to discuss Celestia's switch to the Eigen library.

For those new to the discussion, Eigen is a C++ template library for manipulating vectors and matrices. Through version 1.6.0, Celestia was using its own routines for vector and matrix operations. Moving from these custom classes to Eigen will have benefits in code readability and performance. Here's the main page for Eigen:
http://eigen.tuxfamily.org/index.php?title=Main_Page

Programmers will be most interested in the API showcase, which has a lot of code samples demonstrating the expressiveness of the API:
http://eigen.tuxfamily.org/index.php?title=API_Showcase

Here's an example from Celestia. This is some code from staroctree.cpp in 1.6.0:

Code: Select all

float   r     = scale * (abs(plane->normal.x) +
                         abs(plane->normal.y) +
                         abs(plane->normal.z));


With Eigen, this expression can be written more simply:

Code: Select all

float r = scale * plane.normal().cwise().abs().sum();


In the above code, 'cwise' means 'component-wise', i.e. apply the next operation to each component of the vector. It's one of many features that makes is possible to write more concise and readable code with Eigen. When manipulating vectors, the less one has to refer explicitly to the vector's individual components, the better.

The performance benefits of the switch to Eigen will be the result of three things:
1. Vectorization
2. Reduced amount of copying to store temporary results
3. Elimination of a few Celestia vector class inefficiencies (e.g. lots of copying from Point -> Vector and vice versa0

Vectorization promises the biggest benefit. All CPUs these days have extended instruction sets for performing multiple mathematical operations in parallel: SSE2 on Intel, Altivec on PowerPC. Both Altivec and SSE2 operate on 128-bit packets of data: either 4 single precision floats, or 2 double precision values. Simple code like this:

Code: Select all

Vector4f v = v1 + v2;

can be handled with a single SSE2 instruction instead of four regular CPU add instructions. Up until now, Celestia wasn't benefiting from CPU vector instructions; that will finally change after the switch to Eigen.

It will take some cleverness to fully exploit vectorization. CPUs required data for vector instructions to be aligned to 16-byte boundaries. Eigen takes care of this for structures with sizes that are multiples of 16-bytes such as Vector4f, Vector2d, and Vector4d. But, Vector3f and Vector3d are 12- and 24-bytes in size, respectively, and will not be vectorized. This is rather unfortunate, as these are the types used to represent points and normals in 3D space. In some cases, it will be worthwhile to convert a Vector3f to a Vector4f in order to take advantage of vectorization. I haven't made any optimizations like this so far. Better I think to wait until the conversion to Eigen is complete before tuning performance critical code sections for vectorization.

At this point, I don't expect to see much benefit from enabling SSE2 with the current SVN revision of Celestia. Most code in Celestia operates on Vector3f and Vector3d objects, which don't get vectorized. I'm optimistic that we can change some of this code to be vectorizable. I've had good results already with Vector3 to Vector4 conversion in some new code to draw orbits and trajectories.

There's already been some talk of benchmarking the current SVN version of Celestia with and without SSE2 enabled (at the end of this topic: viewtopic.php?f=4&t=13998&start=0 ). The most performance critical sections of code so far converted to Eigen are the star and DSO octree traversal, and the code to draw stars. For the most useful benchmark, it's best to aim the viewpoint away from any planets and observe a field with just distant stars and DSOs. In my own tests, I wait for the default star script to complete and then press * to point away from the Earth:

1.6.0: 284 fps peak
SVN, SSE2 enabled: 292 fps peak

So at this point, an insignificant performance increase on my system.

Edit: the above values are with galaxies disabled. When galaxies are enabled, I see these frame rates:
1.6.0: 166 fps peak
SVN, SSE2 enabled: 160 fps peak

...a performance [i]decrease[i]. I don't know yet whether this is a result of enabling SSE2 or whether there's an inefficiency in some of the Eigen-ized code I've checked in.

--Chris

Avatar
t00fri
Developer
Posts: 8772
Joined: 29.03.2002
Age: 22
With us: 22 years 7 months
Location: Hamburg, Germany

Re: Celestia and the Eigen library

Post #2by t00fri » 16.07.2009, 14:32

Looks quite good, as concerns matrices and vectors.

However it seems to me that quaternions are not extensively implemented (if at all) in Eigen. Of course, we know that quaternions do have matrix representations (as injective homomorphisms to the Matrix rings M_2(C) and M_4(R)). Yet quaternions are well known to have some special advantages:

1) Quaternions and their generalizations come handy for various purposes (e.g. conformal transformations!).

2) In computer science unit quaternions are said to require less CPU cycles for a 3d rotation than the matrix equivalent. I always thought that I have understood why this is so...

3) Rotations in 4 dimensions (Aha!) can be represented by pairs of unit quaternions!

etc.

Fridger
Image

Avatar
t00fri
Developer
Posts: 8772
Joined: 29.03.2002
Age: 22
With us: 22 years 7 months
Location: Hamburg, Germany

Re: Celestia and the Eigen library

Post #3by t00fri » 16.07.2009, 14:38

chris wrote:
...a performance [i]decrease[i]. I don't know yet whether this is a result of enabling SSE2 or whether there's an inefficiency in some of the Eigen-ized code I've checked in.

--Chris

Yes, thats what I found as well. See my respective posts of yesterday.
Yet, the effect is not very big...

Fridger
Image

Topic author
chris
Site Admin
Posts: 4211
Joined: 28.01.2002
With us: 22 years 9 months
Location: Seattle, Washington, USA

Re: Celestia and the Eigen library

Post #4by chris » 16.07.2009, 15:16

t00fri wrote:Looks quite good, as concerns matrices and vectors.

However it seems to me that quaternions are not extensively implemented (if at all) in Eigen. Of course, we know that quaternions do have matrix representations (as injective homomorphisms to the Matrix rings M_2(C) and M_4(R)). Yet quaternions are well known to have some special advantages:

1) Quaternions and their generalizations come handy for various purposes (e.g. conformal transformations!).

2) In computer science unit quaternions are said to require less CPU cycles for a 3d rotation than the matrix equivalent. I always thought that I have understood why this is so...

3) Rotations in 4 dimensions (Aha!) can be represented by pairs of unit quaternions!

Actually, quaternions are supported by Eigen, and I've been switching to Eigen quaternions at the same time I'm converting vector operations. Celestia's quaternion class has a few operations not supported (yet) by Eigen's quaternion class, such as sine, cosine, and exponentials. But, all of the operations required for using quaternions in 3D graphics (and mostly likely for 4D rotations) are there. See this page:

http://eigen.tuxfamily.org/dox/classEig ... rnion.html

Regarding performance of quaternions versus 3x3 matrices for rotations, see the note here:
http://eigen.tuxfamily.org/dox/classEig ... c02b6433ca
30n operations for direct multiplication, 24+15n operations if you convert the quaternion to a matrix and then multiply.

Quaternions are more compact and faster when multiplying two rotations together. The usual approach in 3D graphics is to keep rotations as quaternions until you need to transform a bunch of points and then convert them to 3x3 matrices for transforming points. In the conversion to Eigen, I've been taking advantage of the direct quaternion-vector product to save a few operations when only a single point is modified. We might see some small performance gain from this eventually, and it's also more concise.

--Chris

Avatar
t00fri
Developer
Posts: 8772
Joined: 29.03.2002
Age: 22
With us: 22 years 7 months
Location: Hamburg, Germany

Re: Celestia and the Eigen library

Post #5by t00fri » 16.07.2009, 16:00

Very good. Sorry, didn't have time yet to scan carefully through the docs...

Fridger
Image

Avatar
t00fri
Developer
Posts: 8772
Joined: 29.03.2002
Age: 22
With us: 22 years 7 months
Location: Hamburg, Germany

Re: Celestia and the Eigen library

Post #6by t00fri » 16.07.2009, 16:14

Chris,

another thought: apparently the adaptation to Eigen represented a major transscription affair and bugs (also non-trivial ones) cannot be excluded. Did you run any sensitive checks already to make sure that we really get the same results back?

In case of Eigen, bugs could be pretty nastily hidden...and therefore, I think real hard and sort of systematic numerical cross-checks are unavoidable.

Fridger
Image

Topic author
chris
Site Admin
Posts: 4211
Joined: 28.01.2002
With us: 22 years 9 months
Location: Seattle, Washington, USA

Re: Celestia and the Eigen library

Post #7by chris » 16.07.2009, 17:59

t00fri wrote:Chris,

another thought: apparently the adaptation to Eigen represented a major transscription affair and bugs (also non-trivial ones) cannot be excluded. Did you run any sensitive checks already to make sure that we really get the same results back?

In case of Eigen, bugs could be pretty nastily hidden...and therefore, I think real hard and sort of systematic numerical cross-checks are unavoidable.

I have not yet done anything other than visual checks. I want to write a script that dumps the coordinates of all the stars and DSOs to a file. We could then compare the results of running this script with 1.6.0 and the SVN version of Celestia. Another script could calculate dump the positions and orientations of some set of solar system bodies to a file. These are only partial tests. There could still be bugs in the stages between computing position/orientation and sending triangles to the hardware. Visual tests might be adequate here.

If you've got further suggestions (or even better, some working test scripts), I'd appreciate the help. I do expect some slight numerical differences, especially when enabling vectorization; these should be well below the uncertainties in the data.

Generally, the translation from Celestia's vectors to Eigen is straightforward and not particularly error prone. In fact, Eigen makes it easier to write bug free code. Typo-prone code like this:

Code: Select all

Vec3f vf((float) vd.x, (float) vd.y, (float) vd.z);

can be replaced with:

Code: Select all

Vector3f vf = vd.cast<float>();

However, there are a few tricky things... All vectors in Eigen are column vectors, so expressions like v1 = v2 * M are not legal. In contrast, Celestia lets a vector be treated as either a row or column, and has lots of code of the form vector * matrix. In most cases, M is a rotation matrix, and thus it's important to remember to transpose the matrix when swapping the operands: v1 = M.transpose() * v2. Fortunately, errors of this sort tend to (but won't always!) have unmistakable visual manifestations. :)

--Chris

Topic author
chris
Site Admin
Posts: 4211
Joined: 28.01.2002
With us: 22 years 9 months
Location: Seattle, Washington, USA

Re: Celestia and the Eigen library

Post #8by chris » 16.07.2009, 18:07

Looking forward to having this vectorized quaternion product in Eigen:

http://listengine.tuxfamily.org/lists.t ... 00019.html

This operation is used all over the Celestia code, so having a 2x faster version will be very nice indeed.

--Chris

Avatar
t00fri
Developer
Posts: 8772
Joined: 29.03.2002
Age: 22
With us: 22 years 7 months
Location: Hamburg, Germany

Re: Celestia and the Eigen library

Post #9by t00fri » 16.07.2009, 18:15

chris wrote:
t00fri wrote:Chris,

another thought: apparently the adaptation to Eigen represented a major transscription affair and bugs (also non-trivial ones) cannot be excluded. Did you run any sensitive checks already to make sure that we really get the same results back?

In case of Eigen, bugs could be pretty nastily hidden...and therefore, I think real hard and sort of systematic numerical cross-checks are unavoidable.

I have not yet done anything other than visual checks. I want to write a script that dumps the coordinates of all the stars and DSOs to a file. We could then compare the results of running this script with 1.6.0 and the SVN version of Celestia. Another script could calculate dump the positions and orientations of some set of solar system bodies to a file. These are only partial tests. There could still be bugs in the stages between computing position/orientation and sending triangles to the hardware. Visual tests might be adequate here.
In general a systematic test via such scripts seems the right thing to do. It would really be a pitty if stupid bugs would creep into Celestia unnoticed...Visual tests may be a good start, but for the nasty bugs this is clearly insufficient.
However, there are a few tricky things... All vectors in Eigen are column vectors, so expressions like v1 = v2 * M are not legal. In contrast, Celestia lets a vector be treated as either a row or column, and has lots of code of the form vector * matrix. In most cases, M is a rotation matrix, and thus it's important to remember to transpose the matrix when swapping the operands: v1 = M.transpose() * v2. Fortunately, errors of this sort tend to (but won't always!) have unmistakable visual manifestations. :)

--Chris

Well in case of 3d rotations the group is SO(3) with elements being the special orthogonal 3x3 matrices, satisfying M M^T = M^T M = 1, det(M) =+1. This means that the transposed matrix corresponds to the inverse rotation (M^-1 = M^T)...

Hence accidentally swapping M with M^T could generate quite a mess ;-)

Fridger
Image

Avatar
t00fri
Developer
Posts: 8772
Joined: 29.03.2002
Age: 22
With us: 22 years 7 months
Location: Hamburg, Germany

Re: Celestia and the Eigen library

Post #10by t00fri » 16.07.2009, 18:19

chris wrote:Looking forward to having this vectorized quaternion product in Eigen:

http://listengine.tuxfamily.org/lists.t ... 00019.html

This operation is used all over the Celestia code, so having a 2x faster version will be very nice indeed.

--Chris

Yeah! Looking forward to seeing vectorized quaternions in action...

Fridger
Image

Avatar
Chuft-Captain
Posts: 1779
Joined: 18.12.2005
With us: 18 years 11 months

Re: Celestia and the Eigen library

Post #11by Chuft-Captain » 16.07.2009, 19:54

chris wrote:I have not yet done anything other than visual checks. I want to write a script that dumps the coordinates of all the stars and DSOs to a file. We could then compare the results of running this script with 1.6.0 and the SVN version of Celestia. Another script could calculate dump the positions and orientations of some set of solar system bodies to a file. These are only partial tests. There could still be bugs in the stages between computing position/orientation and sending triangles to the hardware. Visual tests might be adequate here.
I worry that this approach could involve a lot of regression testing and yet still only partially test some pretty critical core code.
As this seems like quite a major re-factoring of the code, what about using assertions at key points in the code to prove that the new code is [ equivalent to / within a certain tolerance of] the old code?

CC
"Is a planetary surface the right place for an expanding technological civilization?"
-- Gerard K. O'Neill (1969)

CATALOG SYNTAX HIGHLIGHTING TOOLS LAGRANGE POINTS

Topic author
chris
Site Admin
Posts: 4211
Joined: 28.01.2002
With us: 22 years 9 months
Location: Seattle, Washington, USA

Re: Celestia and the Eigen library

Post #12by chris » 17.07.2009, 04:11

Chuft-Captain wrote:
chris wrote:I have not yet done anything other than visual checks. I want to write a script that dumps the coordinates of all the stars and DSOs to a file. We could then compare the results of running this script with 1.6.0 and the SVN version of Celestia. Another script could calculate dump the positions and orientations of some set of solar system bodies to a file. These are only partial tests. There could still be bugs in the stages between computing position/orientation and sending triangles to the hardware. Visual tests might be adequate here.
I worry that this approach could involve a lot of regression testing and yet still only partially test some pretty critical core code.
As this seems like quite a major re-factoring of the code, what about using assertions at key points in the code to prove that the new code is [ equivalent to / within a certain tolerance of] the old code?
Assertions are helpful during the conversion, but only in a few cases. The problem is that there are lots of trivial modifications, hardly any of which is worth the effort of an assertion by itself. The cumulative result of all these changes has a not insignificant chance of introducing a bug, but assertions are near useless in checking for such things--it's just impractical to retain the enough of the original code to generate comparison results.

So far, so good with the conversion... It's tedious, but the resulting code is much cleaner.

--Chris

Avatar
Chuft-Captain
Posts: 1779
Joined: 18.12.2005
With us: 18 years 11 months

Re: Celestia and the Eigen library

Post #13by Chuft-Captain » 17.07.2009, 07:09

chris wrote:
Chuft-Captain wrote:
chris wrote:I have not yet done anything other than visual checks. I want to write a script that dumps the coordinates of all the stars and DSOs to a file. We could then compare the results of running this script with 1.6.0 and the SVN version of Celestia. Another script could calculate dump the positions and orientations of some set of solar system bodies to a file. These are only partial tests. There could still be bugs in the stages between computing position/orientation and sending triangles to the hardware. Visual tests might be adequate here.
I worry that this approach could involve a lot of regression testing and yet still only partially test some pretty critical core code.
As this seems like quite a major re-factoring of the code, what about using assertions at key points in the code to prove that the new code is [ equivalent to / within a certain tolerance of] the old code?
Assertions are helpful during the conversion, but only in a few cases. The problem is that there are lots of trivial modifications, hardly any of which is worth the effort of an assertion by itself. The cumulative result of all these changes has a not insignificant chance of introducing a bug, but assertions are near useless in checking for such things--it's just impractical to retain the enough of the original code to generate comparison results.
Understood. Who said software development wasn't a hazardous job?! 8)

BTW. with regard to the visual checks of shader changes, rather than just eyeballing it, you might be able to set up regression tests before making the changes as follows;
1. Create a celURL at the scene you want to test.
2. Capture a PNG image of the scene.
The celURL together with the corresponding image forms the baseline test.

After making any code changes, go back to the celURL, re-capture a new image, then use something like Imagemagick to compare the 2 images. (You can script operations such as subtracting one image from the other in Imagemagick I think.)
You could set up a number of these regression tests and repeat them all after any code changes.

The capture process would still be tedious, but the scripted comparisons would be more reliable than a casual visual comparison.
EDIT: I just realized that you could script most of this process to make it less tedious. eg. a celx script could visit all the celURL locations, and capture the view from each location into a test output folder (there is a celx method to do image capture isn't there?). The only remaining task would be to do the comparisons between the test output and the baseline images, and it might be possible to automate this as well.

There you go, an automated regression testing procedure for detection of visual side-effects in Celestia. :)


CC
Last edited by Chuft-Captain on 17.07.2009, 18:01, edited 1 time in total.
"Is a planetary surface the right place for an expanding technological civilization?"
-- Gerard K. O'Neill (1969)

CATALOG SYNTAX HIGHLIGHTING TOOLS LAGRANGE POINTS

Avatar
Chuft-Captain
Posts: 1779
Joined: 18.12.2005
With us: 18 years 11 months

Re: Celestia and the Eigen library

Post #14by Chuft-Captain » 17.07.2009, 17:59

FYI, I edited the previous post, as it's Imagemagick NOT Irfanview which has these capabilities (if I remember correctly). It's a while since I used either of them. :oops:
"Is a planetary surface the right place for an expanding technological civilization?"
-- Gerard K. O'Neill (1969)

CATALOG SYNTAX HIGHLIGHTING TOOLS LAGRANGE POINTS

Avatar
t00fri
Developer
Posts: 8772
Joined: 29.03.2002
Age: 22
With us: 22 years 7 months
Location: Hamburg, Germany

Re: Celestia and the Eigen library

Post #15by t00fri » 17.07.2009, 18:07

CC,

I am afraid that your image comparison proposal cannot work since internally, the Eigen lib is quite different in "detail" from what Celesltia was using previously. You are thus bound to always get a small image difference, which leaves you with the problem to decide whether this is due to a bug or just due to numerics...

Actually the best image comparator is provided by nvimgdiff from the new NVIDIA texture tools...

Fridger
Last edited by t00fri on 17.07.2009, 18:29, edited 1 time in total.
Image

Avatar
cartrite
Posts: 1978
Joined: 15.09.2005
With us: 19 years 2 months
Location: Pocono Mountains, Pennsylvania, USA Greate Grandfother from Irshava, Zakarpattia Oblast Ukraine

Re: Celestia and the Eigen library

Post #16by cartrite » 17.07.2009, 18:25

I've been having problems building the kde gui with the most recent changes. Now at rev 4781. Anyhow, anyone building kde have similar problems? Fridger reports that he can build the kde gui as is.

I've noticed that changes were made to the gtk gui to get that to work. I got kde to work with a patch which is probably incorrect. To see what I did to get this to work, see the patch I attached to this post.

patched.txt.zip

cartrite
VivoBook_ASUSLaptop X712JA_S712JA Intel(R) UHD Graphics 8gb ram. Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz, 1190 Mhz, 4 Core(s), 8 Logical Processor(s) 8 GB ram. Running on Windows 11 and OpenSuse 15.4

Topic author
chris
Site Admin
Posts: 4211
Joined: 28.01.2002
With us: 22 years 9 months
Location: Seattle, Washington, USA

Re: Celestia and the Eigen library

Post #17by chris » 17.07.2009, 18:29

cartrite wrote:I've been having problems building the kde gui with the most recent changes. Now at rev 4781. Anyhow, anyone building kde have similar problems? Fridger reports that he can build the kde gui as is.

I've noticed that changes were made to the gtk gui to get that to work. I got kde to work with a patch which is probably incorrect. To see what I did to get this to work, see the patch I attached to this post.

The KDE star browser definitely does need to be patched. All versions of the star browser have similar code to compute the distance between the observer and stars, and all of this code is affected by the switch to Eigen. Your patch looks like it should work, though there's a slightly more elegant way to implement it using some new methods of the UniversalCoord class.

--Chris

Avatar
cartrite
Posts: 1978
Joined: 15.09.2005
With us: 19 years 2 months
Location: Pocono Mountains, Pennsylvania, USA Greate Grandfother from Irshava, Zakarpattia Oblast Ukraine

Re: Celestia and the Eigen library

Post #18by cartrite » 17.07.2009, 18:41

Your patch looks like it should work, though there's a slightly more elegant way to implement it using some new methods of the UniversalCoord class.
This is what I figured. I tried many different things. But this is all I could get to work. I didn't like the change

Code: Select all

Point3d bodyPos = body->getPosition(appSim->getTime());
but it does work. I seen what you did to qtcelestialbrowser.cpp but I had no idea how to implement those changes into the kde version celestialbrowser.cpp.
cartrite
VivoBook_ASUSLaptop X712JA_S712JA Intel(R) UHD Graphics 8gb ram. Intel(R) Core(TM) i5-1035G1 CPU @ 1.00GHz, 1190 Mhz, 4 Core(s), 8 Logical Processor(s) 8 GB ram. Running on Windows 11 and OpenSuse 15.4

Avatar
t00fri
Developer
Posts: 8772
Joined: 29.03.2002
Age: 22
With us: 22 years 7 months
Location: Hamburg, Germany

Re: Celestia and the Eigen library

Post #19by t00fri » 17.07.2009, 18:47

Also at rev 4781 celestia-kde compiles flawlessly on my machine (gcc 4.2.1) ;-) .Also the celestial browser seems to work fine. Not my fault ;-) But of course I have nothing against a fix as long as the result works as well ....

From looking at the code, I would also vote for a fix. ;-)

Fridger
Image

Avatar
Chuft-Captain
Posts: 1779
Joined: 18.12.2005
With us: 18 years 11 months

Re: Celestia and the Eigen library

Post #20by Chuft-Captain » 17.07.2009, 19:03

t00fri wrote:CC,

I am afraid that your image comparison proposal cannot work since internally, the Eigen lib is quite different in "detail" from what Celesltia was using previously. You are thus bound to always get a small image difference, which leaves you with the problem to decide whether this is due to a bug or just due to numerics...

Actually the best image comparator is provided by nvimgdiff from the new NVIDIA texture tools...

Fridger
Hi Fridger,

Well perhaps it will not be useful for the Eigen lib changes, but in principle it will be useful in the future so might well be worth the effort.
The other point is that the test comparison wouldn't nescessarily always/ever require a **perfect** image match. I think the idea is to set a threshold which would ignore the small image difference you mention above. So potentially, it could still be useful for picking up any *gross* errors which might occur as a result of the Eigen changes.

In any case, certainly after the Eigen changes are complete, it may well be worthwhile creating a baseline set of tests at that point for future use. It certainly would have picked up this error: viewtopic.php?f=3&t=13924

A set of automated regression tests is always useful for picking up *unexpected surprises*.
This has always been problematic I guess in celestia (wrt. shader bugs) because of the nature of the beast.

I imagine nvimgdiff will also be faster than Imagemagick. :).

CC
"Is a planetary surface the right place for an expanding technological civilization?"
-- Gerard K. O'Neill (1969)

CATALOG SYNTAX HIGHLIGHTING TOOLS LAGRANGE POINTS


Return to “Ideas & News”