This is a followup to a posting I sent on 27/10. I was having problems getting
a program to run in vector mode on a Fujitsu system. I had checked it on
the fuji with no vectorisation where it would run fine. I had also run it
on a Sun and SGI system where it also ran ok.
I'm grateful to those who replied. Most suggested it was a indicative of
writing beyond an array, which I had initially suspected. However, I'd tried
the array bounding checking options on the Sun, SGI and Fuji compilers and
none of them had spotted anything. This lead me to the possibility it might
be a compiler bug with vectorising the code near to the point where the program
crashed.
Fortunately (for me anyway), we'd just got the Portland Group compiler suite
for our linux systems. Tryng the program with the pgf90 compiler and their
array bounding checking turned on spotted the problem straight away. I'm still
somewhat surprised that none of the other compilers array bound checking
managed to spot it.
I have written a small test program which illustrates what happens. It's quite
a small code. It's available from
ftp://ftp.atm.ch.cam.ac.uk/staff/glenn/zbuck.tar.gz. Included in the file
are the various Makefiles for the machines/compilers I've tried it on.
I also append below the source code. The problem is caused by the assignment
marked in subroutine write_restart. The array l_ourotn is dynamic and
deliberately made too small for the assignment to the larger array ourotn.
Only the pgf90 compiler spotted this. The other compilers produce code that
runs on or crashes. I may not be using the most recent compilers on these
systems (certainly not for the Sun compiler) but I would be interested to know
if this error can be detected for other compilers.
I think I've just found my favourite f90 compiler! 8-)
Glenn
--
module grid
implicit none
integer, save :: ngrids, nlev
integer, save :: p2, nface, nedge, nvert
integer, save :: p4, nfacet, nedget, nvertt
integer, save :: nradg, nradf
contains
subroutine inires
implicit none
ngrids = 2
nlev = 5
! Compute the other sizes
nradg = ngrids
nradf = 5*(2**(2*nradg-1))+2
p2 = 2**(2*ngrids-1)
nface = 5*p2+2
nedge = 15*p2
nvert = 10*p2
p4 = (4**ngrids)-1
nfacet = 2*ngrids+(10*p4)/3
nedget = 10*p4
nvertt = (20*p4)/3
end subroutine inires
end module grid
module winds
use grid
implicit none
real, dimension(:,:), allocatable, save :: ourotn
real, dimension(:,:), allocatable, save :: pv
contains
function alloc_winds()
implicit none
integer :: alloc_winds, returncode
alloc_winds = 0
allocate( ourotn(nedge,nlev), pv(nface,nlev), stat=returncode )
if ( returncode /= 0 ) then
alloc_winds = returncode; return
endif
return
end function alloc_winds
end module winds
module restart
contains
subroutine write_restart( pv, ourotn )
implicit none
real, dimension(:,:) :: pv, ourotn
!!!!!! THIS IS THE ERROR !!!!!!!!!!!!
real, dimension(size(pv,1),size(pv,2)) :: l_ourotn
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
print *,'size of pv : ',size(pv,1), size(pv,2)
print *,'size of ourotn : ',size(ourotn,1), size(ourotn,2)
print *,'size of l_ourotn : ',size(l_ourotn,1),size(l_ourotn,2)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ourotn = l_ourotn
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
return
end subroutine write_restart
end module restart
program zbuck
! this program is a small test based on a much larger programme
! and is designed to demonstrate how some compilers fail to spot
! the array bound exception
use grid
use winds
use restart
implicit none
integer :: iret
call inires
iret = alloc_winds()
! Initialise with any old thing
ourotn = 3.142
pv = 10.1234
call write_restart( pv, ourotn )
print *,'ourotn '
print *,ourotn
print *,'pv '
print *,pv
stop
end program
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|