
After a great deal of effort, I’ve finally finished compiling Sage 5.5 on the Raspberry Pi. It seems to be basically functional; it starts and adds 2+2 successfully. (So already it’s doing better than Trurl’s Machine.) I’m currently running the full test suite, which could very well take a few days. We’ll see when it gets there. For now, here’s a link to a binary; drop me a line if you have trouble with it. To get started, extract it with:
tar -xvpf sage-5.5-pi.tar.bz2
Then cd into the resulting directory and run “./sage” from the command line, or set up a link which runs “[full-path-to-sage]/sage -notebook()]”, which will automatically open a sage notebook in a browser.
If you’re curious about building sage yourself, there are details after the jump. It requires a bit of blood and something like 3 days of processor time, with somewhere south of 3 days of additional time used by the swap memory.
The gory details:
- This was a long, long process. The full build took 6.32 days of ‘real’ time (plus some extra down time a couple times when things were stopped for a few hours while I slept), but only 2.9 days of processor time. This discrepancy is discussed in point 3, below.
- The Sage build is broken up into ‘spkg’ files, essentially many different components of Sage which need to be built. This modularity is actually quite helpful, since if the build is interrupted for any reason, it restarts on the last spkg it was working on instead of starting over from scratch.
- I ran the build on an 8gb USB stick with 3gb set aside as swap. You have to set aside a large amount of swap in order for the build to succeed. The USB ports on the Pi are known to have much better throughput than the SD reader, so it’s better to build on an attached drive. It would be best to use an external mechanical hard drive, both due to good write speed and because utilizing a USB key as swap space is pretty dumb and will greatly shorten the life of the drive. I didn’t have easy access to an external mechanical hard drive, so used a USB key. (Actually, I do have an external drive, but the Pi doesn’t supply enough power to spin it up; so an external drive should either be wall-powered or running from an attached powered USB hub.)
- The build really uses the swap quite a bit; the 512mb of memory isn’t quite enough. You can make things a bit better by running headless and not starting the X server and setting aside 0mb of memory for the video card, using raspi-config. But still the swap is heavily used. The worst instance is in building libm4rie, which took about 100 minutes of CPU time and almost three days of real time, the great majority of which was spent waiting for read/writes to the swap memory.
- I also managed to speed things up a bit by using ‘nice’ to greatly increase the priority of the build. In the Sage directory, start the compilation with:
sudo nice -n -20 make - Probably the most fiddly part technically was building the Tachyon package. (Everything else you can deal with by just waiting longer!) The ‘tachyon’ spkg fails to build out of the box because it doesn’t recognize the ‘armv6l’ architecture. To fix this, you need to unpack the tachyon spkg (which lives in sage-X/spkg/standard) and edit the spkg-install file. In this file, find the sole reference to the ‘armv7l’ and change the 7 to a 6 and you’ll be good to go. Repack the spkg, put it back in the original directory where you found it, and all will be ok. (This old Sage trac ticket was very helpful in figuring out the problem. And here’s the Sage page on building spkgs.)
Finally, here’s a bunch of data on how long all of the various spkg’s took, sorted by ‘real’ time. When you see a large discrepancy between ‘real’ time and the sum of the user and system columns, it indicates a package that used a lot of swap in the build process.
SPKG | Real | User | Sys |
libm4rie-20120613 | 254473.15 | 9875.25 | 1066.77 |
sage-5.5 | 55130.081 | 52872.23 | 666.71 |
atlas-3.8.4.p1 | 44580.16 | 42346.38 | 1159.65 |
ppl-0.11.2.p1 | 26241.045 | 5738.98 | 901.72 |
singular-3-1-5.p1 | 18821.298 | 17805.58 | 348.44 |
symmetrica-2.0.p7 | 16648.936 | 16105.89 | 144.14 |
r-2.14.0.p6 | 15221.223 | 14395.16 | 296.36 |
linbox-1.3.2 | 14897.041 | 3053.92 | 413.48 |
polybori-0.8.2 | 14343.793 | 5131.82 | 386.12 |
eclib-20120428 | 10940.947 | 10518.8 | 199.8 |
scipy-0.11.0 | 10284.038 | 9737.85 | 168.51 |
maxima-5.26.0.p0 | 8199.652 | 7340.61 | 263.43 |
gfan-0.5.p0 | 6443.753 | 6242.54 | 103.76 |
gsl-1.15.p0 | 3966.285 | 3563.82 | 211.71 |
pari-2.5.3.p0 | 3800.964 | 3649.57 | 45.86 |
python-2.7.3.p2 | 3035.209 | 2737.94 | 117.8 |
ecl-11.1.2.cvs20111120.p2 | 2958.457 | 2786.2 | 80.1 |
palp-2.1.p0 | 2837.422 | 2437.3 | 31.55 |
ntl-5.5.2 | 2792.485 | 2710.47 | 49.83 |
cython-0.17pre | 2475.362 | 2437.68 | 14.66 |
mpir-2.4.0.p6 | 2308.991 | 1726.08 | 249.39 |
pynac-0.2.5 | 2007.256 | 1285.2 | 60.55 |
libm4ri-20120613 | 1980.33 | 1922.14 | 23.01 |
gap-4.4.12.p8 | 1509.469 | 1416.34 | 32.35 |
matplotlib-1.1.0 | 1478.705 | 1435.35 | 24.71 |
numpy-1.5.1.p1 | 1425.49 | 1379.76 | 20.51 |
cvxopt-1.1.5 | 1385.595 | 1330.61 | 36.6 |
givaro-3.7.1 | 1280.573 | 1166.25 | 57.87 |
mpfr-3.1.0.p2 | 1139.385 | 951.21 | 94.17 |
sqlite-3.7.5.p1 | 1087.921 | 1020.52 | 18.48 |
lapack-20071123.p2 | 988.834 | 829.74 | 91.65 |
freetype-2.3.5.p4 | 835.653 | 752.11 | 36.51 |
lcalc-1.23.p10 | 818.566 | 798.6 | 7.53 |
libfplll-3.0.12.p2 | 780.614 | 706.52 | 34.11 |
glpk-4.44.p0 | 726.694 | 661.55 | 30.32 |
cddlib-094f.p11 | 610.865 | 536.58 | 30.92 |
flint-1.5.2.p2 | 600.518 | 579.99 | 6.21 |
ecm-6.3.p8 | 583.175 | 505.76 | 29.4 |
sagenb-0.10.2 | 538.538 | 435.19 | 47.24 |
pil-1.1.6.p4 | 506.733 | 340.21 | 17.11 |
zodb3-3.7.0.p4 | 462.132 | 434.62 | 14.09 |
mpfi-1.5.1 | 428.638 | 282.4 | 46.91 |
mpc-1.0.p0 | 387.135 | 277.61 | 35.19 |
fflas_ffpack-1.6.0 | 382.08 | 327.77 | 20.96 |
readline-6.2.p3 | 375.043 | 320.18 | 22.05 |
rubiks-20070912.p18 | 357.277 | 337.42 | 7.12 |
boehm_gc-7.2.alpha6.p2 | 342.06 | 274.52 | 26.26 |
iml-1.0.1.p14 | 334.849 | 262.68 | 26.44 |
zn_poly-0.9.p9 | 306.675 | 280.65 | 7.5 |
gd-2.0.35.p7 | 305.343 | 181.53 | 49.24 |
libpng-1.2.35.p4 | 223.678 | 180.82 | 17.07 |
pycrypto-2.1.0 | 192.053 | 170.88 | 4.54 |
lrcalc-1.1.6beta1 | 165.47 | 110.51 | 18.87 |
zlib-1.2.6 | 158.386 | 144.59 | 5.04 |
tachyon-0.98.9.p5 | 153.322 | 144.25 | 4.61 |
patch-2.5.9.p2 | 143.158 | 108.19 | 14.43 |
sympow-1.018.1.p11 | 132.392 | 125.1 | 4.15 |
blas-20070724 | 116.96 | 89.88 | 10.43 |
bzip2-1.0.6 | 114.085 | 109.06 | 1.7 |
sympy-0.7.1.p0 | 94.905 | 79.36 | 3.96 |
ratpoints-2.1.3.p3 | 59.683 | 57.25 | 1.17 |
mercurial-2.2.2.p0 | 58.576 | 51.43 | 3.15 |
cliquer-1.21.p0 | 51.493 | 49.92 | 0.9 |
elliptic_curves-0.7 | 43.704 | 38.17 | 1.12 |
sphinx-1.1.2.p1 | 41.391 | 33.39 | 3.64 |
flintqs-20070817.p8 | 37.736 | 36.31 | 0.87 |
genus2reduction-0.3.p8 | 37.522 | 36.21 | 0.36 |
ipython-0.10.2.p1 | 34.109 | 25.35 | 2.98 |
sqlalchemy-0.5.8 | 32.044 | 26.97 | 1.56 |
rpy2-2.0.8.p0 | 29.931 | 21.24 | 1.52 |
setuptools-0.6.16.p0 | 20.592 | 12.71 | 0.77 |
pygments-1.3.1.p0 | 19.533 | 16.76 | 1.43 |
networkx-1.6 | 19.408 | 15.36 | 1.49 |
scons-1.2.0 | 18.811 | 10.45 | 1.1 |
gdmodule-0.56.p8 | 18.048 | 17.25 | 0.58 |
jinja2-2.5.5 | 14.011 | 12.57 | 0.98 |
mpmath-0.17 | 13.23 | 11.29 | 0.71 |
termcap-1.3.1.p2 | 8.993 | 6.65 | 0.64 |
docutils-0.7.p0 | 8.487 | 7.04 | 0.91 |
sagetex-2.3.3.p2 | 2.108 | 1.39 | 0.16 |
pexpect-2.0.p5 | 1.851 | 1.6 | 0.17 |
sage_root-5.5 | 1.641 | 1.42 | 0.12 |
extcode-5.5 | 1.532 | 0.11 | 0.77 |
boost-cropped-1.34.1 | 1.058 | 0.1 | 0.45 |
jmol-12.3.27.p3 | 0.864 | 0.06 | 0.69 |
sage_scripts-5.5 | 0.259 | 0.05 | 0.18 |
polytopes_db-20100210.p2 | 0.08 | 0.05 | 0.01 |
graphs-20120404.p4 | 0.046 | 0.02 | 0 |
conway_polynomials-0.3 | 0.041 | 0 | 0.02 |
iconv-1.13.1.p3 | 0.039 | 0.02 | 0.02 |
cephes-2.8 | 0.029 | 0 | 0.02 |
This seems like a case where something like distcc (http://code.google.com/p/distcc/) would be helpful.
Or actually, I guess it would be just as reasonable to just use a cross-compiler to compile everything on a more powerful system.
I looked into cross-compiling, but it’s actually not terribly feasible for Sage. Certain components, like Atlas, ‘tune’ themselves to the particular processor you’re compiling on, running hundreds of tests to find cut-off points for where to use different kinds of algorithms and so on; building with another processor would undermine this tuning process. It would be nice if one could selectively cross-compile, building most of the packages on a fast computer and building just a few on the actual machine. But this would have been even more of a project.
Distcc, on the other hand, looks just great. I’ll probably have a few spare Pi’s kicking around at some point, and it will be great to be able to attach the bunch of them to a switch and see about speeding up the process by a factor of ‘a bunch.’
Thank you for posting the binaries. I gave up trying to build past libm4rie.
-d