Subgroups

A *subgroup* is some slice of a process array,
formed by restricting the process coordinates in one or more dimensions
to single values. Process arrays (class `Procs`) and subgroups
have a common base class, `Group`. In general the argument
of an *on* construct and the `on` clause in an array constructor
is a member of `Group`. This implies that the active process group or the
group over which an array is distributed may be just some a slice of a
complete process array.

By definition, any group has a parent process array and a dimension set.
In general the dimension set is
some subset of the dimensions of the parent array. The *restriction* operation on a group takes a slice in a particular
dimension. It is quite natural and convenient to express this
restriction procedure is in
terms of a *location*. If `i` is a location
in a range distributed over a dimension of `p`, then

p / irepresents a subgroup of p--the slice of

Using the `/` operator on groups explicitly is fairly unusual
practise. But subgroups are occur naturally in two ways:

- If an array
`a`is distributed over`p`, a section of`a`will generally be distributed over some subgroup of`p`. For example, if the only*scalar*subscript in the section subscript list was location`i`, the section would be distributed over the subgroup`p / i`

. Triplet subscripts don't change the group--only scalar subscripts. - The distributed control constructs
*over*and*at*change the active process group in a way that has not been described so far. Assume the current active process group is`p`, and`i`is a location. Then inside the constructat(i) { ... }

the active process group is equal to`p / i`

. If the current active process group is`p`, and`i`is an*index*, then inside the constructover(i) { ... }

the active process group is equal to`p / i`

. This case is slightly more subtle, because in different parallel ``iterations'' of the loop the location component of`i`has different values. In other words, the*over*construct*partitions*the original active process group into several subgroups (slices) operating independently.

To illustrate how subgroups can be used--in particular how the effect
of *over* on the active process group can be exploited--we
return to the matrix multiplication example of figure 1.
As a preliminary step, figure 9 is transcribes that program
using the distributed control constructs developed over the last
few sections. The changes are very minor. Because the active
process group is formally changed to `p`, the `on p`

clauses
can be omitted from the array constructors. Use of the `crd`
inquiry to obtain the integer subscript in the `x` range is
replaced by use of an *over* construct.
Now we want to change from distribution over a one-dimensional
process array to a two-dimensional grid.

The result is given in figure 10. Inside the `over(ip)`
construct there are `P` independent active process groups corresponding
to the rows of the original grid. The temporary array `tmp` is replicated
over these rows. The `remap` operation, working independently in
the `P` separate groups, implements a broadcast of the array section
representing the block of the `a` stored on process `(ip + s) % P`

within each group.

The freedom to embed calls to collective communication functions inside
distributed control constructs is a distinctive feature of Java-Ad.
There are a few restrictions on what operations are allowed. In
general the requirement is that all array arguments of a collective operation
should be *accessible* at the point of call. An array is accesible if
it is distributed over a group contained in the active process group.