About

The Diderot project is an effort to design and implement a Parallel Domain-specific Language (PDSL) for image analysis and visualization. We are particularly interested in a class of algorithms that are programmed in terms of continuous scalar, vector, and tensor fields that are reconstructed from the image data. Our goals are to provide a high-level mathematical programming model for these algorithms, while also providing high-performance implementations on a variety of parallel hardware platforms.

People

Language overview

The following is an overview of our current preliminary design for Diderot. We are building a compiler for this design and expect that the design will evolve as we get experience with the implementation. Also, the design is conservative, in that it does not provide all of the features that we plan to provide (e.g., interactions between strands).

Types

The main type of computational value in Diderot is a tensor, which includes reals (0-order tensors), vectors, and matrices. In addition, Diderot provides booleans, integers, and strings. Diderot also has three abstract types:

images
are used to represent the data being analyzed, as well as other array data, such as transfer functions.
kernels
are separable convolution kernels
fields
are an abstraction of functions from 1D, 2D, or 3D space to some tensor type. A field is defined by convolving an image with a kernel.

Program structure

A Diderot program is organized into three logical sections:

  1. Global declarations define global values, such as fields, as well as the inputs to the program.
  2. Strand definitions define the computational agents that implement the program
  3. Initialization defines the initial set of strands and their structure

Strands

A strand represents a mostly autonomous computation with local state, which includes its position in world space. A strand definition consists of declared state variables and methods. All strands must have an update method and may optionally have a stabilize method.

Note that we used use the term actor for the computational entities, but that led to some confusion with actor-languages, so we have changed the name to strand.

Execution model

The Diderot execution model is bulk synchronous. At each iteration, the update methods of all active strands are invoked, resulting in a new configuration.

An example: A simple volume renderer in Diderot

The following code is a simple diffuse-only volume rendering with head-light written in Diderot. It uses an opacity function that varies linearly between two values. This example illustrates the use of probing both a field and its gradient.

This example uses Unicode characters for convolution (code point \u229B) and differentiation (code point \u2207). If your browser has trouble with displaying these characters, an ASCII-only version can be found here.

input string dataFile; // name of dataset input real stepSz = 0.1; // size of steps input vec3 eye; // location of eye point input vec3 orig; // location of pixel (0,0) input vec3 cVec; // vector between pixels horizontally input vec3 rVec; // vector between pixels vertically input real valOpacMin; // highest value with opacity 0.0 input real valOpacMax; // lowest value with opacity 1.0 image(3)[] img = load (dataFile); field#1(3)[] F = img ⊛ bspln3; strand RayCast (int row, int col) { vec3 pos = orig + real(row)*rVec + real(col)*cVec; vec3 dir = (pos - eye)/|pos - eye|; real t = 0.0; real transp = 1.0; real gray = 0.0; output vec4 rgba = [0.0, 0.0, 0.0, 0.0]; update { pos = pos + stepSz*dir; if (inside (pos,F)) { real val = F@pos; vec3 grad = ∇F@pos; vec3 norm = -grad / |grad|; if (val > valOpacMin) { // we have some opacity real opac = 1.0 if (val > valOpacMax) else (val - valOpacMin)/(valOpacMax - valOpacMin); gray = gray + transp*opac*max(0.0, dot(-dir,norm)); transp = transp*(1.0 - opac); } } if (transp < 0.01) { // early ray termination transp = 0.0; stabilize; } if (t > 40.0) { stabilize; } t = t + stepSz; } stabilize { rgba = [gray, gray, gray, 1.0-transp]; } } initially [ RayCast(r, c) | r in 0..199, c in 0..199 ];

Status

We have a prototype language design that can handle simple examples, such as volume rendering, and we are working on a baseline compiler for the design. This compiler will generate CUDA or OpenCL code for running on GPUs.

Further information

We have not published any papers on Diderot yet, but here are some unpublished documents that provide additional details about the project.

Support

We thank NVIDIA for hardware and financial support.


Last modified: December 10, 2010.