Lines Matching full:rank
8 # Assumed-Rank Objects
10 An assumed-rank dummy data object is a dummy argument that takes its rank from
12 SELECT RANK in the `RANK DEFAULT` block. Its rank is not known at compile
13 time. The rank can be anything from 0 (scalar) to the maximum allowed rank in
17 This document summarizes the contexts where assumed-rank objects can appear,
33 - 8.5.8.7 Assumed-rank entity
37 - 11.1.10 SELECT RANK
47 Assumed-rank can:
52 - appear as an actual argument of an assumed-rank dummy (C838)
53 - appear as the selector of SELECT RANK (C838)
56 inquiry functions listed in table 16.1 are detailed in the "Assumed-rank
60 assumed-rank to be associated with an assumed-size.
63 Assumed-rank cannot:
77 With regard to aliasing, assumed-rank dummy objects follow the same rules as
79 the actual is a scalar (adding that TARGET assumed-rank may alias if the actual
86 ## Assumed-Rank Representations in Flang
89 In semantics (there is no concept of assumed-rank expression needed in
92 "assumed-rank-shape" (can be tested with IsAssumedRank()), or they have
93 `semantics::AssocEntityDetails` (associated entity in the RANK DEFAULT case).
95 Inside a select rank, a `semantics::Symbol` is created for the associated
97 and holds the rank outside of the RANK DEFAULT case.
99 Assumed-rank dummies are also represented in the
101 represent assumed-rank in procedure characteristics.
109 corresponding entity is passed as an assumed-rank.
111 This means that any descriptor can be passed to an assumed-rank dummy (with
114 arguments of any ranks already work with assumed-rank entities without any
118 assumed-rank based on its descriptor, but there seems to be not need for this
119 so far ("rank based" dispatching for user defined assignments and IO is not
121 for the runtime to distinguish between finalization of an assumed-rank and
122 finalization of other entities: only the runtime rank matters).
125 assumed-rank cannot be precisely known at compile time, and this impacts the
127 maximized using the maximum rank, which the runtime code already does when
132 Note that an alternative to maximizing the allocation of assumed-rank temporary
133 descriptor could be to use automatic allocation based on the rank of the input
138 allocation to the maximum rank.
141 SSA values for assumed-rank entities have an MLIR type containing a
155 There is no need to allow assumed-rank "expression" in HLFIR (hlfir.expr) since
156 assumed-rank cannot appear in expressions (except as the actual argument to an
157 assumed-rank dummy). Assumed-rank are variables. Also, since they cannot have
161 FIR/HLFIR operation where assumed-rank may appear:
167 fields of assumed-rank descriptors).
168 - as `fir.box_rank` operand (rank inquiry).
170 assumed-rank in a compile time constant dimension).
174 - as `fir.absent` result (passing absent actual to OPTIONAL assumed-rank dummy)
177 copy-out of assumed-rank)
178 - as `fir.alloca` type and result (when creating an assumed-rank POINTER dummy
184 - `fir.box_tdesc` and `fir.box_typecode` (polymorphic assumed-rank cannot
185 appear in a SELECT TYPE directly without using a SELECT RANK). Given the
188 position of the type descriptor pointer depends on the rank.
192 descriptor can be created with the entity rank, and then casted via
195 It is not expected for any other FIR or HLFIR operations to handle assumed-rank
204 will also allow creating rank-one assumed-size descriptor from an input
205 assumed-rank descriptor to cover the SELECT RANK `RANK(*)` case.
213 likely benefit the non assumed-rank case too (even though LLVM is quite good at
216 It will be ensured that all the operation listed above accept assumed-rank
223 Assumed-rank descriptor types are lowered to the LLVM type of a CFI_cdesc_t
227 to address the first descriptor fields in LLVM (to get the base address, rank,
232 ## Assumed-rank Features
234 This section list the different Fortran features where assumed-rank objects are
237 ### Assumed-rank in procedure references
238 Assumed-rank arguments are implemented as being the address of a CFI_cdesc_t.
240 When passing an actual argument to an assumed-rank dummy, the following points
243 - Creation of forwarding of the assumed-rank dummy descriptor (including when
245 - Finalization, deallocation, and initialization of INTENT(OUT) assumed-rank
248 OPTIONAL assumed-ranks are implemented like other non assumed-rank OPTIONAL
249 objects passed by descriptor: an absent assumed-rank is represented by a null
252 The passing interface for assumed-rank described above and below is compliant
253 by default with the BIND(C) case, except for the assumed-rank dummy descriptor
257 VALUE is forbidden for assumed-rank dummies, so there is nothing to be done for
259 with creating assumed-rank copies, so it would likely not be an issue to relax
264 to a non POINTER CONTIGUOUS assumed-rank.
290 When the actual is also an assumed-rank special the same copy-in/copy-out need
297 maximum rank with the same type as the input descriptor and only the descriptor
315 #### Creating the descriptor for assumed-rank dummies
321 4. Actual has an assumed-rank descriptor that cannot be forwarded for the dummy
324 has if it has the rank of the actual argument. This is the same logic as when
326 an extra cast to the assumed-rank descriptor type is added (no-op at runtime).
329 for an assumed-size still has the rank of the assumed-size, a rank-one
330 descriptor will be created for it if needed in a RANK(*) block (nothing says
331 that an assumed-size should be passed as a rank-one array in 15.5.2.4 point 17).
333 For the second case, a cast is added to assumed-rank descriptor type if it is
338 done when passing to an assume shape dummy, and a cast to the assumed-rank
356 the same situations than with non assumed-rank arguments, but when passing
357 assumed-rank to assumed-ranks, the cost of this extra copy is higher.
359 #### Intent(out) assumed-rank finalization, deallocation, initialization
361 The standard prevents INTENT(OUT) assumed-rank requiring finalization to be
364 actual is not an assumed-size and not a nonpointer nonallocatable assumed-rank.
369 descriptor and can be directly used with an assumed-rank descriptor with no
377 assumed-rank descriptors with no changes (like any runtime API taking
378 descriptors of any rank).
395 ### Select Rank
397 Select rank is implemented with a rank inquiry (and last extent for `RANK(*)`),
399 to a descriptor with the associated entity rank for the current block for the
400 `RANK(cst)` cases. In the `RANK DEFAULT`, the input descriptor is kept with no
401 cast, and in the RANK(*), a rank-one descriptor is created with the same
405 implemented. The `RANK(*)` is a bit odd, it detects assumed-ranks associated
406 with an assumed-size arrays regardless of the rank, and takes precedence over
407 any rank based matching.
416 The implementation of SELECT RANK is done as follow:
417 - Read the rank `r` in the descriptor
418 - If there is a `RANK(*)`, read the extent in dimension `r`. If it is `-1`,
419 jump to the `RANK(*)` block. Otherwise, continue to the steps below.
420 - For each `RANK(constant)` case, compare `constant` to `r`. Stop at first
423 - Jump to `RANK DEFAULT` block is any. Otherwise jump to the end of the
428 since the select-rank selector is a named entity and cannot be a temporary with
431 Except for the `RANK(*)` case, the branching logic is implemented in FIR with a
432 `fir.select_case` operating on the rank.
454 select rank (y => x)
455 rank(*)
457 rank(0)
459 rank(1)
461 rank default
549 #### RANK
550 Implemented inline with `fir.box_rank` which simply reads the descriptor rank
559 %rank = fir.box_rank %x : (!fir.box<!fir.array<*xf32>>) -> i32
564 a runtime check that RANK <= DIM. Pointers and allocatables are dereferenced,
571 with assumed shapes. When DIM is absent, the result is a rank-one array whose
572 extent is the rank. The runtime has an entry for UBOUND that takes a descriptor
593 PRECISION, RADIX, RANGE, TINY all accept assumed-rank, but are always constant
598 Assumed-rank cannot be coarrays (C837), but they can still technically appear
615 shape/rank dummy (18.5.3 point 3).
651 ## Annex 2 - Assumed-Rank Objects and IGNORE_TKR
654 - Set IGNORE_TKR(TK) on assumed-rank dummies (but TYPE(*) is better when
656 - Pass an assumed-rank to an IGNORE_TKR(R) dummy that is not passed
661 - Set IGNORE_TKR(R) on an assumed-rank dummy.
685 MPI_f08 module makes usage of assumed-rank (see