Procedure array argument ensure dimensionality

Can somebody tell me how I can ensure that the array argument for my procedure:

proc test(a: [?D] real){
//Do Stuff
}

Is ensured to be a 2D array.

One way to do this is with a where clause:

proc test(a: [?D] real) where a.rank == 2 {
  writeln("in test, rank is 2, array is:");
  writeln(a);
}

//var a1D:[1..4] real;
//test(a1D); // error: unresolved call... where clause evaluated to false

var a2D:[1..3, 1..2] real;
test(a2D);

The where clause allows any compile-time checking that is needed to make sure the function can apply. See also Procedures — Chapel Documentation 2.0 .

2 Likes

Hi @toihr

[edited since original post to fix a copy-paste error]

Michael's response is the same one that I reach for first. But another approach that I sometimes reach for is to use a conditional within the routine in order to get a more specific error message, as follows [ATO]:

proc test(a: [?D] real) {
  if (a.rank != 2) {
    compilerError("test() requires its array argument to be 2D");
  }
  writeln("in test, rank is 2, array is:");
  writeln(a);
}

//var a1D:[1..4] real;
//test(a1D); // error: test() requires its array argument to be 2D

var a2D:[1..3, 1..2] real;
test(a2D);

Such custom errors can also be generated using Michael's approach by providing another, more general, overload of the routine that serves as a fallback if the one with the 'where' clause doesn't match [ATO]:

proc test(a: [?D] real) where a.rank == 2 {
  writeln("in test, rank is 2, array is:");
  writeln(a);
}

proc test(a: [?D] real) {
  compilerError("test() requires its array argument to be 2D");
}

//var a1D:[1..4] real;
//test(a1D); // error: unresolved call... where clause evaluated to false

var a2D:[1..3, 1..2] real;
test(a2D);

Both of these lean on the compilerError() routine which prints out a compilerError() if it is in a live code path—in this case, if an array that isn't 2D is passed to test().

-Brad

1 Like