Domain scientists are more productive when using high-level languages such as Python and Matlab, but to get the performance they need they must often rewrite applications using efficiency-level languages like C++ or CUDA and explicit parallelism frameworks like OpenMP or Cilk. That is, application writers are forced to choose between high productivity and high performance.
We address the performance-productivity gap with Selective Embedded Just-In-Time Specialization (SEJITS), a methodology for developing Domain-Specific Embedded Languages (DSELs). DSELs embed a DSL into an existing language, so programmers can use the DSL as well as features the host language (in our case Python) interoperably.
Efficiency programmers comfortable with low-level languages and parallel programming design a DSEL for a particular problem type (say, structured grids) and create a just-in-time compiler for the DSEL, called a specializer. A specializer is much easier to write than a general compiler, since it optimizes only one kind of computation. At runtime, the specializer is handed the subset of Python code that uses that DSEL, and compiles it to efficiency-level code in a language such as C++ or CUDA that can express parallelism, use GPUs, and so on to obtain high performance. Compilation can include both template-driven code generation and conventional syntax-directed translation, and the compiler logic is expressed in Python, allowing the compiler to be implemented with high productivity in a modest amount of code.
Because the DSELs are embedded in a common higher-level language (Python), each specializer DSEL appears to the application writers as a Python class, so a single application can mix multiple DSELs. When the domain scientist's application runs, code written in a specializer DSEL is JIT-compiled by the appropriate specializer and the resulting object code dynamically linked to the application at runtime. To the domain programmer, the code simply runs faster, and even enjoys performance portability if the specializer has strategies for code generation to different targets.