NAG Fortran Compiler, Release 7.2: Intrinsic procedures and modules

Navigation: Previous Up Next

## 11.6 Intrinsic procedures and modules

- [6.2] The intrinsic subroutine `MOVE_ALLOC` now has optional `STAT` and `ERRMSG` arguments. The `STAT` argument must be of type Integer, with a decimal exponent range of at least four (i.e. not an 8-bit integer); it is assigned the value zero if the subroutine executes successfully, and a nonzero value otherwise. The `ERRMSG` argument must be of type Character with default kind. If `STAT` is present and assigned a nonzero value, `ERRMSG` will be assigned an explanatory message (if it is present); otherwise, `ERRMSG` will retain its previous value (if any).

  For example,

          INTEGER,ALLOCATABLE :: x(:),y(:)
          INTEGER istat
          CHARACTER(80) emsg
          ...
          CALL MOVE_ALLOC(x,y,istat,emsg)
          IF (istat/=0) THEN
            PRINT *,'Unexpected error in MOVE_ALLOC: ',TRIM(emsg)

  The purpose of these arguments is to catch errors in multiple image coarray allocation/deallocation, such as `STAT_STOPPED_IMAGE` and `STAT_FAILED_IMAGE`.

- [7.1] The `DIM` argument to the intrinsic functions `ALL`, `ANY`, `FINDLOC`, `IALL`, `IANY`, `IPARITY`, `MAXLOC`, `MAXVAL`, `MINLOC`, `MINVAL`, `NORM2`, `PARITY`, `PRODUCT` and `SUM` can be an optional dummy argument, as long as it is present at execution time. For example,

        Subroutine sub(x,n)
          Real,Intent(In) :: x(:,:,:)
          Integer,Intent(In),Optional :: n
          If (Present(n)) Then
            Print *,Norm2(x,n) ! Rank two array result.
          Else
            Print *,Norm2(x)   ! Scalar result.
          End If
        End Subroutine

- Integer and Logical arguments to intrinsic procedures that were previously required to be of default kind no longer have that requirement, except for `RANDOM_SEED`. The changes are as follows:
  - [7.2] The `VALUES` argument of the intrinsic subroutine `DATE_AND_TIME` can be any kind of integer with a decimal exponent range of at least four; that is, any kind except 8-bit integer. For example,

                Program show_year
                    Use Iso_Fortran_Env
                    Integer(int16) v(8)
                    Call Date_And_Time(Values=v)
                    Print *,'The year is',v(1)
                End Program

  - [7.2] The `WAIT` argument of the intrinsic subroutine `EXECUTE_COMMAND_LINE` can be any kind of logical. The `CMDSTAT` and `EXITSTAT` arguments can be any kind of integer with a decimal exponent range of at least four; that is, any kind except 8-bit integer. For example,

                Program ok
                    Use Iso_Fortran_Env
                    Logical(logical8) :: w = .True._logical8
                    Integer(int16) :: cstat
                    Integer(int64) :: estat
                    Call Execute_Command_Line('echo ok',w,estat,cstat)
                    If (estat/=0 .Or. cstat/=0) Print *,'Bad STAT',estat,cstat
                End Program

    will, assuming ‘`echo`’ is the Unix echo command, display

                ok

- [7.1] Specific intrinsic functions are considered to be obsolescent (and reported as such with the -f2018 option). In the case of a function that is both specific and generic, e.g. `SQRT`, the obsolescent usage is passing as an actual argument, use as a procedure interface, or being the target of a procedure pointer assignment.
- [7.1] The intrinsic inquiry function `RANK` returns the dimensionality of its argument. It has the following syntax:

      RANK ( A )

  `A` : data object of any type:

  Result : scalar Integer of default kind.

  The result is the rank of `A`, that is, zero for scalar `A`, one if `A` is a one-dimensional array, and so on.

  This function can be used in a constant expression except when `A` is an assumed-rank variable.

- [7.2] The random-number generator (intrinsic `RANDOM_NUMBER`) is now per-image. Fortran 2008 permitted a compiler to use a single random-number stream, shared between all images; Fortran 2018 does not permit that, instead requiring each image to have its own random-number state.
- [7.2] The new intrinsic subroutine `RANDOM_INIT` initialises the random-number generator on the invoking image. It has the syntax:

      CALL RANDOM_INIT ( REPEATABLE, IMAGE_DISTINCT )

  `REPEATABLE` : scalar of type Logical, `Intent(In)`;
  `IMAGE_DISTINCT` : scalar of type Logical, `Intent(In)`.

  If `IMAGE_DISTINCT` is true, the initial state (seed) of the random-number generator will be different on every invoking image; otherwise, the initial state will not depend on which image it is. If `REPEATABLE` is true, each execution of the program will use the same initial seed (image-dependent if `IMAGE_DISTINCT` is also true); otherwise, each execution of the program will use a different initial seed.

  The default for the NAG Fortran Compiler, when no call to `RANDOM_INIT` is made, is `REPEATABLE=`false and `IMAGE_DISTINCT=`true.

- [7.1] The intrinsic function `REDUCE` performs user-defined array reductions. It has the following syntax:

      REDUCE ( ARRAY, OPERATION [, MASK, IDENTITY, ORDERED ] ) or
      REDUCE ( ARRAY, OPERATION DIM [, MASK, IDENTITY, ORDERED ] )

  `ARRAY` : array of any type;

  `OPERATION` : pure function with two arguments, each argument being scalar, non-allocatable, non-pointer, non-polymorphic non-optional variables with the same declared type and type parameters as `ARRAY`; if one argument has the `ASYNCHRONOUS`, `TARGET` or `VALUE` attribute, the other must also have that attribute; the result must be a non-polymorphic scalar variable with the same type and type parameters as `ARRAY`;

  `DIM` : scalar Integer in the range 1 to N, where N is the rank of `ARRAY`;

  `MASK` : type Logical, and either scalar or an array with the same shape as `ARRAY`;

  `IDENTITY` : scalar with the same declared type and type parameters as `ARRAY`;

  `ORDERED` : scalar of type Logical;

  Result : Same type and type parameters as `ARRAY`.

  The result is `ARRAY` reduced by the user-supplied `OPERATION`. If `DIM` is absent, the whole (masked) `ARRAY` is reduced to a scalar result. If `DIM` is present, the result has rank N-1 and the shape of `ARRAY` with dimension `DIM` removed; each element of the result is the reduction of the masked elements in that dimension.

  If exactly one element contributes to a result value, that value is equal to the element; that is, `OPERATION` is only invoked when more that one element appears.

  If no elements contribute to a result value, the `IDENTITY` argument must be present, and that value is equal to `IDENTITY`.

  For example,

      Module triplet_m
        Type triplet
          Integer i,j,k
        End Type
      Contains
        Pure Type(triplet) Function tadd(a,b)
          Type(triplet),Intent(In) :: a,b
          tadd%i = a%i + b%i
          tadd%j = a%j + b%j
          tadd%k = a%k + b%k
        End Function
      End Module
      Program reduce_example
        Use triplet_m
        Type(triplet) a(2,3)
        a = Reshape( [ triplet(1,2,3),triplet(1,2,4), &
                       triplet(2,2,5),triplet(2,2,6), &
                       triplet(3,2,7),triplet(3,2,8) ], [ 2,3 ] )
        Print 1, Reduce(a,tadd)
        Print 1, Reduce(a,tadd,1)
        Print 1, Reduce(a,tadd,a%i/=2)
        Print 1, Reduce(Array=a,Dim=2,Operation=tadd)
        Print 1, Reduce(a, Mask=a%i/=2, Dim=1, Operation=tadd, Identity=triplet(0,0,0))
      1 Format(1x,6('triplet(',I0,',',I0,',',I0,')',:,'; '))
      End Program

  This will produce the output:

       triplet(12,12,33)
       triplet(2,4,7); triplet(4,4,11); triplet(6,4,15)
       triplet(8,8,22)
       triplet(6,6,15); triplet(6,6,18)
       triplet(2,4,7); triplet(0,0,0); triplet(6,4,15)

- [7.0] The intrinsic atomic subroutines `ATOMIC_ADD`, `ATOMIC_AND`, `ATOMIC_CAS`, `ATOMIC_FETCH_ADD`, `ATOMIC_FETCH_AND`, `ATOMIC_FETCH_OR`, `ATOMIC_FETCH_XOR`, `ATOMIC_OR` and `ATOMIC_XOR` are described under Advanced coarray programming.

- [7.1] The intrinsic collective subroutines `CO_BROADCAST`, `CO_MAX`, `CO_MIN`, `CO_REDUCE` and `CO_SUM` are described under Advanced coarray programming.
- [7.0] The intrinsic functions `COSHAPE`, `EVENT_QUERY`, `FAILED_IMAGES`, `GET_TEAM`, `IMAGE_STATUS`, `STOPPED_IMAGES`, and `TEAM_NUMBER`. The changes to the intrinsic functions `IMAGE_INDEX`, `NUM_IMAGES`, and `THIS_IMAGE`, are described under Advanced coarray programming.
- The elemental intrinsic function `OUT_OF_RANGE` returns true if and only if a conversion would be out of range. It has the syntax:

      OUT_OF_RANGE ( X, MOLD [ , ROUND ] )

  `X` : type Real or Integer;

  `MOLD` : scalar of type Real or Integer;

  `ROUND` (optional) : scalar of type Logical;

  Result : Logical of default kind.

  The result is true if and only if the value of `X` is outside the range of values that can be converted to the type and kind of `MOLD` without error. If the `MOLD` argument is a variable, it need not have a defined value — only its type and kind are used. The `ROUND` argument is only allowed when `X` is type Real and `MOLD` is type Integer.

  For Real to Integer conversions, the default check is whether the value would be out of range for the intrinsic function `INT (X, KIND (MOLD))`; this is the same conversion that is used in intrinsic assignment. If the `ROUND` argument is present with the value `.TRUE.`, the check is instead whether the value would be out of range for the intrinsic function `NINT (X, KIND (MOLD))`.

  For example, `OUT_OF_RANGE (127.5, 0_int8)` is false, but `OUT_OF_RANGE (127.5, 0_int8, .TRUE.)` is true.

  If the value of `X` is an IEEE infinity, `OUT_OF_RANGE` will return `.TRUE.` if and only if the type and kind of `MOLD` does not support IEEE infinities. Similarly, if `X` is an IEEE NaN, the result is true if and only if `MOLD` does not support IEEE NaNs.

  Note that when checking conversions of type Real of one kind to type Real of another kind (for example, `REAL(real32)` to `REAL(real16)` or `REAL(real64)` to `REAL(real32)`), a finite value that is greater than `HUGE (KIND (MOLD))` will be considered out of range, but an infinite value will not be considered out of range. That is, `OUT_OF_RANGE (1.0E200_real64, 1.0_real32)` will return `.TRUE.`, but `OUT_OF_RANGE (IEEE_VALUE (1.0_real64, IEEE_POSITIVE_INF), 1.0_real32)` will return `.FALSE.`.

  Although this function is elemental, and can be used in constant expressions (if the value of `X` is constant and the `ROUND` argument is missing or constant), only the `X` argument is permitted to be an array. The result thus always has the rank and shape of `X`.

- [mostly 7.2] There are additional constants, types, and procedures in the standard intrinsic module `IEEE_ARITHMETIC`, providing additional support for IEEE (ISO/IEC 60559) arithmetic. These are described in the section “Updated IEEE arithmetic capabilities”.
- [7.2] Fortran 2018 requires diagnosis of the use of a non-standard intrinsic module such as `F90_KIND`. In the NAG Fortran Compiler, the OpenMP module `OMP_LIB` is also an intrinsic module, and so its use will be diagnosed as an extension.