Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
6 Views

Incorrect reallocation of the LHS on assignment

The attached code prints

$ ./test
 Before:            2
 After:            1 ; w =  0.6000000    

which is incorrect, since the shape of w should not change during the
assignment (no need for reallocation, and in any case the rhs has two
elements).

Notice that using w(:) solves the problem.

Compiled with
$ ifort test.f90 -o test
$ ifort -V
Intel(R) Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 17.0.1.132 Build 20161005

program p
 implicit none

 integer, allocatable :: ii(:)
 real,    allocatable :: w(:), zz(:,:)

  allocate( ii , source=(/2,1/) )
  allocate( zz(2,2) , w(2) )

  zz(:,1) = 0.3
  zz(:,2) = 0.6

  write(*,*) "Before: ", shape(w)
  w = zz(1,ii)
  !w(:) = zz(1,ii) ! no problems here
  write(*,*) "After: ", shape(w), "; w =", w

end program p

 

0 Kudos
17 Replies
Highlighted
Black Belt
6 Views

There was a change in the

There was a change in the default value of the -assume realloc_lhs option when the 2017 compiler came out. Please see https://software.intel.com/en-us/articles/intel-fortran-compiler-support-for-fortran-language-standa..., where you can see (at almost the end) this notice:

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)

0 Kudos
Highlighted
6 Views

mecej4,

mecej4,

Line 14 in #1 has

array = scalar

Why would array w get reallocated in this situation?

IOW, if line 14 were changed to

w = 1.0

Are you expecting w to be reallocated to an array of 1 element???

Jim Dempsey

0 Kudos
Highlighted
Valued Contributor III
6 Views

This looks like a bug in

This looks like a bug in Intel Fortran with the use of vector-subscript in the array assignment shown on line 14:

https://software.intel.com/en-us/node/678553

 

0 Kudos
Highlighted
Valued Contributor I
6 Views

Actually, with gfortran 4.8.4

Actually, with gfortran 4.8.4 this gives an ICE. nagfor 6.1 is fine and gives array shape 2, as expected. ifort 16 also gives array shape 2, so this seems to be a regression in ifort 17. gfortran 7.0.0 also gives the expected 2 for the array shape, as well as PGI 16.10.

0 Kudos
Highlighted
Black Belt
6 Views

Quote:jimdempseyatthecove

jimdempseyatthecove wrote:
 mecej4,

Line 14 in #1 has

     array = scalar

Why would array w get reallocated in this situation? 

Sorry, I did not make an analysis of the code. I simply remembered that there had been a recent change in the default behavior of IFort and brought that to the OP's attention.

0 Kudos
Highlighted
Beginner
6 Views

Quote:mecej4 wrote:

mecej4 wrote:

Quote:

jimdempseyatthecove wrote:
 mecej4,

 

Line 14 in #1 has

     array = scalar

Why would array w get reallocated in this situation? 

 

Sorry, I did not make an analysis of the code. I simply remembered that there had been a recent change in the default behavior of IFort and brought that to the OP's attention.

At line 14, ii is an array, so this is indeed  array = array  (as noted by FortranFan in #4) and there is no need to reallocate the lhs. I think that this is a compiler bug in ifort 17.

0 Kudos
Highlighted
6 Views

oops, my bad, should have

oops, my bad, should have looked at the declaration of ii (it is an array not a scalar). You are right, this is (analogous to) a gather of zz. I should have read the code more closely. (bad habit of me using i, ii, iii as loop indices).

ii is a 1 dimensional array, z(1,ii) equivalent to z(1,[2,1]) produces a 1 dimensional array with two elements. w should not have been reallocated, however if it had been (due to the compiler not necessarily knowing the shape of ii) then it should have been reallocated into a 1 dimensional array with two elements.

Jim Dempsey

0 Kudos
Highlighted
Beginner
6 Views

Quote:jimdempseyatthecove

jimdempseyatthecove wrote:

oops, my bad, should have looked at the declaration of ii (it is an array not a scalar). You are right, this is (analogous to) a gather of zz. I should have read the code more closely. (bad habit of me using i, ii, iii as loop indices).

ii is a 1 dimensional array, z(1,ii) equivalent to z(1,[2,1]) produces a 1 dimensional array with two elements. w should not have been reallocated, however if it had been (due to the compiler not necessarily knowing the shape of ii) then it should have been reallocated into a 1 dimensional array with two elements.

Jim Dempsey

Indeed. Just one comment: given that the size of the lhs matches the rhs, reallocation is forbidden by the standard if I understand it correctly. This could be relevant in case the lhs is a TARGET, or in case it is has a derived type with a finalizer.

Marco

0 Kudos
Highlighted
Employee
6 Views

Thank you for reporting this

Thank you for reporting this and for the concise reproducer. I escalated this to the Developers.

(Internal tracking id: DPD200417127)

0 Kudos
Highlighted
6 Views

>> Just one comment: given

>> Just one comment: given that the size of the lhs matches the rhs, reallocation is forbidden by the standard if I understand it correctly.

Various versions of the compiler generated code to do the reallocation regardless of the necessity, this may have been fixed. It wouldn't hurt to verify to assert if the (:) should be used or not. There was a similar issue with the unnecessary creation of a temporary array (this too may be fixed by now).

Jim Dempsey

0 Kudos
Highlighted
Valued Contributor III
6 Views

Quote:Kevin D (Intel) wrote:

Kevin D (Intel) wrote:

Thank you for reporting this and for the concise reproducer. I escalated this to the Developers.

(Internal tracking id: DPD200417127)

Kevin,

As noted by Juergen R. above, this would appear to be a regression in compiler 17, perhaps even update 1 (I didn't check initial release) since compiler 16, update 4 seems to work as expected.

Now, please note regression such as these are worrisome for users, it will be reassuring if Intel Fortran team were to share more on the regression testing and the QA procedure(s) followed for new compiler version updates.  You have to admit at some point bugs like these shouldn't get past beta-testing phase, let alone customer updates.

0 Kudos
Highlighted
Employee
6 Views

Hi FortranFan – It does fail

Hi FortranFan – It does fail with the initial 17.0 release also. We have an extensive regression suite used to test the compilers and each test case we receive as a defect report is added to it. Our internal reporting system also has fields permitting us to tag reports as a regression and those are specifically watched and tracked. We really do try hard to avoid regressions and any defects in general because we do recognize how worrisome both of those are to customers. I can’t speak to the complete details of the testing since I don’t exercise it myself, but I am aware that Developer’s changes, development branches, and release candidates are tested extensively on a regular basis and at key points within our release cycle. It is impossible to test every possible feature combination and I expect that nothing representative like this case exists in our regression suite today otherwise it would have been seen earlier and addressed. We’ll know more about the root cause of this case once Development has investigated it further. If there’s something more that I can provide you regarding the testing to reassure you about that then please let me know.

0 Kudos
Highlighted
Beginner
6 Views

Kevin, thank you for the

Kevin, thank you for the feedback and the tracking ID.

Concerning comments #12 and #13, I would like to mention two more points:

1) the problem disappears if zz has rank one, i.e. w = zz(1,ii) does not work but w = zz_rank1(ii) works fine (I did not test different ranks). Without knowing the compiler internals, I can imagine that covering all the possible use cases for modern fortran is a formidable task for a test suite.

2) given 1), I think that the importance of updating-compilers, running unit-tests, reporting compiler-bugs is largely underestimated in the community of the fortran users.

Marco

0 Kudos
Highlighted
Employee
6 Views

Thank you Marco, I will pass

Thank you Marco, I will pass along those additional findings.

Development also just noted in the internal tracking report a relationship to vector-subscript (as FortranFan surmised) and that another workaround is to use -assume norealloc_lhs for this case.

0 Kudos
Highlighted
Beginner
6 Views

Quote:Kevin D (Intel) wrote:

Kevin D (Intel) wrote:

Development also just noted in the internal tracking report a relationship to vector-subscript (as FortranFan surmised)

Yes, sorry for not mentioning this explicitly in the first post. Indeed the test was rather mininal.

Kevin D (Intel) wrote:

and that another workaround is to use -assume norealloc_lhs for this case.

OK, thank you.

0 Kudos
Highlighted
Valued Contributor III
6 Views

Quote:Kevin D (Intel) wrote:

Kevin D (Intel) wrote:

Hi FortranFan – .. We’ll know more about the root cause of this case once Development has investigated it further...

Kevin,

Thanks much for your feedback.  We look forward to further improvements in the upcoming updates this year and a real step up with respect to Fortran standard support in the next major release.

Re: "the root cause of this case", perhaps you can feed back to Intel Fortran Development there appears to be some connection to array element order in Fortran and thus the contiguous nature, or lack thereof, of the address in memory of the source data used with a vector subscript in an assignment.  Please see below a slightly modified example of the one in the original post and how the result is as expected for the case when source address is contiguous in memory:

program p

   implicit none

   integer, allocatable :: ii(:)
   real, allocatable :: zz(:,:)
   real, allocatable :: u(:)
   real, allocatable :: w(:)

   allocate( ii , source=[ 2,1 ] )
   allocate( zz(2,2), u(2), w(2) )

   zz(1,1) = 0.3
   zz(1,2) = 0.6
   zz(2,1) = 0.4
   zz(2,2) = 0.8

   write(*,*) "Before: shape(u) = ", shape(u)
   u = zz(ii,1)
   write(*,*) "After: shape(u) = ", shape(u), "; u =", u

   write(*,*) "Before: shape(w) = ", shape(w)
   w = zz(1,ii)
   write(*,*) "After: shape(w) = ", shape(w), "; w =", w

   stop

end program p

Upon execution with compiler 17, update 2:

 Before: shape(u) =  2
 After: shape(u) =  2 ; u = 0.4000000 0.3000000
 Before: shape(w) =  2
 After: shape(w) =  1 ; w = 0.6000000

 

0 Kudos
Highlighted
Employee
6 Views

Thank you FortranFan for the

Thank you FortranFan for the added insight. I posted that in the internal tracking id.

0 Kudos