Harlan with Support for Rich Data Structures, Trees, Ragged Arrays and Higher Order Procedures
Harlan is a new programming language specially developed for GPU computing with native support for rich data structures, trees and ragged arrays. It works with Mac OS X 10.6, 10.7, 10.8 and other flavors of Linux.
Harlan requires an OpenCL implementation such as Intel OpenCL SDK, NVIDIA CUDA Toolkit and AMD Accelerated Parallel Processing (APP) SDK in addition to Petite Chez Scheme. Moreover, it also provide support for higher order procedures.
InfoQ had a chat with Eric Holk, who is also a Ph.D student at Indiana University, to know more about Harlan programming lanuguage.
InfoQ: What are the basic requirements for building applications with Harlan?
Harlan tries its best to work with a variety of hardware. The written in Harlan should run on any machine with an OpenCL implementation available for it. The compiler itself is written using Chez Scheme, so you'll need this or Petite Chez Scheme. We've tried hard to keep the requirements for Harlan as minimal as possible in order to make it easy for people to experiment with the language.
InfoQ: Can you share with us the kind of software applications that can be developed using Harlan?
Harlan is designed to be a general purpose data parallel computing language, so it should be applicable to a wide range of programs. It provides a lot of higher level programming features, like custom data types and first class procedures, which are not common in existing languages that target the GPU.
As a compiler writer, I'm particularly interested in the possibility using Harlan to accelerate some program analysis tasks. Some of our existing benchmarks show Harlan can work well for traditional scientific applications. The language features should also support less traditional GPU applications, such as graph analysis or ray tracing.
InfoQ: Is Harlan compatible with Windows 7 and 8?
Not currently. That said, it would not take much to make Harlan run on Windows. Most of the code is portable, there would just need to be a few changes in the runtime system.
InfoQ: How does Harlan benefit Graphics rendering?
Harlan's focus is really on general purpose computation, rather than graphics specifically. That said, the programs do run on the GPU and many graphics processing tasks could be written in Harlan.
InfoQ: Can you demonstrate a simple Hello World app using Harlan?
Here's Hello World:
(println "Hello, World!")
(return 0))) >
That's not particularly interesting though, since it doesn't actually use any of Harlan's parallel features. Here's another program that shows how to compute the dot product between two small vectors:
(let ((X (vector 1 2 3 4))
(Y (vector 4 3 2 1)))
(let ((dot (reduce + (kernel ((x X) (y Y))
(* x y)))))
The vectors could be made longer by using a different expression in place of (vector 1 2 3 4) and (vector 4 3 2 1).
Harlan uses a Scheme-like S-Expression syntax, which is why there are so many parentheses. This is in part because the compiler was written in Scheme, so working with S-Expressions was the natural choice. S-Expressions also enables certain language features, such as Harlan's macro system, which would be much harder to implement in a language with more traditional syntax.
InfoQ: Does Harlan provide support for all major features included with NVidia and ATI GPUs?
Harlan compiles to OpenCL, which is a generate computing layer that supports many GPUs, CPUs, and other accelerators. As such, it doesn't provide support for the latest features. For example, Harlan does not currently support the new dynamic parallelism features of CUDA. I imagine some of this will change over time. Harlan does not yet make extensive use of the different memories on the GPU, but this is an area I am interested in exploring in the future.
InfoQ: Can you share with us more information regarding support for higher order procedures in Harlan?
Actually, basic support for higher order procedures are in Harlan as of about a week ago.
One common higher order function is called "map," which takes a function and a list, and returns a new list that is made by applying the function to every element in the list that was passed in. Here's an example in Scheme:
(let ((ls (list 1 2 3 4)))
(map add1 ls))
This creates a list of the numbers 1, 2, 3, and 4, and then applies add1, the procedure that increments its argument by 1, to each of the elements in the list. The result would be:
(2 3 4 5)