Subject: Re: comments on FORALL draft

From: [email-masked]
Date: Thu, 15 Oct 1992 19:20:20 -0600

Will incorporate your suggestions, except as noted below.

At 20:04 10/15/92 +0000, John Merlin wrote:
>
>-----------------------
>>                                                                        \BNF
>> forall-assignment    \IS array-element = expr
>>                      \OR array-element => target
>>                      \OR array-section = expr
>>                                                                        \FNB
>
>Rather than introduce the new grammar symbol 'forall-assignment'
>(which should be 'forall-assignment-stmt' anyway) I wonder if it 
>wouldn't be better just to use the existing F90 grammar symbols 
>'assignment-stmt' and 'pointer-assignment-stmt', along with constraints 
>that the 'variable' or 'pointer-object' must be subscripted, etc. etc.  
>That's the way that F90 handles the assignments in a 'where-stmt' and 
>'where-construct'.

A more radical suggestion occurs to me: 

Constraint: The variable of an assignment-stmt must refer to distinct data
objects for all active combinations of subcript-name values.

Constraint: The pointer-object of a pointer-assignment-stmt must refer to
distinct data objects for all active combinations of subscript-name values.

Someone with a good cross-reference into the F90 standard check whether
"refer to distinct data objects" are the right words - my intent is that
the objects (or subobjects, like array sections) named on the left-hand
sides should be disjoint (nonoverlapping) sections of memory.

Reasoning - John's right that I was picking the wrong syntactic categories.
 This is an attempt to make the condition as general as possible, and tie
it to behavior rather than syntax.  For example, if we wanted to define
PRIVATE variables within the scope of nested FORALLs (JUST AN EXAMPLE, NOT
A PROPOSAL!), then presumably the variable would refer to a different
object for each "iteration" - and the condition allows that.  On the other
hand, a normal scalar certainly does not refer to different objects for
different FORALL indices and thus is disallowed on the left-hand side.

>(Actually, I'm not convinced that pointer assignment should be here at 
>all, since it has such limited use and probably very limited scope for
>concurrency).

Why didn't you say so earlier?  Your vote might have carried the election
(which was tied 0-0 going into the last meeting)!  Sorry, it's political
season here in the states...

>
>> For each subscript name in the {\it forall-assignment}, the set of
>> permitted values is determined on entry to the statement and is
>> \[  m1 + (k-1) * m3, where~k = 1, 2, ..., \lfloor \frac{m2 - m1 +
>> 1}{m3} \rfloor  \]
>> and where {\it m1}, {\it m2}, and {\it m3} are the values of the first
>> subscript, the second subscript, and the stride respectively in the
>> {\it forall-triplet-spec}.  If {\it stride} is missing, it is as if it
>> were present with a value of the integer 1.  The expression {\it
>> stride} must not have the value 0.  If for some subscript name 
>> \(\lfloor (m2 -m1 + 1) / m3 \rfloor \leq 0\), the {\it
>> forall-assignment} is not executed.
>
>I believe the expression should be:
>
>        \lfloor (m2 -m1 + m3) / m3 \rfloor
>not
>        \lfloor (m2 -m1 + 1) / m3 \rfloor

How did this make it through 3 drafts before someone caught it?
      
>> \subsection{Scalarization of the FORALL Statement}
>
>In the scalarisation of the 'forall-stmt', it's claimed that:
>
>> !               ... (it is safe to avoid saving the subscript 
>> !expressions because of the conditions on FORALL expressions)
>
>but I thought that the following was allowed:
>
>        FORALL (I=...)  J(J(I)) = ...
>
>If so, then the subscript expressions must be saved.

Correct; I oversimplified when side effects were eliminated.

>Also, if all functions in FORALL must be pure then a big simplification 
>is possible, since the 'mask', 'rhs' and the subscript expressions can all 
>be evaluated concurrently (except that for a given index, 'mask' must 
>precede 'rhs' and 'e1,..,em').  This is because all expressions are 
>guaranteed side-effect free; the only 'side-effect' of a forall is 
>actually performing the assignment.

Also correct.

However, the bounds and stride expressions must be evaluated first in any
case, since evaluation of the mask, rhs, and subscripts depends on them
(unless you can explain how to fill in an array section without knowing its
bounds?).  I'll therefore use the temporaries in the scalarization instead
of the actual expressions.

>> \subsection{General Form of the FORALL Construct}
>
>contains the constraint:
>
>> Constraint: If a {\it forall-stmt} or {\it forall-construct} is nested 
>> within a {\it forall-construct}, then the inner FORALL may not redefine 
>> any {\it subscript-name} used in the outer {\it forall-construct}.
>> This rule applies recursively in the event of multiple nesting levels.
>
>If functions in FORALL are pure and side-effect free, then I think
>this constraint is redundant; the only 'side-effects' of the inner
>FORALL are assignment to array elements, so the 'subscript-name's
>cannot be redefined.

The constraint was there to disallow
        FORALL ( i = 1 : n )
            FORALL ( i = 2 : m )
                A(i) = 0.0
            END FORALL
        END FORALL

                                                Chuck

---

From: "Rex Page" <[email-masked]>
Date: Fri, 16 Oct 92 10:23:06 -0500

> sides should be disjoint (nonoverlapping) sections of memory.

I would regard A(1:10) and A(2:10) as distinct data objects, but they
have some subobjects in common.  This, unfortunately, complicates the
wording of the first constraint.

Something like the following might work:

  Constraint: Variables defined in an assignment statement corresponding
  to different active values of subscript names from the forall triplet
  specification must be distinct and must have no subobjects in common.

(Note: The phrase "must be distinct and" is redundant, strictly speaking.)

The problem doesn't come up with pointer objects in pointer assignment
statements because they must be scalars of type POINTER, and such scalars
have no subobjects.  So, the constraint on pointer assignments is ok as
written.  Still, it might be a good idea to be clear about what pointer
object in the pointer assignment is being restricted.  (The target of the
assignment can also be a pointer object, but targets need not be distinct.)

Something like this, perhaps:

  Constraint:  Pointer objects defined in a pointer assignment statement
  corresponding to different active values of subscript names from the
  forall triplet specification must be distinct.

Rex Page