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

Reply via email to