# SlicesΒΆ

This example program demonstrates the use of array slicing and reindexing.

In this program, diagonal blocks (or slices) of `A`

are initialized
according to the row indices of the diagonal block.

`(i,j) = i`

, for all `(i,j)`

in diagonal blocks

If the block has been reindexed, then each diagonal block is initialized with the same values. If the block has not been reindexed, then the block has the same indices as the full array, so each diagonal block is initialized with different values.

(Incomplete diagonal blocks are not initialized. If `blk`

does not
divide into `n`

evenly, the last diagonal block of `A`

will be
uninitialized.)

Three different cases are given, to show different ways of slicing
arrays, with and without reindexing. Array aliases are declared
for the diagonal blocks in two of the three cases. One of these
array aliases uses reindexing of the domain of the array alias.
The initialization of the blocks is handled in either `initBlock`

or `initBlock2`

. The procedure `initBlock`

does not reindex
the domain of the input array while `initBlock2`

does.

Configuration variables for `n`

and `blk`

where the array `A`

is `n * n`

and `blk`

is the size of the diagonal subblock.

```
config const n = 10,
blk = 2;
proc main() {
```

Variable declarations for the range `vec`

, and for the domain `D`

and array `A`

. `vec`

is used to define the ranges of each dimension
of `D`

and it is later used in the iterator for the for loop statements
which call the init procedure for each diagonal block of `A`

.

```
const vec = 1..n;
var D = {vec,vec};
var A:[D] int;
```

`D0`

is a domain which is used to reindex the diagonal blocks of `A`

.

```
var D0 = {1..blk, 1..blk};
```

Each of the following three for loop statements uses the
iterator `blockIter`

to yield a range `subvec`

that is then
used to define `subvec * subvec`

blocks along the diagonal of `A`

.

Case 1: No reindexing of the diagonal blocks.
The array slice is sent directly to `initBlock`

.

```
writeln("Initializing the diagonal blocks of A.");
writeln("No reindexing of diagonal blocks.");
for subvec in blockIter(vec,blk) {
initBlock(A[subvec,subvec]);
}
writeln(A);
writeln();
```

`A`

is reset to zero between each case. (This step is not
necessary, but done to show that each case starts with a zero array.)

```
A = 0;
```

Case 2: An array alias with reindexing is used to point to each
diagonal block, and that array alias is sent to `initBlock`

.

```
writeln("Initializing the diagonal blocks of A.");
writeln("Reindexing of each diagonal block in alias declaration. ");
for subvec in blockIter(vec,blk) {
ref Ablock = A[subvec,subvec].reindex(D0);
initBlock(Ablock);
}
writeln(A);
writeln();
A = 0;
```

Case 3: An array alias is used to point to each diagonal block
and is reindexed to use 1-based indexing in order to meet the
requirements of the `initBlock2()`

routine.

```
writeln("Initializing the diagonal blocks of A.");
writeln("Reindexing of array argument in init procedure definition. ");
for subvec in blockIter(vec,blk) {
ref Ablock = A[subvec,subvec].reindex(1..blk, 1..blk);
initBlock2(Ablock);
}
writeln(A);
writeln();
```

```
} // main()
```

The iterator `blockIter`

yields a range that defines a subset
of `vec`

, which is always of length `blk`

.

```
iter blockIter(vec:range,blk) {
for i in vec by blk {
if (i + blk-1 <= vec.high) then
yield i..i+blk-1;
}
}
```

This procedure sets each element of `A`

to be the value of its
row index.

```
proc initBlock(ref A) {
for (i,j) in A.domain {
A(i,j) = i;
}
}
```

This procedure requires the domain of the array argument to
be `{1..blk,1..blk}`

. It sets each element of `A`

to be
the value of its row index.

```
proc initBlock2(ref A: [1..blk,1..blk]) {
for (i,j) in A.domain {
A(i,j) = i;
}
}
```