POOMA: A C++ Toolkit for High-Performance Parallel Scientific Computing | ||
---|---|---|
Prev | Chapter 4. Overview of POOMA Concepts | Next |
POOMA computations can be expressed using a variety of modes. Many POOMA computations involve Array or Field containers, but how their values are accessed and how the associated algorithms use them varies. For example, element-wise computation involves explicitly accessing a container's values. A data-parallel computation operates on larger subsets of a container's values. Stencil-based computations express a computation as repeatedly applying a local computation to each element of an array. Relation-based computations use relations on containers to establish dependencies among them so the values of one container are updated whenever any other's values change. A program may use any or all of these styles, which are described below.
Element-wise computation accesses individual container values through explicit notation. For example, values in a two-dimensional container C might be referenced as C(3,4) or C(i,j+1). This is the usual notation for non-object-oriented languages such as C.
Data-parallel computation uses expressions to access subsets of a container's values. For example, in Example 3-3, a(I,J) represents the subset of Array a's values having coordinates in the domain specified by the direct product of one-dimensional Intervals I and J. Using data-parallel expressions frequently eliminates the need for writing explicit loops.
Stencil-based computation uses stencils to compute containers' values using neighboring data values. Each stencil consists of a specification of which neighboring values to read and a function using those values. For example, an averaging stencil may access all its adjacent neighbors, averaging them. In POOMA, we represent a stencil using a function object with additional functions indicating which neighboring values are used. Stencil computations are frequently used in solving partial differential equations, image processing, and geometric modeling.
Relation-based computation uses relations to create dependences among containers such the dependent container's values are updated when its values are needed and any of its related containers' values have changed. A relation is specified by a dependent container, independent containers, and a function computing the dependent container's values using the independent containers' values. To avoid excess computation, the dependent container's values are computed only when needed, e.g., for printing the container or for computing the values of another dependent container. Thus, this computation is sometimes called "lazy evaluation".