Elemental references to pure procedures Revision of X3J3/94-245 Rationale Elemental functions provide the programmer with expressive power and the processor with additional opportunities for efficient parallelization. Extending the concept of elemental procedures from intrinsic to both intrinsic and user-defined procedures is very much analogous to, but simpler than, extending the concept of generic procedures from intrinsic to both intrinsic and user-defined procedures. Generic procedures were introduced to intrinsic procedures in Fortran 77 and extended to user-defined procedures in Fortran 90. Elemental procedures were introduced to intrinsic procedures in Fortran 90 and, especially because of their usefulness in parallel processing, it is quite natural that they be extended in Fortran 95 to user-defined procedures. Based on discussions at meeting 130, restrictions were added to non-intrinsic elemental functions that prohibit passing dummy procedures as arguments to elemental functions, prohibit passing elemental functions as dummy procedures, and prohibit recursive elemental procedures. Technical Description The extension of elemental to user-defined procedures is straightforward. A minimal facility is proposed here, that involves a procedure's arguments being elemental. A user-defined elemental procedure must be a pure procedure, having both the PURE keyword, and the ELEMENTAL keyword. All dummy arguments must be scalar and must not be pointers. The actual arguments in a reference to an elemental procedure must all be conformable. Note that a scalar is conformable to any shape array, and thus any actual argument may be scalar; an actual argument must be scalar if it is associated with a dummy argument used in a specification expression in the procedure definition. To be referenced elementally, the procedure must be given a generic specification in an interface block. This allows there to be no change in the rules for how specific procedures differ and a simple change (addition) to the rules for resolving generic overloads: if there is no specific match the processor looks for an elemental match (see section 14.1.2.4.1). One way of extending this feature in the future is to specify an ELEMENTAL attribute for any individual dummy argument(s) in lieu of the ELEMENTAL procedure keyword; the ELEMENTAL keyword included here may be considered to automatically give each dummy argument the elemental attribute. Detailed Edits section 7.1.3 - add a fifth paragraph A defined elemental operation is a defined operation for which the function is elemental (12.yyyy). section 7.1.5 - change title change "intrinsic" to "elemental" section 7.1.5 - new first sentence An elemental operation is an intrinsic operation or a defined elemental operation. section 7.1.5 - second paragraph change "intrinsic" to "elemental" section 7.1.7 - penultimate paragraph change "intrinsic binary" to "elemental binary" section 7.1.7 - last paragraph change "intrinsic unary" to "elemental unary" section 7.3.1 - in item (5) replace "The" with (a) The function is elemental, or (b) The section 7.3.2 - in item (5) replace "The" with (a) The function is elemental and x1 and x2 are conformable, or (b) The section 7.5.1.3 - add the following sentence to the paragraph A defined elemental assignment statement is a defined assignment statement for which the subroutine is elemental (12.yyyy). section 7.5.1.6 - in item (5) replace "The" with (a) The subroutine is elemental and either x1 and x2 have the same shape or x2 is scalar, or (b) The section 7.5.1.6 - add as a last paragraph If the defined assignment is an elemental assignment and the variable in the assignment is an array, the assignment is performed element-by-element, in any order, on corresponding array elements of variable and expr. section 7.5.3.2 - third paragraph change "elemental intrinsic operation" to "elemental operation" section 8.1.1.2 - last sentence change "12.4.2, 12.4.3, 12.4.4, 12.4.5" to "12.4.2, 12.4.4, 12.yyyy" section 12.1.1 - last paragraph replace "an intrinsic" with "a", and replace the references with "12.yyyy" section 12.2 - first paragraph (as modified by 94-149r2) after "whether or not it is pure," add "whether or not it is elemental," section 12.3.1.1 - Add to list in part 2 f) the ELEMENTAL keyword section 12.4.1.1 - third paragraph change "12.4.3, 12.4.5" to "12.yyyy" section 12.4.1.1 - insert phrase in last sentence of fourth-from-last paragraph change "procedure is referenced" to "procedure is nonelemental and is referenced" section 12.4.1.1 - insert phrase in last sentence change "dummy argument" to "dummy argument of a nonelemental procedure" section 12.4.2 - add to the paragraph A reference to an elemental function (12.yyyy) is an elemental reference if one or more actual arguments are arrays and all array arguments have the same shape. section 12.4.3 - delete entire section section 12.4.4 - add to the paragraph A reference to an elemental subroutine (12.yyyy) is an elemental reference if all actual arguments corresponding to INTENT(OUT) and INTENT(INOUT) dummy arguments are arrays that have the same shape and the remaining actual arguments are conformable with them. section 12.4.5 - delete entire section section 12.5.2.2 - add to syntax rule R1217a (as modified by 94-149r2) or ELEMENTAL Constraint: If ELEMENTAL is present, PURE must be present. Constraint: If ELEMENTAL is present, RECURSIVE must not be present. section 13.1 - first paragraph change "elemental function" with "elemental intrinsic function" section 13.2 - replace sections 13.2.1 and 13.2.2 with Elemental intrinsic procedures behave as described in 12.yyyy. section 14.1.2.4.1 - insert a new rule (2), and renumber accordingly (2) If (1) does not apply, if the reference is consistent with an elemental reference to one of the specific interfaces of an interface block that has that name and either is contained in the scoping unit in which the reference appears or is made accessible by a USE statement contained in the scoping unit, the reference is to the specific elemental procedure in that interface block that provides that interface. Note that the rules in 14.1.2.3 ensure that there can be at most one such specific interface. section 14.1.2.4.1 - new item (3) change ""If (1) does" to "If (1) and (2) do" section 14.1.2.4.1 - new item (4) change ""If (1) and (2) do" to "If (1), (2), and (3) do" section 14.1.2.4.1 - new item (5) change ""If (1), (2), and (3) do" to "If (1), (2), (3), and (4) do" annex A - elemental remove the word "intrinsic" and replace the references with "12.yyyy" section 12.yyyy - immediately after 12.xxxx (Pure procedures) 12.yyyy Elemental procedures 12.yyyy.1 Elemental procedure declaration and interface An elemental procedure is an elemental intrinsic procedure or a procedure that is defined with the prefix-spec ELEMENTAL. Procedures defined with the keyword ELEMENTAL must satisfy the additional constraints: Constraint: All dummy arguments must be scalar and must not have the POINTER attribute. Constraint: For a function, the result must be scalar and must not have the POINTER attribute. Constraint: A dummy-arg must not be *. Constraint: A dummy-arg must not be a dummy procedure. Constraint: An elemental procedure must not be used as an actual argument. Note that an elemental procedure is a pure procedure and all of the constraints for pure procedures also apply. 12.yyyy.2 Elemental function arguments and results If a generic name or a specific name is used to reference an elemental function, the shape of the result is the same as the shape of the argument with the greatest rank. If the arguments are all scalar, the result is scalar. For those elemental functions that have more than one argument, all arguments must be conformable. In the array-valued case, the values of the elements, if any, of the result are the same as would have been obtained if the scalar-valued function had been applied separately, in any order, to corresponding elements of each argument. For an intrinsic function, an argument called KIND must be specified as a scalar integer initialization expression and must specify a representation method for the function result that exists on the processor. For a non-intrinsic function, an actual argument must be scalar if it is associated with a dummy argument that is used in a specification expression. An example of an elemental reference to the intrinsic function MAX: if X and Y are arrays of shape (m, n), MAX (X, 0.0, Y) is an array expression of shape (m, n) whose elements have values MAX (X (i, j), 0.0, Y (i, j)), i = 1, 2, ..., m, j = 1, 2, ..., n 12.yyyy.3 Elemental subroutine arguments An elemental subroutine is one that is specified for scalar arguments, but in a generic reference may be applied to array arguments. In a reference to an elemental subroutine, either all actual arguments must be scalar, or all INTENT (OUT) and INTENT (INOUT) arguments must be arrays of the same shape and the remaining arguments must be conformable with them. In the case that the INTENT (OUT) and INTENT (INOUT) arguments are arrays, the values of the elements, if any, of the results are the same as would be obtained if the subroutine with scalar arguments were applied separately, in any order, to corresponding elements of each argument. [undecipherable tables] [footnote 1. These rules allow specific instances of a generic function to be used for specific array ranks and a general elemental version to be used for other ranks. Given an interface block such as: INTERFACE RANF ELEMENTAL FUNCTION SCALAR_RANF(X) REAL X END FUNCTION VECTOR_RANDOM(X) REAL X(:) REAL VECTOR_RANDOM(SIZE(X)) END END INTERFACE RANF and a declaration such as: REAL A(10,10), AA(10,10) then the statement A = RANF(AA) is an elemental reference to SCALAR_RANF. The statement A(1,1:5) = RANF(AA(6:10,2)) is a non-elemental reference to VECTOR_RANDOM. [undecipherable tables]