next up previous contents index
Next: Programming Examples Up: The HPspmd Model and Previous: Communication Library Functions   Contents   Index


Java Packages for HPspmd Programming

The implementation of the HPJava compiler is based on a run-time system. It is actually a source-to-source translator converting an HPJava program to a Java node program, with function calls to the run-time library, called adJava.

The run-time interface consists of several Java packages. The most important one is the HPspmd runtime proper. It includes the classes needed to translate language constructs. Other packages provide communication and some simple I/O functions. Important classes in the first package include distributed array ``container classes'' and related classes describing process groups and index ranges. These classes correspond directly to HPJava built-in classes.

The first hierarchy is based on Group. A group, or process group, defines some subset of the processes executing the SPMD program. They can be used to describe how program variables, such as arrays, are distributed or replicated across the process pool, or to specify which subset of processes executes a particular code fragment. Important members of adJava Group class include the pair on(), no() used to translate the on construct.

The most common way to create a group object is through the constructor for one of the subclasses representing a process grid. The subclass Procs represents a grid of processes and carries information on process dimensions: in particular an inquiry function dim(r) returns a range object describing the $r$-th process dimension. Procs is further subclassed by Procs0, Procs1, Procs2, ...which provide simpler constructors for fixed dimensionality process grids.

The second hierarchy in the package is based on Range. A range is a map from the integer interval $0,\ldots,n-1$ into some process dimension (i.e., some dimension of a process grid). Ranges are used to parametrize distributed arrays and the overall distributed loop.

The most common way to create a range object is to use the constructor for one of the subclasses representing ranges with specific distribution formats. Simple block distribution format is implemented by BlockRange, while CyclicRange and BlockCyclicRange represent other standard distribution formats of HPF. The subclass CollapsedRange represents a sequential (undistributed range). Finally, a DimRange is associated with each process dimension and represents the range of coordinates for the process dimension itself--just one element is mapped to each process.

The related adJava class Location represents an individual location in a particular distributed range. Important members of the adJava Range class include the function location(i), which returns the $i$th location in a range, and its inverse, idx(l), which returns the global subscript associated with a given location. Important members of the Location class include at() and ta(), used in the implementation of the HPJava that at construct.

Finally, we have the rather complex hierarchy of classes representing distributed arrays. HPJava global arrays declared using [[]] are represented by Java objects belonging to classes such as:

   Array1dI, Array1cI,
   Array2ddI, Array2dcI, Array2cdI, Array2ccI,
   ...
   Array1dF, Array1cF,
   Array2ddF, Array2dcF, Array2cdF, Array2ccF,
   ...
Generally speaking, the class ``Arraync|d...T'' represents $n$-dimensional distributed arrays with elements of type T--currently one of I, F, ..., meaning int, float, .... [*] The penultimate part of the class name is a string of $n$ ``c''s and ``d''s specifying whether each dimension is collapsed or normally distributed. These correlate with presence or absence of an asterisk in slots of the HPJava type signature. The concrete Array... classes implement a series of abstract interfaces. These follow a similar naming convention, but the root of their names is Section rather than Array (so Array2dcI, for example, implements Section2dcI). The hierarchy of Section interfaces is illustrated in Figure 1.5. The need to introduce the Section interfaces should be evident from the hierarchy diagram. The type hierarchy of HPJava involves a kind of multiple inheritance. The array type int [[*, *]], for example, is a specialization of both the types int [[*, ]] and int [[, *]]. Java allows ``multiple inheritance'' only from interfaces, not classes.

Figure 1.5: The adJava Section hierarchy

Important members of the Section interfaces include inquiry functions dat(), which returns an ordinary one dimensional Java array used to store the locally held elements of the distributed array, and the member pos(i, ...), which takes $n$ subscript arguments and returns the local offset of the element implied by those subscripts. Each argument of pos is a location or an integer (only allowed if the corresponding dimension is collapsed). These functions are used to implement elemental subscripting. The inquiry grp() returns the group over which elements of the array are distributed. The inquiry rng(d) returns the $d$th range of the array.

Another package in adJava is the communication library. The adJava communication package includes classes corresponding to the various collective communication schedules provided in the NPAC PCRC kernel. Most of them provide a constructor to establish a schedule, and an execute method, which carries out the data movement specified by the schedule. Different communication models may eventually be added through further packages.

The collective communication schedules can be used directly by the programmer or invoked through certain wrapper functions. A class named Adlib is defined with static members that create and execute communication schedules and perform simple I/O functions. This class includes, for example, the following methods, each implemented by constructing the appropriate schedule and then executing it:

  static void remap(Section dst, Section src)
  static void shift(Section dst, Section src, int shift, int dim, int mode)
  static void copy(Section dst, Section src)
  static void writeHalo(Section src, int [] wlo, int [] whi, int [] mode)
Adlib.remap will copy the corresponding elements from one array to another, regardless of their respective distribution format. Adlib.shift will shift data by a certain amount in a specific dimension of the array, in either cyclic or edge-off mode. Adlib.writeHalo is used to update ghost regions.

Given the classes described above, one can program in the HPspmd style in pure Java program. Then the idea of the HPJava compiler is just to translate the HPJava program onto this interface, in the meanwhile, to use optimized address calculation instead of function calls to access elements of arrays. (For a detailed translation scheme, please refer to [11].)


next up previous contents index
Next: Programming Examples Up: The HPspmd Model and Previous: Communication Library Functions   Contents   Index
Bryan Carpenter 2002-07-11