forums.silverfrost.com
Welcome to the Silverfrost forums

Author Message
JohnCampbell

Joined: 16 Feb 2006
Posts: 2172
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
mecej4

Joined: 31 Oct 2006
Posts: 1274

 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.
PaulLaidler

Joined: 21 Feb 2005
Posts: 6325
Location: Salford, UK

 Posted: Sat Jan 21, 2017 1:41 pm    Post subject: I have logged this for investigation.
PaulLaidler

Joined: 21 Feb 2005
Posts: 6325
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
JohnCampbell

Joined: 16 Feb 2006
Posts: 2172
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       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
mecej4

Joined: 31 Oct 2006
Posts: 1274

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
PaulLaidler

Joined: 21 Feb 2005
Posts: 6325
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".
PaulLaidler

Joined: 21 Feb 2005
Posts: 6325
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.
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First
 All times are GMT + 1 Hour Page 1 of 1