Print

Print


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



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%