Monday, September 22, 2008

master studies

I did it! :) I defended my thesis and passed master finals from theoretical physics at Charles University in Prague couple hours ago.

After almost dropping out of my school exactly a year ago for not having enough credits to go to the next year, I gave myself an obligation to finish my school on time. I worked very hard the last year, I had to do 8 exams, some of them very hard, requiring more than a week of thorough learning and 9 seminars, requiring a lot of work too and also a master thesis, for which I had to had working finite element solvers and together with SymPy it took all my time and energy. I even had to cancel my trip to Austin and Caltech for the SciPy conference. But I finished my school after all, I am very happy about it.

Last year, two of my friends bet $100 between themselves that I will not finish on time. Jarda, who believed in me is now at Princeton doing his Ph.D. Matouš, who didn't believe in me, will now pay $100 to Jarda. I think that life is fair.:)

Now I'll be visiting pubs quite often and then I'll fix some long standing issues in SymPy, hopefully finish my Debian task & skills (to finally become a Developer couple months after that) and finally do useful stuff for my research with a fresh head now.

Saturday, August 16, 2008

I am switching from Mercurial to git

After a long night of debugging and while preparing, reviewing and pushing final patches before a SymPy release, I got this:

$ hg qpush
applying 1645.diff
Unable to read 1645.diff
** unknown exception encountered, details follow
** report bug details to http://www.selenic.com/mercurial/bts
** or mercurial@selenic.com
** Mercurial Distributed SCM (version 1.0.1)
Traceback (most recent call last):
File "/usr/bin/hg", line 20, in
mercurial.dispatch.run()
File "/var/lib/python-support/python2.5/mercurial/dispatch.py", line 20, in run
sys.exit(dispatch(sys.argv[1:]))
File "/var/lib/python-support/python2.5/mercurial/dispatch.py", line 29, in dispatch
return _runcatch(u, args)
File "/var/lib/python-support/python2.5/mercurial/dispatch.py", line 45, in _runcatch
return _dispatch(ui, args)
File "/var/lib/python-support/python2.5/mercurial/dispatch.py", line 364, in _dispatch
ret = _runcommand(ui, options, cmd, d)
File "/var/lib/python-support/python2.5/mercurial/dispatch.py", line 417, in _runcommand
return checkargs()
File "/var/lib/python-support/python2.5/mercurial/dispatch.py", line 373, in checkargs
return cmdfunc()
File "/var/lib/python-support/python2.5/mercurial/dispatch.py", line 356, in
d = lambda: func(ui, repo, *args, **cmdoptions)
File "/var/lib/python-support/python2.5/hgext/mq.py", line 1942, in push
mergeq=mergeq)
File "/var/lib/python-support/python2.5/hgext/mq.py", line 833, in push
top = self.applied[-1].name
IndexError: list index out of range

I am using:

$ hg --version
Mercurial Distributed SCM (version 1.0.1)

Copyright (C) 2005-2008 Matt Mackall and others
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


And I just got pissed off and I am switching to git for good. I've been using mercurial every day since about November 2007, and I think I am quite proficient in it. But we were missing some features, like recording a patch by hunks (git add -p), so Kirill Smelkov (another SymPy developer) just implemented this to mercurial queues, it is now included in hg 1.0. But I am constantly beaten by stupid bugs, mercurial broke into pieces several times already (last time with hg bisect, before it with mercurial queues and file renaming), that just should not happen in a production version. Another problem is that hgweb is constantly using 100% of CPU on my server whenever someone clicks to see the contents of the README file. Again I can spend time debugging it, but I will just use git and if it works, I'll stay with it.

I started learning git recently and it is just better in every aspect. Bigger community, it has all the features that I was always missing in mercurial (like rebase, hunks recording, diff diff --color-words, better gitk). And it's superfast.

Unless I find some showstopper bugs in git too, I don't think I am coming back.

We'll have to create a live mercurial mirror of SymPy, so that people can continue using mercurial, but I'll myself just be using git. We wrote a simple translation table for anyone using mercurial to get started:

http://wiki.sympy.org/wiki/Git_hg_rosetta_stone

I love Python and I like that Mercurial is just a small C core and the rest is in Python, but for some reason, it still has the baby bugs, that should have been fixed years ago and why should we spend our time fixing and improving Mercurial, if other people have already done the job for us (and usually a better job than I could do) in git?

Another reason for switching is that in Debian, mercurial is not used for packages, while git is used a lot.

Thursday, August 14, 2008

SymPy core in Cython, general CAS design thoughts

We managed to write a new core of SymPy that is an order of magnitude faster than the current sympy, but contrary to sympycore (which is Pearu's attempt to write a fast core), it uses the same architecture as sympy, so we can now merge it back and speedup everything.

It started like this: I was unsatisfied with the current sympy speed, and also with the fact, that it was only Kirill and sometimes Mateusz who were submitting speedup patches to sympy, but unfortunately noone was doing any effort to get sympycore merged. I (and I think many people too) hoped that when sympycore got started, the aim was to get it merged back. That was not happening. So I said to myself, ok, noone does the job for you, you need to get your hands dirty and gets things moving yourself.

I came with my thoughts 3 years back, when it was a rainy weekend in Portland, Oregon, I was sitting in my office at the university, just finished playing with swiginac that we wrote with Ola Skavhaug, and said to myself then -- no, there must be a better way. First all this bloated swig thing, but this could be fixed by hand (today we just use Cython). But especially with how things were done in GiNaC internally. Too many classes, too difficult to write new functions. So I wrote my own cas in pure Python just to see if things can be done better. Then a year later at the Space Telescope Science Institute, I was again wondering, ok, a good CAS in Python is really needed.

So I wrote to ginac developers saying my concerns and exchanging ideas how to do it better. I read this email from July 2006 now again and it seems I was right. Citing
"I think there are people, who would implement for example the factorization (you can copy it from eigenmath for example) and other stuff like limits and integration, if the code weren't so
complex (or am I wrong?)."
I was right, except limits (that I wrote myself), all of the above was implemented by someone else in SymPy (Mateusz, but others too, did a stellar job here). It's actually pretty amusing for me to read my other emails from the ginac list, for example this. I basically said the design of SymPy in that email. As one of replies, I was told to consider education in C++. As I also found later, ginac developers get very easily attacking me over nothing. But if one ignores it, I had several interesting discussions with them about a CAS design (we also discussed something later, but I cannot find it now). But anyway, flaming people is something I would never tolerate on a sympy list, because this is exactly what drives people away. And I am not interested in any flame. I just want to get things done. Anyway, I did exactly what I said in those emails on the ginac list with sympy and it seems it worked really well. One remainging piece of the puzzle is speed though. As I watched one Linus talk today, he said "well, maybe 30s is not much for you, but if people are used to do the same thing in 0.1s, trust me, it is way too slow." He's of course 100% right. So we need to speed sympy up drastically if we want to be competitive.

So those were my thoughts recently. So I wrote a SymPy core in pure C over the last weekend, see my emails to the sympy list. I achieved some pretty competitive benchmarks, but there was one "minor" issue -- memory management. I wasn't freeing any memory as I thought I could fix that later easily. And it turned out to be a night mare. I hoped I could use boehm-gc, but it doesn't work with glib (it gives nasty segfaults), that I was using for dictionaries and string management. So I hacked up reference counting just like in Python, but I didn't manage to make it work without segfaults. Segfaults can be debugged, but it's a lot of effort, especially if it fails deeply in some libc function, far away from the code that actually breaks it. Valgrind helps here too, but I want to spend my time on other things than debugging segfaults. Then Robert Bradshaw told me: why not to use Cython? BTW, Kirill was telling me this from the beginning. But I am stubborn, if I believe in something, I want to try it. So I tried and failed. Anyway, I must say I really enjoyed coding in C, it's a very good language.

So then I threw the code away and started from scratch. I think this was the 4th time I wrote the "x+y+x -> 2*x + y" simplification algorithm. For the first time 2 years ago it took me maybe a week to get it right. In the C (3rd time) it took me just maybe an hour. And now (4th time) in Python it was just couple minutes. So it makes me feel good if I can see that I am improving after all. Anyway, so I wrote a core in pure Python, but using all my 2 years experience and a know-how after discussing with Kirill, Mateusz, Fredrik, Pearu and many others how to do things. So our new core, we call it sympyx, is less than 600 lines long, it uses the same architecture as sympy and it is amazingly fast.

Then we reserved couple evenings with Kirill and cythonized it (neither of us has time during the day, I need to work on my thesis and Kirr works). We logged into one machine, setup screen so that we could see each other typing and also type to each other's terminal and started cythonizing. Kirr is very good at it, he submitted couple patches to Cython and he's just much better developer than I am. So he used his approach of rewriting everything directly to Cython, while I used my iterative approach of always trying to satisfy tests. So when he completely broke the core in the middle and I saw on his terminal something like:

In [1]: x+x
[huge stacktrace with Cython errors]

and then I saw the cursor stopped moving, I write to his terminal "haha" and was laughing. Probably a minute later I screwed something up in my terminal and I saw that my cursor wrote haha.
Actually very good moment was that I managed to get all tests run first. So I got hold of his terminal and wrote in his vim session "look at my terminal". And there he saw:

$ py.test
============================= test process starts ==============================
executable: /usr/bin/python (2.5.2-final-0)
using py lib: /usr/lib/python2.5/site-packages/py

test_basic.py[13] .............
test_basic2.py[4] ....

================== tests finished: 17 passed in 0.04 seconds ===================

You know, all tests run, with the core in Cython! And then I saw how my cursor started to move and it was typing "git diff" and "git cherry -v origin" and "git log" and other things, as Kirr was checking that what he sees is correct. But I haven't cdefed the classes, just make it work (there were problems with the __new__ method not yet supported in Cython and other minor things). We both came home from our work and continued, so I continued bringing more and more classes and methods to Cython, but then I got this message from Kirr on my jabber: "all tests pass. Speedup is 3x". So I said to myself -- yes! So he beated me and he did it. I pulled his changes and indeed, everything was cythonized and it was superfast. So his approach provided faster results after all.

We polished things, did couple benchmarks and announced it on sympy and sage-devel lists.

GiNaC is still faster, but not 100x faster, depending on the benchmark usually 2x to 10x faster (but sometimes also slower). There is still a lot of room for both design and technical optimizations, so I think we'll improve for sure. I very strongly believe it is possible to be simple in design, maintainable and fast.

Saturday, May 24, 2008

Ubuntu Developer Summit in Prague

Last weekend I was at FOSSCamp. Since I live in Prague I wanted to go to Ubuntu Developer Summit (UDS) each day, but unfortunately I had some exams, so I only went on Wednesday and Friday.

On Wednesday I first met Lars Wirzenius:


we agreed to go to pub in the evening. Then I did a little work, there was quite a nice view from the window (Prague castle on the horizon):



and I went to the #ubuntu-devel-summit IRC channel and pinged Scott Kitterman, whom I new from the Debian Python Modules Team (DPMT), but didn't know how he looks like. We met and once I knew Scott, it was easy to get around, so he introduced me to Steve Langasek (pronounced Langášek). We agreed to go to pub as well. Steve lives in Portland, OR, where I spent the summer 2005 and Scott is from Baltimore where I spent the summer 2006.
Then I also met Riku Voipio, Martin Böhm, Christian Reis (whom I asked if it's possible to support Debian unstable on Ubuntu Personal Package Archives and he said that it will probably happen, so that's really cool -- I also offered my help with this) and others, so in the end, there were 14 of us going to the pub, so I chose again the same pub as with the FOSSCamp people and it seems it tasted good again:




Notice the svíčková na smetaně above, my favourite meal. Good choice Scott. :)





Ok, that was on Wednesday. On Friday I arrived at around 3pm, looked at the schedule table and noticed that Matthias Klose should be at UDS too, so I started IRC and pinged him. Fortunately, Emilio Pozuelo Monfort, whom I know from DPMT as well, replied first so we met, it was cool and he showed where Matthias is. I am very glad I met him, so we discussed python-central and python-support packages and why we have them both, also with Scott later on.

When I was waiting for Matthias, I sat next to Nicolas Valcárcel, started my laptop and begun looking at some SymPy bugs and Nicolas noticed that and said -- "You are developing SymPy?", I said "Yes.", flattered. And he showed me a bug with plotting and Compiz, so we immediately reported that to pyglet.

In the evening people continued to some kind of a party, but unfortunately, I was already going to some other pub.

Overall, even though I was there for only two afternoons, it was just awesome and I utterly enjoyed meeting all the people I knew from mailinglists and IRC.

Tuesday, May 20, 2008

Installing a printer in Debian

I finally bought a new toner to my old Minolta 1250e that I didn't use for a few years (because I was lazy to fix it) and I was surprised how easy it is to install it these days:

1. plugged the USB cable from the printer to my laptop
2. wajig install cupsys foomatic-db-engine
3. sudo ln -s /usr/bin/foomatic-ppdfile /usr/lib/cups/driver
4. On http://localhost:631/ I added the new printer in cupsys, it showed my printer over USB, I selected it and then I chose the correct PPD.

And everything just works. The only nontrivial part is the step 3, that was suggested in /usr/share/doc/foomatic-db-engine/USAGE.gz:

If the printers of the Foomatic database do not appear, check whether the
link to foomatic-ppdfile is in /usr/lib/cups/driver:

lrwxrwxrwx 1 root root 25 Apr 19 18:13 foomatic -> /usr/bin/foomatic-ppdfile

If not, create it manually.

Without it, I didn't see the right PPD in the step 4. Maybe it'd be a nice idea to do this automatically (either when installing foomatic-db-engine or cupsys), or am I missing something?

As to the PPDs, one can get all printer IDs by:

$ foomatic-ppdfile -A

and the PPD for my printer by

$ foomatic-ppdfile -p Minolta-PagePro_1250E

However, it's not necessary in the above howto.

Friday, May 16, 2008

FOSSCamp, Friday

Since I live in Prague, it's basically compulsory to go to FOSSCamp. Yesterday I went with Lucas to some pubs + sightseeing, today we went in a larger group to this pub:

and we had a couple of good Czech meals with Plzeň beer:




Seems it tasted good:

Wednesday, May 7, 2008

snapshot.debian.net saved me again

On one computer I am taking care of, I suddenly started getting:

$ ps2pdf fa_808.ps fa_808.pdf
/usr/bin/ps2pdfwr: line 45: exec: gs: not found

What's wrong?

$ ls /usr/bin/gs
ls: cannot access /usr/bin/gs: No such file or directory
$ wajig find-file /usr/bin/gs
ghostscript: /usr/bin/gs
$ wajig list ghostscript
ii ghostscript 8.61.dfsg.1-1 The GPL Ghostscript PostScript/PDF interpret
ii ghostscript-x 8.61.dfsg.1-1 The GPL Ghostscript PostScript/PDF interpret

That is really weird, the file /usr/bin/gs is simply missing, even though I have the ghostscript package installed. Ok, let's reinstall it:

$ wajig reinstall ghostscript
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
libwine-capi libstdc++5 libopenal0a xgnokii libglut3 libcapi20-3
libggi-target-x lib64gfortran2 libsvg1 lib64gomp1 libggi2 libgii1
libgii1-target-x libxine1-gnome cups-pdf lib64objc2
Use 'apt-get autoremove' to remove them.
The following extra packages will be installed:
akregator gs kaddressbook kaddressbook-plugins kalarm kandy kappfinder karm
kate kcontrol kdebase-bin kdebase-data kdelibs-data kdelibs4c2a
kdepim-kfile-plugins kdepim-kio-plugins kdepim-kresources kdepim-wizards
kdesktop kghostview kicker kitchensync kleopatra kmplayer kmplayer-common
kpersonalizer ksplash libarts1c2a libgnutls26 libgs8 libilmbase6 libkcal2b
libkdepim1a libkleopatra1 libkmime2 libkonq4 libkpimidentities1 libktnef1
libopenexr6
Suggested packages:
kdeaddons-doc-html ntpdate ntp-simple perl-suid egroupware ffmpeg xawtv
gnutls-bin
The following packages will be REMOVED:
digikam kde-amusements kde-core kdeaddons kdebase kdebase-kio-plugins kdepim
kmail kmailcvt kmplayer-plugin knights konq-plugins konqueror
konqueror-nsplugins korn smb4k
The following NEW packages will be installed:
gs libgnutls26 libilmbase6 libopenexr6
The following packages will be upgraded:
akregator ghostscript kaddressbook kaddressbook-plugins kalarm kandy
kappfinder karm kate kcontrol kdebase-bin kdebase-data kdelibs-data
kdelibs4c2a kdepim-kfile-plugins kdepim-kio-plugins kdepim-kresources
kdepim-wizards kdesktop kghostview kicker kitchensync kleopatra kmplayer
kmplayer-common kpersonalizer ksplash libarts1c2a libgs8 libkcal2b
libkdepim1a libkleopatra1 libkmime2 libkonq4 libkpimidentities1 libktnef1
36 upgraded, 4 newly installed, 16 to remove and 683 not upgraded.
Need to get 53.1MB of archives.
After this operation, 42.9MB disk space will be freed.
Do you want to continue [Y/n]? n
Abort.

Oops, unstable is broken at the moment. Ok, what now? Well, snapshot.debian.net comes to rescue again. Find "ghostcript", version "8.61.dfsg.1-1" and here we are:

$ wget http://snapshot.debian.net/archive/2008/03/02/debian/pool/main/g/ghostscript/ghostscript_8.61.dfsg.1-1_i386.deb
$ wajig install ./ghostscript_8.61.dfsg.1-1_i386.deb

And all is fine now:

$ ls /usr/bin/gs
/usr/bin/gs