Search code examples
chapel

Chapel - Ranges defined using bounds of type 'range(int(64),bounded,false)' are not currently supported


The title "Ranges defined using bounds of type 'range(int(64),bounded,false)' are not currently supported" shows up as error when I try to compile this 5-point stencil benchmark code. What is causing this? I use chapel 1.8.2, and it does not show up when only compiling the procedures.

use Time;
use IO;

/* Use ./2dstencil --n=20000 --iterations=5 to run with different arguments. */
config const n: int = 10000;
config const iterations: int = 10;

const constants = [[0.0, 0.5, 0.0],
                   [0.5, 0.5, 0.5],
                   [0.0, 0.5, 0.0]];

proc relax(input: [1..n, 1..n] real)
{
    var output: [1..n, 1..n] real;

    /* Inner part */
    forall i in [2..n - 1] do
        forall j in [2..n - 1] do
            output[i, j] = + reduce (input[i - 1..i + 1, j - 1..j + 1] * constants);

    /* Boundary */
    output[1, 1..n] = input[1, 1..n];
    output[n, 1..n] = input[n, 1..n];
    output[1..n, 1] = input[1..n, 1];
    output[1..n, n] = input[1..n, n];

    return output;
}

proc stencil(input: [1..n, 1..n] real)
{
    var copy: [1..n, 1..n] real = input;

    for t in [1..iterations] do
        input = relax(input);

    return input;
}

var input: [1..n, 1..n] real = 1;
var watch: Timer;
watch.start();

input = stencil(input);
watch.stop();
stderr.writeln('Anti-optimisation number: ', + reduce input, '\n');

stdout.writeln(watch.elapsed(), '\n');

Solution

  • This is a bit subtle, but the cause of the problem is the following loops:

        forall i in [2..n - 1] do
            forall j in [2..n - 1] do
    

    Specifically, I believe you're writing these with the intention to have i and j be integer variables looping from 2 through n-1. In order to get that behavior, you would need to drop the square brackets from these expressions for the following reason:

    The syntax [expr-list] in Chapel represents an array literal whose elements are the expressions between the square brackets. E.g., forall i in [1, 3, 5, 4, 6] would loop over the integers represented by that array literal. In your code, you're looping over a 1-element array of range values whose single element is the range 2..n-1. Thus, both i and j are range variables representing the range 2..n-1.

    Then, in the body of the loop, when trying to evaluate the expressions i - 1..i + 1 and j - 1..j + 1, the compiler is complaining that the bounds of the ranges being constructed by the .. operator are themselves ranges rather than some other supported type (like integers or enums).

    To see this, try the following code:

    forall i in [2..n-1] do
      writeln(i, ": ", i.type:string);
    

    which prints as its output:

    2..99: range(int(64),bounded,false)
    

    Or this one:

    config var n = 100;
    
    var r = (1..n)..(1..n);
    

    which prints a similar error to the one you're getting.

    The one other thing going on here is that ranges support +/- operators taking integer values, which result in a translation of the range. Thus, i + 1, where i is a unit-stride range, effectively becomes i.low+1..i.high+1.

    Because of this subtlety, I've opened this issue, asking the question whether Chapel should require trailing commas in single-element array literals, much like it does for single-element tuples today.