This style goes some way toward forging a link between lowlevel SPMD programming and the higher level dataparallel style of HPJava, but by itself it doesn't help if we are presented with an existing onedimensional, blockdistributed array, and required to do some lowlevel processing on its blocks. To allow for this situation, the language is extended to support dimension splitting. Dimension splitting is introduced as an extension of the array section mechanism described at length in Chapter 4. The extra syntactic baggage is minimal, but we get a lot of new flexibility.
First we note that a particular element in a distributed array can be identified in one of two ways. It can be identified by giving a global subscript in the distributed range, which is effectively what we have done in HPJava in earlier chapters. Alternatively it can be identified by giving a process coordinate and a local subscripta subscript within the array segment held on the associated process. Dimension splitting provides a way of accessing an element through its process coordinate and local subscript, by allowing a distributed dimension of an array to be temporarily viewed as a pair of dimensionsa coordinate dimension plus a local subscript dimension.
If the subscript in a particular dimension of a section expression is the special symbol <>, that dimension of the array is split. Whereas a triplet subscript in a section expression yields one dimension in the result array, a splitting subscript yields twoa distributed dimension and a sequential dimension. The range of the distributed dimension is the process dimension over which the original array dimension was distributed; the local blocks of the original array are embedded in the the sequential dimension of the result. The two new dimensions appear consecutively in the signature of the result array, distributed dimension first.
Now we can combine the examples from Figures 7.1 and 7.5 of the last section. The version in Figure 7.6 initally creates the arrays as distributed, onedimensional arrays, and uses this convenient form to initialize them. It then uses a split representation of the same arrays to compute the force array. Note that, because as and fs are semantically sections of a and f, they share common elementsthey provide aliases through which the same element variables can be accessed. So when the computation loop is complete, the vector of forces can be accessed again through the onedimensional array f. This is likely to be what is needed in this case.
As a similar but slightly more complicated example, Figure
7.7 contains an optimized version of the pipelined
matrix multiplication from Figure 3.15.
Here the arithmetic is done in local blocks by a method
matmul,
which implements the matrix multiplication
on sequential twodimensional arrays.
It could be written in elementary style as
