My Google Summer of Code project was working on the NMatrix project, moving
functionality that depends on external libraries from the core nmatrix
gem to optional plugin gems. NMatrix is a Ruby library for linear algebra,
used by many other projects.
In addition to the code that was part of
NMatrix proper, NMatrix previously required the ATLAS library, which
implemented fast versions of common matrix operations like multiplication
and inversion, as well as more advanced operations like eigenvalue
decomposition and Cholesky decomposition.
There were two separate but related motivations for my project. The first was to simplify the NMatrix installation process. ATLAS can be difficult to install, so the installation process for NMatrix was complicated, especially on OS X, and may have discouraged people from using NMatrix. The second motivation was that by separating out the ATLAS code from the main NMatrix code, it would be easier to add new linear algebra backends which provide similar features. Indeed, I implemented a second backend this summer.
The end result of my summer’s work:
- The core
nmatrix
gem does not depend on any external linear matrix libraries. It provides non-optimized implementations of common matrix operations. - All code that requires ATLAS has been moved into the new
nmatrix-atlas
gem, so that those who are only interested in the core functionality are not required to install ATLAS.nmatrix-atlas
provides optimized implementations of common matrix operations, as well as advanced functions not available innmatrix
. I wrote a blog post describing the setup for releasing multiple gems from the same repository, which this required. - A new gem
nmatrix-lapacke
, which provides the same features asnmatrix-atlas
, but instead of depending specifically on the ATLAS library, requires any generic LAPACK and BLAS implementation. This should be easier to use for many users as they may already have LAPACK installed (it comes pre-installed with OS X and is commonly used in Linux systems), but not ATLAS. - The installation procedure is simplified, especially for those installing
just the
nmatrix
gem. Compare the new installation instructions to the old ones.
The one deviation from my original proposal was that I originally intended to remove
all the ATLAS code and release only the nmatrix-lapacke
plugin, so that we
would only have one interface to the advanced linear algebra functions, but I
decided to keep the ATLAS code, since the nmatrix-lapacke
code is new and
has not had a chance to be thoroughly tested.
Usage
1 2 3 4 5 |
|
1 2 3 4 5 6 |
|
For advanced functions not provided by the core nmatrix
gem, for example
gesvd
, nmatrix-atlas
and nmatrix-lapacke
provide a common interface:
1 2 3 4 5 |
|
1 2 3 4 5 6 |
|
If the developer wants to use an advanced feature, but does not care
whether the user is using nmatrix-atlas
or nmatrix-lapacke
, they can require nmatrix/lapack_plugin
, which will
require whichever of the two is available, instead of being forced to
choose between the two.
As a fun test of the new gems, I did a very simple benchmark, just
testing how long it took to invert a
1500-by-1500 matrix in place using NMatix#invert!
:
nmatrix
(no external libraries): 3.67snmatrix-atlas
: 0.96snmatrix-lapacke
with ATLAS: 0.99snmatrix-lapacke
with OpenBLAS (multithreading enabled): 0.39snmatrix-lapacke
with reference implementations of LAPACK and BLAS: 3.72s
This is not supposed to be a thorough or realistic benchmark (performance will depend on your system, on how you built the libraries, and on the exact functions that you use), but there are still a few interesting conclusions we can draw from it:
- Performance is much better using the two highly optimized libraries (ATLAS and OpenBLAS) than using either the NMatrix internal implementation or the reference implementation.
- When using ATLAS, performance is similar whether using
nmatrix-atlas
andnmatrix-lapacke
(this means we could consider deprecating thenmatix-atlas
gem).
Overall, my summer has been productive. I implemented everything that I proposed and feedback from testers so far has been positive. I plan to stay involved with NMatrix, especially to follow up on any issues related to my changes. Although I won’t be a student next summer, I would certainly consider participating in Google Summer of Code in the future as a mentor. I’d like to thank my mentor John Woods and the rest of the SciRuby community for support and feedback throughout the summer.