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

Optimization issue: reallocation of array in a contained procedure not recognized.

FortranFan
Honored Contributor II
532 Views

With initial release of compiler 17.0, in code generated with the compiler optimization of /On where n>0, reallocation of array in a contained procedure does not seem to be recognized fully e.g., SIZE function result does not change.  /O0 works as expected.  I have not had a chance to try update 1 of 17.0 yet.

program p

   implicit none

   integer, parameter :: N = 1
   integer, allocatable :: foo(:)

   allocate( foo(N) )

   print *, "Before reallocation:"
   print *, "size(foo) = ", size(foo)

   call realloc()

   print *
   print *, "After reallocation:"
   print *, "size(foo) = ", size(foo)

   stop

contains

   subroutine realloc()

      integer, allocatable :: tmp(:)

      allocate( tmp(2*N) )
      call move_alloc( from=tmp, to=foo )

      return

   end subroutine realloc

end program p

Upon execution with /On where n>0,

 Before reallocation:
 size(foo) =  1

 After reallocation:
 size(foo) =  1

 

0 Kudos
12 Replies
Johannes_Rieke
New Contributor III
532 Views

Dear FortranFan,

I tested your code I could not reproduce the behavior with PSXE 2017 intitial and update 1 with /O3 in x32 and x64.

 Before reallocation:
 size(foo) =            1

 After reallocation:
 size(foo) =            2

Strangely, I thought I had seen something like this in my code some days ago. I used reallocation (move_alloc) also and called this in a module contained subroutine and was wondering, why my control output missed some lines. At the end I figured out that it was gone after a clean rebuild (/O2 PSXE 2017 update 1, x64, old build was done with PSXE 2016 update3). Could this be caused by some objects mixed?

Hopefully it will work for you with update 1. Best regards, Johannes

0 Kudos
Steven_L_Intel1
Employee
532 Views

I can reproduce this in Update 1. I know I've reported this problem before but so far I can't locate the previous report. I'll keep looking.

0 Kudos
Steven_L_Intel1
Employee
532 Views

Ah, found it. That case works now, though - this one doesn't. Will investigate.

0 Kudos
Steven_L_Intel1
Employee
532 Views

Escalated as issue DPD200415640.

0 Kudos
Johannes_Rieke
New Contributor III
532 Views

Hi Steve,

can you share the condition, when this simple example fails? As shown above, I could not reproduce it, but you and FortranFan can. I can reproduce the test case results in the other thread where PSXE 17 initial fails and 17 update 1 works fine.

Under what circumstances occur this problem? I'm asking, because I use move_alloc massively in my projects and cannot test it in every case. To know when exactly DPD200415640 shows up would be very helpful and would let me sleep better ;-)

Best regards, Johannes

0 Kudos
FortranFan
Honored Contributor II
532 Views

Johannes wrote:

.. Under what circumstances occur this problem? I'm asking, because I use move_alloc massively in my projects and cannot test it in every case. To know when exactly DPD200415640 shows up would be very helpful and would let me sleep better ;-) ..

@Johannes,

See this first!! http://www.searchquotes.com/search/Sleep_Is_Overrated/

With the example in the original post,

C:\..>ifort /O2 /standard-semantics /stand /warn:all p.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R
) 64, Version 17.0.1.143 Build 20161005
Copyright (C) 1985-2016 Intel Corporation.  All rights reserved.

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

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

C:\..>p.exe
 Before reallocation:
 size(foo) =  1

 After reallocation:
 size(foo) =  1

 

0 Kudos
Johannes_Rieke
New Contributor III
532 Views

Hi FortranFan,

thanks for your answer. Not that I sleep much, but sometimes it helps to defrag my brain ;-)

I can reproduce the error now, if I build from console with exactly your build instruction:

D:\02_Fortran\99_test\Realloc_PSXE17>ifort /O2 /standard-semantics /stand /warn:
all Realloc_PSXE17.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R
) 64, Version 17.0.1.143 Build 20161005
Copyright (C) 1985-2016 Intel Corporation.  All rights reserved.

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

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

-->
 Before reallocation:
 size(foo) =  1

 After reallocation:
 size(foo) =  1

, but not if I build from VS2015 with:

Compiling with Intel(R) Visual Fortran Compiler 17.0.1.143 [Intel(R) 64]...
ifort /nologo /O2 /standard-semantics /warn:all /module:"x64\Release\\" /object:"x64\Release\\" /Fd"x64\Release\vc140.pdb" /libs:static /threads /c /stand /Qlocation,link,"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\\bin\amd64" /Qm64 "D:\02_Fortran\99_test\Realloc_PSXE17\Realloc_PSXE17.f90"
Linking...
Link /OUT:"x64\Release\Realloc_PSXE17.exe" /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"x64\Release\Realloc_PSXE17.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /SUBSYSTEM:CONSOLE /IMPLIB:"D:\02_Fortran\99_test\Realloc_PSXE17\x64\Release\Realloc_PSXE17.lib" -qm64 "x64\Release\Realloc_PSXE17.obj"
Embedding manifest...
mt.exe /nologo /outputresource:"D:\02_Fortran\99_test\Realloc_PSXE17\x64\Release\Realloc_PSXE17.exe;#1" /manifest "x64\Release\Realloc_PSXE17.exe.intermediate.manifest"

Realloc_PSXE17 - 0 error(s), 0 warning(s)

--> 
 Before reallocation
 size(foo) =  1

 After reallocation:
 size(foo) =  2

Strange. I also run the VS build instruction in the shell and I can reproduce the error too (ifort /nologo /O2 /standard-semantics /warn:all /libs:static /threads /c /stand /Qm64 Realloc_PSXE17.f90 path stuff removed). Where is the difference and why fails the console build?

Best regards, Johannes

0 Kudos
andrew_4619
Honored Contributor II
532 Views

For what it is worth I also get the same output as #7 in both 32 and 64 bit builds. 

 

0 Kudos
andrew_4619
Honored Contributor II
532 Views
program p

   implicit none

   integer, parameter :: N = 1
   integer, allocatable :: foo(:)

   allocate( foo(N) )

   print *, "Before reallocation:"
   print *, "size(foo) = ", size(foo)

   call realloc()

   print *
   print *, "After reallocation:"
   print *, "size(foo) = ", size(foo)
   
   foo(1)=1
   foo(2)=2
   print *, "foo = ", foo
   print *, "foo(1), foo(2) = ", foo(1), foo(2)

   stop

contains

   subroutine realloc()

      integer, allocatable :: tmp(:)

      allocate( tmp(2*N) )
      call move_alloc( from=tmp, to=foo )

      return

   end subroutine realloc

end program p
!******output*******
! Before reallocation:
! size(foo) =  1
! 
! After reallocation:
! size(foo) =  1
! foo =  1
! foo(1), foo(2) =  1 2

For what it is worth it is not just SIZE that is wrong the whole array op to write foo also fails so I assume there will be a host of consequential failures as a result of this bug. 

0 Kudos
Steven_L_Intel1
Employee
532 Views

It's an optimization that is failing - it thinks that the descriptor isn't changing in the subroutine but it is. Like most optimization bugs, it won't show up in all programs that do this sort of thing.

0 Kudos
Steven_L_Intel1
Employee
532 Views

I am told that this bug has been fixed and that the fix should appear in Update 2 to Parallel Studio XE 2017.

0 Kudos
FortranFan
Honored Contributor II
532 Views

Thanks for the feedback Steve.

0 Kudos
Reply