Figure 1 shows a PE arrangement as a two-dimensional grid structure in a simple Parallaxis example. The CONFIGURATION declaration provides 4 x 5 virtual processors, which are virtually connected to one another in the following CONNECTION declaration In the figure, PE 1,1 is in the upper left corner; however, you may also choose to put the `origin' in the lower left corner - it does not matter as long as you use it consistently in your program. Since homogeneous connection structures or topologies are easy to declare, four connection declarations are sufficient to construct a grid of any size. One connection is defined for each cardinal direction. The connection to the north, for example, decrements the first index. Some connections from the border PEs lead `nowhere', which means that these connections do not exist, and will not participate in any data exchange operation.
CONFIGURATION gid [1..4],[1..5];
CONNECTION north: grid[i,j] -> grid[i-1,j];
south: grid[i,j] -> grid[i+1,j];
east : grid[i,j] -> grid[i, j+1];
west : grid[i,j] -> grid[i, j-1];
Figure 1 Two-dimensional grid topology with representative PE
In case one prefers a wrapped-around torus instead of an open grid for some application, this can be easily accomplished by using the modulo-operator (remainder). Identifiers h and w denote constants:
CONFIGURATION torus [0..h-1],[0..w-1];
CONNECTION north: torus[i,j] -> torus[(i-1) MOD h, j];
south: torus[i,j] -> torus[(i+1) MOD h, j];
east : torus[i,j] -> torus[i, (j+1) MOD w];
west : torus[i,j] -> torus[i, (j-1) MOD w];
There is a list of extensions to this simple process of defining virtual machine structures: Connections may be parameterized, as with the hypercube in Figure 2. With these, it is possible to perform a data exchange in a computed direction. For the definition of the binary tree network,
also in Figure 2, bi-directional connections (`<->' or `<-
>'
in ASCII notation) have been used instead of uni-directional connections (`->' or `-
>').
A bi-directional connection is an abbreviation for two uni-directional
connections and, therefore, requires a second connection name on the right hand side of the connection.CONFIGURATION TREE [1..15]; CONNECTION lchild: tree[i] <-> tree[2*i] :parent; rchild: tree[i] <-> tree[2*i+1] :parent;
CONFIGURATION hyper [0..1],[0..1],[0..1],[0..1]; CONNECTION go[1]: hyper[i,j,k,l] -> hyper[(i+1)MOD 2, j,k,l]; go[2]: hyper[i,j,k,l] -> hyper[i, (j+1)MOD 2, k,l]; go[3]: hyper[i,j,k,l] -> hyper[i,j, (k+1)MOD 2, l]; go[4]: hyper[i,j,k,l] -> hyper[i,j,k, (l+1)MOD 2];Figure 2 Tree and hypercube topology
So-called `compound connections' may be used to have a case distinction inside a connection. The following example connects local pairs of PEs:
CONFIGURATION list [1..100];
CONNECTION next: list[i] -> {IDD (i)} list [i+1],
{EVEN(i)} list[i-1];
Figure 3 Compound connections
A case distinction is made for the next connection. If the PE-number is odd, a connection to the right neighbor is established, while if it is even, a connection to the left neighbor is established. Using compound connections, arbitrary connection structures, even with irregularities, may be defined. If several parts of a compound connection evaluate to TRUE for a particular PE, then for this PE all of these connections are defined (one-to-many or 1:n connection).
The connection structures as defined by the CONNECTION declaration do not have to be 1:1 (one-to-one) connections. For 1:n connections, an implicit broadcast is executed. In the following example, the first element of each row is connected to all elements in this row.
CONFIGURATION grid [1..100],[1..100]; CONNECTION one2many: grid[i,1] -> grid[i,1..100];If a one-to-many connection is to be established to all PEs of a dimension, the range may be substituted by an asterisk `*'. So the following is equivalent to the previous example.
CONFIGURATION grid [1..100],[1..100]; CONNECTION one2many: grid[i,1] -> grid[i,*];However, for n:1 (many-to-one) connections (and the general m:n connections, many-to-many) one must ensure that only a single value arrives at any PE's entry port. Therefore, each data exchange operation may include a vector reduction, as will be discussed later. In the following example, all elements of a row are connected to the first element in their column.
CONFIGURATION grid [1..100],[1..100]; CONNECTION many2one: grid[i,j] -> grid[i,1];
Figure4 Multiple connections