Subject: User-defined elemental procedures (> John Merlin)

From: "Rex Page" <[email-masked]>
Date: Mon, 29 Jun 92 09:33:40 -0500

> I'd like to propose extending the Fortran 90 concept of 'elemental 
> procedures' for the purpose of HP Fortran -- the extension being to 
> allow programmers to define such procedures, which in F90 are restricted 
> to a subset of the intrinsic procedures.  

True, programmers cannot define elemental procedures in a technical sense,
but they can get the effect of such procedures by overloading a procedure
name.  Overloading is resolved by matching the type/kind/rank pattern of
the actual arguments in an invocation against that of the dummy arguments
in a procedure definition.  For elemental procedures, rank is the relevant
issue.  Since rank must be between zero and seven, the programmer can
overload a procedure name with eight definitions, one for each rank, to
get the effect of elemental functions.

HPFF seems reluctant to add syntax to Fortran 90 (fortunately, in my view).
Adding syntax to make an existing capability less clumsy will, I hope,
have a low priority in our list of tasks.

> Informal proposal
> To define an elemental procedure, the subroutine or function statement 
> is prefixed with the new keyword 'ELEMENTAL', e.g.:
> 	ELEMENTAL SUBROUTINE S (X)
>	ELEMENTAL REAL FUNCTION F (X)

Fortran 8x contained, at one time, a facility for user-defined, elemental
procedures.  If HPF is to have this feature, we should review old drafts
of Fortran 8x to get the benefit of earlier thinking on the matter.

> Incidentally, I've chosen not to insist that the dummy arguments and 
> result are scalar---that's another extension to the F90 definition!  

The overloading device covers this extension.

> For a function to be valid for use as an elemental function, it must 
> obey the following constraints:
>	1. Its arguments must have intent '(IN)'.
>	2. Local arrays cannot be SAVEd.
>	3. It cannot define any global variable.
>	4. Its arguments, result and local variables must not be distributed.
>	5. It can only reference a global variable if it is *not distributed*.

I like constraints 1-3 (plus the prohibition of i/o, which John mentions
later is his proposal).  I don't see the need for contraint 4.  (Does "local
variable" mean dummy argument?)  Elemental functions operate locally on
arrays.  The result has the same shape as the arguments.  As long as the
argument and result arrays all have the same distribution, this seems a
perfect opportunity for parallel computation on distributed arrays.

Constraint 5 applies no more strongly to elemental functions than to ordinary
ones.  A computation will be more efficient when a function executes on the
processor whose fastest-access memory contains the data the function refers
to.  When the data resides elsewhere, the computation takes a performance hit.
Programmers wishing to avoid this will express themselves in some other way.

> These functions can also be used in a FORALL.  Because a 'forall-assignment'
> may be an 'array-assignment' (in most definitions anyway) the elemental
> function can have an array result.
>  ...
>
>	REAL  v (3,10,10)
>	INTERFACE
>	  ELEMENTAL FUNCTION f (x)
>	    REAL, DIMENSION(3) :: f, x
>	  END FUNCTION f
>	END INTERFACE
>	...
>	FORALL (i=1:10, j=1:10)  v(:,i,j) = f (v(:,i,j)) 

The invocation of f in the preceding FORALL is an ordinary invocation.
For this, f need not be elemental.

If f were invoked as    v=f(v)   then it would need to be elemental.
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.

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

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?

> 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.  

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.

> In addition, the implementation of an elemental function array in an
> array expression is likely to be more efficient than that of an 
> equivalent array function.  One reason is that it requires less temporary
> storage for the result ... .  Another is that it saves on looping ... .
> ... the elemental function can be invoked elementally in situ within
> the expression.

True, the ELEMENTAL designation provides more specific information to the
processor.  It raises the level of communication possible in the language.
This is a good argument for adding syntax.  It sways me, for one, but not
quite enough to support the idea.

  -  Rex Page

---

From: [email-masked] (James Cownie)
Date: Mon, 29 Jun 92 16:51:40 BST

> perfect opportunity for parallel computation on distributed arrays.

The local variables of a function are the ones which are declared
inside the function, and are not visible outside it. (In most
recursive languages they are declared on the stack). Rather different
from the dummy arguments.

> Programmers wishing to avoid this will express themselves in some other way.

Quite right !

I think John is trying to achieve two separate effects here (since
he's away I think I can say this without fear of immediate
contradiction !)

1) To insist that the functions are "mathematical" in that they always
produce the same results when called with the same arguments, and have
no side effects. Rules 1,2,3 and "no I/O" are intended to achieve this.
(This is required to allow them in the context of FORALL, where the
order of evaluation of the function calls is explicitly not
specified). This is the major attribute of their being elemental, the
ability to deal with arguments of different rank is syntactical sugar
which makes sense because of the underlying property.

2) To ensure that all data references made by the function can be
achieved locally. (Rules four and five are trying to achieve this)

Point 1) is important if we're not throwing away a semantic
specification of what happens inside the FORALL.

Point 2) is "solely an implementation issue" :-). John wants it
because he wants a run-time which doesn't require demand driven
communication. It is easy to construct elemental functions which
access non-local data.  (Ignoring John's rules 4 and 5 for now)
e.g.
	REAL ELEMENTAL FUNCTION REMOTE (X)
	REAL X
	REAL Y(1000)
	COMMON /FOO/Y   ! Assuming Y can be distributed, add
			! appropriate MODULE if required 
CHPF$   TEMPLATE T(1000)
CHPF$   ALIGN Y WITH T
CHPF$   PROCESSORS P(10)
CHPF$   DISTRIBUTE T BLOCK ONTO P

 	REMOTE = Y(INT(ABS(X))

	END

C Some call of this
	REAL Z(1000),BAH(1000)	
	FORALL(I = 1:1000)
	   BAH(I) = REMOTE(Z(I))
	ENDFORALL

This function is definitely elemental, but will also require an
arbitrary communication pattern (which depends on the values in the
actuals), when the 1000 instances are called on the 10 processors. In
particular there is no knowledge local to any particular processor
that its values of Y will be required by any instance of the
subroutine. To implement this (in parallel) one needs demand
driven communication, so either a send receive model with a remote
store access daemon, or a direct (unsynchronised) remote read, remote
write model.

It is actually unclear that there is any easy way of making the
restrictions John wants visible in hpf, since "every array is create
with an alignment to some template, and every template is created
with some distribution onto some arrangement of processors."
Therefore my example would stand EVEN without any explicit mapping
statements for the global data.

In summary :-

Beware of confusing the semantic requirement of ELEMENTALITY with the
(MIMD) implementation issue of local access.

--Jim
James Cownie 
Meiko Limited
650 Aztec West
Bristol BS12 4SD
England

Phone : +44 454 616171
FAX   : +44 454 618188
E-Mail: [email-masked] or [email-masked]