Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Automatic reallocation of arrays in IVF 19.0.2.190

avinashs
New Contributor I
635 Views

When an allocatable array that was allocated as (say) allocate(arr(5)) is subsequently assigned values using (say) arr = [1, 2, 3], the variable arr is automatically reallocated to be of size 3 i.e. arr(3) in IVF 19.0.2.190.

(a) Is there a way to suppress this automatic reallocation? In a fairly general program, I had accidentally used the wrong number of elements to initialize arr and it created several subsequent errors in other allocatable arrays when arr was used in expressions involving those arrays.
(b) How recent is this change in behavior? I remember this type of situation triggering a runtime error.

A toy example is provided below although this did not generate any errors.

program main
  
  implicit none
  integer(kind = 4) :: n
  integer(kind = 4), dimension(:), allocatable :: x, y, z
  
  n = 5

  allocate(x(n), y(n), z(n))

  x = 1
  y = 2
  z = 3
  
  write(*,*) 'x = ', x
  write(*,*) 'size(x) = ', size(x)

  ! in the step below:
  ! ... size of x changed automatically to 2
  x = [2, 3]
  
  write(*,*) 'x = ', x
  write(*,*) 'size(x) = ', size(x)

  ! in the step below:
  ! ... size of y also changed automatically to 2
  ! ... operation performed is y(1:2) = x(1:2) + z(1:2)
  y = x + z 

  write(*,*) 'y = ', y
  write(*,*) 'size(y) = ', size(y)

  write(*,*) 'z = ', z
  write(*,*) 'size(z) = ', size(z)
  
  deallocate(z, y, x)

  read *
  
end program main
Output:

 x =            1           1           1           1           1
 size(x) =            5
 
 x =            2           3
 size(x) =            2
 
 y =            5           6
 size(y) =            2
 
 z =            3           3           3           3           3
 size(z) =            5

 

0 Kudos
8 Replies
andrew_4619
Honored Contributor II
635 Views

From help: 

NOTE: Compiler version 17.0 changed the default behavior to be that of /assume:realloc_lhs (-assume realloc_lhs). To disable that behavior in version 17.0 or later, use /assume:norealloc_lhs (-assume norealloc_lhs) or /nostandard-realloc-lhs (-nostandard-realloc-lhs)

For more information, please refer to the "Compiler Options" section of the Intel Fortran Compiler documentation.

0 Kudos
IanH
Honored Contributor II
635 Views
>ifort /check:all /warn:all "2019-03-07 auto-alloc.f90"
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 19.0.2.190 Build 20190117
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.00.24215.1
Copyright (C) Microsoft Corporation.  All rights reserved.

"-out:2019-03-07 auto-alloc.exe"
-subsystem:console
"2019-03-07 auto-alloc.obj"


>"2019-03-07 auto-alloc.exe"
 x =            1           1           1           1           1
 size(x) =            5
 x =            2           3
 size(x) =            2
forrtl: warning (406): fort: (33): Shape mismatch: The extent of dimension 1 of array X is 2 and the corresponding extent of array Z is 5

Image              PC                Routine            Line        Source
2019-03-07 auto-a  00007FF62E1FDD01  Unknown               Unknown  Unknown
2019-03-07 auto-a  00007FF62E1F1F65  Unknown               Unknown  Unknown
2019-03-07 auto-a  00007FF62E252402  Unknown               Unknown  Unknown
2019-03-07 auto-a  00007FF62E2530A9  Unknown               Unknown  Unknown
KERNEL32.DLL       00007FF84B6B3DC4  Unknown               Unknown  Unknown
ntdll.dll          00007FF84BF43691  Unknown               Unknown  Unknown
 y =            5           6
 size(y) =            2
 z =            3           3           3           3           3
 size(z) =            5

You can disable this standard language feature with /assume:norealloc_lhs.

The compiler has only provided shape checking for array expressions and assignments in the last few years or so - a similar timeframe to the F2003 assignment semantics for allocatables being enabled by default.

Mismatches in shape in array expressions are a serious program bug (or mismatches in shape when assigning to non-allocatable arrays).  Do not rely on the observed behaviour with any particular version of the compiler.

 

0 Kudos
avinashs
New Contributor I
635 Views

Thanks for the prompt replies. I added the option /assume:norealloc_lhs under Command Line -> Additional Options in MSVS17 (I could not find the setting for this on the interface). However, in this case no error was generated but the sizes of x, y were preserved. Hence, y(1:2) = x(1:2) + z(1:2) was executed without changing the sizes of x and y. Is there a further setting to generate an error when an array of size 2 is assigned to an array declared to be of size 5? i.e.

x(1:2) = [2,3]    ! no error
x = [2,3]           ! error

0 Kudos
FortranFan
Honored Contributor II
635 Views

avinashs wrote:

.. Is there a further setting to generate an error when an array of size 2 is assigned to an array declared to be of size 5? ..

Look at run-time checking options, especially shape: https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-check

0 Kudos
avinashs
New Contributor I
635 Views

I am seeing a somewhat unexpected behavior (to me) when I added /assume:norealloc_lhs. The code executes without error but the last 3 elements of y are changed to 4 while I would have expected them to remain at 2. Clearly, this is an error that should not be made. Unfortunately, I have a lot of code that makes use of x = [...] to initialize arrays as part of class constructors.

Output with /assume:norealloc_lhs

 x =            1           1           1           1           1
 size(x) =            5
 x =            2           3           1           1           1
 size(x) =            5
 y =            5           6           4           4           4
 size(y) =            5
 z =            3           3           3           3           3
 size(z) =            5

 

0 Kudos
avinashs
New Contributor I
635 Views

@IanH, @FortranFan. Thanks for the suggestions. I added  /warn:all /check:all /check:bounds /check:shape to the options but have not been warned of any errors.

0 Kudos
FortranFan
Honored Contributor II
635 Views

avinashs wrote:

.. I added  /warn:all /check:all /check:bounds /check:shape to the options but have not been warned of any errors.

@avinashs,

You may want to engage with Intel Online Support Center (OSC) to get *better clarity* on the /check and /warn compiler options e.g., /check:all should cover /check:bounds and /check:shape but does it really?  Also you may want to discuss whether there are any bugs or gaps in Intel Fortran team's intended implementation of these options, particularly with /check:shape.

For example, consider the following trivial code:

   integer, allocatable :: x(:)
   allocate( x(5), source=1 )
   x = [ 2, 3 ]
   print *, "x = ", x
end

And the following:

C:\Temp>ifort /assume:norealloc_lhs /check:shape p.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64,
Version 19.0.2.190 Build 20190117
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.16.27027.1
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:p.exe
-subsystem:console
p.obj

C:\Temp>p.exe
 x =            2           3           1           1           1

C:\Temp>

I expect the run-time checking to flag an error at the non-conforming instruction on line 3 given the /assume:norealloc_lhs and /check:shape options but no exception is raised.  So you can inquire with Intel support as to why this is the case.  Or perhaps someone from Intel Fortran team will post an explanation here.

Note with the above simple code, you can add the following tidbits which is that prima facie the /assume:norealloc_lhs feature appears to work as the Fortran standard option of using whole array section section which suppresses reallocation of LHS in the intrinsic assignment. as shown below.  Under the circumstances, the instruction on line 3 in the example below is again non-conforming:  And the compiler provides NO exception without /check:shape but it raises a run-time error when this option is in effect.  If so, why does the compiler not do the same in the above case?

   integer, allocatable :: x(:)
   allocate( x(5), source=1 )
   x(:) = [ 2, 3 ]
   print *, "x = ", x
end

 

C:\Temp>type p.f90
   integer, allocatable :: x(:)
   allocate( x(5), source=1 )
   x(:) = [ 2, 3 ]
   print *, "x = ", x
end

C:\Temp>ifort /standard-semantics p.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64,
Version 19.0.2.190 Build 20190117
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.16.27027.1
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:p.exe
-subsystem:console
p.obj

C:\Temp>p.exe
 x =  2 3 1 1 1

C:\Temp>ifort /standard-semantics /check:shape p.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64,
Version 19.0.2.190 Build 20190117
Copyright (C) 1985-2019 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.16.27027.1
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:p.exe
-subsystem:console
p.obj

C:\Temp>p.exe
forrtl: severe (408): fort: (33): Shape mismatch: The extent of dimension 1 of array
X is 5 and the corresponding extent of array <RHS expression> is 2

Image              PC                Routine            Line        Source
p.exe              00007FF6FB8F4E01  Unknown               Unknown  Unknown
p.exe              00007FF6FB8F1168  Unknown               Unknown  Unknown
p.exe              00007FF6FB940B92  Unknown               Unknown  Unknown
p.exe              00007FF6FB940F20  Unknown               Unknown  Unknown
KERNEL32.DLL       00007FFCC4001FE4  Unknown               Unknown  Unknown
ntdll.dll          00007FFCC4C8CB81  Unknown               Unknown  Unknown

C:\Temp>

 

0 Kudos
Reply