Array Shape Check: New in Intel® Fortran Compiler 19.0 BETA

Array Shape Check: New in Intel® Fortran Compiler 19.0 BETA

The array shape checking feature implemented in Intel® Fortran Compiler 19.0 BETA checks for array shape conformance where it is required by the Fortran standard. When enabled, the compiler checks contexts at compile-time and will generate code that checks at run-time that the shapes of arrays conform in various contexts where conformance is required. Try this compiler option to help debug a program with arrays!

To enable array shape checking, compile with -check shape (Linux* and macOS*) or /check:shape (Windows*). Using this code as an example,

program t3
  implicit none
  real(8) :: a(20)=1,b(20)=2
  integer :: n=10,m=20
  a(1:10)=3
  b(1:m)=b(1:m)+a(1:n)
  print *,b
end program t3

the array shape mismatch is detected at runtime. This example output is on Linux and is similar for Windows.

ifort -check shape t3.f90
a.out
forrtl: severe (408): fort: (33): Shape mismatch: The extent of dimension 1 of array B is 20 and the corresponding extent of array A is 10

Image              PC                Routine            Line        Source     
a.out              0000000000405400  Unknown               Unknown  Unknown
a.out              0000000000402CA9  Unknown               Unknown  Unknown
a.out              0000000000402C1E  Unknown               Unknown  Unknown
libc-2.17.so       00007F3285A74AF5  __libc_start_main     Unknown  Unknown
a.out              0000000000402B29  Unknown               Unknown 
a.out              0000000000402C1E  Unknown               Unknown  Unknown
libc-2.17.so       00007F93C172BAF5  __libc_start_main     Unknown  Unknown
a.out              0000000000402B29  Unknown               Unknown  Unknown

The severe error can be changed to a warning by also compiling with -warn shape (Linux and macOS) or /warn:shape (Windows) and the program prints the warning and traceback and, in this case, runs to completion.

ifort -check shape -warn shape t3.f90
a.out
forrtl: warning (406): fort: (33): Shape mismatch: The extent of dimension 1 of array B is 20 and the corresponding extent of array A is 10

Image              PC                Routine            Line        Source     
a.out              0000000000405420  Unknown               Unknown  Unknown
a.out              0000000000402D1B  Unknown               Unknown  Unknown
a.out              0000000000402C1E  Unknown               Unknown  Unknown
libc-2.17.so       00007F51932C3AF5  __libc_start_main     Unknown  Unknown
a.out              0000000000402B29  Unknown               Unknown  Unknown
   5.00000000000000        5.00000000000000        5.00000000000000
   5.00000000000000        5.00000000000000        5.00000000000000
   5.00000000000000        5.00000000000000        5.00000000000000
   5.00000000000000        3.00000000000000        3.00000000000000
   3.00000000000000        3.00000000000000        3.00000000000000
   3.00000000000000        3.00000000000000        3.00000000000000
   3.00000000000000        3.00000000000000

Add -traceback to get more information about the runtime failure. In the traceback in the example below, notice that the shape mismatch is on line 6.

ifort -check shape -traceback t3.f90
a.out
forrtl: severe (408): fort: (33): Shape mismatch: The extent of dimension 1 of array B is 20 and the corresponding extent of array A is 10

Image              PC                Routine            Line        Source     
a.out              00000000004055C0  Unknown               Unknown  Unknown
a.out              0000000000402E58  MAIN__                      6  t3.f90
a.out              0000000000402C1E  Unknown               Unknown  Unknown
libc-2.17.so       00007F13720E8AF5  __libc_start_main     Unknown  Unknown
a.out              0000000000402B29  Unknown               Unknown  Unknown

With the Fortran 2003 standard for an array assignment, if the LHS (left hand side) is an allocatable array, by default the compiler does the following:

  • If the LHS is not allocated, allocate it to the size of the RHS (right hand side).
  • If the LHS is allocated, but is not the same size as the RHS, then deallocate the LHS and reallocate to the size of the RHS.
  • Do the actual array assignment.

As a result, for assignments with an allocatable array on the LHS, there can be no LHS/RHS shape violation. However, if you specify -assume norealloc_lhs (Linux and macOS) or /assume:norealloc_lhs (Windows) or -nostandard-realloc-lhs (Linux and macOS) or /nostandard-realloc-lhs (Windows), then the Fortran 90/95 behavior for allocatable arrays is used, and the allocatable array on the LHS must have the same size as the RHS.

For example, given the following code:

PROGRAM TR
  IMPLICIT NONE
  INTEGER, ALLOCATABLE :: A(:),B(:)
  ALLOCATE(A(20))
  ALLOCATE(B(10))
  A(:) = 10
  B = A
  WRITE(*,*) B(1)
END TR

There is no shape violation, by default, since B will be automatically re-sized to the size of A. If -assume norealloc_lhs is specified, however, a violation does occur, and will be reported, if array shape checking is enabled.

When the array shape check compiler option is enabled, these contexts are checked:

  • right-hand and left-hand side of intrinsic and elemental defined assignments,
  • the operands of intrinsic and elemental defined binary operations,
  • two or more array arguments to ELEMENTAL procedures,
  • the ARRAY= and MASK= arguments to intrinsic procedures as required,
  • and the arguments to the intrinsic module procedures IEEE_SET_FLAG and IEEE_SET_HALTING_MODE.

Array shape checking is also enabled by including -check (Linux and macOS) or /check (Windows) in the compile command.

Add this compiler option to your debugging toolkit!

 

† An array’s shape is determined by its rank and number of extents. The rank is the number of dimensions of the array and the number of elements in a dimension is called the extent of the array.

 

For more complete information about compiler optimizations, see our Optimization Notice.