1828587 Members
3003 Online
109983 Solutions
New Discussion

Re: FORTRAN Debugger

 
Michael Menge
Frequent Advisor

FORTRAN Debugger

OVMS 7.3-2, OVMS Alpha Debug64 Version V7.3-200, FORTRAN V8.0-104655-48F7C

When compiling with /DEBUG/NOOPT/CHECK=ALL
I get
%FOR-W-DIAGNOSTIC, fort:(1): In call to UP2, an array temporary was created for argument #2
break on unhandled exception preceding SHARE$LIBRTL_CODE0+460948

The 2. argument for up2 is column 1 and 2 of a matrix, so continues storage and both subroutines are interal procedures:

PROGRAM a
IMPLICIT NONE
INTEGER*4 i1,i2
READ (5,*) i1,i2
CALL up1

CONTAINS

SUBROUTINE up1
INTEGER*4 :: a(i1:i2,2)
PRINT *,'up1',shape(a),lbound(a),ubound(a)
CALL up2(1,a(:,1))
CALL up2(2,a(:,2))
PRINT *,a
END SUBROUTINE up1

SUBROUTINE up2(j,w)
INTEGER*4, INTENT(IN) :: j
INTEGER*4, INTENT(OUT) :: w(i1:i2)
INTEGER*4 :: i
PRINT *,'up2',shape(w),lbound(w),ubound(w)
DO i = i1,i2
w(i) = i*j
END DO
PRINT *,w
END SUBROUTINE up2

END

Input: i1=2, i2=4

If I change the definition of w in up2 to

INTEGER*4, INTENT(OUT) :: w(:)

the bounds of w become 1 and 3 and the DO-loop will fail.

Does the compiler generate a temporary array only when /DEBUG/NOOPT/CHECK=ALL or in all cases, even when compiling with
/NODEBUG/OPT/LEVEL=5?
How can I get informed from the compiler to have generated temporay files?
4 REPLIES 4
Travis Craig
Frequent Advisor

Re: FORTRAN Debugger

Michael,

I have Fortran V7.5-1961-48BCD on OVMS 7.3-1 and I tried your program. I get the diagnostic at run-time only, but otherwise seem to have the same results as you. I put in some calls to a subroutine to print the addresses of the arrays as seen by up1 and up2 and found that the temporary array is created with either

/DEBUG/NOOPT/CHECK=ALL

or

/NODEBUG/OPT/LEVEL=5

There was no temporary array when I used your

INTEGER*4, INTENT(OUT) :: w(:)

I don't know the impact of temporary arrays, but when I compile with

/CHECK=(ALL,NOAR)

then I at least do not see the diagnostic message.

--Travis Craig
My head is cold.
Jansen_8
Regular Advisor

Re: FORTRAN Debugger

It is a warning for "inefficient" code.
The declartion of a in up2 can be better done
by an "allocatable" array (in fact what you
implicitly do. Change your code the the code below and the run-time warning is gone (at least on my VMS8.2 machine with the same compiler you use


PROGRAM a
IMPLICIT NONE
INTEGER*4 i1,i2
READ (5,*) i1,i2
CALL up1

CONTAINS

SUBROUTINE up1
INTEGER*4 , allocatable :: a(: , :)
allocate( a( i1:i2 , 2 ) )
PRINT *,'up1',shape(a),lbound(a),ubound(a)
CALL up2(1,a(:,1))
CALL up2(2,a(:,2))
PRINT *,a
END SUBROUTINE up1

SUBROUTINE up2(j,w)
INTEGER*4, INTENT(IN) :: j
INTEGER*4, INTENT(OUT) :: w(i1:i2)
INTEGER*4 :: i
PRINT *,'up2',shape(w),lbound(w),ubound(w)
DO i = i1,i2
w(i) = i*j
END DO
PRINT *,w
END SUBROUTINE up2

END



Michael Menge
Frequent Advisor

Re: FORTRAN Debugger

But why does the compiler handle an automatic and an allocatable array differently in this situation?
An automatic array has fixed boundaries throughout the live of subroutine up1 and could therefor better optimized than an allocatable array, the bounds of which could change during a subroutine call.
The allocate-statement would be extra in up1 whereas an automatic array gets storage from the stack. Another point is, that the columns of a are transfered by descriptor and why should an automatic array have other bounds than an allocatable?
Jansen_8
Regular Advisor

Re: FORTRAN Debugger

Right, but than you have to give expiclit boundaries in the calls top up2:

CALL up2(1,a(i1:i2,1))
CALL up2(2,a(i1:i2,2))

Also in this case the warning is gone.
But this is rather tricky since you are not allowed to assume that i1 and i2 are not changed during processing of up2. (which makes optimizing rather difficult, when the routines become more complicated than this example)