It's been some time since I last updated you on
Eigen2...
We just released
alpha6. At this point, Eigen2 can do all what
Eigen1 did (and much, much more) so everyone is encouraged to use it for new code, and to port existing code to it.
We plan to release Eigen 2.0 during this fall, in time for the releases of the software projects which plan to use it (tentatively: KDE 4.2, Avogadro 1.0, KOffice 2.0, OpenBabel 3.0).
Eigen2 is a c++ pure-template-library (all the code in headers) for matrix/vector math (linear algebra) developed by
Gael Guennebaud and myself.
Usually I get questions about "how is it different from other libraries" and "you'll never have the resources to compete against $OTHER_LIBRARY which is developed by a huge team". So let me answer them here...
"how is it different from other libraries?"Other libraries tend to each be specialized on a particular aspect of linear algebra. The first specialization is between fixed-size and dynamic-size: most libraries handle only dynamic-size objects ("vector = new float[n]"), a few others do only fixed-size ("float vector[N]"). Another specialization is between dense and sparse objects. Yet another specialization is between libraries which focus on storage and basic algorithms, libraries which provide advanced algorithms, and libraries which provide convenience features which are not exactly part of linear algebra but very useful to applications.
Eigen2 does
all; of that -- though the sparse part is still experimental and not planned for the 2.0 release. For advanced sparse algorithms we plan to let the user choose a backend, be for the rest Eigen2 is entirely self-contained.
Thus, one of Eigen2's main distinguishing features is to be
versatile. This was commanded by KDE's needs: KDE is a huge metaproject with very very diverse needs, and Eigen
started as an attempt to fulfill them (at that time we wrongly believed that KDE had only simple needs!)
Another distinguishing feature of Eigen2 is that is it thoroughly based on
expression templates. Roughly, this means that when you do "v3 = v1 + v2;", instead of computing the sum v1+v2 and then copying it to v3, Eigen first constructs a "sum expression" object representing v1+v2, storing some "metadata" on this algebraic expression. In the "v3=v1+v2" example this allows to avoid the unneccessary temporary returned by "v1+v2". In more complex expressions, it becomes nontrivial to know which temporaries to remove and which to keep; Eigen has a lot of compile-time logic to determine that intelligently. We believe that we are the only library around to do that; other expression templates libraries tend to always remove temporaries, even when evalutating the temporary is actually a good thing. Non-expression-templates libraries have no choice but to always evaluate, and thus miss huge optimization opportunities.
Expression templates don't stop here -- at least not in Eigen2! First, the compile-time metadata which they convey is used to perform more optimizations: generic vectorization (SSE2 to SSSE3, and experimental AltiVec support), and generic loop unrolling. Second, expression templates allow zero-cost method chaining and allows return values to be lvalues. This means that you can write "matrix.row(i) += something" or "matrix.diagonal().start(n).setZero()" and when you look at the generated asm, it is really like handwritten, vectorized, minimal assembly -- nothing remains of the syntactic sugar.
"you'll never have the resources !"Eigen2 is mostly a 2-persons project and currently
has only 11000 LOC, and that includes some experimental code that i'm not even discussing here (Sparse matrices...). By contrast the other libraries (BLAS/LAPACK implementations) are typically developed by large academic teams or, in the case of MKL, by Intel's own engineers, and they are huge:
- the Intel MKL linux/x86 package weighs 250 MB (can't tell how many LOC, it's closed-source).
- GOTO has 750,000 LOC (and it's barely "open source" as its license does not even allow redistribution! makes me wish the term "open source" had not been coined, it's too easily abused)
- ATLAS, the best of the existing truly free libraries, has 400,000 LOC.
So, we can't stand a chance against them, can we?
Well, the first thing to be said is that none of these libs handles
fixed-size objects. Yet, this is the majority of use cases for a non-scientific project like KDE. So the above libraries can't be used for these use cases (they are then 20x slower than a library optimized for fixed-size objects like Eigen).
Ok ok, you'll tell me, but what about
dynamic-size objects, which is the area in which the above big libraries specialize? A tiny library like Eigen can't compete against them on their own ground, right?
Well, since we have such a generic framework for matrix computations, with a great c++ API and generic optimizations, implementing and optimizing all the usual linear algebra algorithms doesn't take us as long as it takes other projects, nor does it take as many lines of code. In some cases, special care is needed to be cache-friendly (a crucial aspect with very large objects), and fortunately, Gael is extremely good at that.
Here are some benchmark results (
dynamic-size, higher is better),
details and more results here :
I should say that the benchmarking effort and subsequent optimizations was entirely by Gael. Also, 3 of the 4 benchmarks presented above (matrix-vector, matrix-matrix and triangular solver) are benchmarking solely code written by him (just so you know that eigen is not at all anymore the one-person project it used to be until 6-7 monthes ago).