Skip to main content

Domain Specific Languages and runtime code generation

Posted by carcassi on January 24, 2007 at 10:24 PM PST

One area in which Java has an advantage over typical HPC languages
(C/C++/Fortran) is its ability to use information at runtime to fine tune the
code. If used well, this allows you to write code that is a bit more general without
sacrificing performance, as the code will get "re-specialized" at runtime. 
While in C/C++ sometimes you are stuck with macros or preprocessing scripts, in Java I have been
finding a few different techniques. The last few nights I have been working on another one: runtime compilation of Domain Specific Language expressions.

As much as I'd like to show the actual code, it wouldn't really fit in a blog
entry... But the code is in the Jabble CVS repository, so I'll provide links
here and there for the curious reader. The flow is something like this:

  • developer/user specifies at runtime a String that represents
    an expression like

    blogDSL1.png

    where phi[x,y] is the field 'phi' at the offset from the current point (The above
    expression is a second order derivative).

  • the String is passed to an ANTLR
    generated parser, which return the
    Abstract Syntax Tree

    blogDSL2.png

  • the AST is passed to an
    expression builder, which creates a Jabble
    specific tree that is able to calculate the expression at runtime, and aids
    the Java source creation

    blogDSL3.png

  • the expression tree is transformed to
    a String that represents a Java
    class
    that makes that same computation. The Java class will implement the FiniteExpression interface.

    blogDSL4.png

  • the java source is
    passed to the JSR199 compiler, which returns a binary
    representation of the bytecode

    blogDSL5.png

  • the bytecode is given to a
    memory ClassLoader, so that it can be
    accessed by the running JVM.

    blogDSL6.png

  • the ClassLoader is used to create an instance of the newly compiled
    class, which will be handled as a FiniteExpression type object.

    blogDSL7.png

In short: at runtime you can quickly specify an expression (in your code or
through a UI), which gets compiled to Java code, and which is going to take
advantage of all of the Java optimizations. To give you the picture: the calls
made by the runtime generated code are going to be inlined!

There are other, even more interesting possibilities. Given that I have the
domain model expression, I can provide functionalities and optimizations that
are specific to it. For example, I can simplify the expression; I can also
determine the order in which to compute the different fields. (For example, I
can easily understand that "beta[0,0] =  alpha[1,0] - 2 * alpha[0,0] +
alpha[-1,0]" has to be calculated before and in a different Grid iteration than
"gamma[0,0] = beta[1,0] - beta[-1,0] + alpha[0,0]")

The only catch? I have to wait for JDK6 to be available on a Mac to add this
to a Jabble release...

Related Topics >>