Subject: hpff-interpret: Wording change for RANGE

From: [email-masked] (Carl Offner)
Date: Tue, 2 Jul 1996 11:06:26 -0400

---------------------------------------------------------------------------
[email-masked] is a mailing list for corrections,
clarifications, and interpretations related to High Performance Fortran.
Instructions for adding or deleting yourself from this list appear at the
bottom of this message.
---------------------------------------------------------------------------

                 ************************************
                 *                                  *
                 *  Re-Wording the RANGE Directive  *
                 *                                  *
                 ************************************

                            Carl D. Offner
                    Digital Equipment Corporation
                        [email-masked]

                          *****************
                          Executive Summary
                          *****************

The RANGE directive, as currently specified, contains a serious
weakness that makes it virtually useless for a compiler and
counter-intuitive for a programmer.  This re-wording restores the
original intent.

                       ************************
                       Proposal for re-wording:
                       ************************

Replace lines 36-44 (lines 3-10 in the draft document; i.e., the
following lines)

-----------------------------------------------------------------------

  If a ranger is given the RANGE attribute, every range-attr in at
  least one of the range-attr-stuffs must be compatible with the
  distribution format of the corresponding dimension of the

    1. template of the ranger, if the ranger is transcriptively
    distributed;

    2. target of the ranger, if the ranger has the POINTER
    attribute, and is associated; or

    3. ranger, if the ranger has the DYNAMIC attribute.

-----------------------------------------------------------------------

with the following two paragraphs:

-----------------------------------------------------------------------

  Since the length of each range-attr-list is the same as the rank of
  the ranger, each range-attr R in each range-attr-stuff corresponds
  positionally to a dimension D of the ranger.  This dimension D in
  turn corresponds (though in general, not positionally) to an axis A
  of the template with which the ranger is ultimately aligned.

  With this notation, a RANGE attribute on a ranger is equivalent to
  the following constraint:

    For at least one range-attr-stuff in the range-attr-stuff-list,
    every range-attr R must be compatible with the distribution
    format of the corresponding axis A.

-----------------------------------------------------------------------

                             ***********
                             Discussion:
                             ***********

This was actually my understanding of the meaning of the RANGE
attribute when I originally proposed something similar to this in
Group D.  The point was this: in the presence of the new distributions
(generalized block, indirect mapping), it is quite significant for the
compiler to know that the ultimate align target of an argument or a
pointer is or is not distributed generalized block, for instance.  (It
is also good to be able to distinguish between BLOCK and CYCLIC, but
distinguishing between generalized block and other mappings is even
more important.)

The precise alignment of the object with its template, on the other
hand, is nice to know at compile time, but is not nearly so important
in terms of generating efficient code.

So we need a syntactic device enabling the user to specify a range of
possible distributions, leaving open the associated alignment.  This
proposal would do that.

In addition, it should be noted that without this facility, an
explicitly mapped pointer could not be used to point to an array
section.  My understanding is that one of the main uses of pointers
is to give names to array sections.

                          ******************
                          Example:  Pointers
                          ******************

REAL, DIMENSION(:), POINTER :: A
!HPF$ RANGE A (BLOCK)

This now means that A is a pointer that can be used to
point to (a section of) a block-distributed array.  For instance,

A => B(1:307:3)

where B is distributed BLOCK.  Without the rewording suggested above,
such a pointer assignment would be impossible.

             ********************************************
             Example:  Dummies with the INHERIT attribute
             ********************************************
                                   
The discussion here is a bit subtle.  Consider first of all the
following fragment:

-----------------------------------------------------------

module sub_mod
contains

  subroutine sub(d)
  dimension(:,:) :: d
  !hpf$ inherit d

   ...

  end subroutine
end module

program main
use sub_mod

real, dimension(100,100,100) :: a
!hpf$ distribute(block,*,cyclic) :: a

call sub(a(:,:,1))
call sub(a(:,1,:))
call sub(a(1,:,:))

end

-----------------------------------------------------------

If the dummy d in the subroutine sub is constrained by the directive

  !hpf$ range d (block,cyclic)

then only the second call is legal.  However, all three calls could
be made legal, even with a RANGE directive, as follows:

  !hpf$ range d (cyclic(),cyclic()), (*,cyclic()), (cyclic(),*)

                       ************************
                       What is the alternative?
                       ************************

An alternative interpretation of RANGE (which is explicitly rejected
in this proposal) would be to say, in the case of a dummy with the
INHERIT attribute, that the the range-dist-attr-list must refer to the
entire template with which the actual is ultimately aligned.

This would be similar to the current meaning of a DISTRIBUTE directive
applied to a dummy with the INHERIT attribute; Carol Munroe has a
proposal pointing out similar problems with that usage and suggesting
it be done away with.

Under this alternative interpretation, the only allowable RANGE
directive in this case would be

  !hpf$ range d (block, *, cyclic)

or something subsuming this, such as

  !hpf$ range d (cyclic(), *, cyclic())

However, this gives the compiler very little useful information -- in
fact, the only real information it gives the compiler is the rank of
the template with which the actual is ultimately aligned.

The situation is far worse if we allow some of the new distributions
that are approved extensions.  For instance, suppose the example is
modified as follows:

-----------------------------------------------------------

module sub_mod
contains

  subroutine sub(d)
  dimension(:,:) :: d
  !hpf$ inherit d

   ...

  end subroutine
end module

program main
use sub_mod

real, dimension(100,100,100) :: a
!hpf$ distribute(gen_block(extents), cyclic, indirect(map)) :: a

call sub(a(:,:,1))
call sub(a(:,1,:))
call sub(a(1,:,:))

end

-----------------------------------------------------------

In this case, the only RANGE directive that would be allowable under
this proposal (that makes all three calls legal) would be

  !hpf$ range d (all, all)

It might seem that the alternative interpretation, under which one
could write

  !hpf$ range d (gen_block, cyclic, indirect)

would give more information.  But actually, it does not, because the
compiler has no way of knowing which dimension of the dummy has which
distribution.  I believe that the directive should be construed in
such a way that it gives the compiler as much meaningful information
as possible.

  ---------------------------------------------------------------------

  Aside: For the Digital compiler, it is quite important to know (i.e.,
  at compile-time) whether the distribution of the template axis
  corresponding to each dummy axis is

        a) in the cyclic(n) family
        (i.e., block, cyclic, block(n), cyclic(n), or *), or

        b) generalized block, or

        c) an indirect map.

  It would even be nice to know in case (a) whether the mapping was
  actually block or cyclic, for instance.  This, however, is a secondary
  consideration, although one that the language proposed here also
  handles.

  It is fair to say that without this information, the quality of the
  generated code will be compromised.  Given this information, the
  compiler generates quite different loop structures and addressing
  expressions.  Without this information, all the work must be left to
  run-time routines, and we end up with more of an interpreted language
  than a compiled one.

  Other compilers may well have different requirements, but the
  general idea is probably similar---more information is better.

  ---------------------------------------------------------------------

In addition, the proposal presented here is much more in line with
what a programmer would naturally expect.  In fact, the already stated
constraint on line 33 (line 48 of the previous page in the draft
document)

  Constraint:  The length of any range-attr-list must equal the rank
               of the ranger.

is compatible ONLY with the new wording suggested here; this supports
the contention that this interpretation is what programmers will
undoubtedly expect.

In summary, I believe that this alternative interpretation has the
following defects:

  *  It is nearly useless for the compiler:  it does not give the
     compiler information that it really needs to know and could make
     good use of.

  *  It will make it much more difficult to support the generalized
     block and indirect mapping extensions.

  *  It is counter-intuitive for programmers.

  *  It will most likely lead to the RANGE directive being ignored by
     actual implementations; this in turn will probably be regarded,
     incorrectly, as some sort of a bug by programmers who will then
     have to be educated by the vendors on the curious meaning of this
     syntax.
---------------------------------------------------------------------------
To (un)subscribe to this list, send mail to
[email-masked].
Leave the subject line blank, and in the body put the line
(un)subscribe <email-address>
---------------------------------------------------------------------------