LambdaCube and Bullet on Hackage at last

Yesterday we sat down with Csaba to finally clean up the code a little bit and wrap it into, ehm, cabbages. Since this is basically an early snapshot of a rather volatile codebase, there is no documentation beyond a simple start-up guide. In its present state, it is mainly aimed at fanatics, and we made it available in the hope of attracting early feedback.

So what is there on offer? As a first step, I recommend installing lambdacube-examples, which works out of the box. We tried it on Linux as well as a freshly installed Haskell Platform on XP. It gives you two executables: lambdacube-basic, a rather psychedelic experience that shows off some basic features, and lambdacube-cameratrack, a simple non-interactive example. Note the readme in lambdacube-engine, which tells you how to make resources (models, textures, scripts etc.) accessible to your program.

The other half of the deal is the Bullet binding, which contains a little C wrapper around the C++ API, so it doesn’t rely on the rather limited C interface that the library provides. Note that there is an example that requires OpenGL, which also uses unsafeCoerce to convert from CFloat (exposed by the Bullet binding) to GLfloat (which is actually a newtype wrapper around CFloat), because the performance of realToFrac is beyond obscene. We could use some advice on how to deal with this problem in a less fragile way.

Anyway, if you managed to install the binding, you can also try lambdacube-bullet, which shows how to use the two libraries together. Note that meshes can be turned into collision shapes. In this case, the same shape is used for rendering and dynamics, so the simulation is rather slow. If we used a less detailed convex mesh, animation would be smooth even with a hundred objects interacting.

Finally, if you checked the screenshots on the LambdaCube wiki page, you could see that we also have some code to load the content of Tile Racer to some extent. Unfortunately, we cannot distribute the content, and it needs some preprocessing (which requires a working Ogre3D installation) in order for our program to be able to deal with it, so you’ll have to do some manual work to get it working. The track loader can be found in the rather unorganised obsolete branch of the source repository.

That’s it for now. Have fun with it, but prepare for some bumps.


An eventful month in a few words

I haven’t written for a long while, because the past few weeks were packed with excitement. First my hp2any work had to be finalised for Google, and I couldn’t even touch it ever since thanks to all the events that followed. After a brief holiday I went to ICFP and spent the whole week in Edinburgh. Besides the conference, my personal package included the Haskell Symposium and CUFP. It was a great experience, especially because I could meet all these weird people. I spent the next two weeks back in Budapest and went to two FP-BUD meetings during that time among all the less interesting day-to-day duties. The topping of the cake was last week, which I had the pleasure of spending in New York thanks to Jane Street and our JSSP participation with Csaba. After two days of freely roaming in the city we went to the meeting that Yaron already blogged about, then I spent the rest of the week in Newark and South Orange at IFL, and gave a talk about Elerea on the first day. Yes, it was a lot of FP fun in such a short time. And by now I’ve even recovered from the rather exhausting nine-hour flight from JFK to BUD...

The main reason of this post is to complement Yaron’s and show you some pictures (by the way, sorry for the quality in advance) of the JSSP meeting. The trip was a real treat, but I’m not going to recall the days before the meeting. Suffice it to say, New York is highly shocking for someone who spent all their life in Europe. We were basically walking around in Manhattan for two days and tried to absorb as much of it as possible – which is more fun to actually do than to be told about.

The meeting itself started off with a welcome speech.

The essence of it was a shopping list of mostly FP related issues (language features as well as practices) that gave a general idea what using FP in the wild looks like. The whole talk was supported by a single slide with the list on it, but I forgot to take a photo of it. That is a pity, because it would be wonderful flamewar material. ;) Thankfully, it was in huge contrast with the bulk of IFL, so I wouldn’t risk being exposed to a one-sided view over the week.

Afterwards, the first session was about Yaron’s favourite projects, and I can only agree with him seeing all the work that went into them. The very first talk was about Ocamlviz, given by Guillaume Von Tokarski:

It is kind of embarrassing to me, because it really makes my hp2any work pale in comparison. Just look at their project page.

The next one was about the Moby compiler, this time given by Shriram Krishnamurthi:

I already encountered this project at ICFP, and even from that crop it stood out to me with all the real-life results they have in making maths accessible to kids. Danny Yoo gave the same talk on it at IFL a few days later.

After lunch, the next session started with Bertrand Desmons presenting his graphics library.

Even if the work is not finished yet, it still looked fine to me considering the time frame of the summer project, especially knowing how much struggle we had to go through. Having said that, the next talk was about Lambdacube. Amidst all the excitement I forgot to take a picture, so here’s one about the rehearsal:

I plan to write more about the project in a later post. Csaba being the perfectionist he is was not really satisfied with his own performance, but I wouldn’t be so harsh. We started the summer with a piece of hack and ended it with an extensible base and a heap of features implemented.

The last project talk was given by Duru Türkoğlu about his work on the computational geometry library.

I have to admit that I had a hard time following parts of this talk, not being familiar with the area or the depths of SaSML. In that sense, it was a warm-up for the conference days... I had the impression that the emphasis was more on the research than the implementation in this project, so it was slightly different from the rest in its nature. But this only supports the observation that this year’s JSSP projects covered a wide area, and it wasn’t only diverse in terms of the implementation languages.

After the talks we had a demo session, where everyone could wander around and have a word with the creators.

Here’s a screenshot from Lambdacube interacting with the Bullet physics engine:

Yes, we piled up some cars just for fun. You can also do it soon yourself, as the new version of the engine as well as the renewed Bullet binding is bound to be released soon. I’m not sure why, but the program on the photo is called ‘Lambda-Cube GLFW UnsafeFRP Example 1’, so beware.

After the demo session, as a penultimate treat before the dinner, Chris Okasaki told us some fun ‘insider facts’ about his book.

Besides the Slashdot anecdote mentioned by Yaron I liked the part when he recalled how his creative crisis combined by outside pressure was resolved during an inspirational walk home. Moments of enlightenment are always nice to hear about, especially since I have so few of them myself. And even if I normally hate sappy happy endings, sometimes I am willing to make an exception. ;)

The dinner at the end put the crown on the day as we often say in Hungary. We had a chat, ate a lot of good food and ended the day with a walk in the most colourful part of the city. All thanks to Jane Street for making this happen!


hp2any overview online

At last I created a HaskellWiki entry for hp2any. It’s easier to maintain than the Google Code wiki, so I’ll be using this page for the project from now on.

As for the code, there is also a minor update that makes path handling more robust and Windows friendly. However, I still didn’t manage to work around the sharing violation issue that makes live profiling impossible under Windows.


hp2any on Hackage

As the title says. Since the final deadline is very close, I uploaded the current versions of the hp2any packages. There are three of them: hp2any-core, hp2any-graph, and hp2any-manager. That’s also the order in which they depend on each other, so e.g. if you don’t want the history manager (because, say, you are a Windows user and don’t have the GTK bindings installed), you can get just the other two.

The graph package contains a directory called ‘test’ that includes a little example to get started with. The manager should be straightforward to use for the most part, the only thing to remember is that you can zoom graphs with the mouse wheel. Nevertheless, a little readme is included in its package.

There hasn’t been much change since the last update. The biggest issue was the fact that GLFW got broken due to the recent OpenGL update, so I switched to GLUT in the grapher. I also spent some time on cleaning up the code and the Haddock comments for the library interfaces. Everything should be functional, but please do exercise the code a bit and share your comments. :)


More profiling goodies

Time for another update! Most of the changes happened behind the scenes. I wasted a few days because of my naive assumption that the text rendering process presented in the previous post actually works. It seems to, but apparently it causes some GTK calls to randomly hang. And I do mean randomly. The error doesn’t even seem to be related to text rendering per se, but it stops occurring as soon as I remove the call to drawPixBuf. This is something to look into later, but there’s no point pursuing it at the moment.

The changes on the surface are not really spectacular, but they might be useful. After giving up on my text rendering ambitions I added cost centre lists next to the graphs, and also the ability to toggle accumulated and separate views. The lists can be sorted according to the total cost for each cost centre, and as we hover over the graph, the cost centre under the cursor is highlighted on the list. See for yourself:

The extra options can be found under the fourth button next to the left arrow in the graph headers.

As for library interfaces, one major change is the removal of the network protocol for the most part. My original idea was to create a remote controllable graphing application, but I ended up factoring graph rendering routines into a library, which removed the need for serialising various commands. The other change is the introduction of the Stats module, which makes it possible to efficiently query the heap profile in various ways. In particular, you can get the maximum individual cost, the maximum total cost (at a given moment) and the integral of any cost centre for any time range, and you can also extract samples collected during a given time interval. All this requires a preprocessing phase which can be performed in nearly linear time.

From now on, I’ll be concentrating on the interface of the history manager, and after adding some features I’ll also write a tutorial/manual for the applications.


Pango font rendering on an OpenGL canvas

Nowadays I’m working on the interface of the profile history manager, and I ran into the problem mentioned in the title. The problem is actually that the Gtk2Hs interface seems to have more degrees of freedom than the implementation, and even if it seemingly lets us combine various mechanisms in creative ways, most of these combinations lead to a segfault. In particular, using any incarnation of drawLayout in an OpenGL drawing area suffers from this problem.

After some sweat and tears and frantic search for solutions I decided to use Cairo for rendering. This also has the advantage that the result of the rendering can be cached in memory, so the display can be refreshed very efficiently if the text is static. All we have to do is prepare an image for later rendering.

First we need a Cairo context. As part of my goal was to preferably use the same font as the rest of the interface, I also set it to a sans serif typeface:

cctx <- cairoCreateContext Nothing
fontDesc <- contextGetFontDescription cctx
fontDescriptionSetFamily fontDesc "Sans"
contextSetFontDescription cctx fontDesc

The next step towards consistency is to set the resolution to match that of the screen. This is very important to crazy people like me, who had to change their DPI setting.

screenGetDefault >>= \s -> case s of
Nothing -> return ()
Just scr -> do
res <- Gtk.get scr screenResolution
cairoContextSetResolution cctx res

Okay, the context is sufficiently prepared for our purposes, we can create the layout:

txt <- layoutText cctx "Hello world!"

Next, we need a pixel buffer that can hold the final render. We can easily find out its dimensions by asking for the pixel extents of the layout, and it’s probably better to use the logical extents that also include some padding:

Rectangle _ _ txtWidth txtHeight <- snd <$> layoutGetPixelExtents txt
textSurface <- createImageSurface FormatARGB32 txtWidth txtHeight
textSurfacePixbuf <- pixbufFromImageSurface textSurface

And everything’s ready for rendering, so let’s do it:

renderWith textSurface $ showLayout txt

From this moment the rendering of the text is available in the pixbuf. Rendering it is a piece of cake:

withGLDrawingArea glCanvas $ \glw -> do
-- various opengl commands
gc <- gcNew glw
drawPixbuf glw gc textSurfacePixbuf 0 0 textX textY txtWidth txtHeight RgbDitherNone 0 0
-- more opengl commands
glDrawableSwapBuffers glw

When we know that we won’t need the image any more, we can free up the surface:

surfaceFinish textSurface

For more consistency we could look up the actual rendering settings (antialiasing, hinting) and fonts of the current theme and set everything before rendering. That’s left as an exercise to the reader. I’m too tired. ;)


Introducing the heap profile manager

Well-well, it’s been almost two weeks since the last release, so I decided to show you the beginnings of the heap profile viewing application. After thinking about the alternatives I decided to follow in the steps of others who make core tools and use gtk2hs for the interface. Since I had a working grapher in OpenGL, it was also straightforward to keep it. I started out as a complete beginner in gtk2hs last week, and it proved to be one of the smoothest library learning experiences so far. Even getting several OpenGL drawing areas to work simultaneously went without a hitch. The UI started out as something more complex, but after some experimentation I arrived at the present design:

You can load several graphs in each column (note that multiple selection is enabled in the file open dialog), and move them left and right between columns as you wish. Columns can also be created and destroyed at will. This initial version doesn’t have any more interaction, e.g. you cannot zoom in on areas you’re interested in. Consequently, graphs with an occasional high spike can be unpleasant to look at, as illustrated by the example on the right.

The next step is obviously to add the features that make comparison easier, like displaying scales, displaying identical cost centres with identical colours, adding zooming and panning, comparing a given cost centre from separate runs on the same graph and so on. Also, the profile loader could be probably speeded up a bit by not building a map from times to samples if we convert it into a list anyway.

If all this works okay, I can also add some export plugins (e.g. ps and svg) to finally retire hp2ps.

Oh, the button next to the left arrow doesn’t do anything yet.


Remote profiling at your fingertips

Yes, it’s time for another code release after a long hiatus. You can grab the source from the repository, and it should even be able to compile without any major hiccup. The grapher is now capable of connecting to a profile relay server that can broadcast the heap profile of its associated process on the fly. Stopping either the process, the server or a grapher client is handled gracefully. Thanks to decoupling the grapher and the process in the remote case, it is now possible to attach an observer to a program that was started earlier. Here’s the proof:

It’s hopefully obvious that the clients were attached at increasing times from top to bottom, and I flipped the mode of the middle one just for the fun of it.

Unfortunately, even though the code to achieve all this is quite small (hey, thanks Haskell!), getting it to work at a reasonable level of stability took longer than expected. Therefore, instead of adding remote control features to the grapher right away, I’ll start preparation for the history manager, otherwise I might not be able to get it working before the final GSoC deadline.


Playing and learning

My profiling project is currently in the state where I can’t really show any pictures or code, since I’m fighting with various edge cases that one can bump into while writing a multithreaded distributed graphical application. In short, remote graphing has already been working since the beginning of the week, but there are stability issues that need to be ironed out before the next release, and it’s taking longer than I anticipated...

Until then, let me bring another program into your attention. It is a Bloxorz clone in Haskell, available through cabal in the bloxorz package. It is more limited than the original, and only features three levels, but the essence is there. This rendition was made by a student of mine, Viktor Devecseri, for a ‘practical functional programming’ class I’ve been teaching for one and a half years. This is an optional class available to students of electrical engineering and informatics (at our university, the latter involves a fair amount of both CS and IT), who don’t necessarily have any non-mainstream programming background.

The point of the class is basically to give students a wider perspective by exposing them to functional programming. The primary language of the course is Haskell, but I also talk about Hume, and the last time I dedicated a lesson to Timber too, as the official name of the course is Embedded Functional Programming for historical reasons. We even used Hume to control Mindstorms NXT robots and a Tmote Sky sensor the first time this class was held, but this proved to be a bit too complicated due to the lacking toolset for this language, so the topic slowly shifted towards general practical FP. While one might argue that Haskell is not the most practical language, it is definitely among the few languages that’s both useful for real-life purposes and can broaden one’s mind to a great extent.

I always take the time to ask everyone about their learning experience, what they found easy or hard while working on their assignment. Since students can have rather different past experiences, I let everyone choose the topic on their own, the only constraint being that the program should be interactive in some way. In other words, I don’t want to see pure data grinding, because there is another class with that focus, and it’s probably more rewarding for newcomers to see something move and respond right away.

While talking to Viktor, he had remark that the approach being ‘not object oriented enough’ (I hope I’m not misquoting him too much here) was somewhat inconvenient. Afterwards, we had a little conversation about FP being a completely different approach to modularisation than OO. Nevertheless, even if I have a few years of experience with functional languages, I still found it hard to respond to questions pertaining concrete problems. I believe it would help a lot if there was some kind of tutorial on designing real-life applications in the style of Why Functional Programming Matters. Is there such a guide somewhere, or only in the brains of experienced people and scattered everywhere across the web? My dear readers, please help me out!


Short-term hp2any plans

I haven’t written for a while, because I was distracted by other activities for a few days. I have no code or pretty pictures to show this time, just a few words on what I intend to do next.

This week’s milestone is a working network protocol for the grapher that can also be used by other tools, e.g. to monitor the heap of a remote application. Next week will be mainly about improving this feature and implementing some more functionality in the grapher that will hopefully make it a more useful tool. The rest of July shall be dedicated to the history manager.


You can draw your own graphs now!

Sorry, no pictures this time, there’s nothing new to show. However, you can play with the grapher now, so go grab the source from the repository. The details of the update are in the commits. First I wanted to polish the grapher a bit more before this release, but I got held down by more duties than I had expected, and I figured it’s only for everyone’s benefit to start exercising the code as early as possible. It also gives you something to provide feedback on.

There are two main features I’ll add to this grapher: zooming-panning and a socket based remote control interface that allows other programs to use it as a display. It might even become a generic grapher that’s attached to the profiler output through some minimal glue code that also uses the remote interface. The same glue code could actually be used to make profiling output available over the network to anyone interested, sharing the protocol of the grapher.

It’s also time to start thinking about the history manager (I’m reluctant to call it a framework, however fancy it would sound ;). At this point, the most important question is which windowing toolkit to use. I have already collected some vague ideas on the project wiki, and I’d need some advice on this.


More colourful graphs

In order to make it easier to compare cost centres, I added a cumulative view that works the same way as hp2ps. Generating appropriate colours is tricky when you don’t know the data in advance, but the result is at least satisfactory for the time being. Hovering over an area causes the name of the respective cost centre to be displayed in the top left corner, as illustrated by the following screenshots:

The vertical magnification of the graph depends on the last 50 samples, so a huge spike will squeeze the diagram only for a limited amount of time, as you can see on the screenshots too.

Of course, the line graphs are also available, but the two can’t be toggled during a single run yet, so here’s a picture from another one (the lines are broken at places, because the Gnome screenshotter can’t seem to keep up with the animation):

What’s next? The first thing to do is to optimise graphing, because everything is recalculated for each frame in the current snapshot, and it doesn’t take long for the visualiser to stress the CPU more than the program we’re profiling... Pushing everything into display lists should take care of that. The next step is to add the means to stop the animation and look around in the graph, and also the option to display only the last portion while animating the graph.

When the grapher works fine as a standalone application, I’ll start extending it with remote control capabilities as outlined on the project wiki.


The first graphs

Well, after a few days of other distractions I got back to hp2any and implemented a simplistic graphing utility on top of the core library. Here is the first test run featuring a little game I’m working on in my similarly little spare time:

Oops, of course I forgot about the evils of laziness right away... I removed some debug text, but still calculate the values that would be displayed, which are therefore never evaluated and hold on to various big structures from every past frame. The situation is much better after adding an exclamation mark at the right spot:

There’s no public code yet, but I hope to get it in a much better shape in a few days.


Read your profiles!

I uploaded the first version of the hp2any core library that is capable of handling heap profiles both during and after execution. The essence of the interface is this group of functions:

type ProfileReader = IO Profile
type ProfileSink = SinkInput -> IO ()

readProfile :: FilePath -> IO Profile
profile :: CreateProcess -> IO (ProfileReader,ProcessHandle)
profileCallback :: CreateProcess -> ProfileSink -> IO ProcessHandle

The readProfile function can parse an .hp file from an earlier run and build an easy to query structure from it. The profile function takes a process to run and returns an IO action that lets the caller look at the snapshot of the profile at the given moment. For those who want to manage profiling data on their own, the profileCallback function is provided, which takes a callback function that’s called whenever some new piece of information is available. Its input has the following form:

data SinkInput = SinkSample Time ProfileSample
| SinkId CostCentreId CostCentreName
| SinkStop

There are three possibilities: a snapshot that lists active cost centres with their associated costs, an association between a numeric id (created by the library, used in the samples) and the name of the cost centre, and an indication that no more data should be expected. Note that SinkInput is an instance of Show, therefore print can be used as a callback function.

For the time being, the following functions are provided to query the Profile structure:

type CostCentreId = Int
type CostCentreName = String
type Time = Double
type Cost = Int
type ProfileSample = [(CostCentreId,Cost)]

costCentreName :: Profile -> CostCentreId -> Maybe CostCentreName
costCentreNames :: Profile -> [(CostCentreId,CostCentreName)]
toList :: Profile -> [(Time,ProfileSample)]
intervalToList :: Profile -> Time -> Time -> [(Time,ProfileSample)]
profileLength :: Profile -> Time

Caveat: it’s all preliminary and makes no attempt at being efficient, but it seems to work fine at first glance. Do play with it and shower me with your comments. :)


hp2any project wiki updated

I added some wiki pages about various components on the hp2any project page. You are encouraged to read it all (it’s really not much) and leave comments.


Lambda Cube Summer

I’m pleased to announce that the Lambda Cube Engine is among this year’s JSSP projects. Csaba is an extremely productive person, and I’m sure he can achieve a lot by the end of the summer.


How to start?

This blog was created mainly to document my Great Haskell Profiling Adventure, but there’s no guarantee it won’t grow beyond that bubble, even if I’m generally lazy and prefer reading about others instead of exposing my own little self. So hello world, we’ll see how far we can get.