People   Project   Publications   More Info  
    architecture   programming   performance   VLSI   board   applications   tools  


Imagine Stream Programming


Signal and image processing applications are easily expressed as a series of computation kernels that operate on large data streams.  An Imagine application is a set of kernels connected by streams.  Streams are organized as a sequence of records.  Each record in a stream is a collection of related data words, such as the vertex, normal, and color information for a triangle.  A kernel is a small program that runs on the arithmetic clusters of Imagine, and is repeated for each successive element of its input streams to produce output streams for the next kernel in the application.


Stream-Level Programming

The application level programming is done using StreamC language, which uses the C++ language syntax.  While the Imagine stream processor executes VLIW instructions (derived from KernelC), the host processor executes StreamC programs.  StreamC enables the host to set up and transfer data to and from Imagine and between Imagine processors, and to initiate kernels to perform computation on Imagine.

Details of the StreamC language syntax is available in section 4 of the ips_user.pdf documentation. This example StreamC code fragment loads the Stream Register File (SRF) with two 16-element streams of data and initiates the kernel foo to operate on the data:

    im_stream<im_int> datain1(16);
    im_stream<im_int> datain2(16);
    im_stream<im_int> dataout1(16);
    im_stream<im_int> dataout2(16);
    streamLoadFile ("inputfile1.txt", "txt" , "d", datin1); // File in host to SRF
    streamLoadFile ("inputfile2.txt", "txt" , "d", datin2); // File in host to SRF
    foo (datin1, datin2, datout1, datout2); // execute kernel foo to produce datout1 & datout2
    streamCompareFile ("result1.txt", datout1, 0, "a"); // verifies datout1
    streamCompareFile ("result2.txt", datout2, 0, "a"); // verifies datout2


Kernel-Level Programming

Imagine kernels are coded in a programming language called KernelC, using the expression syntax of the C language.  The code appears to operate on a single record at one time, but the 8 clusters on Imagine each run the same kernel on different elements of the stream simultaneously, in SIMD fashion.  Kernels may access local variables, read input streams, and write output streams, but may not make arbitrary memory references.  The Kernel Scheduler compiles KernelC code into a microcode program, which is a sequence of VLIW instructions.   

This example KernelC kernel interacts with the above StreamC code.  It produces two streams, c and d.  The first stream is the sum of the two input streams, while the second stream is the difference of the two input streams.

loop(input_stream0) {
input_stream0 >> a;
input_stream1 >> b;
c = a + b;
d = a - b;
output_stream0 << c;
output_stream1 << d;

Imagine repeats the kernel until the input streams (stored in the SRF by the Host Processor) are emptied.  Details of the KernelC language syntax is available under section 3 of the ips_user.pdf document.

The following figures show a scheduled kernel.  Figure 1 is a single pass through the stereo-depth extraction kernel.  It shows all the functional units in Imagine and their respective usage with time in the y-axis.  Figure 2 shows the kernel after software pipelining.

Figure 1: One Kernel iteration

Figure 2: Scheduled and Pipelined Kernel