I don't see the point of this error. The code in question is
jp(2,2:4)=0
whereby the beginning of the corresponding subroutine declares:
subroutine findphase(p,T,nph,ip,jp,Mg,clap,xc,xctr,dpph,pphtr)
implicit none
integer, intent(out) :: nph,ip(*),jp(2,*)
and the calling subroutine has the following:
integer, parameter :: maxss=7,maxc=8
integer :: i,j,ii,ns,mph,nph,im(maxss),ip(maxc),jp(2,maxc)
In my opinion, there's no way that this code should produce the above
error message. Am I missing some syntax issue here, or is this a bug
in gfortran? Could the problem possibly lie somewhere else, so that
the error is misleading?
I have tried the same code with ifort v.8.1 and didn't get out-of-
bounds error messages.
Tom
There is insufficient information. In particular, the actual code
exhibiting the problem is missing.
Also note, you'll probably get better support on a vendor's mailing
list/forum than you'll get here.
> In article <1192167136.8...@e9g2000prf.googlegroups.com>,
> Tom <flurb...@mailinator.com> writes:
> > Fortran runtime error: Array reference out of bounds, upper bound of
> > dimension 2 of array 'jp' exceeded, 2 is greater than 0
...
> > integer, intent(out) :: nph,ip(*),jp(2,*)
...
> There is insufficient information. In particular, the actual code
> exhibiting the problem is missing.
As Steve said, one would need to see much more to be sure. However....
I'll note that bounds checking and assumed-size arrays don't generally
go well together. Very few compilers can handle that combination well.
Fundamentally, with the usual implementation of assumed-size arrays, the
information needed for bounds checking just isn't there. Assumed-shape
arrays are a *VERY* different matter.
--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain
> integer, intent(out) :: nph,ip(*),jp(2,*)
> jp(2,2:4)=0
This is a bug in gfortran. I filled it as:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33745
The should be no check of the upper bound of dimension as it is
unknown in the subroutine. (Except the compiler uses some special
tricks to make the information available to the subroutine, which
gfortran does not do.)
If you have the choice, I would use either
integer, intent(out) :: nph,ip(nIP),jp(2,nJP)
(where the integers nIP and nJP is passed to the subroutine)
or I would use assumed-shape arrays:
integer, intent(out) :: nph,ip(:),jp(2,:)
which, however, can only be used with an explicit interface.
In either of the two cases, the compiler can easily check the upper
bound of ip and dimension 2 of jp.
Tobias
after I changed my program from using fixed arrays to dynamic arrays
I got a slowdown of about 50%, which is definitely due to dynamic
arrays. Is this because of gfortran (version 4.1.2) or a normal fortran
behaviour. Does any know a workaround (if possible I would like to avoid
pointers) ?
My program does something like:
-------------- Module --------------------------
module PowerFunc
implicit none
integer, parameter :: dp = selected_real_kind(15, 300)
real(kind=dp), dimension(:), allocatable :: numbers
contains
subroutine init(nx)
integer, intent(in) :: nx
integer :: i
! save
allocate(numbers(0:nx+1))
do i=0,nx
numbers(i) = i
enddo
end subroutine init
subroutine calculate(pencil_num, nx)
implicit none
integer, intent(in) :: nx
real(kind=dp) :: pencil_num(0:nx)
integer :: i, j
do j=0, 1000
do i=0, nx
pencil_num(i) = numbers(i) * numbers(i)
enddo
enddo
end subroutine calculate
subroutine finalize
deallocate (numbers)
end subroutine
end module powerFunc
---------------------------------- Main routine ------------
program main
use PowerFunc
! , only : init, calculate, finalize
implicit none
! integer, parameter :: dp = selected_real_kind(15, 300)
real(kind=dp), target, dimension(:), allocatable :: pencil_num
integer :: nx, i ,j
nx = 500
allocate(pencil_num(0:nx))
call init(nx)
do j=0, 6000
call calculate(pencil_num, pencil_1, nx)
enddo
call finalize()
end program main
----------------------------------------------------------------
before all variables were declared as e.g. real :: numbers(0:500)...
Thanks for reading & helping
Paul
(snip)
> I'll note that bounds checking and assumed-size arrays don't generally
> go well together. Very few compilers can handle that combination well.
> Fundamentally, with the usual implementation of assumed-size arrays, the
> information needed for bounds checking just isn't there. Assumed-shape
> arrays are a *VERY* different matter.
I did complain about a compiler that didn't check the lower bound
for assumed size arrays with bounds checking turned on. There doesn't
seem much reason not to do that. Otherwise, yes.
-- glen
I took the above program and expanded it a bit, so that it uses
three different methods:
- Your original, with the computation being performed on numbers as a
module variable
- One with numbers passed as an argument
- One with a static array (in the main program) passed as an argument
I measured the time via system_clock().
I used CVF and gfortran on Windows XP and got somewhat odd results:
- CVF definitely likes it better when you pass the array as an
argument.
The first method is about 15-20% slower (on two measurements, so not
that much)
- gfortran seems to prefer numbers passed as an argument and not the
static array
(that is twice as slow!). The first method is 20% slower (but this
is just
one measurement - running the program takes at least a couple of
minutes, and
my patience runs out faster)
During the runs my machine was not doing much else, but such
measurements usually
are very difficult to interpret - only with a large number of runs do
you get
stable results.
The general wisdom, IIRC, is that allocatable arrays can be a bit
slower than statics,
but pointers (as they can point to different pieces of memory) are
worse.
In other (test) programs I did not notice any significant difference.
Regards,
Arjen
In gfortran, the problem is that the static module variable is assumed
to be contiguous whereas the allocatable module variable is assumed to
be (potentially) not contiguous and thus the offset/stride calculation
slows down the program.
As I fail to come up with a method to generate strides/offsets for
module variables (or for that matter, any non-pointer, non-dummy
variable) I regard this a missed optimization bug and filled a
bugreport. (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33753)
> I took the above program and expanded it a bit, so that it uses
> three different methods:
> - Your original, with the computation being performed on numbers as a
> module variable
> - One with numbers passed as an argument
> - One with a static array (in the main program) passed as an argument
>
> I measured the time via system_clock().
>
> I used CVF and gfortran on Windows XP and got somewhat odd results:
> - CVF definitely likes it better when you pass the array as an
> argument.
> The first method is about 15-20% slower (on two measurements, so not
> that much)
I would not be surprised if CVF had the same problem as gfortran.
I assume you did not use an assume-shaped array for the test, or did
you?
> - gfortran seems to prefer numbers passed as an argument and not the
> static array
> (that is twice as slow!). The first method is 20% slower (but this
I can reproduce this: Using the allocatable module variable is of
cause much slower, but I also can reproduce that the static version is
slightly slower than passing an allocated variable. (Though I do not
have any idea why the latter is the case happens.)
If the size is known at compile time, using
pencil_num = arraynum(0:nx) ! nx = parameter
should be much faster as gfortran then uses memcopy, which is faster
than assigning the values in a loop.
Tobias
All I can contribute is that bugs that move around when write statements
are changed are almost always the result of accessing an array (writing
to it) outside its bounds.
You might think that. I couldn't possibly comment ;-)
> Unfortunately, the inconsistence with the output remains. The code is
> more than 1500 lines long, so I can't post it here; to describe the
> problem shortly in words, with gfortran I get different results for
> some variables depending on whether a write statement is commented out
> or not. This doesn't happen when compiling with ifort. I'm trying to
> find out if there's something else screwed up with my passing to and
> fro of arrays, but I have rather little hope to find something.
> General ideas of what kind of fault could cause this and why it
> happens only with gfortran but not with ifort are welcome nonetheless.
Uninitialized variables can also cause this sort of problem.
You might want to try building with and without optimization just to see
what happens. I'm not 100% sure that the results will tell you anything
useful, but you never know.
Louis
No, Richard M already commented on that earlier in the thread...
--
Subscript checking is usually only against the LOCAL declaration which
results from the call. It may or may not match the ACTUAL declaration
on the other side of the call. Explicit-size and assumed-size can be
lied to rather easily once one gets past beginner status. The strong
debugging systems pass descriptors and check the local declaration
against the actual declaration at considerable cost in both time and
complication. So there are few strong debugging systems. Salford (aka
Silverfrost) is the current example that I am aware of. The old WatFor
was an earlier example.
Undefined checking is another feature of strong debugging systems but
is distinct from the passing of descriptors to do the strong subscript
checking. Undefined variables are a common cause of bad subscripts
so finding undefineds will often cure the problem for which a bad
subscript is only a delayed symptom.
Another source of Heisenbugs (those that change when you add another
line of output etc) is mismatched calls but those are usually caught
at an early stage by strong debugging systems. The good static checkers
can find many, but not all, mismatched calls. F90 when fully used makes
mismatched calls almost nonexistent.
Well, as any software gfortran is neither bugfree nor feature
complete; there are several cases of out-of-bound bugs which are
currently undetected especially when using intrinsics such as MERGE.
Other reasons for such behaviour are:
- Uninitialized variables
- Mismatch between actual arguments and dummy arguments. If one uses
an explicit interface, the compiler has the chance to detect this. For
assumed-shape dummies one needs an explicit interface.
- Unstable algorithm; adding/removing code changes the code path (esp.
on x86 as the register of the x87 processor uses more digits than the
variable stored in RAM). [Probably not the case here, though.]
> The code is more than 1500 lines long, so I can't post it here; to
> describe the problem shortly in words, with gfortran I get different
> results for some variables depending on whether a write statement is
> commented out or not. This doesn't happen when compiling with ifort.
Use "-Wall -Wsurprising -std=f2003" with gfortran and "-check all -
warn all -stand f03" when you compile with ifort and check whether you
find something.
Using a newer gfortran 4.3.0 the -finit* options such as -finit-
real=nan (quiet NaN) might detect uninitialized variables. Or use -
finit-local-zero if your program requires initialized local variables,
which some older programs assume.
Tobias
PS: If you think this is a bug in gfortran, feel free to fill a bug
report or to send me the code as private mail. (Include usage
instructions, a note what goes wrong and what is the expected result,
your platform and gfortran version ("gfortran -v") and the options you
used to compile the program.)
Why are you using the -fbounds-check option. Clearly,
your code is bug free and perfect.
>
> Other reasons for such behaviour are:
>
[snip]
> - Unstable algorithm; adding/removing code changes the code path (esp.
> on x86 as the register of the x87 processor uses more digits than the
> variable stored in RAM). [Probably not the case here, though.]
gcc supports the following option:
`-ffloat-store'
Do not store floating point variables in registers, and inhibit
other options that might change whether a floating point value is
taken from a register or memory.
This option prevents undesirable excess precision on machines such
as the 68000 where the floating registers (of the 68881) keep more
precision than a `double' is supposed to have. Similarly for the
x86 architecture. For most programs, the excess precision does
only good, but a few programs rely on the precise definition of
IEEE floating point. Use `-ffloat-store' for such programs, after
modifying them to store all pertinent intermediate computations
into variables.
Although it didn't appear in the gfortran documentation, it appears to
accept this option also. However, this sort of problem problem shows
up as a binary built for an architecture whose FPU uses IEEE 754 double
precision as its native floating point format (e.g. Alpha or PowerPC)
produces slightly different results than a binary built for an
architecture whose FPU uses extended precision as its native floating
point format (e.g. Intel x86 and Motorola 68000).
Chip
--
Charles M. "Chip" Coldwell
"Turn on, log in, tune out"
Somerville, Massachusetts, New England
"The gfortran command supports all the options supported by the gcc
command. Only options specific to GNU Fortran are documented here.
See GCC Command Options, for information on the non-Fortran-specific
aspects of the gcc command (and, therefore, the gfortran command)."
--
FX