Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Valued Contributor III

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

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
Highlighted
New Contributor III

Dear FortranFan,

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
Highlighted

I can reproduce this in

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.

Retired 12/31/2016
0 Kudos
Highlighted

Ah, found it. That case works

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

Retired 12/31/2016
0 Kudos
Highlighted

Escalated as issue

Escalated as issue DPD200415640.

Retired 12/31/2016
0 Kudos
Highlighted
New Contributor III

Hi Steve,

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
Highlighted
Valued Contributor III

Quote:Johannes wrote:

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
Highlighted
New Contributor III

Hi FortranFan,

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
Highlighted
Valued Contributor II

For what it is worth I also

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

 

0 Kudos
Highlighted
Valued Contributor II

program p

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
Highlighted

It's an optimization that is

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.

Retired 12/31/2016
0 Kudos
Highlighted

I am told that this bug has

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

Retired 12/31/2016
0 Kudos
Highlighted
Valued Contributor III

Thanks for the feedback Steve

Thanks for the feedback Steve.

0 Kudos