Data Parallel Statements Up: Data Alignment and Previous: INHERIT Directive

Alignment, Distribution, and Subprogram Interfaces

Mapping directives may be applied to dummy arguments in the same manner as for other variables; such directives may also appear in interface blocks. However, there are additional options that may be used only with dummy arguments: asterisks, indicating that a specification is descriptive rather than prescriptive, and the INHERIT attribute.

First, consider the rules for the caller. 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. The template of the dummy will then be as declared in the interface. If there is no explicit interface, then actual arguments that are whole arrays or array sections not involving vector subscripts may be remapped at the discretion of the language processor; the values of other expressions may be mapped in any manner at the discretion of the language processor.

In order to describe explicitly the distribution of a dummy argument, the template that is subject to distribution must be determined. A dummy argument always has a fresh template to which it is ultimately aligned; this template is constructed in one of three ways:

Consider the following example: LOGICAL FRUG(128),TWIST(128) !HPF$ DISTRIBUTE (BLOCK) ONTO DANCE_FLOOR::FRUG,TWIST CALL TERPSICHORE(FRUG(1:40:3),TWIST(1:40:3)) The two array sections FRUG(1:40:3) and TWIST(1:40:3) are mapped onto abstract processors in the same manner:

However, the subroutine TERPSICHORE will view them in different ways because it inherits the template for the second dummy but not the first: SUBROUTINE TERPSICHORE(FOXTROT,TANGO) LOGICAL FOXTROT(:),TANGO(:) !HPF$ DISTRIBUTE TANGO *(BLOCK) but it would not be correct to declare !HPF$ PROCESSORS DANCE_FLOOR(16) !HPF$ ALIGN FOXTROT(J) WITH *GURF(3*J-2) could be correctly included in TERPSICHORE to describe the layout of FOXTROT on entry to the subroutine without using an inherited template.

The simplest case is the use of the INHERIT attribute alone. If a dummy argument has the INHERIT attribute and no explicit DISTRIBUTE attribute, the net effect is to tell the compiler to leave the data exactly where it is-and not attempt to remap the actual argument. The dummy argument will be mapped in exactly the same manner as the actual argument; the subprogram must be compiled in such a way as to work correctly no matter how the actual argument may be mapped onto abstract processors. (It has this effect because an INHERIT attribute on a dummy D implicitly specifies the default distribution !HPF$ DISTRIBUTE URANIA (CYCLIC) ONTO GALILEO The language processor should do whatever it takes to cause URANIA to have a CYCLIC distribution on the processor arrangement GALILEO. !HPF$ DISTRIBUTE THALIA *(CYCLIC) ONTO FLIP The language processor should do whatever it takes to cause THALIA to have a CYCLIC distribution on the processor arrangement FLIP; THALIA already has a cyclic distribution, though it might be on some other processor arrangement. !HPF$ DISTRIBUTE MELPOMENE * ONTO *EURIPIDES MELPOMENE is asserted to already be distributed onto EURIPIDES; use whatever distribution format the actual argument had so, if possible, no data movement should occur. (You can't say this in Subset HPF.) !HPF$ DISTRIBUTE EUTERPE (CYCLIC) ONTO * The language processor should do whatever it takes to cause EUTERPE to have a CYCLIC distribution onto whatever processor arrangement the actual was distributed onto. (You can't say this in Subset HPF.) !HPF$ DISTRIBUTE ARTHUR_MURRAY *(CYCLIC) ONTO * ARTHUR_MURRAY is asserted to already be distributed CYCLIC onto whatever processor arrangement the actual argument was distributed onto, and no data movement should occur. (You can't say this in Subset HPF.)

Please note that DISTRIBUTE ERATO * ONTO * does not mean the same thing as !HPF$ DISTRIBUTE WHEEL_OF_FORTUNE *(CYCLIC) WHEEL_OF_FORTUNE is asserted to already be CYCLIC. As long as it is kept CYCLIC, it may be remapped it onto some other processor arrangement, but there is no reason to. !HPF$ DISTRIBUTE DAVID_LETTERMAN ONTO *TV !Nonconforming does not conform to the syntax for a DISTRIBUTE directive.)

The asterisk convention allows the programmer to make claims about the pre-existing distribution of a dummy based on knowledge of the mapping of the actual argument. But what claims may the programmer correctly make?

If the dummy argument has an inherited template, then the subprogram may contain directives corresponding to the directives describing the actual argument. Sometimes it is necessary, as an alternative, to introduce an explicit named template (using a TEMPLATE directive) rather than inheriting a template; an example of this (GURF) appears above, near the beginning of this section.

If the dummy argument has a natural template (no INHERIT attribute) then things are more complicated. In certain situations the programmer is justified in inferring a pre-existing distribution for the natural template from the distribution of the actual's template, that is, the template that would have been inherited if the INHERIT attribute had been specified. In all these situations, the actual argument must be a whole array or array section, and the template of the actual must be coextensive with the array along any axes having a distribution format other than ``*.''

If the actual argument is a whole array, then the pre-existing distribution of the natural template of the dummy is identical to that of the actual argument.

If the actual argument is an array section, then, from each section-subscript and the distribution format for the corresponding axis of the array being subscripted, one constructs an axis distribution format for the corresponding axis of the natural template:

If the situation of interest is not described by the cases listed above, no assertion about the distribution of the natural template of a dummy is HPF-conforming.

Here is a typical example of the use of this feature. The main program has a two-dimensional array TROGGS, which is to be processed by a subroutine one column at a time. (Perhaps processing the entire array at once would require prohibitive amounts of temporary space.) Each column is to be distributed across many processors. REAL TROGGS(1024,473) !HPF$ DISTRIBUTE GROOVY *(BLOCK) ONTO * Consider now the ALIGN directive. The presence or absence of an asterisk at the start of an align-spec has the same meaning as in a dist-format-clause: it specifies whether the ALIGN directive is descriptive or prescriptive, respectively.

If an align-spec that does not begin with * is applied to a dummy argument, the meaning is that the dummy argument will be forced to have the specified alignment on entry to the subprogram (which may require temporarily remapping the data of the actual argument or a copy thereof).

Note that a dummy argument may also be used as an align-target. SUBROUTINE NICHOLAS(TSAR,CZAR) REAL, DIMENSION(1918) :: TSAR,CZAR !HPF$ ALIGN WITH TSAR :: CZAR In this example the first dummy argument, TSAR, is allowed to remain aligned with the corresponding actual argument, while the second dummy argument, CZAR, is forced to be aligned with the first dummy argument. If the two actual arguments are already aligned, no remapping of the data will be required at run time; but the subprogram will operate correctly even if the actual arguments are not already aligned, at the cost of remapping the data for the second dummy argument at run time.

If the align-spec begins with ``*'', then the alignee must be a dummy argument and the directive must be ALIGN and not REALIGN. The ``*'' indicates that the ALIGN directive constitutes a guarantee on the part of the programmer that, on entry to the subprogram, the indicated alignment will already be satisfied by the dummy argument, without any action to remap it required at run time. For example:

This asserts that, for every J in the range 1:1000, on entry to subroutine GRUNGE, the directives in the program have specified that PLUNGE(J) is currently mapped to the same abstract processor as SPONGE(J). (The intent is that if the language processor has in fact honored the directives, then no interprocessor communication will be required to achieve the specified alignment.)

The alignment of a general expression is up to the language processor and therefore unpredictable by the programmer; but the alignment of whole arrays and array sections is predictable. In the code fragment REAL FIJI(5000),SQUEEGEE(2000) !HPF$ PROCESSORS GUNK(32) !HPF$ ALIGN WITH *DENSE :: THICK Note that the programmer cannot be justified in descriptively asserting that THICK will be aligned with DENSE after its remapping unless the remapping is fully specified (that is, no part of the remapping is left to the compiler to choose). Therefore an explicit processors arrangement necessarily appears in the example. The caller must ensure that the first actual argument is appropriately mapped onto an identical processors arrangement. new

It is not permitted to say simply ``ALIGN WITH *''; an align-target must follow the asterisk. (The proper way to say ``accept any alignment'' is INHERIT.)

If a dummy argument has no explicit ALIGN or DISTRIBUTE attribute, then the compiler provides an implicit alignment and distribution specification, one that could have been described explicitly without any ``assertion asterisks''.

The rules on the interaction of the REALIGN and REDISTRIBUTE directives with a subprogram argument interface are:

  1. A dummy argument may be declared DYNAMIC. However, it is subject to the general restrictions concerning the use of the name of an array to stand for its associated template.

  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. For example, if an array is passed as an actual argument, it is forbidden to realign that array, or to redistribute an array or template to which it was aligned at the time of the call, until the subprogram has returned from the call. This prevents nasty aliasing problems. An example:

    MODULE FOO REAL A(10,10) !HPF$ REDISTRIBUTE A !nonconforming ... END Situations such as this are forbidden, for the same reasons that an assignment to A at the statement marked ``nonconforming'' would also be forbidden. 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.

An overriding principle is that any mapping or remapping of arguments is not visible to the caller. This is true whether such remapping is implicit (in order to conform to prescriptive directives, which may themselves be explicit or implicit) or explicit (specified by REALIGN or REDISTRIBUTE directives). When the subprogram returns and the caller resumes execution, all objects accessible to the caller after the call are mapped exactly as they were before the call. It is not possible for a subprogram to change the mapping of any object in a manner visible to its caller, not even by means of REALIGN and REDISTRIBUTE.

Data Parallel Statements Up: Data Alignment and Previous: INHERIT Directive
Thu Dec 8 16:17:11 CST 1994