Chapel domains : differences between `low/high` and `first/last` methods
Asked Answered
E

1

6

Chapel domains have two sets of methods

domain.low, domain.high

and

domain.first, domain.last

What are the various cases where these return different results (i.e when is domain.first != domain.low and domain.last != domain.high?

Extractor answered 13/7, 2018 at 19:53 Comment(0)
P
6

First, note that these queries are supported not just on domains, but also on ranges (a simpler type representing an integer sequence upon which many domains, and their domain queries, are based). For that reason, my answer will initially focus on ranges for simplicity, before returning to dense rectangular domains (which are defined using a range per dimension).

As background, first and last on a range are designed to specify the indices that you'll get when iterating over that range. In contrast, low and high specify the minimal and maximal indices that define the range.

  • For a simple range, like 1..10, first and low will be the same, evaluating to 1, while last and high will both evaluate to 10

  • The way you iterate through a range in reverse order in Chapel is by using a negative stride like 1..10 by -1. For this range, low and high will still be 1 and 10 respectively, but first will be 10 and last will be 1 since the range represents the integers 10, 9, 8, ..., 1.

  • Chapel also supports non-unit strides, and they can also result in differences. For example for the range 1..10 by 2, low and high will still be 1 and 10 respectively, and first will still be 1 but last will be 9 since this range only represents the odd values between 1 and 10.

The following program demonstrates these cases along with 1..10 by -2 which I'll leave as an exercise for the reader (you can also try it online (TIO)):

proc printBounds(r) {
  writeln("For range ", r, ":");
  writeln("  first = ", r.first);
  writeln("  last  = ", r.last);
  writeln("  low   = ", r.low);
  writeln("  high  = ", r.high);
  writeln();
}

printBounds(1..10);
printBounds(1..10 by -1);
printBounds(1..10 by 2);
printBounds(1..10 by -2);

Dense rectangular domains are defined using a range per dimension. Queries like low, high, first, and last on such domains return a tuple of values, one per dimension, corresponding to the results of the queries on the respective ranges. As an example, here's a 4D domain defined in terms of the ranges above (TIO):

const D = {1..10, 1..10 by -1, 1..10 by 2, 1..10 by -2};

writeln("low   = ", D.low);
writeln("high  = ", D.high);
writeln("first = ", D.first);
writeln("last  = ", D.last);
Paraformaldehyde answered 13/7, 2018 at 22:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.