Intel® Fortran Compiler Classic and Intel® Fortran Compiler Developer Guide and Reference

ID 767251
Date 11/07/2023
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

Handle Fortran Array Descriptors

For cases where Standard Fortran needs to keep track of more than a pointer memory address, the Intel® Fortran Compiler uses an array descriptor, which stores the details of how an array is organized.

When using an explicit interface (by association or procedure interface block), the compiler generates a descriptor for the following types of array arguments:

  • Fortran array pointers

  • Assumed-shape arrays

  • Allocatable arrays

  • Coarrays

  • Class objects

Certain types of arguments do not use a descriptor, even when an appropriate explicit interface is provided. For example, explicit-shape and assumed-size arrays do not use a descriptor. In contrast, array pointers and allocatable arrays use descriptors regardless of whether they are used as arguments.

When calling between Intel® Fortran and C/C++, use an implicit interface, which allows the array argument to be passed without an Intel® Fortran descriptor. However, for cases where the called routine needs the information in the Intel® Fortran descriptor, declare the routine with an explicit interface and specify the dummy array as either an assumed-shape array or with the pointer attribute.

You can associate a Fortran array pointer with any piece of memory, organized in any way desired (as long as it is "rectangular" in terms of array bounds). You can also pass Fortran array pointers to the C language, and have it correctly interpret the descriptor to obtain the information it needs.

The downside to using array descriptors is that it can increase the opportunity for errors. Additionally, the corresponding code is not portable. Specifically:

  • If the descriptor is not defined correctly, the program may access the wrong memory address, possibly causing a General Protection Fault.

  • Array descriptor formats are specific to each Fortran compiler. Code that uses array descriptors is not portable to other compilers or platforms.

  • The array descriptor format may change in the future.

  • If the descriptor was built by the compiler, it cannot be modified by the user. Changing fields of existing descriptors is illegal.

The components of the current Intel® Fortran array descriptor on systems using IA-32 architecture are as follows:

  • Bytes 0 to 3 contain the base address.

  • Bytes 4 to 7 contain the size of a single element of the array.

  • Bytes 8 to 11 are reserved and should not be explicitly set.

  • Bytes 12 to 15 contain a set of flags used to store information about the array. This includes:

    • bit 1 (0x01): array is defined -- set if the array has been defined (storage allocated).

    • bit 2 (0x02): no deallocation allowed -- set if the array pointed to cannot be deallocated (that is, it is an explicit array target).

    • bit 3 (0x04): array is contiguous -- set if the array pointed to is a contiguous whole array or slice.

    • bit 8 (0x80): set if the array pointed to is ALLOCATABLE.

    • Other bits are reserved.

  • Bytes 16 to 19 contain the number of dimensions (rank) of the array.

  • Bytes 20 to 23 are reserved and should not be explicitly set.

  • The remaining bytes contain information about each dimension (up to 31). Each dimension is described by a set of three 4-byte entities:

    • The number of elements (extent).

    • The distance between the starting address of two successive elements in this dimension, in bytes.

    • The lower bound.

An array of rank one requires three additional 4-byte entities for a total of nine 4-byte entities (6 + 3*1) and ends at byte 35. An array of rank seven is described in a total of twenty-seven 4-byte entities (6 + 3*7) and ends at byte 107. Consider the following declaration:

   integer,target :: a(10,10)
  integer,pointer :: p(:,:)
  p => a(9:1:-2,1:9:3)
  call f(p)
...

The descriptor for actual argument p would contain the following values:

  • Bytes 0 to 3 contain the base address (assigned at runtime).

  • Bytes 4 to 7 are set to 4 (size of a single element).

  • Bytes 8 to 11 are reserved.

  • Bytes 12 to 15 contain 3 (array is defined and deallocation is not allowed).

  • Bytes 16 to 19 contain 2 (rank).

  • Bytes 20 to 23 are reserved.

  • Bytes 24 to 35 contain information for the first dimension, as follows:

    • 5 (extent).

    • -8 (distance between elements).

    • 9 (the lower bound).

  • For the second dimension, bytes 36 to 47 contain:

    • 3 (extent).

    • 120 (distance between elements).

    • 1 (the lower bound).

  • Byte 47 is the last byte for this example.

NOTE:
The format for the descriptor on systems using Intel® 64 architecture is identical to that on systems using IA-32 architecture, except that all fields are 8-bytes long, instead of 4-bytes.