- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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-standards, 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)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for reporting this and for the concise reproducer. I escalated this to the Developers.
(Internal tracking id: DPD200417127)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>> 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you FortranFan for the added insight. I posted that in the internal tracking id.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page