
I have a number of compute-bound graphics programs written in Haskell. (Fractal generators, ray tracers, that kind of thing.) GHC offers several concurrency and parallelism abstractions, but what's the best way to use these to get images rendered as fast as possible, using the available compute power? (OK, well the *best* way is to use the GPU. But AFAIK that's still a theoretical research project, so we'll leave that for now.) I've identified a couple of common cases. You have a 2D grid of points, and you want to compute the value at each point. Eventually you will have a grid of /pixels/ where each value is a /colour/, but there may be intermediate steps before that. So, what cases exist? 1. A point's value is a function of its coordinates. 2. A point's value is a function of its previous value from the last frame. 3. A point's value is a function of /several/ points from the last frame. How can we accelerate this? I see a few options: - Create a spark for every point in the grid. - Create several explicit threads to populate non-overlapping regions of the grid. - Use parallel arrays. (Does this actually works yet??) I'm presuming that sparking every individual point is going to create billions of absolutely tiny sparks, which probably won't give great performance. We could spark every line rather than every point? Using explicit threads has the nice side-effect that we can produce progress information. Few things are more frustrating than staring at a blank screen with no idea how long it's going to take. I'm thinking this method might also allow you to avoid two cores tripping over each other's caches. And then there's parallel arrays, which presumably are designed from the ground up for exactly this type of task. But are they usable yet? Any further options?

Hi Andrew,
2009/9/15 Andrew Coppin
... I'm presuming that sparking every individual point is going to create billions of absolutely tiny sparks, which probably won't give great performance. We could spark every line rather than every point? ...
You should just try: no one can say if pixels, lines, image buckets or complete images is the right granularity. As for progress information, probably the needed granularity is not the same as the above one. Also, parallelizing a raytracer or the computation of a simple function of coordinates won't need the same solution. For instance ray coherence can be used to more efficiently traverse the accelarating data structure of the raytracer with many rays at once. Maybe before looking at what haskell has to offer you should look how your program can be parallelized then see if your solution maps well to one of haskell technical solutions. Cheers, Thu

Block, line or 'beam' decomposition tends to work well for raytracing tasks,
because they tend to give you a good cache locality and don't create a
ridiculous explosion of parallel jobs.
You'll need to do some tuning to figure out the right granularity for the
decomposition. But typically a few hundred tasks works a lot better than
tens of thousands or millions. You need to balance the tension between
having too much overhead maintaining the decomposition with wasted work from
lumpy task completion times and coarse grain sizes.
Unfortunately, using Haskell it is hard to do what you can do, say, in C++
with Intel Thread Building Blocks to get a self-tuning decomposition of your
range, which self-tunes by splitting stolen tasks. You don't get the same
visibility into whether or not the task you are doing was stolen from
elsewhere when using GHC's sparks.
-Edward Kmett
On Tue, Sep 15, 2009 at 7:48 AM, Andrew Coppin
I have a number of compute-bound graphics programs written in Haskell. (Fractal generators, ray tracers, that kind of thing.) GHC offers several concurrency and parallelism abstractions, but what's the best way to use these to get images rendered as fast as possible, using the available compute power?
(OK, well the *best* way is to use the GPU. But AFAIK that's still a theoretical research project, so we'll leave that for now.)
I've identified a couple of common cases. You have a 2D grid of points, and you want to compute the value at each point. Eventually you will have a grid of *pixels* where each value is a *colour*, but there may be intermediate steps before that. So, what cases exist?
1. A point's value is a function of its coordinates.
2. A point's value is a function of its previous value from the last frame.
3. A point's value is a function of *several* points from the last frame.
How can we accelerate this? I see a few options:
- Create a spark for every point in the grid. - Create several explicit threads to populate non-overlapping regions of the grid. - Use parallel arrays. (Does this actually works yet??)
I'm presuming that sparking every individual point is going to create billions of absolutely tiny sparks, which probably won't give great performance. We could spark every line rather than every point?
Using explicit threads has the nice side-effect that we can produce progress information. Few things are more frustrating than staring at a blank screen with no idea how long it's going to take. I'm thinking this method might also allow you to avoid two cores tripping over each other's caches.
And then there's parallel arrays, which presumably are designed from the ground up for exactly this type of task. But are they usable yet?
Any further options?
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Andrew Coppin wrote:
(OK, well the *best* way is to use the GPU. But AFAIK that's still a theoretical research project, so we'll leave that for now.)
Works for me :-) http://claudiusmaximus.goto10.org/cm/2009-09-24_fl4m6e_in_haskell.html There doesn't need to be a sound theoretical foundation for everything, sometimes sufficient ugly hackery will make pretty pretty pictures... Claude -- http://claudiusmaximus.goto10.org

This is seriously cool stuff!!!
Maybe it's time to start a "Haskell Demo Scene" :-)
(what's a "demo scene"? See http://en.wikipedia.org/wiki/Demoscene )
PS: Note that Conal Elliott also was generating GPU code using Haskell
with Vertigo back in 2004: http://conal.net/papers/Vertigo/
On Thu, Sep 24, 2009 at 5:32 AM, Claude Heiland-Allen
Andrew Coppin wrote:
(OK, well the *best* way is to use the GPU. But AFAIK that's still a theoretical research project, so we'll leave that for now.)
Works for me :-)
http://claudiusmaximus.goto10.org/cm/2009-09-24_fl4m6e_in_haskell.html
There doesn't need to be a sound theoretical foundation for everything, sometimes sufficient ugly hackery will make pretty pretty pictures...
Claude -- http://claudiusmaximus.goto10.org _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Awesome!
On Thu, Sep 24, 2009 at 7:47 AM, Peter Verswyvelen
This is seriously cool stuff!!!
Maybe it's time to start a "Haskell Demo Scene" :-)
(what's a "demo scene"? See http://en.wikipedia.org/wiki/Demoscene )
PS: Note that Conal Elliott also was generating GPU code using Haskell with Vertigo back in 2004: http://conal.net/papers/Vertigo/
On Thu, Sep 24, 2009 at 5:32 AM, Claude Heiland-Allen
wrote: Andrew Coppin wrote:
(OK, well the *best* way is to use the GPU. But AFAIK that's still a theoretical research project, so we'll leave that for now.)
Works for me :-)
http://claudiusmaximus.goto10.org/cm/2009-09-24_fl4m6e_in_haskell.html
There doesn't need to be a sound theoretical foundation for everything, sometimes sufficient ugly hackery will make pretty pretty pictures...
Claude -- http://claudiusmaximus.goto10.org _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

This is just awesome indeed.
You should create a haskell wiki page about that, so that "beginners" could
see Haskell can do that (TM) (yeah, some beginners doubt of it).
On Thu, Sep 24, 2009 at 1:02 PM, Olex P
Awesome!
On Thu, Sep 24, 2009 at 7:47 AM, Peter Verswyvelen
wrote: This is seriously cool stuff!!!
Maybe it's time to start a "Haskell Demo Scene" :-)
(what's a "demo scene"? See http://en.wikipedia.org/wiki/Demoscene )
PS: Note that Conal Elliott also was generating GPU code using Haskell with Vertigo back in 2004: http://conal.net/papers/Vertigo/
On Thu, Sep 24, 2009 at 5:32 AM, Claude Heiland-Allen
wrote: Andrew Coppin wrote:
(OK, well the *best* way is to use the GPU. But AFAIK that's still a theoretical research project, so we'll leave that for now.)
Works for me :-)
http://claudiusmaximus.goto10.org/cm/2009-09-24_fl4m6e_in_haskell.html
There doesn't need to be a sound theoretical foundation for everything, sometimes sufficient ugly hackery will make pretty pretty pictures...
Claude -- http://claudiusmaximus.goto10.org _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Alp Mestan http://blog.mestan.fr/ http://alp.developpez.com/

On Thu, 24 Sep 2009, Alp Mestan wrote:
This is just awesome indeed.
I'm impressed, too!
You should create a haskell wiki page about that, so that "beginners" could see Haskell can do that (TM) (yeah, some beginners doubt of it).
Don't miss to add it to http://www.haskell.org/haskellwiki/Category:Graphics or so.
participants (9)
-
Alp Mestan
-
Andrew Coppin
-
Claude Heiland-Allen
-
Edward Kmett
-
Henning Thielemann
-
minh thu
-
namekuseijin
-
Olex P
-
Peter Verswyvelen