next up previous
Next: Process arrays Up: HPJava: data parallel extensions Previous: Introduction


Multidimensional arrays

First we describe a modest extension to Java that adds a class of true multi-dimensional arrays to the standard Java language. The new arrays allow regular section subscripting, similar to Fortran 90 arrays. The syntax described in this section is a subset of the syntax introduced later for parallel arrays and algorithms: the only motivation for discussing the sequential subset first is to simplify the overall presentation. No attempt is made to integrate the new multidimensional arrays with the standard Java arrays: they are a new kind of entity that coexists in the language with ordinary Java arrays. There are good technical reasons for keeping the two kinds of array separate1.

The type-signatures and constructors of the multidimensional array use double brackets to distinguish them from ordinary arrays:

  int [[,]] a = new int [[5, 5]] ;

  float [[,,]] b = new float [[10, n, 20]] ;

  int [[]] c = new int [[100]] ;
a, b and c are respectively 2-, 3- and one- dimensional arrays. Of course c is very similar in structure to the standard array d, created by
  int [] d = new int [100] ;
c and d are not identical, though2.

Access to individual elements of a multidimensional array goes through a subscripting operation involving single brackets, for example

  for(int i = 0 ; i < 4 ; i++)
    a [i, i + 1] = i + c [i] ;
For reasons that will become clearer in later sections, this style of subscripting is called local subscripting. In the current sequential context, apart from the fact that a single pair of brackest may include several comma-separated subscripts, this kind of subscripting works just like ordinary Java array subscripting. Subscripts always start at zero, in the ordinary Java or C style (there is no Fortran-like lower bound).

In general our language has no idea of Fortran-like array assignments. In

  int [[,]] e = new int [[n, m]] ;
  ...
  a = e ;
the assignment simply copies a handle to object referenced by e into a. There is no element-by-element copy involved. Similarly we introduce no idea of elemental arithmetic or elemental function application. If e and a are arrays, the expressions
  e + a
  Math.cos(e)
are type errors.

Our HPJava does import a Fortran-90-like idea of array regular sections. The syntax for section subscripting is different to the syntax for local subscripting. Double brackets are used. These brackets can include scalar subscripts or subscript triplets.

A section is an object in its own right--its type is that of a suitable multi-dimensional array. It describes some subset of the elements of the parent array. This is slightly different to the situation in Fortran, where sections cannot usually be captured as named entities3.

  int [[]] e = a [[2,  2 :]] ;

  foo(b [[ : , 0, 1 : 10 : 2]]) ;
e becomes an alias for the 3rd row of elements of a. The procedure foo should expect a two-dimensional array as argument. It can read or write to the set of elements of b selected by the section. As in Fortran, upper or lower bounds can be omitted in triplets, defaulting to the actual bound of the parent array, and the stride entry of the triplet is optional. The subscripts of e, like any other array, start at 0, although the first element is identified with a [2, 2].

In our language, unlike Fortran, it is not allowed to use vectors of integers as subscripts. The only sections recognized are regular sections defined through scalar and triplet subscripts.

The language provides a library of functions for manipulating its arrays, closely analogous to the array transformational intrinsic functions of Fortran 90:

  int [[,]] f = new int [[5, 5]] ;
  HPJlib.shift(f, a, -1, 0, CYCL) ;

  float g = HPJlib.sum(b) ;

  int [[]] h = new int [[100]] ;
  HPJlib.copy(h, c) ;
The shift operation with shift-mode CYCL executes a cyclic shift on the data in its second argument, copying the result to its first argument--an array of the same shape. In the example the shift amount is -1, and the shift is performed in dimension 0 of the array--the first of its two dimensions. The sum operation simply adds all elements of its argument array. The copy operation copies the elements of its second argument to its first--it is something like an array assignment. These functions may have to be overloaded to apply to some finite set of array types, eg they may be defined for arrays with elements of any suitable Java primitive type, up to some maximum rank of array. Alternatively the type-hierarchy for arrays can be defined in a way that allows these functions to be more polymorphic.


next up previous
Next: Process arrays Up: HPJava: data parallel extensions Previous: Introduction
Bryan Carpenter 2002-07-11