|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Sat Jan 21, 2017 12:59 am Post subject: Array asignment problem |
|
|
The following example of array assignment fails with FTN95 Ver 8.05 for both 32 and /64.
The array a is not correctly assigned, as LHS = calculation of RHS array.
I am assuming this is valid Fortran 90/95 syntax ?
32 and 64 give different wrong results. Code: | ! Test of array assignment
! expected result
! a = 1 1 2 3 4
! b = 1 1 2 4 8
!
! fails with ftn95 /lgo
! fails with ftn95 /64 /lgo
!
implicit none
integer :: i, a(5) = 1, b(5) = 1
!
! array assignment
a(2:5) = (/ (sum(a(1:i-1)),i = 2,5) /)
write (*,*) ' a=',a
!
! DO loop asignment
do i = 2,5
b(i) = sum(b(1:i-1))
end do
print '(A,5I2)',' a =',a,' b =',b
end program |
|
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1885
|
Posted: Sat Jan 21, 2017 3:02 am Post subject: |
|
|
With the 32-bit compiler, the option /check causes integer overflow to be detected during the array expression evaluation and assignment. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7916 Location: Salford, UK
|
Posted: Sat Jan 21, 2017 1:41 pm Post subject: |
|
|
I have logged this for investigation. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7916 Location: Salford, UK
|
Posted: Mon Apr 15, 2019 1:02 pm Post subject: |
|
|
I have carried out an initial investigation of this issue. There is certainly a bug in FTN95 when SUM is used within this particular array constructor. But there is a more fundamental issue which arises with similar cases when calling any function (not just the intrinsic SUM).
If the value of A(3) say depends on A(2) and/or A(1) then FTN95 will probably give an "incorrect" result. This is also the case with gFortran and perhaps other compilers as well.
The Fortran Standard does indeed say that an implied DO within an array constructor should be expanded element by element but the issue of feedback is not mentioned and one might naturally assume that the RHS can be evaluated as a block before copying to the LHS.
My initial investigation suggests that a vast amount of work would be needed in order to "fix" this more fundamental issue and I am not convinced that it ought to be "fixed".
If anyone has the interest and has access to other compilers then you might like to test the output from following code.
Code: | integer function mysum(a)
integer a(:)
mysum = sum(a)
end function
program main
interface
integer function mysum(a)
integer a(:)
end function
end interface
integer :: i, a(5) = 1
a(2:5) = (/ (mysum(a(1:i-1)),i = 2,5) /)
print*, a
do i = 2,5
a(i) = sum(a(1:i-1))
end do
print*, a
end program |
|
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Tue Apr 16, 2019 5:41 am Post subject: |
|
|
Paul,
FTN95 and gFortran results are the same when run in Plato (with slight changes)
Code: |
integer function mysum(a)
integer a(:)
mysum = sum(a)
end function
program main
interface
integer function mysum(a)
integer a(:)
end function
end interface
integer :: i, a(5) = 1
open (unit=98,file='mysum.log',position='append')
call echo_dll_version
a(2:5) = (/ (mysum(a(1:i-1)),i = 2,5) /)
write ( *,*) a , ' = (/ (mysum(a(1:i-1)),i = 2,5) /) '
write (98,*) a , ' = (/ (mysum(a(1:i-1)),i = 2,5) /) '
do i = 2,5
a(i) = sum(a(1:i-1))
end do
write ( *,*) a , ' = do i=2,5; a(i) = sum(a(1:i-1)); end do '
write (98,*) a , ' = do i=2,5; a(i) = sum(a(1:i-1)); end do '
end program
subroutine echo_dll_version
!
character str_info*256
!
call get_compiler_version (str_info)
write ( *,1000) ' compiler_version : ', trim (str_info)
write (98,1000) ' compiler_version : ', trim (str_info)
call get_compiler_options (str_info)
write ( *,1000) ' compiler_options : ', trim (str_info)
write (98,1000) ' compiler_options : ', trim (str_info)
write ( *,1000) ' '
write (98,1000) ' '
1000 FORMAT (a,a)
!
RETURN
!
END
subroutine get_compiler_version ( version )
!gf use iso_fortran_env
character version*(*)
character ftn95_ver*80
!
!gf version = compiler_version ()
!
include <ftn95_ver.ins>
version = ftn95_ver
end
subroutine get_compiler_options ( options )
!gf use iso_fortran_env
character options*(*)
!
!gf options = compiler_options ()
options = 'FTN95 options not available'
end
compiler_version : GCC version 8.2.0
compiler_options : -cpp -iprefix c:\program files (x86)\gcc_eq\gcc_8.2.0\bin\../lib/gcc/x86_64-w64-mingw32/8.2.0/
-U_REENTRANT -mtune=generic -march=x86-64 -fno-underscoring -fdollar-ok
1 1 2 3 4 = (/ (mysum(a(1:i-1)),i = 2,5) /)
1 1 2 4 8 = do i=2,5; a(i) = sum(a(1:i-1)); end do
compiler_version : [FTN95/x64 Ver. 8.40.0 Nov18 Copyright (c) Silverfrost Ltd 1993-2018]
compiler_options : FTN95 options not available
1 1 2 3 4 = (/ (mysum(a(1:i-1)),i = 2,5) /)
1 1 2 4 8 = do i=2,5; a(i) = sum(a(1:i-1)); end do
|
|
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1885
|
Posted: Tue Apr 16, 2019 7:54 am Post subject: |
|
|
In an assignment statement, the effect should be the same as if the expression on the right of the '=' is completely evaluated before the variable or array section on the left is assigned the value(s) calculated. In other words, there can be no feedback of newly computed values of array elements into the remaining expression evaluations.
The calculations of the elements of the array valued expression and putting those values into the elements of the array section may be carried out in any order -- not necessarily in the order of increasing index i.
Consider the following modification of John's original example program:
Code: | ! Test of array assignment
! expected result
! a = 4 3 2 1 1
!
! garbage output with ftn95 /lgo
! access violation with ftn95 /64 /lgo
!
implicit none
integer :: i, a(5) = 1
!
! array assignment
a(1:4) = (/ (sum(a(i+1:5)),i = 1,4) /)
write (*,*) ' a=',a
end program |
Each element of a is to be set equal to the sum of the original values of the elements that come after it in increasing index order. The EXE from the 32-bit FTN95 compiler gives garbage output, and the 64-bit compiler produces a program that aborts with an access violation. If /check or /checkmate are used, further errors occur.
Last edited by mecej4 on Wed Apr 17, 2019 9:14 am; edited 2 times in total |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7916 Location: Salford, UK
|
Posted: Tue Apr 16, 2019 7:58 am Post subject: |
|
|
John
Your results confirm my experience. If these results are both "correct" then an implied DO within an array constructor is not equivalent to a explicit DO loop in situations like this where there is "feedback". |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7916 Location: Salford, UK
|
Posted: Sat May 04, 2019 4:11 pm Post subject: |
|
|
This issue has now been fixed for the next release of FTN95 after 8.50. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|