Sourabh Singh Tomar | 932aae7 | 2020-09-10 17:34:37 | [diff] [blame] | 1 | <!--===- docs/Intrinsics.md |
| 2 | |
| 3 | Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | See https://llvm.org/LICENSE.txt for license information. |
| 5 | SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | |
| 7 | --> |
| 8 | |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 9 | # A categorization of standard (2018) and extended Fortran intrinsic procedures |
| 10 | |
cor3ntin | b7ff032 | 2023-09-25 12:02:39 | [diff] [blame] | 11 | ```{contents} |
| 12 | --- |
| 13 | local: |
| 14 | --- |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 15 | ``` |
| 16 | |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 17 | This note attempts to group the intrinsic procedures of Fortran into categories |
| 18 | of functions or subroutines with similar interfaces as an aid to |
| 19 | comprehension beyond that which might be gained from the standard's |
| 20 | alphabetical list. |
| 21 | |
Jean Perier | 3774e9d | 2019-03-29 15:48:39 | [diff] [blame] | 22 | A brief status of intrinsic procedure support in f18 is also given at the end. |
| 23 | |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 24 | Few procedures are actually described here apart from their interfaces; see the |
| 25 | Fortran 2018 standard (section 16) for the complete story. |
| 26 | |
| 27 | Intrinsic modules are not covered here. |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 28 | |
| 29 | ## General rules |
| 30 | |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 31 | 1. The value of any intrinsic function's `KIND` actual argument, if present, |
| 32 | must be a scalar constant integer expression, of any kind, whose value |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 33 | resolves to some supported kind of the function's result type. |
| 34 | If optional and absent, the kind of the function's result is |
| 35 | either the default kind of that category or to the kind of an argument |
| 36 | (e.g., as in `AINT`). |
| 37 | 1. Procedures are summarized with a non-Fortran syntax for brevity. |
| 38 | Wherever a function has a short definition, it appears after an |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 39 | equal sign as if it were a statement function. Any functions referenced |
| 40 | in these short summaries are intrinsic. |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 41 | 1. Unless stated otherwise, an actual argument may have any supported kind |
| 42 | of a particular intrinsic type. Sometimes a pattern variable |
| 43 | can appear in a description (e.g., `REAL(k)`) when the kind of an |
| 44 | actual argument's type must match the kind of another argument, or |
| 45 | determines the kind type parameter of the function result. |
| 46 | 1. When an intrinsic type name appears without a kind (e.g., `REAL`), |
| 47 | it refers to the default kind of that type. Sometimes the word |
| 48 | `default` will appear for clarity. |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 49 | 1. The names of the dummy arguments actually matter because they can |
| 50 | be used as keywords for actual arguments. |
| 51 | 1. All standard intrinsic functions are pure, even when not elemental. |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 52 | 1. Assumed-rank arguments may not appear as actual arguments unless |
| 53 | expressly permitted. |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 54 | 1. When an argument is described with a default value, e.g. `KIND=KIND(0)`, |
| 55 | it is an optional argument. Optional arguments without defaults, |
| 56 | e.g. `DIM` on many transformationals, are wrapped in `[]` brackets |
| 57 | as in the Fortran standard. When an intrinsic has optional arguments |
| 58 | with and without default values, the arguments with default values |
| 59 | may appear within the brackets to preserve the order of arguments |
| 60 | (e.g., `COUNT`). |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 61 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 62 | ## Elemental intrinsic functions |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 63 | |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 64 | Pure elemental semantics apply to these functions, to wit: when one or more of |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 65 | the actual arguments are arrays, the arguments must be conformable, and |
| 66 | the result is also an array. |
| 67 | Scalar arguments are expanded when the arguments are not all scalars. |
| 68 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 69 | ### Elemental intrinsic functions that may have unrestricted specific procedures |
peter klausler | 370c44a | 2018-09-25 23:59:41 | [diff] [blame] | 70 | |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 71 | When an elemental intrinsic function is documented here as having an |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 72 | _unrestricted specific name_, that name may be passed as an actual |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 73 | argument, used as the target of a procedure pointer, appear in |
| 74 | a generic interface, and be otherwise used as if it were an external |
| 75 | procedure. |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 76 | An `INTRINSIC` statement or attribute may have to be applied to an |
peter klausler | 370c44a | 2018-09-25 23:59:41 | [diff] [blame] | 77 | unrestricted specific name to enable such usage. |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 78 | |
peter klausler | 42d17f2 | 2018-09-26 19:58:43 | [diff] [blame] | 79 | When a name is being used as a specific procedure for any purpose other |
| 80 | than that of a called function, the specific instance of the function |
| 81 | that accepts and returns values of the default kinds of the intrinsic |
| 82 | types is used. |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 83 | A Fortran `INTERFACE` could be written to define each of |
| 84 | these unrestricted specific intrinsic function names. |
| 85 | |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 86 | Calls to dummy arguments and procedure pointers that correspond to these |
| 87 | specific names must pass only scalar actual argument values. |
| 88 | |
| 89 | No other intrinsic function name can be passed as an actual argument, |
peter klausler | 42d17f2 | 2018-09-26 19:58:43 | [diff] [blame] | 90 | used as a pointer target, appear in a generic interface, or be otherwise |
| 91 | used except as the name of a called function. |
| 92 | Some of these _restricted specific intrinsic functions_, e.g. `FLOAT`, |
| 93 | provide a means for invoking a corresponding generic (`REAL` in the case of `FLOAT`) |
| 94 | with forced argument and result kinds. |
| 95 | Others, viz. `CHAR`, `ICHAR`, `INT`, `REAL`, and the lexical comparisons like `LGE`, |
| 96 | have the same name as their generic functions, and it is not clear what purpose |
| 97 | is accomplished by the standard by defining them as specific functions. |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 98 | |
| 99 | ### Trigonometric elemental intrinsic functions, generic and (mostly) specific |
| 100 | All of these functions can be used as unrestricted specific names. |
| 101 | |
| 102 | ``` |
| 103 | ACOS(REAL(k) X) -> REAL(k) |
| 104 | ASIN(REAL(k) X) -> REAL(k) |
| 105 | ATAN(REAL(k) X) -> REAL(k) |
| 106 | ATAN(REAL(k) Y, REAL(k) X) -> REAL(k) = ATAN2(Y, X) |
| 107 | ATAN2(REAL(k) Y, REAL(k) X) -> REAL(k) |
| 108 | COS(REAL(k) X) -> REAL(k) |
| 109 | COSH(REAL(k) X) -> REAL(k) |
| 110 | SIN(REAL(k) X) -> REAL(k) |
| 111 | SINH(REAL(k) X) -> REAL(k) |
| 112 | TAN(REAL(k) X) -> REAL(k) |
| 113 | TANH(REAL(k) X) -> REAL(k) |
| 114 | ``` |
| 115 | |
| 116 | These `COMPLEX` versions of some of those functions, and the |
| 117 | inverse hyperbolic functions, cannot be used as specific names. |
| 118 | ``` |
| 119 | ACOS(COMPLEX(k) X) -> COMPLEX(k) |
| 120 | ASIN(COMPLEX(k) X) -> COMPLEX(k) |
| 121 | ATAN(COMPLEX(k) X) -> COMPLEX(k) |
| 122 | ACOSH(REAL(k) X) -> REAL(k) |
| 123 | ACOSH(COMPLEX(k) X) -> COMPLEX(k) |
| 124 | ASINH(REAL(k) X) -> REAL(k) |
| 125 | ASINH(COMPLEX(k) X) -> COMPLEX(k) |
| 126 | ATANH(REAL(k) X) -> REAL(k) |
| 127 | ATANH(COMPLEX(k) X) -> COMPLEX(k) |
| 128 | COS(COMPLEX(k) X) -> COMPLEX(k) |
| 129 | COSH(COMPLEX(k) X) -> COMPLEX(k) |
| 130 | SIN(COMPLEX(k) X) -> COMPLEX(k) |
| 131 | SINH(COMPLEX(k) X) -> COMPLEX(k) |
| 132 | TAN(COMPLEX(k) X) -> COMPLEX(k) |
| 133 | TANH(COMPLEX(k) X) -> COMPLEX(k) |
| 134 | ``` |
| 135 | |
| 136 | ### Non-trigonometric elemental intrinsic functions, generic and specific |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 137 | These functions *can* be used as unrestricted specific names. |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 138 | ``` |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 139 | ABS(REAL(k) A) -> REAL(k) = SIGN(A, 0.0) |
| 140 | AIMAG(COMPLEX(k) Z) -> REAL(k) = Z%IM |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 141 | AINT(REAL(k) A, KIND=k) -> REAL(KIND) |
| 142 | ANINT(REAL(k) A, KIND=k) -> REAL(KIND) |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 143 | CONJG(COMPLEX(k) Z) -> COMPLEX(k) = CMPLX(Z%RE, -Z%IM) |
peter klausler | 370c44a | 2018-09-25 23:59:41 | [diff] [blame] | 144 | DIM(REAL(k) X, REAL(k) Y) -> REAL(k) = X-MIN(X,Y) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 145 | DPROD(default REAL X, default REAL Y) -> DOUBLE PRECISION = DBLE(X)*DBLE(Y) |
| 146 | EXP(REAL(k) X) -> REAL(k) |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 147 | INDEX(CHARACTER(k) STRING, CHARACTER(k) SUBSTRING, LOGICAL(any) BACK=.FALSE., KIND=KIND(0)) -> INTEGER(KIND) |
| 148 | LEN(CHARACTER(k,n) STRING, KIND=KIND(0)) -> INTEGER(KIND) = n |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 149 | LOG(REAL(k) X) -> REAL(k) |
| 150 | LOG10(REAL(k) X) -> REAL(k) |
| 151 | MOD(INTEGER(k) A, INTEGER(k) P) -> INTEGER(k) = A-P*INT(A/P) |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 152 | NINT(REAL(k) A, KIND=KIND(0)) -> INTEGER(KIND) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 153 | SIGN(REAL(k) A, REAL(k) B) -> REAL(k) |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 154 | SQRT(REAL(k) X) -> REAL(k) = X ** 0.5 |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 155 | ``` |
| 156 | |
peter klausler | 970e746c | 2018-09-25 22:36:00 | [diff] [blame] | 157 | These variants, however *cannot* be used as specific names without recourse to an alias |
| 158 | from the following section: |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 159 | ``` |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 160 | ABS(INTEGER(k) A) -> INTEGER(k) = SIGN(A, 0) |
| 161 | ABS(COMPLEX(k) A) -> REAL(k) = HYPOT(A%RE, A%IM) |
peter klausler | 370c44a | 2018-09-25 23:59:41 | [diff] [blame] | 162 | DIM(INTEGER(k) X, INTEGER(k) Y) -> INTEGER(k) = X-MIN(X,Y) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 163 | EXP(COMPLEX(k) X) -> COMPLEX(k) |
| 164 | LOG(COMPLEX(k) X) -> COMPLEX(k) |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 165 | MOD(REAL(k) A, REAL(k) P) -> REAL(k) = A-P*INT(A/P) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 166 | SIGN(INTEGER(k) A, INTEGER(k) B) -> INTEGER(k) |
peter klausler | 370c44a | 2018-09-25 23:59:41 | [diff] [blame] | 167 | SQRT(COMPLEX(k) X) -> COMPLEX(k) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 168 | ``` |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 169 | |
| 170 | ### Unrestricted specific aliases for some elemental intrinsic functions with distinct names |
| 171 | |
| 172 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 173 | ALOG(REAL X) -> REAL = LOG(X) |
| 174 | ALOG10(REAL X) -> REAL = LOG10(X) |
| 175 | AMOD(REAL A, REAL P) -> REAL = MOD(A, P) |
| 176 | CABS(COMPLEX A) = ABS(A) |
| 177 | CCOS(COMPLEX X) = COS(X) |
| 178 | CEXP(COMPLEX A) -> COMPLEX = EXP(A) |
| 179 | CLOG(COMPLEX X) -> COMPLEX = LOG(X) |
peter klausler | 42b33da | 2018-09-29 00:02:11 | [diff] [blame] | 180 | CSIN(COMPLEX X) -> COMPLEX = SIN(X) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 181 | CSQRT(COMPLEX X) -> COMPLEX = SQRT(X) |
peter klausler | 42b33da | 2018-09-29 00:02:11 | [diff] [blame] | 182 | CTAN(COMPLEX X) -> COMPLEX = TAN(X) |
| 183 | DABS(DOUBLE PRECISION A) -> DOUBLE PRECISION = ABS(A) |
| 184 | DACOS(DOUBLE PRECISION X) -> DOUBLE PRECISION = ACOS(X) |
| 185 | DASIN(DOUBLE PRECISION X) -> DOUBLE PRECISION = ASIN(X) |
| 186 | DATAN(DOUBLE PRECISION X) -> DOUBLE PRECISION = ATAN(X) |
| 187 | DATAN2(DOUBLE PRECISION Y, DOUBLE PRECISION X) -> DOUBLE PRECISION = ATAN2(Y, X) |
| 188 | DCOS(DOUBLE PRECISION X) -> DOUBLE PRECISION = COS(X) |
| 189 | DCOSH(DOUBLE PRECISION X) -> DOUBLE PRECISION = COSH(X) |
peter klausler | 370c44a | 2018-09-25 23:59:41 | [diff] [blame] | 190 | DDIM(DOUBLE PRECISION X, DOUBLE PRECISION Y) -> DOUBLE PRECISION = X-MIN(X,Y) |
peter klausler | 42b33da | 2018-09-29 00:02:11 | [diff] [blame] | 191 | DEXP(DOUBLE PRECISION X) -> DOUBLE PRECISION = EXP(X) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 192 | DINT(DOUBLE PRECISION A) -> DOUBLE PRECISION = AINT(A) |
| 193 | DLOG(DOUBLE PRECISION X) -> DOUBLE PRECISION = LOG(X) |
| 194 | DLOG10(DOUBLE PRECISION X) -> DOUBLE PRECISION = LOG10(X) |
| 195 | DMOD(DOUBLE PRECISION A, DOUBLE PRECISION P) -> DOUBLE PRECISION = MOD(A, P) |
peter klausler | 42b33da | 2018-09-29 00:02:11 | [diff] [blame] | 196 | DNINT(DOUBLE PRECISION A) -> DOUBLE PRECISION = ANINT(A) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 197 | DSIGN(DOUBLE PRECISION A, DOUBLE PRECISION B) -> DOUBLE PRECISION = SIGN(A, B) |
peter klausler | 42b33da | 2018-09-29 00:02:11 | [diff] [blame] | 198 | DSIN(DOUBLE PRECISION X) -> DOUBLE PRECISION = SIN(X) |
| 199 | DSINH(DOUBLE PRECISION X) -> DOUBLE PRECISION = SINH(X) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 200 | DSQRT(DOUBLE PRECISION X) -> DOUBLE PRECISION = SQRT(X) |
peter klausler | 42b33da | 2018-09-29 00:02:11 | [diff] [blame] | 201 | DTAN(DOUBLE PRECISION X) -> DOUBLE PRECISION = TAN(X) |
| 202 | DTANH(DOUBLE PRECISION X) -> DOUBLE PRECISION = TANH(X) |
| 203 | IABS(INTEGER A) -> INTEGER = ABS(A) |
peter klausler | 370c44a | 2018-09-25 23:59:41 | [diff] [blame] | 204 | IDIM(INTEGER X, INTEGER Y) -> INTEGER = X-MIN(X,Y) |
peter klausler | 42b33da | 2018-09-29 00:02:11 | [diff] [blame] | 205 | IDNINT(DOUBLE PRECISION A) -> INTEGER = NINT(A) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 206 | ISIGN(INTEGER A, INTEGER B) -> INTEGER = SIGN(A, B) |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 207 | ``` |
| 208 | |
| 209 | ## Generic elemental intrinsic functions without specific names |
| 210 | |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 211 | (No procedures after this point can be passed as actual arguments, used as |
| 212 | pointer targets, or appear as specific procedures in generic interfaces.) |
| 213 | |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 214 | ### Elemental conversions |
| 215 | |
| 216 | ``` |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 217 | ACHAR(INTEGER(k) I, KIND=KIND('')) -> CHARACTER(KIND,LEN=1) |
| 218 | CEILING(REAL() A, KIND=KIND(0)) -> INTEGER(KIND) |
| 219 | CHAR(INTEGER(any) I, KIND=KIND('')) -> CHARACTER(KIND,LEN=1) |
| 220 | CMPLX(COMPLEX(k) X, KIND=KIND(0.0D0)) -> COMPLEX(KIND) |
| 221 | CMPLX(INTEGER or REAL or BOZ X, INTEGER or REAL or BOZ Y=0, KIND=KIND((0,0))) -> COMPLEX(KIND) |
peter klausler | ef9dd9d | 2018-10-17 22:09:48 | [diff] [blame] | 222 | DBLE(INTEGER or REAL or COMPLEX or BOZ A) = REAL(A, KIND=KIND(0.0D0)) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 223 | EXPONENT(REAL(any) X) -> default INTEGER |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 224 | FLOOR(REAL(any) A, KIND=KIND(0)) -> INTEGER(KIND) |
| 225 | IACHAR(CHARACTER(KIND=k,LEN=1) C, KIND=KIND(0)) -> INTEGER(KIND) |
| 226 | ICHAR(CHARACTER(KIND=k,LEN=1) C, KIND=KIND(0)) -> INTEGER(KIND) |
| 227 | INT(INTEGER or REAL or COMPLEX or BOZ A, KIND=KIND(0)) -> INTEGER(KIND) |
| 228 | LOGICAL(LOGICAL(any) L, KIND=KIND(.TRUE.)) -> LOGICAL(KIND) |
| 229 | REAL(INTEGER or REAL or COMPLEX or BOZ A, KIND=KIND(0.0)) -> REAL(KIND) |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 230 | ``` |
| 231 | |
| 232 | ### Other generic elemental intrinsic functions without specific names |
| 233 | N.B. `BESSEL_JN(N1, N2, X)` and `BESSEL_YN(N1, N2, X)` are categorized |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 234 | below with the _transformational_ intrinsic functions. |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 235 | |
| 236 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 237 | BESSEL_J0(REAL(k) X) -> REAL(k) |
| 238 | BESSEL_J1(REAL(k) X) -> REAL(k) |
| 239 | BESSEL_JN(INTEGER(n) N, REAL(k) X) -> REAL(k) |
| 240 | BESSEL_Y0(REAL(k) X) -> REAL(k) |
| 241 | BESSEL_Y1(REAL(k) X) -> REAL(k) |
| 242 | BESSEL_YN(INTEGER(n) N, REAL(k) X) -> REAL(k) |
| 243 | ERF(REAL(k) X) -> REAL(k) |
| 244 | ERFC(REAL(k) X) -> REAL(k) |
| 245 | ERFC_SCALED(REAL(k) X) -> REAL(k) |
| 246 | FRACTION(REAL(k) X) -> REAL(k) |
| 247 | GAMMA(REAL(k) X) -> REAL(k) |
peter klausler | 970e746c | 2018-09-25 22:36:00 | [diff] [blame] | 248 | HYPOT(REAL(k) X, REAL(k) Y) -> REAL(k) = SQRT(X*X+Y*Y) without spurious overflow |
peter klausler | 42b33da | 2018-09-29 00:02:11 | [diff] [blame] | 249 | IMAGE_STATUS(INTEGER(any) IMAGE [, scalar TEAM_TYPE TEAM ]) -> default INTEGER |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 250 | IS_IOSTAT_END(INTEGER(any) I) -> default LOGICAL |
| 251 | IS_IOSTAT_EOR(INTEGER(any) I) -> default LOGICAL |
| 252 | LOG_GAMMA(REAL(k) X) -> REAL(k) |
| 253 | MAX(INTEGER(k) ...) -> INTEGER(k) |
| 254 | MAX(REAL(k) ...) -> REAL(k) |
| 255 | MAX(CHARACTER(KIND=k) ...) -> CHARACTER(KIND=k,LEN=MAX(LEN(...))) |
| 256 | MERGE(any type TSOURCE, same type FSOURCE, LOGICAL(any) MASK) -> type of FSOURCE |
| 257 | MIN(INTEGER(k) ...) -> INTEGER(k) |
| 258 | MIN(REAL(k) ...) -> REAL(k) |
| 259 | MIN(CHARACTER(KIND=k) ...) -> CHARACTER(KIND=k,LEN=MAX(LEN(...))) |
| 260 | MODULO(INTEGER(k) A, INTEGER(k) P) -> INTEGER(k); P*result >= 0 |
| 261 | MODULO(REAL(k) A, REAL(k) P) -> REAL(k) = A - P*FLOOR(A/P) |
| 262 | NEAREST(REAL(k) X, REAL(any) S) -> REAL(k) |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 263 | OUT_OF_RANGE(INTEGER(any) X, scalar INTEGER or REAL(k) MOLD) -> default LOGICAL |
| 264 | OUT_OF_RANGE(REAL(any) X, scalar REAL(k) MOLD) -> default LOGICAL |
| 265 | OUT_OF_RANGE(REAL(any) X, scalar INTEGER(any) MOLD, scalar LOGICAL(any) ROUND=.FALSE.) -> default LOGICAL |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 266 | RRSPACING(REAL(k) X) -> REAL(k) |
| 267 | SCALE(REAL(k) X, INTEGER(any) I) -> REAL(k) |
| 268 | SET_EXPONENT(REAL(k) X, INTEGER(any) I) -> REAL(k) |
| 269 | SPACING(REAL(k) X) -> REAL(k) |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 270 | ``` |
| 271 | |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 272 | ### Restricted specific aliases for elemental conversions &/or extrema with default intrinsic types |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 273 | |
| 274 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 275 | AMAX0(INTEGER ...) = REAL(MAX(...)) |
| 276 | AMAX1(REAL ...) = MAX(...) |
| 277 | AMIN0(INTEGER...) = REAL(MIN(...)) |
| 278 | AMIN1(REAL ...) = MIN(...) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 279 | DMAX1(DOUBLE PRECISION ...) = MAX(...) |
| 280 | DMIN1(DOUBLE PRECISION ...) = MIN(...) |
| 281 | FLOAT(INTEGER I) = REAL(I) |
| 282 | IDINT(DOUBLE PRECISION A) = INT(A) |
| 283 | IFIX(REAL A) = INT(A) |
| 284 | MAX0(INTEGER ...) = MAX(...) |
| 285 | MAX1(REAL ...) = INT(MAX(...)) |
| 286 | MIN0(INTEGER ...) = MIN(...) |
| 287 | MIN1(REAL ...) = INT(MIN(...)) |
| 288 | SNGL(DOUBLE PRECISION A) = REAL(A) |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 289 | ``` |
| 290 | |
| 291 | ### Generic elemental bit manipulation intrinsic functions |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 292 | Many of these accept a typeless "BOZ" literal as an actual argument. |
| 293 | It is interpreted as having the kind of intrinsic `INTEGER` type |
| 294 | as another argument, as if the typeless were implicitly wrapped |
| 295 | in a call to `INT()`. |
| 296 | When multiple arguments can be either `INTEGER` values or typeless |
| 297 | constants, it is forbidden for *all* of them to be typeless |
| 298 | constants if the result of the function is `INTEGER` |
| 299 | (i.e., only `BGE`, `BGT`, `BLE`, and `BLT` can have multiple |
| 300 | typeless arguments). |
| 301 | |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 302 | ``` |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 303 | BGE(INTEGER(n1) or BOZ I, INTEGER(n2) or BOZ J) -> default LOGICAL |
| 304 | BGT(INTEGER(n1) or BOZ I, INTEGER(n2) or BOZ J) -> default LOGICAL |
| 305 | BLE(INTEGER(n1) or BOZ I, INTEGER(n2) or BOZ J) -> default LOGICAL |
| 306 | BLT(INTEGER(n1) or BOZ I, INTEGER(n2) or BOZ J) -> default LOGICAL |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 307 | BTEST(INTEGER(n1) I, INTEGER(n2) POS) -> default LOGICAL |
peter klausler | 42b33da | 2018-09-29 00:02:11 | [diff] [blame] | 308 | DSHIFTL(INTEGER(k) I, INTEGER(k) or BOZ J, INTEGER(any) SHIFT) -> INTEGER(k) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 309 | DSHIFTL(BOZ I, INTEGER(k), INTEGER(any) SHIFT) -> INTEGER(k) |
peter klausler | 42b33da | 2018-09-29 00:02:11 | [diff] [blame] | 310 | DSHIFTR(INTEGER(k) I, INTEGER(k) or BOZ J, INTEGER(any) SHIFT) -> INTEGER(k) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 311 | DSHIFTR(BOZ I, INTEGER(k), INTEGER(any) SHIFT) -> INTEGER(k) |
| 312 | IAND(INTEGER(k) I, INTEGER(k) or BOZ J) -> INTEGER(k) |
| 313 | IAND(BOZ I, INTEGER(k) J) -> INTEGER(k) |
| 314 | IBCLR(INTEGER(k) I, INTEGER(any) POS) -> INTEGER(k) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 315 | IBITS(INTEGER(k) I, INTEGER(n1) POS, INTEGER(n2) LEN) -> INTEGER(k) |
peter klausler | 42b33da | 2018-09-29 00:02:11 | [diff] [blame] | 316 | IBSET(INTEGER(k) I, INTEGER(any) POS) -> INTEGER(k) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 317 | IEOR(INTEGER(k) I, INTEGER(k) or BOZ J) -> INTEGER(k) |
| 318 | IEOR(BOZ I, INTEGER(k) J) -> INTEGER(k) |
| 319 | IOR(INTEGER(k) I, INTEGER(k) or BOZ J) -> INTEGER(k) |
| 320 | IOR(BOZ I, INTEGER(k) J) -> INTEGER(k) |
| 321 | ISHFT(INTEGER(k) I, INTEGER(any) SHIFT) -> INTEGER(k) |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 322 | ISHFTC(INTEGER(k) I, INTEGER(n1) SHIFT, INTEGER(n2) SIZE=BIT_SIZE(I)) -> INTEGER(k) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 323 | LEADZ(INTEGER(any) I) -> default INTEGER |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 324 | MASKL(INTEGER(any) I, KIND=KIND(0)) -> INTEGER(KIND) |
| 325 | MASKR(INTEGER(any) I, KIND=KIND(0)) -> INTEGER(KIND) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 326 | MERGE_BITS(INTEGER(k) I, INTEGER(k) or BOZ J, INTEGER(k) or BOZ MASK) = IOR(IAND(I,MASK),IAND(J,NOT(MASK))) |
| 327 | MERGE_BITS(BOZ I, INTEGER(k) J, INTEGER(k) or BOZ MASK) = IOR(IAND(I,MASK),IAND(J,NOT(MASK))) |
| 328 | NOT(INTEGER(k) I) -> INTEGER(k) |
| 329 | POPCNT(INTEGER(any) I) -> default INTEGER |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 330 | POPPAR(INTEGER(any) I) -> default INTEGER = IAND(POPCNT(I), Z'1') |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 331 | SHIFTA(INTEGER(k) I, INTEGER(any) SHIFT) -> INTEGER(k) |
| 332 | SHIFTL(INTEGER(k) I, INTEGER(any) SHIFT) -> INTEGER(k) |
| 333 | SHIFTR(INTEGER(k) I, INTEGER(any) SHIFT) -> INTEGER(k) |
| 334 | TRAILZ(INTEGER(any) I) -> default INTEGER |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 335 | ``` |
| 336 | |
| 337 | ### Character elemental intrinsic functions |
| 338 | See also `INDEX` and `LEN` above among the elemental intrinsic functions with |
| 339 | unrestricted specific names. |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 340 | ``` |
| 341 | ADJUSTL(CHARACTER(k,LEN=n) STRING) -> CHARACTER(k,LEN=n) |
| 342 | ADJUSTR(CHARACTER(k,LEN=n) STRING) -> CHARACTER(k,LEN=n) |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 343 | LEN_TRIM(CHARACTER(k,n) STRING, KIND=KIND(0)) -> INTEGER(KIND) = n |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 344 | LGE(CHARACTER(k,n1) STRING_A, CHARACTER(k,n2) STRING_B) -> default LOGICAL |
| 345 | LGT(CHARACTER(k,n1) STRING_A, CHARACTER(k,n2) STRING_B) -> default LOGICAL |
| 346 | LLE(CHARACTER(k,n1) STRING_A, CHARACTER(k,n2) STRING_B) -> default LOGICAL |
| 347 | LLT(CHARACTER(k,n1) STRING_A, CHARACTER(k,n2) STRING_B) -> default LOGICAL |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 348 | SCAN(CHARACTER(k,n) STRING, CHARACTER(k,m) SET, LOGICAL(any) BACK=.FALSE., KIND=KIND(0)) -> INTEGER(KIND) |
| 349 | VERIFY(CHARACTER(k,n) STRING, CHARACTER(k,m) SET, LOGICAL(any) BACK=.FALSE., KIND=KIND(0)) -> INTEGER(KIND) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 350 | ``` |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 351 | |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 352 | `SCAN` returns the index of the first (or last, if `BACK=.TRUE.`) character in `STRING` |
| 353 | that is present in `SET`, or zero if none is. |
| 354 | |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 355 | `VERIFY` is essentially the opposite: it returns the index of the first (or last) character |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 356 | in `STRING` that is *not* present in `SET`, or zero if all are. |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 357 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 358 | ## Transformational intrinsic functions |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 359 | |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 360 | This category comprises a large collection of intrinsic functions that |
| 361 | are collected together because they somehow transform their arguments |
| 362 | in a way that prevents them from being elemental. |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 363 | All of them are pure, however. |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 364 | |
| 365 | Some general rules apply to the transformational intrinsic functions: |
| 366 | |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 367 | 1. `DIM` arguments are optional; if present, the actual argument must be |
| 368 | a scalar integer of any kind. |
| 369 | 1. When an optional `DIM` argument is absent, or an `ARRAY` or `MASK` |
| 370 | argument is a vector, the result of the function is scalar; otherwise, |
| 371 | the result is an array of the same shape as the `ARRAY` or `MASK` |
| 372 | argument with the dimension `DIM` removed from the shape. |
| 373 | 1. When a function takes an optional `MASK` argument, it must be conformable |
| 374 | with its `ARRAY` argument if it is present, and the mask can be any kind |
| 375 | of `LOGICAL`. It can be scalar. |
| 376 | 1. The type `numeric` here can be any kind of `INTEGER`, `REAL`, or `COMPLEX`. |
| 377 | 1. The type `relational` here can be any kind of `INTEGER`, `REAL`, or `CHARACTER`. |
| 378 | 1. The type `any` here denotes any intrinsic or derived type. |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 379 | 1. The notation `(..)` denotes an array of any rank (but not an assumed-rank array). |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 380 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 381 | ### Logical reduction transformational intrinsic functions |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 382 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 383 | ALL(LOGICAL(k) MASK(..) [, DIM ]) -> LOGICAL(k) |
| 384 | ANY(LOGICAL(k) MASK(..) [, DIM ]) -> LOGICAL(k) |
| 385 | COUNT(LOGICAL(any) MASK(..) [, DIM, KIND=KIND(0) ]) -> INTEGER(KIND) |
| 386 | PARITY(LOGICAL(k) MASK(..) [, DIM ]) -> LOGICAL(k) |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 387 | ``` |
| 388 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 389 | ### Numeric reduction transformational intrinsic functions |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 390 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 391 | IALL(INTEGER(k) ARRAY(..) [, DIM, MASK ]) -> INTEGER(k) |
| 392 | IANY(INTEGER(k) ARRAY(..) [, DIM, MASK ]) -> INTEGER(k) |
| 393 | IPARITY(INTEGER(k) ARRAY(..) [, DIM, MASK ]) -> INTEGER(k) |
| 394 | NORM2(REAL(k) X(..) [, DIM ]) -> REAL(k) |
| 395 | PRODUCT(numeric ARRAY(..) [, DIM, MASK ]) -> numeric |
| 396 | SUM(numeric ARRAY(..) [, DIM, MASK ]) -> numeric |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 397 | ``` |
| 398 | |
peter klausler | 970e746c | 2018-09-25 22:36:00 | [diff] [blame] | 399 | `NORM2` generalizes `HYPOT` by computing `SQRT(SUM(X*X))` while avoiding spurious overflows. |
| 400 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 401 | ### Extrema reduction transformational intrinsic functions |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 402 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 403 | MAXVAL(relational(k) ARRAY(..) [, DIM, MASK ]) -> relational(k) |
| 404 | MINVAL(relational(k) ARRAY(..) [, DIM, MASK ]) -> relational(k) |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 405 | ``` |
| 406 | |
| 407 | ### Locational transformational intrinsic functions |
| 408 | When the optional `DIM` argument is absent, the result is an `INTEGER(KIND)` |
| 409 | vector whose length is the rank of `ARRAY`. |
| 410 | When the optional `DIM` argument is present, the result is an `INTEGER(KIND)` |
| 411 | array of rank `RANK(ARRAY)-1` and shape equal to that of `ARRAY` with |
| 412 | the dimension `DIM` removed. |
| 413 | |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 414 | The optional `BACK` argument is a scalar LOGICAL value of any kind. |
| 415 | When present and `.TRUE.`, it causes the function to return the index |
| 416 | of the *last* occurence of the target or extreme value. |
| 417 | |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 418 | For `FINDLOC`, `ARRAY` may have any of the five intrinsic types, and `VALUE` |
| 419 | must a scalar value of a type for which `ARRAY==VALUE` or `ARRAY .EQV. VALUE` |
| 420 | is an acceptable expression. |
| 421 | |
| 422 | ``` |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 423 | FINDLOC(intrinsic ARRAY(..), scalar VALUE [, DIM, MASK, KIND=KIND(0), BACK=.FALSE. ]) |
| 424 | MAXLOC(relational ARRAY(..) [, DIM, MASK, KIND=KIND(0), BACK=.FALSE. ]) |
| 425 | MINLOC(relational ARRAY(..) [, DIM, MASK, KIND=KIND(0), BACK=.FALSE. ]) |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 426 | ``` |
| 427 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 428 | ### Data rearrangement transformational intrinsic functions |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 429 | The optional `DIM` argument to these functions must be a scalar integer of |
| 430 | any kind, and it takes a default value of 1 when absent. |
| 431 | |
| 432 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 433 | CSHIFT(any ARRAY(..), INTEGER(any) SHIFT(..) [, DIM ]) -> same type/kind/shape as ARRAY |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 434 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 435 | Either `SHIFT` is scalar or `RANK(SHIFT) == RANK(ARRAY) - 1` and `SHAPE(SHIFT)` is that of `SHAPE(ARRAY)` with element `DIM` removed. |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 436 | |
| 437 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 438 | EOSHIFT(any ARRAY(..), INTEGER(any) SHIFT(..) [, BOUNDARY, DIM ]) -> same type/kind/shape as ARRAY |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 439 | ``` |
| 440 | * `SHIFT` is scalar or `RANK(SHIFT) == RANK(ARRAY) - 1` and `SHAPE(SHIFT)` is that of `SHAPE(ARRAY)` with element `DIM` removed. |
| 441 | * If `BOUNDARY` is present, it must have the same type and parameters as `ARRAY`. |
| 442 | * If `BOUNDARY` is absent, `ARRAY` must be of an intrinsic type, and the default `BOUNDARY` is the obvious `0`, `' '`, or `.FALSE.` value of `KIND(ARRAY)`. |
| 443 | * If `BOUNDARY` is present, either it is scalar, or `RANK(BOUNDARY) == RANK(ARRAY) - 1` and `SHAPE(BOUNDARY)` is that of `SHAPE(ARRAY)` with element `DIM` |
| 444 | removed. |
| 445 | |
| 446 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 447 | PACK(any ARRAY(..), LOGICAL(any) MASK(..)) -> vector of same type and kind as ARRAY |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 448 | ``` |
| 449 | * `MASK` is conformable with `ARRAY` and may be scalar. |
| 450 | * The length of the result vector is `COUNT(MASK)` if `MASK` is an array, else `SIZE(ARRAY)` if `MASK` is `.TRUE.`, else zero. |
| 451 | |
| 452 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 453 | PACK(any ARRAY(..), LOGICAL(any) MASK(..), any VECTOR(n)) -> vector of same type, kind, and size as VECTOR |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 454 | ``` |
| 455 | * `MASK` is conformable with `ARRAY` and may be scalar. |
| 456 | * `VECTOR` has the same type and kind as `ARRAY`. |
| 457 | * `VECTOR` must not be smaller than result of `PACK` with no `VECTOR` argument. |
| 458 | * The leading elements of `VECTOR` are replaced with elements from `ARRAY` as |
| 459 | if `PACK` had been invoked without `VECTOR`. |
| 460 | |
| 461 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 462 | RESHAPE(any SOURCE(..), INTEGER(k) SHAPE(n) [, PAD(..), INTEGER(k2) ORDER(n) ]) -> SOURCE array with shape SHAPE |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 463 | ``` |
| 464 | * If `ORDER` is present, it is a vector of the same size as `SHAPE`, and |
| 465 | contains a permutation. |
| 466 | * The element(s) of `PAD` are used to fill out the result once `SOURCE` |
| 467 | has been consumed. |
| 468 | |
| 469 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 470 | SPREAD(any SOURCE, DIM, scalar INTEGER(any) NCOPIES) -> same type as SOURCE, rank=RANK(SOURCE)+1 |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 471 | TRANSFER(any SOURCE, any MOLD) -> scalar if MOLD is scalar, else vector; same type and kind as MOLD |
| 472 | TRANSFER(any SOURCE, any MOLD, scalar INTEGER(any) SIZE) -> vector(SIZE) of type and kind of MOLD |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 473 | TRANSPOSE(any MATRIX(n,m)) -> matrix(m,n) of same type and kind as MATRIX |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 474 | ``` |
| 475 | |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 476 | The shape of the result of `SPREAD` is the same as that of `SOURCE`, with `NCOPIES` inserted |
| 477 | at position `DIM`. |
| 478 | |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 479 | ``` |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 480 | UNPACK(any VECTOR(n), LOGICAL(any) MASK(..), FIELD) -> type and kind of VECTOR, shape of MASK |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 481 | ``` |
| 482 | `FIELD` has same type and kind as `VECTOR` and is conformable with `MASK`. |
| 483 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 484 | ### Other transformational intrinsic functions |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 485 | ``` |
| 486 | BESSEL_JN(INTEGER(n1) N1, INTEGER(n2) N2, REAL(k) X) -> REAL(k) vector (MAX(N2-N1+1,0)) |
| 487 | BESSEL_YN(INTEGER(n1) N1, INTEGER(n2) N2, REAL(k) X) -> REAL(k) vector (MAX(N2-N1+1,0)) |
| 488 | COMMAND_ARGUMENT_COUNT() -> scalar default INTEGER |
| 489 | DOT_PRODUCT(LOGICAL(k) VECTOR_A(n), LOGICAL(k) VECTOR_B(n)) -> LOGICAL(k) = ANY(VECTOR_A .AND. VECTOR_B) |
| 490 | DOT_PRODUCT(COMPLEX(any) VECTOR_A(n), numeric VECTOR_B(n)) = SUM(CONJG(VECTOR_A) * VECTOR_B) |
| 491 | DOT_PRODUCT(INTEGER(any) or REAL(any) VECTOR_A(n), numeric VECTOR_B(n)) = SUM(VECTOR_A * VECTOR_B) |
| 492 | MATMUL(numeric ARRAY_A(j), numeric ARRAY_B(j,k)) -> numeric vector(k) |
| 493 | MATMUL(numeric ARRAY_A(j,k), numeric ARRAY_B(k)) -> numeric vector(j) |
| 494 | MATMUL(numeric ARRAY_A(j,k), numeric ARRAY_B(k,m)) -> numeric matrix(j,m) |
| 495 | MATMUL(LOGICAL(n1) ARRAY_A(j), LOGICAL(n2) ARRAY_B(j,k)) -> LOGICAL vector(k) |
| 496 | MATMUL(LOGICAL(n1) ARRAY_A(j,k), LOGICAL(n2) ARRAY_B(k)) -> LOGICAL vector(j) |
| 497 | MATMUL(LOGICAL(n1) ARRAY_A(j,k), LOGICAL(n2) ARRAY_B(k,m)) -> LOGICAL matrix(j,m) |
| 498 | NULL([POINTER/ALLOCATABLE MOLD]) -> POINTER |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 499 | REDUCE(any ARRAY(..), function OPERATION [, DIM, LOGICAL(any) MASK(..), IDENTITY, LOGICAL ORDERED=.FALSE. ]) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 500 | REPEAT(CHARACTER(k,n) STRING, INTEGER(any) NCOPIES) -> CHARACTER(k,n*NCOPIES) |
| 501 | SELECTED_CHAR_KIND('DEFAULT' or 'ASCII' or 'ISO_10646' or ...) -> scalar default INTEGER |
| 502 | SELECTED_INT_KIND(scalar INTEGER(any) R) -> scalar default INTEGER |
| 503 | SELECTED_REAL_KIND([scalar INTEGER(any) P, scalar INTEGER(any) R, scalar INTEGER(any) RADIX]) -> scalar default INTEGER |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 504 | SHAPE(SOURCE, KIND=KIND(0)) -> INTEGER(KIND)(RANK(SOURCE)) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 505 | TRIM(CHARACTER(k,n) STRING) -> CHARACTER(k) |
| 506 | ``` |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 507 | |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 508 | The type and kind of the result of a numeric `MATMUL` is the same as would result from |
| 509 | a multiplication of an element of ARRAY_A and an element of ARRAY_B. |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 510 | |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 511 | The kind of the `LOGICAL` result of a `LOGICAL` `MATMUL` is the same as would result |
| 512 | from an intrinsic `.AND.` operation between an element of `ARRAY_A` and an element |
| 513 | of `ARRAY_B`. |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 514 | |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 515 | Note that `DOT_PRODUCT` with a `COMPLEX` first argument operates on its complex conjugate, |
| 516 | but that `MATMUL` with a `COMPLEX` argument does not. |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 517 | |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 518 | The `MOLD` argument to `NULL` may be omitted only in a context where the type of the pointer is known, |
| 519 | such as an initializer or pointer assignment statement. |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 520 | |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 521 | At least one argument must be present in a call to `SELECTED_REAL_KIND`. |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 522 | |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 523 | An assumed-rank array may be passed to `SHAPE`, and if it is associated with an assumed-size array, |
| 524 | the last element of the result will be -1. |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 525 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 526 | ### Coarray transformational intrinsic functions |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 527 | ``` |
| 528 | FAILED_IMAGES([scalar TEAM_TYPE TEAM, KIND=KIND(0)]) -> INTEGER(KIND) vector |
| 529 | GET_TEAM([scalar INTEGER(?) LEVEL]) -> scalar TEAM_TYPE |
| 530 | IMAGE_INDEX(COARRAY, INTEGER(any) SUB(n) [, scalar TEAM_TYPE TEAM ]) -> scalar default INTEGER |
| 531 | IMAGE_INDEX(COARRAY, INTEGER(any) SUB(n), scalar INTEGER(any) TEAM_NUMBER) -> scalar default INTEGER |
| 532 | NUM_IMAGES([scalar TEAM_TYPE TEAM]) -> scalar default INTEGER |
| 533 | NUM_IMAGES(scalar INTEGER(any) TEAM_NUMBER) -> scalar default INTEGER |
| 534 | STOPPED_IMAGES([scalar TEAM_TYPE TEAM, KIND=KIND(0)]) -> INTEGER(KIND) vector |
| 535 | TEAM_NUMBER([scalar TEAM_TYPE TEAM]) -> scalar default INTEGER |
| 536 | THIS_IMAGE([COARRAY, DIM, scalar TEAM_TYPE TEAM]) -> default INTEGER |
| 537 | ``` |
| 538 | The result of `THIS_IMAGE` is a scalar if `DIM` is present or if `COARRAY` is absent, |
| 539 | and a vector whose length is the corank of `COARRAY` otherwise. |
| 540 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 541 | ## Inquiry intrinsic functions |
peter klausler | e7c5a470 | 2018-09-25 22:23:01 | [diff] [blame] | 542 | These are neither elemental nor transformational; all are pure. |
| 543 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 544 | ### Type inquiry intrinsic functions |
peter klausler | ad9aede | 2018-10-11 21:51:14 | [diff] [blame] | 545 | All of these functions return constants. |
| 546 | The value of the argument is not used, and may well be undefined. |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 547 | ``` |
| 548 | BIT_SIZE(INTEGER(k) I(..)) -> INTEGER(k) |
| 549 | DIGITS(INTEGER or REAL X(..)) -> scalar default INTEGER |
| 550 | EPSILON(REAL(k) X(..)) -> scalar REAL(k) |
| 551 | HUGE(INTEGER(k) X(..)) -> scalar INTEGER(k) |
| 552 | HUGE(REAL(k) X(..)) -> scalar of REAL(k) |
| 553 | KIND(intrinsic X(..)) -> scalar default INTEGER |
| 554 | MAXEXPONENT(REAL(k) X(..)) -> scalar default INTEGER |
| 555 | MINEXPONENT(REAL(k) X(..)) -> scalar default INTEGER |
| 556 | NEW_LINE(CHARACTER(k,n) A(..)) -> scalar CHARACTER(k,1) = CHAR(10) |
peter klausler | ad9aede | 2018-10-11 21:51:14 | [diff] [blame] | 557 | PRECISION(REAL(k) or COMPLEX(k) X(..)) -> scalar default INTEGER |
| 558 | RADIX(INTEGER(k) or REAL(k) X(..)) -> scalar default INTEGER, always 2 |
| 559 | RANGE(INTEGER(k) or REAL(k) or COMPLEX(k) X(..)) -> scalar default INTEGER |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 560 | TINY(REAL(k) X(..)) -> scalar REAL(k) |
| 561 | ``` |
| 562 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 563 | ### Bound and size inquiry intrinsic functions |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 564 | The results are scalar when `DIM` is present, and a vector of length=(co)rank(`(CO)ARRAY`) |
| 565 | when `DIM` is absent. |
| 566 | ``` |
| 567 | LBOUND(any ARRAY(..) [, DIM, KIND=KIND(0) ]) -> INTEGER(KIND) |
| 568 | LCOBOUND(any COARRAY [, DIM, KIND=KIND(0) ]) -> INTEGER(KIND) |
| 569 | SIZE(any ARRAY(..) [, DIM, KIND=KIND(0) ]) -> INTEGER(KIND) |
| 570 | UBOUND(any ARRAY(..) [, DIM, KIND=KIND(0) ]) -> INTEGER(KIND) |
| 571 | UCOBOUND(any COARRAY [, DIM, KIND=KIND(0) ]) -> INTEGER(KIND) |
| 572 | ``` |
| 573 | |
| 574 | Assumed-rank arrays may be used with `LBOUND`, `SIZE`, and `UBOUND`. |
| 575 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 576 | ### Object characteristic inquiry intrinsic functions |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 577 | ``` |
| 578 | ALLOCATED(any type ALLOCATABLE ARRAY) -> scalar default LOGICAL |
| 579 | ALLOCATED(any type ALLOCATABLE SCALAR) -> scalar default LOGICAL |
| 580 | ASSOCIATED(any type POINTER POINTER [, same type TARGET]) -> scalar default LOGICAL |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 581 | COSHAPE(COARRAY, KIND=KIND(0)) -> INTEGER(KIND) vector of length corank(COARRAY) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 582 | EXTENDS_TYPE_OF(A, MOLD) -> default LOGICAL |
| 583 | IS_CONTIGUOUS(any data ARRAY(..)) -> scalar default LOGICAL |
| 584 | PRESENT(OPTIONAL A) -> scalar default LOGICAL |
| 585 | RANK(any data A) -> scalar default INTEGER = 0 if A is scalar, SIZE(SHAPE(A)) if A is an array, rank if assumed-rank |
| 586 | SAME_TYPE_AS(A, B) -> scalar default LOGICAL |
peter klausler | bab1f67 | 2018-09-26 17:42:55 | [diff] [blame] | 587 | STORAGE_SIZE(any data A, KIND=KIND(0)) -> INTEGER(KIND) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 588 | ``` |
| 589 | The arguments to `EXTENDS_TYPE_OF` must be of extensible derived types or be unlimited polymorphic. |
| 590 | |
| 591 | An assumed-rank array may be used with `IS_CONTIGUOUS` and `RANK`. |
| 592 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 593 | ## Intrinsic subroutines |
peter klausler | 970e746c | 2018-09-25 22:36:00 | [diff] [blame] | 594 | |
| 595 | (*TODO*: complete these descriptions) |
| 596 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 597 | ### One elemental intrinsic subroutine |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 598 | ``` |
| 599 | INTERFACE |
| 600 | SUBROUTINE MVBITS(FROM, FROMPOS, LEN, TO, TOPOS) |
| 601 | INTEGER(k1) :: FROM, TO |
| 602 | INTENT(IN) :: FROM |
| 603 | INTENT(INOUT) :: TO |
| 604 | INTEGER(k2), INTENT(IN) :: FROMPOS |
| 605 | INTEGER(k3), INTENT(IN) :: LEN |
| 606 | INTEGER(k4), INTENT(IN) :: TOPOS |
| 607 | END SUBROUTINE |
| 608 | END INTERFACE |
| 609 | ``` |
| 610 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 611 | ### Non-elemental intrinsic subroutines |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 612 | ``` |
| 613 | CALL CPU_TIME(REAL INTENT(OUT) TIME) |
| 614 | ``` |
| 615 | The kind of `TIME` is not specified in the standard. |
| 616 | |
| 617 | ``` |
peter klausler | ad9aede | 2018-10-11 21:51:14 | [diff] [blame] | 618 | CALL DATE_AND_TIME([DATE, TIME, ZONE, VALUES]) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 619 | ``` |
| 620 | * All arguments are `OPTIONAL` and `INTENT(OUT)`. |
| 621 | * `DATE`, `TIME`, and `ZONE` are scalar default `CHARACTER`. |
| 622 | * `VALUES` is a vector of at least 8 elements of `INTEGER(KIND >= 2)`. |
| 623 | ``` |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 624 | CALL EVENT_QUERY(EVENT, COUNT [, STAT]) |
| 625 | CALL EXECUTE_COMMAND_LINE(COMMAND [, WAIT, EXITSTAT, CMDSTAT, CMDMSG ]) |
| 626 | CALL GET_COMMAND([COMMAND, LENGTH, STATUS, ERRMSG ]) |
| 627 | CALL GET_COMMAND_ARGUMENT(NUMBER [, VALUE, LENGTH, STATUS, ERRMSG ]) |
| 628 | CALL GET_ENVIRONMENT_VARIABLE(NAME [, VALUE, LENGTH, STATUS, TRIM_NAME, ERRMSG ]) |
| 629 | CALL MOVE_ALLOC(ALLOCATABLE INTENT(INOUT) FROM, ALLOCATABLE INTENT(OUT) TO [, STAT, ERRMSG ]) |
| 630 | CALL RANDOM_INIT(LOGICAL(k1) INTENT(IN) REPEATABLE, LOGICAL(k2) INTENT(IN) IMAGE_DISTINCT) |
| 631 | CALL RANDOM_NUMBER(REAL(k) INTENT(OUT) HARVEST(..)) |
| 632 | CALL RANDOM_SEED([SIZE, PUT, GET]) |
| 633 | CALL SYSTEM_CLOCK([COUNT, COUNT_RATE, COUNT_MAX]) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 634 | ``` |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 635 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 636 | ### Atomic intrinsic subroutines |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 637 | ``` |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 638 | CALL ATOMIC_ADD(ATOM, VALUE [, STAT=]) |
| 639 | CALL ATOMIC_AND(ATOM, VALUE [, STAT=]) |
| 640 | CALL ATOMIC_CAS(ATOM, OLD, COMPARE, NEW [, STAT=]) |
| 641 | CALL ATOMIC_DEFINE(ATOM, VALUE [, STAT=]) |
| 642 | CALL ATOMIC_FETCH_ADD(ATOM, VALUE, OLD [, STAT=]) |
| 643 | CALL ATOMIC_FETCH_AND(ATOM, VALUE, OLD [, STAT=]) |
| 644 | CALL ATOMIC_FETCH_OR(ATOM, VALUE, OLD [, STAT=]) |
| 645 | CALL ATOMIC_FETCH_XOR(ATOM, VALUE, OLD [, STAT=]) |
| 646 | CALL ATOMIC_OR(ATOM, VALUE [, STAT=]) |
| 647 | CALL ATOMIC_REF(VALUE, ATOM [, STAT=]) |
| 648 | CALL ATOMIC_XOR(ATOM, VALUE [, STAT=]) |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 649 | ``` |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 650 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 651 | ### Collective intrinsic subroutines |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 652 | ``` |
peter klausler | 3cecff6 | 2018-09-25 20:26:35 | [diff] [blame] | 653 | CALL CO_BROADCAST |
| 654 | CALL CO_MAX |
| 655 | CALL CO_MIN |
| 656 | CALL CO_REDUCE |
| 657 | CALL CO_SUM |
peter klausler | 9849cf5 | 2018-09-25 21:47:55 | [diff] [blame] | 658 | ``` |
peter klausler | 370c44a | 2018-09-25 23:59:41 | [diff] [blame] | 659 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 660 | ## Non-standard intrinsics |
| 661 | ### PGI |
peter klausler | 370c44a | 2018-09-25 23:59:41 | [diff] [blame] | 662 | ``` |
| 663 | AND, OR, XOR |
| 664 | LSHIFT, RSHIFT, SHIFT |
| 665 | ZEXT, IZEXT |
| 666 | COSD, SIND, TAND, ACOSD, ASIND, ATAND, ATAN2D |
| 667 | COMPL |
| 668 | DCMPLX |
| 669 | EQV, NEQV |
| 670 | INT8 |
| 671 | JINT, JNINT, KNINT |
| 672 | LOC |
| 673 | ``` |
| 674 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 675 | ### Intel |
peter klausler | 370c44a | 2018-09-25 23:59:41 | [diff] [blame] | 676 | ``` |
| 677 | DCMPLX(X,Y), QCMPLX(X,Y) |
| 678 | DREAL(DOUBLE COMPLEX A) -> DOUBLE PRECISION |
| 679 | DFLOAT, DREAL |
| 680 | QEXT, QFLOAT, QREAL |
| 681 | DNUM, INUM, JNUM, KNUM, QNUM, RNUM - scan value from string |
| 682 | ZEXT |
| 683 | RAN, RANF |
| 684 | ILEN(I) = BIT_SIZE(I) |
| 685 | SIZEOF |
| 686 | MCLOCK, SECNDS |
| 687 | COTAN(X) = 1.0/TAN(X) |
| 688 | COSD, SIND, TAND, ACOSD, ASIND, ATAND, ATAN2D, COTAND - degrees |
| 689 | AND, OR, XOR |
| 690 | LSHIFT, RSHIFT |
| 691 | IBCHNG, ISHA, ISHC, ISHL, IXOR |
| 692 | IARG, IARGC, NARGS, NUMARG |
| 693 | BADDRESS, IADDR |
| 694 | CACHESIZE, EOF, FP_CLASS, INT_PTR_KIND, ISNAN, LOC |
| 695 | MALLOC |
| 696 | ``` |
peter klausler | 42b33da | 2018-09-29 00:02:11 | [diff] [blame] | 697 | |
Yi Wu | 18af032 | 2023-12-21 10:35:28 | [diff] [blame] | 698 | ### Library subroutine |
| 699 | ``` |
| 700 | CALL GETLOG(USRNAME) |
| 701 | ``` |
| 702 | |
Jean Perier | 878b526 | 2020-10-26 10:25:40 | [diff] [blame] | 703 | ## Intrinsic Procedure Name Resolution |
| 704 | |
| 705 | When the name of a procedure in a program is the same as the one of an intrinsic |
| 706 | procedure, and nothing other than its usage allows to decide whether the procedure |
| 707 | is the intrinsic or not (i.e, it does not appear in an INTRINSIC or EXTERNAL attribute |
| 708 | statement, is not an use/host associated procedure...), Fortran 2018 standard |
| 709 | section 19.5.1.4 point 6 rules that the procedure is established to be intrinsic if it is |
| 710 | invoked as an intrinsic procedure. |
| 711 | |
| 712 | In case the invocation would be an error if the procedure were the intrinsic |
| 713 | (e.g. wrong argument number or type), the broad wording of the standard |
| 714 | leaves two choices to the compiler: emit an error about the intrinsic invocation, |
| 715 | or consider this is an external procedure and emit no error. |
| 716 | |
| 717 | f18 will always consider this case to be the intrinsic and emit errors, unless the procedure |
| 718 | is used as a function (resp. subroutine) and the intrinsic is a subroutine (resp. function). |
| 719 | The table below gives some examples of decisions made by Fortran compilers in such case. |
| 720 | |
| 721 | | What is ACOS ? | Bad intrinsic call | External with warning | External no warning | Other error | |
| 722 | | --- | --- | --- | --- | --- | |
| 723 | | `print*, ACOS()` | gfortran, nag, xlf, f18 | ifort | nvfortran | | |
| 724 | | `print*, ACOS(I)` | gfortran, nag, xlf, f18 | ifort | nvfortran | | |
| 725 | | `print*, ACOS(X=I)` | gfortran, nag, xlf, f18 | ifort | | nvfortran (keyword on implicit extrenal )| |
| 726 | | `print*, ACOS(X, X)` | gfortran, nag, xlf, f18 | ifort | nvfortran | | |
| 727 | | `CALL ACOS(X)` | | | gfortran, nag, xlf, nvfortran, ifort, f18 | | |
| 728 | |
| 729 | |
| 730 | The rationale for f18 behavior is that when referring to a procedure with an |
| 731 | argument number or type that does not match the intrinsic specification, it seems safer to block |
| 732 | the rather likely case where the user is using the intrinsic the wrong way. |
| 733 | In case the user wanted to refer to an external function, he can add an explicit EXTERNAL |
| 734 | statement with no other consequences on the program. |
| 735 | However, it seems rather unlikely that a user would confuse an intrinsic subroutine for a |
| 736 | function and vice versa. Given no compiler is issuing an error here, changing the behavior might |
| 737 | affect existing programs that omit the EXTERNAL attribute in such case. |
| 738 | |
| 739 | Also note that in general, the standard gives the compiler the right to consider |
| 740 | any procedure that is not explicitly external as a non standard intrinsic (section 4.2 point 4). |
| 741 | So it is highly advised for the programmer to use EXTERNAL statements to prevent any ambiguity. |
| 742 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 743 | ## Intrinsic Procedure Support in f18 |
Jean Perier | 3774e9d | 2019-03-29 15:48:39 | [diff] [blame] | 744 | This section gives an overview of the support inside f18 libraries for the |
| 745 | intrinsic procedures listed above. |
| 746 | It may be outdated, refer to f18 code base for the actual support status. |
| 747 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 748 | ### Semantic Analysis |
Jean Perier | 3774e9d | 2019-03-29 15:48:39 | [diff] [blame] | 749 | F18 semantic expression analysis phase detects intrinsic procedure references, |
| 750 | validates the argument types and deduces the return types. |
| 751 | This phase currently supports all the intrinsic procedures listed above but the ones in the table below. |
| 752 | |
| 753 | | Intrinsic Category | Intrinsic Procedures Lacking Support | |
| 754 | | --- | --- | |
Katherine Rasmussen | 7dbbf77 | 2022-05-14 04:41:21 | [diff] [blame] | 755 | | Coarray intrinsic functions | IMAGE_INDEX, COSHAPE | |
Jean Perier | 3774e9d | 2019-03-29 15:48:39 | [diff] [blame] | 756 | | Object characteristic inquiry functions | ALLOCATED, ASSOCIATED, EXTENDS_TYPE_OF, IS_CONTIGUOUS, PRESENT, RANK, SAME_TYPE, STORAGE_SIZE | |
| 757 | | Type inquiry intrinsic functions | BIT_SIZE, DIGITS, EPSILON, HUGE, KIND, MAXEXPONENT, MINEXPONENT, NEW_LINE, PRECISION, RADIX, RANGE, TINY| |
Yi Wu | de58aa8 | 2023-11-13 10:31:36 | [diff] [blame] | 758 | | Non-standard intrinsic functions | AND, OR, XOR, SHIFT, ZEXT, IZEXT, COSD, SIND, TAND, ACOSD, ASIND, ATAND, ATAN2D, COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT, QCMPLX, DREAL, DFLOAT, QEXT, QFLOAT, QREAL, DNUM, NUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN, SIZEOF, MCLOCK, SECNDS, COTAN, IBCHNG, ISHA, ISHC, ISHL, IXOR, IARG, IARGC, NARGS, GETPID, NUMARG, BADDRESS, IADDR, CACHESIZE, EOF, FP_CLASS, INT_PTR_KIND, ISNAN, MALLOC | |
Jean Perier | 3774e9d | 2019-03-29 15:48:39 | [diff] [blame] | 759 | | Intrinsic subroutines |MVBITS (elemental), CPU_TIME, DATE_AND_TIME, EVENT_QUERY, EXECUTE_COMMAND_LINE, GET_COMMAND, GET_COMMAND_ARGUMENT, GET_ENVIRONMENT_VARIABLE, MOVE_ALLOC, RANDOM_INIT, RANDOM_NUMBER, RANDOM_SEED, SYSTEM_CLOCK | |
Katherine Rasmussen | ecedc4d | 2022-11-01 21:14:08 | [diff] [blame] | 760 | | Atomic intrinsic subroutines | ATOMIC_ADD | |
Katherine Rasmussen | bc2a85f | 2022-08-25 21:33:59 | [diff] [blame] | 761 | | Collective intrinsic subroutines | CO_REDUCE | |
Yi Wu | 18af032 | 2023-12-21 10:35:28 | [diff] [blame] | 762 | | Library subroutines | GETLOG| |
Jean Perier | 3774e9d | 2019-03-29 15:48:39 | [diff] [blame] | 763 | |
| 764 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 765 | ### Intrinsic Function Folding |
Jean Perier | 3774e9d | 2019-03-29 15:48:39 | [diff] [blame] | 766 | Fortran Constant Expressions can contain references to a certain number of |
| 767 | intrinsic functions (see Fortran 2018 standard section 10.1.12 for more details). |
| 768 | Constant Expressions may be used to define kind arguments. Therefore, the semantic |
| 769 | expression analysis phase must be able to fold references to intrinsic functions |
| 770 | listed in section 10.1.12. |
| 771 | |
| 772 | F18 intrinsic function folding is either performed by implementations directly |
| 773 | operating on f18 scalar types or by using host runtime functions and |
| 774 | host hardware types. F18 supports folding elemental intrinsic functions over |
| 775 | arrays when an implementation is provided for the scalars (regardless of whether |
| 776 | it is using host hardware types or not). |
| 777 | The status of intrinsic function folding support is given in the sub-sections below. |
| 778 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 779 | #### Intrinsic Functions with Host Independent Folding Support |
Jean Perier | 3774e9d | 2019-03-29 15:48:39 | [diff] [blame] | 780 | Implementations using f18 scalar types enables folding intrinsic functions |
| 781 | on any host and with any possible type kind supported by f18. The intrinsic functions |
| 782 | listed below are folded using host independent implementations. |
| 783 | |
| 784 | | Return Type | Intrinsic Functions with Host Independent Folding Support| |
| 785 | | --- | --- | |
| 786 | | INTEGER| ABS(INTEGER(k)), DIM(INTEGER(k), INTEGER(k)), DSHIFTL, DSHIFTR, IAND, IBCLR, IBSET, IEOR, INT, IOR, ISHFT, KIND, LEN, LEADZ, MASKL, MASKR, MERGE_BITS, POPCNT, POPPAR, SHIFTA, SHIFTL, SHIFTR, TRAILZ | |
| 787 | | REAL | ABS(REAL(k)), ABS(COMPLEX(k)), AIMAG, AINT, DPROD, REAL | |
| 788 | | COMPLEX | CMPLX, CONJG | |
| 789 | | LOGICAL | BGE, BGT, BLE, BLT | |
| 790 | |
Richard Barton | 271a7bb | 2020-09-11 13:17:19 | [diff] [blame] | 791 | #### Intrinsic Functions with Host Dependent Folding Support |
Jean Perier | f9ab321 | 2019-04-01 08:39:19 | [diff] [blame] | 792 | Implementations using the host runtime may not be available for all supported |
| 793 | f18 types depending on the host hardware types and the libraries available on the host. |
Jean Perier | 3774e9d | 2019-03-29 15:48:39 | [diff] [blame] | 794 | The actual support on a host depends on what the host hardware types are. |
| 795 | The list below gives the functions that are folded using host runtime and the related C/C++ types. |
| 796 | F18 automatically detects if these types match an f18 scalar type. If so, |
| 797 | folding of the intrinsic functions will be possible for the related f18 scalar type, |
Jean Perier | f9ab321 | 2019-04-01 08:39:19 | [diff] [blame] | 798 | otherwise an error message will be produced by f18 when attempting to fold related intrinsic functions. |
Jean Perier | 3774e9d | 2019-03-29 15:48:39 | [diff] [blame] | 799 | |
| 800 | | C/C++ Host Type | Intrinsic Functions with Host Standard C++ Library Based Folding Support | |
| 801 | | --- | --- | |
| 802 | | float, double and long double | ACOS, ACOSH, ASINH, ATAN, ATAN2, ATANH, COS, COSH, ERF, ERFC, EXP, GAMMA, HYPOT, LOG, LOG10, LOG_GAMMA, MOD, SIN, SQRT, SINH, SQRT, TAN, TANH | |
| 803 | | std::complex for float, double and long double| ACOS, ACOSH, ASIN, ASINH, ATAN, ATANH, COS, COSH, EXP, LOG, SIN, SINH, SQRT, TAN, TANH | |
| 804 | |
| 805 | On top of the default usage of C++ standard library functions for folding described |
| 806 | in the table above, it is possible to compile f18 evaluate library with |
| 807 | [libpgmath](https://github.com/flang-compiler/flang/tree/master/runtime/libpgmath) |
| 808 | so that it can be used for folding. To do so, one must have a compiled version |
| 809 | of the libpgmath library available on the host and add |
| 810 | `-DLIBPGMATH_DIR=<path to the compiled shared libpgmath library>` to the f18 cmake command. |
| 811 | |
| 812 | Libpgmath comes with real and complex functions that replace C++ standard library |
| 813 | float and double functions to fold all the intrinsic functions listed in the table above. |
| 814 | It has no long double versions. If the host long double matches an f18 scalar type, |
| 815 | C++ standard library functions will still be used for folding expressions with this scalar type. |
| 816 | Libpgmath adds the possibility to fold the following functions for f18 real scalar |
| 817 | types related to host float and double types. |
| 818 | |
| 819 | | C/C++ Host Type | Additional Intrinsic Function Folding Support with Libpgmath (Optional) | |
| 820 | | --- | --- | |
| 821 | |float and double| BESSEL_J0, BESSEL_J1, BESSEL_JN (elemental only), BESSEL_Y0, BESSEL_Y1, BESSEL_Yn (elemental only), ERFC_SCALED | |
| 822 | |
jeanPerier | 5d18a30 | 2019-04-03 08:26:46 | [diff] [blame] | 823 | Libpgmath comes in three variants (precise, relaxed and fast). So far, only the |
Jean Perier | 3774e9d | 2019-03-29 15:48:39 | [diff] [blame] | 824 | precise version is used for intrinsic function folding in f18. It guarantees the greatest numerical precision. |
| 825 | |
| 826 | ### Intrinsic Functions with Missing Folding Support |
| 827 | The following intrinsic functions are allowed in constant expressions but f18 |
| 828 | is not yet able to fold them. Note that there might be constraints on the arguments |
| 829 | so that these intrinsics can be used in constant expressions (see section 10.1.12 of Fortran 2018 standard). |
| 830 | |
| 831 | ALL, ACHAR, ADJUSTL, ADJUSTR, ANINT, ANY, BESSEL_JN (transformational only), |
| 832 | BESSEL_YN (transformational only), BTEST, CEILING, CHAR, COUNT, CSHIFT, DOT_PRODUCT, |
| 833 | DIM (REAL only), DOT_PRODUCT, EOSHIFT, FINDLOC, FLOOR, FRACTION, HUGE, IACHAR, IALL, |
| 834 | IANY, IPARITY, IBITS, ICHAR, IMAGE_STATUS, INDEX, ISHFTC, IS_IOSTAT_END, |
| 835 | IS_IOSTAT_EOR, LBOUND, LEN_TRIM, LGE, LGT, LLE, LLT, LOGICAL, MATMUL, MAX, MAXLOC, |
| 836 | MAXVAL, MERGE, MIN, MINLOC, MINVAL, MOD (INTEGER only), MODULO, NEAREST, NINT, |
| 837 | NORM2, NOT, OUT_OF_RANGE, PACK, PARITY, PRODUCT, REPEAT, REDUCE, RESHAPE, |
| 838 | RRSPACING, SCAN, SCALE, SELECTED_CHAR_KIND, SELECTED_INT_KIND, SELECTED_REAL_KIND, |
| 839 | SET_EXPONENT, SHAPE, SIGN, SIZE, SPACING, SPREAD, SUM, TINY, TRANSFER, TRANSPOSE, |
| 840 | TRIM, UBOUND, UNPACK, VERIFY. |
| 841 | |
| 842 | Coarray, non standard, IEEE and ISO_C_BINDINGS intrinsic functions that can be |
| 843 | used in constant expressions have currently no folding support at all. |
Yi Wu | e2b896a | 2024-01-10 10:02:48 | [diff] [blame^] | 844 | |
| 845 | ### Standard Intrinsics: EXECUTE_COMMAND_LINE |
| 846 | |
| 847 | #### Usage and Info |
| 848 | |
| 849 | - **Standard:** Fortran 2008 and later, specified in 16.9.73 |
| 850 | - **Class:** Subroutine |
| 851 | - **Syntax:** `CALL EXECUTE_COMMAND_LINE(COMMAND [, WAIT, EXITSTAT, CMDSTAT, CMDMSG ])` |
| 852 | - **Arguments:** |
| 853 | |
| 854 | | Argument | Description | |
| 855 | |-----------|--------------------------------------------------------------| |
| 856 | | `COMMAND` | Shall be a default CHARACTER scalar. | |
| 857 | | `WAIT` | (Optional) Shall be a default LOGICAL scalar. | |
| 858 | | `EXITSTAT`| (Optional) Shall be an INTEGER of the default kind. | |
| 859 | | `CMDSTAT` | (Optional) Shall be an INTEGER of the default kind. | |
| 860 | | `CMDMSG` | (Optional) Shall be a CHARACTER scalar of the default kind. | |
| 861 | |
| 862 | #### Implementation Specifics |
| 863 | |
| 864 | - **`COMMAND`:** |
| 865 | - Must be preset. |
| 866 | |
| 867 | - **`WAIT`:** |
| 868 | - If set to `false`, the command is executed asynchronously. If not preset or set to `false`, it is executed synchronously. |
| 869 | - Sync: achieved by passing command into `std::system` on all systems. |
| 870 | - Async: achieved by calling a `fork()` on POSIX-compatible systems, or `CreateProcess()` on Windows. |
| 871 | |
| 872 | - **`CMDSTAT`:** |
| 873 | - -2: No error condition occurs, but `WAIT` is present with the value `false`, and the processor does not support asynchronous execution. |
| 874 | - -1: The processor does not support command line execution. |
| 875 | - \+ (positive value): An error condition occurs. |
| 876 | - 1: Fork Error, where `pid_t < 0`, would only occur on POSIX-compatible systems. |
| 877 | - 2: Execution Error, a command exits with status -1. |
| 878 | - 3: Invalid Command Error, determined by the exit code depending on the system. |
| 879 | - On Windows, if the exit code is 1. |
| 880 | - On POSIX-compatible systems, if the exit code is 127 or 126. |
| 881 | - 4: Signal error, either it is stopped or killed by signal, would only occur on POSIX-compatible systems. |
| 882 | - 0: Otherwise. |
| 883 | |
| 884 | - **`CMDMSG`:** |
| 885 | - If an error condition occurs, it is assigned an explanatory message. Otherwise, it remains unchanged. |
| 886 | - If a condition occurs that would assign a nonzero value to `CMDSTAT` but the `CMDSTAT` variable is not present, error termination is initiated. |
| 887 | - On POSIX-compatible systems, this applies to both synchronous and asynchronous error termination. When the execution mode is set to async with error termination, the child process (async process) will be terminated with no effect on the parent process (continues). |
| 888 | - On Windows, this only applies to synchronous error termination. |