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
-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
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
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
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
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
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].)