Hi Chapel Users --
Executive Summary: This mail proposes that domains in a rectangular formal
array argument's type signature serve as an assertion that the actual
array argument is defined over a certain index set rather than a request
that the actual argument be reindexed to match the formal's index set.
At the end of the mail are some questions to which we'd be interested in
your feedback.
Background:
-----------
Since Chapel's inception, the presence of a domain in the type signature
of a formal rectangular array argument has been interpreted as a
reindexing operation. That is, one could write a routine like this:
proc foo(X: [1..blk, 1..blk] real) {
...A[1, 1]... // can use 1-based indexing within this proc
}
And then call it using a blk x blk slice of A that didn't necessarily
start at (1,1):
foo(A[lo1..#blk, lo2..#blk]);
This was done in order to productively write routines like the above that
wish to compute on a sub-array using their own indexing schemes without
worrying about what domain defines the actual argument. This has been
implemented by having the compiler "reindex" the actual argument using the
formal's domain whenever one is present. That is, the compiler
effectively rewrites the callsite above into:
foo(A[lo1..#blk, lo2..#blk].reindex({1..blk, 1..blk}));
Meanwhile, for non-rectangular domains, the presence of a domain in a
formal array argument's type has been an assertion that the actual
argument's domain must describe those same indices (an assertion that, it
appears to me, has never been implemented). The rationale for this
inconsistency was that reindexing doesn't make much sense for irregular
domains.
Impact:
-------
This approach to rectangular domains has been a source of unnecessary
overhead for many Chapel users for some time, because those users who
prefer to specify formal types have often used it for simple cases in
which no reindexing is required. For example:
var A: [1..n] real;
proc foo(X: [1..n] real) {
...
}
foo(A);
In such cases, the Chapel compiler has dutifully put in the reindexing
operation even though none is required for correct execution since the
formal's and actual's domains match. Worse, the reindexing operation
tends to be fairly heavyweight, so this has bogged down cases like this
that really ought to be able to just pass A through. And worst of all,
this has appeared to be the common case in most users' codes that we're
aware of (assert the actual's domain rather than request a reindexing of
it).
For the specific case above, the reindexing operation could arguably be
optimized away by the compiler since it can plainly see that the domains
are the same. But in more complex cases where it isn't so obvious that an
actual and formal match, the compiler would still have to conservatively
reindex.
Similarly, it could be argued that our current reindexing should be
optimized such that it isn't such a burden in the no-op case (and this is
true), but it still suggests that some overhead would be incurred by users
who just wish to assert a specific array size rather than just passing the
array through.
Instead, for some time, we've discussed handling these two use cases in
distinct ways, and reclaiming the current syntax as an assertion of array
size rather than an implicit reindexing.
Proposed alternative:
---------------------
The alternative being proposed here is to have a rectangular formal array
argument's domain specify the domain of the actual (as with irregular
array types), both for consistency and to avoid unnecessary reindexing.
The domain match would be checked at execution time, and could be disabled
through a flag for those who really wanted a zero-cost/no-seatbelt
implementation.
For users who want/need the reindexing capability when calling a function,
there are two possibilities:
A) insert the reindex() call manually on the actual argument as shown in
the compiler rewrite above. This will of course work, but at some cost
in typing. On the other hand, it reduces the degree of invisible,
expensive work taking place.
B) add an operator/sugar to the language that says "when passing me to
this function, reindex me to match the domain that it expects." As
a placeholder example, imagine something like the presence of the '=>':
operator in this call:
foo(=>A[lo1..#blk, lo2..#blk]));
to mean "reindex this array to match the formal's domain (i.e., {1..n,
1..n}). (That said, note that I'm not particularly fond with this
placeholder syntax).
Questions for you:
------------------
1) Does anyone object to changing the interpretation of formal rectangular
array arguments for rectangular array from "reindex the actual's
domain" to "assert that the actual's domain matches?"
2) Do you like/want the "auto-reindex" capability proposed in option B
above? If so, do you have a favorite syntax for it?
3) If the proposed semantics were adopted for this fall's release, but
an "auto-reindex" capability were not yet implemented, would that
cause you hardship?
Thanks for your feedback,
-Brad
------------------------------------------------------------------------------
_______________________________________________
Chapel-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-users