The purpose of the RESIDENT clause is to promise that data accessed by a computation are mapped to active processors. That is, RESIDENT asserts that certain references (or all references) in its scope are stored on the active processor set. The compiler can use this information to avoid generating communication or to simplify array address calculations. Note that whether a given data element is resident depends on two facts:
H910 resident-clause is RESIDENT resident-stuff H911 resident-stuff is [ ( res-object-list ) ] H912 resident-directive is RESIDENT resident-stuff H913 resident-construct is directive-origin block-resident-directive
directive-origin end-resident-directive H914 block-resident-directive is RESIDENT resident-stuff BEGIN H915 end-resident-directive is END RESIDENT H915 res-object is object
A resident-directive is a kind of executable-directive. Similarly, a resident-construct is a kind of executable-construct.
Any top-level objects in the RESIDENT clause must be explicitly mapped. Similarly, the RESIDENT clause must appear at a point in the program with a declared active processor set (i.e., inside an ON block). Otherwise, the assertion (see below) is a statement about how the compiler works, not about the program.
The RESIDENT directive is an assertion to the compiler that certain object references made within the ON are stored on the active processors if the computation is performed by the specified active processor set. The scope of the assertion is the next Fortran statement if the resident-directive form is used and the enclosed block of code if the resident-construct form is used. If RESIDENT appears as a clause in an ON directive, then the ON and RESIDENT apply to the same statements.
RESIDENT(var) means the lexical expression var, when encountered in the execution of statements in the scope of the RESIDENT directive, accesses only data resident on the set of active processors. (That is, the set of processors named by the innermost available ON directive.) If var is accessed by the statement (e.g., it appears on the right-hand side of an assignment statement, or in the evaluation of a conditional expression), then at least one copy of the object and any subobject of the object must be mapped to the active processor set. If var is assigned to by the statement (e.g., it appears on the left hand side of an assignment statement, or in the variable list of a READ statement), or in any other context that may cause its value to change) then all copies of the variable and all subobjects of the variable must reside in the active processor set. The application of RESIDENT to CALL statements and function invocations introduces some complexity into this interpretation; these issues will be dealt with in Section 9.3.2.
Note that RESIDENT is always an assertion relative to the surrounding ON directive. Therefore, if the compiler does not implement the ON directive then it must be careful in interpreting RESIDENT. Similarly, if the compiler overrules the programmer-specified ALIGN and DISTRIBUTE directives, then it may not rely on the RESIDENT clause in general.
Finally, NEW variables are not considered by any nested RESIDENT directives, as detailed below.
The RESIDENT assertion is always relative to the declared data mappings and ON clauses because both pieces of information are necessary to determine the locality of data references. Data mapping determines where the data is stored, while ON clauses determine where they are used; in essence they determine the endpoints of a data path. RESIDENT itself says that the path length is very short; obviously, one cannot measure a path without knowing both endpoints. (End of rationale.)
Consider the following:
!HPF$ ON HOME(Z(I)), RESIDENT(X,Y,RECORD(I)) X(I) = Y(I+1) + RECORD(I)%FIELD1 + RECORD(I+1)%FIELD2
The following facts are asserted by the directive:
!HPF$ ALIGN Y(J) WITH Z(J-1)
appears elsewhere in the program. (Other situations also make the RESIDENT assertion true.)
If there is no res-object-list, then all references to all variables referenced during execution of the RESIDENT directive's body except those declared NEW in a surrounding ON directive are local in the sense described above. That is, for every usage of any variable's value, at least one copy of the variable will be mapped to the ON processor set. Likewise, for every operation that assigns to a variable, all copies of that variable are mapped to the ON processor set. References and assignments to NEW variables are always considered resident. If there are no function or subroutine invocations, this is syntactic sugar for listing all variable references within the directive's scope. (See Section 9.3.2 for a discussion of RESIDENT clauses applied to subprogram calls.) It might well have been named the ALL_RESIDENT clause; the present form, however, does not add yet another keyword to the directive sublanguage.
Note that if the active set includes more than one processor, then RESIDENT only asserts that the variables are stored on one of the processors. For example, if a statement is executed on a section of the processors arrangement, then communication within that section may be needed for some variables in the RESIDENT clause. Communication with processors outside of the section will not be needed for those variables, however.
!HPF$ PROCESSORS PROCS(MP,MP) !HPF$ DISTRIBUTE X(BLOCK,BLOCK) ONTO PROCS !HPF$ ON HOME(PROCS(1,1:MP)), RESIDENT(X(K,1:N) ) CALL FOO( X(K,1:N) )
would presumably call FOO on a row of the processors arrangement, passing elements of X in place. This is what the current definition does; if RESIDENT meant ``resident on every processor'', the call would force X to be replicated. (End of rationale.)
It is not correct to assert that an unmapped object, including of necessity any sequential object, is mapped exclusively to the active processors, unless the programmer knows that all of the processors are active. Thus, when a proper subset of processors is active, no such object can occur in a res-object-list or in the scope of a RESIDENT directive with no res-object-list.
The RESIDENT directive is similar to the INDEPENDENT directive, in that if it is correct it does not change the meaning of the program. If the RESIDENT clause is incorrect, the program is not standard-conforming (and is thus undefined). Like the INDEPENDENT directive, the compiler may use the information in the RESIDENT clause, or ignore it if it is insufficient for the compiler's purposes. If the compiler can detect that the RESIDENT clause is incorrect (i.e., that a RESIDENT variable is definitely nonlocal), it is justified in producing a warning. Unlike the INDEPENDENT directive, however, the truth of the RESIDENT clause depends on the mapping of computations (specified with the ON clause) and the mapping of data (specified with DISTRIBUTE and ALIGN clauses); if the compiler overrides either of these, then it may not be able to use information in the RESIDENT directive.