Print

Print


At 11:34 AM 3/5/2003 +0100, Roland Schilling wrote:
>I have the following problems with the FORALL statement:
>
>FORALL allows, optionally, a scalar logical expression as
>the last argument, similar to, e.g., SUM.  But with SUM
>this optional argument has the name MASK; not so with FORALL.
>Why?  This seems to be inconsistent to me.
>
>Furthermore, and much more important, when calling SUM from
>inside a subroutine that has an optional argument MASK, I can
>simply write
>
>     S = SUM(ARRAY, DIM, MASK)
>
>without checking for the presence of MASK, as I can do with
>any nested, user-written routines using optional arguments.
>But not so in the case of FORALL!  Here I get a run-time error
>(at least with the two compilers I have available) when I use
>FORALL with the logical expression, and this logical expression
>is not present.  This is quite annoying and not understandable
>to me.

The cases are quite different:

In any non-trivial case, MASK is an array that is either present or
not.  If you pass MASK _as_a_whole_ to another optional argument, you can
have "pass through" optionality, but as soon as you attach any kind of
subscript to MASK, MASK is required to be present, and you are identifying
part of that array that is present.

As you noted, FORALL takes a _scalar_ expression, not an array, and that
expression is evaluated for each combination of index values to determine
whether the body of the FORALL is executed for that combination of index
values.  You can't put MASK there (because it is an array, not scalar), so
instead you have to put something like MASK(I,J) and as I noted in the
previous paragraph, once you add the subscript, the language _consistently_
requires MASK to be present.

In some sense, what you would like to be able to do is make the expression
MERGE(MASK(I,J),.TRUE.,PRESENT(MASK)), but that isn't legal either, because
conceptually MASK(I,J) is evaluated even if PRESENT(MASK) is false.

 From a performance perspective, you are probably better off with something
like
IF(PRESENT(MASK)) THEN
    FORALL(..., MASK(I,J)) ....
ELSE
    FORALL(...) ...
END IF
because redundantly testing whether MASK is PRESENT for every index
combination is likely to have a significant performance cost.

--
Kurt W Hirchert                                  [log in to unmask]
UIUC Department of Atmospheric Sciences                  +1-217-265-0327