Subject: Forall

From: [email-masked] (Min-You Wu)
Date: Mon, 22 Jun 92 15:46:39 EDT

Some of my comments on Marc's proposal and Chuck and Alok's comments.

> Worm 3:
> The principle of least astonishment may need invocation here.  One
> interesting consequence of Marc's proposal is that this is legal:
> 	FORALL ( I = 1:N )
> 	  IF ( N > 1 ) THEN
> 	    A(I) = 1.0
> 	  END IF
> 	END FORALL
> but this is not legal:
> 	FORALL ( I = 1:N )
> 	  IF ( N > I ) THEN
> 	    A(I) = 1.0
> 	  END IF
> 	END FORALL
> (Look carefully at the IF condition...  Marc does not allow the FORALL
> index to be referenced in any statement except forall-assignments.)
> The intent (I assume) is to force all iterations, and thus all
> processors, down the same path at all branch points, and that sure
> makes FORALL easier to define.  But it will make some useful
> computations difficult to code:
> 	Iterating to convergence on each point of a grid
> 	Conditional assignment to points on a grid
> 	Having different formulas for different grid points
> 	Guy Steele's ragged array example (ALLOCATE different-sized blocks)
> 	Nested triangular loops or triangular FORALLs
> 	Boundary conditions
> (Some of these limitations are solved by the WHERE construct.)
> Question for users: Are you willing to live with these restrictions?
> -- Chuck

We can allow FORALL index in the IF statement, as long as the user
can ensure there is no dependence between FORALL instances.
It there is a dependence, we have to define the semantics first
(IF-THEN and ELSE executed in order or simultaneously).

> Worm 4:
> If the statements in the forall-block can be arbitrary, we have to
> define semantics for
> 	FORALL ( I = 1:N )
> 	    CALL FOO( A )	! How many times is FOO called?
> 				! Scalarization says 1, users will say N
> 	    OPEN(5,FILE='BAR')	! Parallel I/O, here we come
> 	    READ (5) B(1:100)
> 	    			! READ (5) B(I) is illegal, though
> 	    WRITE (5) C(1:5)
> 	    			! WRITE (5) C(I) is illegal
> 	    CLOSE (5)
> 	END FORALL
> (Interestingly, I don't see any trouble from GOTO or STOP, since all
> iterations must follow the same control flow.)  There may be other
> problematic Fortran statements.
> -- Chuck

I agree that in this FORALL, FOO is called N times.  It can be solved
by using a different function:
       FORALL ( I = 1:N )
           CALL foo( a(I) )

> Overall, I think the proposal went too far in generalizing the FORALL.
> I'll make the following modest (and informal) counterproposal:
> 	Only "generalized assignment statements" (GASes) are allowed
> 	in a FORALL body.
> 	The following statements are GASes - assignment, WHERE,
> 	FORALL.
> 	Use Marc's semantics for interpreting GASes (no object
> 	assigned twice by one statement, assignments executed once for
> 	each element of the index space, GASes executed in sequence).
> 	I think that Marc's proposal still disallows triangular
> 	FORALLs; I propose lifting this restriction.
> If there's interest, I'll write this up more formally.
> 
> 
> 	Chuck
> 	
>A {\it forall-block} can be an arbitrary sequence of executable constructs,
>treated as a unit (R801).  It can also contain {forall-assignment}'s.
> -- Marc

My understanding is, in Marc's proposal, besides of GASes, all other 
statements follow the same flow.  The good thing is that ARBITRARY sequence 
of statements is allowed, but these statements can only follow the same
control flow.  Moreover, it is not clear that those statements should be 
scalar or not.  For example, the statements
       FORALL(I=1:N, J=1:N, I.NE.J)
          IF(COND)
             THEN A(I,J) = I+J
             ELSE A(I,J) = I-J
          END IF
       END FORALL
and 
       FORALL(I=1:N)
          WHERE(MOD(I,2)=0)
              A(I) = 0
          ELSEWHERE
              A(I) = A(I-1)
          END WHERE
       END FORALL
are scalar, and this statement
       FORALL ( I = 1:N )
           CALL FOO( A )
       END FORALL
is not scalar.

>  I do not see a need for a WHERE inside a Forall if "IF" statement
>is allowed
>
> Anyway, I am not sure if WHERE Construct allows MASKS to be specified
>the way they have been used in Marc's proposal. I looked up
>the F90 documents, but did not find anything explicitly prohibiting it,
>nor did I ever find an example using it also.
>
> For example, the following illustration used in Marc's proposal
>uses MOD(I,2) inside the WHERE Mask Expression. I am not sure
>if it is allowed.
>
>PLEASE CHECK.
>
>FORALL(I=1:N)
>   WHERE(MOD(I,2)=0)
>       A(I) = 0
>   ELSEWHERE
>       A(I) = A(I-1)
>    END WHERE
>END FORALL
>
> -- Alok

Alok, I think Marc uses IF for a uniform flow but WHERE allows
different conditions applied to different grid points.  
However, Marc's WHERE in FORALL is not consistent with that
outside of FORALL.  So if it is necessary, I suggest a different
name should be used to avoid confusion.

Min-You Wu

---

From: [email-masked]
Date: Mon, 22 Jun 92 15:38:01 -0500

> Date: Mon, 22 Jun 92 15:46:39 EDT
> From: [email-masked] (Min-You Wu)
> Subject: Forall
> 
> 

Which of the following are you advocating?
    1. IF-THEN-ELSE is allowed in a FORALL, but it is the user's
	responsibility to ensure that array elements assigned in the THEN
	branch are not referenced in the ELSE branch on another iteration.
    2. IF-THEN-ELSE is allowed in a FORALL, and assignments made in
	the THEN branch are visible in the ELSE branch of another
	iteration (i.e. WHERE semantics).
    3. IF-THEN-ELSE is allowed in a FORALL, and the effect of an
	assignment in one branch to an element used in the other
	branch on another iteration is undefined (i.e. asynchronous
	semantics).
    4. IF-THEN-ELSE is allowed in a FORALL, and references made in
	either branch always refer to array values that were current before
	the IF or assigned in the same branch (almost Fortran D
	semantics, but not quite).
    5. Something else.  (If you choose this one, please tell us what
	you have in mind! :-)

> by using a different function:

Now I'm confused.  Why should changing the function's argument change
the number of times it is called?

Let me say that I'm in favor a semantics that would call FOO N times.
It's not the semantics that Marc defined, however.  We need to
    1. Allow the CALL to reference FORALL indices. (Otherwise the
	subroutine is called with the same arguments every time; not
	efficient!)
    2. Define some restrictions on FOO to either disallow dependences
	between iterations, or define the behavior when dependences
	occur.
Part 1 is easy, part 2 is hard.  It's things like this that led me to
propose the very restricted block FORALL.  Anybody willing to put in
the time to define these semantics is welcome to, and I'll support
more general proposals if they look reasonable.

> are scalar, and this statement

Please define what you mean by "scalar" in this context.  In Fortran
90, "scalar" is a noun meaning roughly "a data object that is not an
array."

> >the way they have been used in Marc's proposal. ...
> 

As I argued before, Marc's proposal extends WHERE in a natural way.
If you're saying that there is a case in Marc's semantics in which a
vector WHERE statement has a different meaning than in standard
Fortran 90, then please show us an example.  (That would be grounds
for modifying the treatment of WHERE or throwing it out entirely,
depending on how hard it was to fix.)  If you are against extending
WHERE for some reason, then say that.

I'm against adding any new statement except for FORALL.  If Marc's
WHERE is different from Fortran 90 WHERE (except for extending the
domain), then we should fix or abandon it.

	Chuck