Subject: User-defined elemental procedures (Page reply to Merlin response)

From: "Rex Page" <[email-masked]>
Date: Wed, 15 Jul 92 10:58:28 -0500

In my comments on John's proposal for elemental procedures, I claimed
that programmers could get the effect of elemental procedures through
overloading.  I should have said "one of the effects."  What I had
in mind was that a programmer writing a function could use overloading
to make it possible for invocations of the function to operate on
either scalars or arrays.  People using the function could invoke
it, then, as if it were an elemental function.  

John pointed out that the version of such a function that operates
on array arguments (and delivers an array value) will probably be
viewed by the compiler in the same way as other array-valued functions.
That is, the compiler probably won't view the invocation as a
collection of parallel invocations unless it does a tremendous amount
of inter-procedural analysis.  Yet that view that would be obvious if
the invocation were elemental.  The point here is that the elemental
facility allows programmers to add precision to their specifications,
that is to raise their level of communication.

I agree that this is a powerful argument, and I was opposed to
removing elementals from Fortran 90.  Nevertheless they were removed.
Putting them back in raises the ante for compiler developers, which
is a trade-off HPFF must consider if it is important for people to be
able to run their code on both sequential workstations and high
performance systems.

The last version of Fortran 8x to contain a facility for user-defined
elemental functions did so by defining elemental invocations.  The
language included no syntax for designating a function as elemental.
It required the interface to be visible, making it possible for the
compiler to recognize an elemental invocation by matching arrays in
the actual argument list with scalars in corresponding positions of
the dummy argument list.

If we add elementals to HPF using the F8x approach, then we will be
adding semantics to Fortran 90, but not syntax.  This simplifies the
plight of someone trying to run an HPF program on a Fortran 90 system.
People lacking an HPF compiler can link in a collection of overloads
to simulate HPF elemental functions; they won't need to change any of
the invoking code.

On all of the above points, I think John agree on the facts.  We differ
a little on potential benefits, but not much.  I like elemental functions
as a mechanism for SPMD programming.

The following are some points of disagreement:

Page:
*    REAL v(3,10,10)
*    INTERFACE
*      ELEMENTAL FUNCTION f(x)
*        REAL, DIMENSION(3) :: f,x
*      END FUNCTION f
*    END INTERFACE
* ...
* The question of the shape of the object f(v) needs careful attention.
* John Merlin's proposal matches the first subscript of the actual and
* dummy arguments and makes f elemental on the last two subscripts in
* this invocation, so the shape of the result would be [10,10].
* 
* However, other matchings are possible.  Why not match the last subscripts?
* The result shape would then be [3,10]?  The decision seems arbitrary; it
* will be easy for programmers to forget which decision the language takes
* -- a likely source of errors.

Merlin's reply:
> Here you're making a case against the generalisation of allowing the 
> 'elements' of elemental procedures to be compound data objects as well as
> scalars.
> ...
> In full F90 implementations of HPF, the 'elements' of elemental
> procedures could be data structures as well as arrays, so these procedures 
> could be applied to arrays of structures as well as arrays of arrays.  

No, I'm not opposed to compound elements.  As John points out, Fortran 90
already permits this, and I think it is an essential concept.  It is
essentially the same idea as structure-valued expressions, without which
Fortran 90 programmers would be forced back to the ways of the ancients. 

An array of arrays is a bit clumsy in Fortran 90, since it must be
expressed as an array of structures (the structure has only one component,
which is an array).  But the facility has important uses, as John pointed
out.

Merlin's reply, continued:
> However, if HPF were to adopt this generalisation, there's definitley no 
> arbitrariness about which indices of an actual argument match those of the 
> corresponding dummy argument, and which are elemental.  Viewing the actual 
> argument as an array of compound data objects, its leading indices must be 
> matched with the dummy argument, as dictated by Fortran's column-major 
> ordering.

Fortran 90 defines an array element ordering only so that a whole array
in an i/o list will imply a particular sequence of i/o elements.  F90
uses this notion in a storage association sense only where it needs this
concept for compatibility with Fortran 77.  When one assumes that the
leading indices are the ones that must match, one elevates the concept
of array element ordering and drifts back towards the storage association
regime.  HPF could define a particular matching, such as first indices,
but should not try to justify the idea through appeals to array element
ordering.

I tried to sell the idea of arrays of arrays (without going through
structures) several times to the Fortran 8x committee, but came up short.
One of the arguments against it was the arbitrary choice of indices to form
elements of a lower-rank array from one of higher rank.  The array-of-arrays
concept would be a major addition to the language.  The issue is whether
it adds enough expressiveness to make it worthwhile.

Merlin:
* > I would propose that only elemental functions (both user-defined and
* > intrinsic) are allowed in FORALL, just as in array expressions.  

Page's reply:
* I don't understand what this means.  Array expressions, even in FORALL
* assignment, may refer to non-elemental functions.  John, will you clarify
* this for me?

Part of Merlin's clarification:
> I would dispute [your statement that array expressions in FORALL may
> refer to non-elemental functions]---you need the constraints 
> I listed to ensure that the function may be evaluated concurrently over 
> all elements of the FORALL assignment.

Fortran 90 (and 77 and 66) includes constraints against side-effects that
make the value of an expression depend on the order of evaluation of
subexpressions.  I would like HPF to expand these contraints to permit
concurrent evaluation of subexpressions.  (I think that John's constraints
are adequate and that they add to Fortran's existing constraints only the
requirement that functions within the same statement must avoid sharing
temporary resources.)  Then forall statements could call non-elemental
functions with impunity, expanding their usefulness for SPMD programming.

If we add these constraints under all circumstances, we improve the
language, but invalidate certain standard-conforming programs.  (I think
the improvement would be worth the cost in this case, but I don't expect
to convince many others.)  We will need to add the constraint in the case
of FORALL regardless of the decision on elemental functions.  Otherwise,
forall won't be a parallel construct.

(Actually, if we define forall to permit parallelism, then we inherit the
constraints we need from Fortran's prohibition of side-effects in functions
when they may change the meaning of an assignment statement.)

Merlin:
* > Elemental subroutine calls could also be allowed in FORALL, with a very 
* > similar interpretation to elemental functions.  The main reason for
* > using them would be to allow the return of multiple results.  

Page's reply: 
* Structure-valued functions provide a way to return multiple results, so
* this doesn't seem to be a strong reason for including subroutine calls
* in FORALL.

Merlin's response:
> But it's a nuisance to have to clump together logically distinct
> data objects into a single structure simply to achieve this effect.
> Also, only one grouping of data objects can be achieved this way statically
> ---other groupings must be created by assignment to a structure,
> which will be expensive in time and storage.  (Also, early HPF 
> implementations may not support structures, though that's not a 
> strong argument!).

If a subroutine is returning multiple data objects that are logically
distinct, then the subroutine is ill-conceived.  If it is worth defining
a subroutine, it is worth defining a datatype corresponding to the
result it delivers.

The Fortran 8x version of elementals permitted elemental subroutines
only for subroutines used to overload the assignment operation.  I'd
like to restrict the elemental notion to functions only.  Subroutines
(unlike functions) are an outmoded concept in Fortran 90.
Accomplished programmers will not use them -- except to package i/o
or other side-effects, or possibly for efficiency reasons to cope with
poor compilers.

 - Rex Page