Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.5k views
in Technique[技术] by (71.8m points)

fortran - Output formatting with the write statement via gfortran

I used to the Intel fortran compiler which supports using the <n> extension like

write(*, '(<n>(2I4))') (i, 2*i, i=1,n)

To illustrate, I give a s1_fprint.f90 subroutine as follows

subroutine fprint(name,bb)

IMPLICIT NONE
character(len=*), intent(in) :: name
real, intent(in) :: bb(:,:)
integer :: column=10
integer i,j,k,m,n

n = size(bb,1)
m = size(bb,2)

write(*,'(1a)')name
do k=0,m/column-1
    write(*, '(1x,<column>i16)')(i,i=k*column+1,(k+1)*column)
    write(*,'(1i10,<column>f)')(i,(bb(i,j),j=k*column+1,(k+1)*column),i=1,n)
    write(*,'(/)')
end do
if(mod(m,column)/=0)then
    write(*, '(1x,<m-m/column*column>i16)')(i,i=m/column*column+1,m)
    write(*,'(1i10,<m-m/column*column>f)')(i,(bb(i,j),j=m/column*column+1,m),i=1,n)
    write(*,'(/)')
endif

end subroutine fprint

Now, I change the Intel fortran compiler to gfortran, then I test (t1_useSur.f90) above subroutine in gfortran as follows:

program main

implicit none
real :: A(2,3) = reshape([1.2, 2.3, 3.4, 4.5, 5.6, 6.7], [2,3])

call fprint('A',A)

end program main

which should show us something like

A
            1              2              3
    1      1.2000000      3.4000001      5.5999999
    2      2.3000000      4.5000000      6.6999998

However, in gfortran compiler when I run

gfortran t1_useSur.f90 s1_fprint.f90 -o out
./out

there are many errors as

.s1_fprint.f90:14.17:

    write(*, '(1x,<column>i16)')(i,i=k*column+1,(k+1)*column)
                1
Error: Unexpected element '<' in format string at (1)
.s1_fprint.f90:15.19:

    write(*,'(1i10,<column>f)')(i,(bb(i,j),j=k*column+1,(k+1)*column),i=1,n)
                1
Error: Unexpected element '<' in format string at (1)
.s1_fprint.f90:19.17:

    write(*, '(1x,<m-m/column*column>i16)')(i,i=m/column*column+1,m)
                1
Error: Unexpected element '<' in format string at (1)
.s1_fprint.f90:20.19:

    write(*,'(1i10,<m-m/column*column>f)')(i,(bb(i,j),j=m/column*column+1,m),i=
                1
Error: Unexpected element '<' in format string at (1)

Since the <n> extension is not supported by gfortran, how can fix these problems?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Near dupe Variable format statement when porting from Intel to GNU gfortran

For the 1-dim cases like (i,i=...) :

  • If you have (or get) a version of gfortran that supports F08, which browsing https://gcc.gnu.org/onlinedocs/ appears to be around 4.6.4 up, use * as the count like (1x,*i16)

  • Otherwise, use the old-as-the-hillsF77 trick: since format repetitions or items 'beyond' the data list are ignored, just use a repetition count that is at least as big as the data will ever be (but not more than HUGE(0)) here (1x,10i16) is actually enough but something like (1x,999i16) makes it much more obvious

  • or if you like extra work, do on-the-fly like the 2-dim case below

For the 2-dim cases like (i,(bb(i,j),j=...),i=...) which currently use format looping to insert record breaks either:

  • reduce to 1-dim by making the record breaks into separate WRITEs:
    do i=...
        write(*,'(1i10,*f)') i,(bb(i,j),j=...)
    end do !i
  • generate the correct count on-the-fly:
    character(len=20) fmt
    ...
    write(fmt,'(a,i0,a)') '(1i10,', numcols_expression, 'f)'
    write(*, trim(fmt)) (i,(bb(i,j),j=...),i=...)
    ... or ...
    write(fmt,'(i0)') numcols_expression
    write(*, '(1i10,'//trim(fmt)//'f)') (i,bb(i,j),j=...),i=...)

PS: you don't actually need 1i10 just i10, but I left it for consistency. Also rather than a loop for the full chunks then an if for the partial chunk, which have to be kept in sync, I would probably do:

    do k=1,m,column
      l=min(k+column-1,m)
      ... print chunk for i=k,l (numcols is l-k+1) ...
    end do !k

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...