Subject: hpff-core: active cci

From: Mary E Zosel <[email-masked]>
Date: Wed, 3 Jul 1996 16:48:11 -0700 (PDT)

---------------------------------------------------------------------------
[email-masked] is a mailing list for announcements related to High
Performance Fortran.  Instructions for adding or deleting yourself
from this list appear at the bottom of this message.
---------------------------------------------------------------------------
For the July 96 HPFF Meeting

Here's the handfull of active CCI items.
   -mz-

================================
Subgroup C
================================
60	Global name HPF_LIBRARY
	Group C
hennecke	[email-masked]		
status: new	

Question:
HPF v1.1, section 5, [91:18+] says
  "HPF defines a library module, HPF_LIBRARY, 
   that must be provided by vendors of any full HPF implementation."

Fortran 90, sections 14.1.1, say that 
  "Program units ... are global entities of an executable program.
   A name that identifies a global entity must not be used to identify
   any other global entity in the same executable program."
Modules are program units (Fortran 90, section 2.2).

Question 1:
Is it valid full-HPF to use the name HPF_LIBRARY as a global name in an
HPF program (other than in a USE stmt), e.g. as the name of an external
procedure or even a user-defined module?

Question 2:
If the answer to 1 is YES and the program contains a <module> with
name HPF_LIBRARY: to which module is a USE HPF_LIBRARY statement 
resolved - the user module or the "intrinsic" module?

Thanks,
Michael

---------

Discussion:

	none

================================

56	Interpretation of HPF_TEMPLATE library routine	
Group C
Whaley	[email-masked]	3/20/96	
status: new	
Question:

Hi,

I'm looking at "High Performance Fortran Language Specification", May 3, 1993
Version 1.0.

Under the description of HPF_TEMPLATE, is the following wording:

... HPF_TEMPLATE returns information concerning the variable from the template's point of view (assuming the alignment is to a template rather than an array) ...

My understanding of this routine is that it can give information about any ALIGNEE, even those not ultimately aligned to an !HPF$ TEMPLATE.  Rather, I interpret this to reference to be to the more general definition of template, "an index space".  Can you tell me if this is correct?  If so, it might be helpful to disambiguate the above sentence . . .

Thanks,
Clint

DIscussion:
	No record of answer to this

================================
Subgroup D
================================

59		
Group D
zongaro	[email-masked]	6/26/96	
status: new	     
Question:
According to Section 3.10 of the HPF Language Spec.,
         If there is an explicit interface for the called subprogram
         and that interface contains mapping directives (whether
         prescriptive or descriptive) for the dummy argument in
         question, the actual argument will be remapped if necessary
         to conform to the directives in the explicit interface.
     However, it does not state what should happen if there is an explicit
interface that does not contain explicit mapping directives.  I always took it
to mean that the mapping would be determined by the called procedure, just as
it would be for procedures with implicit interfaces, rather than happening on
the calling side.
     For example, my understanding is that the calls to sub1 and sub2 would
be permitted, but not the call to sub3, just as the calls would be permitted
if sub1, sub2 and sub3 had implicit interfaces in prog.
         program prog
           interface
             subroutine sub1(a)
               integer :: a(:)
             end subroutine sub1
             subroutine sub2(a)
               integer :: a(:)
             end subroutine sub2
             subroutine sub3(a)
               integer :: a(:)
             end subroutine sub3
           end interface
           integer :: a(100)
   !hpf$   processors proc(number_of_processors())
   !hpf$   distribute a(block) onto proc
           call sub1(a)
           call sub2(a)
           call sub3(a)
         end program prog
         subroutine sub1(a)
           integer :: a(:)
   !hpf$   processors proc(number_of_processors())
   !hpf$   distribute a(cyclic) onto proc
         end subroutine sub1
         subroutine sub2(a)
           integer :: a(:)
   !hpf$   processors proc(number_of_processors())
   !hpf$   distribute a*(block) onto *proc
         end subroutine sub2
         subroutine sub3(a)
           integer :: a(:)
   !hpf$   processors proc(number_of_processors())
   !hpf$   distribute a*(cyclic) onto *proc
         end subroutine sub3
     Do others have a different understanding of how this operates?
Thanks,  Henry

Lengthy discussion:

----- Carol replies:  Hi Henry,
The following is my understanding of this example.
I believe that the point of the explicit interface is to reconcile any
possible discrepancy in mappings between the actual argument and the dummy
argument, so that any remapping can always be done by the caller. The
intention was also to remove the distinction between prescriptive and
descriptive directives.  It was not intended to prevent the callee from 
doing it, but by not removing the old syntactic distinction between
prescriptive and descriptive directives, some ambiguity may remain. I
believe that if a full interface is included, showing a discrepancy between
the actual argument's mapping and an incompatible descriptive mapping for
the dummy argument, the caller is apparently expected to make the remapping happen anyway. So with an explicit interface, the call to sub3 is correct. (cont.)	(cont.)  In particular, the lack of explicit mapping directives in the interface for
sub1 means that there is no guarantee that the remapping will be done
(since the caller doesn't see the need). The programmer is therefore taking
a change by relying on the (no longer significant) "prescriptive" form of
the directives in sub1.
    With sub2, the default mapping behavior of the compiler may or may not be
nonsequential, block-distributed onto proc(number_of_processors()), so
again there could be a failure.
    With sub3, again, the lack of an interface means that the caller 
does not remap as needed, so there will be a programmer's error.
With an interface, the remapping would be done.  --Carol
------- and Carl replies:  On Henry's example - 
I would say that all three interfaces are non-conforming because the
interfaces do not reflect the mappings.  There are, to be sure,
instances in which an interface would not be required -- sub2 is
an example -- but if an interface is present, it should correctly
reflect the mapping of all explicitly mapped arguments.
    Now I don't actually see that the HPF spec says precisely this.
However, it was certainly the understanding behind the explicit
interface proposal.  After all, what is the point in requiring an
explicit interface if the explicit interface does not have to describe
the mappings?  So maybe (unless some language lawyer can convince us
all that this is already in the spec) we should add a sentence to this
effect.  Presumably this would be something like specifying that
the mapping of a dummy argument is a "characteristic" of that
argument, in the terminology of the Fortran standard.
     Again, I assume that this is nothing really new, just a clarification.   --Carl
----------- and Dave Watson addes:I believe Carl has hit the nail on the head. Alignment/Distribution of a dummy
SHOULD be a characteristic. With this statement the distinction between
prescriptive and descriptive mappings in HPF-1.x becomes redundant naturally
since an interface must be present for any mapped object and remapping
must be performed if the interface is present for a descriptive mapping.
It seems to me to be both logical and in the spirit of F90/F95 that mapping
should be a characteristic. After all, F90 requires an interface if TARGET is 
specified for a dummy but HPF does not (currently) require that a compiler
is informed that an argument is/is not distributed and if so how! I believe 
the current position within HPF-2 to be that an interface is required if there
is remapping of the actual and not otherwise. From this I would concur that 
all 3 interfaces are non-conforming. However, I think that HPF-2 should be 
explicit and state that hpf directives applied to dummy arguments are 
characteristics of the dummy. Consider the following :
            integer :: a(10),b(10)
    !hpf$   distribute a(block)
    !hpf$   distribute b(cyclic)
            call external_sub(a)  $   call external_sub(b)          
A compiler would be justified in rejecting this program since it can prove 
that either or both interfaces cause remapping but no interface is present. If
we add an interface both calls become legal. By the absence of a specified 
interface the compiler can infer the f77 interface and thus that the arguments
need to be remapped to the default mapping the compiler uses when no mapping  is specified.
            integer :: a(10),b(10)
    !hpf$   distribute a(block)
    !hpf$   distribute b(cyclic)
            interface
              subroutine external_sub(x)
                integer :: external_x(*)
              end subroutine sub
            end interface
            call external_sub(a) $  call external_sub(b)
   I strongly support the notion that mapping is a characteristic of a dummy and
hence that interfaces are required for all procedures with mapped arguments. 

================================

50	implicit remapping	
Group D
Zongaro	[email-masked]	2/8/96	
status: in progress	     
Question:
The much-beloved section 3.10 of the HPF Language Spec. states (in part)
on page 54 that
      The rules on the interaction of the REALIGN and REDISTRIBUTE directives
      with a subprogram argument interface are:
      1. . . . .
      2. If an array or any section thereof is accessible by two or more paths,
         it is not HPF-conforming to remap it through any of those paths. . . .
         In general, in any situation where assignment to a variable would be
         nonconforming by reason of aliasing, remapping of that variable by an
         explicit REALIGN or REDISTRIBUTE directive is also forbidden.
     These rules deal explicitly with REALIGN and REDISTRIBUTE, but not with
some other situations in which aliasing might occur.  For example, is the
following a conforming program?  Here 'a' is remapped on becoming associated
with 'x'.  Can an element of 'a' then be referenced in sub?  If I had a call
to HPF_DISTRIBUTION passing 'a', what would be the AXIS_TYPE?
      program p
        integer :: a(100) = 1
!hpf$   distribute a(block)
        call sub(a)
      contains
        subroutine sub(x)
          integer x(100)
!hpf$     distribute x*(cyclic)
          i = a(1)
        end subroutine sub
      end program p
How about the following?  'a' is remapped when it becomes associated with 'x' -
can 'a' then be passed to sub2, which would require remapping as well?  Given
that REALIGN and REDISTRIBUTE are prohibited, my guess is that this would be prohibited as well.
      program p
        integer :: a(100) = 1
!hpf$   distribute a(block)
        call sub(a)
      contains
        subroutine sub(x)
          integer x(100)
!hpf$     distribute x*(cyclic)
          call sub2(a)
        end subroutine sub
        subroutine sub2(y)
          integer y(100)
!hpf$     distribute y*(*)
        end subroutine sub2
      end program p
How about this one?  Here, the same actual argument is associated with two
different dummy arguments, each of which requires a different mapping from the actual.
      program p
        integer :: a(10, 10) = 1
!hpf$   distribute a(block, block)
        call sub(a, a)
      contains
        subroutine sub(x, y)
          integer x(10, 10), y(10, 10)
!hpf$     distribute x*(cyclic, block)
!hpf$     distribute y*(block, cyclic)
          print *, x, y
        end subroutine sub
      end program p
If the mapping of 'x' had been the same as that of 'a', would the third example
then be conforming?
Thanks,  Henry	discussion:  FROM MARCH 96 Meeting:  CCI 50:  Legal F90!
program p
   integer a(100), b(10,10)
!HPF$ DISTRIBUTE a(block), b((block,block)
    call sub1 (a,b,b)
contains
   subroutine sub1(x1,x2,x3)
   integer x1(100), x2(10,10), x3(10,10)
!HPF$ DISTRIBUTE x1 *(cyclic)
!HPF$ DISTRIBUTE x2 *(block,cyclic)
!HPF$ DISTRIBUTE x3 *(cyclic,block)
    print *, x2, x3
  .....  = a(i)
   call sub2(a)
  end
subroutine sub2 (x)
   integer x(100)
!HPF$ DISTRIBUTE x *(*)
  end sub2
end 
Not HPF conforming.
page 46 line 17
  - actual arg will be remapped to conform to the interface
 page 54 line 14
  - if array accessible through 2 or more paths cannot be remapped.
Proposal:  (to make the above example legal)
   Change text page 46 line 17 to delete reference to remapping of actual arguments;    [need better words]
... and a remapping of the actual argument is necessary, the call should proceed as if the data was copied to a temporary variable mapped to match the mapping of the dummy argument.
     Rational (to be added): sometime actual is accessible through say host association, so cannot remap actual.
===== 
Discussion - is a better solution just to say it illegal. 
Ken - points out that the places to worry are where a program is legal in F90 and one changes to HPF it is illegal - with no fix ... doesn't apply here.
straw poll on fix (vs saying illegal) - aliasing     0 - 14 - 6
====
second part of the same problem (aliasing involving pointers)
program p
   integer, pointer :: a(;)
!HPF$ DISTRIBUTE a(block)
    allocate a(100)
    call sub(a)  
contains 
    subroutine sub(x)
       integer, pointer :: x(:)
!HPF$ DISTRIBUTE x  *(cyclic)
        x(i) = ...
        a(i)   = ... 
     end sub
  end p
problem:  legal F90 => a and x point to same data with different distribution:
Proposal: add restriction [better words]  to the pointer proposal discussed earlier
   The mapping of a dummy argument with a pointer attribute has to match the mapping of the actual argument if the latter is accessible inside the procedure through another path.  strawpoll :  18 - 0 - 3

================================
SUBGROUP E
================================

57	HPF_LOCAL and assumed size arrays	
Group E
Whaley	[email-masked]	3/22/96	

Question:
Hi,
I am looking at the HTML version of the HPF language specification, version 1.1.  It says:

>A dummy array argument of an EXTRINSIC(HPF_LOCAL) routine must have assumed
>shape, even when it is explicit shape in the interface. Note that, in general,
>the shape of a dummy array argument differs from the shape of the corresponding
>actual argument, unless there is a single executing processor. 

I think this statement is misleading.  Is it true that all HPF_LOCAL routines are constrained to accept only assumed shape arrays, or is it only HPF_LOCAL routines which are called from global HPF that have this restriction?

The reason I ask is that we have Fortran77 code which we are hoping to access from HPF.  The easiest route to do this is to have the HPF routine call an HPF_LOCAL routine with our arrays passed in as assumed shape.  Then, since HPF_LOCAL is a superset of Fortran77, we declare our Fortran77 routine as another HPF_LOCAL routine taking an assumed size array (required by Fortran77).

So, my question is: can HPF_LOCAL routines which will not be called from global HPF take assumed size arrays?  If so, I think a slight rewording of the standard might help make this apparent.

Thanks,
Clint
--------end of question - ---- beginning of discussion ---------
Mary comments:
Good point ... We already have wording here and there that
distinguishes the HPF_LOCAL routines that may be called from
global from the others ... it seems completely reasonable
to me that the assumed shape requirement would apply only
to those routines that cross that boundary.  
      Formally - your question will go on the list for the next meeting
(May 1-3).
   -mary-
-----------
Carl comments:
There is no constraint stopping an HPF_LOCAL routine from calling
a Fortran 77 routine, as far as I know.  In fact, a standard way
of calling such routines would be, as you suggest, to use the HPF_LOCAL
routine as a wrapper to set up the argument passing for the Fortran 77
or Fortran 90 routine it then calls.  Such a routine could be
declared, for example, as EXTRINSIC(F90_LOCAL).  (You have to declare
it as *something*; otherwise the default is that it is also considered
to be HPF_LOCAL.)
     Clearly there are some issues here that could be re-examined; but what
is there now is certainly workable.
                --Carl Offner   [email-masked]
---------
Clint replies:
Thanks for the response, but this is not at all what I am asking.  Probably my message was not very clear.  If the compiler supports F90_LOCAL, I don't need the intermediary step of HPF_LOCAL in the first place.  The whole point is that the compilers I have used are very selective in the extrinsics they support, and I'd like to be able to use HPF_LOCAL alone as a route to using an assumed size array.

It is clear that if F90_LOCAL is supported, my problem is solved.  However, if  HPF_LOCAL is contrained to accept assumed shape arrays only when called from  global HPF, I will have a solution if either F90_LOCAL or HPF_LOCAL is  supported.

It seems to me that the assumed shape restriction was probably set in place to facilitate transfer from the global HPF to local, and thus it is not necessary when one HPF_LOCAL routine calls another.  Therefore, my question remains: can HPF_LOCAL routines which will not be called from global HPF take assumed size arrays?
Thanks, Clint	discussion continued - 
---------------------------------------------------------------------------
Back to Carl:
   Perhaps you misunderstood what I was trying to say.  You can take
your Fortran 77 routine and call it from an HPF_LOCAL as you
suggested.  There is nothing that currently prevents you from doing
that.  The only thing you have to be careful about is that you
have to explicitly declare it as NOT being HPF_LOCAL, since otherwise
that is the default.  I suggested EXTRINSIC(F90_LOCAL), which is
compatible with Fortran 77.  But anything else would do as well.
                --Carl Offner  [email-masked]

---------------------------------------------------------------------------
and back to Clint:
Yes, I understand your point.  It was one I examined before sending mail. My whole problem is that I do not want to have to count on there being any extrinsic besides HPF_LOCAL.  I see no reason to have the assumed shape restriction if one HPF_LOCAL routine calls another.  If this is the case, I can call a Fortran77 routine using HPF_LOCAL as the only extrinsic type.  To use the idea you are suggesting, the compiler must support two extrinsics, HPF_LOCAL and, for instance, F90_LOCAL or F77_LOCAL.

To give you an example, DEC's HPF compiler (at least the version I have) supports only HPF and HPF_LOCAL.  If the ruling is that HPF_LOCAL routines which are not called from global HPF can take assumed size arrays, I could get my code to work there without asking DEC to support more extrinsics.  I believe that IBM's xlhpf also does not support F90_LOCAL or F77_LOCAL at this time. That is why my question involved the ruling on passing assumed size arrays between HPF_LOCAL routines, rather than how to call a F77 routine from  HPF_LOCAL.
 Thanks,
Clint
---------------------------------------------------------------------------
And - now a comment from Carol:

Clint raised an important point that has been bothering me as well. Not all
implementations of HPF_LOCAL necessarily have other types of EXTRINSIC
interface available, so HPF_LOCAL should be complete in itself, especially
since there exists a default assumption that a subprogram call from within
an HPF_LOCAL routine is calling another HPF_LOCAL routine.  I don't believe
there was an intent to block any use of explicit shape arrays locally,
whatever constraints might be put on dummies associated with globally
distributed arrays (even such a constraint has disadvantages). I do believe
that it should be possible to pass explicit-shape arrays from one HPF_LOCAL routine to another. I think the language specifications need to be altered to fix this problem.
--Carol Munroe   [email-masked]
   ---------------------------------------------------------------------------
And a couple more comments from Carl:
Well, I agree that there may be some room for language development
here.  But we will soon be supporting F90_LOCAL for the very reason
you need it; and the idea is that you can call it from an HPF_LOCAL
as you desire.  Calling an F90_LOCAL from a (global) HPF routine
would still not be possible with anything but assumed-shape dummy 
arguments (unless some further language enhancements are made
to support this kind of feature).  I don't think this is a big
feature for any compiler to implement -- the only real glitch
is that the default for a routine called from HPF_LOCAL is
stated to be HPF_LOCAL -- that's the only reason one even needs
another kind of intrinsic at all in this case.
                --Carl Offner  [email-masked]
---------------------------------------------------------------------------
I guess what has been motivating my replies is the feeling that
we are too late in this round of HPFF meetings to make any
changes in HPF_LOCAL like what Clint is suggesting.  Personally,
I don't have any objection to having HPF_LOCAL be able to accept
other than assumed-shape arguments when called from another HPF_LOCAL.

I just thought that in effect we have a mechanism for doing that,
with a very modest (really only a front-end) investment of work
for a compiler, and that we were unlikely to get anything else
immediately.  Again, though, I agree that there is room here
for some possible language change.

                --Carl Offner  [email-masked]
WHAT DID WE DECIDE ABOUT THIS???	

================================

51	array sections and HPF_LOCAL	
Group E

Zongaro	[email-masked]	2/13/96	
status: in progress	
Question:

Hello,
     I thought I had sent this question a few weeks ago, but I couldn't find
any record of having done that - my apologies if this is a duplicate.

     Consider the following program.

         program prog
           interface
             extrinsic(hpf_local) subroutine sub(dummy)
               integer :: dummy(:, :)
   !hpf$       inherit dummy
             end subroutine sub
           end interface
           integer actual(4, 4)
   !hpf$   processors p(2, 2)
   !hpf$   distribute actual(block, block) onto p

           call sub(actual(1:2, 1:2))
         end program prog

         extrinsic(hpf_local) subroutine sub(dummy)
           use hpf_local_library
           integer :: dummy(:, :)

           print *, 'proc = ', my_processor(),                                &
        &           'lbound = ', lbound(dummy),                               &
        &           'ubound = ', ubound(dummy)
         end subroutine sub

Assuming that elements of p correspond to physical processors as follows
             p(1,1)     0
             p(2,1)     1
             p(1,2)     2
             p(2,2)     3
which of the following correctly describes the output from the four instances
of the HPF_LOCAL subroutine?

a)     proc = 0 lbound = 1 1 ubound = 2 2
       proc = 1 lbound = 1 1 ubound = 0 2
       proc = 2 lbound = 1 1 ubound = 2 0
       proc = 3 lbound = 1 1 ubound = 0 0

b)     proc = 0 lbound = 1 1 ubound = 2 2
       proc = 1 lbound = 1 1 ubound = 0 0
       proc = 2 lbound = 1 1 ubound = 0 0
       proc = 3 lbound = 1 1 ubound = 0 0

In other words, should sub behave as if dummy is divided up like this

            -------------------------------------
           | dummy(1:2, 1:2)  |  dummy(1:2, 1:0) |
a)          -------------------------------------
           | dummy(1:0, 1:2)  |  dummy(1:0, 1:0) |
            -------------------------------------
or this?
            -------------------------------------
           | dummy(1:2, 1:2)  |  dummy(1:0, 1:0) |
b)          -------------------------------------
           | dummy(1:0, 1:0)  |  dummy(1:0, 1:0) |
            -------------------------------------
Thanks, Henry
	Rob replies ...
Henry,
Good question about lbound and ubound for dummies
of extrinsic local routines!    I favor iterpretation (a)

            -------------------------------------
           | dummy(1:2, 1:2)  |  dummy(1:2, 1:0) |
a)          -------------------------------------
           | dummy(1:0, 1:2)  |  dummy(1:0, 1:0) |
            -------------------------------------
All HPF distributions onto multidimensional processors arrangements are
cartesian products of one-dimensional distributions; this interpretation
is consistent with that rule.
Rob
----- 
comment from David Watson 
[email-masked]
---
Can I add support for interpretation a) i.e.
            -------------------------------------
           | dummy(1:2, 1:2)  |  dummy(1:2, 1:0) |
            -------------------------------------
           | dummy(1:0, 1:2)  |  dummy(1:0, 1:0) |
            -------------------------------------
If we consider a function or subroutine delivering a result sized according
to an incoming argument this interpretation is necessary for correct behaviour.
The following (exceedingly artificial) code illustrates the necessity

         program prog
           interface
             extrinsic(hpf_local) function funres(dummy)
               integer :: dummy(:, :)
               integer :: funres(size(dummy,1))
   !hpf$       inherit dummy
   !hpf$       align with dummy(:,*) :: funres
             end subroutine funres
           end interface
           integer actual(4, 4)
           integer junk(4)
   !hpf$   processors p(2, 2)
   !hpf$   distribute actual(block, block) onto p
   !hpf$   align junk(:) with actual(:,*)

           junk(1:2) = funres(actual(1:2,1:2))
         end program prog

         extrinsic(hpf_local) function funres(dummy)
               integer :: dummy(:, :)
               integer :: funres(size(dummy,1))
   !hpf$       inherit dummy
   !hpf$       align with dummy(:,*) :: funres
               funres = 0
               dummy  = 0
         end subroutine funres

under interpretation b) processor 2 (assuming the numbering in the original
example) would return a size zero array into a size 2 array.
Cheers,
   Dave
#51, 54 and 55 being discussed together - see #55 for proposal.

NOTE REMOVING GLOBAL_LB/UB is not solution to this problem	
---------------------------------------------------------------------------
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>
---------------------------------------------------------------------------