HPJava adds class libraries and some additional syntax for dealing with distributed arrays. These arrays are viewed as coherent global entities, but their elements are divided across a set of cooperating processes. As a preliminary to introducing distributed arrays we discuss the process arrays over which their elements are scattered.
A base class Group describes a general group of processes. It has subclasses Procs1, Procs2, ..., representing one-dimensional process arrays, two-dimensional process arrays, and so on.
Procs2 p = new Procs2(2, 2) ; Procs1 q = new Procs1(4) ;These declarations set p to represent a 2 by 2 process array and q to represent a 4-element, one-dimensional process array. In either case the object created describes a group of 4 processes. At the time the Procs constructors are executed the program should be executing on four or more processes. Either constructor selects four processes from this set and identifies them as members of the constructed group.
The multi-dimensional structure of a process array is reflected in its set of process dimensions. An object is associated with each dimension. These objects are accessed through the inquiry member dim:
Dimension x = p.dim(0) ; Dimension y = p.dim(1) ; Dimension z = q.dim(0) ;As indicated, the object returned by the dim inquiry has class Dimension.
Now, some or all of the dimensions of a multi-dimensional array can be declared as distributed ranges. In general a distributed range is represented by an object of class Range. A Range object defines a range of integer subscripts, and defines how they are mapped into a process array dimension. For example, the class BlockRange is a subclass of Range which describes a simple block-distributed range of subscripts. Like BLOCK distribution format in HPF, it maps blocks of contiguous subscripts to each element of its target process dimension. The constructor of BlockRange usually takes two arguments: the extent of the range and a Dimension object defining the process dimension over which the new range is distributed.
The syntax of Sect.2 is extended in the following way to support distributed arrays
For example, in
Procs2 p = new Procs2(3, 2) ; Range x = new BlockRange(100, p.dim(0)) ; Range y = new BlockRange(200, p.dim(1)) ; float [[#,#]] a = new float [[x, y]] on p ;a is created as a 100 200 array, block-distributed over the 6 processes in p. The fragment is essentially equivalent to the HPF declarations
!HPF$ PROCESSORS p(3, 2) REAL a(100, 200) !HPF$ DISTRIBUTE a(BLOCK, BLOCK) ONTO p
Because a is declared as a collective object we can apply collective operations to it. The HPJlib functions introduced in Sect.2 apply equally well to distributed arrays, but now they imply inter-processor communication.
float [[#,#]] b = new float [[x, y]] on p ; HPJlib.shift(a, b, -1, 0, CYCL) ;At the edges of the local segment of a the shift operation causes the local values of a to be overwritten with values of b from a processor adjacent in the x dimension.
Subscripting operations on distributed arrays are subject to a strict restriction. As already emphasized, the HPJava model is explicitly SPMD. An array access such as
a [17, 23] = 13 ;is legal, but only if the local process holds the element in question. The language provides several distributed control constructs to alleviate the inconvenience of this restriction.